From fc3783a9698dbdd537a8c50bacc72565b1402be2 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Thu, 11 Jul 2024 21:41:26 +0530 Subject: [PATCH 1/6] Test EstimateRetryableTicket With No Funds And Zero GasPrice --- system_tests/retryable_test.go | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) 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) From a656df40b0d5ff3339e1725850476bbac0e43f68 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Thu, 11 Jul 2024 21:41:40 +0530 Subject: [PATCH 2/6] fix --- system_tests/retryable_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index a5f18f6303..ba0eb37578 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -131,7 +131,7 @@ func TestRetryableNoExist(t *testing.T) { } } -func TestEstimateRetryableTicketWithNoFundsAndZeroGas(t *testing.T) { +func TestEstimateRetryableTicketWithNoFundsAndZeroGasPrice(t *testing.T) { t.Parallel() builder, _, _, ctx, teardown := retryableSetup(t) defer teardown() From a5892d858f9d74242b7cce2be62a006a9ffe13a1 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Thu, 11 Jul 2024 21:44:33 +0530 Subject: [PATCH 3/6] fix --- system_tests/retryable_test.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index ba0eb37578..268d59ac98 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -145,13 +145,12 @@ func TestEstimateRetryableTicketWithNoFundsAndZeroGasPrice(t *testing.T) { 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( + _, err = nodeInterface.EstimateRetryableTicket( &usertxoptsL2, usertxoptsL2.From, deposit, @@ -159,18 +158,9 @@ func TestEstimateRetryableTicketWithNoFundsAndZeroGasPrice(t *testing.T) { callValue, beneficiaryAddress, beneficiaryAddress, - []byte{0x32, 0x42, 0x32, 0x88}, // increase the cost to beyond that of params.TxGas + []byte{}, ) 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) { From a42a7a152402c5438b04934039b8ce684dfa1d4c Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Fri, 12 Jul 2024 16:51:19 -0500 Subject: [PATCH 4/6] Update scopeContext's stack to have correct contract address while tracing for ethCalls --- arbos/programs/api.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/arbos/programs/api.go b/arbos/programs/api.go index 65a58a47c2..ed43751a54 100644 --- a/arbos/programs/api.go +++ b/arbos/programs/api.go @@ -137,16 +137,29 @@ func newApiClosures( startGas := am.SaturatingUSub(gasLeft, baseCost) * 63 / 64 gas := am.MinInt(startGas, gasReq) - // Tracing: emit the call (value transfer is done later in evm.Call) - if tracingInfo != nil { - tracingInfo.Tracer.CaptureState(0, opcode, startGas, baseCost+gas, scope, []byte{}, depth, nil) - } - // EVM rule: calls that pay get a stipend (opCall) if value.Sign() != 0 { gas = am.SaturatingUAdd(gas, params.CallStipend) } + // Tracing: emit the call (value transfer is done later in evm.Call) + if tracingInfo != nil { + s := &vm.ScopeContext{ + Memory: vm.NewMemory(), + Stack: util.TracingStackFromArgs( + *uint256.NewInt(gas), // gas + *uint256.NewInt(0).SetBytes(contract.Bytes()), // to address + *uint256.NewInt(0).SetBytes(value.Bytes()), // call value + *uint256.NewInt(0), // memory offset + *uint256.NewInt(uint64(len(input))), // memory length + *uint256.NewInt(0), // return offset + *uint256.NewInt(0), // return size + ), + Contract: scope.Contract, + } + tracingInfo.Tracer.CaptureState(0, opcode, startGas, baseCost+gas, s, []byte{}, depth, nil) + } + var ret []byte var returnGas uint64 From ead2b2412730abae7b8262cddf8e89ea44ba2f35 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Sun, 14 Jul 2024 23:54:16 -0600 Subject: [PATCH 5/6] Fix "sequencer batches out of order" log --- arbnode/sequencer_inbox.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbnode/sequencer_inbox.go b/arbnode/sequencer_inbox.go index 46e1edb78b..73e52ded53 100644 --- a/arbnode/sequencer_inbox.go +++ b/arbnode/sequencer_inbox.go @@ -232,7 +232,7 @@ func (i *SequencerInbox) LookupBatchesInRange(ctx context.Context, from, to *big seqNum := parsedLog.BatchSequenceNumber.Uint64() if lastSeqNum != nil { if seqNum != *lastSeqNum+1 { - return nil, fmt.Errorf("sequencer batches out of order; after batch %v got batch %v", lastSeqNum, seqNum) + return nil, fmt.Errorf("sequencer batches out of order; after batch %v got batch %v", *lastSeqNum, seqNum) } } lastSeqNum = &seqNum From 256d27ecf0ee6ce6aa33c7b4b22ea17ade58dab3 Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Mon, 15 Jul 2024 10:47:11 -0500 Subject: [PATCH 6/6] make scopecontext stack accurate towards delegate and static calls --- arbos/programs/api.go | 22 ++++++++++++---------- arbos/util/tracing.go | 5 +---- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/arbos/programs/api.go b/arbos/programs/api.go index ed43751a54..0519cd9f01 100644 --- a/arbos/programs/api.go +++ b/arbos/programs/api.go @@ -144,17 +144,19 @@ func newApiClosures( // Tracing: emit the call (value transfer is done later in evm.Call) if tracingInfo != nil { + var args []uint256.Int + args = append(args, *uint256.NewInt(gas)) // gas + args = append(args, *uint256.NewInt(0).SetBytes(contract.Bytes())) // to address + if opcode == vm.CALL { + args = append(args, *uint256.NewInt(0).SetBytes(value.Bytes())) // call value + } + args = append(args, *uint256.NewInt(0)) // memory offset + args = append(args, *uint256.NewInt(uint64(len(input)))) // memory length + args = append(args, *uint256.NewInt(0)) // return offset + args = append(args, *uint256.NewInt(0)) // return size s := &vm.ScopeContext{ - Memory: vm.NewMemory(), - Stack: util.TracingStackFromArgs( - *uint256.NewInt(gas), // gas - *uint256.NewInt(0).SetBytes(contract.Bytes()), // to address - *uint256.NewInt(0).SetBytes(value.Bytes()), // call value - *uint256.NewInt(0), // memory offset - *uint256.NewInt(uint64(len(input))), // memory length - *uint256.NewInt(0), // return offset - *uint256.NewInt(0), // return size - ), + Memory: util.TracingMemoryFromBytes(input), + Stack: util.TracingStackFromArgs(args...), Contract: scope.Contract, } tracingInfo.Tracer.CaptureState(0, opcode, startGas, baseCost+gas, s, []byte{}, depth, nil) diff --git a/arbos/util/tracing.go b/arbos/util/tracing.go index f0f101bc20..f3564143c5 100644 --- a/arbos/util/tracing.go +++ b/arbos/util/tracing.go @@ -56,11 +56,8 @@ func (info *TracingInfo) RecordEmitLog(topics []common.Hash, data []byte) { for _, topic := range topics { args = append(args, HashToUint256(topic)) // topic: 32-byte value. Max topics count is 4 } - memory := vm.NewMemory() - memory.Resize(size) - memory.Set(0, size, data) scope := &vm.ScopeContext{ - Memory: memory, + Memory: TracingMemoryFromBytes(data), Stack: TracingStackFromArgs(args...), Contract: info.Contract, }