Skip to content

Commit

Permalink
Properly handle failing clear state programs (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonpaulos authored Jan 4, 2024
1 parent d4a1b8b commit b0e025c
Show file tree
Hide file tree
Showing 12 changed files with 709 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Fix app state not being properly reset when stepping back ([#19](https://github.com/algorand/avm-debugger/pull/19))
- Properly handle failing clear state programs ([#20](https://github.com/algorand/avm-debugger/pull/20))

## [0.1.2] - 2023-12-14

Expand Down
4 changes: 4 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ Execution errors will be reported by the debugger. Since any error stops the exe
transaction group, the debugger will not allow you to advance after an error. You can however step
backwards to inspect what happened prior to the error.

> Note: There are a special class of errors which do not stop the execution of a transaction group.
> These are errors or rejections that occur in a clear state program. The debugger will still show
> these errors, and it will allow you to continue execution over them.
![An error in the debugger](images/error.png)

## Inspect program state
Expand Down
20 changes: 19 additions & 1 deletion algosdk/client/v2/algod/models/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2316,6 +2316,17 @@ export declare class SimulationTransactionExecTrace extends BaseModel {
* Program trace that contains a trace of opcode effects in a clear state program.
*/
clearStateProgramTrace?: SimulationOpcodeTraceUnit[];
/**
* If true, indicates that the clear state program failed and any persistent state
* changes it produced should be reverted once the program exits.
*/
clearStateRollback?: boolean;
/**
* The error message explaining why the clear state program failed. This field will
* only be populated if clear-state-rollback is true and the failure was due to an
* execution error.
*/
clearStateRollbackError?: string;
/**
* An array of SimulationTransactionExecTrace representing the execution trace of
* any inner transactions executed.
Expand All @@ -2335,16 +2346,23 @@ export declare class SimulationTransactionExecTrace extends BaseModel {
* @param approvalProgramTrace - Program trace that contains a trace of opcode effects in an approval program.
* @param clearStateProgramHash - SHA512_256 hash digest of the clear state program executed in transaction.
* @param clearStateProgramTrace - Program trace that contains a trace of opcode effects in a clear state program.
* @param clearStateRollback - If true, indicates that the clear state program failed and any persistent state
* changes it produced should be reverted once the program exits.
* @param clearStateRollbackError - The error message explaining why the clear state program failed. This field will
* only be populated if clear-state-rollback is true and the failure was due to an
* execution error.
* @param innerTrace - An array of SimulationTransactionExecTrace representing the execution trace of
* any inner transactions executed.
* @param logicSigHash - SHA512_256 hash digest of the logic sig executed in transaction.
* @param logicSigTrace - Program trace that contains a trace of opcode effects in a logic sig.
*/
constructor({ approvalProgramHash, approvalProgramTrace, clearStateProgramHash, clearStateProgramTrace, innerTrace, logicSigHash, logicSigTrace, }: {
constructor({ approvalProgramHash, approvalProgramTrace, clearStateProgramHash, clearStateProgramTrace, clearStateRollback, clearStateRollbackError, innerTrace, logicSigHash, logicSigTrace, }: {
approvalProgramHash?: string | Uint8Array;
approvalProgramTrace?: SimulationOpcodeTraceUnit[];
clearStateProgramHash?: string | Uint8Array;
clearStateProgramTrace?: SimulationOpcodeTraceUnit[];
clearStateRollback?: boolean;
clearStateRollbackError?: string;
innerTrace?: SimulationTransactionExecTrace[];
logicSigHash?: string | Uint8Array;
logicSigTrace?: SimulationOpcodeTraceUnit[];
Expand Down
13 changes: 12 additions & 1 deletion algosdk/client/v2/algod/models/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -2706,12 +2706,17 @@ class SimulationTransactionExecTrace extends basemodel_1.default {
* @param approvalProgramTrace - Program trace that contains a trace of opcode effects in an approval program.
* @param clearStateProgramHash - SHA512_256 hash digest of the clear state program executed in transaction.
* @param clearStateProgramTrace - Program trace that contains a trace of opcode effects in a clear state program.
* @param clearStateRollback - If true, indicates that the clear state program failed and any persistent state
* changes it produced should be reverted once the program exits.
* @param clearStateRollbackError - The error message explaining why the clear state program failed. This field will
* only be populated if clear-state-rollback is true and the failure was due to an
* execution error.
* @param innerTrace - An array of SimulationTransactionExecTrace representing the execution trace of
* any inner transactions executed.
* @param logicSigHash - SHA512_256 hash digest of the logic sig executed in transaction.
* @param logicSigTrace - Program trace that contains a trace of opcode effects in a logic sig.
*/
constructor({ approvalProgramHash, approvalProgramTrace, clearStateProgramHash, clearStateProgramTrace, innerTrace, logicSigHash, logicSigTrace, }) {
constructor({ approvalProgramHash, approvalProgramTrace, clearStateProgramHash, clearStateProgramTrace, clearStateRollback, clearStateRollbackError, innerTrace, logicSigHash, logicSigTrace, }) {
super();
this.approvalProgramHash =
typeof approvalProgramHash === 'string'
Expand All @@ -2723,6 +2728,8 @@ class SimulationTransactionExecTrace extends basemodel_1.default {
? (0, binarydata_1.base64ToBytes)(clearStateProgramHash)
: clearStateProgramHash;
this.clearStateProgramTrace = clearStateProgramTrace;
this.clearStateRollback = clearStateRollback;
this.clearStateRollbackError = clearStateRollbackError;
this.innerTrace = innerTrace;
this.logicSigHash =
typeof logicSigHash === 'string'
Expand All @@ -2734,6 +2741,8 @@ class SimulationTransactionExecTrace extends basemodel_1.default {
approvalProgramTrace: 'approval-program-trace',
clearStateProgramHash: 'clear-state-program-hash',
clearStateProgramTrace: 'clear-state-program-trace',
clearStateRollback: 'clear-state-rollback',
clearStateRollbackError: 'clear-state-rollback-error',
innerTrace: 'inner-trace',
logicSigHash: 'logic-sig-hash',
logicSigTrace: 'logic-sig-trace',
Expand All @@ -2751,6 +2760,8 @@ class SimulationTransactionExecTrace extends basemodel_1.default {
clearStateProgramTrace: typeof data['clear-state-program-trace'] !== 'undefined'
? data['clear-state-program-trace'].map(SimulationOpcodeTraceUnit.from_obj_for_encoding)
: undefined,
clearStateRollback: data['clear-state-rollback'],
clearStateRollbackError: data['clear-state-rollback-error'],
innerTrace: typeof data['inner-trace'] !== 'undefined'
? data['inner-trace'].map(SimulationTransactionExecTrace.from_obj_for_encoding)
: undefined,
Expand Down
20 changes: 20 additions & 0 deletions sampleWorkspace/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,26 @@
"simulateTraceFile": "${workspaceFolder}/errors/logicsig-after-error/simulate-response.json",
"programSourcesDescriptionFile": "${workspaceFolder}/errors/logicsig-after-error/sources.json",

"stopOnEntry": true
},
{
"type": "avm",
"request": "launch",
"name": "Clear State Rejection",

"simulateTraceFile": "${workspaceFolder}/errors/clear-state/rejection-response.json",
"programSourcesDescriptionFile": "${workspaceFolder}/errors/clear-state/sources.json",

"stopOnEntry": true
},
{
"type": "avm",
"request": "launch",
"name": "Clear State Error",

"simulateTraceFile": "${workspaceFolder}/errors/clear-state/error-response.json",
"programSourcesDescriptionFile": "${workspaceFolder}/errors/clear-state/sources.json",

"stopOnEntry": true
}
]
Expand Down
180 changes: 180 additions & 0 deletions sampleWorkspace/errors/clear-state/error-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
{
"exec-trace-config": {
"enable": true,
"scratch-change": true,
"stack-change": true,
"state-change": true
},
"initial-states": {
"app-initial-states": [
{
"app-globals": {
"kvs": [
{
"key": "Y291bnRlcg==",
"value": {
"type": 2,
"uint": 4
}
}
]
},
"id": 1001
}
]
},
"last-round": 4,
"txn-groups": [
{
"app-budget-added": 700,
"app-budget-consumed": 14,
"txn-results": [
{
"app-budget-consumed": 14,
"exec-trace": {
"clear-state-program-hash": "ZY8dOBgLGyQoqiQqBH1PSo+dCcJIDpwqLzqLBvNJaNk=",
"clear-state-program-trace": [
{
"pc": 1
},
{
"pc": 4,
"stack-additions": [
{
"bytes": "Y291bnRlcg==",
"type": 1
}
]
},
{
"pc": 13,
"stack-additions": [
{
"bytes": "Y291bnRlcg==",
"type": 1
},
{
"bytes": "Y291bnRlcg==",
"type": 1
}
],
"stack-pop-count": 1
},
{
"pc": 14,
"stack-additions": [
{
"type": 2,
"uint": 4
}
],
"stack-pop-count": 1
},
{
"pc": 15,
"stack-additions": [
{
"type": 2,
"uint": 1
}
]
},
{
"pc": 16,
"stack-additions": [
{
"type": 2,
"uint": 5
}
],
"stack-pop-count": 2
},
{
"pc": 17,
"stack-pop-count": 2,
"state-changes": [
{
"app-state-type": "g",
"key": "Y291bnRlcg==",
"new-value": {
"type": 2,
"uint": 5
},
"operation": "w"
}
]
},
{
"pc": 18,
"stack-additions": [
{
"type": 2,
"uint": 1001
}
]
},
{
"pc": 20,
"stack-pop-count": 1
},
{
"pc": 23,
"stack-additions": [
{
"type": 2,
"uint": 3
}
]
},
{
"pc": 25,
"stack-additions": [
{
"type": 2,
"uint": 1
}
]
},
{
"pc": 26,
"stack-additions": [
{
"type": 2
}
],
"stack-pop-count": 2
},
{
"pc": 27,
"stack-pop-count": 1
},
{
"pc": 30
}
],
"clear-state-rollback": true,
"clear-state-rollback-error": "invalid ApplicationArgs index 0"
},
"txn-result": {
"pool-error": "",
"txn": {
"sig": "Q0UCQSgS7KBWT+N/xXFELqajmZatiAp4NZgoOJRLoEKRGwUkr0/E7BMOybspT7BIVa0vCpjN0l8O/ePdcs9EAg==",
"txn": {
"apan": 3,
"apid": 1001,
"fee": 1000,
"fv": 4,
"gh": "dsgtQlDfh3EgBWQs+f6G+ZorH4WiY2Vmzu7sGgfcbng=",
"lv": 1004,
"note": "sV/32BiFDlA=",
"snd": "EI4F6GLWBIUTRCC4EJK7TXKY4AEW6DOZNUXYZXYEHBPXNFJU53REVFPI34",
"type": "appl"
}
}
}
}
]
}
],
"version": 2
}
Loading

0 comments on commit b0e025c

Please sign in to comment.