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

towards a standard EVM trace format #249

Open
cdetrio opened this Issue Aug 4, 2017 · 33 comments

Comments

Projects
None yet
7 participants
@cdetrio
Member

cdetrio commented Aug 4, 2017

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

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}
@debris

This comment has been minimized.

Show comment
Hide comment
@debris

debris Aug 5, 2017

Contributor

I like the idea of standarization very much! 👍

But if we are about to do that, there can't be any temporary workarounds. Can't a single operation result in two logs? One created before operation execution with the operation itself and the other one with result of the operation.

Contributor

debris commented Aug 5, 2017

I like the idea of standarization very much! 👍

But if we are about to do that, there can't be any temporary workarounds. Can't a single operation result in two logs? One created before operation execution with the operation itself and the other one with result of the operation.

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Aug 8, 2017

Member

@debris this is to document a work-in-progress, so hopefully it will see incremental improvement.

If a single operation resulted in two logs, lots of information would be duplicated. I do like the idea of an error field, which would tell whether an operation failed due to an OOG or some other exception. But that would complicate the tracing logic quite a bit, and it would be non-trivial to implement in the clients I've worked with so far. Maybe if the failed operations are logged twice (the second with the failure) it would be easier for clients to implement?

Member

cdetrio commented Aug 8, 2017

@debris this is to document a work-in-progress, so hopefully it will see incremental improvement.

If a single operation resulted in two logs, lots of information would be duplicated. I do like the idea of an error field, which would tell whether an operation failed due to an OOG or some other exception. But that would complicate the tracing logic quite a bit, and it would be non-trivial to implement in the clients I've worked with so far. Maybe if the failed operations are logged twice (the second with the failure) it would be easier for clients to implement?

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio
Member

cdetrio commented Aug 8, 2017

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Aug 8, 2017

Contributor

Can you describe what data is logged? Is logging the stack and memory feasible?

Contributor

chfast commented Aug 8, 2017

Can you describe what data is logged? Is logging the stack and memory feasible?

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Aug 8, 2017

Member

The stack is logged on every step. Logging the memory should be feasible, but at the moment its not included in the equivalence test.

Member

cdetrio commented Aug 8, 2017

The stack is logged on every step. Logging the memory should be feasible, but at the moment its not included in the equivalence test.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Aug 8, 2017

Contributor

Full stack is logged or only the changes?
I need to design the VM trace API. Dumping full stack and memory every step seems like a waste of resources. The listener can reconstruct the stack and the memory on its own.

Contributor

chfast commented Aug 8, 2017

Full stack is logged or only the changes?
I need to design the VM trace API. Dumping full stack and memory every step seems like a waste of resources. The listener can reconstruct the stack and the memory on its own.

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Aug 8, 2017

Member

The full stack is logged. I agree that just the changes would be more compact.

Member

cdetrio commented Aug 8, 2017

The full stack is logged. I agree that just the changes would be more compact.

@gcolvin

This comment has been minimized.

Show comment
Hide comment
@gcolvin

gcolvin Aug 9, 2017

There is always a STOP opcode, if you count the virtual extension of the code with an indefinite number of zeros. So geth may be right. I suspect eth will also report a STOP for that reason, but am on the road and can't check the code right now.

gcolvin commented Aug 9, 2017

There is always a STOP opcode, if you count the virtual extension of the code with an indefinite number of zeros. So geth may be right. I suspect eth will also report a STOP for that reason, but am on the road and can't check the code right now.

@gcolvin

This comment has been minimized.

Show comment
Hide comment
@gcolvin

gcolvin Aug 9, 2017

Yes, logging the full stack is horrible. For eth the stack grows towards low addresses, so the code has to copy it all out backwards. Only the changes should be logged.

gcolvin commented Aug 9, 2017

Yes, logging the full stack is horrible. For eth the stack grows towards low addresses, so the code has to copy it all out backwards. Only the changes should be logged.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Aug 18, 2017

Contributor

VM trace data:

  1. pc int64 (aka instruction counter) -- number of instructions executed so far in the current call.
  2. opcode int64 -- the numeric id of the opcode to be executed.
  3. depth int64 -- the current call depth, starting with 0.
  4. gas int64 -- the current value of the gas counter. Descending.
  5. opcode gas cost int64 -- the full cost of executing the current opcode (including memory costs).
  6. result int256be -- the result put on stack after the execution of the opcode.
  7. error code int64 -- the information about the failure of execution of the current opcode.
  8. memory size int64 -- the current size of the memory.
  9. pointer to memory void* -- the pointer to the memory.
  10. opcode offset int64 -- the offset of the opcode in the code.

