mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 01:41:36 +00:00
internal/ethapi: apply block overrides to header in eth_call
When BlockOverrides specifies BaseFeePerGas, doCall applies the override to the derived EVM block context, but the original header is still passed down to applyMessage. applyMessage then computes the message's gasPrice via args.ToMessage(header.BaseFee, ...) which ignores the override, so subsequent GASPRICE queries and effectiveTip calculations use the pre-override basefee. As a result, eth_call with a 1559 transaction (MaxFeePerGas + MaxPriorityFeePerGas) and a BaseFeePerGas block override returns a GASPRICE derived from the real block's basefee instead of the override. tracers/api.go and simulate.go already read BaseFee from the overridden block context, so only eth_call was affected. Mirror the fix applied to DoEstimateGas in #34081: after applying the overrides to blockCtx, rebuild the header via blockOverrides.MakeHeader so downstream code sees the overridden basefee. Add a TestCall case that asserts GASPRICE returns tip + overridden basefee. It fails on master and passes with this change.
This commit is contained in:
parent
822e7c6486
commit
1481f98554
2 changed files with 25 additions and 0 deletions
|
|
@ -734,6 +734,10 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S
|
||||||
if err := blockOverrides.Apply(&blockCtx); err != nil {
|
if err := blockOverrides.Apply(&blockCtx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// Override the header so callers that compute gas price from 1559 fee
|
||||||
|
// fields see the overridden basefee. Otherwise GASPRICE/effectiveTip
|
||||||
|
// would be derived from the pre-override basefee.
|
||||||
|
header = blockOverrides.MakeHeader(header)
|
||||||
}
|
}
|
||||||
rules := b.ChainConfig().Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time)
|
rules := b.ChainConfig().Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time)
|
||||||
precompiles := vm.ActivePrecompiledContracts(rules)
|
precompiles := vm.ActivePrecompiledContracts(rules)
|
||||||
|
|
|
||||||
|
|
@ -1315,6 +1315,27 @@ func TestCall(t *testing.T) {
|
||||||
},
|
},
|
||||||
expectErr: errors.New(`block override "withdrawals" is not supported for this RPC method`),
|
expectErr: errors.New(`block override "withdrawals" is not supported for this RPC method`),
|
||||||
},
|
},
|
||||||
|
// Verify that an overridden basefee is honored when computing gasPrice
|
||||||
|
// from the 1559 fee fields. Returning GASPRICE opcode; expected value
|
||||||
|
// is min(MaxFeePerGas, MaxPriorityFeePerGas + overridden BaseFee).
|
||||||
|
//
|
||||||
|
// BaseFee override = 0xa (10); MaxFeePerGas = 0x64 (100);
|
||||||
|
// MaxPriorityFeePerGas = 0x2 (2); expected GASPRICE = 12.
|
||||||
|
{
|
||||||
|
name: "basefee-override-used-in-gasprice",
|
||||||
|
blockNumber: rpc.LatestBlockNumber,
|
||||||
|
call: TransactionArgs{
|
||||||
|
From: &accounts[0].addr,
|
||||||
|
// Contract: GASPRICE; PUSH1 0; MSTORE; PUSH1 32; PUSH1 0; RETURN
|
||||||
|
Input: hex2Bytes("3a60005260206000f3"),
|
||||||
|
MaxFeePerGas: (*hexutil.Big)(big.NewInt(100)),
|
||||||
|
MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(2)),
|
||||||
|
},
|
||||||
|
blockOverrides: override.BlockOverrides{
|
||||||
|
BaseFeePerGas: (*hexutil.Big)(big.NewInt(10)),
|
||||||
|
},
|
||||||
|
want: "0x000000000000000000000000000000000000000000000000000000000000000c",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testSuite {
|
for _, tc := range testSuite {
|
||||||
result, err := api.Call(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides)
|
result, err := api.Call(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue