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

core/tracing: state journal wrapper #30441

Merged
merged 61 commits into from
Feb 5, 2025
Merged

core/tracing: state journal wrapper #30441

merged 61 commits into from
Feb 5, 2025

Conversation

s1na
Copy link
Contributor

@s1na s1na commented Sep 16, 2024

Here we add some more changes for live tracing API:

  • Hook OnSystemCallStartV2 was introduced with VMContext as parameter.
  • Hook OnBlockHashRead was introduced.
  • GetCodeHash was added to the state interface
  • The new WrapWithJournal construction helps with tracking EVM reverts in the tracer.

NonceReadHook = func(addr common.Address, nonce uint64)

// CodeReadHook is called when EVM reads the code of an account.
CodeReadHook = func(addr common.Address, code []byte)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Open question: should we add codeHash here to be consistent with OnCodeChange?

@s1na
Copy link
Contributor Author

s1na commented Oct 8, 2024

Ah seems like the journal has a crasher:

revisions: [{0 2} {1 4} {2 4} {3 4} {4 6} {5 6} {6 9} {7 11} {8 12} {9 18} {10 18} {11 20} {12 22} {13 24} {14 24} {18 27}]
panic: revision id 17 cannot be reverted

goroutine 10470 [running]:
github.com/ethereum/go-ethereum/core/tracing.(*journal).revertToSnapshot(0xc050c41c70, 0x11, 0xc0570360e0)
        github.com/ethereum/go-ethereum/core/tracing/journal.go:170 +0x185
github.com/ethereum/go-ethereum/core/tracing.(*journal).OnExit(0xc050c41c70, 0x0, {0xc13a87fe30, 0x64, 0x64}, 0x48dc9, {0x203f680, 0xc018bcc978}, 0x1)
        github.com/ethereum/go-ethereum/core/tracing/journal.go:206 +0x6f
github.com/ethereum/go-ethereum/core/vm.(*EVM).captureEnd(0xc13a9e0780?, 0x0, 0x12e208, 0xe543f, {0xc13a87fe30, 0x64, 0x64}, {0x203da40, 0x2e05070})


### New methods

- `OnReorg(reverted []*types.Block)`: This hook is called when a reorg is detected. The `reverted` slice contains the blocks that are no longer part of the canonical chain.
Copy link
Member

Choose a reason for hiding this comment

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

Here types block is very very heavy. You should at most pass headers and allow chain access to pull the blocks on demand (chain access in someconstructor, ha)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On second thought what is the issue? it is a slice so passed by reference and the memory can be freed as soon as OnReorg processing is done.

Copy link
Member

Choose a reason for hiding this comment

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

Ugh, this is annoying. So reorg in the blockchain at some point in the past used to collect blocks. Turned out that sometimes it became insanely heavy and we've switched so it operates on headers. I guess later someone refactored it back to operate on blocks again. This is an issue when you do setHead or any similar operation; of even if finality fails for a while and you have blocks reorging back and forth. It's very very bad to pull all the block in from disk IMO.

CC @holiman @rjl493456442 ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. I don't particularly recall switching from headers to blocks....

@@ -194,6 +221,30 @@ type Hooks struct {
OnCodeChange CodeChangeHook
OnStorageChange StorageChangeHook
OnLog LogHook
// State reads
OnBalanceRead BalanceReadHook
OnNonceRead NonceReadHook
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Question from triage: how exactly is OnNonceRead used?

Comment on lines 45 to 47
validRevisions []revision
nextRevisionId int
revIds []int
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see why you need to track this. Why not just maintain a list of entries, and you hand out the id which is the current length of the entries?

core/tracing/journal.go Show resolved Hide resolved
type journal struct {
entries []entry
hooks *Hooks
lastCreator *common.Address // Account that initiated the last contract creation
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a hack. I don't see how this can be accurately updated going forward and backward along the entries. I mean, an inner scope will overwrite the outer lastCreator, and when the inner scope is reverted, the lastCreator will not be set back correctly.

Copy link
Contributor

Choose a reason for hiding this comment

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

Or if we're inside a creation, and inside the constructor we call ripemd to calculate a signature: we lost lastCreator.

@fjl fjl self-assigned this Jan 21, 2025
@fjl fjl modified the milestones: 1.14.13, 1.15.0 Jan 23, 2025
dstValue.Field(i).Set(field)
}
}
return copied
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this not equivalent to

copied := *h
return &copied

@@ -163,6 +171,9 @@ type (
// NonceChangeHook is called when the nonce of an account changes.
NonceChangeHook = func(addr common.Address, prev, new uint64)

// NonceChangeHookV2 is called when the nonce of an account changes.
NonceChangeHookV2 = func(addr common.Address, prev, new uint64, reason NonceChangeReason)
Copy link
Member

Choose a reason for hiding this comment

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

The V2 isn't helpful, we should use NonceChangeHokWithReason. Function names should be explict in what they do.

Copy link
Contributor

@fjl fjl Feb 5, 2025

Choose a reason for hiding this comment

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

We have chosen this naming scheme explicitly. The intent is communicating which version of the hook is the newest one. When we introduce a new hook version, the old one becomes deprecated and will eventually be unsupported. Also, if we were to introduce another revision of this hook, would it be called NonceChangeHookWithReasonAndBellsAndWhistles? The *Vx naming scheme avoids this problem.

Copy link
Member

Choose a reason for hiding this comment

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

When the old one is removed, you can remove the WithReason part, but in the meantime, you know at a glance why the two methods differ. I don't think there's a big risk of that function being rewritten many times and, therefore, having the names getting longer and longer. But sure, just giving my opinion on what could make the code readable, not going to hold the release for that one 🤷

Copy link
Contributor

Choose a reason for hiding this comment

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

We cannot rename the function because it is a stable, user-exposed API. If we could just change it, we wouldn't go through the trouble of having multiple versions of the hook.

core/tracing/journal.go Outdated Show resolved Hide resolved
@fjl fjl merged commit aaaf01d into ethereum:master Feb 5, 2025
3 of 4 checks passed
tokeyg pushed a commit to tokeyg/go-ethereum that referenced this pull request Feb 6, 2025
Here we add some more changes for live tracing API v1.1:

- Hook `OnSystemCallStartV2` was introduced with `VMContext` as parameter.
- Hook `OnBlockHashRead` was introduced.
- `GetCodeHash` was added to the state interface
- The new `WrapWithJournal` construction helps with tracking EVM reverts in the tracer.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants