From f61a73e7e64758fbd415aa07e89e92c87e7f5636 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 11:05:13 -0600 Subject: [PATCH 1/5] Move to Last Call Move to last call and some minor edits. Normative: move memSize position Normative: Remove implementation links (per current linking policy) Non-normative: update sample test case Non-normative: formatting and minor verbiage edits --- EIPS/eip-3155.md | 171 +++++++++++++++++++++++------------------------ 1 file changed, 84 insertions(+), 87 deletions(-) diff --git a/EIPS/eip-3155.md b/EIPS/eip-3155.md index 8d55f3e2e2cbf..18a27c6a3a774 100644 --- a/EIPS/eip-3155.md +++ b/EIPS/eip-3155.md @@ -3,21 +3,21 @@ eip: 3155 title: EVM trace specification author: Martin Holst Swende (@holiman), Marius van der Wijden (@MariusVanDerWijden) discussions-to: https://ethereum-magicians.org/t/eip-3155-create-evm-trace-specification/5007 -status: Stagnant +status: Last Call +last-call-deadline: 2024-09-01 type: Standards Track category: Interface created: 2020-12-07 --- - ## Simple Summary Introduce a new JSON standard for EVM traces during execution of state tests. ## Motivation The Ethereum Virtual Machine executes all smart contract code on ethereum. In order to debug smart contracts and state tests better, a common format was introduced to log every execution step of the EVM. -This format was implemented by go-ethereum, parity, nethermind and Besu. -Since the common format was not well defined, the implementations differed slightly making it hard to develop adequate tooling which reduces the usefulness of tracing significantly. +This format was implemented by Go-Ethereum, Parity-Ethereum, Nethermind and Besu. +Since the common format was not well-defined, the implementations differed slightly, making it hard to develop adequate tooling which reduces the usefulness of tracing significantly. This EIP has multiple objectives: - Move the specification to a more visible place to encourage new clients to implement it @@ -26,95 +26,97 @@ This EIP has multiple objectives: - Provide sample output Implementing this EIP in all major clients allows us to create meaningful differential fuzzers that fuzz EVM implementations for the mainnet and all upcoming hardforks. -It also helps finding differences in execution quickly in the case of a chain split. +It also helps to find differences in execution quickly in the case of a chain split. This EIP will enable users to create better differential fuzzing infrastructure to compare the EVM implementations of all major Ethereum clients against each other. This could help to find bugs that are currently present in the client implementations. ## Specification -Clients should be able to execute simple transactions as well as code and return traces. In the following, we will call this client CUT (client under test) and use go-ethereums `evm` binary for code examples. +Clients should be able to execute simple transactions as well as code and return traces. In the following, we will call this client CUT (client under test) and use go-ethereum's `evm` binary for code examples. ### Datatypes -| Type | Explanation | Example | -|---|---|---| -| Number | Plain json number | "pc":0 | -| Hex-Number | Hex-encoded number | "gas":"0x2540be400" | -| String | Plain string | "opName":"PUSH1" | -| Hex-String | Hex-encoded string | | -| Array of x | Array of x encoded values | | -| Key-Value | Key-Value structure with key and values encoded as hex strings | | -| Boolean | Json bool can either be true or false | "pass": true | +| Type | Explanation | Example | +|------------|----------------------------------------------------------------|---------------------| +| Number | Plain json number | "pc":0 | +| Hex-Number | Hex-encoded number | "gas":"0x2540be400" | +| String | Plain string | "opName":"PUSH1" | +| Hex-String | Hex-encoded string | | +| Array of x | Array of x encoded values | | +| Key-Value | Key-Value structure with key and values encoded as hex strings | | +| Boolean | Json bool can either be true or false | "pass": true | ### Output The CUT MUST output a `json` object for EACH operation. -Required Fields: - -| Name | Type | Explanation | -|---|---|---| -| `pc` | Number | Program Counter | -| `op` | Number | OpCode | -| `gas` | Hex-Number | Gas left before executing this operation | -| `gasCost` | Hex-Number | Gas cost of this operation | -| `stack` | Array of Hex-Numbers | Array of all values on the stack | -| `depth` | Number | Depth of the call stack | -| `returnData` | Hex-String | Data returned by function call | -| `refund` | Hex-Number | Amount of **global** gas refunded | -| `memSize` | Number | Size of memory array | - -Optional Fields: - -| Name | Type | Explanation | -|---|---|---| -| `opName` | String | Name of the operation | -| `error` | Hex-String | Description of an error (should contain revert reason if supported) | -| `memory` | Array of Hex-Strings | Array of all allocated values | -| `storage` | Key-Value | Array of all stored values | -| `returnStack` | Array of Hex-Numbers | Array of values, Stack of the called function | +#### Required Fields + +| Name | Type | Explanation | +|--------------|----------------------|------------------------------------------| +| `pc` | Number | Program Counter | +| `op` | Number | OpCode | +| `gas` | Hex-Number | Gas left before executing this operation | +| `gasCost` | Hex-Number | Gas cost of this operation | +| `memSize` | Number | Size of memory array | +| `stack` | Array of Hex-Numbers | Array of all values on the stack | +| `depth` | Number | Depth of the call stack | +| `returnData` | Hex-String | Data returned by function call | +| `refund` | Hex-Number | Amount of **global** gas refunded | + +#### Optional Fields + +| Name | Type | Explanation | +|---------------|----------------------|---------------------------------------------------------------------| +| `opName` | String | Name of the operation | +| `error` | Hex-String | Description of an error (should contain revert reason if supported) | +| `memory` | Array of Hex-Strings | Array of all allocated values | +| `storage` | Key-Value | Array of all stored values | +| `returnStack` | Array of Hex-Numbers | Array of values, Stack of the called function | *Example:* ``` {"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"depth":1,"error":null,"opName":"PUSH1"} ``` -The `stack`, `memory` and `memSize` are the values _before_ execution of the op. -All array attributes (`stack`, `returnStack`, `memory`) MUST be initialized to empty arrays ("stack":[],) NOT to null. -If the CUT will not output values for `memory` or `storage` then the `memory` and `storage` fields are omitted. -This can happen either because the CUT does not support tracing these fields or it has been configured not to trace it. -The `memSize` field MUST be present regardless of `memory` support. -Clients SHOULD implement a way to disable recording the storage as the stateroot includes all storage updates. -Clients SHOULD output the fields in the same order as listed in this EIP. +- The `stack`, `memory` and `memSize` are the values _before_ execution of the op. +- All array attributes (`stack`, `returnStack`, `memory`) MUST be initialized to empty arrays (`"stack":[]`) NOT to null. +- If the CUT will not be outputting values for `memory` or `storage` then the `memory` and `storage` fields are omitted. + This can happen either because the CUT does not support tracing these fields or it has been configured not to trace it. +- The `memSize` field MUST be present regardless of `memory` support. +- Clients SHOULD implement a way to disable recording the storage as the stateroot includes all storage updates. +- Clients SHOULD output the fields in the same order as listed in this EIP. -The CUT MUST NOT output a line for the `STOP` operation if an error occurred: +- The CUT MUST NOT output a line for the `STOP` operation if an error occurred: *Example:* ``` {"pc":2,"op":0,"gas":"0x2540be3fd","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0x40"],"depth":1,"error":null,"opName":"STOP"} ``` -### Summary and error handling +### Summary and Error Handling -At the end of execution, the CUT MUST print some summerical info, this info SHOULD have the following fields. +At the end of execution, the CUT MUST print summary info; this info SHOULD have the following fields. The summary should be a single `jsonl` object. -Required Fields: +#### Required Fields + +| Name | Type | Explanation | +|-------------|------------|--------------------------------------------------------| +| `stateRoot` | Hex-String | Root of the state trie after executing the transaction | +| `output` | | Return values of the function | +| `gasUsed` | Hex-Number | All gas used by the transaction | +| `pass` | Boolean | Bool whether transaction was executed successfully | -| Name | Type | Explanation | -|---|---|---| -| `stateRoot` | Hex-String | Root of the state trie after executing the transaction | -| `output` | | Return values of the function | -| `gasUsed` | Hex-Number | All gas used by the transaction | -| `pass` | Boolean | Bool whether transaction was executed successfully | +#### Optional Fields -OptionalFields: +| Name | Type | Explanation | +|--------|--------|-------------------------------------------------------| +| `time` | Number | Time in nanoseconds needed to execute the transaction | +| `fork` | String | Name of the fork rules used for execution | -| Name | Type | Explanation | -|---|---|---| -| `time` | Number | Time in nanoseconds needed to execute the transaction | -| `fork` | String | Name of the fork rules used for execution | +*Example*: ``` -{"stateRoot":"0xd4c577737f5d20207d338c360c42d3af78de54812720e3339f7b27293ef195b7","output":"","gasUsed":"0x3","successful":"true","time":141485} +{"stateRoot":"0xd4c577737f5d20207d338c360c42d3af78de54812720e3339f7b27293ef195b7","output":"","gasUsed":"0x3","pass":"true","time":141485} ``` ## Rationale @@ -131,36 +133,31 @@ This EIP is fully backward compatible with go-ethereum. OpenEthereum, Besu and N ## Test Cases ```bash - ~/go/src/github.com/ethereum/go-ethereum/build/bin/evm --code 604080536040604055604060006040600060025afa6040f3 --json run -{"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":2,"op":128,"gas":"0x2540be3fd","gasCost":"0x3","memory":"0x","memSize":0,"stack":["0x40"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"DUP1","error":""} -{"pc":3,"op":83,"gas":"0x2540be3fa","gasCost":"0xc","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x40"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"MSTORE8","error":""} -{"pc":4,"op":96,"gas":"0x2540be3ee","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":[],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":6,"op":96,"gas":"0x2540be3eb","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":8,"op":85,"gas":"0x2540be3e8","gasCost":"0x4e20","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x40"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SSTORE","error":""} -{"pc":9,"op":96,"gas":"0x2540b95c8","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":[],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":11,"op":96,"gas":"0x2540b95c5","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":13,"op":96,"gas":"0x2540b95c2","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":15,"op":96,"gas":"0x2540b95bf","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":17,"op":96,"gas":"0x2540b95bc","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":19,"op":90,"gas":"0x2540b95b9","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x2"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"GAS","error":""} -{"pc":20,"op":250,"gas":"0x2540b95b7","gasCost":"0x24abb676c","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x2","0x2540b95b7"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"STATICCALL","error":""} -{"pc":21,"op":96,"gas":"0x2540b92a7","gasCost":"0x3","memory":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x1"],"returnStack":[],"returnData":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","depth":1,"refund":0,"opName":"PUSH1","error":""} -{"pc":23,"op":243,"gas":"0x2540b92a4","gasCost":"0x0","memory":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x1","0x40"],"returnStack":[],"returnData":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","depth":1,"refund":0,"opName":"RETURN","error":""} -{"stateRoot":"2eef130ec61805516c1f050720b520619787704a5dd826a39aeefb850f83acfd", "output":"40","gasUsed":"0x515c","time":350855} -``` - - -## Implementation -Implementation in [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/cmd/evm) -Implementation in [OpenEthereum](https://github.com/openethereum/openethereum/tree/main/bin/evmbin) -Implementation in [Besu](https://github.com/hyperledger/besu/tree/master/ethereum/evmtool) -Implementation in [Nethermind](https://github.com/NethermindEth/nethermind/tree/master/src/Nethermind/Nethermind.State.Test.Runner) +${BESU_HOME}/bin/evmtool --code 0x604080536040604055604060006040600060025afa6040f3 {"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":2,"op":128,"gas":"0x2540be3fd","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"DUP1"} +{"pc":3,"op":83,"gas":"0x2540be3fa","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"MSTORE8"} +{"pc":4,"op":96,"gas":"0x2540be3ee","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":6,"op":96,"gas":"0x2540be3eb","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":8,"op":85,"gas":"0x2540be3e8","gasCost":"0x4e20","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"SSTORE"} +{"pc":9,"op":96,"gas":"0x2540b95c8","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":11,"op":96,"gas":"0x2540b95c5","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":13,"op":96,"gas":"0x2540b95c2","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":15,"op":96,"gas":"0x2540b95bf","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":17,"op":96,"gas":"0x2540b95bc","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} +{"pc":19,"op":90,"gas":"0x2540b95b9","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x2"],"depth":1,"refund":0,"opName":"GAS"} +{"pc":20,"op":250,"gas":"0x2540b95b7","gasCost":"0x24abb676c","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x2","0x2540b95b7"],"depth":1,"refund":0,"opName":"STATICCALL"} +{"pc":21,"op":96,"gas":"0x2540b92a7","gasCost":"0x3","memory":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x1"],"returnData":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","depth":1,"refund":0,"opName":"PUSH1"} +{"pc":23,"op":243,"gas":"0x2540b92a4","gasCost":"0x0","memory":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x1","0x40"],"returnData":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","depth":1,"refund":0,"opName":"RETURN"} +{"stateRoot":"0x8fa0dcc7f1d2383c89e5737c2843632db881c0946e80b71fe7175365e6538797","output":"0x40","gasUsed":"0x515c","pass":true,"fork":"Istanbul"} +``` ## Security Considerations + Tracing is expensive. -Exposing an endpoint for creating traces publicly could open up a denial of service vector. + +Exposing an endpoint for creating traces publicly could open up a denial of service vector. + Clients should consider putting trace endpoints behind a separate flag from other endpoints. ## Copyright From c19d96fa4e55e51c0aaf81da41841a0f327c974c Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 11:53:41 -0600 Subject: [PATCH 2/5] autobot fixes --- EIPS/eip-3155.md | 59 ++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/EIPS/eip-3155.md b/EIPS/eip-3155.md index 18a27c6a3a774..0f204f67712ce 100644 --- a/EIPS/eip-3155.md +++ b/EIPS/eip-3155.md @@ -1,6 +1,7 @@ --- eip: 3155 title: EVM trace specification +description: A standard JSON format for EVM traces author: Martin Holst Swende (@holiman), Marius van der Wijden (@MariusVanDerWijden) discussions-to: https://ethereum-magicians.org/t/eip-3155-create-evm-trace-specification/5007 status: Last Call @@ -10,16 +11,19 @@ category: Interface created: 2020-12-07 --- -## Simple Summary -Introduce a new JSON standard for EVM traces during execution of state tests. +## Abstract + +Introduce a new JSON standard for EVM traces during execution of state tests. ## Motivation -The Ethereum Virtual Machine executes all smart contract code on ethereum. -In order to debug smart contracts and state tests better, a common format was introduced to log every execution step of the EVM. -This format was implemented by Go-Ethereum, Parity-Ethereum, Nethermind and Besu. + +The Ethereum Virtual Machine executes all smart contract code on ethereum. +In order to debug smart contracts and state tests better, a common format was introduced to log every execution step of the EVM. +This format was implemented by Go-Ethereum, Parity-Ethereum, Nethermind and Besu. Since the common format was not well-defined, the implementations differed slightly, making it hard to develop adequate tooling which reduces the usefulness of tracing significantly. -This EIP has multiple objectives: +This EIP has multiple goals: + - Move the specification to a more visible place to encourage new clients to implement it - Strictly define corner cases that were not addressed in the previous version - Allow for updates to the specification in case new fields are introduced during execution @@ -28,11 +32,13 @@ This EIP has multiple objectives: Implementing this EIP in all major clients allows us to create meaningful differential fuzzers that fuzz EVM implementations for the mainnet and all upcoming hardforks. It also helps to find differences in execution quickly in the case of a chain split. -This EIP will enable users to create better differential fuzzing infrastructure to compare the EVM implementations of all major Ethereum clients against each other. -This could help to find bugs that are currently present in the client implementations. +This EIP will enable users to create better differential fuzzing infrastructure to compare the EVM implementations of all major Ethereum clients against each other. +This could help to find bugs that are currently present in the client implementations. ## Specification -Clients should be able to execute simple transactions as well as code and return traces. In the following, we will call this client CUT (client under test) and use go-ethereum's `evm` binary for code examples. + +Clients should be able to execute simple transactions as well as code and return traces. In the following, we will call this client CUT (client under test) and use go-ethereum's +`evm` binary for code examples. ### Datatypes @@ -48,9 +54,9 @@ Clients should be able to execute simple transactions as well as code and return ### Output -The CUT MUST output a `json` object for EACH operation. +The CUT MUST output a `json` object for EACH operation. -#### Required Fields +#### Required Fields | Name | Type | Explanation | |--------------|----------------------|------------------------------------------| @@ -64,7 +70,7 @@ The CUT MUST output a `json` object for EACH operation. | `returnData` | Hex-String | Data returned by function call | | `refund` | Hex-Number | Amount of **global** gas refunded | -#### Optional Fields +#### Optional Fields | Name | Type | Explanation | |---------------|----------------------|---------------------------------------------------------------------| @@ -74,12 +80,13 @@ The CUT MUST output a `json` object for EACH operation. | `storage` | Key-Value | Array of all stored values | | `returnStack` | Array of Hex-Numbers | Array of values, Stack of the called function | -*Example:* +*Example:* + ``` {"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"depth":1,"error":null,"opName":"PUSH1"} ``` -- The `stack`, `memory` and `memSize` are the values _before_ execution of the op. +- The `stack`, `memory` and `memSize` are the values *before* execution of the op. - All array attributes (`stack`, `returnStack`, `memory`) MUST be initialized to empty arrays (`"stack":[]`) NOT to null. - If the CUT will not be outputting values for `memory` or `storage` then the `memory` and `storage` fields are omitted. This can happen either because the CUT does not support tracing these fields or it has been configured not to trace it. @@ -87,8 +94,10 @@ The CUT MUST output a `json` object for EACH operation. - Clients SHOULD implement a way to disable recording the storage as the stateroot includes all storage updates. - Clients SHOULD output the fields in the same order as listed in this EIP. -- The CUT MUST NOT output a line for the `STOP` operation if an error occurred: -*Example:* +The CUT MUST NOT output a line for the `STOP` operation if an error occurred: + +*Example:* + ``` {"pc":2,"op":0,"gas":"0x2540be3fd","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0x40"],"depth":1,"error":null,"opName":"STOP"} ``` @@ -98,7 +107,7 @@ The CUT MUST output a `json` object for EACH operation. At the end of execution, the CUT MUST print summary info; this info SHOULD have the following fields. The summary should be a single `jsonl` object. -#### Required Fields +#### Required Fields | Name | Type | Explanation | |-------------|------------|--------------------------------------------------------| @@ -115,20 +124,26 @@ The summary should be a single `jsonl` object. | `fork` | String | Name of the fork rules used for execution | *Example*: + ``` {"stateRoot":"0xd4c577737f5d20207d338c360c42d3af78de54812720e3339f7b27293ef195b7","output":"","gasUsed":"0x3","pass":"true","time":141485} ``` ## Rationale -This EIP is largely based on the previous non-official documentation for EVM tracing. + +This EIP is largely based on the previous non-official documentation for EVM tracing. It tries to cover as many corner cases as possible to enable true client compatibility. The datatypes and if a field is optional is chosen to be as compatible with current implementations as possible. ## Backwards Compatibility + This EIP is fully backward compatible with ethereum as it only introduces a better tracing infrastructure that is optional for clients to implement. ### Clients -This EIP is fully backward compatible with go-ethereum. OpenEthereum, Besu and Nethermind clients would have to change their JSON output of `openethereum-evm` `evmtool` and `nethtest` slightly do adhere to the new and stricter specs. New clients would need to implement this change if they want to be part of the differential fuzzing group. + +This EIP is fully backward compatible with go-ethereum. OpenEthereum, Besu and Nethermind clients would have to change their JSON output of +`openethereum-evm` `evmtool` and +`nethtest` slightly do adhere to the new and stricter specs. New clients would need to implement this change if they want to be part of the differential fuzzing group. ## Test Cases @@ -151,14 +166,14 @@ ${BESU_HOME}/bin/evmtool --code 0x604080536040604055604060006040600060025afa6040 {"stateRoot":"0x8fa0dcc7f1d2383c89e5737c2843632db881c0946e80b71fe7175365e6538797","output":"0x40","gasUsed":"0x515c","pass":true,"fork":"Istanbul"} ``` - ## Security Considerations -Tracing is expensive. +Tracing is expensive. -Exposing an endpoint for creating traces publicly could open up a denial of service vector. +Exposing an endpoint for creating traces publicly could open up a denial of service vector. Clients should consider putting trace endpoints behind a separate flag from other endpoints. ## Copyright + Copyright and related rights waived via [CC0](../LICENSE.md). From 8588f8a493a420200b52439062af34d47d7b4587 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 11:56:52 -0600 Subject: [PATCH 3/5] 'standard' is a naughty word. Put it on the ~~blacklist~~ denylist. --- EIPS/eip-3155.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-3155.md b/EIPS/eip-3155.md index 0f204f67712ce..26765092c22ac 100644 --- a/EIPS/eip-3155.md +++ b/EIPS/eip-3155.md @@ -1,7 +1,7 @@ --- eip: 3155 title: EVM trace specification -description: A standard JSON format for EVM traces +description: A JSON format for EVM traces author: Martin Holst Swende (@holiman), Marius van der Wijden (@MariusVanDerWijden) discussions-to: https://ethereum-magicians.org/t/eip-3155-create-evm-trace-specification/5007 status: Last Call From 6f1d33a2559e992894077c0763bb8ec07dae515a Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 15:56:41 -0600 Subject: [PATCH 4/5] remove return stack Normative: Simple Subroutines was removed (EIP-2315) - remove unused elements. --- EIPS/eip-3155.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/EIPS/eip-3155.md b/EIPS/eip-3155.md index 26765092c22ac..ba6da2ba469da 100644 --- a/EIPS/eip-3155.md +++ b/EIPS/eip-3155.md @@ -78,7 +78,6 @@ The CUT MUST output a `json` object for EACH operation. | `error` | Hex-String | Description of an error (should contain revert reason if supported) | | `memory` | Array of Hex-Strings | Array of all allocated values | | `storage` | Key-Value | Array of all stored values | -| `returnStack` | Array of Hex-Numbers | Array of values, Stack of the called function | *Example:* @@ -87,7 +86,7 @@ The CUT MUST output a `json` object for EACH operation. ``` - The `stack`, `memory` and `memSize` are the values *before* execution of the op. -- All array attributes (`stack`, `returnStack`, `memory`) MUST be initialized to empty arrays (`"stack":[]`) NOT to null. +- All array attributes (`stack`, `memory`) MUST be initialized to empty arrays (`"stack":[]`) NOT to null. - If the CUT will not be outputting values for `memory` or `storage` then the `memory` and `storage` fields are omitted. This can happen either because the CUT does not support tracing these fields or it has been configured not to trace it. - The `memSize` field MUST be present regardless of `memory` support. From ad848618568fc62f9b22e98413a23e1bb5aab4f6 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Thu, 15 Aug 2024 12:45:04 -0400 Subject: [PATCH 5/5] Update eip-3155.md --- EIPS/eip-3155.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/EIPS/eip-3155.md b/EIPS/eip-3155.md index ba6da2ba469da..2d28a2d49f8d0 100644 --- a/EIPS/eip-3155.md +++ b/EIPS/eip-3155.md @@ -4,8 +4,7 @@ title: EVM trace specification description: A JSON format for EVM traces author: Martin Holst Swende (@holiman), Marius van der Wijden (@MariusVanDerWijden) discussions-to: https://ethereum-magicians.org/t/eip-3155-create-evm-trace-specification/5007 -status: Last Call -last-call-deadline: 2024-09-01 +status: Draft type: Standards Track category: Interface created: 2020-12-07