diff --git a/execution/nodeInterface/virtual-contracts.go b/execution/nodeInterface/virtual-contracts.go index d72ad0da8e..d04be10857 100644 --- a/execution/nodeInterface/virtual-contracts.go +++ b/execution/nodeInterface/virtual-contracts.go @@ -141,7 +141,8 @@ func init() { return } posterCost, _ := state.L1PricingState().PosterDataCost(msg, l1pricing.BatchPosterAddress, brotliCompressionLevel) - posterCostInL2Gas := arbos.GetPosterGas(state, header.BaseFee, msg.TxRunMode, posterCost) + // Use estimate mode because this is used to raise the gas cap, so we don't want to underestimate. + posterCostInL2Gas := arbos.GetPosterGas(state, header.BaseFee, core.MessageGasEstimationMode, posterCost) *gascap = arbmath.SaturatingUAdd(*gascap, posterCostInL2Gas) } diff --git a/system_tests/estimation_test.go b/system_tests/estimation_test.go index e7f00ca94e..284c709fad 100644 --- a/system_tests/estimation_test.go +++ b/system_tests/estimation_test.go @@ -324,3 +324,35 @@ func TestDisableL1Charging(t *testing.T) { _, err = builder.L2.Client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging, SkipL1Charging: true}, nil) Require(t, err) } + +func TestGasEstimationWithRPCGasLimit(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, true) + cleanup := builder.Build(t) + defer cleanup() + + execConfigA := builder.execConfig + execConfigA.RPC.RPCGasCap = params.TxGas + testClientA, cleanupA := builder.Build2ndNode(t, &SecondNodeParams{execConfig: execConfigA}) + defer cleanupA() + addr := common.HexToAddress("0x12345678") + estimateGas, err := testClientA.Client.EstimateGas(ctx, ethereum.CallMsg{To: &addr}) + Require(t, err) + if estimateGas <= params.TxGas { + Fatal(t, "Incorrect gas estimate") + } + + _, err = testClientA.Client.CallContract(ctx, ethereum.CallMsg{To: &addr}, nil) + Require(t, err) + + execConfigB := builder.execConfig + execConfigB.RPC.RPCGasCap = params.TxGas - 1 + testClientB, cleanupB := builder.Build2ndNode(t, &SecondNodeParams{execConfig: execConfigB}) + defer cleanupB() + _, err = testClientB.Client.EstimateGas(ctx, ethereum.CallMsg{To: &addr}) + if err == nil { + Fatal(t, "EstimateGas passed with insufficient gas") + } +}