diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index bb0dd042ab..3f3751acf2 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -21,6 +21,7 @@ import ( "encoding/hex" "errors" "fmt" + "maps" gomath "math" "math/big" "strings" @@ -1275,12 +1276,15 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH if db == nil || err != nil { return nil, 0, nil, err } + isPostMerge := header.Difficulty.Sign() == 0 + rules := b.ChainConfig().Rules(header.Number, isPostMerge, header.Time) + precompileSet := maps.Clone(vm.ActivePrecompiledContracts(rules)) // Apply state overrides immediately after StateAndHeaderByNumberOrHash. // If not applied here, there could be cases where user-specified overrides (e.g., nonce) // may conflict with default values from the database, leading to inconsistencies. if stateOverrides != nil { - if err := stateOverrides.Apply(db, nil); err != nil { + if err := stateOverrides.Apply(db, precompileSet); err != nil { return nil, 0, nil, err } } @@ -1304,9 +1308,11 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH } else { to = crypto.CreateAddress(args.from(), uint64(*args.Nonce)) } - isPostMerge := header.Difficulty.Sign() == 0 // Retrieve the precompiles since they don't need to be added to the access list - precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number, isPostMerge, header.Time)) + precompiles := make([]common.Address, 0, len(precompileSet)) + for addr := range precompileSet { + precompiles = append(precompiles, addr) + } // addressesToExclude contains sender, receiver, precompiles and valid authorizations addressesToExclude := map[common.Address]struct{}{args.from(): {}, to: {}} @@ -1354,6 +1360,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH tracer := logger.NewAccessListTracer(accessList, addressesToExclude) config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true} evm := b.GetEVM(ctx, statedb, header, &config, nil) + evm.SetPrecompiles(precompileSet) // Lower the basefee to 0 to avoid breaking EVM // invariants (basefee < feecap). diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 62e9979d3d..5f09e5ea2d 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1014,7 +1014,7 @@ func TestCall(t *testing.T) { Balance: big.NewInt(params.Ether), Nonce: 1, Storage: map[common.Hash]common.Hash{ - common.Hash{}: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"), + {}: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"), }, }, }, @@ -3795,7 +3795,7 @@ func TestCreateAccessListWithStateOverrides(t *testing.T) { Balance: (*hexutil.Big)(big.NewInt(1000000000000000000)), Nonce: &nonce, State: map[common.Hash]common.Hash{ - common.Hash{}: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000002a"), + {}: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000002a"), }, }, } @@ -3832,6 +3832,46 @@ func TestCreateAccessListWithStateOverrides(t *testing.T) { require.Equal(t, expected, result.Accesslist) } +func TestCreateAccessListWithMovePrecompile(t *testing.T) { + t.Parallel() + // Initialize test accounts + var ( + accounts = newAccounts(2) + genesis = &core.Genesis{ + Config: params.MergedTestChainConfig, + Alloc: types.GenesisAlloc{ + accounts[0].addr: {Balance: big.NewInt(params.Ether)}, + }, + } + ) + backend := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { + b.SetPoS() + }) + api := NewBlockChainAPI(backend) + + var ( + sha256Addr = common.BytesToAddress([]byte{0x2}) + newSha256Addr = common.BytesToAddress([]byte{0x10, 0}) + sha256Input = hexutil.Bytes([]byte("hello")) + gas = hexutil.Uint64(100000) + args = TransactionArgs{ + From: &accounts[0].addr, + To: &newSha256Addr, + Data: &sha256Input, + Gas: &gas, + } + overrides = &override.StateOverride{ + sha256Addr: override.OverrideAccount{ + MovePrecompileTo: &newSha256Addr, + }, + } + ) + result, err := api.CreateAccessList(context.Background(), args, nil, overrides) + require.NoError(t, err) + require.NotNil(t, result) + require.NotNil(t, result.Accesslist) +} + func TestEstimateGasWithMovePrecompile(t *testing.T) { t.Parallel() // Initialize test accounts