Closed
Description
Towards a standard EVM trace format
The purpose of this standard trace format is to facilitate automated equivalence testing of different EVM implementations.
- steps are logged with the state of the environment (stack, gas remaining, program counter, etc.) immediately before execution of the opcode.
- call stack depth starts at zero
Temporary workarounds
- steps that result in exceptions (e.g. OOG exceptions) are logged as if they were successful
- except for invalid opcode exceptions, which are not logged
- invalid opcode exception is easy to check for before execution
- it is easier to remove them from the log than to converge on a standard error code
- it is useful to see in a trace the operation that caused an OOG exception, or a stack underflow, etc.
- but it complicates the tracing logic if the result of an operation needs to be known before it is logged
- except for invalid opcode exceptions, which are not logged
Noted quirks
geth logs STOP operations on all successful exits, even when there is no STOP opcode. For example, where pyethereum logs:
TRACE:eth.vm.op {"event": "eth.vm.op.vm", "level": "TRACE", "op": "SSTORE", "stack": ["b'133001'", "b'2'"], "gas": "b'20030'", "inst": 85, "pc": "b'72'", "steps": 32, "depth": 132}
TRACE:eth.vm.exit {"event": "eth.vm.exit.exit", "level": "TRACE", "cause": "CODE OUT OF RANGE"}
geth will log:
{"pc":72,"op":85,"gas":"0x4e3e","gasCost":"0x4e20","memory":"0x","memSize":0,"stack":["0x20789","0x2"],"depth":133,"error":null,"opName":"SSTORE"}
{"pc":73,"op":0,"gas":"0x1e","gasCost":"0x0","memory":"0x","memSize":0,"stack":[],"depth":133,"error":null,"opName":"STOP"}
Example trace
This trace is produced by executing the stCallCodes/callcall_00 state test.
{'pc': 0, 'op': 96, 'gas': '0x2d74b8', 'gasCost': '0x3', 'stack': [], 'depth': 0, 'opName': 'PUSH1'}
{'pc': 2, 'op': 96, 'gas': '0x2d74b5', 'gasCost': '0x3', 'stack': ['0x40'], 'depth': 0, 'opName': 'PUSH1'}
{'pc': 4, 'op': 96, 'gas': '0x2d74b2', 'gasCost': '0x3', 'stack': ['0x40', '0x0'], 'depth': 0, 'opName': 'PUSH1'}
{'pc': 6, 'op': 96, 'gas': '0x2d74af', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40'], 'depth': 0, 'opName': 'PUSH1'}
{'pc': 8, 'op': 96, 'gas': '0x2d74ac', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40', '0x0'], 'depth': 0, 'opName': 'PUSH1'}
{'pc': 10, 'op': 115, 'gas': '0x2d74a9', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40', '0x0', '0x1'], 'depth': 0, 'opName': 'PUSH20'}
{'pc': 31, 'op': 98, 'gas': '0x2d74a6', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40', '0x0', '0x1', '0x1000000000000000000000000000000000000001'], 'depth': 0, 'opName': 'PUSH3'}
{'pc': 35, 'op': 241, 'gas': '0x2d74a3', 'gasCost': '0x57d1a', 'stack': ['0x40', '0x0', '0x40', '0x0', '0x1', '0x1000000000000000000000000000000000000001', '0x55730'], 'depth': 0, 'opName': 'CALL'}
{'pc': 0, 'op': 96, 'gas': '0x5602c', 'gasCost': '0x3', 'stack': [], 'depth': 1, 'opName': 'PUSH1'}
{'pc': 2, 'op': 96, 'gas': '0x56029', 'gasCost': '0x3', 'stack': ['0x40'], 'depth': 1, 'opName': 'PUSH1'}
{'pc': 4, 'op': 96, 'gas': '0x56026', 'gasCost': '0x3', 'stack': ['0x40', '0x0'], 'depth': 1, 'opName': 'PUSH1'}
{'pc': 6, 'op': 96, 'gas': '0x56023', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40'], 'depth': 1, 'opName': 'PUSH1'}
{'pc': 8, 'op': 96, 'gas': '0x56020', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40', '0x0'], 'depth': 1, 'opName': 'PUSH1'}
{'pc': 10, 'op': 115, 'gas': '0x5601d', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40', '0x0', '0x2'], 'depth': 1, 'opName': 'PUSH20'}
{'pc': 31, 'op': 98, 'gas': '0x5601a', 'gasCost': '0x3', 'stack': ['0x40', '0x0', '0x40', '0x0', '0x2', '0x1000000000000000000000000000000000000002'], 'depth': 1, 'opName': 'PUSH3'}
{'pc': 35, 'op': 241, 'gas': '0x56017', 'gasCost': '0x3f67a', 'stack': ['0x40', '0x0', '0x40', '0x0', '0x2', '0x1000000000000000000000000000000000000002', '0x3d090'], 'depth': 1, 'opName': 'CALL'}
{'pc': 0, 'op': 96, 'gas': '0x3d98c', 'gasCost': '0x3', 'stack': [], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 2, 'op': 96, 'gas': '0x3d989', 'gasCost': '0x3', 'stack': ['0x1'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 4, 'op': 85, 'gas': '0x3d986', 'gasCost': '0x4e20', 'stack': ['0x1', '0x2'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 5, 'op': 51, 'gas': '0x38b66', 'gasCost': '0x2', 'stack': [], 'depth': 2, 'opName': 'CALLER'}
{'pc': 6, 'op': 96, 'gas': '0x38b64', 'gasCost': '0x3', 'stack': ['0x1000000000000000000000000000000000000001'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 8, 'op': 85, 'gas': '0x38b61', 'gasCost': '0x4e20', 'stack': ['0x1000000000000000000000000000000000000001', '0x4'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 9, 'op': 52, 'gas': '0x33d41', 'gasCost': '0x2', 'stack': [], 'depth': 2, 'opName': 'CALLVALUE'}
{'pc': 10, 'op': 96, 'gas': '0x33d3f', 'gasCost': '0x3', 'stack': ['0x2'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 12, 'op': 85, 'gas': '0x33d3c', 'gasCost': '0x4e20', 'stack': ['0x2', '0x7'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 13, 'op': 48, 'gas': '0x2ef1c', 'gasCost': '0x2', 'stack': [], 'depth': 2, 'opName': 'ADDRESS'}
{'pc': 14, 'op': 96, 'gas': '0x2ef1a', 'gasCost': '0x3', 'stack': ['0x1000000000000000000000000000000000000002'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 16, 'op': 85, 'gas': '0x2ef17', 'gasCost': '0x4e20', 'stack': ['0x1000000000000000000000000000000000000002', '0xe6'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 17, 'op': 50, 'gas': '0x2a0f7', 'gasCost': '0x2', 'stack': [], 'depth': 2, 'opName': 'ORIGIN'}
{'pc': 18, 'op': 96, 'gas': '0x2a0f5', 'gasCost': '0x3', 'stack': ['0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 20, 'op': 85, 'gas': '0x2a0f2', 'gasCost': '0x4e20', 'stack': ['0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', '0xe8'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 21, 'op': 54, 'gas': '0x252d2', 'gasCost': '0x2', 'stack': [], 'depth': 2, 'opName': 'CALLDATASIZE'}
{'pc': 22, 'op': 96, 'gas': '0x252d0', 'gasCost': '0x3', 'stack': ['0x40'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 24, 'op': 85, 'gas': '0x252cd', 'gasCost': '0x4e20', 'stack': ['0x40', '0xec'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 25, 'op': 56, 'gas': '0x204ad', 'gasCost': '0x2', 'stack': [], 'depth': 2, 'opName': 'CODESIZE'}
{'pc': 26, 'op': 96, 'gas': '0x204ab', 'gasCost': '0x3', 'stack': ['0x21'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 28, 'op': 85, 'gas': '0x204a8', 'gasCost': '0x4e20', 'stack': ['0x21', '0xee'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 29, 'op': 58, 'gas': '0x1b688', 'gasCost': '0x2', 'stack': [], 'depth': 2, 'opName': 'GASPRICE'}
{'pc': 30, 'op': 96, 'gas': '0x1b686', 'gasCost': '0x3', 'stack': ['0x1'], 'depth': 2, 'opName': 'PUSH1'}
{'pc': 32, 'op': 85, 'gas': '0x1b683', 'gasCost': '0x4e20', 'stack': ['0x1', '0xf0'], 'depth': 2, 'opName': 'SSTORE'}
{'pc': 36, 'op': 96, 'gas': '0x2d200', 'gasCost': '0x3', 'stack': ['0x1'], 'depth': 1, 'opName': 'PUSH1'}
{'pc': 38, 'op': 85, 'gas': '0x2d1fd', 'gasCost': '0x4e20', 'stack': ['0x1', '0x1'], 'depth': 1, 'opName': 'SSTORE'}
{'pc': 36, 'op': 96, 'gas': '0x2a7b66', 'gasCost': '0x3', 'stack': ['0x1'], 'depth': 0, 'opName': 'PUSH1'}
{'pc': 38, 'op': 85, 'gas': '0x2a7b63', 'gasCost': '0x4e20', 'stack': ['0x1', '0x0'], 'depth': 0, 'opName': 'SSTORE'}
{"output":"","gasUsed":"0x34775","time":1967173}