debug_traceTransaction endpoint implementation
What was wrong?
There was no way to trace transactions in py-evm
How was it fixed?
A basic tracing support was added.
Description
New functionality is based on a go-ethereum's debug_traceTransaction logic (https://github.com/ethereum/go-ethereum/wiki/Tracing:-Introduction). Only basic parts were ported so far (e.g. no JS tracers support). Closes issue #62.
List of open questions to discuss:
- [x] Should we drop output of computation.logger.trace as it mostly duplicates a new tracer's output?
- [x] Find a better way to turn tracer on\off (right now it's a member of VM's state class and we just check if it's "not None" from a computation instance). Another way could be passing Tracer as param all the way down in chain of calls: VM.state.apply_transaction() -> execute_transaction() -> TransactionExecutor.build_computation() -> computation.apply_computation().
- [x] Cross-compare output with go-ethereum tests. Problem is I can't find any tests related to non-JS (basic) tracer there. I've performed cross-comparison of multiple transactions and output is identical except few bugs in geth: e.g. sometimes it initializes memory with zero after push into stack, or do not populate error field in case error fired etc).
- [x] "gas" field in response represents a total block gas usage. I believe this is a bug in geth implementation and for traceTransaction should be equal to the gas used purely by a traced transaction, not the whole block.
- [x] Putting main "capture_state" into "finally" block allows us to catch both error and success cases in one place. Also it's the only way I've found to store a valid "cost" amount. In the future we shall move "cost" estimation calculations into Opcode's "gas_cost" method (see "operation's gasCost gasFunc" implementation in geth: https://github.com/ethereum/go-ethereum/blob/master/core/vm/jump_table.go).
@rayrapetyan I started reviewing and realized that there were somewhat significant architectural changes that I wanted but needed to figure out via code.
Take a look at https://github.com/ethereum/py-evm/pull/1515
Wondering if you feel confident picking that up and continuing from there?
Thanks @pipermerriam, I'll continue here using your changes.
@rayrapetyan :+1: let me know if you need anything from me.
I took some additional liberties here: https://github.com/rayrapetyan/py-evm/pull/2
@pipermerriam, awaiting your responses in https://github.com/rayrapetyan/py-evm/pull/2. Thanks.
@pipermerriam, please review and merge.
This commit history is pretty messy. Are you up for doing rebase/squash and force push?
Also, best to remove [WIP] from the PR title if you're ready for the final review before merging. That is one signal we use for readiness.
@carver, removed WIP, please review and if everything is OK I'll squash. Thanks.
@carver I'm a little too close to this issue (as I did some significant rewriting along the way) so I'm good delegating to you for final merge.
@carver, if possible - please merge on your side. I swear never merge master into dev branches anymore :)
@rayrapetyan in case you aren't aware: https://help.github.com/articles/about-git-rebase/
git rebase master is what you're looking for but it takes a little bit of a learning curve to deal with merge conflicts properly.
@pipermerriam, I would be glad to merge, but most of the changes there are yours so I can miss\overlook something. As for trinity parts - I guess you mean formatting function, I would leave it as is with a TODO mark. while i + 32 <= len(e.memory): part is exactly how it was done in geth. And btw unassign me from bounty - this was primarily your job done here. Thanks.
@rayrapetyan I'm fine with you collecting the bounty.
- you laid the foundation for what I did
- you still did a significant part of the work
- I like contributors being paid though I appreciate you willingness to contribute for free.
@rayrapetyan it's less about that specific line of code and more 1) wanting to give the whole implementation of the RPC endpoint another once-over and 2) wanting to convert that entire normalization function into something more inline with our code style (functional and immutable).