diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 1abf9f2162..a5f18f6303 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -131,6 +131,48 @@ func TestRetryableNoExist(t *testing.T) { } } +func TestEstimateRetryableTicketWithNoFundsAndZeroGas(t *testing.T) { + t.Parallel() + builder, _, _, ctx, teardown := retryableSetup(t) + defer teardown() + + user2Address := builder.L2Info.GetAddress("User2") + beneficiaryAddress := builder.L2Info.GetAddress("Beneficiary") + + deposit := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) + callValue := big.NewInt(1e6) + + nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, builder.L2.Client) + Require(t, err, "failed to deploy NodeInterface") + + // estimate the gas needed to auto redeem the retryable + builder.L2Info.GenerateAccount("zerofunds") + usertxoptsL2 := builder.L2Info.GetDefaultTransactOpts("zerofunds", ctx) + usertxoptsL2.NoSend = true + usertxoptsL2.GasMargin = 0 + usertxoptsL2.GasPrice = big.NewInt(0) + tx, err := nodeInterface.EstimateRetryableTicket( + &usertxoptsL2, + usertxoptsL2.From, + deposit, + user2Address, + callValue, + beneficiaryAddress, + beneficiaryAddress, + []byte{0x32, 0x42, 0x32, 0x88}, // increase the cost to beyond that of params.TxGas + ) + Require(t, err, "failed to estimate retryable submission") + estimate := tx.Gas() + expectedEstimate := params.TxGas + params.TxDataNonZeroGasEIP2028*4 + if float64(estimate) > float64(expectedEstimate)*(1+gasestimator.EstimateGasErrorRatio) { + t.Errorf("estimated retryable ticket at %v gas but expected %v, with error margin of %v", + estimate, + expectedEstimate, + gasestimator.EstimateGasErrorRatio, + ) + } +} + func TestSubmitRetryableImmediateSuccess(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t)