-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ARC-65: AVM Run Time Errors based on program bytecode #315
Merged
Merged
Changes from 10 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
7ced852
doc: ARC-65
cusma 3848dae
doc: fix discussions-to field
cusma 393d7b0
nit: lint
cusma c5b57c7
doc: review's suggestion
cusma 5276618
doc: nit
cusma f86cc28
doc: nit
cusma 348ff1e
doc: typo
cusma 87b1acf
Merge branch 'main' into pr/315
SudoWeezy 32e9092
doc: specify error format
cusma 2030cee
doc: fix regexp, add examples
cusma 690345e
doc: rely on logs array instead of message field
cusma 807f49d
doc: add 32 bytes recommendation
cusma 859a73f
doc: add 8 bytes recommendation
cusma 22128f9
doc: compilers recommendations
cusma ed6d526
doc: error code recommendations
cusma c7ebf3d
doc: lint ARC links
cusma ea82c31
doc: fix non-relative links
cusma e0b0007
doc: update error format according IRL feedback
cusma 2aa3e3c
doc: replace ARC-64 with ARC-56
cusma 249f6f2
doc: update algod api response
cusma 61b223b
Merge branch 'main' into pr/315
SudoWeezy b0492dd
Last call
SudoWeezy 347dd61
Merge branch 'main' into pr/315
SudoWeezy 6ded67d
update to final
SudoWeezy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
--- | ||
arc: 65 | ||
title: AVM Run Time Errors In Program | ||
description: Informative AVM run time errors based on program bytecode | ||
author: Cosimo Bassi (@cusma), Tasos Bitsios (@tasosbit), Steve Ferrigno (@nullun) | ||
discussions-to: https://github.com/algorandfoundation/ARCs/issues/315 | ||
status: Draft | ||
type: Standards Track | ||
category: ARC | ||
created: 2024-10-09 | ||
--- | ||
|
||
## Abstract | ||
|
||
This document introduces a convention for rising informative run time errors on | ||
the Algorand Virtual Machine (AVM) directly from the program bytecode. | ||
|
||
## Motivation | ||
|
||
The AVM does not offer native opcodes to catch and raise run time errors. | ||
|
||
The lack of native error handling semantics could lead to fragmentation of tooling | ||
and frictions for AVM clients, who are unable to retrieve informative and useful | ||
hints about the occurred run time failures. | ||
|
||
This ARC formalizes a convention to rise AVM run time errors based just on the program | ||
bytecode. | ||
|
||
## Specification | ||
|
||
The keywords "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", | ||
"**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" | ||
in this document are to be interpreted as described in <a href="https://datatracker.ietf.org/doc/html/rfc2119">RFC 2119</a>. | ||
|
||
> Notes like this are non-normative. | ||
|
||
### In Program Errors | ||
|
||
When a program wants to emit informative run time errors, contained in the bytecode, | ||
it **MUST**: | ||
|
||
1. Push to the stack the bytes string containing the error; | ||
1. Execute the `log` opcode to use the bytes from the top of the stack; | ||
1. Execute the `err` opcode to immediately terminate the program. | ||
|
||
Upon a program run time failure, the Algod API returns both the failed *program | ||
counter* (`pc`) and the `log` content. | ||
|
||
### Error format | ||
|
||
> The AVM programs bytecode have limited sized. In this convention, the errors are | ||
> part of the bytecode, therefore it is good to mind errors' formatting and sizing. | ||
|
||
> Errors consist of a _code_ and an optional _short message_. | ||
|
||
Errors **MUST** statisfy the regexp: `ERR:(\w*)(?:\s?-\s?(.*))?`. | ||
|
||
It is **RECOMMENDED** to use `UTF-8` for the error encoding. | ||
|
||
It is **RECOMMENDED** to use fixed length error codes and _short_ error messages. | ||
|
||
### Error examples | ||
|
||
Error with a _numeric code_: `ERR:042`. | ||
|
||
Error with an _alphanumeric code_: `ERR:BadRequest`. | ||
|
||
Error with a _numeric code_ and _short message_: `ERR:042 - A Funny Error`. | ||
|
||
### Program example | ||
|
||
The program example raises the error `ERR:001 - Invalid Method` for any application | ||
call to methods different from `m1()void`. | ||
|
||
```teal | ||
#pragma version 10 | ||
|
||
txn ApplicationID | ||
bz end | ||
|
||
method "m1()void" | ||
txn ApplicationArgs 0 | ||
match method1 | ||
byte "ERR:001 - Invalid Method" | ||
log | ||
err | ||
|
||
method1: | ||
b end | ||
|
||
end: | ||
int 1 | ||
``` | ||
|
||
Full Algod API response of a failed execution: | ||
|
||
```json | ||
{ | ||
"data": { | ||
"app-index":1004, | ||
"eval-states": [ | ||
{ | ||
"logs": ["RVJSOiBJbnZhbGlkIE1ldGhvZA=="] | ||
} | ||
], | ||
"group-index":0, | ||
"pc":41 | ||
}, | ||
"message":"TransactionPool.Remember: transaction ESI4GHAZY46MCUCLPBSB5HBRZPGO6V7DDUM5XKMNVPIRJK6DDAGQ: logic eval error: err opcode executed. Details: app=1004, pc=41, opcodes=pushbytes 0x4552523a20496e76616c6964204d6574686f64 // \"ERR:001 - Invalid Method\"; log; err; label2:" | ||
} | ||
``` | ||
|
||
The `message` field contains the error `ERR:001 - Invalid Method`. | ||
|
||
## Rationale | ||
|
||
This convention for AVM run time errors presents the following PROS and CONS. | ||
|
||
### PROS | ||
|
||
- No additional artifacts required to bind the failed *program counter* (`pc`) to | ||
the informative _error_; | ||
- Errors are returned directly in the Algod API response, no additional client operation | ||
needed. | ||
|
||
### CONS | ||
|
||
- Errors consume program bytecode size. | ||
|
||
## Security Considerations | ||
|
||
> Not applicable. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, I think changing it to rely on the
logs
array would be better. Just decode each value and compare against the regex.Here's an example I did via the command line with an application that attempts to use ABI methods first, then falls back to non-ABI methods. It resulted in two logged errors before failing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC the SDKs (e.g. JS) currently only throw the error message, e.g. when you do
sendRawTransaction
in JS/TS.To me, including the error code in the surfaced message makes it significantly more useful