ethereum / go-ethereum

Go implementation of the Ethereum protocol
https://geth.ethereum.org
GNU Lesser General Public License v3.0
47.64k stars 20.17k forks source link

Tracker for live tracing v1.1.0 proposals #30356

Open s1na opened 2 months ago

s1na commented 2 months ago

Here are ideas on improving the live tracing interface that were raised by Tenderly:

### Tasks
- [ ] State revert events: when a call reverts, it would help to get events for balance nonce etc revertals. Then tracers will not have to implement journaling. The same would apply to logs.
- [ ] In a similar vein, emit an event with a list of blocks that are reorged out.
- [ ] Extract headers for the blocks requested via BLOCKHASH opcode. Either a special hook for OpBlockHash or alternatively add a way for tracers to query blocks via their hash.
- [ ] Add GetCodeHash to `tracing.StateDB` to complete the set of account info.
- [ ] Add `tracing.StateDB` as a parameter to `OnSystemCallStart`.
- [ ] Add state read hooks: `OnBalanceRead`, `OnNonceRead`, etc. (incl. storage)

Another item on the wishlist is a testing framework for the live tracers. It should be possible to prototype something via the SimulatedBackend so that you run the tracer against a predefined chain and can compare the output.

s1na commented 2 months ago

WIP branch: https://github.com/s1na/go-ethereum/tree/tracing/v1.1

holiman commented 2 months ago

State revert events: when a call reverts, it would help to get events for balance nonce etc revertals. Then tracers will not have to implement journaling

It doesn't have to implement journallling, it has access to statedb no? It can just query the statedb for the values?

So, if it has a list of n changed accounts, and the call is reverted, just go through the n accounts and check what the values are. ?

s1na commented 2 months ago

So, if it has a list of n changed accounts, and the call is reverted, just go through the n accounts and check what the values are. ?

Right it will need to track all the dirty accounts and slots in the call stack and do the revertals. With the library I provided it becomes much simpler. They will receive OnBalanceChange etc. events with "reverse" values. It is not absolutely necessary but certainly nice to have.

holiman commented 2 months ago

IMO it becomes too tied in with implementation details. I have a prospective future PR, where we journal differently. Instead of journalling Account A: balance was B followed by Account A, balance was C, we would have different journal-scopes (which are == call scopes).

So, when a balance is changed, we'd journal Account A: { balance: x, nonce: y, .... If there are more balance-changes in the same call-scope, nothing is added to the journal (because, per scope, all it needs is the pre-image). And when child-scopes are merged into the parent, we simply discard the child-scope changes to account A, if it's already tracked in parent.

With such a model, you would not be able to get a sorted stream of reverse events. You could get a per-scope dump, basically: "This scope is reverted, the following stuff is what we're going with: Account A balance B, ... ".

I guess what I'm trying to say is that I don't want to our hands to be tied, when it comes to API promises and journalling.

s1na commented 2 months ago

If there are more balance-changes in the same call-scope, nothing is added to the journal (because, per scope, all it needs is the pre-image)

That makes sense.

Please note that I'm not using the journal API in any sense. I build an independent journal (see core/tracing/journal.go) from the existing events (OnBalanceChange etc.). It's true the code is mostly a copy/paste of core/state/journal.go. But it will not be affected by any changes to geth's journal system. I will not be complaining if you change anything there.