Notes:

  • (6) and (7) are hard to do, especially when the current opcode is CALL-like.
  • Knowing the gas cost (5) up front for CREATE is impossible. For calls we can assume max cost?
  • Instead of dumping the full stack, it is enough to show only the results of opcodes. The listener can reconstruct the full stack on its own.
  • Instead of the result (6) we can dump the top stack item. This would be relevant to the previous opcode.
  • In (9) we can allow the listener to read the parts of the memory it wants to (based on the memory size (8)). But this might be too intrusive and assumes memory is continuous. Maybe make this param optional?
Contributor

chfast commented Aug 18, 2017

VM trace data:

  1. pc int64 (aka instruction counter) -- number of instructions executed so far in the current call.
  2. opcode int64 -- the numeric id of the opcode to be executed.
  3. depth int64 -- the current call depth, starting with 0.
  4. gas int64 -- the current value of the gas counter. Descending.
  5. opcode gas cost int64 -- the full cost of executing the current opcode (including memory costs).
  6. result int256be -- the result put on stack after the execution of the opcode.
  7. error code int64 -- the information about the failure of execution of the current opcode.
  8. memory size int64 -- the current size of the memory.
  9. pointer to memory void* -- the pointer to the memory.
  10. opcode offset int64 -- the offset of the opcode in the code.

Notes:

  • (6) and (7) are hard to do, especially when the current opcode is CALL-like.
  • Knowing the gas cost (5) up front for CREATE is impossible. For calls we can assume max cost?
  • Instead of dumping the full stack, it is enough to show only the results of opcodes. The listener can reconstruct the full stack on its own.
  • Instead of the result (6) we can dump the top stack item. This would be relevant to the previous opcode.
  • In (9) we can allow the listener to read the parts of the memory it wants to (based on the memory size (8)). But this might be too intrusive and assumes memory is continuous. Maybe make this param optional?
@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Aug 18, 2017

Member

pc int64 (aka instruction counter)

I think it would make sense naming it differently since usually pc (program counter) refers to the byte offset.

gas int64 -- the current value of the gas counter. Descending.

Would name it gas left or gas remaining.

Member

axic commented Aug 18, 2017

pc int64 (aka instruction counter)

I think it would make sense naming it differently since usually pc (program counter) refers to the byte offset.

gas int64 -- the current value of the gas counter. Descending.

Would name it gas left or gas remaining.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Aug 21, 2017

Contributor

I think I confused pc. In C++ there are steps and pc being the current opcode index in the code. I agree PC is bad name, probably meaningful only for devs ever touching assembly.

Contributor

chfast commented Aug 21, 2017

I think I confused pc. In C++ there are steps and pc being the current opcode index in the code. I agree PC is bad name, probably meaningful only for devs ever touching assembly.

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Aug 21, 2017

Member

How about instead of the flat stack array:

stack: {
  removed: <count>
  inserted: [] // items inserted, first item is the top item on the stack
}
Member

axic commented Aug 21, 2017

How about instead of the flat stack array:

stack: {
  removed: <count>
  inserted: [] // items inserted, first item is the top item on the stack
}
@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Aug 21, 2017

Member

Please specify how the values are represented:

  • which values are represented as numbers in JSON and which as strings
  • include zero padding in hexadecimals or truncate them (in this case: truncate to nibbles or not?)
  • include the 0x prefix in or not
Member

axic commented Aug 21, 2017

Please specify how the values are represented:

  • which values are represented as numbers in JSON and which as strings
  • include zero padding in hexadecimals or truncate them (in this case: truncate to nibbles or not?)
  • include the 0x prefix in or not
@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Sep 21, 2017

Member

Note that the "standardized trace" now also logs a stateRoot at the end of the trace. Here's an example from a cpp-ethereum trace for stZeroKnowledge/ecmul_0-3_9_21000_96:

