From 7b0a54cad56a6c0116d200396469347ba98b6779 Mon Sep 17 00:00:00 2001 From: lightclient Date: Wed, 16 Jul 2025 12:08:49 -0600 Subject: [PATCH] eth/tracers: simplify flow of applying overrides in TraceCall --- eth/tracers/api.go | 40 ++++++++++++++++++++++------------------ eth/tracers/api_test.go | 4 ++-- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 4547420d9a..b50a532b60 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -954,48 +954,52 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc defer release() h := block.Header() + blockContext := core.NewEVMBlockContext(h, api.chainContext(ctx), nil) - if config != nil && config.BlockOverrides != nil { - if config.BlockOverrides.Number.ToInt().Uint64() == h.Number.Uint64()+1 { - h = config.BlockOverrides.MakeHeader(block.Header()) - h.ParentHash = block.Hash() - } - } - - vmctx := core.NewEVMBlockContext(h, api.chainContext(ctx), nil) // Apply the customization rules if required. if config != nil { - if overrideErr := config.BlockOverrides.Apply(&vmctx); overrideErr != nil { - return nil, overrideErr + if config.BlockOverrides != nil && config.BlockOverrides.Number.ToInt().Uint64() == h.Number.Uint64()+1 { + // Overriding the block number to n+1 is a common way for wallets to + // simulate transactions, however without the following fix, a contract + // can assert it is being simulated by checking if blockhash(n) == 0x0 and + // can behave differently during the simulation. (#32175 for more info) + // -- + // Modify the parent hash and number so that downstream, blockContext's + // GetHash function can correctly return n. + h.ParentHash = h.Hash() + h.Number.Add(h.Number, big.NewInt(1)) } - rules := api.backend.ChainConfig().Rules(vmctx.BlockNumber, vmctx.Random != nil, vmctx.Time) - + if err := config.BlockOverrides.Apply(&blockContext); err != nil { + return nil, err + } + rules := api.backend.ChainConfig().Rules(blockContext.BlockNumber, blockContext.Random != nil, blockContext.Time) precompiles = vm.ActivePrecompiledContracts(rules) if err := config.StateOverrides.Apply(statedb, precompiles); err != nil { return nil, err } } - // Execute the trace - if err := args.CallDefaults(api.backend.RPCGasCap(), vmctx.BaseFee, api.backend.ChainConfig().ChainID); err != nil { + + // Execute the trace. + if err := args.CallDefaults(api.backend.RPCGasCap(), blockContext.BaseFee, api.backend.ChainConfig().ChainID); err != nil { return nil, err } var ( - msg = args.ToMessage(vmctx.BaseFee, true, true) + msg = args.ToMessage(blockContext.BaseFee, true, true) tx = args.ToTransaction(types.LegacyTxType) traceConfig *TraceConfig ) // Lower the basefee to 0 to avoid breaking EVM // invariants (basefee < feecap). if msg.GasPrice.Sign() == 0 { - vmctx.BaseFee = new(big.Int) + blockContext.BaseFee = new(big.Int) } if msg.BlobGasFeeCap != nil && msg.BlobGasFeeCap.BitLen() == 0 { - vmctx.BlobBaseFee = new(big.Int) + blockContext.BlobBaseFee = new(big.Int) } if config != nil { traceConfig = &config.TraceConfig } - return api.traceTx(ctx, tx, msg, new(Context), vmctx, statedb, traceConfig, precompiles) + return api.traceTx(ctx, tx, msg, new(Context), blockContext, statedb, traceConfig, precompiles) } // traceTx configures a new tracer according to the provided configuration, and diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 4129ff5e2b..7ed2a5936e 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -801,12 +801,12 @@ func TestTracingWithOverrides(t *testing.T) { byte(vm.PUSH1), 0x20, byte(vm.PUSH1), 0x00, byte(vm.RETURN), - }), // blocknumber + }), }, config: &TraceCallConfig{ BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(int64(genBlocks + 1)))}, }, - want: fmt.Sprintf(`{"gas":59590,"failed":false,"returnValue":"%s"}`, fmt.Sprintf("0x%064s", backend.chain.GetHeaderByNumber(uint64(genBlocks)).Hash().Hex()[2:])), + want: fmt.Sprintf(`{"gas":59590,"failed":false,"returnValue":"%s"}`, backend.chain.GetHeaderByNumber(uint64(genBlocks)).Hash().Hex()), }, /* pragma solidity =0.8.12;