From d487901839a6db400e608790484f3a9aefba6211 Mon Sep 17 00:00:00 2001 From: lupin012 <58134934+lupin012@users.noreply.github.com.> Date: Sat, 25 Apr 2026 08:36:24 +0200 Subject: [PATCH 1/2] execution/tracers: fix prestateTracer diff mode missing deleted accounts on main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port of release/3.4 fix (#20775): adds GetCodeHash to tracing.IntraBlockState so processDiffState can distinguish deleted accounts (NilCodeHash → zero hash) from codeless-but-existing ones (EmptyCodeHash). GetCode returns empty bytes for both cases and cannot make that distinction. Also replaces repeated t.pre[addr] map lookups with the range variable `state` and adds a compile-time interface assertion in the unit test. Fixes flaky rpc-compat test_42 (debug_traceBlockByNumber with prestateTracer diffMode:true). Co-Authored-By: Claude Sonnet 4.6 --- execution/tracing/tracers/native/prestate.go | 20 +++++++++---------- .../tracers/native/prestate_deleted_test.go | 13 ++++++------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/execution/tracing/tracers/native/prestate.go b/execution/tracing/tracers/native/prestate.go index eb90b406f67..b8b88cac24a 100644 --- a/execution/tracing/tracers/native/prestate.go +++ b/execution/tracing/tracers/native/prestate.go @@ -283,24 +283,24 @@ func (t *prestateTracer) processDiffState() { newBalance, _ := t.env.IntraBlockState.GetBalance(addr) newNonce, _ := t.env.IntraBlockState.GetNonce(addr) - // GetCodeHash returns common.Hash{} for deleted accounts; GetCode cannot make - // that distinction (empty bytes for both deleted and codeless accounts). + // GetCode returns empty bytes for both deleted and codeless accounts; + // GetCodeHash distinguishes them (deleted → zero hash). codeHash, _ := t.env.IntraBlockState.GetCodeHash(addr) newCodeHash := codeHash.Value() newBalanceBig := newBalance.ToBig() - if newBalanceBig.Cmp(t.pre[addr].Balance) != 0 { + if newBalanceBig.Cmp(state.Balance) != 0 { modified = true postAccount.Balance = newBalanceBig } - if newNonce != t.pre[addr].Nonce { + if newNonce != state.Nonce { modified = true postAccount.Nonce = newNonce } prevCodeHash := empty.CodeHash - if t.pre[addr].CodeHash != nil { - prevCodeHash = *t.pre[addr].CodeHash + if state.CodeHash != nil { + prevCodeHash = *state.CodeHash } if newCodeHash != prevCodeHash { @@ -311,8 +311,8 @@ func (t *prestateTracer) processDiffState() { if !t.config.DisableCode { newCode, _ := t.env.IntraBlockState.GetCode(addr) var prevCode []byte - if t.pre[addr].Code != nil { - prevCode = *t.pre[addr].Code + if state.Code != nil { + prevCode = *state.Code } if !bytes.Equal(newCode, prevCode) { modified = true @@ -324,13 +324,13 @@ func (t *prestateTracer) processDiffState() { for key, val := range state.Storage { // don't include the empty slot if val == (common.Hash{}) { - delete(t.pre[addr].Storage, key) + delete(state.Storage, key) } newVal, _ := t.env.IntraBlockState.GetState(addr, accounts.InternKey(key)) if new(uint256.Int).SetBytes(val[:]).Eq(&newVal) { // Omit unchanged slots - delete(t.pre[addr].Storage, key) + delete(state.Storage, key) } else { modified = true if !newVal.IsZero() { diff --git a/execution/tracing/tracers/native/prestate_deleted_test.go b/execution/tracing/tracers/native/prestate_deleted_test.go index 94730ad8b3f..d5566b84520 100644 --- a/execution/tracing/tracers/native/prestate_deleted_test.go +++ b/execution/tracing/tracers/native/prestate_deleted_test.go @@ -29,6 +29,8 @@ import ( "github.com/erigontech/erigon/execution/types/accounts" ) +var _ tracing.IntraBlockState = (*postTxIBS)(nil) + // postTxIBS simulates the IntraBlockState *after* a transaction where deletedAddr // no longer exists (GetCodeHash returns NilCodeHash) and all other accounts are // codeless-but-existent (EmptyCodeHash). @@ -39,17 +41,17 @@ type postTxIBS struct { func (m *postTxIBS) GetBalance(accounts.Address) (uint256.Int, error) { return uint256.Int{}, nil } func (m *postTxIBS) GetNonce(accounts.Address) (uint64, error) { return 0, nil } func (m *postTxIBS) GetCode(accounts.Address) ([]byte, error) { return nil, nil } -func (m *postTxIBS) GetState(accounts.Address, accounts.StorageKey) (uint256.Int, error) { - return uint256.Int{}, nil -} -func (m *postTxIBS) Exist(accounts.Address) (bool, error) { return false, nil } -func (m *postTxIBS) GetRefund() mdgas.MdGas { return mdgas.MdGas{} } func (m *postTxIBS) GetCodeHash(addr accounts.Address) (accounts.CodeHash, error) { if addr == m.deletedAddr { return accounts.NilCodeHash, nil } return accounts.EmptyCodeHash, nil } +func (m *postTxIBS) GetState(accounts.Address, accounts.StorageKey) (uint256.Int, error) { + return uint256.Int{}, nil +} +func (m *postTxIBS) Exist(accounts.Address) (bool, error) { return false, nil } +func (m *postTxIBS) GetRefund() mdgas.MdGas { return mdgas.MdGas{} } // TestPrestateTracerDiffModeDeletedAccount verifies that an account deleted during // a tx appears in the diff-mode post state with codeHash == 0x000...000. @@ -64,7 +66,6 @@ func TestPrestateTracerDiffModeDeletedAccount(t *testing.T) { deleted: make(map[accounts.Address]bool), } - // Pre-tx: codeless account — no CodeHash set, balance = 0. tr.pre[deletedAddr] = &account{Balance: big.NewInt(0)} tr.env = &tracing.VMContext{ From 694f44b97b973321ad385e8b531f26b4ac9fdc94 Mon Sep 17 00:00:00 2001 From: lupin012 <58134934+lupin012@users.noreply.github.com.> Date: Tue, 28 Apr 2026 20:37:03 +0200 Subject: [PATCH 2/2] CI: bump rpc-tests to v2.8.2 and re-enable debug_traceBlockByNumber/test_33,test_34 Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/scripts/rpc_version.env | 2 +- .github/workflows/scripts/run_rpc_tests_ethereum.sh | 3 --- .github/workflows/scripts/run_rpc_tests_remote_ethereum.sh | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/scripts/rpc_version.env b/.github/workflows/scripts/rpc_version.env index 38288f18c70..250707ede76 100644 --- a/.github/workflows/scripts/rpc_version.env +++ b/.github/workflows/scripts/rpc_version.env @@ -1 +1 @@ -RPC_VERSION=v2.8.1 +RPC_VERSION=v2.8.2 diff --git a/.github/workflows/scripts/run_rpc_tests_ethereum.sh b/.github/workflows/scripts/run_rpc_tests_ethereum.sh index 4c37e702ed3..068dc9e6121 100755 --- a/.github/workflows/scripts/run_rpc_tests_ethereum.sh +++ b/.github/workflows/scripts/run_rpc_tests_ethereum.sh @@ -19,9 +19,6 @@ DISABLED_TEST_LIST=( net_listening/test_1.json # Temporary disable required block 24298763 debug_traceBlockByNumber/test_51.json - # Temporary disable after merge #20830, waiting for new rpc-tests tag after merge PR #552 - debug_traceBlockByNumber/test_33.tar - debug_traceBlockByNumber/test_34.tar # to investigate engine_exchangeCapabilities/test_1.json engine_exchangeTransitionConfigurationV1/test_01.json diff --git a/.github/workflows/scripts/run_rpc_tests_remote_ethereum.sh b/.github/workflows/scripts/run_rpc_tests_remote_ethereum.sh index 3e407b5b280..5b22f394683 100755 --- a/.github/workflows/scripts/run_rpc_tests_remote_ethereum.sh +++ b/.github/workflows/scripts/run_rpc_tests_remote_ethereum.sh @@ -20,9 +20,6 @@ DISABLED_TEST_LIST=( # these tests/apis are disabled because some methods are not implmented on grpc eth_getProof eth_simulateV1 - # Temporary disable after merge #20830, waiting for new rpc-tests tag after merge PR #552 - debug_traceBlockByNumber/test_33.tar - debug_traceBlockByNumber/test_34.tar # Temporary disable required block 24298763 debug_traceBlockByNumber/test_51.json # Temporary disable required block 23917742