{'depth': '0', 'gas': '21000', 'gasCost': '3', 'memory': [], 'op': 'PUSH1', 'pc': '0', 'stack': []}
{'depth': '0', 'gas': '20997', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '2', 'stack': ['0x00']}
{'depth': '0', 'gas': '20994', 'gasCost': '3', 'op': 'PUSH1', 'pc': '3', 'stack': ['0x30c8d1da00000000000000000000000000000000000000000000000000000000']}
{'depth': '0', 'gas': '20991', 'gasCost': '3', 'op': 'MSTORE', 'pc': '5', 'stack': ['0x30c8d1da00000000000000000000000000000000000000000000000000000000', '0x1c']}
{'depth': '0', 'gas': '20982', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000000000000000000000000000000000000000000000'], 'op': 'PUSH21', 'pc': '6', 'stack': []}
{'depth': '0', 'gas': '20979', 'gasCost': '3', 'op': 'PUSH1', 'pc': '28', 'stack': ['0x010000000000000000000000000000000000000000']}
{'depth': '0', 'gas': '20976', 'gasCost': '3', 'op': 'MSTORE', 'pc': '30', 'stack': ['0x010000000000000000000000000000000000000000', '0x20']}
{'depth': '0', 'gas': '20973', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000'], 'op': 'PUSH16', 'pc': '31', 'stack': []}
{'depth': '0', 'gas': '20970', 'gasCost': '3', 'op': 'PUSH1', 'pc': '48', 'stack': ['0xffffffffffffffffffffffffffffffff']}
{'depth': '0', 'gas': '20967', 'gasCost': '3', 'op': 'MSTORE', 'pc': '50', 'stack': ['0xffffffffffffffffffffffffffffffff', '0x40']}
{'depth': '0', 'gas': '20961', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff'], 'op': 'PUSH32', 'pc': '51', 'stack': []}
{'depth': '0', 'gas': '20958', 'gasCost': '3', 'op': 'PUSH1', 'pc': '84', 'stack': ['0xffffffffffffffffffffffffffffffff00000000000000000000000000000001']}
{'depth': '0', 'gas': '20955', 'gasCost': '3', 'op': 'MSTORE', 'pc': '86', 'stack': ['0xffffffffffffffffffffffffffffffff00000000000000000000000000000001', '0x60']}
{'depth': '0', 'gas': '20949', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001'], 'op': 'PUSH21', 'pc': '87', 'stack': []}
{'depth': '0', 'gas': '20946', 'gasCost': '3', 'op': 'PUSH1', 'pc': '109', 'stack': ['0x02540be3fffffffffffffffffffffffffdabf41c00']}
{'depth': '0', 'gas': '20943', 'gasCost': '3', 'op': 'MSTORE', 'pc': '111', 'stack': ['0x02540be3fffffffffffffffffffffffffdabf41c00', '0x80']}
{'depth': '0', 'gas': '20937', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00'], 'op': 'PUSH32', 'pc': '112', 'stack': []}
{'depth': '0', 'gas': '20934', 'gasCost': '3', 'op': 'PUSH1', 'pc': '145', 'stack': ['0xfffffffffffffffffffffffdabf41c00000000000000000000000002540be400']}
{'depth': '0', 'gas': '20931', 'gasCost': '3', 'op': 'MSTORE', 'pc': '147', 'stack': ['0xfffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0xa0']}
{'depth': '0', 'gas': '20925', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400'], 'op': 'PUSH4', 'pc': '148', 'stack': []}
{'depth': '0', 'gas': '20922', 'gasCost': '3', 'op': 'PUSH1', 'pc': '153', 'stack': ['0x30c8d1da']}
{'depth': '0', 'gas': '20919', 'gasCost': '3', 'op': 'MLOAD', 'pc': '155', 'stack': ['0x30c8d1da', '0x00']}
{'depth': '0', 'gas': '20916', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400'], 'op': 'EQ', 'pc': '156', 'stack': ['0x30c8d1da', '0x30c8d1da']}
{'depth': '0', 'gas': '20913', 'gasCost': '3', 'op': 'ISZERO', 'pc': '157', 'stack': ['0x01']}
{'depth': '0', 'gas': '20910', 'gasCost': '3', 'op': 'PUSH2', 'pc': '158', 'stack': ['0x00']}
{'depth': '0', 'gas': '20907', 'gasCost': '10', 'op': 'JUMPI', 'pc': '161', 'stack': ['0x00', '0x012b']}
{'depth': '0', 'gas': '20897', 'gasCost': '3', 'op': 'PUSH1', 'pc': '162', 'stack': []}
{'depth': '0', 'gas': '20894', 'gasCost': '3', 'op': 'PUSH1', 'pc': '164', 'stack': ['0xc0']}
{'depth': '0', 'gas': '20891', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '166', 'stack': ['0xc0', '0x04']}
{'depth': '0', 'gas': '20888', 'gasCost': '3', 'op': 'PUSH1', 'pc': '167', 'stack': ['0xc0', '0x20']}
{'depth': '0', 'gas': '20885', 'gasCost': '3', 'op': 'ADD', 'pc': '169', 'stack': ['0xc0', '0x20', '0x04']}
{'depth': '0', 'gas': '20882', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '170', 'stack': ['0xc0', '0x24']}
{'depth': '0', 'gas': '20879', 'gasCost': '3', 'op': 'GT', 'pc': '171', 'stack': ['0xc0', '0x60']}
{'depth': '0', 'gas': '20876', 'gasCost': '3', 'op': 'ISZERO', 'pc': '172', 'stack': ['0x00']}
{'depth': '0', 'gas': '20873', 'gasCost': '3', 'op': 'ISZERO', 'pc': '173', 'stack': ['0x01']}
{'depth': '0', 'gas': '20870', 'gasCost': '2', 'op': 'PC', 'pc': '174', 'stack': ['0x00']}
{'depth': '0', 'gas': '20868', 'gasCost': '10', 'op': 'JUMPI', 'pc': '175', 'stack': ['0x00', '0xae']}
{'depth': '0', 'gas': '20858', 'gasCost': '3', 'op': 'PUSH1', 'pc': '176', 'stack': []}
{'depth': '0', 'gas': '20855', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '178', 'stack': ['0x04']}
{'depth': '0', 'gas': '20852', 'gasCost': '3', 'op': 'PUSH1', 'pc': '179', 'stack': ['0x20']}
{'depth': '0', 'gas': '20849', 'gasCost': '3', 'op': 'ADD', 'pc': '181', 'stack': ['0x20', '0x04']}
{'depth': '0', 'gas': '20846', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '182', 'stack': ['0x24']}
{'depth': '0', 'gas': '20843', 'gasCost': '3', 'op': 'PUSH1', 'pc': '183', 'stack': ['0x60']}
{'depth': '0', 'gas': '20840', 'gasCost': '3', 'op': 'ADD', 'pc': '185', 'stack': ['0x60', '0x20']}
{'depth': '0', 'gas': '20837', 'gasCost': '3', 'op': 'PUSH1', 'pc': '186', 'stack': ['0x80']}
{'depth': '0', 'gas': '20834', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '188', 'stack': ['0x80', '0x04']}
{'depth': '0', 'gas': '20831', 'gasCost': '3', 'op': 'PUSH1', 'pc': '189', 'stack': ['0x80', '0x20']}
{'depth': '0', 'gas': '20828', 'gasCost': '3', 'op': 'ADD', 'pc': '191', 'stack': ['0x80', '0x20', '0x04']}
{'depth': '0', 'gas': '20825', 'gasCost': '3', 'op': 'PUSH2', 'pc': '192', 'stack': ['0x80', '0x24']}
{'depth': '0', 'gas': '20822', 'gasCost': '3', 'op': 'CALLDATACOPY', 'pc': '195', 'stack': ['0x80', '0x24', '0x0140']}
{'depth': '0', 'gas': '20783', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000060', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000003', '0000000000000000000000000000000000000000000000000000000000000009'], 'op': 'PUSH1', 'pc': '196', 'stack': []}
{'depth': '0', 'gas': '20780', 'gasCost': '3', 'op': 'PUSH2', 'pc': '198', 'stack': ['0x40']}
{'depth': '0', 'gas': '20777', 'gasCost': '3', 'op': 'PUSH2', 'pc': '201', 'stack': ['0x40', '0x0260']}
{'depth': '0', 'gas': '20774', 'gasCost': '3', 'op': 'MLOAD', 'pc': '204', 'stack': ['0x40', '0x0260', '0x0140']}
{'depth': '0', 'gas': '20771', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000060', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000003', '0000000000000000000000000000000000000000000000000000000000000009'], 'op': 'PUSH2', 'pc': '205', 'stack': ['0x40', '0x0260', '0x60']}
{'depth': '0', 'gas': '20768', 'gasCost': '3', 'op': 'PUSH1', 'pc': '208', 'stack': ['0x40', '0x0260', '0x60', '0x0160']}
{'depth': '0', 'gas': '20765', 'gasCost': '3', 'op': 'PUSH1', 'pc': '210', 'stack': ['0x40', '0x0260', '0x60', '0x0160', '0x00']}
{'depth': '0', 'gas': '20762', 'gasCost': '3', 'op': 'PUSH4', 'pc': '212', 'stack': ['0x40', '0x0260', '0x60', '0x0160', '0x00', '0x07']}
{'depth': '0', 'gas': '20759', 'gasCost': '0', 'op': 'CALL', 'pc': '217', 'stack': ['0x40', '0x0260', '0x60', '0x0160', '0x00', '0x07', '0x05f5e0ff']}
{'depth': '0', 'gas': '313', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000060', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000003', '0000000000000000000000000000000000000000000000000000000000000009', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000'], 'op': 'ISZERO', 'pc': '218', 'stack': ['0x00']}
{'depth': '0', 'gas': '310', 'gasCost': '2', 'op': 'PC', 'pc': '219', 'stack': ['0x01']}
{'depth': '0', 'gas': '308', 'gasCost': '10', 'op': 'JUMPI', 'pc': '220', 'stack': ['0x01', '0xdb']}
{'stateRoot': '618a348e7107ef322cd234fb11ab7c60f1cdb52278a0a29d1d14cb6788f55298'}
Member

cdetrio commented Sep 21, 2017

Note that the "standardized trace" now also logs a stateRoot at the end of the trace. Here's an example from a cpp-ethereum trace for stZeroKnowledge/ecmul_0-3_9_21000_96:

{'depth': '0', 'gas': '21000', 'gasCost': '3', 'memory': [], 'op': 'PUSH1', 'pc': '0', 'stack': []}
{'depth': '0', 'gas': '20997', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '2', 'stack': ['0x00']}
{'depth': '0', 'gas': '20994', 'gasCost': '3', 'op': 'PUSH1', 'pc': '3', 'stack': ['0x30c8d1da00000000000000000000000000000000000000000000000000000000']}
{'depth': '0', 'gas': '20991', 'gasCost': '3', 'op': 'MSTORE', 'pc': '5', 'stack': ['0x30c8d1da00000000000000000000000000000000000000000000000000000000', '0x1c']}
{'depth': '0', 'gas': '20982', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000000000000000000000000000000000000000000000'], 'op': 'PUSH21', 'pc': '6', 'stack': []}
{'depth': '0', 'gas': '20979', 'gasCost': '3', 'op': 'PUSH1', 'pc': '28', 'stack': ['0x010000000000000000000000000000000000000000']}
{'depth': '0', 'gas': '20976', 'gasCost': '3', 'op': 'MSTORE', 'pc': '30', 'stack': ['0x010000000000000000000000000000000000000000', '0x20']}
{'depth': '0', 'gas': '20973', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000'], 'op': 'PUSH16', 'pc': '31', 'stack': []}
{'depth': '0', 'gas': '20970', 'gasCost': '3', 'op': 'PUSH1', 'pc': '48', 'stack': ['0xffffffffffffffffffffffffffffffff']}
{'depth': '0', 'gas': '20967', 'gasCost': '3', 'op': 'MSTORE', 'pc': '50', 'stack': ['0xffffffffffffffffffffffffffffffff', '0x40']}
{'depth': '0', 'gas': '20961', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff'], 'op': 'PUSH32', 'pc': '51', 'stack': []}
{'depth': '0', 'gas': '20958', 'gasCost': '3', 'op': 'PUSH1', 'pc': '84', 'stack': ['0xffffffffffffffffffffffffffffffff00000000000000000000000000000001']}
{'depth': '0', 'gas': '20955', 'gasCost': '3', 'op': 'MSTORE', 'pc': '86', 'stack': ['0xffffffffffffffffffffffffffffffff00000000000000000000000000000001', '0x60']}
{'depth': '0', 'gas': '20949', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001'], 'op': 'PUSH21', 'pc': '87', 'stack': []}
{'depth': '0', 'gas': '20946', 'gasCost': '3', 'op': 'PUSH1', 'pc': '109', 'stack': ['0x02540be3fffffffffffffffffffffffffdabf41c00']}
{'depth': '0', 'gas': '20943', 'gasCost': '3', 'op': 'MSTORE', 'pc': '111', 'stack': ['0x02540be3fffffffffffffffffffffffffdabf41c00', '0x80']}
{'depth': '0', 'gas': '20937', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00'], 'op': 'PUSH32', 'pc': '112', 'stack': []}
{'depth': '0', 'gas': '20934', 'gasCost': '3', 'op': 'PUSH1', 'pc': '145', 'stack': ['0xfffffffffffffffffffffffdabf41c00000000000000000000000002540be400']}
{'depth': '0', 'gas': '20931', 'gasCost': '3', 'op': 'MSTORE', 'pc': '147', 'stack': ['0xfffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0xa0']}
{'depth': '0', 'gas': '20925', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400'], 'op': 'PUSH4', 'pc': '148', 'stack': []}
{'depth': '0', 'gas': '20922', 'gasCost': '3', 'op': 'PUSH1', 'pc': '153', 'stack': ['0x30c8d1da']}
{'depth': '0', 'gas': '20919', 'gasCost': '3', 'op': 'MLOAD', 'pc': '155', 'stack': ['0x30c8d1da', '0x00']}
{'depth': '0', 'gas': '20916', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400'], 'op': 'EQ', 'pc': '156', 'stack': ['0x30c8d1da', '0x30c8d1da']}
{'depth': '0', 'gas': '20913', 'gasCost': '3', 'op': 'ISZERO', 'pc': '157', 'stack': ['0x01']}
{'depth': '0', 'gas': '20910', 'gasCost': '3', 'op': 'PUSH2', 'pc': '158', 'stack': ['0x00']}
{'depth': '0', 'gas': '20907', 'gasCost': '10', 'op': 'JUMPI', 'pc': '161', 'stack': ['0x00', '0x012b']}
{'depth': '0', 'gas': '20897', 'gasCost': '3', 'op': 'PUSH1', 'pc': '162', 'stack': []}
{'depth': '0', 'gas': '20894', 'gasCost': '3', 'op': 'PUSH1', 'pc': '164', 'stack': ['0xc0']}
{'depth': '0', 'gas': '20891', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '166', 'stack': ['0xc0', '0x04']}
{'depth': '0', 'gas': '20888', 'gasCost': '3', 'op': 'PUSH1', 'pc': '167', 'stack': ['0xc0', '0x20']}
{'depth': '0', 'gas': '20885', 'gasCost': '3', 'op': 'ADD', 'pc': '169', 'stack': ['0xc0', '0x20', '0x04']}
{'depth': '0', 'gas': '20882', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '170', 'stack': ['0xc0', '0x24']}
{'depth': '0', 'gas': '20879', 'gasCost': '3', 'op': 'GT', 'pc': '171', 'stack': ['0xc0', '0x60']}
{'depth': '0', 'gas': '20876', 'gasCost': '3', 'op': 'ISZERO', 'pc': '172', 'stack': ['0x00']}
{'depth': '0', 'gas': '20873', 'gasCost': '3', 'op': 'ISZERO', 'pc': '173', 'stack': ['0x01']}
{'depth': '0', 'gas': '20870', 'gasCost': '2', 'op': 'PC', 'pc': '174', 'stack': ['0x00']}
{'depth': '0', 'gas': '20868', 'gasCost': '10', 'op': 'JUMPI', 'pc': '175', 'stack': ['0x00', '0xae']}
{'depth': '0', 'gas': '20858', 'gasCost': '3', 'op': 'PUSH1', 'pc': '176', 'stack': []}
{'depth': '0', 'gas': '20855', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '178', 'stack': ['0x04']}
{'depth': '0', 'gas': '20852', 'gasCost': '3', 'op': 'PUSH1', 'pc': '179', 'stack': ['0x20']}
{'depth': '0', 'gas': '20849', 'gasCost': '3', 'op': 'ADD', 'pc': '181', 'stack': ['0x20', '0x04']}
{'depth': '0', 'gas': '20846', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '182', 'stack': ['0x24']}
{'depth': '0', 'gas': '20843', 'gasCost': '3', 'op': 'PUSH1', 'pc': '183', 'stack': ['0x60']}
{'depth': '0', 'gas': '20840', 'gasCost': '3', 'op': 'ADD', 'pc': '185', 'stack': ['0x60', '0x20']}
{'depth': '0', 'gas': '20837', 'gasCost': '3', 'op': 'PUSH1', 'pc': '186', 'stack': ['0x80']}
{'depth': '0', 'gas': '20834', 'gasCost': '3', 'op': 'CALLDATALOAD', 'pc': '188', 'stack': ['0x80', '0x04']}
{'depth': '0', 'gas': '20831', 'gasCost': '3', 'op': 'PUSH1', 'pc': '189', 'stack': ['0x80', '0x20']}
{'depth': '0', 'gas': '20828', 'gasCost': '3', 'op': 'ADD', 'pc': '191', 'stack': ['0x80', '0x20', '0x04']}
{'depth': '0', 'gas': '20825', 'gasCost': '3', 'op': 'PUSH2', 'pc': '192', 'stack': ['0x80', '0x24']}
{'depth': '0', 'gas': '20822', 'gasCost': '3', 'op': 'CALLDATACOPY', 'pc': '195', 'stack': ['0x80', '0x24', '0x0140']}
{'depth': '0', 'gas': '20783', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000060', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000003', '0000000000000000000000000000000000000000000000000000000000000009'], 'op': 'PUSH1', 'pc': '196', 'stack': []}
{'depth': '0', 'gas': '20780', 'gasCost': '3', 'op': 'PUSH2', 'pc': '198', 'stack': ['0x40']}
{'depth': '0', 'gas': '20777', 'gasCost': '3', 'op': 'PUSH2', 'pc': '201', 'stack': ['0x40', '0x0260']}
{'depth': '0', 'gas': '20774', 'gasCost': '3', 'op': 'MLOAD', 'pc': '204', 'stack': ['0x40', '0x0260', '0x0140']}
{'depth': '0', 'gas': '20771', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000060', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000003', '0000000000000000000000000000000000000000000000000000000000000009'], 'op': 'PUSH2', 'pc': '205', 'stack': ['0x40', '0x0260', '0x60']}
{'depth': '0', 'gas': '20768', 'gasCost': '3', 'op': 'PUSH1', 'pc': '208', 'stack': ['0x40', '0x0260', '0x60', '0x0160']}
{'depth': '0', 'gas': '20765', 'gasCost': '3', 'op': 'PUSH1', 'pc': '210', 'stack': ['0x40', '0x0260', '0x60', '0x0160', '0x00']}
{'depth': '0', 'gas': '20762', 'gasCost': '3', 'op': 'PUSH4', 'pc': '212', 'stack': ['0x40', '0x0260', '0x60', '0x0160', '0x00', '0x07']}
{'depth': '0', 'gas': '20759', 'gasCost': '0', 'op': 'CALL', 'pc': '217', 'stack': ['0x40', '0x0260', '0x60', '0x0160', '0x00', '0x07', '0x05f5e0ff']}
{'depth': '0', 'gas': '313', 'gasCost': '3', 'memory': ['0000000000000000000000000000000000000000000000000000000030c8d1da', '0000000000000000000000010000000000000000000000000000000000000000', '00000000000000000000000000000000ffffffffffffffffffffffffffffffff', 'ffffffffffffffffffffffffffffffff00000000000000000000000000000001', '000000000000000000000002540be3fffffffffffffffffffffffffdabf41c00', 'fffffffffffffffffffffffdabf41c00000000000000000000000002540be400', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000060', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000003', '0000000000000000000000000000000000000000000000000000000000000009', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000000000000000000000000000000000000000000000000000'], 'op': 'ISZERO', 'pc': '218', 'stack': ['0x00']}
{'depth': '0', 'gas': '310', 'gasCost': '2', 'op': 'PC', 'pc': '219', 'stack': ['0x01']}
{'depth': '0', 'gas': '308', 'gasCost': '10', 'op': 'JUMPI', 'pc': '220', 'stack': ['0x01', '0xdb']}
{'stateRoot': '618a348e7107ef322cd234fb11ab7c60f1cdb52278a0a29d1d14cb6788f55298'}
@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Sep 22, 2017

Contributor

Because the the step report describes the EVM state before the opcode execution:

  1. Can we report consumed stack items instead of full stack?
  2. How do you want to report calls, in particular the CALL gas cost?
Contributor

chfast commented Sep 22, 2017

Because the the step report describes the EVM state before the opcode execution:

  1. Can we report consumed stack items instead of full stack?
  2. How do you want to report calls, in particular the CALL gas cost?
@gcolvin

This comment has been minimized.

Show comment
Hide comment
@gcolvin

gcolvin Sep 26, 2017

I still want very much to report only changes to the stack.

gcolvin commented Sep 26, 2017

I still want very much to report only changes to the stack.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Oct 2, 2017

Contributor

If the execution of an instruction will cause OOG, should this instruction still be reported in the trace as the last step?

Contributor

chfast commented Oct 2, 2017

If the execution of an instruction will cause OOG, should this instruction still be reported in the trace as the last step?

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Oct 6, 2017

Member

@chfast I think so, yes. instructions are logged before execution, whether the last step in the call depth (if the call OOGs), or the last step in the whole trace.

Member

cdetrio commented Oct 6, 2017

@chfast I think so, yes. instructions are logged before execution, whether the last step in the call depth (if the call OOGs), or the last step in the whole trace.

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Oct 6, 2017

Member
  1. Can we report consumed stack items instead of full stack?

@chfast sure, feel free to prototype this.

  1. How do you want to report calls, in particular the CALL gas cost?

I'm not sure its worth the trouble to log the gas cost of a step/instruction, since it can be calculated anyway from the difference in gas remaining between two steps. Currently for equivalence testing, we don't use the gas cost of a step that some clients include in the trace. We only use gas remaining.

Member

cdetrio commented Oct 6, 2017

  1. Can we report consumed stack items instead of full stack?

@chfast sure, feel free to prototype this.

  1. How do you want to report calls, in particular the CALL gas cost?

I'm not sure its worth the trouble to log the gas cost of a step/instruction, since it can be calculated anyway from the difference in gas remaining between two steps. Currently for equivalence testing, we don't use the gas cost of a step that some clients include in the trace. We only use gas remaining.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Oct 8, 2017

Contributor

@cdetrio, ok, but "gas remaining" should also be lowered by the cost of the just-to-be-executed instruction. So in case of an instruction resulting in OOG, the gas remaining must be negative. And in case of a call, we don't know the cost up front, so we only can take the "gas" argument of the call into consideration (C++ does it this way - a call cost it the basic CALL instruction cost + value transfer penalty + account creation penalty + the gas argument value).

Contributor

chfast commented Oct 8, 2017

@cdetrio, ok, but "gas remaining" should also be lowered by the cost of the just-to-be-executed instruction. So in case of an instruction resulting in OOG, the gas remaining must be negative. And in case of a call, we don't know the cost up front, so we only can take the "gas" argument of the call into consideration (C++ does it this way - a call cost it the basic CALL instruction cost + value transfer penalty + account creation penalty + the gas argument value).

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Oct 8, 2017

Member

Each step is logged with all values just before the execution, so the gas remaining should never be negative.

Member

cdetrio commented Oct 8, 2017

Each step is logged with all values just before the execution, so the gas remaining should never be negative.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Oct 9, 2017

Contributor

So in case an instruction is causing an exception, this step is not logged?

Contributor

chfast commented Oct 9, 2017

So in case an instruction is causing an exception, this step is not logged?

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Oct 9, 2017

Member

@chfast The only exception is invalid opcode steps, technically these could be logged too but currently they're filtered from the canonicalized trace (before doing the equivalence comparison check, for fuzz testing). This helps accommodate clients that don't log invalid opcodes, or that only log a generic exception but not the opcode itself. I can't remember which client (maybe pyeth).

All other steps (those with valid opcodes) are logged before execution. Also, the exceptions themselves are not explicitly logged (if a client does log exceptions, then its filtered when converting to the canonicalized trace). So where exceptions occur has to be deduced from the trace (e.g. by checking gas remaining where call depth decreases). Not labeling steps that cause exceptions is kind of annoying when reading a (canonicalized) trace, but for the purpose of equivalence fuzz testing its sufficient to just compare all steps without explicitly labeling where exceptions occur.

Member

cdetrio commented Oct 9, 2017

@chfast The only exception is invalid opcode steps, technically these could be logged too but currently they're filtered from the canonicalized trace (before doing the equivalence comparison check, for fuzz testing). This helps accommodate clients that don't log invalid opcodes, or that only log a generic exception but not the opcode itself. I can't remember which client (maybe pyeth).

All other steps (those with valid opcodes) are logged before execution. Also, the exceptions themselves are not explicitly logged (if a client does log exceptions, then its filtered when converting to the canonicalized trace). So where exceptions occur has to be deduced from the trace (e.g. by checking gas remaining where call depth decreases). Not labeling steps that cause exceptions is kind of annoying when reading a (canonicalized) trace, but for the purpose of equivalence fuzz testing its sufficient to just compare all steps without explicitly labeling where exceptions occur.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast Oct 11, 2017

Contributor

I think the term "just before execution" is a bit misleading. So in case of PUSH0 SLOAD with 100 units of gas the trace will be:

PUSH, gas remaining: 99

not

PUSH, gas remaining: 99
SLOAD, gas remaining: -101, status: OOG
Contributor

chfast commented Oct 11, 2017

I think the term "just before execution" is a bit misleading. So in case of PUSH0 SLOAD with 100 units of gas the trace will be:

PUSH, gas remaining: 99

not

PUSH, gas remaining: 99
SLOAD, gas remaining: -101, status: OOG
@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Oct 11, 2017

Member

@chfast the trace would be

PUSH, gas remaining: 100
SLOAD, gas remaining: 99

because on each step, its the gas remaining before execution and before gas deduction.

Member

cdetrio commented Oct 11, 2017

@chfast the trace would be

PUSH, gas remaining: 100
SLOAD, gas remaining: 99

because on each step, its the gas remaining before execution and before gas deduction.

@cdetrio

This comment has been minimized.

Show comment
Hide comment
@cdetrio

cdetrio Nov 19, 2017

Member

The json trace output from clients should be JSONL (JSON Lines).

Member

cdetrio commented Nov 19, 2017

The json trace output from clients should be JSONL (JSON Lines).

@pirapira

This comment has been minimized.

Show comment
Hide comment
@pirapira

pirapira Apr 20, 2018

Member

@winsvega perhaps retesteth should call debug_trace methods and check the format of the trace.

Member

pirapira commented Apr 20, 2018

@winsvega perhaps retesteth should call debug_trace methods and check the format of the trace.

@winsvega

This comment has been minimized.

Show comment
Hide comment
@winsvega

winsvega Apr 20, 2018

Contributor

you mean compare logs instead of root hashes?

Contributor

winsvega commented Apr 20, 2018

you mean compare logs instead of root hashes?

@pirapira

This comment has been minimized.

Show comment
Hide comment
@pirapira

pirapira Apr 23, 2018

Member

I suggested adding a new kind of test. I did not suggest replacing any existing tests that compare root hashes.

Member

pirapira commented Apr 23, 2018

I suggested adding a new kind of test. I did not suggest replacing any existing tests that compare root hashes.

@winsvega

This comment has been minimized.

Show comment
Hide comment
@winsvega

winsvega Apr 23, 2018

Contributor

the goal is actually to get rid of different test types and come to a general test format.

Contributor

winsvega commented Apr 23, 2018

the goal is actually to get rid of different test types and come to a general test format.

@pirapira

This comment has been minimized.

Show comment
Hide comment
@pirapira

pirapira Apr 23, 2018

Member

@winsvega please use a separate GitHub issue for the most general test format.

Member

pirapira commented Apr 23, 2018

@winsvega please use a separate GitHub issue for the most general test format.

@chfast

This comment has been minimized.

Show comment
Hide comment
@chfast

chfast May 11, 2018

Contributor

@cdetrio @holiman I'm back to this issue because I want finally to implement this in EVMC.

I still believe it would be more convenient to report the effect of the instruction execution, not the state before the execution. In this case it might be enough to only report the top stack item being the result of the execution of the current opcode. Also the cost of the execution and exceptions can be reported.

Contributor

chfast commented May 11, 2018

@cdetrio @holiman I'm back to this issue because I want finally to implement this in EVMC.

I still believe it would be more convenient to report the effect of the instruction execution, not the state before the execution. In this case it might be enough to only report the top stack item being the result of the execution of the current opcode. Also the cost of the execution and exceptions can be reported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment