From 916259f2a90028479947dd0101350a4390d1a467 Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Mon, 10 Nov 2025 09:42:41 -0500 Subject: [PATCH] Fixed hooked StateDB handling of `OnCodeChangeV2` While updating to latest Geth, I noticed `OnCodeChangeV2` was not properly handled in `SelfDestruct/6780`, this PR fixes this and bring a unit test. Let me know if it's deemed more approriate to merge the tests with the other one. --- core/state/statedb_hooked.go | 4 +-- core/state/statedb_hooked_test.go | 41 +++++++++++++++++++++++++++++++ eth/tracers/native/mux.go | 8 ++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 9db201fc2b91..50acc03aa8be 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -220,7 +220,7 @@ func (s *hookedStateDB) SelfDestruct(address common.Address) uint256.Int { var prevCode []byte var prevCodeHash common.Hash - if s.hooks.OnCodeChange != nil { + if s.hooks.OnCodeChange != nil || s.hooks.OnCodeChangeV2 != nil { prevCode = s.inner.GetCode(address) prevCodeHash = s.inner.GetCodeHash(address) } @@ -246,7 +246,7 @@ func (s *hookedStateDB) SelfDestruct6780(address common.Address) (uint256.Int, b var prevCode []byte var prevCodeHash common.Hash - if s.hooks.OnCodeChange != nil { + if s.hooks.OnCodeChange != nil || s.hooks.OnCodeChangeV2 != nil { prevCodeHash = s.inner.GetCodeHash(address) prevCode = s.inner.GetCode(address) } diff --git a/core/state/statedb_hooked_test.go b/core/state/statedb_hooked_test.go index bacb7baee129..4ff1023eb2c9 100644 --- a/core/state/statedb_hooked_test.go +++ b/core/state/statedb_hooked_test.go @@ -122,6 +122,47 @@ func TestHooks(t *testing.T) { sdb.AddLog(&types.Log{ Address: common.Address{0xbb}, }) + + if len(result) != len(wants) { + t.Fatalf("number of tracing events wrong, have %d want %d", len(result), len(wants)) + } + + for i, want := range wants { + if have := result[i]; have != want { + t.Fatalf("error event %d, have\n%v\nwant%v\n", i, have, want) + } + } +} + +func TestHooks_OnCodeChangeV2(t *testing.T) { + inner, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) + + var result []string + var wants = []string{ + "0xaa00000000000000000000000000000000000000.code: (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) ->0x1325 (0xa12ae05590de0c93a00bc7ac773c2fdb621e44f814985e72194f921c0050f728) ContractCreation", + "0xaa00000000000000000000000000000000000000.code: 0x1325 (0xa12ae05590de0c93a00bc7ac773c2fdb621e44f814985e72194f921c0050f728) -> (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) SelfDestruct", + "0xbb00000000000000000000000000000000000000.code: (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) ->0x1326 (0x3c54516221d604e623f358bc95996ca3242aaa109bddabcebda13db9b3f90dcb) ContractCreation", + "0xbb00000000000000000000000000000000000000.code: 0x1326 (0x3c54516221d604e623f358bc95996ca3242aaa109bddabcebda13db9b3f90dcb) -> (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) SelfDestruct", + } + emitF := func(format string, a ...any) { + result = append(result, fmt.Sprintf(format, a...)) + } + sdb := NewHookedState(inner, &tracing.Hooks{ + OnCodeChangeV2: func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { + emitF("%v.code: %#x (%v) ->%#x (%v) %s", addr, prevCode, prevCodeHash, code, codeHash, reason) + }, + }) + sdb.SetCode(common.Address{0xaa}, []byte{0x13, 37}, tracing.CodeChangeContractCreation) + sdb.SelfDestruct(common.Address{0xaa}) + + sdb.SetCode(common.Address{0xbb}, []byte{0x13, 38}, tracing.CodeChangeContractCreation) + sdb.CreateContract(common.Address{0xbb}) + sdb.SelfDestruct6780(common.Address{0xbb}) + + if len(result) != len(wants) { + t.Fatalf("number of tracing events wrong, have %d want %d", len(result), len(wants)) + } + for i, want := range wants { if have := result[i]; have != want { t.Fatalf("error event %d, have\n%v\nwant%v\n", i, have, want) diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index 77ab254568e6..37fc64f3f5e2 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -156,6 +156,14 @@ func (t *muxTracer) OnCodeChange(a common.Address, prevCodeHash common.Hash, pre } } +func (t *muxTracer) OnCodeChangeV2(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { + for _, t := range t.tracers { + if t.OnCodeChangeV2 != nil { + t.OnCodeChangeV2(a, prevCodeHash, prev, codeHash, code, reason) + } + } +} + func (t *muxTracer) OnStorageChange(a common.Address, k, prev, new common.Hash) { for _, t := range t.tracers { if t.OnStorageChange != nil {