Skip to content
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

Implement stateDiff tracer, compatible with OpenEthereum #345

Merged
merged 43 commits into from
Apr 1, 2021

Conversation

ziogaschr
Copy link
Member

This PR adds stateDiff tracer that is compatible with OpenEthereum.

stateDiff State difference. Provides information detailing all altered portions of the Ethereum state made due to the execution of the transaction.

The stateDiff tracer can be used in the following Ad-hoc Tracing methods:

  • trace_call
  • trace_callMany
  • trace_rawTransaction
  • trace_replayBlockTransactions
  • trace_replayTransaction

p.s.: The remaining unchecked Ad-hoc Tracing methods will be added in a new PR, and will have stateDiff tracer support out of the box.

Differences with OpenEthereum

  1. SSTORE in some edge cases are being persisted in state but are being removed from stateDiff storage results. (Happens only on 2 transactions on Mordor testnet)
  2. When error ErrInsufficientFundsForTransfer happens, OpenEthereum leaves the tracer run producing negative balances, though using safe math for overflows it returns 0 balance, on the other hand the to account receives the full amount. Core-geth removes only the gas cost from the sender and adds it to the coinbase balance.
  3. Same as in 2, but on top of that, the sender account doesn't have to pay for the gas cost even. In this case, core-geth returns an empty JSON, as in reality this transaction will remain in the tx_pool and never be executed, neither change the state.
  4. On OpenEthereum the block gasLimit is set to be U256::max(), which leads into problems on contracts using it for pseudo-randomness. On core-geth, we believe that the user utilising the trace_* wants to see what will happen in reality, though we leave the block untouched to its true values.
  5. When an internal call fails with out of gas, and its state is not being persisted, we don't add it in stateDiff output, as it happens on OpenEthereum.

eth: add test for stateDiff tracer
eth, eth/tracers: resolve state_diff misconsistencies

eth: pass extra context to call JS tracers hasFromSufficientBalance*
eth: traceCall to use original TransferFunc instead of copy the logic and take care of mutating the value
…CapturePreEVM

Till this point, state_diff was manually calculating balance/nonce changes that have been executed pre/post EVM execution. This was error prone, as any change in consensus within go, will have to be transfered to JS logic as well.

This commit tackles this issue, by adding an init() method call, before anything is be run for a transaction.

eth: clean up vmctx.Tracer (pointer, refs, oh my)

Date: 2021-03-12 15:09:48-06:00
Signed-off-by: meows <b5c6@protonmail.com>
@ziogaschr
Copy link
Member Author

@meowsbits where's the best place to add the Differences with OpenEthereum section from the above notes in our docs? Do you remember if we have a way to add them within the generated docs?

@ziogaschr
Copy link
Member Author

@meowsbits I handled all your comments. Please have a look at them and re-review. Let me know if you find anything else as based on your comments we did some good hardening.

Copy link
Contributor

@meowsbits meowsbits left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work.

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

Successfully merging this pull request may close these issues.

3 participants