From d9759471db186104be49b2a66dbf18c2255755d6 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Tue, 26 Sep 2023 11:34:16 -0500 Subject: [PATCH 01/54] initial test node builder pattern and few impl --- system_tests/aliasing_test.go | 26 +-- system_tests/bloom_test.go | 22 +-- system_tests/common_test.go | 95 ++++++++- system_tests/conditionaltx_test.go | 128 ++++++------ system_tests/contract_tx_test.go | 17 +- system_tests/estimation_test.go | 75 +++---- system_tests/infra_fee_test.go | 28 +-- system_tests/initialization_test.go | 6 +- system_tests/log_subscription_test.go | 15 +- system_tests/outbox_test.go | 17 +- system_tests/precompile_test.go | 29 +-- system_tests/reorg_resequencing_test.go | 43 ++-- system_tests/retryable_test.go | 250 ++++++++++++------------ system_tests/seq_coordinator_test.go | 4 +- system_tests/seq_nonce_test.go | 34 ++-- system_tests/seq_pause_test.go | 21 +- system_tests/seq_reject_test.go | 44 ++--- system_tests/seq_whitelist_test.go | 18 +- system_tests/seqfeed_test.go | 48 ++--- system_tests/transfer_test.go | 18 +- 20 files changed, 514 insertions(+), 424 deletions(-) diff --git a/system_tests/aliasing_test.go b/system_tests/aliasing_test.go index 5e4e65a2ca..852a75720f 100644 --- a/system_tests/aliasing_test.go +++ b/system_tests/aliasing_test.go @@ -22,20 +22,20 @@ func TestAliasing(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - auth := l2info.GetDefaultTransactOpts("Owner", ctx) - user := l1info.GetDefaultTransactOpts("User", ctx) - TransferBalanceTo(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18), l2info, l2client, ctx) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + user := testNode.L1Info.GetDefaultTransactOpts("User", ctx) + TransferBalanceTo(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) - simpleAddr, simple := deploySimple(t, ctx, auth, l2client) + simpleAddr, simple := testNode.DeploySimple(t, auth) simpleContract, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) Require(t, err) // Test direct calls - arbsys, err := precompilesgen.NewArbSys(types.ArbSysAddress, l2client) + arbsys, err := precompilesgen.NewArbSys(types.ArbSysAddress, testNode.L2Client) Require(t, err) top, err := arbsys.IsTopLevelCall(nil) Require(t, err) @@ -56,14 +56,14 @@ func TestAliasing(t *testing.T) { // check via L2 tx, err := simple.CheckCalls(&auth, top, direct, static, delegate, callcode, call) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) // check signed txes via L1 data, err := simpleContract.Pack("checkCalls", top, direct, static, delegate, callcode, call) Require(t, err) - tx = l2info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) - SendSignedTxViaL1(t, ctx, l1info, l1client, l2client, tx) + tx = testNode.L2Info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) + SendSignedTxViaL1(t, ctx, testNode.L1Info, testNode.L1Client, testNode.L2Client, tx) } testUnsigned := func(top, direct, static, delegate, callcode, call bool) { @@ -72,8 +72,8 @@ func TestAliasing(t *testing.T) { // check unsigned txes via L1 data, err := simpleContract.Pack("checkCalls", top, direct, static, delegate, callcode, call) Require(t, err) - tx := l2info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) - SendUnsignedTxViaL1(t, ctx, l1info, l1client, l2client, tx) + tx := testNode.L2Info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) + SendUnsignedTxViaL1(t, ctx, testNode.L1Info, testNode.L1Client, testNode.L2Client, tx) } testL2Signed(true, true, false, false, false, false) diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go index 9ad3253d4a..c61583adfb 100644 --- a/system_tests/bloom_test.go +++ b/system_tests/bloom_test.go @@ -28,14 +28,14 @@ func TestBloom(t *testing.T) { nodeconfig := arbnode.ConfigDefaultL2Test() nodeconfig.RPC.BloomBitsBlocks = 256 nodeconfig.RPC.BloomConfirms = 1 - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, false) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeconfig).CreateTestNodeOnL2Only(t, false) + defer testNode.L2Node.StopAndWait() - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") - ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) + ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) ownerTxOpts.Context = ctx - _, simple := deploySimple(t, ctx, ownerTxOpts, client) + _, simple := testNode.DeploySimple(t, ownerTxOpts) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) @@ -63,7 +63,7 @@ func TestBloom(t *testing.T) { if sendNullEvent { tx, err = simple.EmitNullEvent(&ownerTxOpts) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) } @@ -74,7 +74,7 @@ func TestBloom(t *testing.T) { tx, err = simple.Increment(&ownerTxOpts) } Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) if i%100 == 0 { t.Log("counts: ", i, "/", countsNum) @@ -82,7 +82,7 @@ func TestBloom(t *testing.T) { } for { - sectionSize, sectionNum := node.Execution.Backend.APIBackend().BloomStatus() + sectionSize, sectionNum := testNode.L2Node.Execution.Backend.APIBackend().BloomStatus() if sectionSize != 256 { Fatal(t, "unexpected section size: ", sectionSize) } @@ -92,14 +92,14 @@ func TestBloom(t *testing.T) { } <-time.After(time.Second) } - lastHeader, err := client.HeaderByNumber(ctx, nil) + lastHeader, err := testNode.L2Client.HeaderByNumber(ctx, nil) Require(t, err) nullEventQuery := ethereum.FilterQuery{ FromBlock: big.NewInt(0), ToBlock: lastHeader.Number, Topics: [][]common.Hash{{simpleABI.Events["NullEvent"].ID}}, } - logs, err := client.FilterLogs(ctx, nullEventQuery) + logs, err := testNode.L2Client.FilterLogs(ctx, nullEventQuery) Require(t, err) if len(logs) != len(nullEventCounts) { Fatal(t, "expected ", len(nullEventCounts), " logs, got ", len(logs)) @@ -107,7 +107,7 @@ func TestBloom(t *testing.T) { incrementEventQuery := ethereum.FilterQuery{ Topics: [][]common.Hash{{simpleABI.Events["CounterEvent"].ID}}, } - logs, err = client.FilterLogs(ctx, incrementEventQuery) + logs, err = testNode.L2Client.FilterLogs(ctx, incrementEventQuery) Require(t, err) if len(logs) != len(eventCounts) { Fatal(t, "expected ", len(eventCounts), " logs, got ", len(logs)) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 9fd002bd94..8c76baba31 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -57,6 +57,91 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) +type NodeBuilder struct { + // Nodebuilder configuration + ctx context.Context + chainConfig *params.ChainConfig + cacheConfig *core.CacheConfig + nodeConfig *arbnode.Config + l1StackConfig *node.Config + l2StackConfig *node.Config + isSequencer bool + + // L1 Nodebuilder fields + L1Info info + L1Client *ethclient.Client + L1Backend *eth.Ethereum + L1Stack *node.Node + + // L2 Nodebuilder fields + L2Info info + L2Client *ethclient.Client + L2Backend *eth.Ethereum + L2Node *arbnode.Node + L2Stack *node.Node + L2ChainDB ethdb.Database + L2NodeDB ethdb.Database + L2Blockchain *core.BlockChain +} + +func NewNodeBuilder(ctx context.Context) *NodeBuilder { + return &NodeBuilder{ctx: ctx} +} + +func (b *NodeBuilder) SetChainConfig(c *params.ChainConfig) *NodeBuilder { + b.chainConfig = c + return b +} + +func (b *NodeBuilder) SetNodeConfig(c *arbnode.Config) *NodeBuilder { + b.nodeConfig = c + return b +} + +func (b *NodeBuilder) SetCacheConfig(c *core.CacheConfig) *NodeBuilder { + b.cacheConfig = c + return b +} + +func (b *NodeBuilder) SetL1StackConfig(c *node.Config) *NodeBuilder { + b.l1StackConfig = c + return b +} + +func (b *NodeBuilder) SetL2StackConfig(c *node.Config) *NodeBuilder { + b.l2StackConfig = c + return b +} + +func (b *NodeBuilder) SetL1Info(l1Info info) *NodeBuilder { + b.L1Info = l1Info + return b +} + +func (b *NodeBuilder) SetL2Info(l2Info info) *NodeBuilder { + b.L2Info = l2Info + return b +} + +func (b *NodeBuilder) SetIsSequencer(v bool) *NodeBuilder { + b.isSequencer = v + return b +} + +func (b *NodeBuilder) CreateTestNodeOnL1AndL2(t *testing.T) *NodeBuilder { + b.L2Info, b.L2Node, b.L2Client, b.L2Stack, b.L1Info, b.L1Backend, b.L1Client, b.L1Stack = + createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.l2StackConfig, b.cacheConfig, b.L2Info) + return b +} + +func (b *NodeBuilder) CreateTestNodeOnL2Only(t *testing.T, takeOwnership bool) *NodeBuilder { + b.L2Info, b.L2Node, b.L2Client = CreateTestL2WithConfig(t, b.ctx, b.L2Info, b.nodeConfig, takeOwnership) + return b +} +func (b *NodeBuilder) DeploySimple(t *testing.T, auth bind.TransactOpts) (common.Address, *mocksgen.Simple) { + return deploySimple(t, b.ctx, auth, b.L2Client) +} + type info = *BlockchainTestInfo type client = arbutil.L1Interface @@ -639,12 +724,12 @@ func createTestNodeOnL1WithConfigImpl( // L2 -Only. Enough for tests that needs no interface to L1 // Requires precompiles.AllowDebugPrecompiles = true -func CreateTestL2(t *testing.T, ctx context.Context) (*BlockchainTestInfo, *arbnode.Node, *ethclient.Client) { - return CreateTestL2WithConfig(t, ctx, nil, arbnode.ConfigDefaultL2Test(), true) -} - func CreateTestL2WithConfig( - t *testing.T, ctx context.Context, l2Info *BlockchainTestInfo, nodeConfig *arbnode.Config, takeOwnership bool, + t *testing.T, + ctx context.Context, + l2Info *BlockchainTestInfo, + nodeConfig *arbnode.Config, + takeOwnership bool, ) (*BlockchainTestInfo, *arbnode.Node, *ethclient.Client) { feedErrChan := make(chan error, 10) diff --git a/system_tests/conditionaltx_test.go b/system_tests/conditionaltx_test.go index 14aa000313..f4b6dd85cf 100644 --- a/system_tests/conditionaltx_test.go +++ b/system_tests/conditionaltx_test.go @@ -203,42 +203,42 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, l2client, _, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - auth := l2info.GetDefaultTransactOpts("Owner", ctx) - contractAddress1, simple1 := deploySimple(t, ctx, auth, l2client) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + contractAddress1, simple1 := testNode.DeploySimple(t, auth) tx, err := simple1.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - contractAddress2, simple2 := deploySimple(t, ctx, auth, l2client) + contractAddress2, simple2 := testNode.DeploySimple(t, auth) tx, err = simple2.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) tx, err = simple2.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - currentRootHash1 := getStorageRootHash(t, node, contractAddress1) - currentSlotValueMap1 := getStorageSlotValue(t, node, contractAddress1) - currentRootHash2 := getStorageRootHash(t, node, contractAddress2) - currentSlotValueMap2 := getStorageSlotValue(t, node, contractAddress2) + currentRootHash1 := getStorageRootHash(t, testNode.L2Node, contractAddress1) + currentSlotValueMap1 := getStorageSlotValue(t, testNode.L2Node, contractAddress1) + currentRootHash2 := getStorageRootHash(t, testNode.L2Node, contractAddress2) + currentSlotValueMap2 := getStorageSlotValue(t, testNode.L2Node, contractAddress2) - rpcClient, err := node.Stack.Attach() + rpcClient, err := testNode.L2Node.Stack.Attach() Require(t, err) - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") - testConditionalTxThatShouldSucceed(t, ctx, -1, l2info, rpcClient, nil) + testConditionalTxThatShouldSucceed(t, ctx, -1, testNode.L2Info, rpcClient, nil) for i, options := range getEmptyOptions(contractAddress1) { - testConditionalTxThatShouldSucceed(t, ctx, i, l2info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, i, testNode.L2Info, rpcClient, options) } - block, err := l1client.BlockByNumber(ctx, nil) + block, err := testNode.L1Client.BlockByNumber(ctx, nil) Require(t, err) blockNumber := block.NumberU64() blockTime := block.Time() @@ -249,33 +249,33 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { options1 := dedupOptions(t, append(append(optionsAB, optionsA...), optionsB...)) options1 = optionsDedupProduct(t, options1, getFulfillableBlockTimeLimits(t, blockNumber, blockTime)) for i, options := range options1 { - testConditionalTxThatShouldSucceed(t, ctx, i, l2info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, i, testNode.L2Info, rpcClient, options) } tx, err = simple1.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) tx, err = simple2.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) previousStorageRootHash1 := currentRootHash1 - currentRootHash1 = getStorageRootHash(t, node, contractAddress1) + currentRootHash1 = getStorageRootHash(t, testNode.L2Node, contractAddress1) if bytes.Equal(previousStorageRootHash1.Bytes(), currentRootHash1.Bytes()) { Fatal(t, "storage root hash didn't change as expected") } - currentSlotValueMap1 = getStorageSlotValue(t, node, contractAddress1) + currentSlotValueMap1 = getStorageSlotValue(t, testNode.L2Node, contractAddress1) previousStorageRootHash2 := currentRootHash2 - currentRootHash2 = getStorageRootHash(t, node, contractAddress2) + currentRootHash2 = getStorageRootHash(t, testNode.L2Node, contractAddress2) if bytes.Equal(previousStorageRootHash2.Bytes(), currentRootHash2.Bytes()) { Fatal(t, "storage root hash didn't change as expected") } - currentSlotValueMap2 = getStorageSlotValue(t, node, contractAddress2) + currentSlotValueMap2 = getStorageSlotValue(t, testNode.L2Node, contractAddress2) - block, err = l1client.BlockByNumber(ctx, nil) + block, err = testNode.L1Client.BlockByNumber(ctx, nil) Require(t, err) blockNumber = block.NumberU64() blockTime = block.Time() @@ -286,35 +286,35 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { options2 := dedupOptions(t, append(append(optionsCD, optionsC...), optionsD...)) options2 = optionsDedupProduct(t, options2, getFulfillableBlockTimeLimits(t, blockNumber, blockTime)) for i, options := range options2 { - testConditionalTxThatShouldSucceed(t, ctx, i, l2info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, i, testNode.L2Info, rpcClient, options) } for i, options := range options1 { - testConditionalTxThatShouldFail(t, ctx, i, l2info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, i, testNode.L2Info, rpcClient, options, -32003) } - block, err = l1client.BlockByNumber(ctx, nil) + block, err = testNode.L1Client.BlockByNumber(ctx, nil) Require(t, err) blockNumber = block.NumberU64() blockTime = block.Time() options3 := optionsDedupProduct(t, options2, getUnfulfillableBlockTimeLimits(t, blockNumber, blockTime)) for i, options := range options3 { - testConditionalTxThatShouldFail(t, ctx, i, l2info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, i, testNode.L2Info, rpcClient, options, -32003) } options4 := optionsDedupProduct(t, options2, options1) for i, options := range options4 { - testConditionalTxThatShouldFail(t, ctx, i, l2info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, i, testNode.L2Info, rpcClient, options, -32003) } } func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() - rpcClient, err := node.Stack.Attach() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() + rpcClient, err := testNode.L2Node.Stack.Attach() Require(t, err) - auth := l2info.GetDefaultTransactOpts("Owner", ctx) - contractAddress, simple := deploySimple(t, ctx, auth, client) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + contractAddress, simple := testNode.DeploySimple(t, auth) simpleContract, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) Require(t, err) @@ -325,11 +325,11 @@ func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { var options []*arbitrum_types.ConditionalOptions for i := 0; i < numTxes; i++ { account := fmt.Sprintf("User%v", i) - l2info.GenerateAccount(account) - tx := l2info.PrepareTx("Owner", account, l2info.TransferGas, big.NewInt(1e16), nil) - err := client.SendTransaction(ctx, tx) + testNode.L2Info.GenerateAccount(account) + tx := testNode.L2Info.PrepareTx("Owner", account, testNode.L2Info.TransferGas, big.NewInt(1e16), nil) + err := testNode.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) } for i := numTxes - 1; i >= 0; i-- { @@ -337,7 +337,7 @@ func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { data, err := simpleContract.Pack("logAndIncrement", big.NewInt(int64(expected))) Require(t, err) account := fmt.Sprintf("User%v", i) - txes = append(txes, l2info.PrepareTxTo(account, &contractAddress, l2info.TransferGas, big.NewInt(0), data)) + txes = append(txes, testNode.L2Info.PrepareTxTo(account, &contractAddress, testNode.L2Info.TransferGas, big.NewInt(0), data)) options = append(options, &arbitrum_types.ConditionalOptions{KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{contractAddress: {SlotValue: map[common.Hash]common.Hash{{0}: common.BigToHash(big.NewInt(int64(expected)))}}}}) } ctxWithTimeout, cancelCtxWithTimeout := context.WithTimeout(ctx, 5*time.Second) @@ -367,7 +367,7 @@ func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { } cancelCtxWithTimeout() wg.Wait() - bc := node.Execution.Backend.ArbInterface().BlockChain() + bc := testNode.L2Node.Execution.Backend.ArbInterface().BlockChain() genesis := bc.Config().ArbitrumChainParams.GenesisBlockNum var receipts types.Receipts @@ -409,34 +409,34 @@ func TestSendRawTransactionConditionalPreCheck(t *testing.T) { nodeConfig.TxPreChecker.RequiredStateAge = 1 nodeConfig.TxPreChecker.RequiredStateMaxBlocks = 2 - l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, nil) - defer requireClose(t, l1stack) - defer node.StopAndWait() - rpcClient, err := node.Stack.Attach() + testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() + rpcClient, err := testNode.L2Node.Stack.Attach() Require(t, err) - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") - auth := l2info.GetDefaultTransactOpts("Owner", ctx) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) start := time.Now().Unix() - contractAddress, simple := deploySimple(t, ctx, auth, l2client) + contractAddress, simple := testNode.DeploySimple(t, auth) if time.Since(time.Unix(start, 0)) > 200*time.Millisecond { start++ time.Sleep(time.Until(time.Unix(start, 0))) } tx, err := simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - currentRootHash := getStorageRootHash(t, node, contractAddress) + currentRootHash := getStorageRootHash(t, testNode.L2Node, contractAddress) options := &arbitrum_types.ConditionalOptions{ KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{ contractAddress: {RootHash: ¤tRootHash}, }, } - testConditionalTxThatShouldFail(t, ctx, 0, l2info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, 0, testNode.L2Info, rpcClient, options, -32003) time.Sleep(time.Until(time.Unix(start+1, 0))) - testConditionalTxThatShouldSucceed(t, ctx, 1, l2info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, 1, testNode.L2Info, rpcClient, options) start = time.Now().Unix() if time.Since(time.Unix(start, 0)) > 200*time.Millisecond { @@ -445,23 +445,23 @@ func TestSendRawTransactionConditionalPreCheck(t *testing.T) { } tx, err = simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - currentRootHash = getStorageRootHash(t, node, contractAddress) + currentRootHash = getStorageRootHash(t, testNode.L2Node, contractAddress) options = &arbitrum_types.ConditionalOptions{ KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{ contractAddress: {RootHash: ¤tRootHash}, }, } - testConditionalTxThatShouldFail(t, ctx, 2, l2info, rpcClient, options, -32003) - tx = l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) - Require(t, l2client.SendTransaction(ctx, tx)) - _, err = EnsureTxSucceeded(ctx, l2client, tx) + testConditionalTxThatShouldFail(t, ctx, 2, testNode.L2Info, rpcClient, options, -32003) + tx = testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, big.NewInt(1e12), nil) + Require(t, testNode.L2Client.SendTransaction(ctx, tx)) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - testConditionalTxThatShouldFail(t, ctx, 3, l2info, rpcClient, options, -32003) - tx = l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) - Require(t, l2client.SendTransaction(ctx, tx)) - _, err = EnsureTxSucceeded(ctx, l2client, tx) + testConditionalTxThatShouldFail(t, ctx, 3, testNode.L2Info, rpcClient, options, -32003) + tx = testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, big.NewInt(1e12), nil) + Require(t, testNode.L2Client.SendTransaction(ctx, tx)) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - testConditionalTxThatShouldSucceed(t, ctx, 4, l2info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, 4, testNode.L2Info, rpcClient, options) } diff --git a/system_tests/contract_tx_test.go b/system_tests/contract_tx_test.go index e671dcc6ac..ff2912f539 100644 --- a/system_tests/contract_tx_test.go +++ b/system_tests/contract_tx_test.go @@ -26,19 +26,18 @@ func TestContractTxDeploy(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodeconfig := arbnode.ConfigDefaultL2Test() - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, false) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, false) + defer testNode.L2Node.StopAndWait() from := common.HexToAddress("0x123412341234") - TransferBalanceTo(t, "Faucet", from, big.NewInt(1e18), l2info, client, ctx) + TransferBalanceTo(t, "Faucet", from, big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) for stateNonce := uint64(0); stateNonce < 2; stateNonce++ { - pos, err := node.TxStreamer.GetMessageCount() + pos, err := testNode.L2Node.TxStreamer.GetMessageCount() Require(t, err) var delayedMessagesRead uint64 if pos > 0 { - lastMessage, err := node.TxStreamer.GetMessage(pos - 1) + lastMessage, err := testNode.L2Node.TxStreamer.GetMessage(pos - 1) Require(t, err) delayedMessagesRead = lastMessage.DelayedMessagesRead } @@ -70,7 +69,7 @@ func TestContractTxDeploy(t *testing.T) { l2Msg = append(l2Msg, math.U256Bytes(contractTx.Value)...) l2Msg = append(l2Msg, contractTx.Data...) - err = node.TxStreamer.AddMessages(pos, true, []arbostypes.MessageWithMetadata{ + err = testNode.L2Node.TxStreamer.AddMessages(pos, true, []arbostypes.MessageWithMetadata{ { Message: &arbostypes.L1IncomingMessage{ Header: &arbostypes.L1IncomingMessageHeader{ @@ -91,7 +90,7 @@ func TestContractTxDeploy(t *testing.T) { txHash := types.NewTx(contractTx).Hash() t.Log("made contract tx", contractTx, "with hash", txHash) - receipt, err := WaitForTx(ctx, client, txHash, time.Second*10) + receipt, err := WaitForTx(ctx, testNode.L2Client, txHash, time.Second*10) Require(t, err) if receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "Receipt has non-successful status", receipt.Status) @@ -104,7 +103,7 @@ func TestContractTxDeploy(t *testing.T) { t.Log("deployed contract", receipt.ContractAddress, "from address", from, "with nonce", stateNonce) stateNonce++ - code, err := client.CodeAt(ctx, receipt.ContractAddress, nil) + code, err := testNode.L2Client.CodeAt(ctx, receipt.ContractAddress, nil) Require(t, err) if !bytes.Equal(code, []byte{0xFE}) { Fatal(t, "expected contract", receipt.ContractAddress, "code of 0xFE but got", hex.EncodeToString(code)) diff --git a/system_tests/estimation_test.go b/system_tests/estimation_test.go index 26b5a78145..449f816bad 100644 --- a/system_tests/estimation_test.go +++ b/system_tests/estimation_test.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" + "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/node_interfacegen" @@ -26,17 +27,17 @@ func TestDeploy(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - auth := l2info.GetDefaultTransactOpts("Owner", ctx) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) auth.GasMargin = 0 // don't adjust, we want to see if the estimate alone is sufficient - _, simple := deploySimple(t, ctx, auth, client) + _, simple := testNode.DeploySimple(t, auth) tx, err := simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) counter, err := simple.Counter(&bind.CallOpts{}) @@ -51,24 +52,24 @@ func TestEstimate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - auth := l2info.GetDefaultTransactOpts("Owner", ctx) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) auth.GasMargin = 0 // don't adjust, we want to see if the estimate alone is sufficient gasPrice := big.NewInt(params.GWei / 10) // set the gas price - arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), client) + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), testNode.L2Client) Require(t, err, "could not deploy ArbOwner contract") tx, err := arbOwner.SetMinimumL2BaseFee(&auth, gasPrice) Require(t, err, "could not set L2 gas price") - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) // connect to arbGasInfo precompile - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) Require(t, err, "could not deploy contract") // wait for price to come to equilibrium @@ -76,8 +77,8 @@ func TestEstimate(t *testing.T) { numTriesLeft := 20 for !equilibrated && numTriesLeft > 0 { // make an empty block to let the gas price update - l2info.GasPrice = new(big.Int).Mul(l2info.GasPrice, big.NewInt(2)) - TransferBalance(t, "Owner", "Owner", common.Big0, l2info, client, ctx) + testNode.L2Info.GasPrice = new(big.Int).Mul(testNode.L2Info.GasPrice, big.NewInt(2)) + TransferBalance(t, "Owner", "Owner", common.Big0, testNode.L2Info, testNode.L2Client, ctx) // check if the price has equilibrated _, _, _, _, _, setPrice, err := arbGasInfo.GetPricesInWei(&bind.CallOpts{}) @@ -91,22 +92,22 @@ func TestEstimate(t *testing.T) { Fatal(t, "L2 gas price did not converge", gasPrice) } - initialBalance, err := client.BalanceAt(ctx, auth.From, nil) + initialBalance, err := testNode.L2Client.BalanceAt(ctx, auth.From, nil) Require(t, err, "could not get balance") // deploy a test contract - _, tx, simple, err := mocksgen.DeploySimple(&auth, client) + _, tx, simple, err := mocksgen.DeploySimple(&auth, testNode.L2Client) Require(t, err, "could not deploy contract") - receipt, err := EnsureTxSucceeded(ctx, client, tx) + receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - header, err := client.HeaderByNumber(ctx, receipt.BlockNumber) + header, err := testNode.L2Client.HeaderByNumber(ctx, receipt.BlockNumber) Require(t, err, "could not get header") if header.BaseFee.Cmp(gasPrice) != 0 { Fatal(t, "Header has wrong basefee", header.BaseFee, gasPrice) } - balance, err := client.BalanceAt(ctx, auth.From, nil) + balance, err := testNode.L2Client.BalanceAt(ctx, auth.From, nil) Require(t, err, "could not get balance") expectedCost := receipt.GasUsed * gasPrice.Uint64() observedCost := initialBalance.Uint64() - balance.Uint64() @@ -116,7 +117,7 @@ func TestEstimate(t *testing.T) { tx, err = simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) counter, err := simple.Counter(&bind.CallOpts{}) @@ -131,11 +132,11 @@ func TestComponentEstimate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() l1BaseFee := new(big.Int).Set(arbostypes.DefaultInitialL1BaseFee) - l2BaseFee := GetBaseFee(t, client, ctx) + l2BaseFee := GetBaseFee(t, testNode.L2Client, ctx) colors.PrintGrey("l1 basefee ", l1BaseFee) colors.PrintGrey("l2 basefee ", l2BaseFee) @@ -144,10 +145,10 @@ func TestComponentEstimate(t *testing.T) { maxPriorityFeePerGas := big.NewInt(0) maxFeePerGas := arbmath.BigMulByUfrac(l2BaseFee, 3, 2) - l2info.GenerateAccount("User") - TransferBalance(t, "Owner", "User", userBalance, l2info, client, ctx) + testNode.L2Info.GenerateAccount("User") + TransferBalance(t, "Owner", "User", userBalance, testNode.L2Info, testNode.L2Client, ctx) - from := l2info.GetAddress("User") + from := testNode.L2Info.GetAddress("User") to := testhelpers.RandomAddress() gas := uint64(100000000) calldata := []byte{0x00, 0x12} @@ -171,7 +172,7 @@ func TestComponentEstimate(t *testing.T) { Value: value, Data: estimateCalldata, } - returnData, err := client.CallContract(ctx, msg, nil) + returnData, err := testNode.L2Client.CallContract(ctx, msg, nil) Require(t, err) outputs, err := nodeMethod.Outputs.Unpack(returnData) @@ -185,8 +186,8 @@ func TestComponentEstimate(t *testing.T) { baseFee, _ := outputs[2].(*big.Int) l1BaseFeeEstimate, _ := outputs[3].(*big.Int) - tx := l2info.SignTxAs("User", &types.DynamicFeeTx{ - ChainID: node.Execution.ArbInterface.BlockChain().Config().ChainID, + tx := testNode.L2Info.SignTxAs("User", &types.DynamicFeeTx{ + ChainID: testNode.L2Node.Execution.ArbInterface.BlockChain().Config().ChainID, Nonce: 0, GasTipCap: maxPriorityFeePerGas, GasFeeCap: maxFeePerGas, @@ -207,8 +208,8 @@ func TestComponentEstimate(t *testing.T) { Fatal(t, baseFee, l2BaseFee.Uint64()) } - Require(t, client.SendTransaction(ctx, tx)) - receipt, err := EnsureTxSucceeded(ctx, client, tx) + Require(t, testNode.L2Client.SendTransaction(ctx, tx)) + receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) l2Used := receipt.GasUsed - receipt.GasUsedForL1 @@ -223,14 +224,14 @@ func TestDisableL1Charging(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() addr := common.HexToAddress("0x12345678") - gasWithL1Charging, err := client.EstimateGas(ctx, ethereum.CallMsg{To: &addr}) + gasWithL1Charging, err := testNode.L2Client.EstimateGas(ctx, ethereum.CallMsg{To: &addr}) Require(t, err) - gasWithoutL1Charging, err := client.EstimateGas(ctx, ethereum.CallMsg{To: &addr, SkipL1Charging: true}) + gasWithoutL1Charging, err := testNode.L2Client.EstimateGas(ctx, ethereum.CallMsg{To: &addr, SkipL1Charging: true}) Require(t, err) if gasWithL1Charging <= gasWithoutL1Charging { @@ -240,14 +241,14 @@ func TestDisableL1Charging(t *testing.T) { Fatal(t, "Incorrect gas estimate with disabled L1 charging") } - _, err = client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithL1Charging}, nil) + _, err = testNode.L2Client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithL1Charging}, nil) Require(t, err) - _, err = client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging}, nil) + _, err = testNode.L2Client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging}, nil) if err == nil { Fatal(t, "CallContract passed with insufficient gas") } - _, err = client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging, SkipL1Charging: true}, nil) + _, err = testNode.L2Client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging, SkipL1Charging: true}, nil) Require(t, err) } diff --git a/system_tests/infra_fee_test.go b/system_tests/infra_fee_test.go index 89f869576d..10f43547f0 100644 --- a/system_tests/infra_fee_test.go +++ b/system_tests/infra_fee_test.go @@ -25,45 +25,45 @@ func TestInfraFee(t *testing.T) { defer cancel() nodeconfig := arbnode.ConfigDefaultL2Test() - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, true) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeconfig).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") - ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) + ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) ownerTxOpts.Context = ctx - ownerCallOpts := l2info.GetDefaultCallOpts("Owner", ctx) + ownerCallOpts := testNode.L2Info.GetDefaultCallOpts("Owner", ctx) - arbowner, err := precompilesgen.NewArbOwner(common.HexToAddress("70"), client) + arbowner, err := precompilesgen.NewArbOwner(common.HexToAddress("70"), testNode.L2Client) Require(t, err) - arbownerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("6b"), client) + arbownerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("6b"), testNode.L2Client) Require(t, err) networkFeeAddr, err := arbownerPublic.GetNetworkFeeAccount(ownerCallOpts) Require(t, err) infraFeeAddr := common.BytesToAddress(crypto.Keccak256([]byte{3, 2, 6})) tx, err := arbowner.SetInfraFeeAccount(&ownerTxOpts, infraFeeAddr) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - _, simple := deploySimple(t, ctx, ownerTxOpts, client) + _, simple := testNode.DeploySimple(t, ownerTxOpts) - netFeeBalanceBefore, err := client.BalanceAt(ctx, networkFeeAddr, nil) + netFeeBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - infraFeeBalanceBefore, err := client.BalanceAt(ctx, infraFeeAddr, nil) + infraFeeBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) tx, err = simple.Increment(&ownerTxOpts) Require(t, err) - receipt, err := EnsureTxSucceeded(ctx, client, tx) + receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) l2GasUsed := receipt.GasUsed - receipt.GasUsedForL1 expectedFunds := arbmath.BigMulByUint(arbmath.UintToBig(l2pricing.InitialBaseFeeWei), l2GasUsed) expectedBalanceAfter := arbmath.BigAdd(infraFeeBalanceBefore, expectedFunds) - netFeeBalanceAfter, err := client.BalanceAt(ctx, networkFeeAddr, nil) + netFeeBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - infraFeeBalanceAfter, err := client.BalanceAt(ctx, infraFeeAddr, nil) + infraFeeBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) if !arbmath.BigEquals(netFeeBalanceBefore, netFeeBalanceAfter) { diff --git a/system_tests/initialization_test.go b/system_tests/initialization_test.go index c7797d35e6..cec68d693a 100644 --- a/system_tests/initialization_test.go +++ b/system_tests/initialization_test.go @@ -63,14 +63,14 @@ func TestInitContract(t *testing.T) { l2info.ArbInitData.Accounts = append(l2info.ArbInitData.Accounts, accountInfo) expectedSums[accountAddress] = sum } - _, node, client := CreateTestL2WithConfig(t, ctx, l2info, arbnode.ConfigDefaultL2Test(), true) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).SetL2Info(l2info).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() for accountAddress, sum := range expectedSums { msg := ethereum.CallMsg{ To: &accountAddress, } - res, err := client.CallContract(ctx, msg, big.NewInt(0)) + res, err := testNode.L2Client.CallContract(ctx, msg, big.NewInt(0)) Require(t, err) resBig := new(big.Int).SetBytes(res) if resBig.Cmp(sum) != 0 { diff --git a/system_tests/log_subscription_test.go b/system_tests/log_subscription_test.go index 5ee1732fb0..c64737bdcd 100644 --- a/system_tests/log_subscription_test.go +++ b/system_tests/log_subscription_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" ) @@ -19,21 +20,21 @@ func TestLogSubscription(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - auth := l2info.GetDefaultTransactOpts("Owner", ctx) - arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, client) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, testNode.L2Client) Require(t, err) logChan := make(chan types.Log, 128) - subscription, err := client.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, logChan) + subscription, err := testNode.L2Client.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, logChan) Require(t, err) defer subscription.Unsubscribe() tx, err := arbSys.WithdrawEth(&auth, common.Address{}) Require(t, err) - receipt, err := EnsureTxSucceeded(ctx, client, tx) + receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) if len(receipt.Logs) != 1 { @@ -52,6 +53,6 @@ func TestLogSubscription(t *testing.T) { if !reflect.DeepEqual(receiptLog, subscriptionLog) { Fatal(t, "Receipt log", receiptLog, "is different than subscription log", subscriptionLog) } - _, err = client.BlockByHash(ctx, subscriptionLog.BlockHash) + _, err = testNode.L2Client.BlockByHash(ctx, subscriptionLog.BlockHash) Require(t, err) } diff --git a/system_tests/outbox_test.go b/system_tests/outbox_test.go index 6b43cc83b0..e0db034111 100644 --- a/system_tests/outbox_test.go +++ b/system_tests/outbox_test.go @@ -16,6 +16,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/gethhook" "github.com/offchainlabs/nitro/solgen/go/node_interfacegen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" @@ -35,14 +36,14 @@ func TestOutboxProofs(t *testing.T) { withdrawTopic := arbSysAbi.Events["L2ToL1Tx"].ID merkleTopic := arbSysAbi.Events["SendMerkleUpdate"].ID - l2info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - auth := l2info.GetDefaultTransactOpts("Owner", ctx) + auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) - arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, client) + arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, testNode.L2Client) Require(t, err) - nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, client) + nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, testNode.L2Client) Require(t, err) txnCount := int64(1 + rand.Intn(16)) @@ -71,7 +72,7 @@ func TestOutboxProofs(t *testing.T) { txns = append(txns, tx.Hash()) time.Sleep(4 * time.Millisecond) // Geth takes a few ms for the receipt to show up - _, err = client.TransactionReceipt(ctx, tx.Hash()) + _, err = testNode.L2Client.TransactionReceipt(ctx, tx.Hash()) if err == nil { merkleState, err := arbSys.SendMerkleTreeState(&bind.CallOpts{}) Require(t, err, "could not get merkle root") @@ -86,7 +87,7 @@ func TestOutboxProofs(t *testing.T) { for _, tx := range txns { var receipt *types.Receipt - receipt, err = client.TransactionReceipt(ctx, tx) + receipt, err = testNode.L2Client.TransactionReceipt(ctx, tx) Require(t, err, "No receipt for txn") if receipt.Status != types.ReceiptStatusSuccessful { @@ -187,7 +188,7 @@ func TestOutboxProofs(t *testing.T) { // in one lookup, query geth for all the data we need to construct a proof var logs []types.Log if len(query) > 0 { - logs, err = client.FilterLogs(ctx, ethereum.FilterQuery{ + logs, err = testNode.L2Client.FilterLogs(ctx, ethereum.FilterQuery{ Addresses: []common.Address{ types.ArbSysAddress, }, diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index ad08ff7471..261c45035c 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" + "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" @@ -21,10 +22,10 @@ func TestPurePrecompileMethodCalls(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - arbSys, err := precompilesgen.NewArbSys(common.HexToAddress("0x64"), client) + arbSys, err := precompilesgen.NewArbSys(common.HexToAddress("0x64"), testNode.L2Client) Require(t, err, "could not deploy ArbSys contract") chainId, err := arbSys.ArbChainID(&bind.CallOpts{}) Require(t, err, "failed to get the ChainID") @@ -37,10 +38,10 @@ func TestViewLogReverts(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) Require(t, err, "could not deploy ArbSys contract") err = arbDebug.EventsView(nil) @@ -53,11 +54,11 @@ func TestCustomSolidityErrors(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() callOpts := &bind.CallOpts{Context: ctx} - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) Require(t, err, "could not bind ArbDebug contract") customError := arbDebug.CustomRevert(callOpts, 1024) if customError == nil { @@ -69,7 +70,7 @@ func TestCustomSolidityErrors(t *testing.T) { Fatal(t, observedMessage) } - arbSys, err := precompilesgen.NewArbSys(arbos.ArbSysAddress, client) + arbSys, err := precompilesgen.NewArbSys(arbos.ArbSysAddress, testNode.L2Client) Require(t, err, "could not bind ArbSys contract") _, customError = arbSys.ArbBlockHash(callOpts, big.NewInt(1e9)) if customError == nil { @@ -86,11 +87,11 @@ func TestPrecompileErrorGasLeft(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - auth := info.GetDefaultTransactOpts("Faucet", ctx) - _, _, simple, err := mocksgen.DeploySimple(&auth, client) + auth := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) + _, _, simple, err := mocksgen.DeploySimple(&auth, testNode.L2Client) Require(t, err) assertNotAllGasConsumed := func(to common.Address, input []byte) { diff --git a/system_tests/reorg_resequencing_test.go b/system_tests/reorg_resequencing_test.go index f132d46487..4f72f98233 100644 --- a/system_tests/reorg_resequencing_test.go +++ b/system_tests/reorg_resequencing_test.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/params" + "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos/arbostypes" ) @@ -19,27 +20,27 @@ func TestReorgResequencing(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, client := CreateTestL2(t, ctx) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - startMsgCount, err := node.TxStreamer.GetMessageCount() + startMsgCount, err := testNode.L2Node.TxStreamer.GetMessageCount() Require(t, err) - l2info.GenerateAccount("Intermediate") - l2info.GenerateAccount("User1") - l2info.GenerateAccount("User2") - l2info.GenerateAccount("User3") - l2info.GenerateAccount("User4") - TransferBalance(t, "Owner", "User1", big.NewInt(params.Ether), l2info, client, ctx) - TransferBalance(t, "Owner", "Intermediate", big.NewInt(params.Ether*3), l2info, client, ctx) - TransferBalance(t, "Intermediate", "User2", big.NewInt(params.Ether), l2info, client, ctx) - TransferBalance(t, "Intermediate", "User3", big.NewInt(params.Ether), l2info, client, ctx) + testNode.L2Info.GenerateAccount("Intermediate") + testNode.L2Info.GenerateAccount("User1") + testNode.L2Info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User3") + testNode.L2Info.GenerateAccount("User4") + TransferBalance(t, "Owner", "User1", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) + TransferBalance(t, "Owner", "Intermediate", big.NewInt(params.Ether*3), testNode.L2Info, testNode.L2Client, ctx) + TransferBalance(t, "Intermediate", "User2", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) + TransferBalance(t, "Intermediate", "User3", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) // Intermediate does not have exactly 1 ether because of fees accountsWithBalance := []string{"User1", "User2", "User3"} verifyBalances := func(scenario string) { for _, account := range accountsWithBalance { - balance, err := client.BalanceAt(ctx, l2info.GetAddress(account), nil) + balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress(account), nil) Require(t, err) if balance.Int64() != params.Ether { Fatal(t, "expected account", account, "to have a balance of 1 ether but instead it has", balance, "wei "+scenario) @@ -48,15 +49,15 @@ func TestReorgResequencing(t *testing.T) { } verifyBalances("before reorg") - err = node.TxStreamer.ReorgTo(startMsgCount) + err = testNode.L2Node.TxStreamer.ReorgTo(startMsgCount) Require(t, err) - _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = testNode.L2Node.Execution.ExecEngine.HeadMessageNumberSync(t) Require(t, err) verifyBalances("after empty reorg") - prevMessage, err := node.TxStreamer.GetMessage(startMsgCount - 1) + prevMessage, err := testNode.L2Node.TxStreamer.GetMessage(startMsgCount - 1) Require(t, err) delayedIndexHash := common.BigToHash(big.NewInt(int64(prevMessage.DelayedMessagesRead))) newMessage := &arbostypes.L1IncomingMessage{ @@ -68,24 +69,24 @@ func TestReorgResequencing(t *testing.T) { RequestId: &delayedIndexHash, L1BaseFee: common.Big0, }, - L2msg: append(l2info.GetAddress("User4").Bytes(), math.U256Bytes(big.NewInt(params.Ether))...), + L2msg: append(testNode.L2Info.GetAddress("User4").Bytes(), math.U256Bytes(big.NewInt(params.Ether))...), } - err = node.TxStreamer.AddMessages(startMsgCount, true, []arbostypes.MessageWithMetadata{{ + err = testNode.L2Node.TxStreamer.AddMessages(startMsgCount, true, []arbostypes.MessageWithMetadata{{ Message: newMessage, DelayedMessagesRead: prevMessage.DelayedMessagesRead + 1, }}) Require(t, err) - _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = testNode.L2Node.Execution.ExecEngine.HeadMessageNumberSync(t) Require(t, err) accountsWithBalance = append(accountsWithBalance, "User4") verifyBalances("after reorg with new deposit") - err = node.TxStreamer.ReorgTo(startMsgCount) + err = testNode.L2Node.TxStreamer.ReorgTo(startMsgCount) Require(t, err) - _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = testNode.L2Node.Execution.ExecEngine.HeadMessageNumberSync(t) Require(t, err) verifyBalances("after second empty reorg") diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index b1dd32d1dc..eb7d3528c4 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -32,25 +32,22 @@ import ( ) func retryableSetup(t *testing.T) ( - *BlockchainTestInfo, - *BlockchainTestInfo, - *ethclient.Client, - *ethclient.Client, + *NodeBuilder, *bridgegen.Inbox, func(*types.Receipt) *types.Transaction, context.Context, func(), ) { ctx, cancel := context.WithCancel(context.Background()) - l2info, l2node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - l2info.GenerateAccount("User2") - l2info.GenerateAccount("Beneficiary") - l2info.GenerateAccount("Burn") + testNode.L2Info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("Beneficiary") + testNode.L2Info.GenerateAccount("Burn") - delayedInbox, err := bridgegen.NewInbox(l1info.GetAddress("Inbox"), l1client) + delayedInbox, err := bridgegen.NewInbox(testNode.L1Info.GetAddress("Inbox"), testNode.L1Client) Require(t, err) - delayedBridge, err := arbnode.NewDelayedBridge(l1client, l1info.GetAddress("Bridge"), 0) + delayedBridge, err := arbnode.NewDelayedBridge(testNode.L1Client, testNode.L1Info.GetAddress("Bridge"), 0) Require(t, err) lookupL2Tx := func(l1Receipt *types.Receipt) *types.Transaction { @@ -90,15 +87,15 @@ func retryableSetup(t *testing.T) ( // burn some gas so that the faucet's Callvalue + Balance never exceeds a uint256 discard := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) - TransferBalance(t, "Faucet", "Burn", discard, l2info, l2client, ctx) + TransferBalance(t, "Faucet", "Burn", discard, testNode.L2Info, testNode.L2Client, ctx) teardown := func() { // check the integrity of the RPC - blockNum, err := l2client.BlockNumber(ctx) + blockNum, err := testNode.L2Client.BlockNumber(ctx) Require(t, err, "failed to get L2 block number") for number := uint64(0); number < blockNum; number++ { - block, err := l2client.BlockByNumber(ctx, arbmath.UintToBig(number)) + block, err := testNode.L2Client.BlockByNumber(ctx, arbmath.UintToBig(number)) Require(t, err, "failed to get L2 block", number, "of", blockNum) if block.Number().Uint64() != number { Fatal(t, "block number mismatch", number, block.Number().Uint64()) @@ -107,19 +104,20 @@ func retryableSetup(t *testing.T) ( cancel() - l2node.StopAndWait() - requireClose(t, l1stack) + testNode.L2Node.StopAndWait() + requireClose(t, testNode.L1Stack) } - return l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown + return testNode, delayedInbox, lookupL2Tx, ctx, teardown } func TestRetryableNoExist(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, node, l2client := CreateTestL2(t, ctx) - defer node.StopAndWait() - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), l2client) + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() + + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), testNode.L2Client) Require(t, err) _, err = arbRetryableTx.GetTimeout(&bind.CallOpts{}, common.Hash{}) if err.Error() != "execution reverted: error NoTicketWithID()" { @@ -129,20 +127,20 @@ func TestRetryableNoExist(t *testing.T) { func TestSubmitRetryableImmediateSuccess(t *testing.T) { t.Parallel() - l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - user2Address := l2info.GetAddress("User2") - beneficiaryAddress := l2info.GetAddress("Beneficiary") + user2Address := testNode.L2Info.GetAddress("User2") + beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") deposit := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) callValue := big.NewInt(1e6) - nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, l2client) + nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, testNode.L2Client) Require(t, err, "failed to deploy NodeInterface") // estimate the gas needed to auto redeem the retryable - usertxoptsL2 := l2info.GetDefaultTransactOpts("Faucet", ctx) + usertxoptsL2 := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL2.NoSend = true usertxoptsL2.GasMargin = 0 tx, err := nodeInterface.EstimateRetryableTicket( @@ -160,7 +158,7 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { colors.PrintBlue("estimate: ", estimate) // submit & auto redeem the retryable using the gas estimate - usertxoptsL1 := l1info.GetDefaultTransactOpts("Faucet", ctx) + usertxoptsL1 := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL1.Value = deposit l1tx, err := delayedInbox.CreateRetryableTicket( &usertxoptsL1, @@ -175,21 +173,21 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, l1client, l1info) + waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) - receipt, err := EnsureTxSucceeded(ctx, l2client, lookupL2Tx(l1Receipt)) + receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(l1Receipt)) Require(t, err) if receipt.Status != types.ReceiptStatusSuccessful { Fatal(t) } - l2balance, err := l2client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) Require(t, err) if !arbmath.BigEquals(l2balance, big.NewInt(1e6)) { @@ -199,18 +197,18 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { func TestSubmitRetryableFailThenRetry(t *testing.T) { t.Parallel() - l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) - usertxopts := l1info.GetDefaultTransactOpts("Faucet", ctx) + ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + usertxopts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) - simpleAddr, simple := deploySimple(t, ctx, ownerTxOpts, l2client) + simpleAddr, simple := testNode.DeploySimple(t, ownerTxOpts) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) - beneficiaryAddress := l2info.GetAddress("Beneficiary") + beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") l1tx, err := delayedInbox.CreateRetryableTicket( &usertxopts, simpleAddr, @@ -225,15 +223,15 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, l1client, l1info) + waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) - receipt, err := EnsureTxSucceeded(ctx, l2client, lookupL2Tx(l1Receipt)) + receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(l1Receipt)) Require(t, err) if len(receipt.Logs) != 2 { Fatal(t, len(receipt.Logs)) @@ -242,23 +240,23 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { firstRetryTxId := receipt.Logs[1].Topics[2] // get receipt for the auto redeem, make sure it failed - receipt, err = WaitForTx(ctx, l2client, firstRetryTxId, time.Second*5) + receipt, err = WaitForTx(ctx, testNode.L2Client, firstRetryTxId, time.Second*5) Require(t, err) if receipt.Status != types.ReceiptStatusFailed { Fatal(t, receipt.GasUsed) } - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), l2client) + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), testNode.L2Client) Require(t, err) tx, err := arbRetryableTx.Redeem(&ownerTxOpts, ticketId) Require(t, err) - receipt, err = EnsureTxSucceeded(ctx, l2client, tx) + receipt, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) retryTxId := receipt.Logs[0].Topics[2] // check the receipt for the retry - receipt, err = WaitForTx(ctx, l2client, retryTxId, time.Second*1) + receipt, err = WaitForTx(ctx, testNode.L2Client, retryTxId, time.Second*1) Require(t, err) if receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, receipt.Status) @@ -288,32 +286,32 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { func TestSubmissionGasCosts(t *testing.T) { t.Parallel() - l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, l2client, l2info) - elevateL2Basefee(t, ctx, l2client, l2info) + infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, testNode.L2Client, testNode.L2Info) + elevateL2Basefee(t, ctx, testNode.L2Client, testNode.L2Info) - usertxopts := l1info.GetDefaultTransactOpts("Faucet", ctx) + usertxopts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) - l2info.GenerateAccount("Refund") - l2info.GenerateAccount("Receive") - faucetAddress := util.RemapL1Address(l1info.GetAddress("Faucet")) - beneficiaryAddress := l2info.GetAddress("Beneficiary") - feeRefundAddress := l2info.GetAddress("Refund") - receiveAddress := l2info.GetAddress("Receive") + testNode.L2Info.GenerateAccount("Refund") + testNode.L2Info.GenerateAccount("Receive") + faucetAddress := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) + beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") + feeRefundAddress := testNode.L2Info.GetAddress("Refund") + receiveAddress := testNode.L2Info.GetAddress("Receive") colors.PrintBlue("Faucet ", faucetAddress) colors.PrintBlue("Receive ", receiveAddress) colors.PrintBlue("Beneficiary ", beneficiaryAddress) colors.PrintBlue("Fee Refund ", feeRefundAddress) - fundsBeforeSubmit, err := l2client.BalanceAt(ctx, faucetAddress, nil) + fundsBeforeSubmit, err := testNode.L2Client.BalanceAt(ctx, faucetAddress, nil) Require(t, err) - infraBalanceBefore, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceBefore, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) usefulGas := params.TxGas @@ -337,28 +335,28 @@ func TestSubmissionGasCosts(t *testing.T) { ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, l1client, l1info) + waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) submissionTxOuter := lookupL2Tx(l1Receipt) - submissionReceipt, err := EnsureTxSucceeded(ctx, l2client, submissionTxOuter) + submissionReceipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, submissionTxOuter) Require(t, err) if len(submissionReceipt.Logs) != 2 { Fatal(t, "Unexpected number of logs:", len(submissionReceipt.Logs)) } firstRetryTxId := submissionReceipt.Logs[1].Topics[2] // get receipt for the auto redeem - redeemReceipt, err := WaitForTx(ctx, l2client, firstRetryTxId, time.Second*5) + redeemReceipt, err := WaitForTx(ctx, testNode.L2Client, firstRetryTxId, time.Second*5) Require(t, err) if redeemReceipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "first retry tx failed") } - redeemBlock, err := l2client.HeaderByNumber(ctx, redeemReceipt.BlockNumber) + redeemBlock, err := testNode.L2Client.HeaderByNumber(ctx, redeemReceipt.BlockNumber) Require(t, err) l2BaseFee := redeemBlock.BaseFee @@ -366,18 +364,18 @@ func TestSubmissionGasCosts(t *testing.T) { excessWei := arbmath.BigMulByUint(l2BaseFee, excessGasLimit) excessWei.Add(excessWei, arbmath.BigMul(excessGasPrice, retryableGas)) - fundsAfterSubmit, err := l2client.BalanceAt(ctx, faucetAddress, nil) + fundsAfterSubmit, err := testNode.L2Client.BalanceAt(ctx, faucetAddress, nil) Require(t, err) - beneficiaryFunds, err := l2client.BalanceAt(ctx, beneficiaryAddress, nil) + beneficiaryFunds, err := testNode.L2Client.BalanceAt(ctx, beneficiaryAddress, nil) Require(t, err) - refundFunds, err := l2client.BalanceAt(ctx, feeRefundAddress, nil) + refundFunds, err := testNode.L2Client.BalanceAt(ctx, feeRefundAddress, nil) Require(t, err) - receiveFunds, err := l2client.BalanceAt(ctx, receiveAddress, nil) + receiveFunds, err := testNode.L2Client.BalanceAt(ctx, receiveAddress, nil) Require(t, err) - infraBalanceAfter, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceAfter, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) colors.PrintBlue("CallGas ", retryableGas) @@ -424,7 +422,7 @@ func TestSubmissionGasCosts(t *testing.T) { Fatal(t, "Supplied gas was improperly deducted\n", fundsBeforeSubmit, "\n", fundsAfterSubmit) } - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) Require(t, err) minimumBaseFee, err := arbGasInfo.GetMinimumGasPrice(&bind.CallOpts{Context: ctx}) Require(t, err) @@ -460,17 +458,17 @@ func waitForL1DelayBlocks(t *testing.T, ctx context.Context, l1client *ethclient func TestDepositETH(t *testing.T) { t.Parallel() - _, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - faucetAddr := l1info.GetAddress("Faucet") + faucetAddr := testNode.L1Info.GetAddress("Faucet") - oldBalance, err := l2client.BalanceAt(ctx, faucetAddr, nil) + oldBalance, err := testNode.L2Client.BalanceAt(ctx, faucetAddr, nil) if err != nil { t.Fatalf("BalanceAt(%v) unexpected error: %v", faucetAddr, err) } - txOpts := l1info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) txOpts.Value = big.NewInt(13) l1tx, err := delayedInbox.DepositEth0(&txOpts) @@ -478,20 +476,20 @@ func TestDepositETH(t *testing.T) { t.Fatalf("DepositEth0() unexected error: %v", err) } - l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) if err != nil { t.Fatalf("EnsureTxSucceeded() unexpected error: %v", err) } if l1Receipt.Status != types.ReceiptStatusSuccessful { t.Errorf("Got transaction status: %v, want: %v", l1Receipt.Status, types.ReceiptStatusSuccessful) } - waitForL1DelayBlocks(t, ctx, l1client, l1info) + waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) - l2Receipt, err := EnsureTxSucceeded(ctx, l2client, lookupL2Tx(l1Receipt)) + l2Receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(l1Receipt)) if err != nil { t.Fatalf("EnsureTxSucceeded unexpected error: %v", err) } - newBalance, err := l2client.BalanceAt(ctx, faucetAddr, l2Receipt.BlockNumber) + newBalance, err := testNode.L2Client.BalanceAt(ctx, faucetAddr, l2Receipt.BlockNumber) if err != nil { t.Fatalf("BalanceAt(%v) unexpected error: %v", faucetAddr, err) } @@ -501,13 +499,13 @@ func TestDepositETH(t *testing.T) { } func TestArbitrumContractTx(t *testing.T) { - l2Info, l1Info, l2Client, l1Client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - faucetL2Addr := util.RemapL1Address(l1Info.GetAddress("Faucet")) - TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), l2Info, l2Client, ctx) + faucetL2Addr := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) + TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) - l2TxOpts := l2Info.GetDefaultTransactOpts("Faucet", ctx) - l2ContractAddr, _ := deploySimple(t, ctx, l2TxOpts, l2Client) + l2TxOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) + l2ContractAddr, _ := testNode.DeploySimple(t, l2TxOpts) l2ContractABI, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) if err != nil { t.Fatalf("Error parsing contract ABI: %v", err) @@ -517,15 +515,15 @@ func TestArbitrumContractTx(t *testing.T) { t.Fatalf("Error packing method's call data: %v", err) } unsignedTx := types.NewTx(&types.ArbitrumContractTx{ - ChainId: l2Info.Signer.ChainID(), + ChainId: testNode.L2Info.Signer.ChainID(), From: faucetL2Addr, - GasFeeCap: l2Info.GasPrice.Mul(l2Info.GasPrice, big.NewInt(2)), + GasFeeCap: testNode.L2Info.GasPrice.Mul(testNode.L2Info.GasPrice, big.NewInt(2)), Gas: 1e6, To: &l2ContractAddr, Value: common.Big0, Data: data, }) - txOpts := l1Info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) l1tx, err := delayedInbox.SendContractTransaction( &txOpts, arbmath.UintToBig(unsignedTx.Gas()), @@ -537,15 +535,15 @@ func TestArbitrumContractTx(t *testing.T) { if err != nil { t.Fatalf("Error sending unsigned transaction: %v", err) } - receipt, err := EnsureTxSucceeded(ctx, l1Client, l1tx) + receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", l1tx.Hash(), err) } if receipt.Status != types.ReceiptStatusSuccessful { t.Errorf("L1 transaction: %v has failed", l1tx.Hash()) } - waitForL1DelayBlocks(t, ctx, l1Client, l1Info) - receipt, err = EnsureTxSucceeded(ctx, l2Client, lookupL2Tx(receipt)) + waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) + receipt, err = EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(receipt)) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", unsignedTx.Hash(), err) } @@ -554,17 +552,17 @@ func TestArbitrumContractTx(t *testing.T) { func TestL1FundedUnsignedTransaction(t *testing.T) { t.Parallel() ctx := context.Background() - l2Info, node, l2Client, l1Info, _, l1Client, l1Stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1Stack) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - faucetL2Addr := util.RemapL1Address(l1Info.GetAddress("Faucet")) + faucetL2Addr := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) // Transfer balance to Faucet's corresponding L2 address, so that there is // enough balance on its' account for executing L2 transaction. - TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), l2Info, l2Client, ctx) + TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) - l2TxOpts := l2Info.GetDefaultTransactOpts("Faucet", ctx) - contractAddr, _ := deploySimple(t, ctx, l2TxOpts, l2Client) + l2TxOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) + contractAddr, _ := testNode.DeploySimple(t, l2TxOpts) contractABI, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) if err != nil { t.Fatalf("Error parsing contract ABI: %v", err) @@ -573,27 +571,27 @@ func TestL1FundedUnsignedTransaction(t *testing.T) { if err != nil { t.Fatalf("Error packing method's call data: %v", err) } - nonce, err := l2Client.NonceAt(ctx, faucetL2Addr, nil) + nonce, err := testNode.L2Client.NonceAt(ctx, faucetL2Addr, nil) if err != nil { t.Fatalf("Error getting nonce at address: %v, error: %v", faucetL2Addr, err) } unsignedTx := types.NewTx(&types.ArbitrumUnsignedTx{ - ChainId: l2Info.Signer.ChainID(), + ChainId: testNode.L2Info.Signer.ChainID(), From: faucetL2Addr, Nonce: nonce, - GasFeeCap: l2Info.GasPrice, + GasFeeCap: testNode.L2Info.GasPrice, Gas: 1e6, To: &contractAddr, Value: common.Big0, Data: data, }) - delayedInbox, err := bridgegen.NewInbox(l1Info.GetAddress("Inbox"), l1Client) + delayedInbox, err := bridgegen.NewInbox(testNode.L1Info.GetAddress("Inbox"), testNode.L1Client) if err != nil { t.Fatalf("Error getting Go binding of L1 Inbox contract: %v", err) } - txOpts := l1Info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) l1tx, err := delayedInbox.SendUnsignedTransaction( &txOpts, arbmath.UintToBig(unsignedTx.Gas()), @@ -606,15 +604,15 @@ func TestL1FundedUnsignedTransaction(t *testing.T) { if err != nil { t.Fatalf("Error sending unsigned transaction: %v", err) } - receipt, err := EnsureTxSucceeded(ctx, l1Client, l1tx) + receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", l1tx.Hash(), err) } if receipt.Status != types.ReceiptStatusSuccessful { t.Errorf("L1 transaction: %v has failed", l1tx.Hash()) } - waitForL1DelayBlocks(t, ctx, l1Client, l1Info) - receipt, err = EnsureTxSucceeded(ctx, l2Client, unsignedTx) + waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) + receipt, err = EnsureTxSucceeded(ctx, testNode.L2Client, unsignedTx) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", unsignedTx.Hash(), err) } @@ -624,28 +622,28 @@ func TestL1FundedUnsignedTransaction(t *testing.T) { } func TestRetryableSubmissionAndRedeemFees(t *testing.T) { - l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, l2client, l2info) + infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, testNode.L2Client, testNode.L2Info) - ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) - simpleAddr, simple := deploySimple(t, ctx, ownerTxOpts, l2client) + ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + simpleAddr, simple := testNode.DeploySimple(t, ownerTxOpts) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) - elevateL2Basefee(t, ctx, l2client, l2info) + elevateL2Basefee(t, ctx, testNode.L2Client, testNode.L2Info) - infraBalanceBefore, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceBefore, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - beneficiaryAddress := l2info.GetAddress("Beneficiary") + beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") deposit := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) callValue := common.Big0 - usertxoptsL1 := l1info.GetDefaultTransactOpts("Faucet", ctx) + usertxoptsL1 := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL1.Value = deposit - baseFee := GetBaseFee(t, l2client, ctx) + baseFee := GetBaseFee(t, testNode.L2Client, ctx) l1tx, err := delayedInbox.CreateRetryableTicket( &usertxoptsL1, simpleAddr, @@ -659,16 +657,16 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { simpleABI.Methods["incrementRedeem"].ID, ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, l1client, l1info) + waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) submissionTxOuter := lookupL2Tx(l1Receipt) - submissionReceipt, err := EnsureTxSucceeded(ctx, l2client, submissionTxOuter) + submissionReceipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, submissionTxOuter) Require(t, err) if len(submissionReceipt.Logs) != 2 { Fatal(t, len(submissionReceipt.Logs)) @@ -676,36 +674,36 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { ticketId := submissionReceipt.Logs[0].Topics[1] firstRetryTxId := submissionReceipt.Logs[1].Topics[2] // get receipt for the auto redeem, make sure it failed - autoRedeemReceipt, err := WaitForTx(ctx, l2client, firstRetryTxId, time.Second*5) + autoRedeemReceipt, err := WaitForTx(ctx, testNode.L2Client, firstRetryTxId, time.Second*5) Require(t, err) if autoRedeemReceipt.Status != types.ReceiptStatusFailed { Fatal(t, "first retry tx shouldn't have succeeded") } - infraBalanceAfterSubmission, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceAfterSubmission, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceAfterSubmission, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceAfterSubmission, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - usertxoptsL2 := l2info.GetDefaultTransactOpts("Faucet", ctx) - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), l2client) + usertxoptsL2 := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), testNode.L2Client) Require(t, err) tx, err := arbRetryableTx.Redeem(&usertxoptsL2, ticketId) Require(t, err) - redeemReceipt, err := EnsureTxSucceeded(ctx, l2client, tx) + redeemReceipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) retryTxId := redeemReceipt.Logs[0].Topics[2] // check the receipt for the retry - retryReceipt, err := WaitForTx(ctx, l2client, retryTxId, time.Second*1) + retryReceipt, err := WaitForTx(ctx, testNode.L2Client, retryTxId, time.Second*1) Require(t, err) if retryReceipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "retry failed") } - infraBalanceAfterRedeem, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceAfterRedeem, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceAfterRedeem, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceAfterRedeem, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) // verify that the increment happened, so we know the retry succeeded @@ -734,11 +732,11 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { infraRedeemFee := arbmath.BigSub(infraBalanceAfterRedeem, infraBalanceAfterSubmission) networkRedeemFee := arbmath.BigSub(networkBalanceAfterRedeem, networkBalanceAfterSubmission) - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) Require(t, err) minimumBaseFee, err := arbGasInfo.GetMinimumGasPrice(&bind.CallOpts{Context: ctx}) Require(t, err) - submissionBaseFee := GetBaseFeeAt(t, l2client, ctx, submissionReceipt.BlockNumber) + submissionBaseFee := GetBaseFeeAt(t, testNode.L2Client, ctx, submissionReceipt.BlockNumber) submissionTx, ok := submissionTxOuter.GetInner().(*types.ArbitrumSubmitRetryableTx) if !ok { Fatal(t, "inner tx isn't ArbitrumSubmitRetryableTx") @@ -752,13 +750,13 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { retryableSubmissionFee, ) - retryTxOuter, _, err := l2client.TransactionByHash(ctx, retryTxId) + retryTxOuter, _, err := testNode.L2Client.TransactionByHash(ctx, retryTxId) Require(t, err) retryTx, ok := retryTxOuter.GetInner().(*types.ArbitrumRetryTx) if !ok { Fatal(t, "inner tx isn't ArbitrumRetryTx") } - redeemBaseFee := GetBaseFeeAt(t, l2client, ctx, redeemReceipt.BlockNumber) + redeemBaseFee := GetBaseFeeAt(t, testNode.L2Client, ctx, redeemReceipt.BlockNumber) t.Log("redeem base fee:", redeemBaseFee) // redeem & retry expected fees diff --git a/system_tests/seq_coordinator_test.go b/system_tests/seq_coordinator_test.go index b1f50c9436..27b7031dc9 100644 --- a/system_tests/seq_coordinator_test.go +++ b/system_tests/seq_coordinator_test.go @@ -62,8 +62,8 @@ func TestRedisSeqCoordinatorPriorities(t *testing.T) { createStartNode := func(nodeNum int) { nodeConfig.SeqCoordinator.MyUrl = nodeNames[nodeNum] - _, node, _ := CreateTestL2WithConfig(t, ctx, l2Info, nodeConfig, false) - nodes[nodeNum] = node + testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetL2Info(l2Info).CreateTestNodeOnL2Only(t, false) + nodes[nodeNum] = testNode.L2Node } trySequencing := func(nodeNum int) bool { diff --git a/system_tests/seq_nonce_test.go b/system_tests/seq_nonce_test.go index 968f141364..18363b9984 100644 --- a/system_tests/seq_nonce_test.go +++ b/system_tests/seq_nonce_test.go @@ -26,10 +26,10 @@ func TestSequencerParallelNonces(t *testing.T) { config := arbnode.ConfigDefaultL2Test() config.Sequencer.NonceFailureCacheExpiry = time.Minute - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, false) + defer testNode.L2Node.StopAndWait() - l2info.GenerateAccount("Destination") + testNode.L2Info.GenerateAccount("Destination") wg := sync.WaitGroup{} for thread := 0; thread < 10; thread++ { @@ -37,11 +37,11 @@ func TestSequencerParallelNonces(t *testing.T) { go func() { defer wg.Done() for i := 0; i < 10; i++ { - tx := l2info.PrepareTx("Owner", "Destination", l2info.TransferGas, common.Big1, nil) + tx := testNode.L2Info.PrepareTx("Owner", "Destination", testNode.L2Info.TransferGas, common.Big1, nil) // Sleep a random amount of time up to 20 milliseconds time.Sleep(time.Millisecond * time.Duration(rand.Intn(20))) t.Log("Submitting transaction with nonce", tx.Nonce()) - err := client.SendTransaction(ctx, tx) + err := testNode.L2Client.SendTransaction(ctx, tx) Require(t, err) t.Log("Got response for transaction with nonce", tx.Nonce()) } @@ -49,8 +49,8 @@ func TestSequencerParallelNonces(t *testing.T) { } wg.Wait() - addr := l2info.GetAddress("Destination") - balance, err := client.BalanceAt(ctx, addr, nil) + addr := testNode.L2Info.GetAddress("Destination") + balance, err := testNode.L2Client.BalanceAt(ctx, addr, nil) Require(t, err) if !arbmath.BigEquals(balance, big.NewInt(100)) { Fatal(t, "Unexpected user balance", balance) @@ -63,14 +63,14 @@ func TestSequencerNonceTooHigh(t *testing.T) { defer cancel() config := arbnode.ConfigDefaultL2Test() - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, false) + defer testNode.L2Node.StopAndWait() - l2info.GetInfoWithPrivKey("Owner").Nonce++ + testNode.L2Info.GetInfoWithPrivKey("Owner").Nonce++ before := time.Now() - tx := l2info.PrepareTx("Owner", "Owner", l2info.TransferGas, common.Big0, nil) - err := client.SendTransaction(ctx, tx) + tx := testNode.L2Info.PrepareTx("Owner", "Owner", testNode.L2Info.TransferGas, common.Big0, nil) + err := testNode.L2Client.SendTransaction(ctx, tx) if err == nil { Fatal(t, "No error when nonce was too high") } @@ -91,16 +91,16 @@ func TestSequencerNonceTooHighQueueFull(t *testing.T) { config := arbnode.ConfigDefaultL2Test() config.Sequencer.NonceFailureCacheSize = 5 config.Sequencer.NonceFailureCacheExpiry = time.Minute - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, false) + defer testNode.L2Node.StopAndWait() count := 15 var completed uint64 for i := 0; i < count; i++ { - l2info.GetInfoWithPrivKey("Owner").Nonce++ - tx := l2info.PrepareTx("Owner", "Owner", l2info.TransferGas, common.Big0, nil) + testNode.L2Info.GetInfoWithPrivKey("Owner").Nonce++ + tx := testNode.L2Info.PrepareTx("Owner", "Owner", testNode.L2Info.TransferGas, common.Big0, nil) go func() { - err := client.SendTransaction(ctx, tx) + err := testNode.L2Client.SendTransaction(ctx, tx) if err == nil { Fatal(t, "No error when nonce was too high") } diff --git a/system_tests/seq_pause_test.go b/system_tests/seq_pause_test.go index fd057c0181..8b919d73c6 100644 --- a/system_tests/seq_pause_test.go +++ b/system_tests/seq_pause_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/ethereum/go-ethereum/core/types" + "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbnode/execution" ) @@ -16,12 +17,12 @@ func TestSequencerPause(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info1, nodeA, client := CreateTestL2(t, ctx) - defer nodeA.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() const numUsers = 100 - prechecker, ok := nodeA.Execution.TxPublisher.(*execution.TxPreChecker) + prechecker, ok := testNode.L2Node.Execution.TxPublisher.(*execution.TxPreChecker) if !ok { t.Error("prechecker not found on node") } @@ -34,15 +35,15 @@ func TestSequencerPause(t *testing.T) { for num := 0; num < numUsers; num++ { userName := fmt.Sprintf("My_User_%d", num) - l2info1.GenerateAccount(userName) + testNode.L2Info.GenerateAccount(userName) users = append(users, userName) } for _, userName := range users { - tx := l2info1.PrepareTx("Owner", userName, l2info1.TransferGas, big.NewInt(1e16), nil) - err := client.SendTransaction(ctx, tx) + tx := testNode.L2Info.PrepareTx("Owner", userName, testNode.L2Info.TransferGas, big.NewInt(1e16), nil) + err := testNode.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) } @@ -51,7 +52,7 @@ func TestSequencerPause(t *testing.T) { var txs types.Transactions for _, userName := range users { - tx := l2info1.PrepareTx(userName, "Owner", l2info1.TransferGas, big.NewInt(2), nil) + tx := testNode.L2Info.PrepareTx(userName, "Owner", testNode.L2Info.TransferGas, big.NewInt(2), nil) txs = append(txs, tx) } @@ -62,7 +63,7 @@ func TestSequencerPause(t *testing.T) { }(tx) } - _, err := EnsureTxSucceededWithTimeout(ctx, client, txs[0], time.Second) + _, err := EnsureTxSucceededWithTimeout(ctx, testNode.L2Client, txs[0], time.Second) if err == nil { t.Error("tx passed while sequencer paused") } @@ -70,7 +71,7 @@ func TestSequencerPause(t *testing.T) { sequencer.Activate() for _, tx := range txs { - _, err := EnsureTxSucceeded(ctx, client, tx) + _, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) } } diff --git a/system_tests/seq_reject_test.go b/system_tests/seq_reject_test.go index 19c06c4bc3..811f5669d1 100644 --- a/system_tests/seq_reject_test.go +++ b/system_tests/seq_reject_test.go @@ -31,18 +31,18 @@ func TestSequencerRejection(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() feedErrChan := make(chan error, 10) - l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) - defer nodeA.StopAndWait() + testNode1 := NewNodeBuilder(ctx).SetNodeConfig(seqNodeConfig).CreateTestNodeOnL2Only(t, true) + defer testNode1.L2Node.StopAndWait() clientNodeConfig := arbnode.ConfigDefaultL2Test() - port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port + port := testNode1.L2Node.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) - defer nodeB.StopAndWait() + testNode2 := NewNodeBuilder(ctx).SetNodeConfig(clientNodeConfig).CreateTestNodeOnL2Only(t, false) + defer testNode2.L2Node.StopAndWait() - auth := l2info1.GetDefaultTransactOpts("Owner", ctx) - simpleAddr, _ := deploySimple(t, ctx, auth, client1) + auth := testNode1.L2Info.GetDefaultTransactOpts("Owner", ctx) + simpleAddr, _ := testNode1.DeploySimple(t, auth) simpleAbi, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) noopId := simpleAbi.Methods["noop"].ID @@ -51,7 +51,7 @@ func TestSequencerRejection(t *testing.T) { // Generate the accounts before hand to avoid races for user := 0; user < 9; user++ { name := fmt.Sprintf("User%v", user) - l2info1.GenerateAccount(name) + testNode1.L2Info.GenerateAccount(name) } wg := sync.WaitGroup{} @@ -59,24 +59,24 @@ func TestSequencerRejection(t *testing.T) { for user := 0; user < 9; user++ { user := user name := fmt.Sprintf("User%v", user) - tx := l2info1.PrepareTx("Owner", name, l2info1.TransferGas, big.NewInt(params.Ether), nil) + tx := testNode1.L2Info.PrepareTx("Owner", name, testNode1.L2Info.TransferGas, big.NewInt(params.Ether), nil) - err := client1.SendTransaction(ctx, tx) + err := testNode1.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client1, tx) + _, err = EnsureTxSucceeded(ctx, testNode1.L2Client, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client2, tx) + _, err = EnsureTxSucceeded(ctx, testNode2.L2Client, tx) Require(t, err) wg.Add(1) go func() { defer wg.Done() - info := l2info1.GetInfoWithPrivKey(name) + info := testNode1.L2Info.GetInfoWithPrivKey(name) txData := &types.DynamicFeeTx{ To: &simpleAddr, - Gas: l2info1.TransferGas + 10000, - GasFeeCap: arbmath.BigMulByUint(l2info1.GasPrice, 100), + Gas: testNode1.L2Info.TransferGas + 10000, + GasFeeCap: arbmath.BigMulByUint(testNode1.L2Info.GasPrice, 100), Value: common.Big0, } for atomic.LoadInt32(&stopBackground) == 0 { @@ -92,8 +92,8 @@ func TestSequencerRejection(t *testing.T) { txData.Nonce = 1 << 32 expectedErr = "nonce too high" } - tx = l2info1.SignTxAs(name, txData) - err = client1.SendTransaction(ctx, tx) + tx = testNode1.L2Info.SignTxAs(name, txData) + err = testNode1.L2Client.SendTransaction(ctx, tx) if err != nil && (expectedErr == "" || !strings.Contains(err.Error(), expectedErr)) { Require(t, err, "failed to send tx for user", user) } @@ -102,7 +102,7 @@ func TestSequencerRejection(t *testing.T) { } for i := 100; i >= 0; i-- { - block, err := client1.BlockNumber(ctx) + block, err := testNode1.L2Client.BlockNumber(ctx) Require(t, err) if block >= 200 { break @@ -120,11 +120,11 @@ func TestSequencerRejection(t *testing.T) { atomic.StoreInt32(&stopBackground, 1) wg.Wait() - header1, err := client1.HeaderByNumber(ctx, nil) + header1, err := testNode1.L2Client.HeaderByNumber(ctx, nil) Require(t, err) for i := 100; i >= 0; i-- { - header2, err := client2.HeaderByNumber(ctx, header1.Number) + header2, err := testNode2.L2Client.HeaderByNumber(ctx, header1.Number) if err != nil { select { case err := <-feedErrChan: @@ -132,8 +132,8 @@ func TestSequencerRejection(t *testing.T) { case <-time.After(time.Millisecond * 100): } if i == 0 { - client2Block, _ := client2.BlockNumber(ctx) - Fatal(t, "client2 failed to reach client1 block ", header1.Number, ", only reached block", client2Block) + client2Block, _ := testNode2.L2Client.BlockNumber(ctx) + Fatal(t, "Client2 failed to reach client1 block ", header1.Number, ", only reached block", client2Block) } continue } diff --git a/system_tests/seq_whitelist_test.go b/system_tests/seq_whitelist_test.go index 2d671dcdd6..351b031ca2 100644 --- a/system_tests/seq_whitelist_test.go +++ b/system_tests/seq_whitelist_test.go @@ -18,22 +18,22 @@ func TestSequencerWhitelist(t *testing.T) { config := arbnode.ConfigDefaultL2Test() config.Sequencer.SenderWhitelist = GetTestAddressForAccountName(t, "Owner").String() + "," + GetTestAddressForAccountName(t, "User").String() - l2info, l2node, client := CreateTestL2WithConfig(t, ctx, nil, config, true) - defer l2node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - l2info.GenerateAccount("User") - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User") + testNode.L2Info.GenerateAccount("User2") // Owner is on the whitelist - TransferBalance(t, "Owner", "User", big.NewInt(params.Ether), l2info, client, ctx) - TransferBalance(t, "Owner", "User2", big.NewInt(params.Ether), l2info, client, ctx) + TransferBalance(t, "Owner", "User", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) + TransferBalance(t, "Owner", "User2", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) // User is on the whitelist - TransferBalance(t, "User", "User2", big.NewInt(params.Ether/10), l2info, client, ctx) + TransferBalance(t, "User", "User2", big.NewInt(params.Ether/10), testNode.L2Info, testNode.L2Client, ctx) // User2 is *not* on the whitelist, therefore this should fail - tx := l2info.PrepareTx("User2", "User", l2info.TransferGas, big.NewInt(params.Ether/10), nil) - err := client.SendTransaction(ctx, tx) + tx := testNode.L2Info.PrepareTx("User2", "User", testNode.L2Info.TransferGas, big.NewInt(params.Ether/10), nil) + err := testNode.L2Client.SendTransaction(ctx, tx) if err == nil { Fatal(t, "transaction from user not on whitelist accepted") } diff --git a/system_tests/seqfeed_test.go b/system_tests/seqfeed_test.go index 23c0e44c02..0243c55e5d 100644 --- a/system_tests/seqfeed_test.go +++ b/system_tests/seqfeed_test.go @@ -44,28 +44,28 @@ func TestSequencerFeed(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() - l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) - defer nodeA.StopAndWait() + testNode1 := NewNodeBuilder(ctx).SetNodeConfig(seqNodeConfig).CreateTestNodeOnL2Only(t, true) + defer testNode1.L2Node.StopAndWait() clientNodeConfig := arbnode.ConfigDefaultL2Test() - port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port + port := testNode1.L2Node.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) - defer nodeB.StopAndWait() + testNode2 := NewNodeBuilder(ctx).SetNodeConfig(clientNodeConfig).CreateTestNodeOnL2Only(t, false) + defer testNode2.L2Node.StopAndWait() - l2info1.GenerateAccount("User2") + testNode1.L2Info.GenerateAccount("User2") - tx := l2info1.PrepareTx("Owner", "User2", l2info1.TransferGas, big.NewInt(1e12), nil) + tx := testNode1.L2Info.PrepareTx("Owner", "User2", testNode1.L2Info.TransferGas, big.NewInt(1e12), nil) - err := client1.SendTransaction(ctx, tx) + err := testNode1.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client1, tx) + _, err = EnsureTxSucceeded(ctx, testNode1.L2Client, tx) Require(t, err) - _, err = WaitForTx(ctx, client2, tx.Hash(), time.Second*5) + _, err = WaitForTx(ctx, testNode2.L2Client, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := client2.BalanceAt(ctx, l2info1.GetAddress("User2"), nil) + l2balance, err := testNode2.L2Client.BalanceAt(ctx, testNode1.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { t.Fatal("Unexpected balance:", l2balance) @@ -79,14 +79,14 @@ func TestRelayedSequencerFeed(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() - l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) - defer nodeA.StopAndWait() + testNode1 := NewNodeBuilder(ctx).SetNodeConfig(seqNodeConfig).CreateTestNodeOnL2Only(t, true) + defer testNode1.L2Node.StopAndWait() - bigChainId, err := client1.ChainID(ctx) + bigChainId, err := testNode1.L2Client.ChainID(ctx) Require(t, err) config := relay.ConfigDefault - port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port + port := testNode1.L2Node.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port config.Node.Feed.Input = *newBroadcastClientConfigTest(port) config.Node.Feed.Output = *newBroadcasterConfigTest() config.Chain.ID = bigChainId.Uint64() @@ -101,23 +101,23 @@ func TestRelayedSequencerFeed(t *testing.T) { clientNodeConfig := arbnode.ConfigDefaultL2Test() port = currentRelay.GetListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - _, nodeC, client3 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) - defer nodeC.StopAndWait() - StartWatchChanErr(t, ctx, feedErrChan, nodeC) + testNode3 := NewNodeBuilder(ctx).SetNodeConfig(clientNodeConfig).CreateTestNodeOnL2Only(t, false) + defer testNode3.L2Node.StopAndWait() + StartWatchChanErr(t, ctx, feedErrChan, testNode3.L2Node) - l2info1.GenerateAccount("User2") + testNode1.L2Info.GenerateAccount("User2") - tx := l2info1.PrepareTx("Owner", "User2", l2info1.TransferGas, big.NewInt(1e12), nil) + tx := testNode1.L2Info.PrepareTx("Owner", "User2", testNode1.L2Info.TransferGas, big.NewInt(1e12), nil) - err = client1.SendTransaction(ctx, tx) + err = testNode1.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client1, tx) + _, err = EnsureTxSucceeded(ctx, testNode1.L2Client, tx) Require(t, err) - _, err = WaitForTx(ctx, client3, tx.Hash(), time.Second*5) + _, err = WaitForTx(ctx, testNode3.L2Client, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := client3.BalanceAt(ctx, l2info1.GetAddress("User2"), nil) + l2balance, err := testNode3.L2Client.BalanceAt(ctx, testNode1.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { t.Fatal("Unexpected balance:", l2balance) diff --git a/system_tests/transfer_test.go b/system_tests/transfer_test.go index 2e3317907b..1c7e7cae17 100644 --- a/system_tests/transfer_test.go +++ b/system_tests/transfer_test.go @@ -8,28 +8,30 @@ import ( "fmt" "math/big" "testing" + + "github.com/offchainlabs/nitro/arbnode" ) func TestTransfer(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, l2node, client := CreateTestL2(t, ctx) - defer l2node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) + defer testNode.L2Node.StopAndWait() - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") - tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) + tx := testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, big.NewInt(1e12), nil) - err := client.SendTransaction(ctx, tx) + err := testNode.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - bal, err := client.BalanceAt(ctx, l2info.GetAddress("Owner"), nil) + bal, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("Owner"), nil) Require(t, err) fmt.Println("Owner balance is: ", bal) - bal2, err := client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + bal2, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) Require(t, err) if bal2.Cmp(big.NewInt(1e12)) != 0 { Fatal(t, "Unexpected recipient balance: ", bal2) From ecdb0a608834cc5ec2f1e20619181fe06892ca57 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Wed, 27 Sep 2023 10:43:10 -0500 Subject: [PATCH 02/54] refactor more impl --- system_tests/aliasing_test.go | 6 +- system_tests/arbtrace_test.go | 8 +- system_tests/batch_poster_test.go | 72 ++++++++-------- system_tests/block_hash_test.go | 10 +-- system_tests/block_validator_test.go | 56 ++++++------- system_tests/common_test.go | 106 ++++++++++++------------ system_tests/contract_tx_test.go | 2 +- system_tests/debugapi_test.go | 8 +- system_tests/delayedinbox_test.go | 14 ++-- system_tests/delayedinboxlong_test.go | 26 +++--- system_tests/estimation_test.go | 6 +- system_tests/fees_test.go | 72 ++++++++-------- system_tests/forwarder_test.go | 19 +++-- system_tests/ipc_test.go | 6 +- system_tests/meaningless_reorg_test.go | 34 ++++---- system_tests/nodeinterface_test.go | 14 ++-- system_tests/recreatestate_rpc_test.go | 24 +++--- system_tests/reorg_resequencing_test.go | 8 +- system_tests/retryable_test.go | 32 +++---- system_tests/seq_coordinator_test.go | 20 ++--- system_tests/seq_whitelist_test.go | 6 +- system_tests/seqcompensation_test.go | 22 ++--- system_tests/seqfeed_test.go | 32 +++---- system_tests/seqinbox_test.go | 58 ++++++------- system_tests/staker_test.go | 86 +++++++++---------- system_tests/twonodes_test.go | 24 +++--- system_tests/twonodeslong_test.go | 68 +++++++-------- 27 files changed, 419 insertions(+), 420 deletions(-) diff --git a/system_tests/aliasing_test.go b/system_tests/aliasing_test.go index 852a75720f..d7513fe0cc 100644 --- a/system_tests/aliasing_test.go +++ b/system_tests/aliasing_test.go @@ -28,7 +28,7 @@ func TestAliasing(t *testing.T) { auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) user := testNode.L1Info.GetDefaultTransactOpts("User", ctx) - TransferBalanceTo(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceToViaL2(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18)) simpleAddr, simple := testNode.DeploySimple(t, auth) simpleContract, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) @@ -63,7 +63,7 @@ func TestAliasing(t *testing.T) { data, err := simpleContract.Pack("checkCalls", top, direct, static, delegate, callcode, call) Require(t, err) tx = testNode.L2Info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) - SendSignedTxViaL1(t, ctx, testNode.L1Info, testNode.L1Client, testNode.L2Client, tx) + testNode.SendSignedTxViaL1(t, tx) } testUnsigned := func(top, direct, static, delegate, callcode, call bool) { @@ -73,7 +73,7 @@ func TestAliasing(t *testing.T) { data, err := simpleContract.Pack("checkCalls", top, direct, static, delegate, callcode, call) Require(t, err) tx := testNode.L2Info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) - SendUnsignedTxViaL1(t, ctx, testNode.L1Info, testNode.L1Client, testNode.L2Client, tx) + testNode.SendUnsignedTxViaL1(t, tx) } testL2Signed(true, true, false, false, false, false) diff --git a/system_tests/arbtrace_test.go b/system_tests/arbtrace_test.go index 4aab5c71bd..50575500de 100644 --- a/system_tests/arbtrace_test.go +++ b/system_tests/arbtrace_test.go @@ -147,11 +147,11 @@ func TestArbTraceForwarding(t *testing.T) { nodeConfig := arbnode.ConfigDefaultL1Test() nodeConfig.RPC.ClassicRedirect = ipcPath nodeConfig.RPC.ClassicRedirectTimeout = time.Second - _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nodeConfig, nil, nil, nil, nil) - defer requireClose(t, l1stack) - defer requireClose(t, l2stack) + testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer requireClose(t, testNode.L2Stack) - l2rpc, _ := l2stack.Attach() + l2rpc, _ := testNode.L2Stack.Attach() txArgs := callTxArgs{} traceTypes := []string{"trace"} blockNum := rpc.BlockNumberOrHash{} diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index 11bf92608b..0e1b1816cb 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -48,41 +48,41 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { conf := arbnode.ConfigDefaultL1Test() conf.BatchPoster.Enable = false conf.BatchPoster.RedisUrl = redisUrl - l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() - l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nil) + l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nil) defer nodeB.StopAndWait() - l2info.GenerateAccount("User2") + testNodeA.L2Info.GenerateAccount("User2") var txs []*types.Transaction for i := 0; i < 100; i++ { - tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, common.Big1, nil) + tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, common.Big1, nil) txs = append(txs, tx) - err := l2clientA.SendTransaction(ctx, tx) + err := testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) } for _, tx := range txs { - _, err := EnsureTxSucceeded(ctx, l2clientA, tx) + _, err := EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) } firstTxData, err := txs[0].MarshalBinary() Require(t, err) - seqTxOpts := l1info.GetDefaultTransactOpts("Sequencer", ctx) + seqTxOpts := testNodeA.L1Info.GetDefaultTransactOpts("Sequencer", ctx) conf.BatchPoster.Enable = true conf.BatchPoster.MaxSize = len(firstTxData) * 2 - startL1Block, err := l1client.BlockNumber(ctx) + startL1Block, err := testNodeA.L1Client.BlockNumber(ctx) Require(t, err) for i := 0; i < parallelBatchPosters; i++ { // Make a copy of the batch poster config so NewBatchPoster calling Validate() on it doesn't race batchPosterConfig := conf.BatchPoster - batchPoster, err := arbnode.NewBatchPoster(nil, nodeA.L1Reader, nodeA.InboxTracker, nodeA.TxStreamer, nodeA.SyncMonitor, func() *arbnode.BatchPosterConfig { return &batchPosterConfig }, nodeA.DeployInfo, &seqTxOpts, nil) + batchPoster, err := arbnode.NewBatchPoster(nil, testNodeA.L2Node.L1Reader, testNodeA.L2Node.InboxTracker, testNodeA.L2Node.TxStreamer, testNodeA.L2Node.SyncMonitor, func() *arbnode.BatchPosterConfig { return &batchPosterConfig }, testNodeA.L2Node.DeployInfo, &seqTxOpts, nil) Require(t, err) batchPoster.Start(ctx) defer batchPoster.StopAndWait() @@ -90,8 +90,8 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { lastTxHash := txs[len(txs)-1].Hash() for i := 90; i > 0; i-- { - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ + testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) time.Sleep(500 * time.Millisecond) _, err := l2clientB.TransactionReceipt(ctx, lastTxHash) @@ -107,9 +107,9 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { // However, setting the clique period to 1 slows everything else (including the L1 deployment for this test) down to a crawl. if false { // Make sure the batch poster is able to post multiple batches in one block - endL1Block, err := l1client.BlockNumber(ctx) + endL1Block, err := testNodeA.L1Client.BlockNumber(ctx) Require(t, err) - seqInbox, err := arbnode.NewSequencerInbox(l1client, nodeA.DeployInfo.SequencerInbox, 0) + seqInbox, err := arbnode.NewSequencerInbox(testNodeA.L1Client, testNodeA.L2Node.DeployInfo.SequencerInbox, 0) Require(t, err) batches, err := seqInbox.LookupBatchesInRange(ctx, new(big.Int).SetUint64(startL1Block), new(big.Int).SetUint64(endL1Block)) Require(t, err) @@ -129,7 +129,7 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { } } - l2balance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Sign() == 0 { @@ -144,22 +144,22 @@ func TestBatchPosterLargeTx(t *testing.T) { conf := arbnode.ConfigDefaultL1Test() conf.Sequencer.MaxTxDataSize = 110000 - l2info, nodeA, l2clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() - l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nil) + l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nil) defer nodeB.StopAndWait() data := make([]byte, 100000) _, err := rand.Read(data) Require(t, err) - faucetAddr := l2info.GetAddress("Faucet") - gas := l2info.TransferGas + 20000*uint64(len(data)) - tx := l2info.PrepareTxTo("Faucet", &faucetAddr, gas, common.Big0, data) - err = l2clientA.SendTransaction(ctx, tx) + faucetAddr := testNodeA.L2Info.GetAddress("Faucet") + gas := testNodeA.L2Info.TransferGas + 20000*uint64(len(data)) + tx := testNodeA.L2Info.PrepareTxTo("Faucet", &faucetAddr, gas, common.Big0, data) + err = testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - receiptA, err := EnsureTxSucceeded(ctx, l2clientA, tx) + receiptA, err := EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) receiptB, err := EnsureTxSucceededWithTimeout(ctx, l2clientB, tx, time.Second*30) Require(t, err) @@ -177,21 +177,21 @@ func TestBatchPosterKeepsUp(t *testing.T) { conf.BatchPoster.CompressionLevel = brotli.BestCompression conf.BatchPoster.MaxDelay = time.Hour conf.RPC.RPCTxFeeCap = 1000. - l2info, nodeA, l2clientA, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() - l2info.GasPrice = big.NewInt(100e9) + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() + testNodeA.L2Info.GasPrice = big.NewInt(100e9) go func() { data := make([]byte, 90000) _, err := rand.Read(data) Require(t, err) for { - gas := l2info.TransferGas + 20000*uint64(len(data)) - tx := l2info.PrepareTx("Faucet", "Faucet", gas, common.Big0, data) - err = l2clientA.SendTransaction(ctx, tx) + gas := testNodeA.L2Info.TransferGas + 20000*uint64(len(data)) + tx := testNodeA.L2Info.PrepareTx("Faucet", "Faucet", gas, common.Big0, data) + err = testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err := EnsureTxSucceeded(ctx, l2clientA, tx) + _, err := EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) } }() @@ -199,11 +199,11 @@ func TestBatchPosterKeepsUp(t *testing.T) { start := time.Now() for { time.Sleep(time.Second) - batches, err := nodeA.InboxTracker.GetBatchCount() + batches, err := testNodeA.L2Node.InboxTracker.GetBatchCount() Require(t, err) - postedMessages, err := nodeA.InboxTracker.GetBatchMessageCount(batches - 1) + postedMessages, err := testNodeA.L2Node.InboxTracker.GetBatchMessageCount(batches - 1) Require(t, err) - haveMessages, err := nodeA.TxStreamer.GetMessageCount() + haveMessages, err := testNodeA.L2Node.TxStreamer.GetMessageCount() Require(t, err) duration := time.Since(start) fmt.Printf("batches posted: %v over %v (%.2f batches/second)\n", batches, duration, float64(batches)/(float64(duration)/float64(time.Second))) diff --git a/system_tests/block_hash_test.go b/system_tests/block_hash_test.go index 2b8051242e..9ce752e65f 100644 --- a/system_tests/block_hash_test.go +++ b/system_tests/block_hash_test.go @@ -16,13 +16,13 @@ func TestBlockHash(t *testing.T) { defer cancel() // Even though we don't use the L1, we need to create this node on L1 to get accurate L1 block numbers - l2info, l2node, l2client, _, _, _, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer l2node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - auth := l2info.GetDefaultTransactOpts("Faucet", ctx) + auth := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) - _, _, simple, err := mocksgen.DeploySimple(&auth, l2client) + _, _, simple, err := mocksgen.DeploySimple(&auth, testNode.L2Client) Require(t, err) _, err = simple.CheckBlockHashes(&bind.CallOpts{Context: ctx}) diff --git a/system_tests/block_validator_test.go b/system_tests/block_validator_test.go index fa3d902b18..ae844612f6 100644 --- a/system_tests/block_validator_test.go +++ b/system_tests/block_validator_test.go @@ -50,20 +50,20 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops delayEvery = workloadLoops / 3 } - l2info, nodeA, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetIsSequencer(true).SetNodeConfig(l1NodeConfigA).SetChainConfig(chainConfig).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() - authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) + authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) validatorConfig := arbnode.ConfigDefaultL1NonSequencerTest() validatorConfig.BlockValidator.Enable = true validatorConfig.DataAvailability = l1NodeConfigA.DataAvailability validatorConfig.DataAvailability.RPCAggregator.Enable = false AddDefaultValNode(t, ctx, validatorConfig, !arbitrator) - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, validatorConfig, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, validatorConfig, nil) defer nodeB.StopAndWait() - l2info.GenerateAccount("User2") + testNodeA.L2Info.GenerateAccount("User2") perTransfer := big.NewInt(1e12) @@ -72,7 +72,7 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops var tx *types.Transaction if workload == ethSend { - tx = l2info.PrepareTx("Owner", "User2", l2info.TransferGas, perTransfer, nil) + tx = testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, perTransfer, nil) } else { var contractCode []byte var gas uint64 @@ -86,10 +86,10 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops contractCode = append(contractCode, byte(vm.CODECOPY)) contractCode = append(contractCode, byte(vm.PUSH0)) contractCode = append(contractCode, byte(vm.RETURN)) - basefee := GetBaseFee(t, l2client, ctx) + basefee := testNodeA.GetBaseFeeAtViaL2(t, nil) var err error - gas, err = l2client.EstimateGas(ctx, ethereum.CallMsg{ - From: l2info.GetAddress("Owner"), + gas, err = testNodeA.L2Client.EstimateGas(ctx, ethereum.CallMsg{ + From: testNodeA.L2Info.GetAddress("Owner"), GasPrice: basefee, Value: big.NewInt(0), Data: contractCode, @@ -101,14 +101,14 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops contractCode = append(contractCode, 0x60, 0x00, 0x60, 0x00, 0x52) // PUSH1 0 MSTORE } contractCode = append(contractCode, 0x60, 0x00, 0x56) // JUMP - gas = l2info.TransferGas*2 + l2pricing.InitialPerBlockGasLimitV6 + gas = testNodeA.L2Info.TransferGas*2 + l2pricing.InitialPerBlockGasLimitV6 } - tx = l2info.PrepareTxTo("Owner", nil, gas, common.Big0, contractCode) + tx = testNodeA.L2Info.PrepareTxTo("Owner", nil, gas, common.Big0, contractCode) } - err := l2client.SendTransaction(ctx, tx) + err := testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceededWithTimeout(ctx, l2client, tx, time.Second*5) + _, err = EnsureTxSucceededWithTimeout(ctx, testNodeA.L2Client, tx, time.Second*5) if workload != depleteGas { Require(t, err) } @@ -117,40 +117,40 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops } } } else { - auth := l2info.GetDefaultTransactOpts("Owner", ctx) + auth := testNodeA.L2Info.GetDefaultTransactOpts("Owner", ctx) // make auth a chain owner - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), l2client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNodeA.L2Client) Require(t, err) tx, err := arbDebug.BecomeChainOwner(&auth) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) - arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), l2client) + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), testNodeA.L2Client) Require(t, err) tx, err = arbOwner.ScheduleArbOSUpgrade(&auth, 11, 0) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) - tx = l2info.PrepareTxTo("Owner", nil, l2info.TransferGas, perTransfer, []byte{byte(vm.PUSH0)}) - err = l2client.SendTransaction(ctx, tx) + tx = testNodeA.L2Info.PrepareTxTo("Owner", nil, testNodeA.L2Info.TransferGas, perTransfer, []byte{byte(vm.PUSH0)}) + err = testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceededWithTimeout(ctx, l2client, tx, time.Second*5) + _, err = EnsureTxSucceededWithTimeout(ctx, testNodeA.L2Client, tx, time.Second*5) Require(t, err) } if workload != depleteGas { - delayedTx := l2info.PrepareTx("Owner", "User2", 30002, perTransfer, nil) - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - WrapL2ForDelayed(t, delayedTx, l1info, "User", 100000), + delayedTx := testNodeA.L2Info.PrepareTx("Owner", "User2", 30002, perTransfer, nil) + SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ + WrapL2ForDelayed(t, delayedTx, testNodeA.L1Info, "User", 100000), }) // give the inbox reader a bit of time to pick up the delayed message time.Sleep(time.Millisecond * 500) // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 30; i++ { - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ + testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } @@ -159,7 +159,7 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops } if workload == ethSend { - l2balance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) Require(t, err) expectedBalance := new(big.Int).Mul(perTransfer, big.NewInt(int64(workloadLoops+1))) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 8c76baba31..2d242dcd41 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -57,6 +57,9 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) +type info = *BlockchainTestInfo +type client = arbutil.L1Interface + type NodeBuilder struct { // Nodebuilder configuration ctx context.Context @@ -130,20 +133,54 @@ func (b *NodeBuilder) SetIsSequencer(v bool) *NodeBuilder { func (b *NodeBuilder) CreateTestNodeOnL1AndL2(t *testing.T) *NodeBuilder { b.L2Info, b.L2Node, b.L2Client, b.L2Stack, b.L1Info, b.L1Backend, b.L1Client, b.L1Stack = - createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.l2StackConfig, b.cacheConfig, b.L2Info) + createTestNodeOnL1AndL2Impl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.l2StackConfig, b.cacheConfig, b.L2Info) return b } func (b *NodeBuilder) CreateTestNodeOnL2Only(t *testing.T, takeOwnership bool) *NodeBuilder { - b.L2Info, b.L2Node, b.L2Client = CreateTestL2WithConfig(t, b.ctx, b.L2Info, b.nodeConfig, takeOwnership) + b.L2Info, b.L2Node, b.L2Client = createTestNodeOnL2OnlyImpl(t, b.ctx, b.L2Info, b.nodeConfig, takeOwnership) return b } -func (b *NodeBuilder) DeploySimple(t *testing.T, auth bind.TransactOpts) (common.Address, *mocksgen.Simple) { - return deploySimple(t, b.ctx, auth, b.L2Client) + +func (b *NodeBuilder) SendSignedTxViaL1(t *testing.T, transaction *types.Transaction) *types.Receipt { + return sendSignedTxViaL1Impl(t, b.ctx, b.L1Info, b.L1Client, b.L2Client, transaction) } -type info = *BlockchainTestInfo -type client = arbutil.L1Interface +func (b *NodeBuilder) SendUnsignedTxViaL1(t *testing.T, transaction *types.Transaction) *types.Receipt { + return sendUnsignedTxViaL1Impl(t, b.ctx, b.L1Info, b.L1Client, b.L2Client, transaction) +} + +func (b *NodeBuilder) BridgeBalance(t *testing.T, account string, amount *big.Int) (*types.Transaction, *types.Receipt) { + return bridgeBalanceImpl(t, account, amount, b.L1Info, b.L2Info, b.L1Client, b.L2Client, b.ctx) +} + +func (b *NodeBuilder) TransferBalanceViaL2(t *testing.T, from string, to string, amount *big.Int) (*types.Transaction, *types.Receipt) { + return transferBalanceToImpl(t, from, b.L2Info.GetAddress(to), amount, b.L2Info, b.L2Client, b.ctx) +} + +func (b *NodeBuilder) TransferBalanceViaL1(t *testing.T, from string, to string, amount *big.Int) (*types.Transaction, *types.Receipt) { + return transferBalanceToImpl(t, from, b.L1Info.GetAddress(to), amount, b.L1Info, b.L1Client, b.ctx) +} + +func (b *NodeBuilder) TransferBalanceToViaL2(t *testing.T, from string, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt) { + return transferBalanceToImpl(t, from, to, amount, b.L2Info, b.L2Client, b.ctx) +} + +func (b *NodeBuilder) TransferBalanceToViaL1(t *testing.T, from string, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt) { + return transferBalanceToImpl(t, from, to, amount, b.L1Info, b.L1Client, b.ctx) +} + +func (b *NodeBuilder) GetBaseFeeAtViaL2(t *testing.T, blockNum *big.Int) *big.Int { + return getBaseFeeAtImpl(t, b.L2Client, b.ctx, blockNum) +} + +func (b *NodeBuilder) GetBaseFeeAtViaL1(t *testing.T, blockNum *big.Int) *big.Int { + return getBaseFeeAtImpl(t, b.L1Client, b.ctx, blockNum) +} + +func (b *NodeBuilder) DeploySimple(t *testing.T, auth bind.TransactOpts) (common.Address, *mocksgen.Simple) { + return deploySimpleImpl(t, b.ctx, auth, b.L2Client) +} func SendWaitTestTransactions(t *testing.T, ctx context.Context, client client, txs []*types.Transaction) { t.Helper() @@ -156,14 +193,7 @@ func SendWaitTestTransactions(t *testing.T, ctx context.Context, client client, } } -func TransferBalance( - t *testing.T, from, to string, amount *big.Int, l2info info, client client, ctx context.Context, -) (*types.Transaction, *types.Receipt) { - t.Helper() - return TransferBalanceTo(t, from, l2info.GetAddress(to), amount, l2info, client, ctx) -} - -func TransferBalanceTo( +func transferBalanceToImpl( t *testing.T, from string, to common.Address, amount *big.Int, l2info info, client client, ctx context.Context, ) (*types.Transaction, *types.Receipt) { t.Helper() @@ -176,7 +206,7 @@ func TransferBalanceTo( } // if l2client is not nil - will wait until balance appears in l2 -func BridgeBalance( +func bridgeBalanceImpl( t *testing.T, account string, amount *big.Int, l1info info, l2info info, l1client client, l2client client, ctx context.Context, ) (*types.Transaction, *types.Receipt) { t.Helper() @@ -223,7 +253,7 @@ func BridgeBalance( if balance.Cmp(l2Balance) >= 0 { break } - TransferBalance(t, "Faucet", "User", big.NewInt(1), l1info, l1client, ctx) + transferBalanceToImpl(t, "Faucet", l1info.GetAddress("User"), big.NewInt(1), l1info, l1client, ctx) if i > 20 { Fatal(t, "bridging failed") } @@ -234,7 +264,7 @@ func BridgeBalance( return tx, res } -func SendSignedTxViaL1( +func sendSignedTxViaL1Impl( t *testing.T, ctx context.Context, l1info *BlockchainTestInfo, @@ -265,7 +295,7 @@ func SendSignedTxViaL1( return receipt } -func SendUnsignedTxViaL1( +func sendUnsignedTxViaL1Impl( t *testing.T, ctx context.Context, l1info *BlockchainTestInfo, @@ -316,13 +346,7 @@ func SendUnsignedTxViaL1( return receipt } -func GetBaseFee(t *testing.T, client client, ctx context.Context) *big.Int { - header, err := client.HeaderByNumber(ctx, nil) - Require(t, err) - return header.BaseFee -} - -func GetBaseFeeAt(t *testing.T, client client, ctx context.Context, blockNum *big.Int) *big.Int { +func getBaseFeeAtImpl(t *testing.T, client client, ctx context.Context, blockNum *big.Int) *big.Int { header, err := client.HeaderByNumber(ctx, blockNum) Require(t, err) return header.BaseFee @@ -634,33 +658,7 @@ func ClientForStack(t *testing.T, backend *node.Node) *ethclient.Client { } // Create and deploy L1 and arbnode for L2 -func createTestNodeOnL1( - t *testing.T, - ctx context.Context, - isSequencer bool, -) ( - l2info info, node *arbnode.Node, l2client *ethclient.Client, l1info info, - l1backend *eth.Ethereum, l1client *ethclient.Client, l1stack *node.Node, -) { - return createTestNodeOnL1WithConfig(t, ctx, isSequencer, nil, nil, nil) -} - -func createTestNodeOnL1WithConfig( - t *testing.T, - ctx context.Context, - isSequencer bool, - nodeConfig *arbnode.Config, - chainConfig *params.ChainConfig, - stackConfig *node.Config, -) ( - l2info info, currentNode *arbnode.Node, l2client *ethclient.Client, l1info info, - l1backend *eth.Ethereum, l1client *ethclient.Client, l1stack *node.Node, -) { - l2info, currentNode, l2client, _, l1info, l1backend, l1client, l1stack = createTestNodeOnL1WithConfigImpl(t, ctx, isSequencer, nodeConfig, chainConfig, stackConfig, nil, nil) - return -} - -func createTestNodeOnL1WithConfigImpl( +func createTestNodeOnL1AndL2Impl( t *testing.T, ctx context.Context, isSequencer bool, @@ -724,7 +722,7 @@ func createTestNodeOnL1WithConfigImpl( // L2 -Only. Enough for tests that needs no interface to L1 // Requires precompiles.AllowDebugPrecompiles = true -func CreateTestL2WithConfig( +func createTestNodeOnL2OnlyImpl( t *testing.T, ctx context.Context, l2Info *BlockchainTestInfo, @@ -990,7 +988,7 @@ func getDeadlineTimeout(t *testing.T, defaultTimeout time.Duration) time.Duratio return timeout } -func deploySimple( +func deploySimpleImpl( t *testing.T, ctx context.Context, auth bind.TransactOpts, client *ethclient.Client, ) (common.Address, *mocksgen.Simple) { addr, tx, simple, err := mocksgen.DeploySimple(&auth, client) diff --git a/system_tests/contract_tx_test.go b/system_tests/contract_tx_test.go index ff2912f539..8f6debdf37 100644 --- a/system_tests/contract_tx_test.go +++ b/system_tests/contract_tx_test.go @@ -30,7 +30,7 @@ func TestContractTxDeploy(t *testing.T) { defer testNode.L2Node.StopAndWait() from := common.HexToAddress("0x123412341234") - TransferBalanceTo(t, "Faucet", from, big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceToViaL2(t, "Faucet", from, big.NewInt(1e18)) for stateNonce := uint64(0); stateNonce < 2; stateNonce++ { pos, err := testNode.L2Node.TxStreamer.GetMessageCount() diff --git a/system_tests/debugapi_test.go b/system_tests/debugapi_test.go index ff28e2350c..dedf7d2949 100644 --- a/system_tests/debugapi_test.go +++ b/system_tests/debugapi_test.go @@ -14,11 +14,11 @@ import ( func TestDebugAPI(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil, nil, nil) - defer requireClose(t, l1stack) - defer requireClose(t, l2stack) + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer requireClose(t, testNode.L2Stack) - l2rpc, _ := l2stack.Attach() + l2rpc, _ := testNode.L2Stack.Attach() var dump state.Dump err := l2rpc.CallContext(ctx, &dump, "debug_dumpBlock", rpc.LatestBlockNumber) diff --git a/system_tests/delayedinbox_test.go b/system_tests/delayedinbox_test.go index e48cb37028..9830a06c7d 100644 --- a/system_tests/delayedinbox_test.go +++ b/system_tests/delayedinbox_test.go @@ -38,16 +38,16 @@ func TestDelayInboxSimple(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, l2node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer l2node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") - delayedTx := l2info.PrepareTx("Owner", "User2", 50001, big.NewInt(1e6), nil) - SendSignedTxViaL1(t, ctx, l1info, l1client, l2client, delayedTx) + delayedTx := testNode.L2Info.PrepareTx("Owner", "User2", 50001, big.NewInt(1e6), nil) + testNode.SendSignedTxViaL1(t, delayedTx) - l2balance, err := l2client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e6)) != 0 { Fatal(t, "Unexpected balance:", l2balance) diff --git a/system_tests/delayedinboxlong_test.go b/system_tests/delayedinboxlong_test.go index b1c8ea361b..cc41220ff6 100644 --- a/system_tests/delayedinboxlong_test.go +++ b/system_tests/delayedinboxlong_test.go @@ -25,11 +25,11 @@ func TestDelayInboxLong(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, l2node, l2client, l1info, l1backend, l1client, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer l2node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") fundsPerDelayed := int64(1000000) delayedMessages := int64(0) @@ -42,22 +42,22 @@ func TestDelayInboxLong(t *testing.T) { randNum := rand.Int() % messagesPerDelayed var l1tx *types.Transaction if randNum == 0 { - delayedTx := l2info.PrepareTx("Owner", "User2", 50001, big.NewInt(fundsPerDelayed), nil) - l1tx = WrapL2ForDelayed(t, delayedTx, l1info, "User", 100000) + delayedTx := testNode.L2Info.PrepareTx("Owner", "User2", 50001, big.NewInt(fundsPerDelayed), nil) + l1tx = WrapL2ForDelayed(t, delayedTx, testNode.L1Info, "User", 100000) lastDelayedMessage = delayedTx delayedMessages++ } else { - l1tx = l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) + l1tx = testNode.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) } l1Txs = append(l1Txs, l1tx) } // adding multiple messages in the same AddLocal to get them in the same L1 block - errs := l1backend.TxPool().AddLocals(l1Txs) + errs := testNode.L1Backend.TxPool().AddLocals(l1Txs) for _, err := range errs { Require(t, err) } // Checking every tx is expensive, so we just check the last, assuming that the others succeeded too - _, err := EnsureTxSucceeded(ctx, l1client, l1Txs[len(l1Txs)-1]) + _, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1Txs[len(l1Txs)-1]) Require(t, err) } @@ -68,14 +68,14 @@ func TestDelayInboxLong(t *testing.T) { // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 100; i++ { - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, testNode.L1Client, []*types.Transaction{ + testNode.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } - _, err := WaitForTx(ctx, l2client, lastDelayedMessage.Hash(), time.Second*5) + _, err := WaitForTx(ctx, testNode.L2Client, lastDelayedMessage.Hash(), time.Second*5) Require(t, err) - l2balance, err := l2client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(fundsPerDelayed*delayedMessages)) != 0 { Fatal(t, "Unexpected balance:", "balance", l2balance, "expected", fundsPerDelayed*delayedMessages) diff --git a/system_tests/estimation_test.go b/system_tests/estimation_test.go index 449f816bad..ae3fc39a72 100644 --- a/system_tests/estimation_test.go +++ b/system_tests/estimation_test.go @@ -78,7 +78,7 @@ func TestEstimate(t *testing.T) { for !equilibrated && numTriesLeft > 0 { // make an empty block to let the gas price update testNode.L2Info.GasPrice = new(big.Int).Mul(testNode.L2Info.GasPrice, big.NewInt(2)) - TransferBalance(t, "Owner", "Owner", common.Big0, testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceViaL2(t, "Owner", "Owner", common.Big0) // check if the price has equilibrated _, _, _, _, _, setPrice, err := arbGasInfo.GetPricesInWei(&bind.CallOpts{}) @@ -136,7 +136,7 @@ func TestComponentEstimate(t *testing.T) { defer testNode.L2Node.StopAndWait() l1BaseFee := new(big.Int).Set(arbostypes.DefaultInitialL1BaseFee) - l2BaseFee := GetBaseFee(t, testNode.L2Client, ctx) + l2BaseFee := testNode.GetBaseFeeAtViaL2(t, nil) colors.PrintGrey("l1 basefee ", l1BaseFee) colors.PrintGrey("l2 basefee ", l2BaseFee) @@ -146,7 +146,7 @@ func TestComponentEstimate(t *testing.T) { maxFeePerGas := arbmath.BigMulByUfrac(l2BaseFee, 3, 2) testNode.L2Info.GenerateAccount("User") - TransferBalance(t, "Owner", "User", userBalance, testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceViaL2(t, "Owner", "User", userBalance) from := testNode.L2Info.GetAddress("User") to := testhelpers.RandomAddress() diff --git a/system_tests/fees_test.go b/system_tests/fees_test.go index bdd998357e..5093b873da 100644 --- a/system_tests/fees_test.go +++ b/system_tests/fees_test.go @@ -33,19 +33,19 @@ func TestSequencerFeePaid(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, l2node, l2client, _, _, _, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer l2node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - version := l2node.Execution.ArbInterface.BlockChain().Config().ArbitrumChainParams.InitialArbOSVersion - callOpts := l2info.GetDefaultCallOpts("Owner", ctx) + version := testNode.L2Node.Execution.ArbInterface.BlockChain().Config().ArbitrumChainParams.InitialArbOSVersion + callOpts := testNode.L2Info.GetDefaultCallOpts("Owner", ctx) // get the network fee account - arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("0x6b"), l2client) + arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("0x6b"), testNode.L2Client) Require(t, err, "failed to deploy contract") - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) Require(t, err, "failed to deploy contract") - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), l2client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) Require(t, err, "failed to deploy contract") networkFeeAccount, err := arbOwnerPublic.GetNetworkFeeAccount(callOpts) Require(t, err, "could not get the network fee account") @@ -53,24 +53,24 @@ func TestSequencerFeePaid(t *testing.T) { l1Estimate, err := arbGasInfo.GetL1BaseFeeEstimate(callOpts) Require(t, err) - baseFee := GetBaseFee(t, l2client, ctx) - l2info.GasPrice = baseFee + baseFee := testNode.GetBaseFeeAtViaL2(t, nil) + testNode.L2Info.GasPrice = baseFee testFees := func(tip uint64) (*big.Int, *big.Int) { tipCap := arbmath.BigMulByUint(baseFee, tip) - txOpts := l2info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) txOpts.GasTipCap = tipCap gasPrice := arbmath.BigAdd(baseFee, tipCap) - networkBefore := GetBalance(t, ctx, l2client, networkFeeAccount) + networkBefore := GetBalance(t, ctx, testNode.L2Client, networkFeeAccount) tx, err := arbDebug.Events(&txOpts, true, [32]byte{}) Require(t, err) - receipt, err := EnsureTxSucceeded(ctx, l2client, tx) + receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) - networkAfter := GetBalance(t, ctx, l2client, networkFeeAccount) - l1Charge := arbmath.BigMulByUint(l2info.GasPrice, receipt.GasUsedForL1) + networkAfter := GetBalance(t, ctx, testNode.L2Client, networkFeeAccount) + l1Charge := arbmath.BigMulByUint(testNode.L2Info.GasPrice, receipt.GasUsedForL1) // the network should receive // 1. compute costs @@ -92,7 +92,7 @@ func TestSequencerFeePaid(t *testing.T) { l1GasBought := arbmath.BigDiv(l1Charge, l1Estimate).Uint64() l1ChargeExpected := arbmath.BigMulByUint(l1Estimate, txSize*params.TxDataNonZeroGasEIP2028) // L1 gas can only be charged in terms of L2 gas, so subtract off any rounding error from the expected value - l1ChargeExpected.Sub(l1ChargeExpected, new(big.Int).Mod(l1ChargeExpected, l2info.GasPrice)) + l1ChargeExpected.Sub(l1ChargeExpected, new(big.Int).Mod(l1ChargeExpected, testNode.L2Info.GasPrice)) colors.PrintBlue("bytes ", l1GasBought/params.TxDataNonZeroGasEIP2028, txSize) @@ -135,38 +135,38 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { conf := arbnode.ConfigDefaultL1Test() conf.DelayedSequencer.FinalizeDistance = 1 - l2info, node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, chainConfig, nil) - defer requireClose(t, l1stack) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(conf).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - ownerAuth := l2info.GetDefaultTransactOpts("Owner", ctx) + ownerAuth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) // make ownerAuth a chain owner - arbdebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), l2client) + arbdebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) Require(t, err) tx, err := arbdebug.BecomeChainOwner(&ownerAuth) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2client, tx) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) // use ownerAuth to set the L1 price per unit Require(t, err) - arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), l2client) + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), testNode.L2Client) Require(t, err) tx, err = arbOwner.SetL1PricePerUnit(&ownerAuth, arbmath.UintToBig(initialEstimate)) Require(t, err) - _, err = WaitForTx(ctx, l2client, tx.Hash(), time.Second*5) + _, err = WaitForTx(ctx, testNode.L2Client, tx.Hash(), time.Second*5) Require(t, err) - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) Require(t, err) lastEstimate, err := arbGasInfo.GetL1BaseFeeEstimate(&bind.CallOpts{Context: ctx}) Require(t, err) - lastBatchCount, err := node.InboxTracker.GetBatchCount() + lastBatchCount, err := testNode.L2Node.InboxTracker.GetBatchCount() Require(t, err) - l1Header, err := l1client.HeaderByNumber(ctx, nil) + l1Header, err := testNode.L1Client.HeaderByNumber(ctx, nil) Require(t, err) - rewardRecipientBalanceBefore := GetBalance(t, ctx, l2client, l1pricing.BatchPosterAddress) + rewardRecipientBalanceBefore := GetBalance(t, ctx, testNode.L2Client, l1pricing.BatchPosterAddress) timesPriceAdjusted := 0 colors.PrintBlue("Initial values") @@ -175,17 +175,17 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { numRetrogradeMoves := 0 for i := 0; i < 256; i++ { - tx, receipt := TransferBalance(t, "Owner", "Owner", common.Big1, l2info, l2client, ctx) - header, err := l2client.HeaderByHash(ctx, receipt.BlockHash) + tx, receipt := testNode.TransferBalanceViaL2(t, "Owner", "Owner", common.Big1) + header, err := testNode.L2Client.HeaderByHash(ctx, receipt.BlockHash) Require(t, err) - TransferBalance(t, "Faucet", "Faucet", common.Big1, l1info, l1client, ctx) // generate l1 traffic + testNode.TransferBalanceViaL1(t, "Faucet", "Faucet", common.Big1) // generate l1 traffic units := compressedTxSize(t, tx) * params.TxDataNonZeroGasEIP2028 estimatedL1FeePerUnit := arbmath.BigDivByUint(arbmath.BigMulByUint(header.BaseFee, receipt.GasUsedForL1), units) if !arbmath.BigEquals(lastEstimate, estimatedL1FeePerUnit) { - l1Header, err = l1client.HeaderByNumber(ctx, nil) + l1Header, err = testNode.L1Client.HeaderByNumber(ctx, nil) Require(t, err) callOpts := &bind.CallOpts{Context: ctx, BlockNumber: receipt.BlockNumber} @@ -234,7 +234,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { // see that the inbox advances for j := 16; j > 0; j-- { - newBatchCount, err := node.InboxTracker.GetBatchCount() + newBatchCount, err := testNode.L2Node.InboxTracker.GetBatchCount() Require(t, err) if newBatchCount > lastBatchCount { colors.PrintGrey("posted new batch ", newBatchCount) @@ -249,7 +249,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { } } - rewardRecipientBalanceAfter := GetBalance(t, ctx, l2client, chainConfig.ArbitrumChainParams.InitialChainOwner) + rewardRecipientBalanceAfter := GetBalance(t, ctx, testNode.L2Client, chainConfig.ArbitrumChainParams.InitialChainOwner) colors.PrintMint("reward recipient balance ", rewardRecipientBalanceBefore, " ➤ ", rewardRecipientBalanceAfter) colors.PrintMint("price changes ", timesPriceAdjusted) @@ -260,7 +260,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { Fatal(t, "reward recipient didn't get paid") } - arbAggregator, err := precompilesgen.NewArbAggregator(common.HexToAddress("0x6d"), l2client) + arbAggregator, err := precompilesgen.NewArbAggregator(common.HexToAddress("0x6d"), testNode.L2Client) Require(t, err) batchPosterAddresses, err := arbAggregator.GetBatchPosters(&bind.CallOpts{Context: ctx}) Require(t, err) @@ -268,7 +268,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { for _, bpAddr := range batchPosterAddresses { if bpAddr != l1pricing.BatchPosterAddress && bpAddr != l1pricing.L1PricerFundsPoolAddress { numReimbursed++ - bal, err := l1client.BalanceAt(ctx, bpAddr, nil) + bal, err := testNode.L1Client.BalanceAt(ctx, bpAddr, nil) Require(t, err) if bal.Sign() == 0 { Fatal(t, "Batch poster balance is zero for", bpAddr) diff --git a/system_tests/forwarder_test.go b/system_tests/forwarder_test.go index 0a954719d8..753f067ed2 100644 --- a/system_tests/forwarder_test.go +++ b/system_tests/forwarder_test.go @@ -40,9 +40,9 @@ func TestStaticForwarder(t *testing.T) { nodeConfigA := arbnode.ConfigDefaultL1Test() nodeConfigA.BatchPoster.Enable = false - l2info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, nil, stackConfig) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(nodeConfigA).SetL2StackConfig(stackConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() nodeConfigB := arbnode.ConfigDefaultL1Test() nodeConfigB.Sequencer.Enable = false @@ -51,18 +51,18 @@ func TestStaticForwarder(t *testing.T) { nodeConfigB.ForwardingTarget = ipcPath nodeConfigB.BatchPoster.Enable = false - clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nodeConfigB, nil) + clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfigB, nil) defer nodeB.StopAndWait() - l2info.GenerateAccount("User2") - tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, transferAmount, nil) + testNodeA.L2Info.GenerateAccount("User2") + tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, transferAmount, nil) err := clientB.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, clientA, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) - l2balance, err := clientA.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := testNodeA.L2Client.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(transferAmount) != 0 { @@ -105,7 +105,8 @@ func fallbackSequencer( nodeConfig.SeqCoordinator.Enable = opts.enableSecCoordinator nodeConfig.SeqCoordinator.RedisUrl = opts.redisUrl nodeConfig.SeqCoordinator.MyUrl = opts.ipcPath - return createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, stackConfig) + testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetL2StackConfig(stackConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + return testNode.L2Info, testNode.L2Node, testNode.L2Client, testNode.L1Info, testNode.L1Backend, testNode.L1Client, testNode.L1Stack } func createForwardingNode( diff --git a/system_tests/ipc_test.go b/system_tests/ipc_test.go index 01ecf859d8..fbac4156cc 100644 --- a/system_tests/ipc_test.go +++ b/system_tests/ipc_test.go @@ -24,9 +24,9 @@ func TestIpcRpc(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - _, l2node, _, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, nil, stackConf) - defer requireClose(t, l1stack) - defer l2node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetL2StackConfig(stackConf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() _, err := ethclient.Dial(ipcPath) Require(t, err) diff --git a/system_tests/meaningless_reorg_test.go b/system_tests/meaningless_reorg_test.go index 851bf38ce0..b30417a5af 100644 --- a/system_tests/meaningless_reorg_test.go +++ b/system_tests/meaningless_reorg_test.go @@ -20,24 +20,24 @@ func TestMeaninglessBatchReorg(t *testing.T) { defer cancel() conf := arbnode.ConfigDefaultL1Test() conf.BatchPoster.Enable = false - l2Info, arbNode, l2Client, l1Info, l1Backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) - defer requireClose(t, l1stack) - defer arbNode.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - seqInbox, err := bridgegen.NewSequencerInbox(l1Info.GetAddress("SequencerInbox"), l1Client) + seqInbox, err := bridgegen.NewSequencerInbox(testNode.L1Info.GetAddress("SequencerInbox"), testNode.L1Client) Require(t, err) - seqOpts := l1Info.GetDefaultTransactOpts("Sequencer", ctx) + seqOpts := testNode.L1Info.GetDefaultTransactOpts("Sequencer", ctx) tx, err := seqInbox.AddSequencerL2BatchFromOrigin(&seqOpts, big.NewInt(1), nil, big.NewInt(1), common.Address{}) Require(t, err) - batchReceipt, err := EnsureTxSucceeded(ctx, l1Client, tx) + batchReceipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, tx) Require(t, err) for i := 0; ; i++ { if i >= 500 { Fatal(t, "Failed to read batch from L1") } - msgNum, err := arbNode.Execution.ExecEngine.HeadMessageNumber() + msgNum, err := testNode.L2Node.Execution.ExecEngine.HeadMessageNumber() Require(t, err) if msgNum == 1 { break @@ -46,33 +46,33 @@ func TestMeaninglessBatchReorg(t *testing.T) { } time.Sleep(10 * time.Millisecond) } - metadata, err := arbNode.InboxTracker.GetBatchMetadata(1) + metadata, err := testNode.L2Node.InboxTracker.GetBatchMetadata(1) Require(t, err) originalBatchBlock := batchReceipt.BlockNumber.Uint64() if metadata.ParentChainBlock != originalBatchBlock { Fatal(t, "Posted batch in block", originalBatchBlock, "but metadata says L1 block was", metadata.ParentChainBlock) } - _, l2Receipt := TransferBalance(t, "Owner", "Owner", common.Big1, l2Info, l2Client, ctx) + _, l2Receipt := testNode.TransferBalanceViaL2(t, "Owner", "Owner", common.Big1) // Make the reorg larger to force the miner to discard transactions. // The miner usually collects transactions from deleted blocks and puts them in the mempool. // However, this code doesn't run on reorgs larger than 64 blocks for performance reasons. // Therefore, we make a bunch of small blocks to prevent the code from running. for j := uint64(0); j < 70; j++ { - TransferBalance(t, "Faucet", "Faucet", common.Big1, l1Info, l1Client, ctx) + testNode.TransferBalanceViaL1(t, "Faucet", "Faucet", common.Big1) } - parentBlock := l1Backend.BlockChain().GetBlockByNumber(batchReceipt.BlockNumber.Uint64() - 1) - err = l1Backend.BlockChain().ReorgToOldBlock(parentBlock) + parentBlock := testNode.L1Backend.BlockChain().GetBlockByNumber(batchReceipt.BlockNumber.Uint64() - 1) + err = testNode.L1Backend.BlockChain().ReorgToOldBlock(parentBlock) Require(t, err) // Produce a new l1Block so that the batch ends up in a different l1Block than before - TransferBalance(t, "User", "User", common.Big1, l1Info, l1Client, ctx) + testNode.TransferBalanceViaL1(t, "User", "User", common.Big1) tx, err = seqInbox.AddSequencerL2BatchFromOrigin(&seqOpts, big.NewInt(1), nil, big.NewInt(1), common.Address{}) Require(t, err) - newBatchReceipt, err := EnsureTxSucceeded(ctx, l1Client, tx) + newBatchReceipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, tx) Require(t, err) newBatchBlock := newBatchReceipt.BlockNumber.Uint64() @@ -86,7 +86,7 @@ func TestMeaninglessBatchReorg(t *testing.T) { if i >= 500 { Fatal(t, "Failed to read batch reorg from L1") } - metadata, err = arbNode.InboxTracker.GetBatchMetadata(1) + metadata, err = testNode.L2Node.InboxTracker.GetBatchMetadata(1) Require(t, err) if metadata.ParentChainBlock == newBatchBlock { break @@ -96,10 +96,10 @@ func TestMeaninglessBatchReorg(t *testing.T) { time.Sleep(10 * time.Millisecond) } - _, err = arbNode.InboxReader.GetSequencerMessageBytes(ctx, 1) + _, err = testNode.L2Node.InboxReader.GetSequencerMessageBytes(ctx, 1) Require(t, err) - l2Header, err := l2Client.HeaderByNumber(ctx, l2Receipt.BlockNumber) + l2Header, err := testNode.L2Client.HeaderByNumber(ctx, l2Receipt.BlockNumber) Require(t, err) if l2Header.Hash() != l2Receipt.BlockHash { diff --git a/system_tests/nodeinterface_test.go b/system_tests/nodeinterface_test.go index 167f2204cd..2f36fb1d7b 100644 --- a/system_tests/nodeinterface_test.go +++ b/system_tests/nodeinterface_test.go @@ -19,23 +19,23 @@ func TestL2BlockRangeForL1(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, node, l2client, l1info, _, _, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer node.StopAndWait() - user := l1info.GetDefaultTransactOpts("User", ctx) + testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() + user := testNode.L1Info.GetDefaultTransactOpts("User", ctx) numTransactions := 200 for i := 0; i < numTransactions; i++ { - TransferBalanceTo(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18), l2info, l2client, ctx) + testNode.TransferBalanceToViaL2(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18)) } - nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, l2client) + nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, testNode.L2Client) if err != nil { t.Fatalf("Error creating node interface: %v", err) } l1BlockNums := map[uint64]*[2]uint64{} - latestL2, err := l2client.BlockNumber(ctx) + latestL2, err := testNode.L2Client.BlockNumber(ctx) if err != nil { t.Fatalf("Error querying most recent l2 block: %v", err) } diff --git a/system_tests/recreatestate_rpc_test.go b/system_tests/recreatestate_rpc_test.go index 561085c3f3..22c4f47245 100644 --- a/system_tests/recreatestate_rpc_test.go +++ b/system_tests/recreatestate_rpc_test.go @@ -22,7 +22,7 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func prepareNodeWithHistory(t *testing.T, ctx context.Context, maxRecreateStateDepth int64, txCount uint64) (node *arbnode.Node, bc *core.BlockChain, db ethdb.Database, l2client *ethclient.Client, l2info info, cancel func()) { +func prepareNodeWithHistory(t *testing.T, ctx context.Context, maxRecreateStateDepth int64, txCount uint64) (*arbnode.Node, *core.BlockChain, ethdb.Database, *ethclient.Client, info, func()) { t.Helper() nodeConfig := arbnode.ConfigDefaultL1Test() nodeConfig.RPC.MaxRecreateStateDepth = maxRecreateStateDepth @@ -43,27 +43,27 @@ func prepareNodeWithHistory(t *testing.T, ctx context.Context, maxRecreateStateD SnapshotLimit: 256, SnapshotWait: true, } - l2info, node, l2client, _, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nodeConfig, nil, nil, cacheConfig, nil) - cancel = func() { - defer requireClose(t, l1stack) - defer node.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetCacheConfig(cacheConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + cancel := func() { + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() } - l2info.GenerateAccount("User2") + testNode.L2Info.GenerateAccount("User2") var txs []*types.Transaction for i := uint64(0); i < txCount; i++ { - tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, common.Big1, nil) + tx := testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, common.Big1, nil) txs = append(txs, tx) - err := l2client.SendTransaction(ctx, tx) + err := testNode.L2Client.SendTransaction(ctx, tx) testhelpers.RequireImpl(t, err) } for _, tx := range txs { - _, err := EnsureTxSucceeded(ctx, l2client, tx) + _, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) testhelpers.RequireImpl(t, err) } - bc = node.Execution.Backend.ArbInterface().BlockChain() - db = node.Execution.Backend.ChainDb() + bc := testNode.L2Node.Execution.Backend.ArbInterface().BlockChain() + db := testNode.L2Node.Execution.Backend.ChainDb() - return + return testNode.L2Node, bc, db, testNode.L2Client, testNode.L2Info, cancel } func fillHeaderCache(t *testing.T, bc *core.BlockChain, from, to uint64) { diff --git a/system_tests/reorg_resequencing_test.go b/system_tests/reorg_resequencing_test.go index 4f72f98233..0251969e37 100644 --- a/system_tests/reorg_resequencing_test.go +++ b/system_tests/reorg_resequencing_test.go @@ -31,10 +31,10 @@ func TestReorgResequencing(t *testing.T) { testNode.L2Info.GenerateAccount("User2") testNode.L2Info.GenerateAccount("User3") testNode.L2Info.GenerateAccount("User4") - TransferBalance(t, "Owner", "User1", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) - TransferBalance(t, "Owner", "Intermediate", big.NewInt(params.Ether*3), testNode.L2Info, testNode.L2Client, ctx) - TransferBalance(t, "Intermediate", "User2", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) - TransferBalance(t, "Intermediate", "User3", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceViaL2(t, "Owner", "User1", big.NewInt(params.Ether)) + testNode.TransferBalanceViaL2(t, "Owner", "Intermediate", big.NewInt(params.Ether*3)) + testNode.TransferBalanceViaL2(t, "Intermediate", "User2", big.NewInt(params.Ether)) + testNode.TransferBalanceViaL2(t, "Intermediate", "User3", big.NewInt(params.Ether)) // Intermediate does not have exactly 1 ether because of fees accountsWithBalance := []string{"User1", "User2", "User3"} diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index eb7d3528c4..61c258893c 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -87,7 +87,7 @@ func retryableSetup(t *testing.T) ( // burn some gas so that the faucet's Callvalue + Balance never exceeds a uint256 discard := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) - TransferBalance(t, "Faucet", "Burn", discard, testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceViaL2(t, "Faucet", "Burn", discard) teardown := func() { @@ -289,7 +289,7 @@ func TestSubmissionGasCosts(t *testing.T) { testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, testNode.L2Client, testNode.L2Info) - elevateL2Basefee(t, ctx, testNode.L2Client, testNode.L2Info) + elevateL2Basefee(t, ctx, testNode) usertxopts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) @@ -502,7 +502,7 @@ func TestArbitrumContractTx(t *testing.T) { testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() faucetL2Addr := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) - TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceToViaL2(t, "Faucet", faucetL2Addr, big.NewInt(1e18)) l2TxOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) l2ContractAddr, _ := testNode.DeploySimple(t, l2TxOpts) @@ -559,7 +559,7 @@ func TestL1FundedUnsignedTransaction(t *testing.T) { faucetL2Addr := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) // Transfer balance to Faucet's corresponding L2 address, so that there is // enough balance on its' account for executing L2 transaction. - TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceToViaL2(t, "Faucet", faucetL2Addr, big.NewInt(1e18)) l2TxOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) contractAddr, _ := testNode.DeploySimple(t, l2TxOpts) @@ -631,7 +631,7 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) - elevateL2Basefee(t, ctx, testNode.L2Client, testNode.L2Info) + elevateL2Basefee(t, ctx, testNode) infraBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) @@ -643,7 +643,7 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { callValue := common.Big0 usertxoptsL1 := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL1.Value = deposit - baseFee := GetBaseFee(t, testNode.L2Client, ctx) + baseFee := testNode.GetBaseFeeAtViaL2(t, nil) l1tx, err := delayedInbox.CreateRetryableTicket( &usertxoptsL1, simpleAddr, @@ -736,7 +736,7 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { Require(t, err) minimumBaseFee, err := arbGasInfo.GetMinimumGasPrice(&bind.CallOpts{Context: ctx}) Require(t, err) - submissionBaseFee := GetBaseFeeAt(t, testNode.L2Client, ctx, submissionReceipt.BlockNumber) + submissionBaseFee := testNode.GetBaseFeeAtViaL2(t, submissionReceipt.BlockNumber) submissionTx, ok := submissionTxOuter.GetInner().(*types.ArbitrumSubmitRetryableTx) if !ok { Fatal(t, "inner tx isn't ArbitrumSubmitRetryableTx") @@ -756,7 +756,7 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { if !ok { Fatal(t, "inner tx isn't ArbitrumRetryTx") } - redeemBaseFee := GetBaseFeeAt(t, testNode.L2Client, ctx, redeemReceipt.BlockNumber) + redeemBaseFee := testNode.GetBaseFeeAtViaL2(t, redeemReceipt.BlockNumber) t.Log("redeem base fee:", redeemBaseFee) // redeem & retry expected fees @@ -792,29 +792,29 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { } // elevateL2Basefee by burning gas exceeding speed limit -func elevateL2Basefee(t *testing.T, ctx context.Context, l2client *ethclient.Client, l2info *BlockchainTestInfo) { - baseFeeBefore := GetBaseFee(t, l2client, ctx) +func elevateL2Basefee(t *testing.T, ctx context.Context, testNode *NodeBuilder) { + baseFeeBefore := testNode.GetBaseFeeAtViaL2(t, nil) colors.PrintBlue("Elevating base fee...") arbostestabi, err := precompilesgen.ArbosTestMetaData.GetAbi() Require(t, err) - _, err = precompilesgen.NewArbosTest(common.HexToAddress("0x69"), l2client) + _, err = precompilesgen.NewArbosTest(common.HexToAddress("0x69"), testNode.L2Client) Require(t, err, "failed to deploy ArbosTest") burnAmount := arbnode.ConfigDefaultL1Test().RPC.RPCGasCap burnTarget := uint64(5 * l2pricing.InitialSpeedLimitPerSecondV6 * l2pricing.InitialBacklogTolerance) for i := uint64(0); i < (burnTarget+burnAmount)/burnAmount; i++ { burnArbGas := arbostestabi.Methods["burnArbGas"] - data, err := burnArbGas.Inputs.Pack(arbmath.UintToBig(burnAmount - l2info.TransferGas)) + data, err := burnArbGas.Inputs.Pack(arbmath.UintToBig(burnAmount - testNode.L2Info.TransferGas)) Require(t, err) input := append([]byte{}, burnArbGas.ID...) input = append(input, data...) to := common.HexToAddress("0x69") - tx := l2info.PrepareTxTo("Faucet", &to, burnAmount, big.NewInt(0), input) - Require(t, l2client.SendTransaction(ctx, tx)) - _, err = EnsureTxSucceeded(ctx, l2client, tx) + tx := testNode.L2Info.PrepareTxTo("Faucet", &to, burnAmount, big.NewInt(0), input) + Require(t, testNode.L2Client.SendTransaction(ctx, tx)) + _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) Require(t, err) } - baseFee := GetBaseFee(t, l2client, ctx) + baseFee := testNode.GetBaseFeeAtViaL2(t, nil) colors.PrintBlue("New base fee: ", baseFee, " diff:", baseFee.Uint64()-baseFeeBefore.Uint64()) } diff --git a/system_tests/seq_coordinator_test.go b/system_tests/seq_coordinator_test.go index 27b7031dc9..1e55e1c886 100644 --- a/system_tests/seq_coordinator_test.go +++ b/system_tests/seq_coordinator_test.go @@ -278,9 +278,9 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { initRedisForTest(t, ctx, nodeConfig.SeqCoordinator.RedisUrl, nodeNames) nodeConfig.SeqCoordinator.MyUrl = nodeNames[0] - l2Info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, params.ArbitrumDevTestChainConfig(), nil) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetChainConfig(params.ArbitrumDevTestChainConfig()).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() redisClient, err := redisutil.RedisClientFromURL(nodeConfig.SeqCoordinator.RedisUrl) Require(t, err) @@ -297,7 +297,7 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { break } - l2Info.GenerateAccount("User2") + testNodeA.L2Info.GenerateAccount("User2") nodeConfigDup := *nodeConfig nodeConfig = &nodeConfigDup @@ -305,23 +305,23 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { nodeConfig.SeqCoordinator.MyUrl = nodeNames[1] if !successCase { nodeConfig.SeqCoordinator.Signer.ECDSA.AcceptSequencer = false - nodeConfig.SeqCoordinator.Signer.ECDSA.AllowedAddresses = []string{l2Info.GetAddress("User2").Hex()} + nodeConfig.SeqCoordinator.Signer.ECDSA.AllowedAddresses = []string{testNodeA.L2Info.GetAddress("User2").Hex()} } - clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2Info.ArbInitData, nodeConfig, nil) + clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfig, nil) defer nodeB.StopAndWait() - tx := l2Info.PrepareTx("Owner", "User2", l2Info.TransferGas, big.NewInt(1e12), nil) + tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) - err = clientA.SendTransaction(ctx, tx) + err = testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, clientA, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) if successCase { _, err = WaitForTx(ctx, clientB, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := clientB.BalanceAt(ctx, l2Info.GetAddress("User2"), nil) + l2balance, err := clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { t.Fatal("Unexpected balance:", l2balance) diff --git a/system_tests/seq_whitelist_test.go b/system_tests/seq_whitelist_test.go index 351b031ca2..5275bf9ac6 100644 --- a/system_tests/seq_whitelist_test.go +++ b/system_tests/seq_whitelist_test.go @@ -25,11 +25,11 @@ func TestSequencerWhitelist(t *testing.T) { testNode.L2Info.GenerateAccount("User2") // Owner is on the whitelist - TransferBalance(t, "Owner", "User", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) - TransferBalance(t, "Owner", "User2", big.NewInt(params.Ether), testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceViaL2(t, "Owner", "User", big.NewInt(params.Ether)) + testNode.TransferBalanceViaL2(t, "Owner", "User2", big.NewInt(params.Ether)) // User is on the whitelist - TransferBalance(t, "User", "User2", big.NewInt(params.Ether/10), testNode.L2Info, testNode.L2Client, ctx) + testNode.TransferBalanceViaL2(t, "User", "User2", big.NewInt(params.Ether/10)) // User2 is *not* on the whitelist, therefore this should fail tx := testNode.L2Info.PrepareTx("User2", "User", testNode.L2Info.TransferGas, big.NewInt(params.Ether/10), nil) diff --git a/system_tests/seqcompensation_test.go b/system_tests/seqcompensation_test.go index 362acf6a30..39cf0771a4 100644 --- a/system_tests/seqcompensation_test.go +++ b/system_tests/seqcompensation_test.go @@ -18,19 +18,19 @@ func TestSequencerCompensation(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() - l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nil) + l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nil) defer nodeB.StopAndWait() - l2info.GenerateAccount("User2") + testNodeA.L2Info.GenerateAccount("User2") - tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) - err := l2clientA.SendTransaction(ctx, tx) + tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) + err := testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2clientA, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) // give the inbox reader a bit of time to pick up the delayed message @@ -38,8 +38,8 @@ func TestSequencerCompensation(t *testing.T) { // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 30; i++ { - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ + testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } @@ -47,7 +47,7 @@ func TestSequencerCompensation(t *testing.T) { Require(t, err) // clientB sees balance means sequencer message was sent - l2balance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { Fatal(t, "Unexpected balance:", l2balance) diff --git a/system_tests/seqfeed_test.go b/system_tests/seqfeed_test.go index 0243c55e5d..e89b8a58b8 100644 --- a/system_tests/seqfeed_test.go +++ b/system_tests/seqfeed_test.go @@ -135,11 +135,11 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigA.BatchPoster.Enable = true nodeConfigA.Feed.Output.Enable = false - l2infoA, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, chainConfig, nil) - defer requireClose(t, l1stack, "unable to close l1stack") - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(nodeConfigA).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack, "unable to close l1Stack") + defer testNodeA.L2Node.StopAndWait() - authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) + authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) // The lying sequencer nodeConfigC := arbnode.ConfigDefaultL1Test() @@ -147,7 +147,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigC.DataAvailability = nodeConfigA.DataAvailability nodeConfigC.DataAvailability.RPCAggregator.Enable = false nodeConfigC.Feed.Output = *newBroadcasterConfigTest() - l2clientC, nodeC := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigC, nil) + l2clientC, nodeC := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfigC, nil) defer nodeC.StopAndWait() port := nodeC.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port @@ -158,15 +158,15 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigB.Feed.Input = *newBroadcastClientConfigTest(port) nodeConfigB.DataAvailability = nodeConfigA.DataAvailability nodeConfigB.DataAvailability.RPCAggregator.Enable = false - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigB, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfigB, nil) defer nodeB.StopAndWait() - l2infoA.GenerateAccount("FraudUser") - l2infoA.GenerateAccount("RealUser") + testNodeA.L2Info.GenerateAccount("FraudUser") + testNodeA.L2Info.GenerateAccount("RealUser") - fraudTx := l2infoA.PrepareTx("Owner", "FraudUser", l2infoA.TransferGas, big.NewInt(1e12), nil) - l2infoA.GetInfoWithPrivKey("Owner").Nonce -= 1 // Use same l2info object for different l2s - realTx := l2infoA.PrepareTx("Owner", "RealUser", l2infoA.TransferGas, big.NewInt(1e12), nil) + fraudTx := testNodeA.L2Info.PrepareTx("Owner", "FraudUser", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) + testNodeA.L2Info.GetInfoWithPrivKey("Owner").Nonce -= 1 // Use same l2info object for different l2s + realTx := testNodeA.L2Info.PrepareTx("Owner", "RealUser", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) err := l2clientC.SendTransaction(ctx, fraudTx) if err != nil { @@ -183,7 +183,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { if err != nil { t.Fatal("error waiting for tx:", err) } - l2balance, err := l2clientB.BalanceAt(ctx, l2infoA.GetAddress("FraudUser"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("FraudUser"), nil) if err != nil { t.Fatal("error getting balance:", err) } @@ -192,12 +192,12 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { } // Send the real transaction to client A - err = l2clientA.SendTransaction(ctx, realTx) + err = testNodeA.L2Client.SendTransaction(ctx, realTx) if err != nil { t.Fatal("error sending real transaction:", err) } - _, err = EnsureTxSucceeded(ctx, l2clientA, realTx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, realTx) if err != nil { t.Fatal("error ensuring real transaction succeeded:", err) } @@ -207,7 +207,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { if err != nil { t.Fatal("error waiting for transaction to get to node b:", err) } - l2balanceFraudAcct, err := l2clientB.BalanceAt(ctx, l2infoA.GetAddress("FraudUser"), nil) + l2balanceFraudAcct, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("FraudUser"), nil) if err != nil { t.Fatal("error getting fraud balance:", err) } @@ -215,7 +215,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { t.Fatal("Unexpected balance (fraud acct should be empty) was:", l2balanceFraudAcct) } - l2balanceRealAcct, err := l2clientB.BalanceAt(ctx, l2infoA.GetAddress("RealUser"), nil) + l2balanceRealAcct, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("RealUser"), nil) if err != nil { t.Fatal("error getting real balance:", err) } diff --git a/system_tests/seqinbox_test.go b/system_tests/seqinbox_test.go index bf3e7c86c1..c7583ff1ff 100644 --- a/system_tests/seqinbox_test.go +++ b/system_tests/seqinbox_test.go @@ -47,18 +47,18 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { if validator { conf.BlockValidator.Enable = true } - l2Info, arbNode, _, l1Info, l1backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, false, conf, nil, nil) - l2Backend := arbNode.Execution.Backend - defer requireClose(t, l1stack) - defer arbNode.StopAndWait() + testNode := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(false).CreateTestNodeOnL1AndL2(t) + l2Backend := testNode.L2Node.Execution.Backend + defer requireClose(t, testNode.L1Stack) + defer testNode.L2Node.StopAndWait() - l1BlockChain := l1backend.BlockChain() + l1BlockChain := testNode.L1Backend.BlockChain() - seqInbox, err := bridgegen.NewSequencerInbox(l1Info.GetAddress("SequencerInbox"), l1Client) + seqInbox, err := bridgegen.NewSequencerInbox(testNode.L1Info.GetAddress("SequencerInbox"), testNode.L1Client) Require(t, err) - seqOpts := l1Info.GetDefaultTransactOpts("Sequencer", ctx) + seqOpts := testNode.L1Info.GetDefaultTransactOpts("Sequencer", ctx) - ownerAddress := l2Info.GetAddress("Owner") + ownerAddress := testNode.L2Info.GetAddress("Owner") var startL2BlockNumber uint64 = 0 startState, _, err := l2Backend.APIBackend().StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber) @@ -91,10 +91,10 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { } var faucetTxs []*types.Transaction for _, acct := range accounts { - l1Info.GenerateAccount(acct) - faucetTxs = append(faucetTxs, l1Info.PrepareTx("Faucet", acct, 30000, big.NewInt(1e16), nil)) + testNode.L1Info.GenerateAccount(acct) + faucetTxs = append(faucetTxs, testNode.L1Info.PrepareTx("Faucet", acct, 30000, big.NewInt(1e16), nil)) } - SendWaitTestTransactions(t, ctx, l1Client, faucetTxs) + SendWaitTestTransactions(t, ctx, testNode.L1Client, faucetTxs) for i := 1; i < seqInboxTestIters; i++ { if i%10 == 0 { @@ -106,7 +106,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { // The miner usually collects transactions from deleted blocks and puts them in the mempool. // However, this code doesn't run on reorgs larger than 64 blocks for performance reasons. // Therefore, we make a bunch of small blocks to prevent the code from running. - padAddr := l1Info.GetAddress("ReorgPadding") + padAddr := testNode.L1Info.GetAddress("ReorgPadding") for j := uint64(0); j < 70; j++ { rawTx := &types.DynamicFeeTx{ To: &padAddr, @@ -115,12 +115,12 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { Value: new(big.Int), Nonce: j, } - tx := l1Info.SignTxAs("ReorgPadding", rawTx) - Require(t, l1Client.SendTransaction(ctx, tx)) - _, _ = EnsureTxSucceeded(ctx, l1Client, tx) + tx := testNode.L1Info.SignTxAs("ReorgPadding", rawTx) + Require(t, testNode.L1Client.SendTransaction(ctx, tx)) + _, _ = EnsureTxSucceeded(ctx, testNode.L1Client, tx) } reorgTargetNumber := blockStates[reorgTo].l1BlockNumber - currentHeader, err := l1Client.HeaderByNumber(ctx, nil) + currentHeader, err := testNode.L1Client.HeaderByNumber(ctx, nil) Require(t, err) if currentHeader.Number.Int64()-int64(reorgTargetNumber) < 65 { Fatal(t, "Less than 65 blocks of difference between current block", currentHeader.Number, "and target", reorgTargetNumber) @@ -135,10 +135,10 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { // Sometimes, this causes it to drop the next tx. // To work around this, we create a sacrificial tx, which may or may not succeed. // Whichever happens, by the end of this block, the miner will have processed the reorg. - tx := l1Info.PrepareTx(fmt.Sprintf("ReorgSacrifice%v", i/10), "Faucet", 30000, big.NewInt(0), nil) - err = l1Client.SendTransaction(ctx, tx) + tx := testNode.L1Info.PrepareTx(fmt.Sprintf("ReorgSacrifice%v", i/10), "Faucet", 30000, big.NewInt(0), nil) + err = testNode.L1Client.SendTransaction(ctx, tx) Require(t, err) - _, _ = WaitForTx(ctx, l1Client, tx.Hash(), time.Second) + _, _ = WaitForTx(ctx, testNode.L1Client, tx.Hash(), time.Second) } else { state := blockStates[len(blockStates)-1] newBalances := make(map[common.Address]*big.Int) @@ -166,10 +166,10 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { var dest common.Address if j == 0 && amount.Cmp(reserveAmount) >= 0 { name := accountName(len(state.accounts)) - if !l2Info.HasAccount(name) { - l2Info.GenerateAccount(name) + if !testNode.L2Info.HasAccount(name) { + testNode.L2Info.GenerateAccount(name) } - dest = l2Info.GetAddress(name) + dest = testNode.L2Info.GetAddress(name) state.accounts = append(state.accounts, dest) state.balances[dest] = big.NewInt(0) } else { @@ -184,7 +184,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { Nonce: state.nonces[source], } state.nonces[source]++ - tx := l2Info.SignTxAs(accountName(sourceNum), rawTx) + tx := testNode.L2Info.SignTxAs(accountName(sourceNum), rawTx) txData, err := tx.MarshalBinary() Require(t, err) var segment []byte @@ -204,7 +204,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { seqNonce := len(blockStates) - 1 for j := 0; ; j++ { - haveNonce, err := l1Client.PendingNonceAt(ctx, seqOpts.From) + haveNonce, err := testNode.L1Client.PendingNonceAt(ctx, seqOpts.From) Require(t, err) if haveNonce == uint64(seqNonce) { break @@ -222,15 +222,15 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { tx, err = seqInbox.AddSequencerL2BatchFromOrigin(&seqOpts, big.NewInt(int64(len(blockStates))), batchData, big.NewInt(1), common.Address{}) } Require(t, err) - txRes, err := EnsureTxSucceeded(ctx, l1Client, tx) + txRes, err := EnsureTxSucceeded(ctx, testNode.L1Client, tx) if err != nil { // Geth's clique miner is finicky. // Unfortunately this is so rare that I haven't had an opportunity to test this workaround. // Specifically, I suspect there's a race where it thinks there's no txs to put in the new block, // if a new tx arrives at the same time as it tries to create a block. // Resubmit the transaction in an attempt to get the miner going again. - _ = l1Client.SendTransaction(ctx, tx) - txRes, err = EnsureTxSucceeded(ctx, l1Client, tx) + _ = testNode.L1Client.SendTransaction(ctx, tx) + txRes, err = EnsureTxSucceeded(ctx, testNode.L1Client, tx) Require(t, err) } @@ -267,9 +267,9 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { if validator && i%15 == 0 { for i := 0; ; i++ { - expectedPos, err := arbNode.Execution.ExecEngine.BlockNumberToMessageIndex(expectedBlockNumber) + expectedPos, err := testNode.L2Node.Execution.ExecEngine.BlockNumberToMessageIndex(expectedBlockNumber) Require(t, err) - lastValidated := arbNode.BlockValidator.Validated(t) + lastValidated := testNode.L2Node.BlockValidator.Validated(t) if lastValidated == expectedPos+1 { break } else if i >= 1000 { diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index 96ea1ee2e7..3a45b53905 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -64,9 +64,9 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) types.NewArbitrumSigner(types.NewLondonSigner(l2chainConfig.ChainID)), big.NewInt(l2pricing.InitialBaseFeeWei*2), transferGas, ) - _, l2nodeA, l2clientA, _, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, l2chainConfig, nil, nil, l2info) - defer requireClose(t, l1stack) - defer l2nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetIsSequencer(true).SetChainConfig(l2chainConfig).SetL2Info(l2info).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() if faultyStaker { l2info.GenerateGenesisAccount("FaultyAddr", common.Big1) @@ -75,10 +75,10 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) config.Sequencer.Enable = false config.DelayedSequencer.Enable = false config.BatchPoster.Enable = false - _, l2nodeB := Create2ndNodeWithConfig(t, ctx, l2nodeA, l1stack, l1info, &l2info.ArbInitData, config, nil) + _, l2nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &l2info.ArbInitData, config, nil) defer l2nodeB.StopAndWait() - nodeAGenesis := l2nodeA.Execution.Backend.APIBackend().CurrentHeader().Hash() + nodeAGenesis := testNodeA.L2Node.Execution.Backend.APIBackend().CurrentHeader().Hash() nodeBGenesis := l2nodeB.Execution.Backend.APIBackend().CurrentHeader().Hash() if faultyStaker { if nodeAGenesis == nodeBGenesis { @@ -90,51 +90,51 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) } } - BridgeBalance(t, "Faucet", big.NewInt(1).Mul(big.NewInt(params.Ether), big.NewInt(10000)), l1info, l2info, l1client, l2clientA, ctx) + testNodeA.BridgeBalance(t, "Faucet", big.NewInt(1).Mul(big.NewInt(params.Ether), big.NewInt(10000))) - deployAuth := l1info.GetDefaultTransactOpts("RollupOwner", ctx) + deployAuth := testNodeA.L1Info.GetDefaultTransactOpts("RollupOwner", ctx) balance := big.NewInt(params.Ether) balance.Mul(balance, big.NewInt(100)) - l1info.GenerateAccount("ValidatorA") - TransferBalance(t, "Faucet", "ValidatorA", balance, l1info, l1client, ctx) - l1authA := l1info.GetDefaultTransactOpts("ValidatorA", ctx) + testNodeA.L1Info.GenerateAccount("ValidatorA") + testNodeA.TransferBalanceViaL1(t, "Faucet", "ValidatorA", balance) + l1authA := testNodeA.L1Info.GetDefaultTransactOpts("ValidatorA", ctx) - l1info.GenerateAccount("ValidatorB") - TransferBalance(t, "Faucet", "ValidatorB", balance, l1info, l1client, ctx) - l1authB := l1info.GetDefaultTransactOpts("ValidatorB", ctx) + testNodeA.L1Info.GenerateAccount("ValidatorB") + testNodeA.TransferBalanceViaL1(t, "Faucet", "ValidatorB", balance) + l1authB := testNodeA.L1Info.GetDefaultTransactOpts("ValidatorB", ctx) - valWalletAddrAPtr, err := staker.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true) + valWalletAddrAPtr, err := staker.GetValidatorWalletContract(ctx, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, 0, &l1authA, testNodeA.L2Node.L1Reader, true) Require(t, err) valWalletAddrA := *valWalletAddrAPtr - valWalletAddrCheck, err := staker.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true) + valWalletAddrCheck, err := staker.GetValidatorWalletContract(ctx, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, 0, &l1authA, testNodeA.L2Node.L1Reader, true) Require(t, err) if valWalletAddrA == *valWalletAddrCheck { Require(t, err, "didn't cache validator wallet address", valWalletAddrA.String(), "vs", valWalletAddrCheck.String()) } - rollup, err := rollupgen.NewRollupAdminLogic(l2nodeA.DeployInfo.Rollup, l1client) + rollup, err := rollupgen.NewRollupAdminLogic(testNodeA.L2Node.DeployInfo.Rollup, testNodeA.L1Client) Require(t, err) tx, err := rollup.SetValidator(&deployAuth, []common.Address{valWalletAddrA, l1authB.From}, []bool{true, true}) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l1client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) Require(t, err) tx, err = rollup.SetMinimumAssertionPeriod(&deployAuth, big.NewInt(1)) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l1client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) Require(t, err) - validatorUtils, err := rollupgen.NewValidatorUtils(l2nodeA.DeployInfo.ValidatorUtils, l1client) + validatorUtils, err := rollupgen.NewValidatorUtils(testNodeA.L2Node.DeployInfo.ValidatorUtils, testNodeA.L1Client) Require(t, err) valConfig := staker.TestL1ValidatorConfig - dpA, err := arbnode.StakerDataposter(rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), l2nodeA.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) + dpA, err := arbnode.StakerDataposter(rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), testNodeA.L2Node.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) if err != nil { t.Fatalf("Error creating validator dataposter: %v", err) } - valWalletA, err := staker.NewContractValidatorWallet(dpA, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, &l1authA, 0, func(common.Address) {}, func() uint64 { return valConfig.ExtraGas }) + valWalletA, err := staker.NewContractValidatorWallet(dpA, nil, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, testNodeA.L2Node.DeployInfo.Rollup, testNodeA.L2Node.L1Reader, &l1authA, 0, func(common.Address) {}, func() uint64 { return valConfig.ExtraGas }) Require(t, err) if honestStakerInactive { valConfig.Strategy = "Defensive" @@ -146,11 +146,11 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) blockValidatorConfig := staker.TestBlockValidatorConfig statelessA, err := staker.NewStatelessBlockValidator( - l2nodeA.InboxReader, - l2nodeA.InboxTracker, - l2nodeA.TxStreamer, - l2nodeA.Execution.Recorder, - l2nodeA.ArbDB, + testNodeA.L2Node.InboxReader, + testNodeA.L2Node.InboxTracker, + testNodeA.L2Node.TxStreamer, + testNodeA.L2Node.Execution.Recorder, + testNodeA.L2Node.ArbDB, nil, StaticFetcherFrom(t, &blockValidatorConfig), valStack, @@ -159,7 +159,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) err = statelessA.Start(ctx) Require(t, err) stakerA, err := staker.NewStaker( - l2nodeA.L1Reader, + testNodeA.L2Node.L1Reader, valWalletA, bind.CallOpts{}, valConfig, @@ -167,7 +167,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) statelessA, nil, nil, - l2nodeA.DeployInfo.ValidatorUtils, + testNodeA.L2Node.DeployInfo.ValidatorUtils, nil, ) Require(t, err) @@ -217,15 +217,15 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) err = valWalletB.Initialize(ctx) Require(t, err) } - dpC, err := arbnode.StakerDataposter(rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), l2nodeA.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) + dpC, err := arbnode.StakerDataposter(rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), testNodeA.L2Node.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) if err != nil { t.Fatalf("Error creating validator dataposter: %v", err) } - valWalletC, err := staker.NewContractValidatorWallet(dpC, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, nil, 0, func(common.Address) {}, func() uint64 { return 10000 }) + valWalletC, err := staker.NewContractValidatorWallet(dpC, nil, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, testNodeA.L2Node.DeployInfo.Rollup, testNodeA.L2Node.L1Reader, nil, 0, func(common.Address) {}, func() uint64 { return 10000 }) Require(t, err) valConfig.Strategy = "Watchtower" stakerC, err := staker.NewStaker( - l2nodeA.L1Reader, + testNodeA.L2Node.L1Reader, valWalletC, bind.CallOpts{}, valConfig, @@ -233,7 +233,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) statelessA, nil, nil, - l2nodeA.DeployInfo.ValidatorUtils, + testNodeA.L2Node.DeployInfo.ValidatorUtils, nil, ) Require(t, err) @@ -246,9 +246,9 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) l2info.GenerateAccount("BackgroundUser") tx = l2info.PrepareTx("Faucet", "BackgroundUser", l2info.TransferGas, balance, nil) - err = l2clientA.SendTransaction(ctx, tx) + err = testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2clientA, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) // Continually make L2 transactions in a background thread @@ -260,7 +260,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) })() go (func() { defer close(backgroundTxsShutdownChan) - err := makeBackgroundTxs(backgroundTxsCtx, l2info, l2clientA) + err := makeBackgroundTxs(backgroundTxsCtx, l2info, testNodeA.L2Client) if !errors.Is(err, context.Canceled) { log.Warn("error making background txs", "err", err) } @@ -303,26 +303,26 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) if !challengeMangerTimedOut { // Upgrade the ChallengeManager contract to an implementation which says challenges are always timed out - mockImpl, tx, _, err := mocksgen.DeployTimedOutChallengeManager(&deployAuth, l1client) + mockImpl, tx, _, err := mocksgen.DeployTimedOutChallengeManager(&deployAuth, testNodeA.L1Client) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l1client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) Require(t, err) managerAddr := valWalletA.ChallengeManagerAddress() // 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 proxyAdminSlot := common.BigToHash(arbmath.BigSub(crypto.Keccak256Hash([]byte("eip1967.proxy.admin")).Big(), common.Big1)) - proxyAdminBytes, err := l1client.StorageAt(ctx, managerAddr, proxyAdminSlot, nil) + proxyAdminBytes, err := testNodeA.L1Client.StorageAt(ctx, managerAddr, proxyAdminSlot, nil) Require(t, err) proxyAdminAddr := common.BytesToAddress(proxyAdminBytes) if proxyAdminAddr == (common.Address{}) { Fatal(t, "failed to get challenge manager proxy admin") } - proxyAdmin, err := mocksgen.NewProxyAdminForBinding(proxyAdminAddr, l1client) + proxyAdmin, err := mocksgen.NewProxyAdminForBinding(proxyAdminAddr, testNodeA.L1Client) Require(t, err) tx, err = proxyAdmin.Upgrade(&deployAuth, managerAddr, mockImpl) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l1client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) Require(t, err) challengeMangerTimedOut = true @@ -342,11 +342,11 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) } Require(t, err, "Staker", stakerName, "failed to act") if tx != nil { - _, err = EnsureTxSucceeded(ctx, l1client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) Require(t, err, "EnsureTxSucceeded failed for staker", stakerName, "tx") } if faultyStaker { - conflictInfo, err := validatorUtils.FindStakerConflict(&bind.CallOpts{}, l2nodeA.DeployInfo.Rollup, l1authA.From, l1authB.From, big.NewInt(1024)) + conflictInfo, err := validatorUtils.FindStakerConflict(&bind.CallOpts{}, testNodeA.L2Node.DeployInfo.Rollup, l1authA.From, l1authB.From, big.NewInt(1024)) Require(t, err) if staker.ConflictType(conflictInfo.Ty) == staker.CONFLICT_TYPE_FOUND { cancelBackgroundTxs() @@ -378,7 +378,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) Require(t, err) } for j := 0; j < 5; j++ { - TransferBalance(t, "Faucet", "Faucet", common.Big0, l1info, l1client, ctx) + testNodeA.TransferBalanceViaL1(t, "Faucet", "Faucet", common.Big0) } } diff --git a/system_tests/twonodes_test.go b/system_tests/twonodes_test.go index 72de2aa50a..b9be59a19a 100644 --- a/system_tests/twonodes_test.go +++ b/system_tests/twonodes_test.go @@ -20,24 +20,24 @@ func testTwoNodesSimple(t *testing.T, dasModeStr string) { chainConfig, l1NodeConfigA, lifecycleManager, _, dasSignerKey := setupConfigWithDAS(t, ctx, dasModeStr) defer lifecycleManager.StopAndWaitUntil(time.Second) - l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) - defer requireClose(t, l1stack) - defer nodeA.StopAndWait() + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(l1NodeConfigA).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) + defer testNodeA.L2Node.StopAndWait() - authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) + authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) l1NodeConfigBDataAvailability := l1NodeConfigA.DataAvailability l1NodeConfigBDataAvailability.RPCAggregator.Enable = false - l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, &l1NodeConfigBDataAvailability) + l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, &l1NodeConfigBDataAvailability) defer nodeB.StopAndWait() - l2info.GenerateAccount("User2") + testNodeA.L2Info.GenerateAccount("User2") - tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) + tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) - err := l2clientA.SendTransaction(ctx, tx) + err := testNodeA.L2Client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, l2clientA, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) Require(t, err) // give the inbox reader a bit of time to pick up the delayed message @@ -45,15 +45,15 @@ func testTwoNodesSimple(t *testing.T, dasModeStr string) { // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 30; i++ { - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ + testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } _, err = WaitForTx(ctx, l2clientB, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { diff --git a/system_tests/twonodeslong_test.go b/system_tests/twonodeslong_test.go index 0cac9d6442..2dde9a512e 100644 --- a/system_tests/twonodeslong_test.go +++ b/system_tests/twonodeslong_test.go @@ -42,32 +42,32 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { chainConfig, l1NodeConfigA, lifecycleManager, _, dasSignerKey := setupConfigWithDAS(t, ctx, dasModeStr) defer lifecycleManager.StopAndWaitUntil(time.Second) - l2info, nodeA, l2client, l1info, l1backend, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) - defer requireClose(t, l1stack) + testNodeA := NewNodeBuilder(ctx).SetNodeConfig(l1NodeConfigA).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, testNodeA.L1Stack) - authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) + authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) l1NodeConfigBDataAvailability := l1NodeConfigA.DataAvailability l1NodeConfigBDataAvailability.RPCAggregator.Enable = false - l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, &l1NodeConfigBDataAvailability) + l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, &l1NodeConfigBDataAvailability) defer nodeB.StopAndWait() - l2info.GenerateAccount("DelayedFaucet") - l2info.GenerateAccount("DelayedReceiver") - l2info.GenerateAccount("DirectReceiver") + testNodeA.L2Info.GenerateAccount("DelayedFaucet") + testNodeA.L2Info.GenerateAccount("DelayedReceiver") + testNodeA.L2Info.GenerateAccount("DirectReceiver") - l2info.GenerateAccount("ErrorTxSender") + testNodeA.L2Info.GenerateAccount("ErrorTxSender") - SendWaitTestTransactions(t, ctx, l2client, []*types.Transaction{ - l2info.PrepareTx("Faucet", "ErrorTxSender", l2info.TransferGas, big.NewInt(l2pricing.InitialBaseFeeWei*int64(l2info.TransferGas)), nil), + SendWaitTestTransactions(t, ctx, testNodeA.L2Client, []*types.Transaction{ + testNodeA.L2Info.PrepareTx("Faucet", "ErrorTxSender", testNodeA.L2Info.TransferGas, big.NewInt(l2pricing.InitialBaseFeeWei*int64(testNodeA.L2Info.TransferGas)), nil), }) delayedMsgsToSendMax := big.NewInt(int64(largeLoops * avgDelayedMessagesPerLoop * 10)) delayedFaucetNeeds := new(big.Int).Mul(new(big.Int).Add(fundsPerDelayed, new(big.Int).SetUint64(l2pricing.InitialBaseFeeWei*100000)), delayedMsgsToSendMax) - SendWaitTestTransactions(t, ctx, l2client, []*types.Transaction{ - l2info.PrepareTx("Faucet", "DelayedFaucet", l2info.TransferGas, delayedFaucetNeeds, nil), + SendWaitTestTransactions(t, ctx, testNodeA.L2Client, []*types.Transaction{ + testNodeA.L2Info.PrepareTx("Faucet", "DelayedFaucet", testNodeA.L2Info.TransferGas, delayedFaucetNeeds, nil), }) - delayedFaucetBalance, err := l2client.BalanceAt(ctx, l2info.GetAddress("DelayedFaucet"), nil) + delayedFaucetBalance, err := testNodeA.L2Client.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DelayedFaucet"), nil) Require(t, err) if delayedFaucetBalance.Cmp(delayedFaucetNeeds) != 0 { @@ -85,17 +85,17 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { randNum := rand.Int() % avgTotalL1MessagesPerLoop var l1tx *types.Transaction if randNum < avgDelayedMessagesPerLoop { - delayedTx := l2info.PrepareTx("DelayedFaucet", "DelayedReceiver", 30001, fundsPerDelayed, nil) - l1tx = WrapL2ForDelayed(t, delayedTx, l1info, "User", 100000) + delayedTx := testNodeA.L2Info.PrepareTx("DelayedFaucet", "DelayedReceiver", 30001, fundsPerDelayed, nil) + l1tx = WrapL2ForDelayed(t, delayedTx, testNodeA.L1Info, "User", 100000) delayedTxs = append(delayedTxs, delayedTx) delayedTransfers++ } else { - l1tx = l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) + l1tx = testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) } l1Txs = append(l1Txs, l1tx) } // adding multiple messages in the same AddLocal to get them in the same L1 block - errs := l1backend.TxPool().AddLocals(l1Txs) + errs := testNodeA.L1Backend.TxPool().AddLocals(l1Txs) for _, err := range errs { if err != nil { Fatal(t, err) @@ -104,26 +104,26 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { l2TxsThisTime := rand.Int() % (avgL2MsgsPerLoop * 2) l2Txs := make([]*types.Transaction, 0, l2TxsThisTime) for len(l2Txs) < l2TxsThisTime { - l2Txs = append(l2Txs, l2info.PrepareTx("Faucet", "DirectReceiver", l2info.TransferGas, fundsPerDirect, nil)) + l2Txs = append(l2Txs, testNodeA.L2Info.PrepareTx("Faucet", "DirectReceiver", testNodeA.L2Info.TransferGas, fundsPerDirect, nil)) } - SendWaitTestTransactions(t, ctx, l2client, l2Txs) + SendWaitTestTransactions(t, ctx, testNodeA.L2Client, l2Txs) directTransfers += int64(l2TxsThisTime) if len(l1Txs) > 0 { - _, err := EnsureTxSucceeded(ctx, l1client, l1Txs[len(l1Txs)-1]) + _, err := EnsureTxSucceeded(ctx, testNodeA.L1Client, l1Txs[len(l1Txs)-1]) if err != nil { Fatal(t, err) } } // create bad tx on delayed inbox - l2info.GetInfoWithPrivKey("ErrorTxSender").Nonce = 10 - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - WrapL2ForDelayed(t, l2info.PrepareTx("ErrorTxSender", "DelayedReceiver", 30002, delayedFaucetNeeds, nil), l1info, "User", 100000), + testNodeA.L2Info.GetInfoWithPrivKey("ErrorTxSender").Nonce = 10 + SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ + WrapL2ForDelayed(t, testNodeA.L2Info.PrepareTx("ErrorTxSender", "DelayedReceiver", 30002, delayedFaucetNeeds, nil), testNodeA.L1Info, "User", 100000), }) extrBlocksThisTime := rand.Int() % (avgExtraBlocksPerLoop * 2) for i := 0; i < extrBlocksThisTime; i++ { - SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ - l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ + testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } } @@ -137,38 +137,38 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { for i := 0; i < finalPropagateLoops; i++ { var tx *types.Transaction for j := 0; j < 30; j++ { - tx = l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) - err := l1client.SendTransaction(ctx, tx) + tx = testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) + err := testNodeA.L1Client.SendTransaction(ctx, tx) if err != nil { Fatal(t, err) } - _, err = EnsureTxSucceeded(ctx, l1client, tx) + _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) if err != nil { Fatal(t, err) } } } - _, err = EnsureTxSucceededWithTimeout(ctx, l2client, delayedTxs[len(delayedTxs)-1], time.Second*10) + _, err = EnsureTxSucceededWithTimeout(ctx, testNodeA.L2Client, delayedTxs[len(delayedTxs)-1], time.Second*10) Require(t, err, "Failed waiting for Tx on main node") _, err = EnsureTxSucceededWithTimeout(ctx, l2clientB, delayedTxs[len(delayedTxs)-1], time.Second*10) Require(t, err, "Failed waiting for Tx on secondary node") - delayedBalance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("DelayedReceiver"), nil) + delayedBalance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DelayedReceiver"), nil) Require(t, err) - directBalance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("DirectReceiver"), nil) + directBalance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DirectReceiver"), nil) Require(t, err) delayedExpectd := new(big.Int).Mul(fundsPerDelayed, big.NewInt(delayedTransfers)) directExpectd := new(big.Int).Mul(fundsPerDirect, big.NewInt(directTransfers)) if (delayedBalance.Cmp(delayedExpectd) != 0) || (directBalance.Cmp(directExpectd) != 0) { t.Error("delayed balance", delayedBalance, "expected", delayedExpectd, "transfers", delayedTransfers) t.Error("direct balance", directBalance, "expected", directExpectd, "transfers", directTransfers) - ownerBalance, _ := l2clientB.BalanceAt(ctx, l2info.GetAddress("Owner"), nil) - delayedFaucetBalance, _ := l2clientB.BalanceAt(ctx, l2info.GetAddress("DelayedFaucet"), nil) + ownerBalance, _ := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("Owner"), nil) + delayedFaucetBalance, _ := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DelayedFaucet"), nil) t.Error("owner balance", ownerBalance, "delayed faucet", delayedFaucetBalance) Fatal(t, "Unexpected balance") } - nodeA.StopAndWait() + testNodeA.L2Node.StopAndWait() if nodeB.BlockValidator != nil { lastBlockHeader, err := l2clientB.HeaderByNumber(ctx, nil) From 2e778ff3d27c222d4b248d615600dab51a6c09d3 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Thu, 28 Sep 2023 15:56:20 -0500 Subject: [PATCH 03/54] update implementation and limit diff to a few testfiles for avoiding merge conflicts --- system_tests/aliasing_test.go | 26 +-- system_tests/arbtrace_test.go | 8 +- system_tests/batch_poster_test.go | 84 ++++---- system_tests/block_hash_test.go | 10 +- system_tests/block_validator_test.go | 56 ++--- system_tests/bloom_test.go | 22 +- system_tests/common_test.go | 258 +++++++++++++++++------ system_tests/conditionaltx_test.go | 128 ++++++------ system_tests/contract_tx_test.go | 17 +- system_tests/debugapi_test.go | 8 +- system_tests/delayedinbox_test.go | 14 +- system_tests/delayedinboxlong_test.go | 26 +-- system_tests/estimation_test.go | 75 ++++--- system_tests/fees_test.go | 72 +++---- system_tests/forwarder_test.go | 19 +- system_tests/infra_fee_test.go | 28 +-- system_tests/initialization_test.go | 6 +- system_tests/ipc_test.go | 6 +- system_tests/log_subscription_test.go | 15 +- system_tests/meaningless_reorg_test.go | 34 +-- system_tests/nodeinterface_test.go | 14 +- system_tests/outbox_test.go | 17 +- system_tests/precompile_test.go | 29 ++- system_tests/recreatestate_rpc_test.go | 20 +- system_tests/reorg_resequencing_test.go | 43 ++-- system_tests/retryable_test.go | 266 ++++++++++++------------ system_tests/seq_coordinator_test.go | 24 +-- system_tests/seq_nonce_test.go | 34 +-- system_tests/seq_pause_test.go | 21 +- system_tests/seq_reject_test.go | 44 ++-- system_tests/seq_whitelist_test.go | 18 +- system_tests/seqcompensation_test.go | 22 +- system_tests/seqfeed_test.go | 80 +++---- system_tests/seqinbox_test.go | 58 +++--- system_tests/staker_test.go | 86 ++++---- system_tests/transfer_test.go | 18 +- system_tests/twonodes_test.go | 24 +-- system_tests/twonodeslong_test.go | 68 +++--- 38 files changed, 960 insertions(+), 838 deletions(-) diff --git a/system_tests/aliasing_test.go b/system_tests/aliasing_test.go index d7513fe0cc..5e4e65a2ca 100644 --- a/system_tests/aliasing_test.go +++ b/system_tests/aliasing_test.go @@ -22,20 +22,20 @@ func TestAliasing(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) - user := testNode.L1Info.GetDefaultTransactOpts("User", ctx) - testNode.TransferBalanceToViaL2(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18)) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) + user := l1info.GetDefaultTransactOpts("User", ctx) + TransferBalanceTo(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18), l2info, l2client, ctx) - simpleAddr, simple := testNode.DeploySimple(t, auth) + simpleAddr, simple := deploySimple(t, ctx, auth, l2client) simpleContract, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) Require(t, err) // Test direct calls - arbsys, err := precompilesgen.NewArbSys(types.ArbSysAddress, testNode.L2Client) + arbsys, err := precompilesgen.NewArbSys(types.ArbSysAddress, l2client) Require(t, err) top, err := arbsys.IsTopLevelCall(nil) Require(t, err) @@ -56,14 +56,14 @@ func TestAliasing(t *testing.T) { // check via L2 tx, err := simple.CheckCalls(&auth, top, direct, static, delegate, callcode, call) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) // check signed txes via L1 data, err := simpleContract.Pack("checkCalls", top, direct, static, delegate, callcode, call) Require(t, err) - tx = testNode.L2Info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) - testNode.SendSignedTxViaL1(t, tx) + tx = l2info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) + SendSignedTxViaL1(t, ctx, l1info, l1client, l2client, tx) } testUnsigned := func(top, direct, static, delegate, callcode, call bool) { @@ -72,8 +72,8 @@ func TestAliasing(t *testing.T) { // check unsigned txes via L1 data, err := simpleContract.Pack("checkCalls", top, direct, static, delegate, callcode, call) Require(t, err) - tx := testNode.L2Info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) - testNode.SendUnsignedTxViaL1(t, tx) + tx := l2info.PrepareTxTo("Owner", &simpleAddr, 500000, big.NewInt(0), data) + SendUnsignedTxViaL1(t, ctx, l1info, l1client, l2client, tx) } testL2Signed(true, true, false, false, false, false) diff --git a/system_tests/arbtrace_test.go b/system_tests/arbtrace_test.go index 50575500de..78907aa622 100644 --- a/system_tests/arbtrace_test.go +++ b/system_tests/arbtrace_test.go @@ -147,11 +147,11 @@ func TestArbTraceForwarding(t *testing.T) { nodeConfig := arbnode.ConfigDefaultL1Test() nodeConfig.RPC.ClassicRedirect = ipcPath nodeConfig.RPC.ClassicRedirectTimeout = time.Second - testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer requireClose(t, testNode.L2Stack) + _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nodeConfig, nil, nil, nil) + defer requireClose(t, l1stack) + defer requireClose(t, l2stack) - l2rpc, _ := testNode.L2Stack.Attach() + l2rpc, _ := l2stack.Attach() txArgs := callTxArgs{} traceTypes := []string{"trace"} blockNum := rpc.BlockNumberOrHash{} diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index eab175b8e6..ef50be6ec4 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -48,41 +48,43 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { conf := arbnode.ConfigDefaultL1Test() conf.BatchPoster.Enable = false conf.BatchPoster.RedisUrl = redisUrl - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + builder := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true) + l1A, l2A := builder.BuildL2OnL1(t) + // testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + defer requireClose(t, l1A.Stack) + defer l2A.Node.StopAndWait() - l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nil) - defer nodeB.StopAndWait() + l2B := builder.Build2ndNodeDAS(t, &l2A.Info.ArbInitData, nil) + defer l2B.Node.StopAndWait() - testNodeA.L2Info.GenerateAccount("User2") + l2A.Info.GenerateAccount("User2") var txs []*types.Transaction for i := 0; i < 100; i++ { - tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, common.Big1, nil) + tx := l2A.Info.PrepareTx("Owner", "User2", l2A.Info.TransferGas, common.Big1, nil) txs = append(txs, tx) - err := testNodeA.L2Client.SendTransaction(ctx, tx) + err := l2A.Client.SendTransaction(ctx, tx) Require(t, err) } for _, tx := range txs { - _, err := EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err := EnsureTxSucceeded(ctx, l2A.Client, tx) Require(t, err) } firstTxData, err := txs[0].MarshalBinary() Require(t, err) - seqTxOpts := testNodeA.L1Info.GetDefaultTransactOpts("Sequencer", ctx) + seqTxOpts := l1A.Info.GetDefaultTransactOpts("Sequencer", ctx) conf.BatchPoster.Enable = true conf.BatchPoster.MaxSize = len(firstTxData) * 2 - startL1Block, err := testNodeA.L1Client.BlockNumber(ctx) + startL1Block, err := l1A.Client.BlockNumber(ctx) Require(t, err) for i := 0; i < parallelBatchPosters; i++ { // Make a copy of the batch poster config so NewBatchPoster calling Validate() on it doesn't race batchPosterConfig := conf.BatchPoster - batchPoster, err := arbnode.NewBatchPoster(ctx, nil, testNodeA.L2Node.L1Reader, testNodeA.L2Node.InboxTracker, testNodeA.L2Node.TxStreamer, testNodeA.L2Node.SyncMonitor, func() *arbnode.BatchPosterConfig { return &batchPosterConfig }, testNodeA.L2Node.DeployInfo, &seqTxOpts, nil) + batchPoster, err := arbnode.NewBatchPoster(ctx, nil, l2A.Node.L1Reader, l2A.Node.InboxTracker, l2A.Node.TxStreamer, l2A.Node.SyncMonitor, func() *arbnode.BatchPosterConfig { return &batchPosterConfig }, l2A.Node.DeployInfo, &seqTxOpts, nil) Require(t, err) batchPoster.Start(ctx) defer batchPoster.StopAndWait() @@ -90,11 +92,11 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { lastTxHash := txs[len(txs)-1].Hash() for i := 90; i > 0; i-- { - SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ - testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, l1A.Client, []*types.Transaction{ + l1A.Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) time.Sleep(500 * time.Millisecond) - _, err := l2clientB.TransactionReceipt(ctx, lastTxHash) + _, err := l2B.Client.TransactionReceipt(ctx, lastTxHash) if err == nil { break } @@ -107,9 +109,9 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { // However, setting the clique period to 1 slows everything else (including the L1 deployment for this test) down to a crawl. if false { // Make sure the batch poster is able to post multiple batches in one block - endL1Block, err := testNodeA.L1Client.BlockNumber(ctx) + endL1Block, err := l1A.Client.BlockNumber(ctx) Require(t, err) - seqInbox, err := arbnode.NewSequencerInbox(testNodeA.L1Client, testNodeA.L2Node.DeployInfo.SequencerInbox, 0) + seqInbox, err := arbnode.NewSequencerInbox(l1A.Client, l2A.Node.DeployInfo.SequencerInbox, 0) Require(t, err) batches, err := seqInbox.LookupBatchesInRange(ctx, new(big.Int).SetUint64(startL1Block), new(big.Int).SetUint64(endL1Block)) Require(t, err) @@ -129,7 +131,7 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { } } - l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) + l2balance, err := l2B.Client.BalanceAt(ctx, l2A.Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Sign() == 0 { @@ -144,24 +146,25 @@ func TestBatchPosterLargeTx(t *testing.T) { conf := arbnode.ConfigDefaultL1Test() conf.Sequencer.MaxTxDataSize = 110000 - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + builder := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true) + l1A, l2A := builder.BuildL2OnL1(t) + defer requireClose(t, l1A.Stack) + defer l2A.Node.StopAndWait() - l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nil) - defer nodeB.StopAndWait() + l2B := builder.Build2ndNodeDAS(t, &l2A.Info.ArbInitData, nil) + defer l2B.Node.StopAndWait() data := make([]byte, 100000) _, err := rand.Read(data) Require(t, err) - faucetAddr := testNodeA.L2Info.GetAddress("Faucet") - gas := testNodeA.L2Info.TransferGas + 20000*uint64(len(data)) - tx := testNodeA.L2Info.PrepareTxTo("Faucet", &faucetAddr, gas, common.Big0, data) - err = testNodeA.L2Client.SendTransaction(ctx, tx) + faucetAddr := l2A.Info.GetAddress("Faucet") + gas := l2A.Info.TransferGas + 20000*uint64(len(data)) + tx := l2A.Info.PrepareTxTo("Faucet", &faucetAddr, gas, common.Big0, data) + err = l2A.Client.SendTransaction(ctx, tx) Require(t, err) - receiptA, err := EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + receiptA, err := EnsureTxSucceeded(ctx, l2A.Client, tx) Require(t, err) - receiptB, err := EnsureTxSucceededWithTimeout(ctx, l2clientB, tx, time.Second*30) + receiptB, err := EnsureTxSucceededWithTimeout(ctx, l2B.Client, tx, time.Second*30) Require(t, err) if receiptA.BlockHash != receiptB.BlockHash { Fatal(t, "receipt A block hash", receiptA.BlockHash, "does not equal receipt B block hash", receiptB.BlockHash) @@ -177,21 +180,22 @@ func TestBatchPosterKeepsUp(t *testing.T) { conf.BatchPoster.CompressionLevel = brotli.BestCompression conf.BatchPoster.MaxDelay = time.Hour conf.RPC.RPCTxFeeCap = 1000. - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() - testNodeA.L2Info.GasPrice = big.NewInt(100e9) + builder := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true) + l1A, l2A := builder.BuildL2OnL1(t) + defer requireClose(t, l1A.Stack) + defer l2A.Node.StopAndWait() + l2A.Info.GasPrice = big.NewInt(100e9) go func() { data := make([]byte, 90000) _, err := rand.Read(data) Require(t, err) for { - gas := testNodeA.L2Info.TransferGas + 20000*uint64(len(data)) - tx := testNodeA.L2Info.PrepareTx("Faucet", "Faucet", gas, common.Big0, data) - err = testNodeA.L2Client.SendTransaction(ctx, tx) + gas := l2A.Info.TransferGas + 20000*uint64(len(data)) + tx := l2A.Info.PrepareTx("Faucet", "Faucet", gas, common.Big0, data) + err = l2A.Client.SendTransaction(ctx, tx) Require(t, err) - _, err := EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err := EnsureTxSucceeded(ctx, l2A.Client, tx) Require(t, err) } }() @@ -199,11 +203,11 @@ func TestBatchPosterKeepsUp(t *testing.T) { start := time.Now() for { time.Sleep(time.Second) - batches, err := testNodeA.L2Node.InboxTracker.GetBatchCount() + batches, err := l2A.Node.InboxTracker.GetBatchCount() Require(t, err) - postedMessages, err := testNodeA.L2Node.InboxTracker.GetBatchMessageCount(batches - 1) + postedMessages, err := l2A.Node.InboxTracker.GetBatchMessageCount(batches - 1) Require(t, err) - haveMessages, err := testNodeA.L2Node.TxStreamer.GetMessageCount() + haveMessages, err := l2A.Node.TxStreamer.GetMessageCount() Require(t, err) duration := time.Since(start) fmt.Printf("batches posted: %v over %v (%.2f batches/second)\n", batches, duration, float64(batches)/(float64(duration)/float64(time.Second))) diff --git a/system_tests/block_hash_test.go b/system_tests/block_hash_test.go index 9ce752e65f..2b8051242e 100644 --- a/system_tests/block_hash_test.go +++ b/system_tests/block_hash_test.go @@ -16,13 +16,13 @@ func TestBlockHash(t *testing.T) { defer cancel() // Even though we don't use the L1, we need to create this node on L1 to get accurate L1 block numbers - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, l2node, l2client, _, _, _, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer l2node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) + auth := l2info.GetDefaultTransactOpts("Faucet", ctx) - _, _, simple, err := mocksgen.DeploySimple(&auth, testNode.L2Client) + _, _, simple, err := mocksgen.DeploySimple(&auth, l2client) Require(t, err) _, err = simple.CheckBlockHashes(&bind.CallOpts{Context: ctx}) diff --git a/system_tests/block_validator_test.go b/system_tests/block_validator_test.go index ae844612f6..fa3d902b18 100644 --- a/system_tests/block_validator_test.go +++ b/system_tests/block_validator_test.go @@ -50,20 +50,20 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops delayEvery = workloadLoops / 3 } - testNodeA := NewNodeBuilder(ctx).SetIsSequencer(true).SetNodeConfig(l1NodeConfigA).SetChainConfig(chainConfig).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + l2info, nodeA, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) + defer requireClose(t, l1stack) + defer nodeA.StopAndWait() - authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) + authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) validatorConfig := arbnode.ConfigDefaultL1NonSequencerTest() validatorConfig.BlockValidator.Enable = true validatorConfig.DataAvailability = l1NodeConfigA.DataAvailability validatorConfig.DataAvailability.RPCAggregator.Enable = false AddDefaultValNode(t, ctx, validatorConfig, !arbitrator) - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, validatorConfig, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, validatorConfig, nil) defer nodeB.StopAndWait() - testNodeA.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") perTransfer := big.NewInt(1e12) @@ -72,7 +72,7 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops var tx *types.Transaction if workload == ethSend { - tx = testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, perTransfer, nil) + tx = l2info.PrepareTx("Owner", "User2", l2info.TransferGas, perTransfer, nil) } else { var contractCode []byte var gas uint64 @@ -86,10 +86,10 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops contractCode = append(contractCode, byte(vm.CODECOPY)) contractCode = append(contractCode, byte(vm.PUSH0)) contractCode = append(contractCode, byte(vm.RETURN)) - basefee := testNodeA.GetBaseFeeAtViaL2(t, nil) + basefee := GetBaseFee(t, l2client, ctx) var err error - gas, err = testNodeA.L2Client.EstimateGas(ctx, ethereum.CallMsg{ - From: testNodeA.L2Info.GetAddress("Owner"), + gas, err = l2client.EstimateGas(ctx, ethereum.CallMsg{ + From: l2info.GetAddress("Owner"), GasPrice: basefee, Value: big.NewInt(0), Data: contractCode, @@ -101,14 +101,14 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops contractCode = append(contractCode, 0x60, 0x00, 0x60, 0x00, 0x52) // PUSH1 0 MSTORE } contractCode = append(contractCode, 0x60, 0x00, 0x56) // JUMP - gas = testNodeA.L2Info.TransferGas*2 + l2pricing.InitialPerBlockGasLimitV6 + gas = l2info.TransferGas*2 + l2pricing.InitialPerBlockGasLimitV6 } - tx = testNodeA.L2Info.PrepareTxTo("Owner", nil, gas, common.Big0, contractCode) + tx = l2info.PrepareTxTo("Owner", nil, gas, common.Big0, contractCode) } - err := testNodeA.L2Client.SendTransaction(ctx, tx) + err := l2client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceededWithTimeout(ctx, testNodeA.L2Client, tx, time.Second*5) + _, err = EnsureTxSucceededWithTimeout(ctx, l2client, tx, time.Second*5) if workload != depleteGas { Require(t, err) } @@ -117,40 +117,40 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops } } } else { - auth := testNodeA.L2Info.GetDefaultTransactOpts("Owner", ctx) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) // make auth a chain owner - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNodeA.L2Client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), l2client) Require(t, err) tx, err := arbDebug.BecomeChainOwner(&auth) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), testNodeA.L2Client) + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), l2client) Require(t, err) tx, err = arbOwner.ScheduleArbOSUpgrade(&auth, 11, 0) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - tx = testNodeA.L2Info.PrepareTxTo("Owner", nil, testNodeA.L2Info.TransferGas, perTransfer, []byte{byte(vm.PUSH0)}) - err = testNodeA.L2Client.SendTransaction(ctx, tx) + tx = l2info.PrepareTxTo("Owner", nil, l2info.TransferGas, perTransfer, []byte{byte(vm.PUSH0)}) + err = l2client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceededWithTimeout(ctx, testNodeA.L2Client, tx, time.Second*5) + _, err = EnsureTxSucceededWithTimeout(ctx, l2client, tx, time.Second*5) Require(t, err) } if workload != depleteGas { - delayedTx := testNodeA.L2Info.PrepareTx("Owner", "User2", 30002, perTransfer, nil) - SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ - WrapL2ForDelayed(t, delayedTx, testNodeA.L1Info, "User", 100000), + delayedTx := l2info.PrepareTx("Owner", "User2", 30002, perTransfer, nil) + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + WrapL2ForDelayed(t, delayedTx, l1info, "User", 100000), }) // give the inbox reader a bit of time to pick up the delayed message time.Sleep(time.Millisecond * 500) // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 30; i++ { - SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ - testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } @@ -159,7 +159,7 @@ func testBlockValidatorSimple(t *testing.T, dasModeString string, workloadLoops } if workload == ethSend { - l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) expectedBalance := new(big.Int).Mul(perTransfer, big.NewInt(int64(workloadLoops+1))) diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go index c61583adfb..9ad3253d4a 100644 --- a/system_tests/bloom_test.go +++ b/system_tests/bloom_test.go @@ -28,14 +28,14 @@ func TestBloom(t *testing.T) { nodeconfig := arbnode.ConfigDefaultL2Test() nodeconfig.RPC.BloomBitsBlocks = 256 nodeconfig.RPC.BloomConfirms = 1 - testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeconfig).CreateTestNodeOnL2Only(t, false) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, false) + defer node.StopAndWait() - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) ownerTxOpts.Context = ctx - _, simple := testNode.DeploySimple(t, ownerTxOpts) + _, simple := deploySimple(t, ctx, ownerTxOpts, client) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) @@ -63,7 +63,7 @@ func TestBloom(t *testing.T) { if sendNullEvent { tx, err = simple.EmitNullEvent(&ownerTxOpts) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) } @@ -74,7 +74,7 @@ func TestBloom(t *testing.T) { tx, err = simple.Increment(&ownerTxOpts) } Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) if i%100 == 0 { t.Log("counts: ", i, "/", countsNum) @@ -82,7 +82,7 @@ func TestBloom(t *testing.T) { } for { - sectionSize, sectionNum := testNode.L2Node.Execution.Backend.APIBackend().BloomStatus() + sectionSize, sectionNum := node.Execution.Backend.APIBackend().BloomStatus() if sectionSize != 256 { Fatal(t, "unexpected section size: ", sectionSize) } @@ -92,14 +92,14 @@ func TestBloom(t *testing.T) { } <-time.After(time.Second) } - lastHeader, err := testNode.L2Client.HeaderByNumber(ctx, nil) + lastHeader, err := client.HeaderByNumber(ctx, nil) Require(t, err) nullEventQuery := ethereum.FilterQuery{ FromBlock: big.NewInt(0), ToBlock: lastHeader.Number, Topics: [][]common.Hash{{simpleABI.Events["NullEvent"].ID}}, } - logs, err := testNode.L2Client.FilterLogs(ctx, nullEventQuery) + logs, err := client.FilterLogs(ctx, nullEventQuery) Require(t, err) if len(logs) != len(nullEventCounts) { Fatal(t, "expected ", len(nullEventCounts), " logs, got ", len(logs)) @@ -107,7 +107,7 @@ func TestBloom(t *testing.T) { incrementEventQuery := ethereum.FilterQuery{ Topics: [][]common.Hash{{simpleABI.Events["CounterEvent"].ID}}, } - logs, err = testNode.L2Client.FilterLogs(ctx, incrementEventQuery) + logs, err = client.FilterLogs(ctx, incrementEventQuery) Require(t, err) if len(logs) != len(eventCounts) { Fatal(t, "expected ", len(eventCounts), " logs, got ", len(logs)) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index cb24555d2b..9525d9d6cc 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -60,31 +60,75 @@ import ( type info = *BlockchainTestInfo type client = arbutil.L1Interface +type TestClient struct { + // Nodebuilder fields + ctx context.Context + Info info + Client *ethclient.Client + Backend *eth.Ethereum + Stack *node.Node + Node *arbnode.Node +} + +func NewTestClient(ctx context.Context) *TestClient { + return &TestClient{ctx: ctx} +} + +// SetClient is used to initialize *ethclient.Client when users dont want to create TestClients via create methods from nodebuilder +func (tc *TestClient) SetClient(c *ethclient.Client) *TestClient { + tc.Client = c + return tc +} + +// SetInfo is used to initialize *BlockchainTestInfo when users dont want to create TestClients via create methods from nodebuilder +func (tc *TestClient) SetInfo(i info) *TestClient { + tc.Info = i + return tc +} + +func (tc *TestClient) SendSignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction) *types.Receipt { + return SendSignedTxViaL1(t, tc.ctx, tc.Info, tc.Client, l2Client, transaction) +} + +func (tc *TestClient) SendUnsignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction) *types.Receipt { + return SendUnsignedTxViaL1(t, tc.ctx, tc.Info, tc.Client, l2Client, transaction) +} + +func (tc *TestClient) TransferBalance(t *testing.T, from string, to string, amount *big.Int) (*types.Transaction, *types.Receipt) { + return TransferBalanceTo(t, from, tc.Info.GetAddress(to), amount, tc.Info, tc.Client, tc.ctx) +} + +func (tc *TestClient) TransferBalanceTo(t *testing.T, from string, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt) { + return TransferBalanceTo(t, from, to, amount, tc.Info, tc.Client, tc.ctx) +} + +func (tc *TestClient) GetBalance(t *testing.T, account common.Address) *big.Int { + return GetBalance(t, tc.ctx, tc.Client, account) +} + +func (tc *TestClient) GetBaseFeeAt(t *testing.T, blockNum *big.Int) *big.Int { + return GetBaseFeeAt(t, tc.Client, tc.ctx, blockNum) +} + +func (tc *TestClient) DeploySimple(t *testing.T, auth bind.TransactOpts) (common.Address, *mocksgen.Simple) { + return deploySimple(t, tc.ctx, auth, tc.Client) +} + type NodeBuilder struct { // Nodebuilder configuration ctx context.Context + Info info chainConfig *params.ChainConfig cacheConfig *core.CacheConfig nodeConfig *arbnode.Config - l1StackConfig *node.Config - l2StackConfig *node.Config + stackConfig *node.Config + cachingConfig *execution.CachingConfig isSequencer bool + takeOwnership bool - // L1 Nodebuilder fields - L1Info info - L1Client *ethclient.Client - L1Backend *eth.Ethereum - L1Stack *node.Node - - // L2 Nodebuilder fields - L2Info info - L2Client *ethclient.Client - L2Backend *eth.Ethereum - L2Node *arbnode.Node - L2Stack *node.Node - L2ChainDB ethdb.Database - L2NodeDB ethdb.Database - L2Blockchain *core.BlockChain + // Created nodes + L1 *TestClient + L2 *TestClient } func NewNodeBuilder(ctx context.Context) *NodeBuilder { @@ -106,23 +150,18 @@ func (b *NodeBuilder) SetCacheConfig(c *core.CacheConfig) *NodeBuilder { return b } -func (b *NodeBuilder) SetL1StackConfig(c *node.Config) *NodeBuilder { - b.l1StackConfig = c - return b -} - -func (b *NodeBuilder) SetL2StackConfig(c *node.Config) *NodeBuilder { - b.l2StackConfig = c +func (b *NodeBuilder) SetStackConfig(c *node.Config) *NodeBuilder { + b.stackConfig = c return b } -func (b *NodeBuilder) SetL1Info(l1Info info) *NodeBuilder { - b.L1Info = l1Info +func (b *NodeBuilder) SetInfo(i info) *NodeBuilder { + b.Info = i return b } -func (b *NodeBuilder) SetL2Info(l2Info info) *NodeBuilder { - b.L2Info = l2Info +func (b *NodeBuilder) SetCachingConfig(c *execution.CachingConfig) *NodeBuilder { + b.cachingConfig = c return b } @@ -131,55 +170,101 @@ func (b *NodeBuilder) SetIsSequencer(v bool) *NodeBuilder { return b } -func (b *NodeBuilder) CreateTestNodeOnL1AndL2(t *testing.T) *NodeBuilder { - b.L2Info, b.L2Node, b.L2Client, b.L2Stack, b.L1Info, b.L1Backend, b.L1Client, b.L1Stack = - createTestNodeOnL1AndL2Impl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.l2StackConfig, b.L2Info) +func (b *NodeBuilder) SetTakeOwnership(v bool) *NodeBuilder { + b.takeOwnership = v return b } -func (b *NodeBuilder) CreateTestNodeOnL2Only(t *testing.T, takeOwnership bool) *NodeBuilder { - b.L2Info, b.L2Node, b.L2Client = createTestNodeOnL2OnlyImpl(t, b.ctx, b.L2Info, b.nodeConfig, takeOwnership) +func (b *NodeBuilder) ConfigForL2OnL1(isSequencer bool, n *arbnode.Config, c *params.ChainConfig, s *node.Config, i info) *NodeBuilder { + b.isSequencer = isSequencer + b.nodeConfig = n + b.chainConfig = c + b.stackConfig = s + b.Info = i return b } -func (b *NodeBuilder) SendSignedTxViaL1(t *testing.T, transaction *types.Transaction) *types.Receipt { - return sendSignedTxViaL1Impl(t, b.ctx, b.L1Info, b.L1Client, b.L2Client, transaction) +func (b *NodeBuilder) BuildL2OnL1(t *testing.T) (*TestClient, *TestClient) { + l1, l2 := NewTestClient(b.ctx), NewTestClient(b.ctx) + l2.Info, l2.Node, l2.Client, l2.Stack, l1.Info, l1.Backend, l1.Client, l1.Stack = + createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.stackConfig, b.Info) + b.L1, b.L2 = l1, l2 + return l1, l2 } -func (b *NodeBuilder) SendUnsignedTxViaL1(t *testing.T, transaction *types.Transaction) *types.Receipt { - return sendUnsignedTxViaL1Impl(t, b.ctx, b.L1Info, b.L1Client, b.L2Client, transaction) +func (b *NodeBuilder) ConfigForL2(takeOwnership bool, n *arbnode.Config, i info) *NodeBuilder { + b.takeOwnership = takeOwnership + b.nodeConfig = n + b.Info = i + return b } -func (b *NodeBuilder) BridgeBalance(t *testing.T, account string, amount *big.Int) (*types.Transaction, *types.Receipt) { - return bridgeBalanceImpl(t, account, amount, b.L1Info, b.L2Info, b.L1Client, b.L2Client, b.ctx) +func (b *NodeBuilder) BuildL2(t *testing.T) *TestClient { + l2 := NewTestClient(b.ctx) + l2.Info, l2.Node, l2.Client = + CreateTestL2WithConfig(t, b.ctx, b.Info, b.nodeConfig, b.takeOwnership) + b.L2 = l2 + return l2 } -func (b *NodeBuilder) TransferBalanceViaL2(t *testing.T, from string, to string, amount *big.Int) (*types.Transaction, *types.Receipt) { - return transferBalanceToImpl(t, from, b.L2Info.GetAddress(to), amount, b.L2Info, b.L2Client, b.ctx) +func (b *NodeBuilder) Build2ndNode(t *testing.T, initData *statetransfer.ArbosInitializationInfo, nodeConfig *arbnode.Config, stackConfig *node.Config) *TestClient { + if b.L1 == nil { + t.Fatal("builder did not previously build a L1 Node") + } + if b.L2 == nil { + t.Fatal("builder did not previously build a L2 Node") + } + l2 := NewTestClient(b.ctx) + l2.Client, l2.Node = + Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, b.L1.Stack, b.L1.Info, initData, nodeConfig, stackConfig) + return l2 } -func (b *NodeBuilder) TransferBalanceViaL1(t *testing.T, from string, to string, amount *big.Int) (*types.Transaction, *types.Receipt) { - return transferBalanceToImpl(t, from, b.L1Info.GetAddress(to), amount, b.L1Info, b.L1Client, b.ctx) +func (b *NodeBuilder) Build2ndNodeDAS(t *testing.T, initData *statetransfer.ArbosInitializationInfo, dasConfig *das.DataAvailabilityConfig) *TestClient { + if b.L1 == nil { + t.Fatal("builder did not previously build a L1 Node") + } + if b.L2 == nil { + t.Fatal("builder did not previously build a L2 Node") + } + l2 := NewTestClient(b.ctx) + l2.Client, l2.Node = + Create2ndNode(t, b.ctx, b.L2.Node, b.L1.Stack, b.L1.Info, initData, dasConfig) + return l2 } -func (b *NodeBuilder) TransferBalanceToViaL2(t *testing.T, from string, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt) { - return transferBalanceToImpl(t, from, to, amount, b.L2Info, b.L2Client, b.ctx) +type TestBlockchain struct { + TestClient + // Blockchain fields + ChainDB ethdb.Database + NodeDB ethdb.Database + Blockchain *core.BlockChain } -func (b *NodeBuilder) TransferBalanceToViaL1(t *testing.T, from string, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt) { - return transferBalanceToImpl(t, from, to, amount, b.L1Info, b.L1Client, b.ctx) +func (b *NodeBuilder) ConfigForL1Blockchain(s *node.Config, i info) *NodeBuilder { + b.stackConfig = s + b.Info = i + return b } -func (b *NodeBuilder) GetBaseFeeAtViaL2(t *testing.T, blockNum *big.Int) *big.Int { - return getBaseFeeAtImpl(t, b.L2Client, b.ctx, blockNum) +func (b *NodeBuilder) BuilL1Blockchain(t *testing.T) *TestBlockchain { + l1 := &TestBlockchain{} + l1.ctx = b.ctx + l1.Info, l1.Client, l1.Backend, l1.Stack = createTestL1BlockChainWithConfig(t, b.Info, b.stackConfig) + return l1 } -func (b *NodeBuilder) GetBaseFeeAtViaL1(t *testing.T, blockNum *big.Int) *big.Int { - return getBaseFeeAtImpl(t, b.L1Client, b.ctx, blockNum) +func (b *NodeBuilder) ConfigForL2Blockchain(s *node.Config, i info) *NodeBuilder { + b.stackConfig = s + b.Info = i + return b } -func (b *NodeBuilder) DeploySimple(t *testing.T, auth bind.TransactOpts) (common.Address, *mocksgen.Simple) { - return deploySimpleImpl(t, b.ctx, auth, b.L2Client) +func (b *NodeBuilder) BuilL2Blockchain(t *testing.T, dataDir string, initMessage *arbostypes.ParsedInitMessage) *TestBlockchain { + l2 := &TestBlockchain{} + l2.Info, l2.Stack, l2.ChainDB, l2.NodeDB, l2.Blockchain = + createL2BlockChainWithStackConfig(t, b.Info, dataDir, b.chainConfig, initMessage, b.stackConfig, b.cachingConfig) + return l2 } func SendWaitTestTransactions(t *testing.T, ctx context.Context, client client, txs []*types.Transaction) { @@ -193,7 +278,14 @@ func SendWaitTestTransactions(t *testing.T, ctx context.Context, client client, } } -func transferBalanceToImpl( +func TransferBalance( + t *testing.T, from, to string, amount *big.Int, l2info info, client client, ctx context.Context, +) (*types.Transaction, *types.Receipt) { + t.Helper() + return TransferBalanceTo(t, from, l2info.GetAddress(to), amount, l2info, client, ctx) +} + +func TransferBalanceTo( t *testing.T, from string, to common.Address, amount *big.Int, l2info info, client client, ctx context.Context, ) (*types.Transaction, *types.Receipt) { t.Helper() @@ -206,7 +298,7 @@ func transferBalanceToImpl( } // if l2client is not nil - will wait until balance appears in l2 -func bridgeBalanceImpl( +func BridgeBalance( t *testing.T, account string, amount *big.Int, l1info info, l2info info, l1client client, l2client client, ctx context.Context, ) (*types.Transaction, *types.Receipt) { t.Helper() @@ -253,7 +345,7 @@ func bridgeBalanceImpl( if balance.Cmp(l2Balance) >= 0 { break } - transferBalanceToImpl(t, "Faucet", l1info.GetAddress("User"), big.NewInt(1), l1info, l1client, ctx) + TransferBalance(t, "Faucet", "User", big.NewInt(1), l1info, l1client, ctx) if i > 20 { Fatal(t, "bridging failed") } @@ -264,7 +356,7 @@ func bridgeBalanceImpl( return tx, res } -func sendSignedTxViaL1Impl( +func SendSignedTxViaL1( t *testing.T, ctx context.Context, l1info *BlockchainTestInfo, @@ -295,7 +387,7 @@ func sendSignedTxViaL1Impl( return receipt } -func sendUnsignedTxViaL1Impl( +func SendUnsignedTxViaL1( t *testing.T, ctx context.Context, l1info *BlockchainTestInfo, @@ -346,7 +438,13 @@ func sendUnsignedTxViaL1Impl( return receipt } -func getBaseFeeAtImpl(t *testing.T, client client, ctx context.Context, blockNum *big.Int) *big.Int { +func GetBaseFee(t *testing.T, client client, ctx context.Context) *big.Int { + header, err := client.HeaderByNumber(ctx, nil) + Require(t, err) + return header.BaseFee +} + +func GetBaseFeeAt(t *testing.T, client client, ctx context.Context, blockNum *big.Int) *big.Int { header, err := client.HeaderByNumber(ctx, blockNum) Require(t, err) return header.BaseFee @@ -662,7 +760,33 @@ func ClientForStack(t *testing.T, backend *node.Node) *ethclient.Client { } // Create and deploy L1 and arbnode for L2 -func createTestNodeOnL1AndL2Impl( +func createTestNodeOnL1( + t *testing.T, + ctx context.Context, + isSequencer bool, +) ( + l2info info, node *arbnode.Node, l2client *ethclient.Client, l1info info, + l1backend *eth.Ethereum, l1client *ethclient.Client, l1stack *node.Node, +) { + return createTestNodeOnL1WithConfig(t, ctx, isSequencer, nil, nil, nil) +} + +func createTestNodeOnL1WithConfig( + t *testing.T, + ctx context.Context, + isSequencer bool, + nodeConfig *arbnode.Config, + chainConfig *params.ChainConfig, + stackConfig *node.Config, +) ( + l2info info, currentNode *arbnode.Node, l2client *ethclient.Client, l1info info, + l1backend *eth.Ethereum, l1client *ethclient.Client, l1stack *node.Node, +) { + l2info, currentNode, l2client, _, l1info, l1backend, l1client, l1stack = createTestNodeOnL1WithConfigImpl(t, ctx, isSequencer, nodeConfig, chainConfig, stackConfig, nil) + return +} + +func createTestNodeOnL1WithConfigImpl( t *testing.T, ctx context.Context, isSequencer bool, @@ -725,12 +849,12 @@ func createTestNodeOnL1AndL2Impl( // L2 -Only. Enough for tests that needs no interface to L1 // Requires precompiles.AllowDebugPrecompiles = true -func createTestNodeOnL2OnlyImpl( - t *testing.T, - ctx context.Context, - l2Info *BlockchainTestInfo, - nodeConfig *arbnode.Config, - takeOwnership bool, +func CreateTestL2(t *testing.T, ctx context.Context) (*BlockchainTestInfo, *arbnode.Node, *ethclient.Client) { + return CreateTestL2WithConfig(t, ctx, nil, arbnode.ConfigDefaultL2Test(), true) +} + +func CreateTestL2WithConfig( + t *testing.T, ctx context.Context, l2Info *BlockchainTestInfo, nodeConfig *arbnode.Config, takeOwnership bool, ) (*BlockchainTestInfo, *arbnode.Node, *ethclient.Client) { feedErrChan := make(chan error, 10) @@ -993,7 +1117,7 @@ func getDeadlineTimeout(t *testing.T, defaultTimeout time.Duration) time.Duratio return timeout } -func deploySimpleImpl( +func deploySimple( t *testing.T, ctx context.Context, auth bind.TransactOpts, client *ethclient.Client, ) (common.Address, *mocksgen.Simple) { addr, tx, simple, err := mocksgen.DeploySimple(&auth, client) diff --git a/system_tests/conditionaltx_test.go b/system_tests/conditionaltx_test.go index f4b6dd85cf..14aa000313 100644 --- a/system_tests/conditionaltx_test.go +++ b/system_tests/conditionaltx_test.go @@ -203,42 +203,42 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, node, l2client, _, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) - contractAddress1, simple1 := testNode.DeploySimple(t, auth) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) + contractAddress1, simple1 := deploySimple(t, ctx, auth, l2client) tx, err := simple1.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - contractAddress2, simple2 := testNode.DeploySimple(t, auth) + contractAddress2, simple2 := deploySimple(t, ctx, auth, l2client) tx, err = simple2.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) tx, err = simple2.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - currentRootHash1 := getStorageRootHash(t, testNode.L2Node, contractAddress1) - currentSlotValueMap1 := getStorageSlotValue(t, testNode.L2Node, contractAddress1) - currentRootHash2 := getStorageRootHash(t, testNode.L2Node, contractAddress2) - currentSlotValueMap2 := getStorageSlotValue(t, testNode.L2Node, contractAddress2) + currentRootHash1 := getStorageRootHash(t, node, contractAddress1) + currentSlotValueMap1 := getStorageSlotValue(t, node, contractAddress1) + currentRootHash2 := getStorageRootHash(t, node, contractAddress2) + currentSlotValueMap2 := getStorageSlotValue(t, node, contractAddress2) - rpcClient, err := testNode.L2Node.Stack.Attach() + rpcClient, err := node.Stack.Attach() Require(t, err) - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - testConditionalTxThatShouldSucceed(t, ctx, -1, testNode.L2Info, rpcClient, nil) + testConditionalTxThatShouldSucceed(t, ctx, -1, l2info, rpcClient, nil) for i, options := range getEmptyOptions(contractAddress1) { - testConditionalTxThatShouldSucceed(t, ctx, i, testNode.L2Info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, i, l2info, rpcClient, options) } - block, err := testNode.L1Client.BlockByNumber(ctx, nil) + block, err := l1client.BlockByNumber(ctx, nil) Require(t, err) blockNumber := block.NumberU64() blockTime := block.Time() @@ -249,33 +249,33 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { options1 := dedupOptions(t, append(append(optionsAB, optionsA...), optionsB...)) options1 = optionsDedupProduct(t, options1, getFulfillableBlockTimeLimits(t, blockNumber, blockTime)) for i, options := range options1 { - testConditionalTxThatShouldSucceed(t, ctx, i, testNode.L2Info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, i, l2info, rpcClient, options) } tx, err = simple1.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) tx, err = simple2.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) previousStorageRootHash1 := currentRootHash1 - currentRootHash1 = getStorageRootHash(t, testNode.L2Node, contractAddress1) + currentRootHash1 = getStorageRootHash(t, node, contractAddress1) if bytes.Equal(previousStorageRootHash1.Bytes(), currentRootHash1.Bytes()) { Fatal(t, "storage root hash didn't change as expected") } - currentSlotValueMap1 = getStorageSlotValue(t, testNode.L2Node, contractAddress1) + currentSlotValueMap1 = getStorageSlotValue(t, node, contractAddress1) previousStorageRootHash2 := currentRootHash2 - currentRootHash2 = getStorageRootHash(t, testNode.L2Node, contractAddress2) + currentRootHash2 = getStorageRootHash(t, node, contractAddress2) if bytes.Equal(previousStorageRootHash2.Bytes(), currentRootHash2.Bytes()) { Fatal(t, "storage root hash didn't change as expected") } - currentSlotValueMap2 = getStorageSlotValue(t, testNode.L2Node, contractAddress2) + currentSlotValueMap2 = getStorageSlotValue(t, node, contractAddress2) - block, err = testNode.L1Client.BlockByNumber(ctx, nil) + block, err = l1client.BlockByNumber(ctx, nil) Require(t, err) blockNumber = block.NumberU64() blockTime = block.Time() @@ -286,35 +286,35 @@ func TestSendRawTransactionConditionalBasic(t *testing.T) { options2 := dedupOptions(t, append(append(optionsCD, optionsC...), optionsD...)) options2 = optionsDedupProduct(t, options2, getFulfillableBlockTimeLimits(t, blockNumber, blockTime)) for i, options := range options2 { - testConditionalTxThatShouldSucceed(t, ctx, i, testNode.L2Info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, i, l2info, rpcClient, options) } for i, options := range options1 { - testConditionalTxThatShouldFail(t, ctx, i, testNode.L2Info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, i, l2info, rpcClient, options, -32003) } - block, err = testNode.L1Client.BlockByNumber(ctx, nil) + block, err = l1client.BlockByNumber(ctx, nil) Require(t, err) blockNumber = block.NumberU64() blockTime = block.Time() options3 := optionsDedupProduct(t, options2, getUnfulfillableBlockTimeLimits(t, blockNumber, blockTime)) for i, options := range options3 { - testConditionalTxThatShouldFail(t, ctx, i, testNode.L2Info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, i, l2info, rpcClient, options, -32003) } options4 := optionsDedupProduct(t, options2, options1) for i, options := range options4 { - testConditionalTxThatShouldFail(t, ctx, i, testNode.L2Info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, i, l2info, rpcClient, options, -32003) } } func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() - rpcClient, err := testNode.L2Node.Stack.Attach() + l2info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() + rpcClient, err := node.Stack.Attach() Require(t, err) - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) - contractAddress, simple := testNode.DeploySimple(t, auth) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) + contractAddress, simple := deploySimple(t, ctx, auth, client) simpleContract, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) Require(t, err) @@ -325,11 +325,11 @@ func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { var options []*arbitrum_types.ConditionalOptions for i := 0; i < numTxes; i++ { account := fmt.Sprintf("User%v", i) - testNode.L2Info.GenerateAccount(account) - tx := testNode.L2Info.PrepareTx("Owner", account, testNode.L2Info.TransferGas, big.NewInt(1e16), nil) - err := testNode.L2Client.SendTransaction(ctx, tx) + l2info.GenerateAccount(account) + tx := l2info.PrepareTx("Owner", account, l2info.TransferGas, big.NewInt(1e16), nil) + err := client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) } for i := numTxes - 1; i >= 0; i-- { @@ -337,7 +337,7 @@ func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { data, err := simpleContract.Pack("logAndIncrement", big.NewInt(int64(expected))) Require(t, err) account := fmt.Sprintf("User%v", i) - txes = append(txes, testNode.L2Info.PrepareTxTo(account, &contractAddress, testNode.L2Info.TransferGas, big.NewInt(0), data)) + txes = append(txes, l2info.PrepareTxTo(account, &contractAddress, l2info.TransferGas, big.NewInt(0), data)) options = append(options, &arbitrum_types.ConditionalOptions{KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{contractAddress: {SlotValue: map[common.Hash]common.Hash{{0}: common.BigToHash(big.NewInt(int64(expected)))}}}}) } ctxWithTimeout, cancelCtxWithTimeout := context.WithTimeout(ctx, 5*time.Second) @@ -367,7 +367,7 @@ func TestSendRawTransactionConditionalMultiRoutine(t *testing.T) { } cancelCtxWithTimeout() wg.Wait() - bc := testNode.L2Node.Execution.Backend.ArbInterface().BlockChain() + bc := node.Execution.Backend.ArbInterface().BlockChain() genesis := bc.Config().ArbitrumChainParams.GenesisBlockNum var receipts types.Receipts @@ -409,34 +409,34 @@ func TestSendRawTransactionConditionalPreCheck(t *testing.T) { nodeConfig.TxPreChecker.RequiredStateAge = 1 nodeConfig.TxPreChecker.RequiredStateMaxBlocks = 2 - testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() - rpcClient, err := testNode.L2Node.Stack.Attach() + l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, nil) + defer requireClose(t, l1stack) + defer node.StopAndWait() + rpcClient, err := node.Stack.Attach() Require(t, err) - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) start := time.Now().Unix() - contractAddress, simple := testNode.DeploySimple(t, auth) + contractAddress, simple := deploySimple(t, ctx, auth, l2client) if time.Since(time.Unix(start, 0)) > 200*time.Millisecond { start++ time.Sleep(time.Until(time.Unix(start, 0))) } tx, err := simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - currentRootHash := getStorageRootHash(t, testNode.L2Node, contractAddress) + currentRootHash := getStorageRootHash(t, node, contractAddress) options := &arbitrum_types.ConditionalOptions{ KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{ contractAddress: {RootHash: ¤tRootHash}, }, } - testConditionalTxThatShouldFail(t, ctx, 0, testNode.L2Info, rpcClient, options, -32003) + testConditionalTxThatShouldFail(t, ctx, 0, l2info, rpcClient, options, -32003) time.Sleep(time.Until(time.Unix(start+1, 0))) - testConditionalTxThatShouldSucceed(t, ctx, 1, testNode.L2Info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, 1, l2info, rpcClient, options) start = time.Now().Unix() if time.Since(time.Unix(start, 0)) > 200*time.Millisecond { @@ -445,23 +445,23 @@ func TestSendRawTransactionConditionalPreCheck(t *testing.T) { } tx, err = simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - currentRootHash = getStorageRootHash(t, testNode.L2Node, contractAddress) + currentRootHash = getStorageRootHash(t, node, contractAddress) options = &arbitrum_types.ConditionalOptions{ KnownAccounts: map[common.Address]arbitrum_types.RootHashOrSlots{ contractAddress: {RootHash: ¤tRootHash}, }, } - testConditionalTxThatShouldFail(t, ctx, 2, testNode.L2Info, rpcClient, options, -32003) - tx = testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, big.NewInt(1e12), nil) - Require(t, testNode.L2Client.SendTransaction(ctx, tx)) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + testConditionalTxThatShouldFail(t, ctx, 2, l2info, rpcClient, options, -32003) + tx = l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) + Require(t, l2client.SendTransaction(ctx, tx)) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - testConditionalTxThatShouldFail(t, ctx, 3, testNode.L2Info, rpcClient, options, -32003) - tx = testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, big.NewInt(1e12), nil) - Require(t, testNode.L2Client.SendTransaction(ctx, tx)) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + testConditionalTxThatShouldFail(t, ctx, 3, l2info, rpcClient, options, -32003) + tx = l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) + Require(t, l2client.SendTransaction(ctx, tx)) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - testConditionalTxThatShouldSucceed(t, ctx, 4, testNode.L2Info, rpcClient, options) + testConditionalTxThatShouldSucceed(t, ctx, 4, l2info, rpcClient, options) } diff --git a/system_tests/contract_tx_test.go b/system_tests/contract_tx_test.go index 8f6debdf37..e671dcc6ac 100644 --- a/system_tests/contract_tx_test.go +++ b/system_tests/contract_tx_test.go @@ -26,18 +26,19 @@ func TestContractTxDeploy(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, false) - defer testNode.L2Node.StopAndWait() + nodeconfig := arbnode.ConfigDefaultL2Test() + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, false) + defer node.StopAndWait() from := common.HexToAddress("0x123412341234") - testNode.TransferBalanceToViaL2(t, "Faucet", from, big.NewInt(1e18)) + TransferBalanceTo(t, "Faucet", from, big.NewInt(1e18), l2info, client, ctx) for stateNonce := uint64(0); stateNonce < 2; stateNonce++ { - pos, err := testNode.L2Node.TxStreamer.GetMessageCount() + pos, err := node.TxStreamer.GetMessageCount() Require(t, err) var delayedMessagesRead uint64 if pos > 0 { - lastMessage, err := testNode.L2Node.TxStreamer.GetMessage(pos - 1) + lastMessage, err := node.TxStreamer.GetMessage(pos - 1) Require(t, err) delayedMessagesRead = lastMessage.DelayedMessagesRead } @@ -69,7 +70,7 @@ func TestContractTxDeploy(t *testing.T) { l2Msg = append(l2Msg, math.U256Bytes(contractTx.Value)...) l2Msg = append(l2Msg, contractTx.Data...) - err = testNode.L2Node.TxStreamer.AddMessages(pos, true, []arbostypes.MessageWithMetadata{ + err = node.TxStreamer.AddMessages(pos, true, []arbostypes.MessageWithMetadata{ { Message: &arbostypes.L1IncomingMessage{ Header: &arbostypes.L1IncomingMessageHeader{ @@ -90,7 +91,7 @@ func TestContractTxDeploy(t *testing.T) { txHash := types.NewTx(contractTx).Hash() t.Log("made contract tx", contractTx, "with hash", txHash) - receipt, err := WaitForTx(ctx, testNode.L2Client, txHash, time.Second*10) + receipt, err := WaitForTx(ctx, client, txHash, time.Second*10) Require(t, err) if receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "Receipt has non-successful status", receipt.Status) @@ -103,7 +104,7 @@ func TestContractTxDeploy(t *testing.T) { t.Log("deployed contract", receipt.ContractAddress, "from address", from, "with nonce", stateNonce) stateNonce++ - code, err := testNode.L2Client.CodeAt(ctx, receipt.ContractAddress, nil) + code, err := client.CodeAt(ctx, receipt.ContractAddress, nil) Require(t, err) if !bytes.Equal(code, []byte{0xFE}) { Fatal(t, "expected contract", receipt.ContractAddress, "code of 0xFE but got", hex.EncodeToString(code)) diff --git a/system_tests/debugapi_test.go b/system_tests/debugapi_test.go index dedf7d2949..03e3dfd405 100644 --- a/system_tests/debugapi_test.go +++ b/system_tests/debugapi_test.go @@ -14,11 +14,11 @@ import ( func TestDebugAPI(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer requireClose(t, testNode.L2Stack) + _, _, _, l2stack, _, _, _, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, nil, nil, nil) + defer requireClose(t, l1stack) + defer requireClose(t, l2stack) - l2rpc, _ := testNode.L2Stack.Attach() + l2rpc, _ := l2stack.Attach() var dump state.Dump err := l2rpc.CallContext(ctx, &dump, "debug_dumpBlock", rpc.LatestBlockNumber) diff --git a/system_tests/delayedinbox_test.go b/system_tests/delayedinbox_test.go index 9830a06c7d..e48cb37028 100644 --- a/system_tests/delayedinbox_test.go +++ b/system_tests/delayedinbox_test.go @@ -38,16 +38,16 @@ func TestDelayInboxSimple(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, l2node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer l2node.StopAndWait() - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - delayedTx := testNode.L2Info.PrepareTx("Owner", "User2", 50001, big.NewInt(1e6), nil) - testNode.SendSignedTxViaL1(t, delayedTx) + delayedTx := l2info.PrepareTx("Owner", "User2", 50001, big.NewInt(1e6), nil) + SendSignedTxViaL1(t, ctx, l1info, l1client, l2client, delayedTx) - l2balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) + l2balance, err := l2client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e6)) != 0 { Fatal(t, "Unexpected balance:", l2balance) diff --git a/system_tests/delayedinboxlong_test.go b/system_tests/delayedinboxlong_test.go index cc41220ff6..b1c8ea361b 100644 --- a/system_tests/delayedinboxlong_test.go +++ b/system_tests/delayedinboxlong_test.go @@ -25,11 +25,11 @@ func TestDelayInboxLong(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, l2node, l2client, l1info, l1backend, l1client, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer l2node.StopAndWait() - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") fundsPerDelayed := int64(1000000) delayedMessages := int64(0) @@ -42,22 +42,22 @@ func TestDelayInboxLong(t *testing.T) { randNum := rand.Int() % messagesPerDelayed var l1tx *types.Transaction if randNum == 0 { - delayedTx := testNode.L2Info.PrepareTx("Owner", "User2", 50001, big.NewInt(fundsPerDelayed), nil) - l1tx = WrapL2ForDelayed(t, delayedTx, testNode.L1Info, "User", 100000) + delayedTx := l2info.PrepareTx("Owner", "User2", 50001, big.NewInt(fundsPerDelayed), nil) + l1tx = WrapL2ForDelayed(t, delayedTx, l1info, "User", 100000) lastDelayedMessage = delayedTx delayedMessages++ } else { - l1tx = testNode.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) + l1tx = l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) } l1Txs = append(l1Txs, l1tx) } // adding multiple messages in the same AddLocal to get them in the same L1 block - errs := testNode.L1Backend.TxPool().AddLocals(l1Txs) + errs := l1backend.TxPool().AddLocals(l1Txs) for _, err := range errs { Require(t, err) } // Checking every tx is expensive, so we just check the last, assuming that the others succeeded too - _, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1Txs[len(l1Txs)-1]) + _, err := EnsureTxSucceeded(ctx, l1client, l1Txs[len(l1Txs)-1]) Require(t, err) } @@ -68,14 +68,14 @@ func TestDelayInboxLong(t *testing.T) { // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 100; i++ { - SendWaitTestTransactions(t, ctx, testNode.L1Client, []*types.Transaction{ - testNode.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } - _, err := WaitForTx(ctx, testNode.L2Client, lastDelayedMessage.Hash(), time.Second*5) + _, err := WaitForTx(ctx, l2client, lastDelayedMessage.Hash(), time.Second*5) Require(t, err) - l2balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) + l2balance, err := l2client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(fundsPerDelayed*delayedMessages)) != 0 { Fatal(t, "Unexpected balance:", "balance", l2balance, "expected", fundsPerDelayed*delayedMessages) diff --git a/system_tests/estimation_test.go b/system_tests/estimation_test.go index ae3fc39a72..26b5a78145 100644 --- a/system_tests/estimation_test.go +++ b/system_tests/estimation_test.go @@ -13,7 +13,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/node_interfacegen" @@ -27,17 +26,17 @@ func TestDeploy(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) auth.GasMargin = 0 // don't adjust, we want to see if the estimate alone is sufficient - _, simple := testNode.DeploySimple(t, auth) + _, simple := deploySimple(t, ctx, auth, client) tx, err := simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) counter, err := simple.Counter(&bind.CallOpts{}) @@ -52,24 +51,24 @@ func TestEstimate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) auth.GasMargin = 0 // don't adjust, we want to see if the estimate alone is sufficient gasPrice := big.NewInt(params.GWei / 10) // set the gas price - arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), testNode.L2Client) + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), client) Require(t, err, "could not deploy ArbOwner contract") tx, err := arbOwner.SetMinimumL2BaseFee(&auth, gasPrice) Require(t, err, "could not set L2 gas price") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) // connect to arbGasInfo precompile - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), client) Require(t, err, "could not deploy contract") // wait for price to come to equilibrium @@ -77,8 +76,8 @@ func TestEstimate(t *testing.T) { numTriesLeft := 20 for !equilibrated && numTriesLeft > 0 { // make an empty block to let the gas price update - testNode.L2Info.GasPrice = new(big.Int).Mul(testNode.L2Info.GasPrice, big.NewInt(2)) - testNode.TransferBalanceViaL2(t, "Owner", "Owner", common.Big0) + l2info.GasPrice = new(big.Int).Mul(l2info.GasPrice, big.NewInt(2)) + TransferBalance(t, "Owner", "Owner", common.Big0, l2info, client, ctx) // check if the price has equilibrated _, _, _, _, _, setPrice, err := arbGasInfo.GetPricesInWei(&bind.CallOpts{}) @@ -92,22 +91,22 @@ func TestEstimate(t *testing.T) { Fatal(t, "L2 gas price did not converge", gasPrice) } - initialBalance, err := testNode.L2Client.BalanceAt(ctx, auth.From, nil) + initialBalance, err := client.BalanceAt(ctx, auth.From, nil) Require(t, err, "could not get balance") // deploy a test contract - _, tx, simple, err := mocksgen.DeploySimple(&auth, testNode.L2Client) + _, tx, simple, err := mocksgen.DeploySimple(&auth, client) Require(t, err, "could not deploy contract") - receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + receipt, err := EnsureTxSucceeded(ctx, client, tx) Require(t, err) - header, err := testNode.L2Client.HeaderByNumber(ctx, receipt.BlockNumber) + header, err := client.HeaderByNumber(ctx, receipt.BlockNumber) Require(t, err, "could not get header") if header.BaseFee.Cmp(gasPrice) != 0 { Fatal(t, "Header has wrong basefee", header.BaseFee, gasPrice) } - balance, err := testNode.L2Client.BalanceAt(ctx, auth.From, nil) + balance, err := client.BalanceAt(ctx, auth.From, nil) Require(t, err, "could not get balance") expectedCost := receipt.GasUsed * gasPrice.Uint64() observedCost := initialBalance.Uint64() - balance.Uint64() @@ -117,7 +116,7 @@ func TestEstimate(t *testing.T) { tx, err = simple.Increment(&auth) Require(t, err, "failed to call Increment()") - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) counter, err := simple.Counter(&bind.CallOpts{}) @@ -132,11 +131,11 @@ func TestComponentEstimate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() l1BaseFee := new(big.Int).Set(arbostypes.DefaultInitialL1BaseFee) - l2BaseFee := testNode.GetBaseFeeAtViaL2(t, nil) + l2BaseFee := GetBaseFee(t, client, ctx) colors.PrintGrey("l1 basefee ", l1BaseFee) colors.PrintGrey("l2 basefee ", l2BaseFee) @@ -145,10 +144,10 @@ func TestComponentEstimate(t *testing.T) { maxPriorityFeePerGas := big.NewInt(0) maxFeePerGas := arbmath.BigMulByUfrac(l2BaseFee, 3, 2) - testNode.L2Info.GenerateAccount("User") - testNode.TransferBalanceViaL2(t, "Owner", "User", userBalance) + l2info.GenerateAccount("User") + TransferBalance(t, "Owner", "User", userBalance, l2info, client, ctx) - from := testNode.L2Info.GetAddress("User") + from := l2info.GetAddress("User") to := testhelpers.RandomAddress() gas := uint64(100000000) calldata := []byte{0x00, 0x12} @@ -172,7 +171,7 @@ func TestComponentEstimate(t *testing.T) { Value: value, Data: estimateCalldata, } - returnData, err := testNode.L2Client.CallContract(ctx, msg, nil) + returnData, err := client.CallContract(ctx, msg, nil) Require(t, err) outputs, err := nodeMethod.Outputs.Unpack(returnData) @@ -186,8 +185,8 @@ func TestComponentEstimate(t *testing.T) { baseFee, _ := outputs[2].(*big.Int) l1BaseFeeEstimate, _ := outputs[3].(*big.Int) - tx := testNode.L2Info.SignTxAs("User", &types.DynamicFeeTx{ - ChainID: testNode.L2Node.Execution.ArbInterface.BlockChain().Config().ChainID, + tx := l2info.SignTxAs("User", &types.DynamicFeeTx{ + ChainID: node.Execution.ArbInterface.BlockChain().Config().ChainID, Nonce: 0, GasTipCap: maxPriorityFeePerGas, GasFeeCap: maxFeePerGas, @@ -208,8 +207,8 @@ func TestComponentEstimate(t *testing.T) { Fatal(t, baseFee, l2BaseFee.Uint64()) } - Require(t, testNode.L2Client.SendTransaction(ctx, tx)) - receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + Require(t, client.SendTransaction(ctx, tx)) + receipt, err := EnsureTxSucceeded(ctx, client, tx) Require(t, err) l2Used := receipt.GasUsed - receipt.GasUsedForL1 @@ -224,14 +223,14 @@ func TestDisableL1Charging(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + _, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() addr := common.HexToAddress("0x12345678") - gasWithL1Charging, err := testNode.L2Client.EstimateGas(ctx, ethereum.CallMsg{To: &addr}) + gasWithL1Charging, err := client.EstimateGas(ctx, ethereum.CallMsg{To: &addr}) Require(t, err) - gasWithoutL1Charging, err := testNode.L2Client.EstimateGas(ctx, ethereum.CallMsg{To: &addr, SkipL1Charging: true}) + gasWithoutL1Charging, err := client.EstimateGas(ctx, ethereum.CallMsg{To: &addr, SkipL1Charging: true}) Require(t, err) if gasWithL1Charging <= gasWithoutL1Charging { @@ -241,14 +240,14 @@ func TestDisableL1Charging(t *testing.T) { Fatal(t, "Incorrect gas estimate with disabled L1 charging") } - _, err = testNode.L2Client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithL1Charging}, nil) + _, err = client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithL1Charging}, nil) Require(t, err) - _, err = testNode.L2Client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging}, nil) + _, err = client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging}, nil) if err == nil { Fatal(t, "CallContract passed with insufficient gas") } - _, err = testNode.L2Client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging, SkipL1Charging: true}, nil) + _, err = client.CallContract(ctx, ethereum.CallMsg{To: &addr, Gas: gasWithoutL1Charging, SkipL1Charging: true}, nil) Require(t, err) } diff --git a/system_tests/fees_test.go b/system_tests/fees_test.go index 5093b873da..bdd998357e 100644 --- a/system_tests/fees_test.go +++ b/system_tests/fees_test.go @@ -33,19 +33,19 @@ func TestSequencerFeePaid(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, l2node, l2client, _, _, _, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer l2node.StopAndWait() - version := testNode.L2Node.Execution.ArbInterface.BlockChain().Config().ArbitrumChainParams.InitialArbOSVersion - callOpts := testNode.L2Info.GetDefaultCallOpts("Owner", ctx) + version := l2node.Execution.ArbInterface.BlockChain().Config().ArbitrumChainParams.InitialArbOSVersion + callOpts := l2info.GetDefaultCallOpts("Owner", ctx) // get the network fee account - arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("0x6b"), testNode.L2Client) + arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("0x6b"), l2client) Require(t, err, "failed to deploy contract") - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) Require(t, err, "failed to deploy contract") - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), l2client) Require(t, err, "failed to deploy contract") networkFeeAccount, err := arbOwnerPublic.GetNetworkFeeAccount(callOpts) Require(t, err, "could not get the network fee account") @@ -53,24 +53,24 @@ func TestSequencerFeePaid(t *testing.T) { l1Estimate, err := arbGasInfo.GetL1BaseFeeEstimate(callOpts) Require(t, err) - baseFee := testNode.GetBaseFeeAtViaL2(t, nil) - testNode.L2Info.GasPrice = baseFee + baseFee := GetBaseFee(t, l2client, ctx) + l2info.GasPrice = baseFee testFees := func(tip uint64) (*big.Int, *big.Int) { tipCap := arbmath.BigMulByUint(baseFee, tip) - txOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := l2info.GetDefaultTransactOpts("Faucet", ctx) txOpts.GasTipCap = tipCap gasPrice := arbmath.BigAdd(baseFee, tipCap) - networkBefore := GetBalance(t, ctx, testNode.L2Client, networkFeeAccount) + networkBefore := GetBalance(t, ctx, l2client, networkFeeAccount) tx, err := arbDebug.Events(&txOpts, true, [32]byte{}) Require(t, err) - receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + receipt, err := EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) - networkAfter := GetBalance(t, ctx, testNode.L2Client, networkFeeAccount) - l1Charge := arbmath.BigMulByUint(testNode.L2Info.GasPrice, receipt.GasUsedForL1) + networkAfter := GetBalance(t, ctx, l2client, networkFeeAccount) + l1Charge := arbmath.BigMulByUint(l2info.GasPrice, receipt.GasUsedForL1) // the network should receive // 1. compute costs @@ -92,7 +92,7 @@ func TestSequencerFeePaid(t *testing.T) { l1GasBought := arbmath.BigDiv(l1Charge, l1Estimate).Uint64() l1ChargeExpected := arbmath.BigMulByUint(l1Estimate, txSize*params.TxDataNonZeroGasEIP2028) // L1 gas can only be charged in terms of L2 gas, so subtract off any rounding error from the expected value - l1ChargeExpected.Sub(l1ChargeExpected, new(big.Int).Mod(l1ChargeExpected, testNode.L2Info.GasPrice)) + l1ChargeExpected.Sub(l1ChargeExpected, new(big.Int).Mod(l1ChargeExpected, l2info.GasPrice)) colors.PrintBlue("bytes ", l1GasBought/params.TxDataNonZeroGasEIP2028, txSize) @@ -135,38 +135,38 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { conf := arbnode.ConfigDefaultL1Test() conf.DelayedSequencer.FinalizeDistance = 1 - testNode := NewNodeBuilder(ctx).SetNodeConfig(conf).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, chainConfig, nil) + defer requireClose(t, l1stack) + defer node.StopAndWait() - ownerAuth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + ownerAuth := l2info.GetDefaultTransactOpts("Owner", ctx) // make ownerAuth a chain owner - arbdebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) + arbdebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), l2client) Require(t, err) tx, err := arbdebug.BecomeChainOwner(&ownerAuth) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2client, tx) // use ownerAuth to set the L1 price per unit Require(t, err) - arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), testNode.L2Client) + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), l2client) Require(t, err) tx, err = arbOwner.SetL1PricePerUnit(&ownerAuth, arbmath.UintToBig(initialEstimate)) Require(t, err) - _, err = WaitForTx(ctx, testNode.L2Client, tx.Hash(), time.Second*5) + _, err = WaitForTx(ctx, l2client, tx.Hash(), time.Second*5) Require(t, err) - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) Require(t, err) lastEstimate, err := arbGasInfo.GetL1BaseFeeEstimate(&bind.CallOpts{Context: ctx}) Require(t, err) - lastBatchCount, err := testNode.L2Node.InboxTracker.GetBatchCount() + lastBatchCount, err := node.InboxTracker.GetBatchCount() Require(t, err) - l1Header, err := testNode.L1Client.HeaderByNumber(ctx, nil) + l1Header, err := l1client.HeaderByNumber(ctx, nil) Require(t, err) - rewardRecipientBalanceBefore := GetBalance(t, ctx, testNode.L2Client, l1pricing.BatchPosterAddress) + rewardRecipientBalanceBefore := GetBalance(t, ctx, l2client, l1pricing.BatchPosterAddress) timesPriceAdjusted := 0 colors.PrintBlue("Initial values") @@ -175,17 +175,17 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { numRetrogradeMoves := 0 for i := 0; i < 256; i++ { - tx, receipt := testNode.TransferBalanceViaL2(t, "Owner", "Owner", common.Big1) - header, err := testNode.L2Client.HeaderByHash(ctx, receipt.BlockHash) + tx, receipt := TransferBalance(t, "Owner", "Owner", common.Big1, l2info, l2client, ctx) + header, err := l2client.HeaderByHash(ctx, receipt.BlockHash) Require(t, err) - testNode.TransferBalanceViaL1(t, "Faucet", "Faucet", common.Big1) // generate l1 traffic + TransferBalance(t, "Faucet", "Faucet", common.Big1, l1info, l1client, ctx) // generate l1 traffic units := compressedTxSize(t, tx) * params.TxDataNonZeroGasEIP2028 estimatedL1FeePerUnit := arbmath.BigDivByUint(arbmath.BigMulByUint(header.BaseFee, receipt.GasUsedForL1), units) if !arbmath.BigEquals(lastEstimate, estimatedL1FeePerUnit) { - l1Header, err = testNode.L1Client.HeaderByNumber(ctx, nil) + l1Header, err = l1client.HeaderByNumber(ctx, nil) Require(t, err) callOpts := &bind.CallOpts{Context: ctx, BlockNumber: receipt.BlockNumber} @@ -234,7 +234,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { // see that the inbox advances for j := 16; j > 0; j-- { - newBatchCount, err := testNode.L2Node.InboxTracker.GetBatchCount() + newBatchCount, err := node.InboxTracker.GetBatchCount() Require(t, err) if newBatchCount > lastBatchCount { colors.PrintGrey("posted new batch ", newBatchCount) @@ -249,7 +249,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { } } - rewardRecipientBalanceAfter := GetBalance(t, ctx, testNode.L2Client, chainConfig.ArbitrumChainParams.InitialChainOwner) + rewardRecipientBalanceAfter := GetBalance(t, ctx, l2client, chainConfig.ArbitrumChainParams.InitialChainOwner) colors.PrintMint("reward recipient balance ", rewardRecipientBalanceBefore, " ➤ ", rewardRecipientBalanceAfter) colors.PrintMint("price changes ", timesPriceAdjusted) @@ -260,7 +260,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { Fatal(t, "reward recipient didn't get paid") } - arbAggregator, err := precompilesgen.NewArbAggregator(common.HexToAddress("0x6d"), testNode.L2Client) + arbAggregator, err := precompilesgen.NewArbAggregator(common.HexToAddress("0x6d"), l2client) Require(t, err) batchPosterAddresses, err := arbAggregator.GetBatchPosters(&bind.CallOpts{Context: ctx}) Require(t, err) @@ -268,7 +268,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) { for _, bpAddr := range batchPosterAddresses { if bpAddr != l1pricing.BatchPosterAddress && bpAddr != l1pricing.L1PricerFundsPoolAddress { numReimbursed++ - bal, err := testNode.L1Client.BalanceAt(ctx, bpAddr, nil) + bal, err := l1client.BalanceAt(ctx, bpAddr, nil) Require(t, err) if bal.Sign() == 0 { Fatal(t, "Batch poster balance is zero for", bpAddr) diff --git a/system_tests/forwarder_test.go b/system_tests/forwarder_test.go index 753f067ed2..0a954719d8 100644 --- a/system_tests/forwarder_test.go +++ b/system_tests/forwarder_test.go @@ -40,9 +40,9 @@ func TestStaticForwarder(t *testing.T) { nodeConfigA := arbnode.ConfigDefaultL1Test() nodeConfigA.BatchPoster.Enable = false - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(nodeConfigA).SetL2StackConfig(stackConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + l2info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, nil, stackConfig) + defer requireClose(t, l1stack) + defer nodeA.StopAndWait() nodeConfigB := arbnode.ConfigDefaultL1Test() nodeConfigB.Sequencer.Enable = false @@ -51,18 +51,18 @@ func TestStaticForwarder(t *testing.T) { nodeConfigB.ForwardingTarget = ipcPath nodeConfigB.BatchPoster.Enable = false - clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfigB, nil) + clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nodeConfigB, nil) defer nodeB.StopAndWait() - testNodeA.L2Info.GenerateAccount("User2") - tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, transferAmount, nil) + l2info.GenerateAccount("User2") + tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, transferAmount, nil) err := clientB.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, clientA, tx) Require(t, err) - l2balance, err := testNodeA.L2Client.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) + l2balance, err := clientA.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(transferAmount) != 0 { @@ -105,8 +105,7 @@ func fallbackSequencer( nodeConfig.SeqCoordinator.Enable = opts.enableSecCoordinator nodeConfig.SeqCoordinator.RedisUrl = opts.redisUrl nodeConfig.SeqCoordinator.MyUrl = opts.ipcPath - testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetL2StackConfig(stackConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - return testNode.L2Info, testNode.L2Node, testNode.L2Client, testNode.L1Info, testNode.L1Backend, testNode.L1Client, testNode.L1Stack + return createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, stackConfig) } func createForwardingNode( diff --git a/system_tests/infra_fee_test.go b/system_tests/infra_fee_test.go index 10f43547f0..89f869576d 100644 --- a/system_tests/infra_fee_test.go +++ b/system_tests/infra_fee_test.go @@ -25,45 +25,45 @@ func TestInfraFee(t *testing.T) { defer cancel() nodeconfig := arbnode.ConfigDefaultL2Test() - testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeconfig).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, true) + defer node.StopAndWait() - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) ownerTxOpts.Context = ctx - ownerCallOpts := testNode.L2Info.GetDefaultCallOpts("Owner", ctx) + ownerCallOpts := l2info.GetDefaultCallOpts("Owner", ctx) - arbowner, err := precompilesgen.NewArbOwner(common.HexToAddress("70"), testNode.L2Client) + arbowner, err := precompilesgen.NewArbOwner(common.HexToAddress("70"), client) Require(t, err) - arbownerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("6b"), testNode.L2Client) + arbownerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("6b"), client) Require(t, err) networkFeeAddr, err := arbownerPublic.GetNetworkFeeAccount(ownerCallOpts) Require(t, err) infraFeeAddr := common.BytesToAddress(crypto.Keccak256([]byte{3, 2, 6})) tx, err := arbowner.SetInfraFeeAccount(&ownerTxOpts, infraFeeAddr) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) - _, simple := testNode.DeploySimple(t, ownerTxOpts) + _, simple := deploySimple(t, ctx, ownerTxOpts, client) - netFeeBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) + netFeeBalanceBefore, err := client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - infraFeeBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) + infraFeeBalanceBefore, err := client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) tx, err = simple.Increment(&ownerTxOpts) Require(t, err) - receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + receipt, err := EnsureTxSucceeded(ctx, client, tx) Require(t, err) l2GasUsed := receipt.GasUsed - receipt.GasUsedForL1 expectedFunds := arbmath.BigMulByUint(arbmath.UintToBig(l2pricing.InitialBaseFeeWei), l2GasUsed) expectedBalanceAfter := arbmath.BigAdd(infraFeeBalanceBefore, expectedFunds) - netFeeBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) + netFeeBalanceAfter, err := client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - infraFeeBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) + infraFeeBalanceAfter, err := client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) if !arbmath.BigEquals(netFeeBalanceBefore, netFeeBalanceAfter) { diff --git a/system_tests/initialization_test.go b/system_tests/initialization_test.go index cec68d693a..c7797d35e6 100644 --- a/system_tests/initialization_test.go +++ b/system_tests/initialization_test.go @@ -63,14 +63,14 @@ func TestInitContract(t *testing.T) { l2info.ArbInitData.Accounts = append(l2info.ArbInitData.Accounts, accountInfo) expectedSums[accountAddress] = sum } - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).SetL2Info(l2info).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + _, node, client := CreateTestL2WithConfig(t, ctx, l2info, arbnode.ConfigDefaultL2Test(), true) + defer node.StopAndWait() for accountAddress, sum := range expectedSums { msg := ethereum.CallMsg{ To: &accountAddress, } - res, err := testNode.L2Client.CallContract(ctx, msg, big.NewInt(0)) + res, err := client.CallContract(ctx, msg, big.NewInt(0)) Require(t, err) resBig := new(big.Int).SetBytes(res) if resBig.Cmp(sum) != 0 { diff --git a/system_tests/ipc_test.go b/system_tests/ipc_test.go index fbac4156cc..01ecf859d8 100644 --- a/system_tests/ipc_test.go +++ b/system_tests/ipc_test.go @@ -24,9 +24,9 @@ func TestIpcRpc(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetL2StackConfig(stackConf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + _, l2node, _, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, nil, stackConf) + defer requireClose(t, l1stack) + defer l2node.StopAndWait() _, err := ethclient.Dial(ipcPath) Require(t, err) diff --git a/system_tests/log_subscription_test.go b/system_tests/log_subscription_test.go index c64737bdcd..5ee1732fb0 100644 --- a/system_tests/log_subscription_test.go +++ b/system_tests/log_subscription_test.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" ) @@ -20,21 +19,21 @@ func TestLogSubscription(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) - arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, testNode.L2Client) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) + arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, client) Require(t, err) logChan := make(chan types.Log, 128) - subscription, err := testNode.L2Client.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, logChan) + subscription, err := client.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, logChan) Require(t, err) defer subscription.Unsubscribe() tx, err := arbSys.WithdrawEth(&auth, common.Address{}) Require(t, err) - receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + receipt, err := EnsureTxSucceeded(ctx, client, tx) Require(t, err) if len(receipt.Logs) != 1 { @@ -53,6 +52,6 @@ func TestLogSubscription(t *testing.T) { if !reflect.DeepEqual(receiptLog, subscriptionLog) { Fatal(t, "Receipt log", receiptLog, "is different than subscription log", subscriptionLog) } - _, err = testNode.L2Client.BlockByHash(ctx, subscriptionLog.BlockHash) + _, err = client.BlockByHash(ctx, subscriptionLog.BlockHash) Require(t, err) } diff --git a/system_tests/meaningless_reorg_test.go b/system_tests/meaningless_reorg_test.go index b30417a5af..851bf38ce0 100644 --- a/system_tests/meaningless_reorg_test.go +++ b/system_tests/meaningless_reorg_test.go @@ -20,24 +20,24 @@ func TestMeaninglessBatchReorg(t *testing.T) { defer cancel() conf := arbnode.ConfigDefaultL1Test() conf.BatchPoster.Enable = false - testNode := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2Info, arbNode, l2Client, l1Info, l1Backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, conf, nil, nil) + defer requireClose(t, l1stack) + defer arbNode.StopAndWait() - seqInbox, err := bridgegen.NewSequencerInbox(testNode.L1Info.GetAddress("SequencerInbox"), testNode.L1Client) + seqInbox, err := bridgegen.NewSequencerInbox(l1Info.GetAddress("SequencerInbox"), l1Client) Require(t, err) - seqOpts := testNode.L1Info.GetDefaultTransactOpts("Sequencer", ctx) + seqOpts := l1Info.GetDefaultTransactOpts("Sequencer", ctx) tx, err := seqInbox.AddSequencerL2BatchFromOrigin(&seqOpts, big.NewInt(1), nil, big.NewInt(1), common.Address{}) Require(t, err) - batchReceipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, tx) + batchReceipt, err := EnsureTxSucceeded(ctx, l1Client, tx) Require(t, err) for i := 0; ; i++ { if i >= 500 { Fatal(t, "Failed to read batch from L1") } - msgNum, err := testNode.L2Node.Execution.ExecEngine.HeadMessageNumber() + msgNum, err := arbNode.Execution.ExecEngine.HeadMessageNumber() Require(t, err) if msgNum == 1 { break @@ -46,33 +46,33 @@ func TestMeaninglessBatchReorg(t *testing.T) { } time.Sleep(10 * time.Millisecond) } - metadata, err := testNode.L2Node.InboxTracker.GetBatchMetadata(1) + metadata, err := arbNode.InboxTracker.GetBatchMetadata(1) Require(t, err) originalBatchBlock := batchReceipt.BlockNumber.Uint64() if metadata.ParentChainBlock != originalBatchBlock { Fatal(t, "Posted batch in block", originalBatchBlock, "but metadata says L1 block was", metadata.ParentChainBlock) } - _, l2Receipt := testNode.TransferBalanceViaL2(t, "Owner", "Owner", common.Big1) + _, l2Receipt := TransferBalance(t, "Owner", "Owner", common.Big1, l2Info, l2Client, ctx) // Make the reorg larger to force the miner to discard transactions. // The miner usually collects transactions from deleted blocks and puts them in the mempool. // However, this code doesn't run on reorgs larger than 64 blocks for performance reasons. // Therefore, we make a bunch of small blocks to prevent the code from running. for j := uint64(0); j < 70; j++ { - testNode.TransferBalanceViaL1(t, "Faucet", "Faucet", common.Big1) + TransferBalance(t, "Faucet", "Faucet", common.Big1, l1Info, l1Client, ctx) } - parentBlock := testNode.L1Backend.BlockChain().GetBlockByNumber(batchReceipt.BlockNumber.Uint64() - 1) - err = testNode.L1Backend.BlockChain().ReorgToOldBlock(parentBlock) + parentBlock := l1Backend.BlockChain().GetBlockByNumber(batchReceipt.BlockNumber.Uint64() - 1) + err = l1Backend.BlockChain().ReorgToOldBlock(parentBlock) Require(t, err) // Produce a new l1Block so that the batch ends up in a different l1Block than before - testNode.TransferBalanceViaL1(t, "User", "User", common.Big1) + TransferBalance(t, "User", "User", common.Big1, l1Info, l1Client, ctx) tx, err = seqInbox.AddSequencerL2BatchFromOrigin(&seqOpts, big.NewInt(1), nil, big.NewInt(1), common.Address{}) Require(t, err) - newBatchReceipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, tx) + newBatchReceipt, err := EnsureTxSucceeded(ctx, l1Client, tx) Require(t, err) newBatchBlock := newBatchReceipt.BlockNumber.Uint64() @@ -86,7 +86,7 @@ func TestMeaninglessBatchReorg(t *testing.T) { if i >= 500 { Fatal(t, "Failed to read batch reorg from L1") } - metadata, err = testNode.L2Node.InboxTracker.GetBatchMetadata(1) + metadata, err = arbNode.InboxTracker.GetBatchMetadata(1) Require(t, err) if metadata.ParentChainBlock == newBatchBlock { break @@ -96,10 +96,10 @@ func TestMeaninglessBatchReorg(t *testing.T) { time.Sleep(10 * time.Millisecond) } - _, err = testNode.L2Node.InboxReader.GetSequencerMessageBytes(ctx, 1) + _, err = arbNode.InboxReader.GetSequencerMessageBytes(ctx, 1) Require(t, err) - l2Header, err := testNode.L2Client.HeaderByNumber(ctx, l2Receipt.BlockNumber) + l2Header, err := l2Client.HeaderByNumber(ctx, l2Receipt.BlockNumber) Require(t, err) if l2Header.Hash() != l2Receipt.BlockHash { diff --git a/system_tests/nodeinterface_test.go b/system_tests/nodeinterface_test.go index 2f36fb1d7b..167f2204cd 100644 --- a/system_tests/nodeinterface_test.go +++ b/system_tests/nodeinterface_test.go @@ -19,23 +19,23 @@ func TestL2BlockRangeForL1(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() - user := testNode.L1Info.GetDefaultTransactOpts("User", ctx) + l2info, node, l2client, l1info, _, _, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer node.StopAndWait() + user := l1info.GetDefaultTransactOpts("User", ctx) numTransactions := 200 for i := 0; i < numTransactions; i++ { - testNode.TransferBalanceToViaL2(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18)) + TransferBalanceTo(t, "Owner", util.RemapL1Address(user.From), big.NewInt(1e18), l2info, l2client, ctx) } - nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, testNode.L2Client) + nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, l2client) if err != nil { t.Fatalf("Error creating node interface: %v", err) } l1BlockNums := map[uint64]*[2]uint64{} - latestL2, err := testNode.L2Client.BlockNumber(ctx) + latestL2, err := l2client.BlockNumber(ctx) if err != nil { t.Fatalf("Error querying most recent l2 block: %v", err) } diff --git a/system_tests/outbox_test.go b/system_tests/outbox_test.go index e0db034111..6b43cc83b0 100644 --- a/system_tests/outbox_test.go +++ b/system_tests/outbox_test.go @@ -16,7 +16,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/gethhook" "github.com/offchainlabs/nitro/solgen/go/node_interfacegen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" @@ -36,14 +35,14 @@ func TestOutboxProofs(t *testing.T) { withdrawTopic := arbSysAbi.Events["L2ToL1Tx"].ID merkleTopic := arbSysAbi.Events["SendMerkleUpdate"].ID - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) + auth := l2info.GetDefaultTransactOpts("Owner", ctx) - arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, testNode.L2Client) + arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, client) Require(t, err) - nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, testNode.L2Client) + nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, client) Require(t, err) txnCount := int64(1 + rand.Intn(16)) @@ -72,7 +71,7 @@ func TestOutboxProofs(t *testing.T) { txns = append(txns, tx.Hash()) time.Sleep(4 * time.Millisecond) // Geth takes a few ms for the receipt to show up - _, err = testNode.L2Client.TransactionReceipt(ctx, tx.Hash()) + _, err = client.TransactionReceipt(ctx, tx.Hash()) if err == nil { merkleState, err := arbSys.SendMerkleTreeState(&bind.CallOpts{}) Require(t, err, "could not get merkle root") @@ -87,7 +86,7 @@ func TestOutboxProofs(t *testing.T) { for _, tx := range txns { var receipt *types.Receipt - receipt, err = testNode.L2Client.TransactionReceipt(ctx, tx) + receipt, err = client.TransactionReceipt(ctx, tx) Require(t, err, "No receipt for txn") if receipt.Status != types.ReceiptStatusSuccessful { @@ -188,7 +187,7 @@ func TestOutboxProofs(t *testing.T) { // in one lookup, query geth for all the data we need to construct a proof var logs []types.Log if len(query) > 0 { - logs, err = testNode.L2Client.FilterLogs(ctx, ethereum.FilterQuery{ + logs, err = client.FilterLogs(ctx, ethereum.FilterQuery{ Addresses: []common.Address{ types.ArbSysAddress, }, diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 261c45035c..ad08ff7471 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" @@ -22,10 +21,10 @@ func TestPurePrecompileMethodCalls(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + _, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - arbSys, err := precompilesgen.NewArbSys(common.HexToAddress("0x64"), testNode.L2Client) + arbSys, err := precompilesgen.NewArbSys(common.HexToAddress("0x64"), client) Require(t, err, "could not deploy ArbSys contract") chainId, err := arbSys.ArbChainID(&bind.CallOpts{}) Require(t, err, "failed to get the ChainID") @@ -38,10 +37,10 @@ func TestViewLogReverts(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + _, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), client) Require(t, err, "could not deploy ArbSys contract") err = arbDebug.EventsView(nil) @@ -54,11 +53,11 @@ func TestCustomSolidityErrors(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + _, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() callOpts := &bind.CallOpts{Context: ctx} - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), testNode.L2Client) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), client) Require(t, err, "could not bind ArbDebug contract") customError := arbDebug.CustomRevert(callOpts, 1024) if customError == nil { @@ -70,7 +69,7 @@ func TestCustomSolidityErrors(t *testing.T) { Fatal(t, observedMessage) } - arbSys, err := precompilesgen.NewArbSys(arbos.ArbSysAddress, testNode.L2Client) + arbSys, err := precompilesgen.NewArbSys(arbos.ArbSysAddress, client) Require(t, err, "could not bind ArbSys contract") _, customError = arbSys.ArbBlockHash(callOpts, big.NewInt(1e9)) if customError == nil { @@ -87,11 +86,11 @@ func TestPrecompileErrorGasLeft(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - auth := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) - _, _, simple, err := mocksgen.DeploySimple(&auth, testNode.L2Client) + auth := info.GetDefaultTransactOpts("Faucet", ctx) + _, _, simple, err := mocksgen.DeploySimple(&auth, client) Require(t, err) assertNotAllGasConsumed := func(to common.Address, input []byte) { diff --git a/system_tests/recreatestate_rpc_test.go b/system_tests/recreatestate_rpc_test.go index 5224f21bfc..dbf68c8479 100644 --- a/system_tests/recreatestate_rpc_test.go +++ b/system_tests/recreatestate_rpc_test.go @@ -21,26 +21,26 @@ import ( "github.com/offchainlabs/nitro/util" ) -func prepareNodeWithHistory(t *testing.T, ctx context.Context, nodeConfig *arbnode.Config, txCount uint64) (*arbnode.Node, *execution.ExecutionNode, *ethclient.Client, func()) { +func prepareNodeWithHistory(t *testing.T, ctx context.Context, nodeConfig *arbnode.Config, txCount uint64) (node *arbnode.Node, executionNode *execution.ExecutionNode, l2client *ethclient.Client, cancel func()) { t.Helper() - testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - cancel := func() { - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, nil) + cancel = func() { + defer requireClose(t, l1stack) + defer node.StopAndWait() } - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") var txs []*types.Transaction for i := uint64(0); i < txCount; i++ { - tx := testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, common.Big1, nil) + tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, common.Big1, nil) txs = append(txs, tx) - err := testNode.L2Client.SendTransaction(ctx, tx) + err := l2client.SendTransaction(ctx, tx) Require(t, err) } for _, tx := range txs { - _, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err := EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) } - return testNode.L2Node, testNode.L2Node.Execution, testNode.L2Client, cancel + return node, node.Execution, l2client, cancel } func fillHeaderCache(t *testing.T, bc *core.BlockChain, from, to uint64) { diff --git a/system_tests/reorg_resequencing_test.go b/system_tests/reorg_resequencing_test.go index 0251969e37..f132d46487 100644 --- a/system_tests/reorg_resequencing_test.go +++ b/system_tests/reorg_resequencing_test.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbos/arbostypes" ) @@ -20,27 +19,27 @@ func TestReorgResequencing(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2(t, ctx) + defer node.StopAndWait() - startMsgCount, err := testNode.L2Node.TxStreamer.GetMessageCount() + startMsgCount, err := node.TxStreamer.GetMessageCount() Require(t, err) - testNode.L2Info.GenerateAccount("Intermediate") - testNode.L2Info.GenerateAccount("User1") - testNode.L2Info.GenerateAccount("User2") - testNode.L2Info.GenerateAccount("User3") - testNode.L2Info.GenerateAccount("User4") - testNode.TransferBalanceViaL2(t, "Owner", "User1", big.NewInt(params.Ether)) - testNode.TransferBalanceViaL2(t, "Owner", "Intermediate", big.NewInt(params.Ether*3)) - testNode.TransferBalanceViaL2(t, "Intermediate", "User2", big.NewInt(params.Ether)) - testNode.TransferBalanceViaL2(t, "Intermediate", "User3", big.NewInt(params.Ether)) + l2info.GenerateAccount("Intermediate") + l2info.GenerateAccount("User1") + l2info.GenerateAccount("User2") + l2info.GenerateAccount("User3") + l2info.GenerateAccount("User4") + TransferBalance(t, "Owner", "User1", big.NewInt(params.Ether), l2info, client, ctx) + TransferBalance(t, "Owner", "Intermediate", big.NewInt(params.Ether*3), l2info, client, ctx) + TransferBalance(t, "Intermediate", "User2", big.NewInt(params.Ether), l2info, client, ctx) + TransferBalance(t, "Intermediate", "User3", big.NewInt(params.Ether), l2info, client, ctx) // Intermediate does not have exactly 1 ether because of fees accountsWithBalance := []string{"User1", "User2", "User3"} verifyBalances := func(scenario string) { for _, account := range accountsWithBalance { - balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress(account), nil) + balance, err := client.BalanceAt(ctx, l2info.GetAddress(account), nil) Require(t, err) if balance.Int64() != params.Ether { Fatal(t, "expected account", account, "to have a balance of 1 ether but instead it has", balance, "wei "+scenario) @@ -49,15 +48,15 @@ func TestReorgResequencing(t *testing.T) { } verifyBalances("before reorg") - err = testNode.L2Node.TxStreamer.ReorgTo(startMsgCount) + err = node.TxStreamer.ReorgTo(startMsgCount) Require(t, err) - _, err = testNode.L2Node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) Require(t, err) verifyBalances("after empty reorg") - prevMessage, err := testNode.L2Node.TxStreamer.GetMessage(startMsgCount - 1) + prevMessage, err := node.TxStreamer.GetMessage(startMsgCount - 1) Require(t, err) delayedIndexHash := common.BigToHash(big.NewInt(int64(prevMessage.DelayedMessagesRead))) newMessage := &arbostypes.L1IncomingMessage{ @@ -69,24 +68,24 @@ func TestReorgResequencing(t *testing.T) { RequestId: &delayedIndexHash, L1BaseFee: common.Big0, }, - L2msg: append(testNode.L2Info.GetAddress("User4").Bytes(), math.U256Bytes(big.NewInt(params.Ether))...), + L2msg: append(l2info.GetAddress("User4").Bytes(), math.U256Bytes(big.NewInt(params.Ether))...), } - err = testNode.L2Node.TxStreamer.AddMessages(startMsgCount, true, []arbostypes.MessageWithMetadata{{ + err = node.TxStreamer.AddMessages(startMsgCount, true, []arbostypes.MessageWithMetadata{{ Message: newMessage, DelayedMessagesRead: prevMessage.DelayedMessagesRead + 1, }}) Require(t, err) - _, err = testNode.L2Node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) Require(t, err) accountsWithBalance = append(accountsWithBalance, "User4") verifyBalances("after reorg with new deposit") - err = testNode.L2Node.TxStreamer.ReorgTo(startMsgCount) + err = node.TxStreamer.ReorgTo(startMsgCount) Require(t, err) - _, err = testNode.L2Node.Execution.ExecEngine.HeadMessageNumberSync(t) + _, err = node.Execution.ExecEngine.HeadMessageNumberSync(t) Require(t, err) verifyBalances("after second empty reorg") diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 61c258893c..b1dd32d1dc 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -32,22 +32,25 @@ import ( ) func retryableSetup(t *testing.T) ( - *NodeBuilder, + *BlockchainTestInfo, + *BlockchainTestInfo, + *ethclient.Client, + *ethclient.Client, *bridgegen.Inbox, func(*types.Receipt) *types.Transaction, context.Context, func(), ) { ctx, cancel := context.WithCancel(context.Background()) - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + l2info, l2node, l2client, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) - testNode.L2Info.GenerateAccount("User2") - testNode.L2Info.GenerateAccount("Beneficiary") - testNode.L2Info.GenerateAccount("Burn") + l2info.GenerateAccount("User2") + l2info.GenerateAccount("Beneficiary") + l2info.GenerateAccount("Burn") - delayedInbox, err := bridgegen.NewInbox(testNode.L1Info.GetAddress("Inbox"), testNode.L1Client) + delayedInbox, err := bridgegen.NewInbox(l1info.GetAddress("Inbox"), l1client) Require(t, err) - delayedBridge, err := arbnode.NewDelayedBridge(testNode.L1Client, testNode.L1Info.GetAddress("Bridge"), 0) + delayedBridge, err := arbnode.NewDelayedBridge(l1client, l1info.GetAddress("Bridge"), 0) Require(t, err) lookupL2Tx := func(l1Receipt *types.Receipt) *types.Transaction { @@ -87,15 +90,15 @@ func retryableSetup(t *testing.T) ( // burn some gas so that the faucet's Callvalue + Balance never exceeds a uint256 discard := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) - testNode.TransferBalanceViaL2(t, "Faucet", "Burn", discard) + TransferBalance(t, "Faucet", "Burn", discard, l2info, l2client, ctx) teardown := func() { // check the integrity of the RPC - blockNum, err := testNode.L2Client.BlockNumber(ctx) + blockNum, err := l2client.BlockNumber(ctx) Require(t, err, "failed to get L2 block number") for number := uint64(0); number < blockNum; number++ { - block, err := testNode.L2Client.BlockByNumber(ctx, arbmath.UintToBig(number)) + block, err := l2client.BlockByNumber(ctx, arbmath.UintToBig(number)) Require(t, err, "failed to get L2 block", number, "of", blockNum) if block.Number().Uint64() != number { Fatal(t, "block number mismatch", number, block.Number().Uint64()) @@ -104,20 +107,19 @@ func retryableSetup(t *testing.T) ( cancel() - testNode.L2Node.StopAndWait() - requireClose(t, testNode.L1Stack) + l2node.StopAndWait() + requireClose(t, l1stack) } - return testNode, delayedInbox, lookupL2Tx, ctx, teardown + return l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown } func TestRetryableNoExist(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + _, node, l2client := CreateTestL2(t, ctx) + defer node.StopAndWait() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() - - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), testNode.L2Client) + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), l2client) Require(t, err) _, err = arbRetryableTx.GetTimeout(&bind.CallOpts{}, common.Hash{}) if err.Error() != "execution reverted: error NoTicketWithID()" { @@ -127,20 +129,20 @@ func TestRetryableNoExist(t *testing.T) { func TestSubmitRetryableImmediateSuccess(t *testing.T) { t.Parallel() - testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - user2Address := testNode.L2Info.GetAddress("User2") - beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") + user2Address := l2info.GetAddress("User2") + beneficiaryAddress := l2info.GetAddress("Beneficiary") deposit := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) callValue := big.NewInt(1e6) - nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, testNode.L2Client) + nodeInterface, err := node_interfacegen.NewNodeInterface(types.NodeInterfaceAddress, l2client) Require(t, err, "failed to deploy NodeInterface") // estimate the gas needed to auto redeem the retryable - usertxoptsL2 := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) + usertxoptsL2 := l2info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL2.NoSend = true usertxoptsL2.GasMargin = 0 tx, err := nodeInterface.EstimateRetryableTicket( @@ -158,7 +160,7 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { colors.PrintBlue("estimate: ", estimate) // submit & auto redeem the retryable using the gas estimate - usertxoptsL1 := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) + usertxoptsL1 := l1info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL1.Value = deposit l1tx, err := delayedInbox.CreateRetryableTicket( &usertxoptsL1, @@ -173,21 +175,21 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) + waitForL1DelayBlocks(t, ctx, l1client, l1info) - receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(l1Receipt)) + receipt, err := EnsureTxSucceeded(ctx, l2client, lookupL2Tx(l1Receipt)) Require(t, err) if receipt.Status != types.ReceiptStatusSuccessful { Fatal(t) } - l2balance, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) + l2balance, err := l2client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) if !arbmath.BigEquals(l2balance, big.NewInt(1e6)) { @@ -197,18 +199,18 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { func TestSubmitRetryableFailThenRetry(t *testing.T) { t.Parallel() - testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) - usertxopts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) + ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) + usertxopts := l1info.GetDefaultTransactOpts("Faucet", ctx) usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) - simpleAddr, simple := testNode.DeploySimple(t, ownerTxOpts) + simpleAddr, simple := deploySimple(t, ctx, ownerTxOpts, l2client) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) - beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") + beneficiaryAddress := l2info.GetAddress("Beneficiary") l1tx, err := delayedInbox.CreateRetryableTicket( &usertxopts, simpleAddr, @@ -223,15 +225,15 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) + waitForL1DelayBlocks(t, ctx, l1client, l1info) - receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(l1Receipt)) + receipt, err := EnsureTxSucceeded(ctx, l2client, lookupL2Tx(l1Receipt)) Require(t, err) if len(receipt.Logs) != 2 { Fatal(t, len(receipt.Logs)) @@ -240,23 +242,23 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { firstRetryTxId := receipt.Logs[1].Topics[2] // get receipt for the auto redeem, make sure it failed - receipt, err = WaitForTx(ctx, testNode.L2Client, firstRetryTxId, time.Second*5) + receipt, err = WaitForTx(ctx, l2client, firstRetryTxId, time.Second*5) Require(t, err) if receipt.Status != types.ReceiptStatusFailed { Fatal(t, receipt.GasUsed) } - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), testNode.L2Client) + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), l2client) Require(t, err) tx, err := arbRetryableTx.Redeem(&ownerTxOpts, ticketId) Require(t, err) - receipt, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + receipt, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) retryTxId := receipt.Logs[0].Topics[2] // check the receipt for the retry - receipt, err = WaitForTx(ctx, testNode.L2Client, retryTxId, time.Second*1) + receipt, err = WaitForTx(ctx, l2client, retryTxId, time.Second*1) Require(t, err) if receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, receipt.Status) @@ -286,32 +288,32 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { func TestSubmissionGasCosts(t *testing.T) { t.Parallel() - testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, testNode.L2Client, testNode.L2Info) - elevateL2Basefee(t, ctx, testNode) + infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, l2client, l2info) + elevateL2Basefee(t, ctx, l2client, l2info) - usertxopts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) + usertxopts := l1info.GetDefaultTransactOpts("Faucet", ctx) usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) - testNode.L2Info.GenerateAccount("Refund") - testNode.L2Info.GenerateAccount("Receive") - faucetAddress := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) - beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") - feeRefundAddress := testNode.L2Info.GetAddress("Refund") - receiveAddress := testNode.L2Info.GetAddress("Receive") + l2info.GenerateAccount("Refund") + l2info.GenerateAccount("Receive") + faucetAddress := util.RemapL1Address(l1info.GetAddress("Faucet")) + beneficiaryAddress := l2info.GetAddress("Beneficiary") + feeRefundAddress := l2info.GetAddress("Refund") + receiveAddress := l2info.GetAddress("Receive") colors.PrintBlue("Faucet ", faucetAddress) colors.PrintBlue("Receive ", receiveAddress) colors.PrintBlue("Beneficiary ", beneficiaryAddress) colors.PrintBlue("Fee Refund ", feeRefundAddress) - fundsBeforeSubmit, err := testNode.L2Client.BalanceAt(ctx, faucetAddress, nil) + fundsBeforeSubmit, err := l2client.BalanceAt(ctx, faucetAddress, nil) Require(t, err) - infraBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceBefore, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceBefore, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) usefulGas := params.TxGas @@ -335,28 +337,28 @@ func TestSubmissionGasCosts(t *testing.T) { ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) + waitForL1DelayBlocks(t, ctx, l1client, l1info) submissionTxOuter := lookupL2Tx(l1Receipt) - submissionReceipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, submissionTxOuter) + submissionReceipt, err := EnsureTxSucceeded(ctx, l2client, submissionTxOuter) Require(t, err) if len(submissionReceipt.Logs) != 2 { Fatal(t, "Unexpected number of logs:", len(submissionReceipt.Logs)) } firstRetryTxId := submissionReceipt.Logs[1].Topics[2] // get receipt for the auto redeem - redeemReceipt, err := WaitForTx(ctx, testNode.L2Client, firstRetryTxId, time.Second*5) + redeemReceipt, err := WaitForTx(ctx, l2client, firstRetryTxId, time.Second*5) Require(t, err) if redeemReceipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "first retry tx failed") } - redeemBlock, err := testNode.L2Client.HeaderByNumber(ctx, redeemReceipt.BlockNumber) + redeemBlock, err := l2client.HeaderByNumber(ctx, redeemReceipt.BlockNumber) Require(t, err) l2BaseFee := redeemBlock.BaseFee @@ -364,18 +366,18 @@ func TestSubmissionGasCosts(t *testing.T) { excessWei := arbmath.BigMulByUint(l2BaseFee, excessGasLimit) excessWei.Add(excessWei, arbmath.BigMul(excessGasPrice, retryableGas)) - fundsAfterSubmit, err := testNode.L2Client.BalanceAt(ctx, faucetAddress, nil) + fundsAfterSubmit, err := l2client.BalanceAt(ctx, faucetAddress, nil) Require(t, err) - beneficiaryFunds, err := testNode.L2Client.BalanceAt(ctx, beneficiaryAddress, nil) + beneficiaryFunds, err := l2client.BalanceAt(ctx, beneficiaryAddress, nil) Require(t, err) - refundFunds, err := testNode.L2Client.BalanceAt(ctx, feeRefundAddress, nil) + refundFunds, err := l2client.BalanceAt(ctx, feeRefundAddress, nil) Require(t, err) - receiveFunds, err := testNode.L2Client.BalanceAt(ctx, receiveAddress, nil) + receiveFunds, err := l2client.BalanceAt(ctx, receiveAddress, nil) Require(t, err) - infraBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceAfter, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceAfter, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceAfter, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) colors.PrintBlue("CallGas ", retryableGas) @@ -422,7 +424,7 @@ func TestSubmissionGasCosts(t *testing.T) { Fatal(t, "Supplied gas was improperly deducted\n", fundsBeforeSubmit, "\n", fundsAfterSubmit) } - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) Require(t, err) minimumBaseFee, err := arbGasInfo.GetMinimumGasPrice(&bind.CallOpts{Context: ctx}) Require(t, err) @@ -458,17 +460,17 @@ func waitForL1DelayBlocks(t *testing.T, ctx context.Context, l1client *ethclient func TestDepositETH(t *testing.T) { t.Parallel() - testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + _, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - faucetAddr := testNode.L1Info.GetAddress("Faucet") + faucetAddr := l1info.GetAddress("Faucet") - oldBalance, err := testNode.L2Client.BalanceAt(ctx, faucetAddr, nil) + oldBalance, err := l2client.BalanceAt(ctx, faucetAddr, nil) if err != nil { t.Fatalf("BalanceAt(%v) unexpected error: %v", faucetAddr, err) } - txOpts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := l1info.GetDefaultTransactOpts("Faucet", ctx) txOpts.Value = big.NewInt(13) l1tx, err := delayedInbox.DepositEth0(&txOpts) @@ -476,20 +478,20 @@ func TestDepositETH(t *testing.T) { t.Fatalf("DepositEth0() unexected error: %v", err) } - l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) if err != nil { t.Fatalf("EnsureTxSucceeded() unexpected error: %v", err) } if l1Receipt.Status != types.ReceiptStatusSuccessful { t.Errorf("Got transaction status: %v, want: %v", l1Receipt.Status, types.ReceiptStatusSuccessful) } - waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) + waitForL1DelayBlocks(t, ctx, l1client, l1info) - l2Receipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(l1Receipt)) + l2Receipt, err := EnsureTxSucceeded(ctx, l2client, lookupL2Tx(l1Receipt)) if err != nil { t.Fatalf("EnsureTxSucceeded unexpected error: %v", err) } - newBalance, err := testNode.L2Client.BalanceAt(ctx, faucetAddr, l2Receipt.BlockNumber) + newBalance, err := l2client.BalanceAt(ctx, faucetAddr, l2Receipt.BlockNumber) if err != nil { t.Fatalf("BalanceAt(%v) unexpected error: %v", faucetAddr, err) } @@ -499,13 +501,13 @@ func TestDepositETH(t *testing.T) { } func TestArbitrumContractTx(t *testing.T) { - testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + l2Info, l1Info, l2Client, l1Client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - faucetL2Addr := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) - testNode.TransferBalanceToViaL2(t, "Faucet", faucetL2Addr, big.NewInt(1e18)) + faucetL2Addr := util.RemapL1Address(l1Info.GetAddress("Faucet")) + TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), l2Info, l2Client, ctx) - l2TxOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) - l2ContractAddr, _ := testNode.DeploySimple(t, l2TxOpts) + l2TxOpts := l2Info.GetDefaultTransactOpts("Faucet", ctx) + l2ContractAddr, _ := deploySimple(t, ctx, l2TxOpts, l2Client) l2ContractABI, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) if err != nil { t.Fatalf("Error parsing contract ABI: %v", err) @@ -515,15 +517,15 @@ func TestArbitrumContractTx(t *testing.T) { t.Fatalf("Error packing method's call data: %v", err) } unsignedTx := types.NewTx(&types.ArbitrumContractTx{ - ChainId: testNode.L2Info.Signer.ChainID(), + ChainId: l2Info.Signer.ChainID(), From: faucetL2Addr, - GasFeeCap: testNode.L2Info.GasPrice.Mul(testNode.L2Info.GasPrice, big.NewInt(2)), + GasFeeCap: l2Info.GasPrice.Mul(l2Info.GasPrice, big.NewInt(2)), Gas: 1e6, To: &l2ContractAddr, Value: common.Big0, Data: data, }) - txOpts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := l1Info.GetDefaultTransactOpts("Faucet", ctx) l1tx, err := delayedInbox.SendContractTransaction( &txOpts, arbmath.UintToBig(unsignedTx.Gas()), @@ -535,15 +537,15 @@ func TestArbitrumContractTx(t *testing.T) { if err != nil { t.Fatalf("Error sending unsigned transaction: %v", err) } - receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) + receipt, err := EnsureTxSucceeded(ctx, l1Client, l1tx) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", l1tx.Hash(), err) } if receipt.Status != types.ReceiptStatusSuccessful { t.Errorf("L1 transaction: %v has failed", l1tx.Hash()) } - waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) - receipt, err = EnsureTxSucceeded(ctx, testNode.L2Client, lookupL2Tx(receipt)) + waitForL1DelayBlocks(t, ctx, l1Client, l1Info) + receipt, err = EnsureTxSucceeded(ctx, l2Client, lookupL2Tx(receipt)) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", unsignedTx.Hash(), err) } @@ -552,17 +554,17 @@ func TestArbitrumContractTx(t *testing.T) { func TestL1FundedUnsignedTransaction(t *testing.T) { t.Parallel() ctx := context.Background() - testNode := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2Info, node, l2Client, l1Info, _, l1Client, l1Stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1Stack) + defer node.StopAndWait() - faucetL2Addr := util.RemapL1Address(testNode.L1Info.GetAddress("Faucet")) + faucetL2Addr := util.RemapL1Address(l1Info.GetAddress("Faucet")) // Transfer balance to Faucet's corresponding L2 address, so that there is // enough balance on its' account for executing L2 transaction. - testNode.TransferBalanceToViaL2(t, "Faucet", faucetL2Addr, big.NewInt(1e18)) + TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), l2Info, l2Client, ctx) - l2TxOpts := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) - contractAddr, _ := testNode.DeploySimple(t, l2TxOpts) + l2TxOpts := l2Info.GetDefaultTransactOpts("Faucet", ctx) + contractAddr, _ := deploySimple(t, ctx, l2TxOpts, l2Client) contractABI, err := abi.JSON(strings.NewReader(mocksgen.SimpleABI)) if err != nil { t.Fatalf("Error parsing contract ABI: %v", err) @@ -571,27 +573,27 @@ func TestL1FundedUnsignedTransaction(t *testing.T) { if err != nil { t.Fatalf("Error packing method's call data: %v", err) } - nonce, err := testNode.L2Client.NonceAt(ctx, faucetL2Addr, nil) + nonce, err := l2Client.NonceAt(ctx, faucetL2Addr, nil) if err != nil { t.Fatalf("Error getting nonce at address: %v, error: %v", faucetL2Addr, err) } unsignedTx := types.NewTx(&types.ArbitrumUnsignedTx{ - ChainId: testNode.L2Info.Signer.ChainID(), + ChainId: l2Info.Signer.ChainID(), From: faucetL2Addr, Nonce: nonce, - GasFeeCap: testNode.L2Info.GasPrice, + GasFeeCap: l2Info.GasPrice, Gas: 1e6, To: &contractAddr, Value: common.Big0, Data: data, }) - delayedInbox, err := bridgegen.NewInbox(testNode.L1Info.GetAddress("Inbox"), testNode.L1Client) + delayedInbox, err := bridgegen.NewInbox(l1Info.GetAddress("Inbox"), l1Client) if err != nil { t.Fatalf("Error getting Go binding of L1 Inbox contract: %v", err) } - txOpts := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) + txOpts := l1Info.GetDefaultTransactOpts("Faucet", ctx) l1tx, err := delayedInbox.SendUnsignedTransaction( &txOpts, arbmath.UintToBig(unsignedTx.Gas()), @@ -604,15 +606,15 @@ func TestL1FundedUnsignedTransaction(t *testing.T) { if err != nil { t.Fatalf("Error sending unsigned transaction: %v", err) } - receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) + receipt, err := EnsureTxSucceeded(ctx, l1Client, l1tx) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", l1tx.Hash(), err) } if receipt.Status != types.ReceiptStatusSuccessful { t.Errorf("L1 transaction: %v has failed", l1tx.Hash()) } - waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) - receipt, err = EnsureTxSucceeded(ctx, testNode.L2Client, unsignedTx) + waitForL1DelayBlocks(t, ctx, l1Client, l1Info) + receipt, err = EnsureTxSucceeded(ctx, l2Client, unsignedTx) if err != nil { t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", unsignedTx.Hash(), err) } @@ -622,28 +624,28 @@ func TestL1FundedUnsignedTransaction(t *testing.T) { } func TestRetryableSubmissionAndRedeemFees(t *testing.T) { - testNode, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + l2info, l1info, l2client, l1client, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() - infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, testNode.L2Client, testNode.L2Info) + infraFeeAddr, networkFeeAddr := setupFeeAddresses(t, ctx, l2client, l2info) - ownerTxOpts := testNode.L2Info.GetDefaultTransactOpts("Owner", ctx) - simpleAddr, simple := testNode.DeploySimple(t, ownerTxOpts) + ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) + simpleAddr, simple := deploySimple(t, ctx, ownerTxOpts, l2client) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) - elevateL2Basefee(t, ctx, testNode) + elevateL2Basefee(t, ctx, l2client, l2info) - infraBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceBefore, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceBefore, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceBefore, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - beneficiaryAddress := testNode.L2Info.GetAddress("Beneficiary") + beneficiaryAddress := l2info.GetAddress("Beneficiary") deposit := arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) callValue := common.Big0 - usertxoptsL1 := testNode.L1Info.GetDefaultTransactOpts("Faucet", ctx) + usertxoptsL1 := l1info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL1.Value = deposit - baseFee := testNode.GetBaseFeeAtViaL2(t, nil) + baseFee := GetBaseFee(t, l2client, ctx) l1tx, err := delayedInbox.CreateRetryableTicket( &usertxoptsL1, simpleAddr, @@ -657,16 +659,16 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { simpleABI.Methods["incrementRedeem"].ID, ) Require(t, err) - l1Receipt, err := EnsureTxSucceeded(ctx, testNode.L1Client, l1tx) + l1Receipt, err := EnsureTxSucceeded(ctx, l1client, l1tx) Require(t, err) if l1Receipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "l1Receipt indicated failure") } - waitForL1DelayBlocks(t, ctx, testNode.L1Client, testNode.L1Info) + waitForL1DelayBlocks(t, ctx, l1client, l1info) submissionTxOuter := lookupL2Tx(l1Receipt) - submissionReceipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, submissionTxOuter) + submissionReceipt, err := EnsureTxSucceeded(ctx, l2client, submissionTxOuter) Require(t, err) if len(submissionReceipt.Logs) != 2 { Fatal(t, len(submissionReceipt.Logs)) @@ -674,36 +676,36 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { ticketId := submissionReceipt.Logs[0].Topics[1] firstRetryTxId := submissionReceipt.Logs[1].Topics[2] // get receipt for the auto redeem, make sure it failed - autoRedeemReceipt, err := WaitForTx(ctx, testNode.L2Client, firstRetryTxId, time.Second*5) + autoRedeemReceipt, err := WaitForTx(ctx, l2client, firstRetryTxId, time.Second*5) Require(t, err) if autoRedeemReceipt.Status != types.ReceiptStatusFailed { Fatal(t, "first retry tx shouldn't have succeeded") } - infraBalanceAfterSubmission, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceAfterSubmission, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceAfterSubmission, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceAfterSubmission, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) - usertxoptsL2 := testNode.L2Info.GetDefaultTransactOpts("Faucet", ctx) - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), testNode.L2Client) + usertxoptsL2 := l2info.GetDefaultTransactOpts("Faucet", ctx) + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), l2client) Require(t, err) tx, err := arbRetryableTx.Redeem(&usertxoptsL2, ticketId) Require(t, err) - redeemReceipt, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + redeemReceipt, err := EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) retryTxId := redeemReceipt.Logs[0].Topics[2] // check the receipt for the retry - retryReceipt, err := WaitForTx(ctx, testNode.L2Client, retryTxId, time.Second*1) + retryReceipt, err := WaitForTx(ctx, l2client, retryTxId, time.Second*1) Require(t, err) if retryReceipt.Status != types.ReceiptStatusSuccessful { Fatal(t, "retry failed") } - infraBalanceAfterRedeem, err := testNode.L2Client.BalanceAt(ctx, infraFeeAddr, nil) + infraBalanceAfterRedeem, err := l2client.BalanceAt(ctx, infraFeeAddr, nil) Require(t, err) - networkBalanceAfterRedeem, err := testNode.L2Client.BalanceAt(ctx, networkFeeAddr, nil) + networkBalanceAfterRedeem, err := l2client.BalanceAt(ctx, networkFeeAddr, nil) Require(t, err) // verify that the increment happened, so we know the retry succeeded @@ -732,11 +734,11 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { infraRedeemFee := arbmath.BigSub(infraBalanceAfterRedeem, infraBalanceAfterSubmission) networkRedeemFee := arbmath.BigSub(networkBalanceAfterRedeem, networkBalanceAfterSubmission) - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), testNode.L2Client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), l2client) Require(t, err) minimumBaseFee, err := arbGasInfo.GetMinimumGasPrice(&bind.CallOpts{Context: ctx}) Require(t, err) - submissionBaseFee := testNode.GetBaseFeeAtViaL2(t, submissionReceipt.BlockNumber) + submissionBaseFee := GetBaseFeeAt(t, l2client, ctx, submissionReceipt.BlockNumber) submissionTx, ok := submissionTxOuter.GetInner().(*types.ArbitrumSubmitRetryableTx) if !ok { Fatal(t, "inner tx isn't ArbitrumSubmitRetryableTx") @@ -750,13 +752,13 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { retryableSubmissionFee, ) - retryTxOuter, _, err := testNode.L2Client.TransactionByHash(ctx, retryTxId) + retryTxOuter, _, err := l2client.TransactionByHash(ctx, retryTxId) Require(t, err) retryTx, ok := retryTxOuter.GetInner().(*types.ArbitrumRetryTx) if !ok { Fatal(t, "inner tx isn't ArbitrumRetryTx") } - redeemBaseFee := testNode.GetBaseFeeAtViaL2(t, redeemReceipt.BlockNumber) + redeemBaseFee := GetBaseFeeAt(t, l2client, ctx, redeemReceipt.BlockNumber) t.Log("redeem base fee:", redeemBaseFee) // redeem & retry expected fees @@ -792,29 +794,29 @@ func TestRetryableSubmissionAndRedeemFees(t *testing.T) { } // elevateL2Basefee by burning gas exceeding speed limit -func elevateL2Basefee(t *testing.T, ctx context.Context, testNode *NodeBuilder) { - baseFeeBefore := testNode.GetBaseFeeAtViaL2(t, nil) +func elevateL2Basefee(t *testing.T, ctx context.Context, l2client *ethclient.Client, l2info *BlockchainTestInfo) { + baseFeeBefore := GetBaseFee(t, l2client, ctx) colors.PrintBlue("Elevating base fee...") arbostestabi, err := precompilesgen.ArbosTestMetaData.GetAbi() Require(t, err) - _, err = precompilesgen.NewArbosTest(common.HexToAddress("0x69"), testNode.L2Client) + _, err = precompilesgen.NewArbosTest(common.HexToAddress("0x69"), l2client) Require(t, err, "failed to deploy ArbosTest") burnAmount := arbnode.ConfigDefaultL1Test().RPC.RPCGasCap burnTarget := uint64(5 * l2pricing.InitialSpeedLimitPerSecondV6 * l2pricing.InitialBacklogTolerance) for i := uint64(0); i < (burnTarget+burnAmount)/burnAmount; i++ { burnArbGas := arbostestabi.Methods["burnArbGas"] - data, err := burnArbGas.Inputs.Pack(arbmath.UintToBig(burnAmount - testNode.L2Info.TransferGas)) + data, err := burnArbGas.Inputs.Pack(arbmath.UintToBig(burnAmount - l2info.TransferGas)) Require(t, err) input := append([]byte{}, burnArbGas.ID...) input = append(input, data...) to := common.HexToAddress("0x69") - tx := testNode.L2Info.PrepareTxTo("Faucet", &to, burnAmount, big.NewInt(0), input) - Require(t, testNode.L2Client.SendTransaction(ctx, tx)) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + tx := l2info.PrepareTxTo("Faucet", &to, burnAmount, big.NewInt(0), input) + Require(t, l2client.SendTransaction(ctx, tx)) + _, err = EnsureTxSucceeded(ctx, l2client, tx) Require(t, err) } - baseFee := testNode.GetBaseFeeAtViaL2(t, nil) + baseFee := GetBaseFee(t, l2client, ctx) colors.PrintBlue("New base fee: ", baseFee, " diff:", baseFee.Uint64()-baseFeeBefore.Uint64()) } diff --git a/system_tests/seq_coordinator_test.go b/system_tests/seq_coordinator_test.go index 1e55e1c886..b1f50c9436 100644 --- a/system_tests/seq_coordinator_test.go +++ b/system_tests/seq_coordinator_test.go @@ -62,8 +62,8 @@ func TestRedisSeqCoordinatorPriorities(t *testing.T) { createStartNode := func(nodeNum int) { nodeConfig.SeqCoordinator.MyUrl = nodeNames[nodeNum] - testNode := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetL2Info(l2Info).CreateTestNodeOnL2Only(t, false) - nodes[nodeNum] = testNode.L2Node + _, node, _ := CreateTestL2WithConfig(t, ctx, l2Info, nodeConfig, false) + nodes[nodeNum] = node } trySequencing := func(nodeNum int) bool { @@ -278,9 +278,9 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { initRedisForTest(t, ctx, nodeConfig.SeqCoordinator.RedisUrl, nodeNames) nodeConfig.SeqCoordinator.MyUrl = nodeNames[0] - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(nodeConfig).SetChainConfig(params.ArbitrumDevTestChainConfig()).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + l2Info, nodeA, clientA, l1info, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, params.ArbitrumDevTestChainConfig(), nil) + defer requireClose(t, l1stack) + defer nodeA.StopAndWait() redisClient, err := redisutil.RedisClientFromURL(nodeConfig.SeqCoordinator.RedisUrl) Require(t, err) @@ -297,7 +297,7 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { break } - testNodeA.L2Info.GenerateAccount("User2") + l2Info.GenerateAccount("User2") nodeConfigDup := *nodeConfig nodeConfig = &nodeConfigDup @@ -305,23 +305,23 @@ func testCoordinatorMessageSync(t *testing.T, successCase bool) { nodeConfig.SeqCoordinator.MyUrl = nodeNames[1] if !successCase { nodeConfig.SeqCoordinator.Signer.ECDSA.AcceptSequencer = false - nodeConfig.SeqCoordinator.Signer.ECDSA.AllowedAddresses = []string{testNodeA.L2Info.GetAddress("User2").Hex()} + nodeConfig.SeqCoordinator.Signer.ECDSA.AllowedAddresses = []string{l2Info.GetAddress("User2").Hex()} } - clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfig, nil) + clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2Info.ArbInitData, nodeConfig, nil) defer nodeB.StopAndWait() - tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) + tx := l2Info.PrepareTx("Owner", "User2", l2Info.TransferGas, big.NewInt(1e12), nil) - err = testNodeA.L2Client.SendTransaction(ctx, tx) + err = clientA.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, clientA, tx) Require(t, err) if successCase { _, err = WaitForTx(ctx, clientB, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) + l2balance, err := clientB.BalanceAt(ctx, l2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { t.Fatal("Unexpected balance:", l2balance) diff --git a/system_tests/seq_nonce_test.go b/system_tests/seq_nonce_test.go index 18363b9984..968f141364 100644 --- a/system_tests/seq_nonce_test.go +++ b/system_tests/seq_nonce_test.go @@ -26,10 +26,10 @@ func TestSequencerParallelNonces(t *testing.T) { config := arbnode.ConfigDefaultL2Test() config.Sequencer.NonceFailureCacheExpiry = time.Minute - testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, false) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) + defer node.StopAndWait() - testNode.L2Info.GenerateAccount("Destination") + l2info.GenerateAccount("Destination") wg := sync.WaitGroup{} for thread := 0; thread < 10; thread++ { @@ -37,11 +37,11 @@ func TestSequencerParallelNonces(t *testing.T) { go func() { defer wg.Done() for i := 0; i < 10; i++ { - tx := testNode.L2Info.PrepareTx("Owner", "Destination", testNode.L2Info.TransferGas, common.Big1, nil) + tx := l2info.PrepareTx("Owner", "Destination", l2info.TransferGas, common.Big1, nil) // Sleep a random amount of time up to 20 milliseconds time.Sleep(time.Millisecond * time.Duration(rand.Intn(20))) t.Log("Submitting transaction with nonce", tx.Nonce()) - err := testNode.L2Client.SendTransaction(ctx, tx) + err := client.SendTransaction(ctx, tx) Require(t, err) t.Log("Got response for transaction with nonce", tx.Nonce()) } @@ -49,8 +49,8 @@ func TestSequencerParallelNonces(t *testing.T) { } wg.Wait() - addr := testNode.L2Info.GetAddress("Destination") - balance, err := testNode.L2Client.BalanceAt(ctx, addr, nil) + addr := l2info.GetAddress("Destination") + balance, err := client.BalanceAt(ctx, addr, nil) Require(t, err) if !arbmath.BigEquals(balance, big.NewInt(100)) { Fatal(t, "Unexpected user balance", balance) @@ -63,14 +63,14 @@ func TestSequencerNonceTooHigh(t *testing.T) { defer cancel() config := arbnode.ConfigDefaultL2Test() - testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, false) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) + defer node.StopAndWait() - testNode.L2Info.GetInfoWithPrivKey("Owner").Nonce++ + l2info.GetInfoWithPrivKey("Owner").Nonce++ before := time.Now() - tx := testNode.L2Info.PrepareTx("Owner", "Owner", testNode.L2Info.TransferGas, common.Big0, nil) - err := testNode.L2Client.SendTransaction(ctx, tx) + tx := l2info.PrepareTx("Owner", "Owner", l2info.TransferGas, common.Big0, nil) + err := client.SendTransaction(ctx, tx) if err == nil { Fatal(t, "No error when nonce was too high") } @@ -91,16 +91,16 @@ func TestSequencerNonceTooHighQueueFull(t *testing.T) { config := arbnode.ConfigDefaultL2Test() config.Sequencer.NonceFailureCacheSize = 5 config.Sequencer.NonceFailureCacheExpiry = time.Minute - testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, false) - defer testNode.L2Node.StopAndWait() + l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, config, false) + defer node.StopAndWait() count := 15 var completed uint64 for i := 0; i < count; i++ { - testNode.L2Info.GetInfoWithPrivKey("Owner").Nonce++ - tx := testNode.L2Info.PrepareTx("Owner", "Owner", testNode.L2Info.TransferGas, common.Big0, nil) + l2info.GetInfoWithPrivKey("Owner").Nonce++ + tx := l2info.PrepareTx("Owner", "Owner", l2info.TransferGas, common.Big0, nil) go func() { - err := testNode.L2Client.SendTransaction(ctx, tx) + err := client.SendTransaction(ctx, tx) if err == nil { Fatal(t, "No error when nonce was too high") } diff --git a/system_tests/seq_pause_test.go b/system_tests/seq_pause_test.go index 8b919d73c6..fd057c0181 100644 --- a/system_tests/seq_pause_test.go +++ b/system_tests/seq_pause_test.go @@ -8,7 +8,6 @@ import ( "time" "github.com/ethereum/go-ethereum/core/types" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/arbnode/execution" ) @@ -17,12 +16,12 @@ func TestSequencerPause(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info1, nodeA, client := CreateTestL2(t, ctx) + defer nodeA.StopAndWait() const numUsers = 100 - prechecker, ok := testNode.L2Node.Execution.TxPublisher.(*execution.TxPreChecker) + prechecker, ok := nodeA.Execution.TxPublisher.(*execution.TxPreChecker) if !ok { t.Error("prechecker not found on node") } @@ -35,15 +34,15 @@ func TestSequencerPause(t *testing.T) { for num := 0; num < numUsers; num++ { userName := fmt.Sprintf("My_User_%d", num) - testNode.L2Info.GenerateAccount(userName) + l2info1.GenerateAccount(userName) users = append(users, userName) } for _, userName := range users { - tx := testNode.L2Info.PrepareTx("Owner", userName, testNode.L2Info.TransferGas, big.NewInt(1e16), nil) - err := testNode.L2Client.SendTransaction(ctx, tx) + tx := l2info1.PrepareTx("Owner", userName, l2info1.TransferGas, big.NewInt(1e16), nil) + err := client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) } @@ -52,7 +51,7 @@ func TestSequencerPause(t *testing.T) { var txs types.Transactions for _, userName := range users { - tx := testNode.L2Info.PrepareTx(userName, "Owner", testNode.L2Info.TransferGas, big.NewInt(2), nil) + tx := l2info1.PrepareTx(userName, "Owner", l2info1.TransferGas, big.NewInt(2), nil) txs = append(txs, tx) } @@ -63,7 +62,7 @@ func TestSequencerPause(t *testing.T) { }(tx) } - _, err := EnsureTxSucceededWithTimeout(ctx, testNode.L2Client, txs[0], time.Second) + _, err := EnsureTxSucceededWithTimeout(ctx, client, txs[0], time.Second) if err == nil { t.Error("tx passed while sequencer paused") } @@ -71,7 +70,7 @@ func TestSequencerPause(t *testing.T) { sequencer.Activate() for _, tx := range txs { - _, err := EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err := EnsureTxSucceeded(ctx, client, tx) Require(t, err) } } diff --git a/system_tests/seq_reject_test.go b/system_tests/seq_reject_test.go index 811f5669d1..19c06c4bc3 100644 --- a/system_tests/seq_reject_test.go +++ b/system_tests/seq_reject_test.go @@ -31,18 +31,18 @@ func TestSequencerRejection(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() feedErrChan := make(chan error, 10) - testNode1 := NewNodeBuilder(ctx).SetNodeConfig(seqNodeConfig).CreateTestNodeOnL2Only(t, true) - defer testNode1.L2Node.StopAndWait() + l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) + defer nodeA.StopAndWait() clientNodeConfig := arbnode.ConfigDefaultL2Test() - port := testNode1.L2Node.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port + port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - testNode2 := NewNodeBuilder(ctx).SetNodeConfig(clientNodeConfig).CreateTestNodeOnL2Only(t, false) - defer testNode2.L2Node.StopAndWait() + _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) + defer nodeB.StopAndWait() - auth := testNode1.L2Info.GetDefaultTransactOpts("Owner", ctx) - simpleAddr, _ := testNode1.DeploySimple(t, auth) + auth := l2info1.GetDefaultTransactOpts("Owner", ctx) + simpleAddr, _ := deploySimple(t, ctx, auth, client1) simpleAbi, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) noopId := simpleAbi.Methods["noop"].ID @@ -51,7 +51,7 @@ func TestSequencerRejection(t *testing.T) { // Generate the accounts before hand to avoid races for user := 0; user < 9; user++ { name := fmt.Sprintf("User%v", user) - testNode1.L2Info.GenerateAccount(name) + l2info1.GenerateAccount(name) } wg := sync.WaitGroup{} @@ -59,24 +59,24 @@ func TestSequencerRejection(t *testing.T) { for user := 0; user < 9; user++ { user := user name := fmt.Sprintf("User%v", user) - tx := testNode1.L2Info.PrepareTx("Owner", name, testNode1.L2Info.TransferGas, big.NewInt(params.Ether), nil) + tx := l2info1.PrepareTx("Owner", name, l2info1.TransferGas, big.NewInt(params.Ether), nil) - err := testNode1.L2Client.SendTransaction(ctx, tx) + err := client1.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode1.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client1, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode2.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client2, tx) Require(t, err) wg.Add(1) go func() { defer wg.Done() - info := testNode1.L2Info.GetInfoWithPrivKey(name) + info := l2info1.GetInfoWithPrivKey(name) txData := &types.DynamicFeeTx{ To: &simpleAddr, - Gas: testNode1.L2Info.TransferGas + 10000, - GasFeeCap: arbmath.BigMulByUint(testNode1.L2Info.GasPrice, 100), + Gas: l2info1.TransferGas + 10000, + GasFeeCap: arbmath.BigMulByUint(l2info1.GasPrice, 100), Value: common.Big0, } for atomic.LoadInt32(&stopBackground) == 0 { @@ -92,8 +92,8 @@ func TestSequencerRejection(t *testing.T) { txData.Nonce = 1 << 32 expectedErr = "nonce too high" } - tx = testNode1.L2Info.SignTxAs(name, txData) - err = testNode1.L2Client.SendTransaction(ctx, tx) + tx = l2info1.SignTxAs(name, txData) + err = client1.SendTransaction(ctx, tx) if err != nil && (expectedErr == "" || !strings.Contains(err.Error(), expectedErr)) { Require(t, err, "failed to send tx for user", user) } @@ -102,7 +102,7 @@ func TestSequencerRejection(t *testing.T) { } for i := 100; i >= 0; i-- { - block, err := testNode1.L2Client.BlockNumber(ctx) + block, err := client1.BlockNumber(ctx) Require(t, err) if block >= 200 { break @@ -120,11 +120,11 @@ func TestSequencerRejection(t *testing.T) { atomic.StoreInt32(&stopBackground, 1) wg.Wait() - header1, err := testNode1.L2Client.HeaderByNumber(ctx, nil) + header1, err := client1.HeaderByNumber(ctx, nil) Require(t, err) for i := 100; i >= 0; i-- { - header2, err := testNode2.L2Client.HeaderByNumber(ctx, header1.Number) + header2, err := client2.HeaderByNumber(ctx, header1.Number) if err != nil { select { case err := <-feedErrChan: @@ -132,8 +132,8 @@ func TestSequencerRejection(t *testing.T) { case <-time.After(time.Millisecond * 100): } if i == 0 { - client2Block, _ := testNode2.L2Client.BlockNumber(ctx) - Fatal(t, "Client2 failed to reach client1 block ", header1.Number, ", only reached block", client2Block) + client2Block, _ := client2.BlockNumber(ctx) + Fatal(t, "client2 failed to reach client1 block ", header1.Number, ", only reached block", client2Block) } continue } diff --git a/system_tests/seq_whitelist_test.go b/system_tests/seq_whitelist_test.go index 5275bf9ac6..2d671dcdd6 100644 --- a/system_tests/seq_whitelist_test.go +++ b/system_tests/seq_whitelist_test.go @@ -18,22 +18,22 @@ func TestSequencerWhitelist(t *testing.T) { config := arbnode.ConfigDefaultL2Test() config.Sequencer.SenderWhitelist = GetTestAddressForAccountName(t, "Owner").String() + "," + GetTestAddressForAccountName(t, "User").String() - testNode := NewNodeBuilder(ctx).SetNodeConfig(config).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, l2node, client := CreateTestL2WithConfig(t, ctx, nil, config, true) + defer l2node.StopAndWait() - testNode.L2Info.GenerateAccount("User") - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User") + l2info.GenerateAccount("User2") // Owner is on the whitelist - testNode.TransferBalanceViaL2(t, "Owner", "User", big.NewInt(params.Ether)) - testNode.TransferBalanceViaL2(t, "Owner", "User2", big.NewInt(params.Ether)) + TransferBalance(t, "Owner", "User", big.NewInt(params.Ether), l2info, client, ctx) + TransferBalance(t, "Owner", "User2", big.NewInt(params.Ether), l2info, client, ctx) // User is on the whitelist - testNode.TransferBalanceViaL2(t, "User", "User2", big.NewInt(params.Ether/10)) + TransferBalance(t, "User", "User2", big.NewInt(params.Ether/10), l2info, client, ctx) // User2 is *not* on the whitelist, therefore this should fail - tx := testNode.L2Info.PrepareTx("User2", "User", testNode.L2Info.TransferGas, big.NewInt(params.Ether/10), nil) - err := testNode.L2Client.SendTransaction(ctx, tx) + tx := l2info.PrepareTx("User2", "User", l2info.TransferGas, big.NewInt(params.Ether/10), nil) + err := client.SendTransaction(ctx, tx) if err == nil { Fatal(t, "transaction from user not on whitelist accepted") } diff --git a/system_tests/seqcompensation_test.go b/system_tests/seqcompensation_test.go index 39cf0771a4..362acf6a30 100644 --- a/system_tests/seqcompensation_test.go +++ b/system_tests/seqcompensation_test.go @@ -18,19 +18,19 @@ func TestSequencerCompensation(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNodeA := NewNodeBuilder(ctx).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1(t, ctx, true) + defer requireClose(t, l1stack) + defer nodeA.StopAndWait() - l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nil) + l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, nil) defer nodeB.StopAndWait() - testNodeA.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) - err := testNodeA.L2Client.SendTransaction(ctx, tx) + tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) + err := l2clientA.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2clientA, tx) Require(t, err) // give the inbox reader a bit of time to pick up the delayed message @@ -38,8 +38,8 @@ func TestSequencerCompensation(t *testing.T) { // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 30; i++ { - SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ - testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } @@ -47,7 +47,7 @@ func TestSequencerCompensation(t *testing.T) { Require(t, err) // clientB sees balance means sequencer message was sent - l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { Fatal(t, "Unexpected balance:", l2balance) diff --git a/system_tests/seqfeed_test.go b/system_tests/seqfeed_test.go index e89b8a58b8..23c0e44c02 100644 --- a/system_tests/seqfeed_test.go +++ b/system_tests/seqfeed_test.go @@ -44,28 +44,28 @@ func TestSequencerFeed(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() - testNode1 := NewNodeBuilder(ctx).SetNodeConfig(seqNodeConfig).CreateTestNodeOnL2Only(t, true) - defer testNode1.L2Node.StopAndWait() + l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) + defer nodeA.StopAndWait() clientNodeConfig := arbnode.ConfigDefaultL2Test() - port := testNode1.L2Node.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port + port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - testNode2 := NewNodeBuilder(ctx).SetNodeConfig(clientNodeConfig).CreateTestNodeOnL2Only(t, false) - defer testNode2.L2Node.StopAndWait() + _, nodeB, client2 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) + defer nodeB.StopAndWait() - testNode1.L2Info.GenerateAccount("User2") + l2info1.GenerateAccount("User2") - tx := testNode1.L2Info.PrepareTx("Owner", "User2", testNode1.L2Info.TransferGas, big.NewInt(1e12), nil) + tx := l2info1.PrepareTx("Owner", "User2", l2info1.TransferGas, big.NewInt(1e12), nil) - err := testNode1.L2Client.SendTransaction(ctx, tx) + err := client1.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode1.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client1, tx) Require(t, err) - _, err = WaitForTx(ctx, testNode2.L2Client, tx.Hash(), time.Second*5) + _, err = WaitForTx(ctx, client2, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := testNode2.L2Client.BalanceAt(ctx, testNode1.L2Info.GetAddress("User2"), nil) + l2balance, err := client2.BalanceAt(ctx, l2info1.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { t.Fatal("Unexpected balance:", l2balance) @@ -79,14 +79,14 @@ func TestRelayedSequencerFeed(t *testing.T) { seqNodeConfig := arbnode.ConfigDefaultL2Test() seqNodeConfig.Feed.Output = *newBroadcasterConfigTest() - testNode1 := NewNodeBuilder(ctx).SetNodeConfig(seqNodeConfig).CreateTestNodeOnL2Only(t, true) - defer testNode1.L2Node.StopAndWait() + l2info1, nodeA, client1 := CreateTestL2WithConfig(t, ctx, nil, seqNodeConfig, true) + defer nodeA.StopAndWait() - bigChainId, err := testNode1.L2Client.ChainID(ctx) + bigChainId, err := client1.ChainID(ctx) Require(t, err) config := relay.ConfigDefault - port := testNode1.L2Node.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port + port := nodeA.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port config.Node.Feed.Input = *newBroadcastClientConfigTest(port) config.Node.Feed.Output = *newBroadcasterConfigTest() config.Chain.ID = bigChainId.Uint64() @@ -101,23 +101,23 @@ func TestRelayedSequencerFeed(t *testing.T) { clientNodeConfig := arbnode.ConfigDefaultL2Test() port = currentRelay.GetListenerAddr().(*net.TCPAddr).Port clientNodeConfig.Feed.Input = *newBroadcastClientConfigTest(port) - testNode3 := NewNodeBuilder(ctx).SetNodeConfig(clientNodeConfig).CreateTestNodeOnL2Only(t, false) - defer testNode3.L2Node.StopAndWait() - StartWatchChanErr(t, ctx, feedErrChan, testNode3.L2Node) + _, nodeC, client3 := CreateTestL2WithConfig(t, ctx, nil, clientNodeConfig, false) + defer nodeC.StopAndWait() + StartWatchChanErr(t, ctx, feedErrChan, nodeC) - testNode1.L2Info.GenerateAccount("User2") + l2info1.GenerateAccount("User2") - tx := testNode1.L2Info.PrepareTx("Owner", "User2", testNode1.L2Info.TransferGas, big.NewInt(1e12), nil) + tx := l2info1.PrepareTx("Owner", "User2", l2info1.TransferGas, big.NewInt(1e12), nil) - err = testNode1.L2Client.SendTransaction(ctx, tx) + err = client1.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode1.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client1, tx) Require(t, err) - _, err = WaitForTx(ctx, testNode3.L2Client, tx.Hash(), time.Second*5) + _, err = WaitForTx(ctx, client3, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := testNode3.L2Client.BalanceAt(ctx, testNode1.L2Info.GetAddress("User2"), nil) + l2balance, err := client3.BalanceAt(ctx, l2info1.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { t.Fatal("Unexpected balance:", l2balance) @@ -135,11 +135,11 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigA.BatchPoster.Enable = true nodeConfigA.Feed.Output.Enable = false - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(nodeConfigA).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack, "unable to close l1Stack") - defer testNodeA.L2Node.StopAndWait() + l2infoA, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfigA, chainConfig, nil) + defer requireClose(t, l1stack, "unable to close l1stack") + defer nodeA.StopAndWait() - authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) + authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) // The lying sequencer nodeConfigC := arbnode.ConfigDefaultL1Test() @@ -147,7 +147,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigC.DataAvailability = nodeConfigA.DataAvailability nodeConfigC.DataAvailability.RPCAggregator.Enable = false nodeConfigC.Feed.Output = *newBroadcasterConfigTest() - l2clientC, nodeC := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfigC, nil) + l2clientC, nodeC := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigC, nil) defer nodeC.StopAndWait() port := nodeC.BroadcastServer.ListenerAddr().(*net.TCPAddr).Port @@ -158,15 +158,15 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { nodeConfigB.Feed.Input = *newBroadcastClientConfigTest(port) nodeConfigB.DataAvailability = nodeConfigA.DataAvailability nodeConfigB.DataAvailability.RPCAggregator.Enable = false - l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, nodeConfigB, nil) + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2infoA.ArbInitData, nodeConfigB, nil) defer nodeB.StopAndWait() - testNodeA.L2Info.GenerateAccount("FraudUser") - testNodeA.L2Info.GenerateAccount("RealUser") + l2infoA.GenerateAccount("FraudUser") + l2infoA.GenerateAccount("RealUser") - fraudTx := testNodeA.L2Info.PrepareTx("Owner", "FraudUser", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) - testNodeA.L2Info.GetInfoWithPrivKey("Owner").Nonce -= 1 // Use same l2info object for different l2s - realTx := testNodeA.L2Info.PrepareTx("Owner", "RealUser", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) + fraudTx := l2infoA.PrepareTx("Owner", "FraudUser", l2infoA.TransferGas, big.NewInt(1e12), nil) + l2infoA.GetInfoWithPrivKey("Owner").Nonce -= 1 // Use same l2info object for different l2s + realTx := l2infoA.PrepareTx("Owner", "RealUser", l2infoA.TransferGas, big.NewInt(1e12), nil) err := l2clientC.SendTransaction(ctx, fraudTx) if err != nil { @@ -183,7 +183,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { if err != nil { t.Fatal("error waiting for tx:", err) } - l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("FraudUser"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, l2infoA.GetAddress("FraudUser"), nil) if err != nil { t.Fatal("error getting balance:", err) } @@ -192,12 +192,12 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { } // Send the real transaction to client A - err = testNodeA.L2Client.SendTransaction(ctx, realTx) + err = l2clientA.SendTransaction(ctx, realTx) if err != nil { t.Fatal("error sending real transaction:", err) } - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, realTx) + _, err = EnsureTxSucceeded(ctx, l2clientA, realTx) if err != nil { t.Fatal("error ensuring real transaction succeeded:", err) } @@ -207,7 +207,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { if err != nil { t.Fatal("error waiting for transaction to get to node b:", err) } - l2balanceFraudAcct, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("FraudUser"), nil) + l2balanceFraudAcct, err := l2clientB.BalanceAt(ctx, l2infoA.GetAddress("FraudUser"), nil) if err != nil { t.Fatal("error getting fraud balance:", err) } @@ -215,7 +215,7 @@ func testLyingSequencer(t *testing.T, dasModeStr string) { t.Fatal("Unexpected balance (fraud acct should be empty) was:", l2balanceFraudAcct) } - l2balanceRealAcct, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("RealUser"), nil) + l2balanceRealAcct, err := l2clientB.BalanceAt(ctx, l2infoA.GetAddress("RealUser"), nil) if err != nil { t.Fatal("error getting real balance:", err) } diff --git a/system_tests/seqinbox_test.go b/system_tests/seqinbox_test.go index c7583ff1ff..bf3e7c86c1 100644 --- a/system_tests/seqinbox_test.go +++ b/system_tests/seqinbox_test.go @@ -47,18 +47,18 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { if validator { conf.BlockValidator.Enable = true } - testNode := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(false).CreateTestNodeOnL1AndL2(t) - l2Backend := testNode.L2Node.Execution.Backend - defer requireClose(t, testNode.L1Stack) - defer testNode.L2Node.StopAndWait() + l2Info, arbNode, _, l1Info, l1backend, l1Client, l1stack := createTestNodeOnL1WithConfig(t, ctx, false, conf, nil, nil) + l2Backend := arbNode.Execution.Backend + defer requireClose(t, l1stack) + defer arbNode.StopAndWait() - l1BlockChain := testNode.L1Backend.BlockChain() + l1BlockChain := l1backend.BlockChain() - seqInbox, err := bridgegen.NewSequencerInbox(testNode.L1Info.GetAddress("SequencerInbox"), testNode.L1Client) + seqInbox, err := bridgegen.NewSequencerInbox(l1Info.GetAddress("SequencerInbox"), l1Client) Require(t, err) - seqOpts := testNode.L1Info.GetDefaultTransactOpts("Sequencer", ctx) + seqOpts := l1Info.GetDefaultTransactOpts("Sequencer", ctx) - ownerAddress := testNode.L2Info.GetAddress("Owner") + ownerAddress := l2Info.GetAddress("Owner") var startL2BlockNumber uint64 = 0 startState, _, err := l2Backend.APIBackend().StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber) @@ -91,10 +91,10 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { } var faucetTxs []*types.Transaction for _, acct := range accounts { - testNode.L1Info.GenerateAccount(acct) - faucetTxs = append(faucetTxs, testNode.L1Info.PrepareTx("Faucet", acct, 30000, big.NewInt(1e16), nil)) + l1Info.GenerateAccount(acct) + faucetTxs = append(faucetTxs, l1Info.PrepareTx("Faucet", acct, 30000, big.NewInt(1e16), nil)) } - SendWaitTestTransactions(t, ctx, testNode.L1Client, faucetTxs) + SendWaitTestTransactions(t, ctx, l1Client, faucetTxs) for i := 1; i < seqInboxTestIters; i++ { if i%10 == 0 { @@ -106,7 +106,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { // The miner usually collects transactions from deleted blocks and puts them in the mempool. // However, this code doesn't run on reorgs larger than 64 blocks for performance reasons. // Therefore, we make a bunch of small blocks to prevent the code from running. - padAddr := testNode.L1Info.GetAddress("ReorgPadding") + padAddr := l1Info.GetAddress("ReorgPadding") for j := uint64(0); j < 70; j++ { rawTx := &types.DynamicFeeTx{ To: &padAddr, @@ -115,12 +115,12 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { Value: new(big.Int), Nonce: j, } - tx := testNode.L1Info.SignTxAs("ReorgPadding", rawTx) - Require(t, testNode.L1Client.SendTransaction(ctx, tx)) - _, _ = EnsureTxSucceeded(ctx, testNode.L1Client, tx) + tx := l1Info.SignTxAs("ReorgPadding", rawTx) + Require(t, l1Client.SendTransaction(ctx, tx)) + _, _ = EnsureTxSucceeded(ctx, l1Client, tx) } reorgTargetNumber := blockStates[reorgTo].l1BlockNumber - currentHeader, err := testNode.L1Client.HeaderByNumber(ctx, nil) + currentHeader, err := l1Client.HeaderByNumber(ctx, nil) Require(t, err) if currentHeader.Number.Int64()-int64(reorgTargetNumber) < 65 { Fatal(t, "Less than 65 blocks of difference between current block", currentHeader.Number, "and target", reorgTargetNumber) @@ -135,10 +135,10 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { // Sometimes, this causes it to drop the next tx. // To work around this, we create a sacrificial tx, which may or may not succeed. // Whichever happens, by the end of this block, the miner will have processed the reorg. - tx := testNode.L1Info.PrepareTx(fmt.Sprintf("ReorgSacrifice%v", i/10), "Faucet", 30000, big.NewInt(0), nil) - err = testNode.L1Client.SendTransaction(ctx, tx) + tx := l1Info.PrepareTx(fmt.Sprintf("ReorgSacrifice%v", i/10), "Faucet", 30000, big.NewInt(0), nil) + err = l1Client.SendTransaction(ctx, tx) Require(t, err) - _, _ = WaitForTx(ctx, testNode.L1Client, tx.Hash(), time.Second) + _, _ = WaitForTx(ctx, l1Client, tx.Hash(), time.Second) } else { state := blockStates[len(blockStates)-1] newBalances := make(map[common.Address]*big.Int) @@ -166,10 +166,10 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { var dest common.Address if j == 0 && amount.Cmp(reserveAmount) >= 0 { name := accountName(len(state.accounts)) - if !testNode.L2Info.HasAccount(name) { - testNode.L2Info.GenerateAccount(name) + if !l2Info.HasAccount(name) { + l2Info.GenerateAccount(name) } - dest = testNode.L2Info.GetAddress(name) + dest = l2Info.GetAddress(name) state.accounts = append(state.accounts, dest) state.balances[dest] = big.NewInt(0) } else { @@ -184,7 +184,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { Nonce: state.nonces[source], } state.nonces[source]++ - tx := testNode.L2Info.SignTxAs(accountName(sourceNum), rawTx) + tx := l2Info.SignTxAs(accountName(sourceNum), rawTx) txData, err := tx.MarshalBinary() Require(t, err) var segment []byte @@ -204,7 +204,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { seqNonce := len(blockStates) - 1 for j := 0; ; j++ { - haveNonce, err := testNode.L1Client.PendingNonceAt(ctx, seqOpts.From) + haveNonce, err := l1Client.PendingNonceAt(ctx, seqOpts.From) Require(t, err) if haveNonce == uint64(seqNonce) { break @@ -222,15 +222,15 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { tx, err = seqInbox.AddSequencerL2BatchFromOrigin(&seqOpts, big.NewInt(int64(len(blockStates))), batchData, big.NewInt(1), common.Address{}) } Require(t, err) - txRes, err := EnsureTxSucceeded(ctx, testNode.L1Client, tx) + txRes, err := EnsureTxSucceeded(ctx, l1Client, tx) if err != nil { // Geth's clique miner is finicky. // Unfortunately this is so rare that I haven't had an opportunity to test this workaround. // Specifically, I suspect there's a race where it thinks there's no txs to put in the new block, // if a new tx arrives at the same time as it tries to create a block. // Resubmit the transaction in an attempt to get the miner going again. - _ = testNode.L1Client.SendTransaction(ctx, tx) - txRes, err = EnsureTxSucceeded(ctx, testNode.L1Client, tx) + _ = l1Client.SendTransaction(ctx, tx) + txRes, err = EnsureTxSucceeded(ctx, l1Client, tx) Require(t, err) } @@ -267,9 +267,9 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { if validator && i%15 == 0 { for i := 0; ; i++ { - expectedPos, err := testNode.L2Node.Execution.ExecEngine.BlockNumberToMessageIndex(expectedBlockNumber) + expectedPos, err := arbNode.Execution.ExecEngine.BlockNumberToMessageIndex(expectedBlockNumber) Require(t, err) - lastValidated := testNode.L2Node.BlockValidator.Validated(t) + lastValidated := arbNode.BlockValidator.Validated(t) if lastValidated == expectedPos+1 { break } else if i >= 1000 { diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index e03cd15b87..78fa7fa83b 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -65,9 +65,9 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) types.NewArbitrumSigner(types.NewLondonSigner(l2chainConfig.ChainID)), big.NewInt(l2pricing.InitialBaseFeeWei*2), transferGas, ) - testNodeA := NewNodeBuilder(ctx).SetIsSequencer(true).SetChainConfig(l2chainConfig).SetL2Info(l2info).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + _, l2nodeA, l2clientA, _, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfigImpl(t, ctx, true, nil, l2chainConfig, nil, l2info) + defer requireClose(t, l1stack) + defer l2nodeA.StopAndWait() if faultyStaker { l2info.GenerateGenesisAccount("FaultyAddr", common.Big1) @@ -76,10 +76,10 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) config.Sequencer.Enable = false config.DelayedSequencer.Enable = false config.BatchPoster.Enable = false - _, l2nodeB := Create2ndNodeWithConfig(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &l2info.ArbInitData, config, nil) + _, l2nodeB := Create2ndNodeWithConfig(t, ctx, l2nodeA, l1stack, l1info, &l2info.ArbInitData, config, nil) defer l2nodeB.StopAndWait() - nodeAGenesis := testNodeA.L2Node.Execution.Backend.APIBackend().CurrentHeader().Hash() + nodeAGenesis := l2nodeA.Execution.Backend.APIBackend().CurrentHeader().Hash() nodeBGenesis := l2nodeB.Execution.Backend.APIBackend().CurrentHeader().Hash() if faultyStaker { if nodeAGenesis == nodeBGenesis { @@ -91,51 +91,51 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) } } - testNodeA.BridgeBalance(t, "Faucet", big.NewInt(1).Mul(big.NewInt(params.Ether), big.NewInt(10000))) + BridgeBalance(t, "Faucet", big.NewInt(1).Mul(big.NewInt(params.Ether), big.NewInt(10000)), l1info, l2info, l1client, l2clientA, ctx) - deployAuth := testNodeA.L1Info.GetDefaultTransactOpts("RollupOwner", ctx) + deployAuth := l1info.GetDefaultTransactOpts("RollupOwner", ctx) balance := big.NewInt(params.Ether) balance.Mul(balance, big.NewInt(100)) - testNodeA.L1Info.GenerateAccount("ValidatorA") - testNodeA.TransferBalanceViaL1(t, "Faucet", "ValidatorA", balance) - l1authA := testNodeA.L1Info.GetDefaultTransactOpts("ValidatorA", ctx) + l1info.GenerateAccount("ValidatorA") + TransferBalance(t, "Faucet", "ValidatorA", balance, l1info, l1client, ctx) + l1authA := l1info.GetDefaultTransactOpts("ValidatorA", ctx) - testNodeA.L1Info.GenerateAccount("ValidatorB") - testNodeA.TransferBalanceViaL1(t, "Faucet", "ValidatorB", balance) - l1authB := testNodeA.L1Info.GetDefaultTransactOpts("ValidatorB", ctx) + l1info.GenerateAccount("ValidatorB") + TransferBalance(t, "Faucet", "ValidatorB", balance, l1info, l1client, ctx) + l1authB := l1info.GetDefaultTransactOpts("ValidatorB", ctx) - valWalletAddrAPtr, err := validatorwallet.GetValidatorWalletContract(ctx, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, 0, &l1authA, testNodeA.L2Node.L1Reader, true) + valWalletAddrAPtr, err := validatorwallet.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true) Require(t, err) valWalletAddrA := *valWalletAddrAPtr - valWalletAddrCheck, err := validatorwallet.GetValidatorWalletContract(ctx, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, 0, &l1authA, testNodeA.L2Node.L1Reader, true) + valWalletAddrCheck, err := validatorwallet.GetValidatorWalletContract(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader, true) Require(t, err) if valWalletAddrA == *valWalletAddrCheck { Require(t, err, "didn't cache validator wallet address", valWalletAddrA.String(), "vs", valWalletAddrCheck.String()) } - rollup, err := rollupgen.NewRollupAdminLogic(testNodeA.L2Node.DeployInfo.Rollup, testNodeA.L1Client) + rollup, err := rollupgen.NewRollupAdminLogic(l2nodeA.DeployInfo.Rollup, l1client) Require(t, err) tx, err := rollup.SetValidator(&deployAuth, []common.Address{valWalletAddrA, l1authB.From}, []bool{true, true}) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) + _, err = EnsureTxSucceeded(ctx, l1client, tx) Require(t, err) tx, err = rollup.SetMinimumAssertionPeriod(&deployAuth, big.NewInt(1)) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) + _, err = EnsureTxSucceeded(ctx, l1client, tx) Require(t, err) - validatorUtils, err := rollupgen.NewValidatorUtils(testNodeA.L2Node.DeployInfo.ValidatorUtils, testNodeA.L1Client) + validatorUtils, err := rollupgen.NewValidatorUtils(l2nodeA.DeployInfo.ValidatorUtils, l1client) Require(t, err) valConfig := staker.TestL1ValidatorConfig - dpA, err := arbnode.StakerDataposter(ctx, rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), testNodeA.L2Node.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) + dpA, err := arbnode.StakerDataposter(ctx, rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), l2nodeA.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) if err != nil { t.Fatalf("Error creating validator dataposter: %v", err) } - valWalletA, err := validatorwallet.NewContract(dpA, nil, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, testNodeA.L2Node.DeployInfo.Rollup, testNodeA.L2Node.L1Reader, &l1authA, 0, func(common.Address) {}, func() uint64 { return valConfig.ExtraGas }) + valWalletA, err := validatorwallet.NewContract(dpA, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, &l1authA, 0, func(common.Address) {}, func() uint64 { return valConfig.ExtraGas }) Require(t, err) if honestStakerInactive { valConfig.Strategy = "Defensive" @@ -147,11 +147,11 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) blockValidatorConfig := staker.TestBlockValidatorConfig statelessA, err := staker.NewStatelessBlockValidator( - testNodeA.L2Node.InboxReader, - testNodeA.L2Node.InboxTracker, - testNodeA.L2Node.TxStreamer, - testNodeA.L2Node.Execution.Recorder, - testNodeA.L2Node.ArbDB, + l2nodeA.InboxReader, + l2nodeA.InboxTracker, + l2nodeA.TxStreamer, + l2nodeA.Execution.Recorder, + l2nodeA.ArbDB, nil, StaticFetcherFrom(t, &blockValidatorConfig), valStack, @@ -160,7 +160,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) err = statelessA.Start(ctx) Require(t, err) stakerA, err := staker.NewStaker( - testNodeA.L2Node.L1Reader, + l2nodeA.L1Reader, valWalletA, bind.CallOpts{}, valConfig, @@ -168,7 +168,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) statelessA, nil, nil, - testNodeA.L2Node.DeployInfo.ValidatorUtils, + l2nodeA.DeployInfo.ValidatorUtils, nil, ) Require(t, err) @@ -218,15 +218,15 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) err = valWalletB.Initialize(ctx) Require(t, err) } - dpC, err := arbnode.StakerDataposter(ctx, rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), testNodeA.L2Node.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) + dpC, err := arbnode.StakerDataposter(ctx, rawdb.NewTable(l2nodeB.ArbDB, storage.StakerPrefix), l2nodeA.L1Reader, &l1authA, NewFetcherFromConfig(arbnode.ConfigDefaultL1NonSequencerTest()), nil) if err != nil { t.Fatalf("Error creating validator dataposter: %v", err) } - valWalletC, err := validatorwallet.NewContract(dpC, nil, testNodeA.L2Node.DeployInfo.ValidatorWalletCreator, testNodeA.L2Node.DeployInfo.Rollup, testNodeA.L2Node.L1Reader, nil, 0, func(common.Address) {}, func() uint64 { return 10000 }) + valWalletC, err := validatorwallet.NewContract(dpC, nil, l2nodeA.DeployInfo.ValidatorWalletCreator, l2nodeA.DeployInfo.Rollup, l2nodeA.L1Reader, nil, 0, func(common.Address) {}, func() uint64 { return 10000 }) Require(t, err) valConfig.Strategy = "Watchtower" stakerC, err := staker.NewStaker( - testNodeA.L2Node.L1Reader, + l2nodeA.L1Reader, valWalletC, bind.CallOpts{}, valConfig, @@ -234,7 +234,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) statelessA, nil, nil, - testNodeA.L2Node.DeployInfo.ValidatorUtils, + l2nodeA.DeployInfo.ValidatorUtils, nil, ) Require(t, err) @@ -247,9 +247,9 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) l2info.GenerateAccount("BackgroundUser") tx = l2info.PrepareTx("Faucet", "BackgroundUser", l2info.TransferGas, balance, nil) - err = testNodeA.L2Client.SendTransaction(ctx, tx) + err = l2clientA.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2clientA, tx) Require(t, err) // Continually make L2 transactions in a background thread @@ -261,7 +261,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) })() go (func() { defer close(backgroundTxsShutdownChan) - err := makeBackgroundTxs(backgroundTxsCtx, l2info, testNodeA.L2Client) + err := makeBackgroundTxs(backgroundTxsCtx, l2info, l2clientA) if !errors.Is(err, context.Canceled) { log.Warn("error making background txs", "err", err) } @@ -304,26 +304,26 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) if !challengeMangerTimedOut { // Upgrade the ChallengeManager contract to an implementation which says challenges are always timed out - mockImpl, tx, _, err := mocksgen.DeployTimedOutChallengeManager(&deployAuth, testNodeA.L1Client) + mockImpl, tx, _, err := mocksgen.DeployTimedOutChallengeManager(&deployAuth, l1client) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) + _, err = EnsureTxSucceeded(ctx, l1client, tx) Require(t, err) managerAddr := valWalletA.ChallengeManagerAddress() // 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 proxyAdminSlot := common.BigToHash(arbmath.BigSub(crypto.Keccak256Hash([]byte("eip1967.proxy.admin")).Big(), common.Big1)) - proxyAdminBytes, err := testNodeA.L1Client.StorageAt(ctx, managerAddr, proxyAdminSlot, nil) + proxyAdminBytes, err := l1client.StorageAt(ctx, managerAddr, proxyAdminSlot, nil) Require(t, err) proxyAdminAddr := common.BytesToAddress(proxyAdminBytes) if proxyAdminAddr == (common.Address{}) { Fatal(t, "failed to get challenge manager proxy admin") } - proxyAdmin, err := mocksgen.NewProxyAdminForBinding(proxyAdminAddr, testNodeA.L1Client) + proxyAdmin, err := mocksgen.NewProxyAdminForBinding(proxyAdminAddr, l1client) Require(t, err) tx, err = proxyAdmin.Upgrade(&deployAuth, managerAddr, mockImpl) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) + _, err = EnsureTxSucceeded(ctx, l1client, tx) Require(t, err) challengeMangerTimedOut = true @@ -343,11 +343,11 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) } Require(t, err, "Staker", stakerName, "failed to act") if tx != nil { - _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) + _, err = EnsureTxSucceeded(ctx, l1client, tx) Require(t, err, "EnsureTxSucceeded failed for staker", stakerName, "tx") } if faultyStaker { - conflictInfo, err := validatorUtils.FindStakerConflict(&bind.CallOpts{}, testNodeA.L2Node.DeployInfo.Rollup, l1authA.From, l1authB.From, big.NewInt(1024)) + conflictInfo, err := validatorUtils.FindStakerConflict(&bind.CallOpts{}, l2nodeA.DeployInfo.Rollup, l1authA.From, l1authB.From, big.NewInt(1024)) Require(t, err) if staker.ConflictType(conflictInfo.Ty) == staker.CONFLICT_TYPE_FOUND { cancelBackgroundTxs() @@ -379,7 +379,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) Require(t, err) } for j := 0; j < 5; j++ { - testNodeA.TransferBalanceViaL1(t, "Faucet", "Faucet", common.Big0) + TransferBalance(t, "Faucet", "Faucet", common.Big0, l1info, l1client, ctx) } } diff --git a/system_tests/transfer_test.go b/system_tests/transfer_test.go index 1c7e7cae17..2e3317907b 100644 --- a/system_tests/transfer_test.go +++ b/system_tests/transfer_test.go @@ -8,30 +8,28 @@ import ( "fmt" "math/big" "testing" - - "github.com/offchainlabs/nitro/arbnode" ) func TestTransfer(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - testNode := NewNodeBuilder(ctx).SetNodeConfig(arbnode.ConfigDefaultL2Test()).CreateTestNodeOnL2Only(t, true) - defer testNode.L2Node.StopAndWait() + l2info, l2node, client := CreateTestL2(t, ctx) + defer l2node.StopAndWait() - testNode.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - tx := testNode.L2Info.PrepareTx("Owner", "User2", testNode.L2Info.TransferGas, big.NewInt(1e12), nil) + tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) - err := testNode.L2Client.SendTransaction(ctx, tx) + err := client.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNode.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, client, tx) Require(t, err) - bal, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("Owner"), nil) + bal, err := client.BalanceAt(ctx, l2info.GetAddress("Owner"), nil) Require(t, err) fmt.Println("Owner balance is: ", bal) - bal2, err := testNode.L2Client.BalanceAt(ctx, testNode.L2Info.GetAddress("User2"), nil) + bal2, err := client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) if bal2.Cmp(big.NewInt(1e12)) != 0 { Fatal(t, "Unexpected recipient balance: ", bal2) diff --git a/system_tests/twonodes_test.go b/system_tests/twonodes_test.go index b9be59a19a..72de2aa50a 100644 --- a/system_tests/twonodes_test.go +++ b/system_tests/twonodes_test.go @@ -20,24 +20,24 @@ func testTwoNodesSimple(t *testing.T, dasModeStr string) { chainConfig, l1NodeConfigA, lifecycleManager, _, dasSignerKey := setupConfigWithDAS(t, ctx, dasModeStr) defer lifecycleManager.StopAndWaitUntil(time.Second) - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(l1NodeConfigA).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) - defer testNodeA.L2Node.StopAndWait() + l2info, nodeA, l2clientA, l1info, _, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) + defer requireClose(t, l1stack) + defer nodeA.StopAndWait() - authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) + authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) l1NodeConfigBDataAvailability := l1NodeConfigA.DataAvailability l1NodeConfigBDataAvailability.RPCAggregator.Enable = false - l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, &l1NodeConfigBDataAvailability) + l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, &l1NodeConfigBDataAvailability) defer nodeB.StopAndWait() - testNodeA.L2Info.GenerateAccount("User2") + l2info.GenerateAccount("User2") - tx := testNodeA.L2Info.PrepareTx("Owner", "User2", testNodeA.L2Info.TransferGas, big.NewInt(1e12), nil) + tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) - err := testNodeA.L2Client.SendTransaction(ctx, tx) + err := l2clientA.SendTransaction(ctx, tx) Require(t, err) - _, err = EnsureTxSucceeded(ctx, testNodeA.L2Client, tx) + _, err = EnsureTxSucceeded(ctx, l2clientA, tx) Require(t, err) // give the inbox reader a bit of time to pick up the delayed message @@ -45,15 +45,15 @@ func testTwoNodesSimple(t *testing.T, dasModeStr string) { // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in for i := 0; i < 30; i++ { - SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ - testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } _, err = WaitForTx(ctx, l2clientB, tx.Hash(), time.Second*5) Require(t, err) - l2balance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("User2"), nil) + l2balance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("User2"), nil) Require(t, err) if l2balance.Cmp(big.NewInt(1e12)) != 0 { diff --git a/system_tests/twonodeslong_test.go b/system_tests/twonodeslong_test.go index 2dde9a512e..0cac9d6442 100644 --- a/system_tests/twonodeslong_test.go +++ b/system_tests/twonodeslong_test.go @@ -42,32 +42,32 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { chainConfig, l1NodeConfigA, lifecycleManager, _, dasSignerKey := setupConfigWithDAS(t, ctx, dasModeStr) defer lifecycleManager.StopAndWaitUntil(time.Second) - testNodeA := NewNodeBuilder(ctx).SetNodeConfig(l1NodeConfigA).SetChainConfig(chainConfig).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) - defer requireClose(t, testNodeA.L1Stack) + l2info, nodeA, l2client, l1info, l1backend, l1client, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, l1NodeConfigA, chainConfig, nil) + defer requireClose(t, l1stack) - authorizeDASKeyset(t, ctx, dasSignerKey, testNodeA.L1Info, testNodeA.L1Client) + authorizeDASKeyset(t, ctx, dasSignerKey, l1info, l1client) l1NodeConfigBDataAvailability := l1NodeConfigA.DataAvailability l1NodeConfigBDataAvailability.RPCAggregator.Enable = false - l2clientB, nodeB := Create2ndNode(t, ctx, testNodeA.L2Node, testNodeA.L1Stack, testNodeA.L1Info, &testNodeA.L2Info.ArbInitData, &l1NodeConfigBDataAvailability) + l2clientB, nodeB := Create2ndNode(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, &l1NodeConfigBDataAvailability) defer nodeB.StopAndWait() - testNodeA.L2Info.GenerateAccount("DelayedFaucet") - testNodeA.L2Info.GenerateAccount("DelayedReceiver") - testNodeA.L2Info.GenerateAccount("DirectReceiver") + l2info.GenerateAccount("DelayedFaucet") + l2info.GenerateAccount("DelayedReceiver") + l2info.GenerateAccount("DirectReceiver") - testNodeA.L2Info.GenerateAccount("ErrorTxSender") + l2info.GenerateAccount("ErrorTxSender") - SendWaitTestTransactions(t, ctx, testNodeA.L2Client, []*types.Transaction{ - testNodeA.L2Info.PrepareTx("Faucet", "ErrorTxSender", testNodeA.L2Info.TransferGas, big.NewInt(l2pricing.InitialBaseFeeWei*int64(testNodeA.L2Info.TransferGas)), nil), + SendWaitTestTransactions(t, ctx, l2client, []*types.Transaction{ + l2info.PrepareTx("Faucet", "ErrorTxSender", l2info.TransferGas, big.NewInt(l2pricing.InitialBaseFeeWei*int64(l2info.TransferGas)), nil), }) delayedMsgsToSendMax := big.NewInt(int64(largeLoops * avgDelayedMessagesPerLoop * 10)) delayedFaucetNeeds := new(big.Int).Mul(new(big.Int).Add(fundsPerDelayed, new(big.Int).SetUint64(l2pricing.InitialBaseFeeWei*100000)), delayedMsgsToSendMax) - SendWaitTestTransactions(t, ctx, testNodeA.L2Client, []*types.Transaction{ - testNodeA.L2Info.PrepareTx("Faucet", "DelayedFaucet", testNodeA.L2Info.TransferGas, delayedFaucetNeeds, nil), + SendWaitTestTransactions(t, ctx, l2client, []*types.Transaction{ + l2info.PrepareTx("Faucet", "DelayedFaucet", l2info.TransferGas, delayedFaucetNeeds, nil), }) - delayedFaucetBalance, err := testNodeA.L2Client.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DelayedFaucet"), nil) + delayedFaucetBalance, err := l2client.BalanceAt(ctx, l2info.GetAddress("DelayedFaucet"), nil) Require(t, err) if delayedFaucetBalance.Cmp(delayedFaucetNeeds) != 0 { @@ -85,17 +85,17 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { randNum := rand.Int() % avgTotalL1MessagesPerLoop var l1tx *types.Transaction if randNum < avgDelayedMessagesPerLoop { - delayedTx := testNodeA.L2Info.PrepareTx("DelayedFaucet", "DelayedReceiver", 30001, fundsPerDelayed, nil) - l1tx = WrapL2ForDelayed(t, delayedTx, testNodeA.L1Info, "User", 100000) + delayedTx := l2info.PrepareTx("DelayedFaucet", "DelayedReceiver", 30001, fundsPerDelayed, nil) + l1tx = WrapL2ForDelayed(t, delayedTx, l1info, "User", 100000) delayedTxs = append(delayedTxs, delayedTx) delayedTransfers++ } else { - l1tx = testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) + l1tx = l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) } l1Txs = append(l1Txs, l1tx) } // adding multiple messages in the same AddLocal to get them in the same L1 block - errs := testNodeA.L1Backend.TxPool().AddLocals(l1Txs) + errs := l1backend.TxPool().AddLocals(l1Txs) for _, err := range errs { if err != nil { Fatal(t, err) @@ -104,26 +104,26 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { l2TxsThisTime := rand.Int() % (avgL2MsgsPerLoop * 2) l2Txs := make([]*types.Transaction, 0, l2TxsThisTime) for len(l2Txs) < l2TxsThisTime { - l2Txs = append(l2Txs, testNodeA.L2Info.PrepareTx("Faucet", "DirectReceiver", testNodeA.L2Info.TransferGas, fundsPerDirect, nil)) + l2Txs = append(l2Txs, l2info.PrepareTx("Faucet", "DirectReceiver", l2info.TransferGas, fundsPerDirect, nil)) } - SendWaitTestTransactions(t, ctx, testNodeA.L2Client, l2Txs) + SendWaitTestTransactions(t, ctx, l2client, l2Txs) directTransfers += int64(l2TxsThisTime) if len(l1Txs) > 0 { - _, err := EnsureTxSucceeded(ctx, testNodeA.L1Client, l1Txs[len(l1Txs)-1]) + _, err := EnsureTxSucceeded(ctx, l1client, l1Txs[len(l1Txs)-1]) if err != nil { Fatal(t, err) } } // create bad tx on delayed inbox - testNodeA.L2Info.GetInfoWithPrivKey("ErrorTxSender").Nonce = 10 - SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ - WrapL2ForDelayed(t, testNodeA.L2Info.PrepareTx("ErrorTxSender", "DelayedReceiver", 30002, delayedFaucetNeeds, nil), testNodeA.L1Info, "User", 100000), + l2info.GetInfoWithPrivKey("ErrorTxSender").Nonce = 10 + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + WrapL2ForDelayed(t, l2info.PrepareTx("ErrorTxSender", "DelayedReceiver", 30002, delayedFaucetNeeds, nil), l1info, "User", 100000), }) extrBlocksThisTime := rand.Int() % (avgExtraBlocksPerLoop * 2) for i := 0; i < extrBlocksThisTime; i++ { - SendWaitTestTransactions(t, ctx, testNodeA.L1Client, []*types.Transaction{ - testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) } } @@ -137,38 +137,38 @@ func testTwoNodesLong(t *testing.T, dasModeStr string) { for i := 0; i < finalPropagateLoops; i++ { var tx *types.Transaction for j := 0; j < 30; j++ { - tx = testNodeA.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) - err := testNodeA.L1Client.SendTransaction(ctx, tx) + tx = l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil) + err := l1client.SendTransaction(ctx, tx) if err != nil { Fatal(t, err) } - _, err = EnsureTxSucceeded(ctx, testNodeA.L1Client, tx) + _, err = EnsureTxSucceeded(ctx, l1client, tx) if err != nil { Fatal(t, err) } } } - _, err = EnsureTxSucceededWithTimeout(ctx, testNodeA.L2Client, delayedTxs[len(delayedTxs)-1], time.Second*10) + _, err = EnsureTxSucceededWithTimeout(ctx, l2client, delayedTxs[len(delayedTxs)-1], time.Second*10) Require(t, err, "Failed waiting for Tx on main node") _, err = EnsureTxSucceededWithTimeout(ctx, l2clientB, delayedTxs[len(delayedTxs)-1], time.Second*10) Require(t, err, "Failed waiting for Tx on secondary node") - delayedBalance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DelayedReceiver"), nil) + delayedBalance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("DelayedReceiver"), nil) Require(t, err) - directBalance, err := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DirectReceiver"), nil) + directBalance, err := l2clientB.BalanceAt(ctx, l2info.GetAddress("DirectReceiver"), nil) Require(t, err) delayedExpectd := new(big.Int).Mul(fundsPerDelayed, big.NewInt(delayedTransfers)) directExpectd := new(big.Int).Mul(fundsPerDirect, big.NewInt(directTransfers)) if (delayedBalance.Cmp(delayedExpectd) != 0) || (directBalance.Cmp(directExpectd) != 0) { t.Error("delayed balance", delayedBalance, "expected", delayedExpectd, "transfers", delayedTransfers) t.Error("direct balance", directBalance, "expected", directExpectd, "transfers", directTransfers) - ownerBalance, _ := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("Owner"), nil) - delayedFaucetBalance, _ := l2clientB.BalanceAt(ctx, testNodeA.L2Info.GetAddress("DelayedFaucet"), nil) + ownerBalance, _ := l2clientB.BalanceAt(ctx, l2info.GetAddress("Owner"), nil) + delayedFaucetBalance, _ := l2clientB.BalanceAt(ctx, l2info.GetAddress("DelayedFaucet"), nil) t.Error("owner balance", ownerBalance, "delayed faucet", delayedFaucetBalance) Fatal(t, "Unexpected balance") } - testNodeA.L2Node.StopAndWait() + nodeA.StopAndWait() if nodeB.BlockValidator != nil { lastBlockHeader, err := l2clientB.HeaderByNumber(ctx, nil) From 104011baa98589ab49993fb2a701a0be7d4de4de Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Fri, 29 Sep 2023 16:56:48 -0500 Subject: [PATCH 04/54] Update builder pattern --- system_tests/batch_poster_test.go | 49 +++--- system_tests/bloom_test.go | 31 ++-- system_tests/common_test.go | 202 ++++++++++------------- system_tests/full_challenge_impl_test.go | 75 +++++---- 4 files changed, 170 insertions(+), 187 deletions(-) diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index ef50be6ec4..e063db9981 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -45,16 +45,19 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { parallelBatchPosters = 4 } - conf := arbnode.ConfigDefaultL1Test() - conf.BatchPoster.Enable = false - conf.BatchPoster.RedisUrl = redisUrl - builder := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true) - l1A, l2A := builder.BuildL2OnL1(t) - // testNodeA := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true).CreateTestNodeOnL1AndL2(t) + builder := NewNodeBuilder(ctx).DefaultConfig(true, nil, nil) + builder.nodeConfig.BatchPoster.Enable = false + builder.nodeConfig.BatchPoster.RedisUrl = redisUrl + builder.Build(t) + l1A, l2A := builder.L1, builder.L2 + defer requireClose(t, l1A.Stack) defer l2A.Node.StopAndWait() - l2B := builder.Build2ndNodeDAS(t, &l2A.Info.ArbInitData, nil) + params := make(SecondNodeParams) + params["initData"] = &l2A.Info.ArbInitData + params["dasConfig"] = nil + l2B := builder.Build2ndNode(t, params) defer l2B.Node.StopAndWait() l2A.Info.GenerateAccount("User2") @@ -77,13 +80,13 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { firstTxData, err := txs[0].MarshalBinary() Require(t, err) seqTxOpts := l1A.Info.GetDefaultTransactOpts("Sequencer", ctx) - conf.BatchPoster.Enable = true - conf.BatchPoster.MaxSize = len(firstTxData) * 2 + builder.nodeConfig.BatchPoster.Enable = true + builder.nodeConfig.BatchPoster.MaxSize = len(firstTxData) * 2 startL1Block, err := l1A.Client.BlockNumber(ctx) Require(t, err) for i := 0; i < parallelBatchPosters; i++ { // Make a copy of the batch poster config so NewBatchPoster calling Validate() on it doesn't race - batchPosterConfig := conf.BatchPoster + batchPosterConfig := builder.nodeConfig.BatchPoster batchPoster, err := arbnode.NewBatchPoster(ctx, nil, l2A.Node.L1Reader, l2A.Node.InboxTracker, l2A.Node.TxStreamer, l2A.Node.SyncMonitor, func() *arbnode.BatchPosterConfig { return &batchPosterConfig }, l2A.Node.DeployInfo, &seqTxOpts, nil) Require(t, err) batchPoster.Start(ctx) @@ -144,14 +147,18 @@ func TestBatchPosterLargeTx(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - conf := arbnode.ConfigDefaultL1Test() - conf.Sequencer.MaxTxDataSize = 110000 - builder := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true) - l1A, l2A := builder.BuildL2OnL1(t) + builder := NewNodeBuilder(ctx).DefaultConfig(true, nil, nil) + builder.nodeConfig.Sequencer.MaxTxDataSize = 110000 + builder.Build(t) + + l1A, l2A := builder.L1, builder.L2 defer requireClose(t, l1A.Stack) defer l2A.Node.StopAndWait() - l2B := builder.Build2ndNodeDAS(t, &l2A.Info.ArbInitData, nil) + params := make(SecondNodeParams) + params["initData"] = &l2A.Info.ArbInitData + params["dasConfig"] = nil + l2B := builder.Build2ndNode(t, params) defer l2B.Node.StopAndWait() data := make([]byte, 100000) @@ -176,12 +183,12 @@ func TestBatchPosterKeepsUp(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - conf := arbnode.ConfigDefaultL1Test() - conf.BatchPoster.CompressionLevel = brotli.BestCompression - conf.BatchPoster.MaxDelay = time.Hour - conf.RPC.RPCTxFeeCap = 1000. - builder := NewNodeBuilder(ctx).SetNodeConfig(conf).SetIsSequencer(true) - l1A, l2A := builder.BuildL2OnL1(t) + builder := NewNodeBuilder(ctx).DefaultConfig(true, nil, nil) + builder.nodeConfig.BatchPoster.CompressionLevel = brotli.BestCompression + builder.nodeConfig.BatchPoster.MaxDelay = time.Hour + builder.nodeConfig.RPC.RPCTxFeeCap = 1000. + builder.Build(t) + l1A, l2A := builder.L1, builder.L2 defer requireClose(t, l1A.Stack) defer l2A.Node.StopAndWait() l2A.Info.GasPrice = big.NewInt(100e9) diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go index 9ad3253d4a..6e1c6b0ab2 100644 --- a/system_tests/bloom_test.go +++ b/system_tests/bloom_test.go @@ -17,7 +17,6 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/solgen/go/mocksgen" ) @@ -25,17 +24,19 @@ func TestBloom(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodeconfig := arbnode.ConfigDefaultL2Test() - nodeconfig.RPC.BloomBitsBlocks = 256 - nodeconfig.RPC.BloomConfirms = 1 - l2info, node, client := CreateTestL2WithConfig(t, ctx, nil, nodeconfig, false) - defer node.StopAndWait() + builder := NewNodeBuilder(ctx).DefaultConfig(false, nil, nil) + builder.nodeConfig.RPC.BloomBitsBlocks = 256 + builder.nodeConfig.RPC.BloomConfirms = 1 + builder.takeOwnership = false + builder.Build(t) - l2info.GenerateAccount("User2") + defer builder.L2.Node.StopAndWait() - ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) + builder.L2.Info.GenerateAccount("User2") + + ownerTxOpts := builder.L2.Info.GetDefaultTransactOpts("Owner", ctx) ownerTxOpts.Context = ctx - _, simple := deploySimple(t, ctx, ownerTxOpts, client) + _, simple := deploySimple(t, ctx, ownerTxOpts, builder.L2.Client) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() Require(t, err) @@ -63,7 +64,7 @@ func TestBloom(t *testing.T) { if sendNullEvent { tx, err = simple.EmitNullEvent(&ownerTxOpts) Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, builder.L2.Client, tx) Require(t, err) } @@ -74,7 +75,7 @@ func TestBloom(t *testing.T) { tx, err = simple.Increment(&ownerTxOpts) } Require(t, err) - _, err = EnsureTxSucceeded(ctx, client, tx) + _, err = EnsureTxSucceeded(ctx, builder.L2.Client, tx) Require(t, err) if i%100 == 0 { t.Log("counts: ", i, "/", countsNum) @@ -82,7 +83,7 @@ func TestBloom(t *testing.T) { } for { - sectionSize, sectionNum := node.Execution.Backend.APIBackend().BloomStatus() + sectionSize, sectionNum := builder.L2.Node.Execution.Backend.APIBackend().BloomStatus() if sectionSize != 256 { Fatal(t, "unexpected section size: ", sectionSize) } @@ -92,14 +93,14 @@ func TestBloom(t *testing.T) { } <-time.After(time.Second) } - lastHeader, err := client.HeaderByNumber(ctx, nil) + lastHeader, err := builder.L2.Client.HeaderByNumber(ctx, nil) Require(t, err) nullEventQuery := ethereum.FilterQuery{ FromBlock: big.NewInt(0), ToBlock: lastHeader.Number, Topics: [][]common.Hash{{simpleABI.Events["NullEvent"].ID}}, } - logs, err := client.FilterLogs(ctx, nullEventQuery) + logs, err := builder.L2.Client.FilterLogs(ctx, nullEventQuery) Require(t, err) if len(logs) != len(nullEventCounts) { Fatal(t, "expected ", len(nullEventCounts), " logs, got ", len(logs)) @@ -107,7 +108,7 @@ func TestBloom(t *testing.T) { incrementEventQuery := ethereum.FilterQuery{ Topics: [][]common.Hash{{simpleABI.Events["CounterEvent"].ID}}, } - logs, err = client.FilterLogs(ctx, incrementEventQuery) + logs, err = builder.L2.Client.FilterLogs(ctx, incrementEventQuery) Require(t, err) if len(logs) != len(eventCounts) { Fatal(t, "expected ", len(eventCounts), " logs, got ", len(logs)) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 9525d9d6cc..56576f9d12 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -74,18 +74,6 @@ func NewTestClient(ctx context.Context) *TestClient { return &TestClient{ctx: ctx} } -// SetClient is used to initialize *ethclient.Client when users dont want to create TestClients via create methods from nodebuilder -func (tc *TestClient) SetClient(c *ethclient.Client) *TestClient { - tc.Client = c - return tc -} - -// SetInfo is used to initialize *BlockchainTestInfo when users dont want to create TestClients via create methods from nodebuilder -func (tc *TestClient) SetInfo(i info) *TestClient { - tc.Info = i - return tc -} - func (tc *TestClient) SendSignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction) *types.Receipt { return SendSignedTxViaL1(t, tc.ctx, tc.Info, tc.Client, l2Client, transaction) } @@ -110,21 +98,31 @@ func (tc *TestClient) GetBaseFeeAt(t *testing.T, blockNum *big.Int) *big.Int { return GetBaseFeeAt(t, tc.Client, tc.ctx, blockNum) } +func (tc *TestClient) SendWaitTestTransactions(t *testing.T, txs []*types.Transaction) { + SendWaitTestTransactions(t, tc.ctx, tc.Client, txs) +} + func (tc *TestClient) DeploySimple(t *testing.T, auth bind.TransactOpts) (common.Address, *mocksgen.Simple) { return deploySimple(t, tc.ctx, auth, tc.Client) } type NodeBuilder struct { - // Nodebuilder configuration + // NodeBuilder configuration ctx context.Context Info info chainConfig *params.ChainConfig - cacheConfig *core.CacheConfig nodeConfig *arbnode.Config stackConfig *node.Config cachingConfig *execution.CachingConfig + + // NodeBuiilder Node parameters isSequencer bool takeOwnership bool + withL1 bool + + // NodeBuiilder Blockchain parameters + dataDir string + initMessage *arbostypes.ParsedInitMessage // Created nodes L1 *TestClient @@ -135,136 +133,108 @@ func NewNodeBuilder(ctx context.Context) *NodeBuilder { return &NodeBuilder{ctx: ctx} } -func (b *NodeBuilder) SetChainConfig(c *params.ChainConfig) *NodeBuilder { - b.chainConfig = c - return b -} - -func (b *NodeBuilder) SetNodeConfig(c *arbnode.Config) *NodeBuilder { - b.nodeConfig = c - return b -} - -func (b *NodeBuilder) SetCacheConfig(c *core.CacheConfig) *NodeBuilder { - b.cacheConfig = c - return b -} - -func (b *NodeBuilder) SetStackConfig(c *node.Config) *NodeBuilder { - b.stackConfig = c - return b -} - -func (b *NodeBuilder) SetInfo(i info) *NodeBuilder { - b.Info = i - return b -} - -func (b *NodeBuilder) SetCachingConfig(c *execution.CachingConfig) *NodeBuilder { - b.cachingConfig = c - return b -} - -func (b *NodeBuilder) SetIsSequencer(v bool) *NodeBuilder { - b.isSequencer = v - return b -} - -func (b *NodeBuilder) SetTakeOwnership(v bool) *NodeBuilder { - b.takeOwnership = v - return b -} - -func (b *NodeBuilder) ConfigForL2OnL1(isSequencer bool, n *arbnode.Config, c *params.ChainConfig, s *node.Config, i info) *NodeBuilder { - b.isSequencer = isSequencer - b.nodeConfig = n - b.chainConfig = c - b.stackConfig = s - b.Info = i +func (b *NodeBuilder) DefaultConfig(withL1 bool, n *arbnode.Config, c *params.ChainConfig) *NodeBuilder { + // most used values across current tests are set here as default + b.withL1 = withL1 + if withL1 { + b.isSequencer = true + b.nodeConfig = arbnode.ConfigDefaultL1Test() + if n != nil { + b.nodeConfig = n + } + b.chainConfig = c + } else { + b.takeOwnership = true + b.nodeConfig = arbnode.ConfigDefaultL2Test() + if n != nil { + b.nodeConfig = n + } + b.chainConfig = c + } return b } -func (b *NodeBuilder) BuildL2OnL1(t *testing.T) (*TestClient, *TestClient) { - l1, l2 := NewTestClient(b.ctx), NewTestClient(b.ctx) - l2.Info, l2.Node, l2.Client, l2.Stack, l1.Info, l1.Backend, l1.Client, l1.Stack = - createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.stackConfig, b.Info) - b.L1, b.L2 = l1, l2 - return l1, l2 -} - -func (b *NodeBuilder) ConfigForL2(takeOwnership bool, n *arbnode.Config, i info) *NodeBuilder { - b.takeOwnership = takeOwnership - b.nodeConfig = n - b.Info = i +func (b *NodeBuilder) Build(t *testing.T) *NodeBuilder { + if b.withL1 { + l1, l2 := NewTestClient(b.ctx), NewTestClient(b.ctx) + l2.Info, l2.Node, l2.Client, l2.Stack, l1.Info, l1.Backend, l1.Client, l1.Stack = + createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.stackConfig, b.Info) + b.L1, b.L2 = l1, l2 + } else { + l2 := NewTestClient(b.ctx) + l2.Info, l2.Node, l2.Client = + CreateTestL2WithConfig(t, b.ctx, b.Info, b.nodeConfig, b.takeOwnership) + b.L2 = l2 + } return b } -func (b *NodeBuilder) BuildL2(t *testing.T) *TestClient { - l2 := NewTestClient(b.ctx) - l2.Info, l2.Node, l2.Client = - CreateTestL2WithConfig(t, b.ctx, b.Info, b.nodeConfig, b.takeOwnership) - b.L2 = l2 - return l2 -} +type SecondNodeParams map[string]interface{} -func (b *NodeBuilder) Build2ndNode(t *testing.T, initData *statetransfer.ArbosInitializationInfo, nodeConfig *arbnode.Config, stackConfig *node.Config) *TestClient { +func (b *NodeBuilder) Build2ndNode(t *testing.T, params SecondNodeParams) *TestClient { if b.L1 == nil { t.Fatal("builder did not previously build a L1 Node") } if b.L2 == nil { t.Fatal("builder did not previously build a L2 Node") } - l2 := NewTestClient(b.ctx) - l2.Client, l2.Node = - Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, b.L1.Stack, b.L1.Info, initData, nodeConfig, stackConfig) - return l2 -} - -func (b *NodeBuilder) Build2ndNodeDAS(t *testing.T, initData *statetransfer.ArbosInitializationInfo, dasConfig *das.DataAvailabilityConfig) *TestClient { - if b.L1 == nil { - t.Fatal("builder did not previously build a L1 Node") + if _, ok := params["dasConfig"]; ok { + nodeConf := arbnode.ConfigDefaultL1NonSequencerTest() + if params["dasConfig"] == nil { + nodeConf.DataAvailability.Enable = false + } else { + nodeConf.DataAvailability = *params["dasConfig"].(*das.DataAvailabilityConfig) + } + params["nodeConfig"] = nodeConf + } else if _, ok := params["nodeConfig"]; !ok { + params["nodeConfig"] = b.nodeConfig } - if b.L2 == nil { - t.Fatal("builder did not previously build a L2 Node") + if _, ok := params["stackConfig"]; !ok { + params["stackConfig"] = b.stackConfig } + l2 := NewTestClient(b.ctx) l2.Client, l2.Node = - Create2ndNode(t, b.ctx, b.L2.Node, b.L1.Stack, b.L1.Info, initData, dasConfig) + Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, b.L1.Stack, b.L1.Info, + params["initData"].(*statetransfer.ArbosInitializationInfo), + params["nodeConfig"].(*arbnode.Config), + params["stackConfig"].(*node.Config)) return l2 } -type TestBlockchain struct { - TestClient - // Blockchain fields - ChainDB ethdb.Database - NodeDB ethdb.Database - Blockchain *core.BlockChain +func (b *NodeBuilder) BuildL1Blockchain(t *testing.T) *TestBlockchain { + l1 := NewTestBlockchain(b.ctx) + l1.Info, l1.Client, l1.Backend, l1.Stack = createTestL1BlockChain(t, b.Info) + return l1 } -func (b *NodeBuilder) ConfigForL1Blockchain(s *node.Config, i info) *NodeBuilder { - b.stackConfig = s - b.Info = i - return b +func (b *NodeBuilder) BuildL2Blockchain(t *testing.T) *TestBlockchain { + l2 := NewTestBlockchain(b.ctx) + l2.Info, l2.Stack, l2.ChainDB, l2.NodeDB, l2.Blockchain = + createL2BlockChainWithStackConfig(t, b.Info, b.dataDir, b.chainConfig, b.initMessage, b.stackConfig, b.cachingConfig) + return l2 } -func (b *NodeBuilder) BuilL1Blockchain(t *testing.T) *TestBlockchain { - l1 := &TestBlockchain{} - l1.ctx = b.ctx - l1.Info, l1.Client, l1.Backend, l1.Stack = createTestL1BlockChainWithConfig(t, b.Info, b.stackConfig) - return l1 +func (b *NodeBuilder) BridgeBalance(t *testing.T, account string, amount *big.Int) (*types.Transaction, *types.Receipt) { + return BridgeBalance(t, account, amount, b.L1.Info, b.L2.Info, b.L1.Client, b.L2.Client, b.ctx) } -func (b *NodeBuilder) ConfigForL2Blockchain(s *node.Config, i info) *NodeBuilder { - b.stackConfig = s - b.Info = i - return b +type TestBlockchain struct { + TestClient + // Blockchain fields + chainConfig *params.ChainConfig + ChainDB ethdb.Database + NodeDB ethdb.Database + Blockchain *core.BlockChain } -func (b *NodeBuilder) BuilL2Blockchain(t *testing.T, dataDir string, initMessage *arbostypes.ParsedInitMessage) *TestBlockchain { - l2 := &TestBlockchain{} - l2.Info, l2.Stack, l2.ChainDB, l2.NodeDB, l2.Blockchain = - createL2BlockChainWithStackConfig(t, b.Info, dataDir, b.chainConfig, initMessage, b.stackConfig, b.cachingConfig) - return l2 +func NewTestBlockchain(ctx context.Context) *TestBlockchain { + tc := NewTestClient(ctx) + return &TestBlockchain{TestClient: *tc} +} + +func (tb *TestBlockchain) Deploy(t *testing.T) (*chaininfo.RollupAddresses, *arbostypes.ParsedInitMessage) { + return DeployOnTestL1(t, tb.ctx, tb.Info, tb.Client, tb.chainConfig) } func SendWaitTestTransactions(t *testing.T, ctx context.Context, client client, txs []*types.Transaction) { diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index b64a655c3e..c5bb78e0d8 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -241,7 +241,9 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall l1Info.GenerateGenesisAccount("sequencer", initialBalance) chainConfig := params.ArbitrumDevTestChainConfig() - l1Info, l1Backend, _, _ := createTestL1BlockChain(t, l1Info) + builder := NewNodeBuilder(ctx).DefaultConfig(false, nil, chainConfig) + builder.Info = l1Info + tbL1 := builder.BuildL1Blockchain(t) conf := arbnode.ConfigDefaultL1Test() conf.BlockValidator.Enable = false conf.BatchPoster.Enable = false @@ -257,61 +259,64 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall configByValidationNode(t, conf, valStack) fatalErrChan := make(chan error, 10) - asserterRollupAddresses, initMessage := DeployOnTestL1(t, ctx, l1Info, l1Backend, chainConfig) + tbL1.chainConfig = chainConfig + asserterRollupAddresses, initMessage := tbL1.Deploy(t) - deployerTxOpts := l1Info.GetDefaultTransactOpts("deployer", ctx) - sequencerTxOpts := l1Info.GetDefaultTransactOpts("sequencer", ctx) - asserterTxOpts := l1Info.GetDefaultTransactOpts("asserter", ctx) - challengerTxOpts := l1Info.GetDefaultTransactOpts("challenger", ctx) + deployerTxOpts := tbL1.Info.GetDefaultTransactOpts("deployer", ctx) + sequencerTxOpts := tbL1.Info.GetDefaultTransactOpts("sequencer", ctx) + asserterTxOpts := tbL1.Info.GetDefaultTransactOpts("asserter", ctx) + challengerTxOpts := tbL1.Info.GetDefaultTransactOpts("challenger", ctx) - asserterBridgeAddr, asserterSeqInbox, asserterSeqInboxAddr := setupSequencerInboxStub(ctx, t, l1Info, l1Backend, chainConfig) - challengerBridgeAddr, challengerSeqInbox, challengerSeqInboxAddr := setupSequencerInboxStub(ctx, t, l1Info, l1Backend, chainConfig) + asserterBridgeAddr, asserterSeqInbox, asserterSeqInboxAddr := setupSequencerInboxStub(ctx, t, tbL1.Info, tbL1.Client, chainConfig) + challengerBridgeAddr, challengerSeqInbox, challengerSeqInboxAddr := setupSequencerInboxStub(ctx, t, tbL1.Info, tbL1.Client, chainConfig) - asserterL2Info, asserterL2Stack, asserterL2ChainDb, asserterL2ArbDb, asserterL2Blockchain := createL2BlockChainWithStackConfig(t, nil, "", chainConfig, initMessage, nil, nil) + builder.initMessage = initMessage + builder.Info = nil + asserterL2tb := builder.BuildL2Blockchain(t) asserterRollupAddresses.Bridge = asserterBridgeAddr asserterRollupAddresses.SequencerInbox = asserterSeqInboxAddr - asserterL2, err := arbnode.CreateNode(ctx, asserterL2Stack, asserterL2ChainDb, asserterL2ArbDb, NewFetcherFromConfig(conf), asserterL2Blockchain, l1Backend, asserterRollupAddresses, nil, nil, nil, fatalErrChan) + asserterL2, err := arbnode.CreateNode(ctx, asserterL2tb.Stack, asserterL2tb.ChainDB, asserterL2tb.NodeDB, NewFetcherFromConfig(conf), asserterL2tb.Blockchain, tbL1.Client, asserterRollupAddresses, nil, nil, nil, fatalErrChan) Require(t, err) err = asserterL2.Start(ctx) Require(t, err) - challengerL2Info, challengerL2Stack, challengerL2ChainDb, challengerL2ArbDb, challengerL2Blockchain := createL2BlockChainWithStackConfig(t, nil, "", chainConfig, initMessage, nil, nil) + challengerL2tb := builder.BuildL2Blockchain(t) challengerRollupAddresses := *asserterRollupAddresses challengerRollupAddresses.Bridge = challengerBridgeAddr challengerRollupAddresses.SequencerInbox = challengerSeqInboxAddr - challengerL2, err := arbnode.CreateNode(ctx, challengerL2Stack, challengerL2ChainDb, challengerL2ArbDb, NewFetcherFromConfig(conf), challengerL2Blockchain, l1Backend, &challengerRollupAddresses, nil, nil, nil, fatalErrChan) + challengerL2, err := arbnode.CreateNode(ctx, challengerL2tb.Stack, challengerL2tb.ChainDB, challengerL2tb.NodeDB, NewFetcherFromConfig(conf), challengerL2tb.Blockchain, tbL1.Client, &challengerRollupAddresses, nil, nil, nil, fatalErrChan) Require(t, err) err = challengerL2.Start(ctx) Require(t, err) - asserterL2Info.GenerateAccount("Destination") - challengerL2Info.SetFullAccountInfo("Destination", asserterL2Info.GetInfoWithPrivKey("Destination")) + asserterL2tb.Info.GenerateAccount("Destination") + challengerL2tb.Info.SetFullAccountInfo("Destination", asserterL2tb.Info.GetInfoWithPrivKey("Destination")) if challengeMsgIdx < 1 || challengeMsgIdx > 3*makeBatch_MsgsPerBatch { Fatal(t, "challengeMsgIdx illegal") } // seqNum := common.Big2 - makeBatch(t, asserterL2, asserterL2Info, l1Backend, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2Info, l1Backend, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-1) + makeBatch(t, asserterL2, asserterL2tb.Info, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2tb.Info, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-1) // seqNum.Add(seqNum, common.Big1) - makeBatch(t, asserterL2, asserterL2Info, l1Backend, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2Info, l1Backend, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch-1) + makeBatch(t, asserterL2, asserterL2tb.Info, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2tb.Info, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch-1) // seqNum.Add(seqNum, common.Big1) - makeBatch(t, asserterL2, asserterL2Info, l1Backend, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2Info, l1Backend, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch*2-1) + makeBatch(t, asserterL2, asserterL2tb.Info, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2tb.Info, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch*2-1) trueSeqInboxAddr := challengerSeqInboxAddr trueDelayedBridge := challengerBridgeAddr - expectedWinner := l1Info.GetAddress("challenger") + expectedWinner := tbL1.Info.GetAddress("challenger") if asserterIsCorrect { trueSeqInboxAddr = asserterSeqInboxAddr trueDelayedBridge = asserterBridgeAddr - expectedWinner = l1Info.GetAddress("asserter") + expectedWinner = tbL1.Info.GetAddress("asserter") } - ospEntry := DeployOneStepProofEntry(t, ctx, &deployerTxOpts, l1Backend) + ospEntry := DeployOneStepProofEntry(t, ctx, &deployerTxOpts, tbL1.Client) locator, err := server_common.NewMachineLocator("") if err != nil { @@ -354,7 +359,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall t, ctx, &deployerTxOpts, - l1Backend, + tbL1.Client, ospEntry, trueSeqInboxAddr, trueDelayedBridge, @@ -362,13 +367,13 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall asserterStartGlobalState, asserterEndGlobalState, numBlocks, - l1Info.GetAddress("asserter"), - l1Info.GetAddress("challenger"), + tbL1.Info.GetAddress("asserter"), + tbL1.Info.GetAddress("challenger"), ) - confirmLatestBlock(ctx, t, l1Info, l1Backend) + confirmLatestBlock(ctx, t, tbL1.Info, tbL1.Client) - asserterValidator, err := staker.NewStatelessBlockValidator(asserterL2.InboxReader, asserterL2.InboxTracker, asserterL2.TxStreamer, asserterL2.Execution.Recorder, asserterL2ArbDb, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) + asserterValidator, err := staker.NewStatelessBlockValidator(asserterL2.InboxReader, asserterL2.InboxTracker, asserterL2.TxStreamer, asserterL2.Execution.Recorder, asserterL2tb.NodeDB, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) if err != nil { Fatal(t, err) } @@ -381,11 +386,11 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall Fatal(t, err) } defer asserterValidator.Stop() - asserterManager, err := staker.NewChallengeManager(ctx, l1Backend, &asserterTxOpts, asserterTxOpts.From, challengeManagerAddr, 1, asserterValidator, 0, 0) + asserterManager, err := staker.NewChallengeManager(ctx, tbL1.Client, &asserterTxOpts, asserterTxOpts.From, challengeManagerAddr, 1, asserterValidator, 0, 0) if err != nil { Fatal(t, err) } - challengerValidator, err := staker.NewStatelessBlockValidator(challengerL2.InboxReader, challengerL2.InboxTracker, challengerL2.TxStreamer, challengerL2.Execution.Recorder, challengerL2ArbDb, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) + challengerValidator, err := staker.NewStatelessBlockValidator(challengerL2.InboxReader, challengerL2.InboxTracker, challengerL2.TxStreamer, challengerL2.Execution.Recorder, challengerL2tb.NodeDB, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) if err != nil { Fatal(t, err) } @@ -398,7 +403,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall Fatal(t, err) } defer challengerValidator.Stop() - challengerManager, err := staker.NewChallengeManager(ctx, l1Backend, &challengerTxOpts, challengerTxOpts.From, challengeManagerAddr, 1, challengerValidator, 0, 0) + challengerManager, err := staker.NewChallengeManager(ctx, tbL1.Client, &challengerTxOpts, challengerTxOpts.From, challengeManagerAddr, 1, challengerValidator, 0, 0) if err != nil { Fatal(t, err) } @@ -410,8 +415,8 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall // This might make gas estimation undersestimate next move. // Invoke a new L1 block, with a new timestamp, before estimating. time.Sleep(time.Second) - SendWaitTestTransactions(t, ctx, l1Backend, []*types.Transaction{ - l1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, tbL1.Client, []*types.Transaction{ + tbL1.Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) if i%2 == 0 { @@ -446,7 +451,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall } } - _, err = EnsureTxSucceeded(ctx, l1Backend, tx) + _, err = EnsureTxSucceeded(ctx, tbL1.Client, tx) if err != nil { if !currentCorrect && strings.Contains(err.Error(), "BAD_SEQINBOX_MESSAGE") { t.Log("challenge complete! Tx failed as expected:", err) @@ -455,7 +460,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall Fatal(t, err) } - confirmLatestBlock(ctx, t, l1Info, l1Backend) + confirmLatestBlock(ctx, t, tbL1.Info, tbL1.Client) winner, err := resultReceiver.Winner(&bind.CallOpts{}) if err != nil { From ade75d9467f48c1068fe75d9b3404cb4a231ac1f Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Fri, 29 Sep 2023 17:00:39 -0500 Subject: [PATCH 05/54] fix typo --- system_tests/common_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 56576f9d12..11d8a57cf5 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -61,7 +61,6 @@ type info = *BlockchainTestInfo type client = arbutil.L1Interface type TestClient struct { - // Nodebuilder fields ctx context.Context Info info Client *ethclient.Client @@ -115,12 +114,12 @@ type NodeBuilder struct { stackConfig *node.Config cachingConfig *execution.CachingConfig - // NodeBuiilder Node parameters + // L1, L2 Node parameters isSequencer bool takeOwnership bool withL1 bool - // NodeBuiilder Blockchain parameters + // Blockchain parameters dataDir string initMessage *arbostypes.ParsedInitMessage From 5658dfa5e07b3aea36c2ff03f0722473e69f9d38 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Mon, 2 Oct 2023 14:15:18 -0500 Subject: [PATCH 06/54] address PR comments --- system_tests/batch_poster_test.go | 61 +++++------ system_tests/bloom_test.go | 10 +- system_tests/common_test.go | 127 ++++++++++++++--------- system_tests/full_challenge_impl_test.go | 20 ++-- 4 files changed, 120 insertions(+), 98 deletions(-) diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index e063db9981..4cb9271c54 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -45,27 +45,25 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { parallelBatchPosters = 4 } - builder := NewNodeBuilder(ctx).DefaultConfig(true, nil, nil) + builder := NewNodeBuilder(ctx).DefaultConfig(t, true) builder.nodeConfig.BatchPoster.Enable = false builder.nodeConfig.BatchPoster.RedisUrl = redisUrl - builder.Build(t) + cleanup := builder.Build(t) + defer cleanup() l1A, l2A := builder.L1, builder.L2 - defer requireClose(t, l1A.Stack) - defer l2A.Node.StopAndWait() - params := make(SecondNodeParams) - params["initData"] = &l2A.Info.ArbInitData + params["nodeConfig"] = nil params["dasConfig"] = nil - l2B := builder.Build2ndNode(t, params) - defer l2B.Node.StopAndWait() + l2B, cleanup2nd := builder.Build2ndNode(t, params) + defer cleanup2nd() - l2A.Info.GenerateAccount("User2") + builder.L2Info.GenerateAccount("User2") var txs []*types.Transaction for i := 0; i < 100; i++ { - tx := l2A.Info.PrepareTx("Owner", "User2", l2A.Info.TransferGas, common.Big1, nil) + tx := builder.L2Info.PrepareTx("Owner", "User2", builder.L2Info.TransferGas, common.Big1, nil) txs = append(txs, tx) err := l2A.Client.SendTransaction(ctx, tx) @@ -79,7 +77,7 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { firstTxData, err := txs[0].MarshalBinary() Require(t, err) - seqTxOpts := l1A.Info.GetDefaultTransactOpts("Sequencer", ctx) + seqTxOpts := builder.L1Info.GetDefaultTransactOpts("Sequencer", ctx) builder.nodeConfig.BatchPoster.Enable = true builder.nodeConfig.BatchPoster.MaxSize = len(firstTxData) * 2 startL1Block, err := l1A.Client.BlockNumber(ctx) @@ -96,7 +94,7 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { lastTxHash := txs[len(txs)-1].Hash() for i := 90; i > 0; i-- { SendWaitTestTransactions(t, ctx, l1A.Client, []*types.Transaction{ - l1A.Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + builder.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) time.Sleep(500 * time.Millisecond) _, err := l2B.Client.TransactionReceipt(ctx, lastTxHash) @@ -134,7 +132,7 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { } } - l2balance, err := l2B.Client.BalanceAt(ctx, l2A.Info.GetAddress("User2"), nil) + l2balance, err := l2B.Client.BalanceAt(ctx, builder.L2Info.GetAddress("User2"), nil) Require(t, err) if l2balance.Sign() == 0 { @@ -147,26 +145,24 @@ func TestBatchPosterLargeTx(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - builder := NewNodeBuilder(ctx).DefaultConfig(true, nil, nil) + builder := NewNodeBuilder(ctx).DefaultConfig(t, true) builder.nodeConfig.Sequencer.MaxTxDataSize = 110000 - builder.Build(t) - - l1A, l2A := builder.L1, builder.L2 - defer requireClose(t, l1A.Stack) - defer l2A.Node.StopAndWait() + cleanup := builder.Build(t) + defer cleanup() + l2A := builder.L2 params := make(SecondNodeParams) - params["initData"] = &l2A.Info.ArbInitData + params["nodeConfig"] = nil params["dasConfig"] = nil - l2B := builder.Build2ndNode(t, params) - defer l2B.Node.StopAndWait() + l2B, cleanup2nd := builder.Build2ndNode(t, params) + defer cleanup2nd() data := make([]byte, 100000) _, err := rand.Read(data) Require(t, err) - faucetAddr := l2A.Info.GetAddress("Faucet") - gas := l2A.Info.TransferGas + 20000*uint64(len(data)) - tx := l2A.Info.PrepareTxTo("Faucet", &faucetAddr, gas, common.Big0, data) + faucetAddr := builder.L2Info.GetAddress("Faucet") + gas := builder.L2Info.TransferGas + 20000*uint64(len(data)) + tx := builder.L2Info.PrepareTxTo("Faucet", &faucetAddr, gas, common.Big0, data) err = l2A.Client.SendTransaction(ctx, tx) Require(t, err) receiptA, err := EnsureTxSucceeded(ctx, l2A.Client, tx) @@ -183,23 +179,22 @@ func TestBatchPosterKeepsUp(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - builder := NewNodeBuilder(ctx).DefaultConfig(true, nil, nil) + builder := NewNodeBuilder(ctx).DefaultConfig(t, true) builder.nodeConfig.BatchPoster.CompressionLevel = brotli.BestCompression builder.nodeConfig.BatchPoster.MaxDelay = time.Hour builder.nodeConfig.RPC.RPCTxFeeCap = 1000. - builder.Build(t) - l1A, l2A := builder.L1, builder.L2 - defer requireClose(t, l1A.Stack) - defer l2A.Node.StopAndWait() - l2A.Info.GasPrice = big.NewInt(100e9) + cleanup := builder.Build(t) + defer cleanup() + l2A := builder.L2 + builder.L2Info.GasPrice = big.NewInt(100e9) go func() { data := make([]byte, 90000) _, err := rand.Read(data) Require(t, err) for { - gas := l2A.Info.TransferGas + 20000*uint64(len(data)) - tx := l2A.Info.PrepareTx("Faucet", "Faucet", gas, common.Big0, data) + gas := builder.L2Info.TransferGas + 20000*uint64(len(data)) + tx := builder.L2Info.PrepareTx("Faucet", "Faucet", gas, common.Big0, data) err = l2A.Client.SendTransaction(ctx, tx) Require(t, err) _, err := EnsureTxSucceeded(ctx, l2A.Client, tx) diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go index 6e1c6b0ab2..4c1fac707e 100644 --- a/system_tests/bloom_test.go +++ b/system_tests/bloom_test.go @@ -24,17 +24,17 @@ func TestBloom(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - builder := NewNodeBuilder(ctx).DefaultConfig(false, nil, nil) + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) builder.nodeConfig.RPC.BloomBitsBlocks = 256 builder.nodeConfig.RPC.BloomConfirms = 1 builder.takeOwnership = false - builder.Build(t) + cleanup := builder.Build(t) - defer builder.L2.Node.StopAndWait() + defer cleanup() - builder.L2.Info.GenerateAccount("User2") + builder.L2Info.GenerateAccount("User2") - ownerTxOpts := builder.L2.Info.GetDefaultTransactOpts("Owner", ctx) + ownerTxOpts := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) ownerTxOpts.Context = ctx _, simple := deploySimple(t, ctx, ownerTxOpts, builder.L2.Client) simpleABI, err := mocksgen.SimpleMetaData.GetAbi() diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 11d8a57cf5..c80044f9e2 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -62,31 +62,31 @@ type client = arbutil.L1Interface type TestClient struct { ctx context.Context - Info info Client *ethclient.Client Backend *eth.Ethereum Stack *node.Node Node *arbnode.Node + cleanup func() // having cleanup() field makes cleanup customizable from default cleanup methods after calling build } func NewTestClient(ctx context.Context) *TestClient { return &TestClient{ctx: ctx} } -func (tc *TestClient) SendSignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction) *types.Receipt { - return SendSignedTxViaL1(t, tc.ctx, tc.Info, tc.Client, l2Client, transaction) +func (tc *TestClient) SendSignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction, i info) *types.Receipt { + return SendSignedTxViaL1(t, tc.ctx, i, tc.Client, l2Client, transaction) } -func (tc *TestClient) SendUnsignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction) *types.Receipt { - return SendUnsignedTxViaL1(t, tc.ctx, tc.Info, tc.Client, l2Client, transaction) +func (tc *TestClient) SendUnsignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction, i info) *types.Receipt { + return SendUnsignedTxViaL1(t, tc.ctx, i, tc.Client, l2Client, transaction) } -func (tc *TestClient) TransferBalance(t *testing.T, from string, to string, amount *big.Int) (*types.Transaction, *types.Receipt) { - return TransferBalanceTo(t, from, tc.Info.GetAddress(to), amount, tc.Info, tc.Client, tc.ctx) +func (tc *TestClient) TransferBalance(t *testing.T, from string, to string, amount *big.Int, i info) (*types.Transaction, *types.Receipt) { + return TransferBalanceTo(t, from, i.GetAddress(to), amount, i, tc.Client, tc.ctx) } -func (tc *TestClient) TransferBalanceTo(t *testing.T, from string, to common.Address, amount *big.Int) (*types.Transaction, *types.Receipt) { - return TransferBalanceTo(t, from, to, amount, tc.Info, tc.Client, tc.ctx) +func (tc *TestClient) TransferBalanceTo(t *testing.T, from string, to common.Address, amount *big.Int, i info) (*types.Transaction, *types.Receipt) { + return TransferBalanceTo(t, from, to, amount, i, tc.Client, tc.ctx) } func (tc *TestClient) GetBalance(t *testing.T, account common.Address) *big.Int { @@ -108,11 +108,13 @@ func (tc *TestClient) DeploySimple(t *testing.T, auth bind.TransactOpts) (common type NodeBuilder struct { // NodeBuilder configuration ctx context.Context - Info info chainConfig *params.ChainConfig nodeConfig *arbnode.Config - stackConfig *node.Config cachingConfig *execution.CachingConfig + L1StackConfig *node.Config + L2StackConfig *node.Config + L1Info info + L2Info info // L1, L2 Node parameters isSequencer bool @@ -126,96 +128,122 @@ type NodeBuilder struct { // Created nodes L1 *TestClient L2 *TestClient + + // Created Blockchains + L1B *TestBlockchain + L2B *TestBlockchain } func NewNodeBuilder(ctx context.Context) *NodeBuilder { return &NodeBuilder{ctx: ctx} } -func (b *NodeBuilder) DefaultConfig(withL1 bool, n *arbnode.Config, c *params.ChainConfig) *NodeBuilder { +func (b *NodeBuilder) DefaultConfig(t *testing.T, withL1 bool) *NodeBuilder { // most used values across current tests are set here as default b.withL1 = withL1 if withL1 { b.isSequencer = true b.nodeConfig = arbnode.ConfigDefaultL1Test() - if n != nil { - b.nodeConfig = n - } - b.chainConfig = c } else { b.takeOwnership = true b.nodeConfig = arbnode.ConfigDefaultL2Test() - if n != nil { - b.nodeConfig = n - } - b.chainConfig = c } + b.chainConfig = params.ArbitrumDevTestChainConfig() + b.L1Info = NewL1TestInfo(t) + b.L2Info = NewArbTestInfo(t, b.chainConfig.ChainID) + b.L1StackConfig = stackConfigForTest(t) return b } -func (b *NodeBuilder) Build(t *testing.T) *NodeBuilder { +func (b *NodeBuilder) Build(t *testing.T) func() { if b.withL1 { l1, l2 := NewTestClient(b.ctx), NewTestClient(b.ctx) - l2.Info, l2.Node, l2.Client, l2.Stack, l1.Info, l1.Backend, l1.Client, l1.Stack = - createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.stackConfig, b.Info) + b.L2Info, l2.Node, l2.Client, l2.Stack, b.L1Info, l1.Backend, l1.Client, l1.Stack = + createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.L2StackConfig, b.L2Info) b.L1, b.L2 = l1, l2 + b.L1.cleanup = func() { requireClose(t, b.L1.Stack) } } else { l2 := NewTestClient(b.ctx) - l2.Info, l2.Node, l2.Client = - CreateTestL2WithConfig(t, b.ctx, b.Info, b.nodeConfig, b.takeOwnership) + b.L2Info, l2.Node, l2.Client = + CreateTestL2WithConfig(t, b.ctx, b.L2Info, b.nodeConfig, b.takeOwnership) b.L2 = l2 } - return b + b.L2.cleanup = func() { b.L2.Node.StopAndWait() } + return func() { + b.L2.cleanup() + if b.L1 != nil && b.L1.cleanup != nil { + b.L1.cleanup() + } + } } type SecondNodeParams map[string]interface{} -func (b *NodeBuilder) Build2ndNode(t *testing.T, params SecondNodeParams) *TestClient { - if b.L1 == nil { - t.Fatal("builder did not previously build a L1 Node") - } +func (b *NodeBuilder) Build2ndNode(t *testing.T, params SecondNodeParams) (*TestClient, func()) { if b.L2 == nil { t.Fatal("builder did not previously build a L2 Node") } + if _, ok := params["nodeConfig"]; !ok { + params["nodeConfig"] = b.nodeConfig + } else if params["nodeConfig"] == nil { + params["nodeConfig"] = arbnode.ConfigDefaultL1NonSequencerTest() + } if _, ok := params["dasConfig"]; ok { - nodeConf := arbnode.ConfigDefaultL1NonSequencerTest() if params["dasConfig"] == nil { - nodeConf.DataAvailability.Enable = false + params["nodeConfig"].(*arbnode.Config). + DataAvailability.Enable = false } else { - nodeConf.DataAvailability = *params["dasConfig"].(*das.DataAvailabilityConfig) + params["nodeConfig"].(*arbnode.Config). + DataAvailability = *params["dasConfig"].(*das.DataAvailabilityConfig) } - params["nodeConfig"] = nodeConf - } else if _, ok := params["nodeConfig"]; !ok { - params["nodeConfig"] = b.nodeConfig } if _, ok := params["stackConfig"]; !ok { - params["stackConfig"] = b.stackConfig + params["stackConfig"] = b.L2StackConfig + } + if _, ok := params["initData"]; !ok { + params["initData"] = &b.L2Info.ArbInitData } + var s *node.Node + var i info + if b.withL1 { + if b.L1 == nil { + t.Fatal("builder did not previously build a L1 Node") + } + s, i = b.L1.Stack, b.L1Info + } else { + if b.L1B == nil { + t.Fatal("builder did not previously build L1 Blockchain") + } + s, i = b.L1B.Stack, b.L1B.Info + } l2 := NewTestClient(b.ctx) l2.Client, l2.Node = - Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, b.L1.Stack, b.L1.Info, + Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, s, i, params["initData"].(*statetransfer.ArbosInitializationInfo), params["nodeConfig"].(*arbnode.Config), params["stackConfig"].(*node.Config)) - return l2 + l2.cleanup = func() { l2.Node.StopAndWait() } + return l2, func() { l2.cleanup() } } -func (b *NodeBuilder) BuildL1Blockchain(t *testing.T) *TestBlockchain { - l1 := NewTestBlockchain(b.ctx) - l1.Info, l1.Client, l1.Backend, l1.Stack = createTestL1BlockChain(t, b.Info) - return l1 +func (b *NodeBuilder) BuildL1Blockchain(t *testing.T) *NodeBuilder { + l1B := NewTestBlockchain(b.ctx) + l1B.Info, l1B.Client, l1B.Backend, l1B.Stack = createTestL1BlockChainWithConfig(t, b.L1Info, b.L1StackConfig) + b.L1B = l1B + return b } -func (b *NodeBuilder) BuildL2Blockchain(t *testing.T) *TestBlockchain { - l2 := NewTestBlockchain(b.ctx) - l2.Info, l2.Stack, l2.ChainDB, l2.NodeDB, l2.Blockchain = - createL2BlockChainWithStackConfig(t, b.Info, b.dataDir, b.chainConfig, b.initMessage, b.stackConfig, b.cachingConfig) - return l2 +func (b *NodeBuilder) BuildL2Blockchain(t *testing.T) *NodeBuilder { + l2B := NewTestBlockchain(b.ctx) + l2B.Info, l2B.Stack, l2B.ChainDB, l2B.NodeDB, l2B.Blockchain = + createL2BlockChainWithStackConfig(t, b.L2Info, b.dataDir, b.chainConfig, b.initMessage, b.L2StackConfig, b.cachingConfig) + b.L2B = l2B + return b } func (b *NodeBuilder) BridgeBalance(t *testing.T, account string, amount *big.Int) (*types.Transaction, *types.Receipt) { - return BridgeBalance(t, account, amount, b.L1.Info, b.L2.Info, b.L1.Client, b.L2.Client, b.ctx) + return BridgeBalance(t, account, amount, b.L1Info, b.L2Info, b.L1.Client, b.L2.Client, b.ctx) } type TestBlockchain struct { @@ -225,6 +253,7 @@ type TestBlockchain struct { ChainDB ethdb.Database NodeDB ethdb.Database Blockchain *core.BlockChain + Info info } func NewTestBlockchain(ctx context.Context) *TestBlockchain { diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index c5bb78e0d8..3be386f9c8 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -234,16 +234,14 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall defer cancel() initialBalance := new(big.Int).Lsh(big.NewInt(1), 200) - l1Info := NewL1TestInfo(t) - l1Info.GenerateGenesisAccount("deployer", initialBalance) - l1Info.GenerateGenesisAccount("asserter", initialBalance) - l1Info.GenerateGenesisAccount("challenger", initialBalance) - l1Info.GenerateGenesisAccount("sequencer", initialBalance) chainConfig := params.ArbitrumDevTestChainConfig() - builder := NewNodeBuilder(ctx).DefaultConfig(false, nil, chainConfig) - builder.Info = l1Info - tbL1 := builder.BuildL1Blockchain(t) + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + builder.L1Info.GenerateGenesisAccount("deployer", initialBalance) + builder.L1Info.GenerateGenesisAccount("asserter", initialBalance) + builder.L1Info.GenerateGenesisAccount("challenger", initialBalance) + builder.L1Info.GenerateGenesisAccount("sequencer", initialBalance) + tbL1 := builder.BuildL1Blockchain(t).L1B conf := arbnode.ConfigDefaultL1Test() conf.BlockValidator.Enable = false conf.BatchPoster.Enable = false @@ -271,8 +269,8 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall challengerBridgeAddr, challengerSeqInbox, challengerSeqInboxAddr := setupSequencerInboxStub(ctx, t, tbL1.Info, tbL1.Client, chainConfig) builder.initMessage = initMessage - builder.Info = nil - asserterL2tb := builder.BuildL2Blockchain(t) + builder.L2Info = nil + asserterL2tb := builder.BuildL2Blockchain(t).L2B asserterRollupAddresses.Bridge = asserterBridgeAddr asserterRollupAddresses.SequencerInbox = asserterSeqInboxAddr asserterL2, err := arbnode.CreateNode(ctx, asserterL2tb.Stack, asserterL2tb.ChainDB, asserterL2tb.NodeDB, NewFetcherFromConfig(conf), asserterL2tb.Blockchain, tbL1.Client, asserterRollupAddresses, nil, nil, nil, fatalErrChan) @@ -280,7 +278,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall err = asserterL2.Start(ctx) Require(t, err) - challengerL2tb := builder.BuildL2Blockchain(t) + challengerL2tb := builder.BuildL2Blockchain(t).L2B challengerRollupAddresses := *asserterRollupAddresses challengerRollupAddresses.Bridge = challengerBridgeAddr challengerRollupAddresses.SequencerInbox = challengerSeqInboxAddr From c7ba88c842d6aaf1f40ce00de2dda66d3c124c21 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Tue, 3 Oct 2023 15:18:14 -0500 Subject: [PATCH 07/54] handle defaults --- system_tests/common_test.go | 47 +++++++++--------------- system_tests/das_test.go | 4 +- system_tests/forwarder_test.go | 8 ++-- system_tests/full_challenge_impl_test.go | 2 + system_tests/ipc_test.go | 2 +- 5 files changed, 27 insertions(+), 36 deletions(-) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index c80044f9e2..cd922336cc 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -8,7 +8,6 @@ import ( "context" "encoding/hex" "encoding/json" - "fmt" "math/big" "net" "os" @@ -151,7 +150,9 @@ func (b *NodeBuilder) DefaultConfig(t *testing.T, withL1 bool) *NodeBuilder { b.chainConfig = params.ArbitrumDevTestChainConfig() b.L1Info = NewL1TestInfo(t) b.L2Info = NewArbTestInfo(t, b.chainConfig.ChainID) - b.L1StackConfig = stackConfigForTest(t) + b.dataDir = t.TempDir() + b.L1StackConfig = createStackConfigForTest(b.dataDir) + b.L2StackConfig = createStackConfigForTest(b.dataDir) return b } @@ -199,6 +200,8 @@ func (b *NodeBuilder) Build2ndNode(t *testing.T, params SecondNodeParams) (*Test } if _, ok := params["stackConfig"]; !ok { params["stackConfig"] = b.L2StackConfig + // should use different dataDir from the previously used ones + params["stackConfig"].(*node.Config).DataDir = t.TempDir() } if _, ok := params["initData"]; !ok { params["initData"] = &b.L2Info.ArbInitData @@ -495,33 +498,19 @@ func createTestL1BlockChain(t *testing.T, l1info info) (info, *ethclient.Client, return createTestL1BlockChainWithConfig(t, l1info, nil) } -func stackConfigForTest(t *testing.T) *node.Config { - stackConfig := node.DefaultConfig - stackConfig.HTTPPort = 0 - stackConfig.WSPort = 0 - stackConfig.UseLightweightKDF = true - stackConfig.P2P.ListenAddr = "" - stackConfig.P2P.NoDial = true - stackConfig.P2P.NoDiscovery = true - stackConfig.P2P.NAT = nil - stackConfig.DataDir = t.TempDir() - return &stackConfig -} - -func createDefaultStackForTest(dataDir string) (*node.Node, error) { +func createStackConfigForTest(dataDir string) *node.Config { stackConf := node.DefaultConfig - var err error stackConf.DataDir = dataDir + stackConf.UseLightweightKDF = true + stackConf.WSPort = 0 + stackConf.HTTPPort = 0 stackConf.HTTPHost = "" stackConf.HTTPModules = append(stackConf.HTTPModules, "eth") stackConf.P2P.NoDiscovery = true + stackConf.P2P.NoDial = true stackConf.P2P.ListenAddr = "" - - stack, err := node.New(&stackConf) - if err != nil { - return nil, fmt.Errorf("error creating protocol stack: %w", err) - } - return stack, nil + stackConf.P2P.NAT = nil + return &stackConf } func createTestValidationNode(t *testing.T, ctx context.Context, config *valnode.Config) (*valnode.ValidationNode, *node.Node) { @@ -597,7 +586,7 @@ func createTestL1BlockChainWithConfig(t *testing.T, l1info info, stackConfig *no l1info = NewL1TestInfo(t) } if stackConfig == nil { - stackConfig = stackConfigForTest(t) + stackConfig = createStackConfigForTest(t.TempDir()) } l1info.GenerateAccount("Faucet") @@ -718,12 +707,10 @@ func createL2BlockChainWithStackConfig( var stack *node.Node var err error if stackConfig == nil { - stack, err = createDefaultStackForTest(dataDir) - Require(t, err) - } else { - stack, err = node.New(stackConfig) - Require(t, err) + stackConfig = createStackConfigForTest(dataDir) } + stack, err = node.New(stackConfig) + Require(t, err) chainDb, err := stack.OpenDatabase("chaindb", 0, 0, "", false) Require(t, err) @@ -948,7 +935,7 @@ func Create2ndNodeWithConfig( l1client := ethclient.NewClient(l1rpcClient) if stackConfig == nil { - stackConfig = stackConfigForTest(t) + stackConfig = createStackConfigForTest(t.TempDir()) } l2stack, err := node.New(stackConfig) Require(t, err) diff --git a/system_tests/das_test.go b/system_tests/das_test.go index 8889d2d53d..f4c880632f 100644 --- a/system_tests/das_test.go +++ b/system_tests/das_test.go @@ -19,6 +19,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbnode" @@ -169,7 +170,8 @@ func TestDASRekey(t *testing.T) { // Restart the node on the new keyset against the new DAS server running on the same disk as the first with new keys - l2stackA, err := createDefaultStackForTest(nodeDir) + stackConfig := createStackConfigForTest(nodeDir) + l2stackA, err := node.New(stackConfig) Require(t, err) l2chainDb, err := l2stackA.OpenDatabase("chaindb", 0, 0, "", false) diff --git a/system_tests/forwarder_test.go b/system_tests/forwarder_test.go index 0a954719d8..8108ad2d16 100644 --- a/system_tests/forwarder_test.go +++ b/system_tests/forwarder_test.go @@ -35,7 +35,7 @@ func TestStaticForwarder(t *testing.T) { ipcPath := tmpPath(t, "test.ipc") ipcConfig := genericconf.IPCConfigDefault ipcConfig.Path = ipcPath - stackConfig := stackConfigForTest(t) + stackConfig := createStackConfigForTest(t.TempDir()) ipcConfig.Apply(stackConfig) nodeConfigA := arbnode.ConfigDefaultL1Test() nodeConfigA.BatchPoster.Enable = false @@ -97,7 +97,7 @@ func fallbackSequencer( ctx context.Context, t *testing.T, opts *fallbackSequencerOpts, ) (l2info info, currentNode *arbnode.Node, l2client *ethclient.Client, l1info info, l1backend *eth.Ethereum, l1client *ethclient.Client, l1stack *node.Node) { - stackConfig := stackConfigForTest(t) + stackConfig := createStackConfigForTest(t.TempDir()) ipcConfig := genericconf.IPCConfigDefault ipcConfig.Path = opts.ipcPath ipcConfig.Apply(stackConfig) @@ -118,7 +118,7 @@ func createForwardingNode( redisUrl string, fallbackPath string, ) (*ethclient.Client, *arbnode.Node) { - stackConfig := stackConfigForTest(t) + stackConfig := createStackConfigForTest(t.TempDir()) if ipcPath != "" { ipcConfig := genericconf.IPCConfigDefault ipcConfig.Path = ipcPath @@ -144,7 +144,7 @@ func createSequencer( ipcPath string, redisUrl string, ) (*ethclient.Client, *arbnode.Node) { - stackConfig := stackConfigForTest(t) + stackConfig := createStackConfigForTest(t.TempDir()) ipcConfig := genericconf.IPCConfigDefault ipcConfig.Path = ipcPath ipcConfig.Apply(stackConfig) diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index 3be386f9c8..ebe8cfc98a 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -270,6 +270,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall builder.initMessage = initMessage builder.L2Info = nil + builder.L2StackConfig.DataDir = t.TempDir() asserterL2tb := builder.BuildL2Blockchain(t).L2B asserterRollupAddresses.Bridge = asserterBridgeAddr asserterRollupAddresses.SequencerInbox = asserterSeqInboxAddr @@ -278,6 +279,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall err = asserterL2.Start(ctx) Require(t, err) + builder.L2StackConfig.DataDir = t.TempDir() challengerL2tb := builder.BuildL2Blockchain(t).L2B challengerRollupAddresses := *asserterRollupAddresses challengerRollupAddresses.Bridge = challengerBridgeAddr diff --git a/system_tests/ipc_test.go b/system_tests/ipc_test.go index 01ecf859d8..095f8e28aa 100644 --- a/system_tests/ipc_test.go +++ b/system_tests/ipc_test.go @@ -18,7 +18,7 @@ func TestIpcRpc(t *testing.T) { ipcConfig := genericconf.IPCConfigDefault ipcConfig.Path = ipcPath - stackConf := stackConfigForTest(t) + stackConf := createStackConfigForTest(t.TempDir()) ipcConfig.Apply(stackConf) ctx, cancel := context.WithCancel(context.Background()) From 098ca99b1306f231a73d7a377d9d3c1a04bb4414 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Wed, 4 Oct 2023 14:00:27 -0500 Subject: [PATCH 08/54] address PR comments --- system_tests/batch_poster_test.go | 10 +- system_tests/common_test.go | 121 ++++++++++------------- system_tests/full_challenge_impl_test.go | 52 +++++----- 3 files changed, 83 insertions(+), 100 deletions(-) diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index 4cb9271c54..ae7cb660f5 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -52,10 +52,7 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { defer cleanup() l1A, l2A := builder.L1, builder.L2 - params := make(SecondNodeParams) - params["nodeConfig"] = nil - params["dasConfig"] = nil - l2B, cleanup2nd := builder.Build2ndNode(t, params) + l2B, cleanup2nd := builder.Build2ndNode(t, &SecondNodeParams{}) defer cleanup2nd() builder.L2Info.GenerateAccount("User2") @@ -151,10 +148,7 @@ func TestBatchPosterLargeTx(t *testing.T) { defer cleanup() l2A := builder.L2 - params := make(SecondNodeParams) - params["nodeConfig"] = nil - params["dasConfig"] = nil - l2B, cleanup2nd := builder.Build2ndNode(t, params) + l2B, cleanup2nd := builder.Build2ndNode(t, &SecondNodeParams{}) defer cleanup2nd() data := make([]byte, 100000) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index cd922336cc..5349c85d7d 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -59,33 +59,48 @@ import ( type info = *BlockchainTestInfo type client = arbutil.L1Interface +type SecondNodeParams struct { + nodeConfig *arbnode.Config + stackConfig *node.Config + dasConfig *das.DataAvailabilityConfig + initData *statetransfer.ArbosInitializationInfo + useBuilderNodeConfig bool +} + type TestClient struct { ctx context.Context Client *ethclient.Client Backend *eth.Ethereum Stack *node.Node Node *arbnode.Node - cleanup func() // having cleanup() field makes cleanup customizable from default cleanup methods after calling build + + // Blockchain specific fields + ChainDB ethdb.Database + NodeDB ethdb.Database + Blockchain *core.BlockChain + + // having cleanup() field makes cleanup customizable from default cleanup methods after calling build + cleanup func() } func NewTestClient(ctx context.Context) *TestClient { return &TestClient{ctx: ctx} } -func (tc *TestClient) SendSignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction, i info) *types.Receipt { - return SendSignedTxViaL1(t, tc.ctx, i, tc.Client, l2Client, transaction) +func (tc *TestClient) SendSignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction, lInfo info) *types.Receipt { + return SendSignedTxViaL1(t, tc.ctx, lInfo, tc.Client, l2Client, transaction) } -func (tc *TestClient) SendUnsignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction, i info) *types.Receipt { - return SendUnsignedTxViaL1(t, tc.ctx, i, tc.Client, l2Client, transaction) +func (tc *TestClient) SendUnsignedTx(t *testing.T, l2Client *ethclient.Client, transaction *types.Transaction, lInfo info) *types.Receipt { + return SendUnsignedTxViaL1(t, tc.ctx, lInfo, tc.Client, l2Client, transaction) } -func (tc *TestClient) TransferBalance(t *testing.T, from string, to string, amount *big.Int, i info) (*types.Transaction, *types.Receipt) { - return TransferBalanceTo(t, from, i.GetAddress(to), amount, i, tc.Client, tc.ctx) +func (tc *TestClient) TransferBalance(t *testing.T, from string, to string, amount *big.Int, lInfo info) (*types.Transaction, *types.Receipt) { + return TransferBalanceTo(t, from, lInfo.GetAddress(to), amount, lInfo, tc.Client, tc.ctx) } -func (tc *TestClient) TransferBalanceTo(t *testing.T, from string, to common.Address, amount *big.Int, i info) (*types.Transaction, *types.Receipt) { - return TransferBalanceTo(t, from, to, amount, i, tc.Client, tc.ctx) +func (tc *TestClient) TransferBalanceTo(t *testing.T, from string, to common.Address, amount *big.Int, lInfo info) (*types.Transaction, *types.Receipt) { + return TransferBalanceTo(t, from, to, amount, lInfo, tc.Client, tc.ctx) } func (tc *TestClient) GetBalance(t *testing.T, account common.Address) *big.Int { @@ -110,8 +125,8 @@ type NodeBuilder struct { chainConfig *params.ChainConfig nodeConfig *arbnode.Config cachingConfig *execution.CachingConfig - L1StackConfig *node.Config - L2StackConfig *node.Config + l1StackConfig *node.Config + l2StackConfig *node.Config L1Info info L2Info info @@ -129,8 +144,8 @@ type NodeBuilder struct { L2 *TestClient // Created Blockchains - L1B *TestBlockchain - L2B *TestBlockchain + L1B *TestClient + L2B *TestClient } func NewNodeBuilder(ctx context.Context) *NodeBuilder { @@ -151,8 +166,8 @@ func (b *NodeBuilder) DefaultConfig(t *testing.T, withL1 bool) *NodeBuilder { b.L1Info = NewL1TestInfo(t) b.L2Info = NewArbTestInfo(t, b.chainConfig.ChainID) b.dataDir = t.TempDir() - b.L1StackConfig = createStackConfigForTest(b.dataDir) - b.L2StackConfig = createStackConfigForTest(b.dataDir) + b.l1StackConfig = createStackConfigForTest(b.dataDir) + b.l2StackConfig = createStackConfigForTest(b.dataDir) return b } @@ -160,7 +175,7 @@ func (b *NodeBuilder) Build(t *testing.T) func() { if b.withL1 { l1, l2 := NewTestClient(b.ctx), NewTestClient(b.ctx) b.L2Info, l2.Node, l2.Client, l2.Stack, b.L1Info, l1.Backend, l1.Client, l1.Stack = - createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.L2StackConfig, b.L2Info) + createTestNodeOnL1WithConfigImpl(t, b.ctx, b.isSequencer, b.nodeConfig, b.chainConfig, b.l2StackConfig, b.L2Info) b.L1, b.L2 = l1, l2 b.L1.cleanup = func() { requireClose(t, b.L1.Stack) } } else { @@ -178,69 +193,60 @@ func (b *NodeBuilder) Build(t *testing.T) func() { } } -type SecondNodeParams map[string]interface{} - -func (b *NodeBuilder) Build2ndNode(t *testing.T, params SecondNodeParams) (*TestClient, func()) { +func (b *NodeBuilder) Build2ndNode(t *testing.T, params *SecondNodeParams) (*TestClient, func()) { if b.L2 == nil { t.Fatal("builder did not previously build a L2 Node") } - if _, ok := params["nodeConfig"]; !ok { - params["nodeConfig"] = b.nodeConfig - } else if params["nodeConfig"] == nil { - params["nodeConfig"] = arbnode.ConfigDefaultL1NonSequencerTest() - } - if _, ok := params["dasConfig"]; ok { - if params["dasConfig"] == nil { - params["nodeConfig"].(*arbnode.Config). - DataAvailability.Enable = false + if params.nodeConfig == nil { + if params.useBuilderNodeConfig { + params.nodeConfig = b.nodeConfig } else { - params["nodeConfig"].(*arbnode.Config). - DataAvailability = *params["dasConfig"].(*das.DataAvailabilityConfig) + params.nodeConfig = arbnode.ConfigDefaultL1NonSequencerTest() } } - if _, ok := params["stackConfig"]; !ok { - params["stackConfig"] = b.L2StackConfig + if params.dasConfig != nil { + params.nodeConfig.DataAvailability = *params.dasConfig + } + if params.stackConfig == nil { + params.stackConfig = b.l2StackConfig // should use different dataDir from the previously used ones - params["stackConfig"].(*node.Config).DataDir = t.TempDir() + params.stackConfig.DataDir = t.TempDir() } - if _, ok := params["initData"]; !ok { - params["initData"] = &b.L2Info.ArbInitData + if params.initData == nil { + params.initData = &b.L2Info.ArbInitData } - var s *node.Node - var i info + var stack *node.Node + var l1Info info if b.withL1 { if b.L1 == nil { t.Fatal("builder did not previously build a L1 Node") } - s, i = b.L1.Stack, b.L1Info + stack, l1Info = b.L1.Stack, b.L1Info } else { if b.L1B == nil { t.Fatal("builder did not previously build L1 Blockchain") } - s, i = b.L1B.Stack, b.L1B.Info + stack, l1Info = b.L1B.Stack, b.L1Info } l2 := NewTestClient(b.ctx) l2.Client, l2.Node = - Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, s, i, - params["initData"].(*statetransfer.ArbosInitializationInfo), - params["nodeConfig"].(*arbnode.Config), - params["stackConfig"].(*node.Config)) + Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, stack, l1Info, params.initData, params.nodeConfig, params.stackConfig) l2.cleanup = func() { l2.Node.StopAndWait() } return l2, func() { l2.cleanup() } } func (b *NodeBuilder) BuildL1Blockchain(t *testing.T) *NodeBuilder { - l1B := NewTestBlockchain(b.ctx) - l1B.Info, l1B.Client, l1B.Backend, l1B.Stack = createTestL1BlockChainWithConfig(t, b.L1Info, b.L1StackConfig) + l1B := NewTestClient(b.ctx) + b.L1Info, l1B.Client, l1B.Backend, l1B.Stack = createTestL1BlockChainWithConfig(t, b.L1Info, b.l1StackConfig) b.L1B = l1B return b } func (b *NodeBuilder) BuildL2Blockchain(t *testing.T) *NodeBuilder { - l2B := NewTestBlockchain(b.ctx) - l2B.Info, l2B.Stack, l2B.ChainDB, l2B.NodeDB, l2B.Blockchain = - createL2BlockChainWithStackConfig(t, b.L2Info, b.dataDir, b.chainConfig, b.initMessage, b.L2StackConfig, b.cachingConfig) + l2B := NewTestClient(b.ctx) + b.L2Info, l2B.Stack, l2B.ChainDB, l2B.NodeDB, l2B.Blockchain = + createL2BlockChainWithStackConfig(t, b.L2Info, b.dataDir, b.chainConfig, b.initMessage, b.l2StackConfig, b.cachingConfig) b.L2B = l2B return b } @@ -249,25 +255,6 @@ func (b *NodeBuilder) BridgeBalance(t *testing.T, account string, amount *big.In return BridgeBalance(t, account, amount, b.L1Info, b.L2Info, b.L1.Client, b.L2.Client, b.ctx) } -type TestBlockchain struct { - TestClient - // Blockchain fields - chainConfig *params.ChainConfig - ChainDB ethdb.Database - NodeDB ethdb.Database - Blockchain *core.BlockChain - Info info -} - -func NewTestBlockchain(ctx context.Context) *TestBlockchain { - tc := NewTestClient(ctx) - return &TestBlockchain{TestClient: *tc} -} - -func (tb *TestBlockchain) Deploy(t *testing.T) (*chaininfo.RollupAddresses, *arbostypes.ParsedInitMessage) { - return DeployOnTestL1(t, tb.ctx, tb.Info, tb.Client, tb.chainConfig) -} - func SendWaitTestTransactions(t *testing.T, ctx context.Context, client client, txs []*types.Transaction) { t.Helper() for _, tx := range txs { diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index ebe8cfc98a..91ddcc2aa8 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -257,21 +257,21 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall configByValidationNode(t, conf, valStack) fatalErrChan := make(chan error, 10) - tbL1.chainConfig = chainConfig - asserterRollupAddresses, initMessage := tbL1.Deploy(t) + asserterRollupAddresses, initMessage := DeployOnTestL1(t, ctx, builder.L1Info, tbL1.Client, chainConfig) - deployerTxOpts := tbL1.Info.GetDefaultTransactOpts("deployer", ctx) - sequencerTxOpts := tbL1.Info.GetDefaultTransactOpts("sequencer", ctx) - asserterTxOpts := tbL1.Info.GetDefaultTransactOpts("asserter", ctx) - challengerTxOpts := tbL1.Info.GetDefaultTransactOpts("challenger", ctx) + deployerTxOpts := builder.L1Info.GetDefaultTransactOpts("deployer", ctx) + sequencerTxOpts := builder.L1Info.GetDefaultTransactOpts("sequencer", ctx) + asserterTxOpts := builder.L1Info.GetDefaultTransactOpts("asserter", ctx) + challengerTxOpts := builder.L1Info.GetDefaultTransactOpts("challenger", ctx) - asserterBridgeAddr, asserterSeqInbox, asserterSeqInboxAddr := setupSequencerInboxStub(ctx, t, tbL1.Info, tbL1.Client, chainConfig) - challengerBridgeAddr, challengerSeqInbox, challengerSeqInboxAddr := setupSequencerInboxStub(ctx, t, tbL1.Info, tbL1.Client, chainConfig) + asserterBridgeAddr, asserterSeqInbox, asserterSeqInboxAddr := setupSequencerInboxStub(ctx, t, builder.L1Info, tbL1.Client, chainConfig) + challengerBridgeAddr, challengerSeqInbox, challengerSeqInboxAddr := setupSequencerInboxStub(ctx, t, builder.L1Info, tbL1.Client, chainConfig) builder.initMessage = initMessage builder.L2Info = nil - builder.L2StackConfig.DataDir = t.TempDir() + builder.l2StackConfig.DataDir = t.TempDir() asserterL2tb := builder.BuildL2Blockchain(t).L2B + asserterL2tbInfo := builder.L2Info asserterRollupAddresses.Bridge = asserterBridgeAddr asserterRollupAddresses.SequencerInbox = asserterSeqInboxAddr asserterL2, err := arbnode.CreateNode(ctx, asserterL2tb.Stack, asserterL2tb.ChainDB, asserterL2tb.NodeDB, NewFetcherFromConfig(conf), asserterL2tb.Blockchain, tbL1.Client, asserterRollupAddresses, nil, nil, nil, fatalErrChan) @@ -279,8 +279,10 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall err = asserterL2.Start(ctx) Require(t, err) - builder.L2StackConfig.DataDir = t.TempDir() + builder.L2Info = nil + builder.l2StackConfig.DataDir = t.TempDir() challengerL2tb := builder.BuildL2Blockchain(t).L2B + challengerL2tbInfo := builder.L2Info challengerRollupAddresses := *asserterRollupAddresses challengerRollupAddresses.Bridge = challengerBridgeAddr challengerRollupAddresses.SequencerInbox = challengerSeqInboxAddr @@ -289,32 +291,32 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall err = challengerL2.Start(ctx) Require(t, err) - asserterL2tb.Info.GenerateAccount("Destination") - challengerL2tb.Info.SetFullAccountInfo("Destination", asserterL2tb.Info.GetInfoWithPrivKey("Destination")) + asserterL2tbInfo.GenerateAccount("Destination") + challengerL2tbInfo.SetFullAccountInfo("Destination", asserterL2tbInfo.GetInfoWithPrivKey("Destination")) if challengeMsgIdx < 1 || challengeMsgIdx > 3*makeBatch_MsgsPerBatch { Fatal(t, "challengeMsgIdx illegal") } // seqNum := common.Big2 - makeBatch(t, asserterL2, asserterL2tb.Info, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2tb.Info, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-1) + makeBatch(t, asserterL2, asserterL2tbInfo, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2tbInfo, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-1) // seqNum.Add(seqNum, common.Big1) - makeBatch(t, asserterL2, asserterL2tb.Info, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2tb.Info, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch-1) + makeBatch(t, asserterL2, asserterL2tbInfo, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2tbInfo, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch-1) // seqNum.Add(seqNum, common.Big1) - makeBatch(t, asserterL2, asserterL2tb.Info, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2tb.Info, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch*2-1) + makeBatch(t, asserterL2, asserterL2tbInfo, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2tbInfo, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch*2-1) trueSeqInboxAddr := challengerSeqInboxAddr trueDelayedBridge := challengerBridgeAddr - expectedWinner := tbL1.Info.GetAddress("challenger") + expectedWinner := builder.L1Info.GetAddress("challenger") if asserterIsCorrect { trueSeqInboxAddr = asserterSeqInboxAddr trueDelayedBridge = asserterBridgeAddr - expectedWinner = tbL1.Info.GetAddress("asserter") + expectedWinner = builder.L1Info.GetAddress("asserter") } ospEntry := DeployOneStepProofEntry(t, ctx, &deployerTxOpts, tbL1.Client) @@ -367,11 +369,11 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall asserterStartGlobalState, asserterEndGlobalState, numBlocks, - tbL1.Info.GetAddress("asserter"), - tbL1.Info.GetAddress("challenger"), + builder.L1Info.GetAddress("asserter"), + builder.L1Info.GetAddress("challenger"), ) - confirmLatestBlock(ctx, t, tbL1.Info, tbL1.Client) + confirmLatestBlock(ctx, t, builder.L1Info, tbL1.Client) asserterValidator, err := staker.NewStatelessBlockValidator(asserterL2.InboxReader, asserterL2.InboxTracker, asserterL2.TxStreamer, asserterL2.Execution.Recorder, asserterL2tb.NodeDB, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) if err != nil { @@ -416,7 +418,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall // Invoke a new L1 block, with a new timestamp, before estimating. time.Sleep(time.Second) SendWaitTestTransactions(t, ctx, tbL1.Client, []*types.Transaction{ - tbL1.Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + builder.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) if i%2 == 0 { @@ -460,7 +462,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall Fatal(t, err) } - confirmLatestBlock(ctx, t, tbL1.Info, tbL1.Client) + confirmLatestBlock(ctx, t, builder.L1Info, tbL1.Client) winner, err := resultReceiver.Winner(&bind.CallOpts{}) if err != nil { From 5da33e78aaafb57045507a7e8609cac496f34b34 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Wed, 4 Oct 2023 14:52:39 -0500 Subject: [PATCH 09/54] remove buildL1/L2 blockchain fns --- system_tests/common_test.go | 35 +--------- system_tests/full_challenge_impl_test.go | 87 +++++++++++------------- 2 files changed, 41 insertions(+), 81 deletions(-) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 5349c85d7d..a1d1a45788 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -74,11 +74,6 @@ type TestClient struct { Stack *node.Node Node *arbnode.Node - // Blockchain specific fields - ChainDB ethdb.Database - NodeDB ethdb.Database - Blockchain *core.BlockChain - // having cleanup() field makes cleanup customizable from default cleanup methods after calling build cleanup func() } @@ -124,28 +119,20 @@ type NodeBuilder struct { ctx context.Context chainConfig *params.ChainConfig nodeConfig *arbnode.Config - cachingConfig *execution.CachingConfig l1StackConfig *node.Config l2StackConfig *node.Config L1Info info L2Info info // L1, L2 Node parameters + dataDir string isSequencer bool takeOwnership bool withL1 bool - // Blockchain parameters - dataDir string - initMessage *arbostypes.ParsedInitMessage - // Created nodes L1 *TestClient L2 *TestClient - - // Created Blockchains - L1B *TestClient - L2B *TestClient } func NewNodeBuilder(ctx context.Context) *NodeBuilder { @@ -223,11 +210,6 @@ func (b *NodeBuilder) Build2ndNode(t *testing.T, params *SecondNodeParams) (*Tes t.Fatal("builder did not previously build a L1 Node") } stack, l1Info = b.L1.Stack, b.L1Info - } else { - if b.L1B == nil { - t.Fatal("builder did not previously build L1 Blockchain") - } - stack, l1Info = b.L1B.Stack, b.L1Info } l2 := NewTestClient(b.ctx) l2.Client, l2.Node = @@ -236,21 +218,6 @@ func (b *NodeBuilder) Build2ndNode(t *testing.T, params *SecondNodeParams) (*Tes return l2, func() { l2.cleanup() } } -func (b *NodeBuilder) BuildL1Blockchain(t *testing.T) *NodeBuilder { - l1B := NewTestClient(b.ctx) - b.L1Info, l1B.Client, l1B.Backend, l1B.Stack = createTestL1BlockChainWithConfig(t, b.L1Info, b.l1StackConfig) - b.L1B = l1B - return b -} - -func (b *NodeBuilder) BuildL2Blockchain(t *testing.T) *NodeBuilder { - l2B := NewTestClient(b.ctx) - b.L2Info, l2B.Stack, l2B.ChainDB, l2B.NodeDB, l2B.Blockchain = - createL2BlockChainWithStackConfig(t, b.L2Info, b.dataDir, b.chainConfig, b.initMessage, b.l2StackConfig, b.cachingConfig) - b.L2B = l2B - return b -} - func (b *NodeBuilder) BridgeBalance(t *testing.T, account string, amount *big.Int) (*types.Transaction, *types.Receipt) { return BridgeBalance(t, account, amount, b.L1Info, b.L2Info, b.L1.Client, b.L2.Client, b.ctx) } diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index 91ddcc2aa8..b64a655c3e 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -234,14 +234,14 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall defer cancel() initialBalance := new(big.Int).Lsh(big.NewInt(1), 200) + l1Info := NewL1TestInfo(t) + l1Info.GenerateGenesisAccount("deployer", initialBalance) + l1Info.GenerateGenesisAccount("asserter", initialBalance) + l1Info.GenerateGenesisAccount("challenger", initialBalance) + l1Info.GenerateGenesisAccount("sequencer", initialBalance) chainConfig := params.ArbitrumDevTestChainConfig() - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - builder.L1Info.GenerateGenesisAccount("deployer", initialBalance) - builder.L1Info.GenerateGenesisAccount("asserter", initialBalance) - builder.L1Info.GenerateGenesisAccount("challenger", initialBalance) - builder.L1Info.GenerateGenesisAccount("sequencer", initialBalance) - tbL1 := builder.BuildL1Blockchain(t).L1B + l1Info, l1Backend, _, _ := createTestL1BlockChain(t, l1Info) conf := arbnode.ConfigDefaultL1Test() conf.BlockValidator.Enable = false conf.BatchPoster.Enable = false @@ -257,68 +257,61 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall configByValidationNode(t, conf, valStack) fatalErrChan := make(chan error, 10) - asserterRollupAddresses, initMessage := DeployOnTestL1(t, ctx, builder.L1Info, tbL1.Client, chainConfig) + asserterRollupAddresses, initMessage := DeployOnTestL1(t, ctx, l1Info, l1Backend, chainConfig) - deployerTxOpts := builder.L1Info.GetDefaultTransactOpts("deployer", ctx) - sequencerTxOpts := builder.L1Info.GetDefaultTransactOpts("sequencer", ctx) - asserterTxOpts := builder.L1Info.GetDefaultTransactOpts("asserter", ctx) - challengerTxOpts := builder.L1Info.GetDefaultTransactOpts("challenger", ctx) + deployerTxOpts := l1Info.GetDefaultTransactOpts("deployer", ctx) + sequencerTxOpts := l1Info.GetDefaultTransactOpts("sequencer", ctx) + asserterTxOpts := l1Info.GetDefaultTransactOpts("asserter", ctx) + challengerTxOpts := l1Info.GetDefaultTransactOpts("challenger", ctx) - asserterBridgeAddr, asserterSeqInbox, asserterSeqInboxAddr := setupSequencerInboxStub(ctx, t, builder.L1Info, tbL1.Client, chainConfig) - challengerBridgeAddr, challengerSeqInbox, challengerSeqInboxAddr := setupSequencerInboxStub(ctx, t, builder.L1Info, tbL1.Client, chainConfig) + asserterBridgeAddr, asserterSeqInbox, asserterSeqInboxAddr := setupSequencerInboxStub(ctx, t, l1Info, l1Backend, chainConfig) + challengerBridgeAddr, challengerSeqInbox, challengerSeqInboxAddr := setupSequencerInboxStub(ctx, t, l1Info, l1Backend, chainConfig) - builder.initMessage = initMessage - builder.L2Info = nil - builder.l2StackConfig.DataDir = t.TempDir() - asserterL2tb := builder.BuildL2Blockchain(t).L2B - asserterL2tbInfo := builder.L2Info + asserterL2Info, asserterL2Stack, asserterL2ChainDb, asserterL2ArbDb, asserterL2Blockchain := createL2BlockChainWithStackConfig(t, nil, "", chainConfig, initMessage, nil, nil) asserterRollupAddresses.Bridge = asserterBridgeAddr asserterRollupAddresses.SequencerInbox = asserterSeqInboxAddr - asserterL2, err := arbnode.CreateNode(ctx, asserterL2tb.Stack, asserterL2tb.ChainDB, asserterL2tb.NodeDB, NewFetcherFromConfig(conf), asserterL2tb.Blockchain, tbL1.Client, asserterRollupAddresses, nil, nil, nil, fatalErrChan) + asserterL2, err := arbnode.CreateNode(ctx, asserterL2Stack, asserterL2ChainDb, asserterL2ArbDb, NewFetcherFromConfig(conf), asserterL2Blockchain, l1Backend, asserterRollupAddresses, nil, nil, nil, fatalErrChan) Require(t, err) err = asserterL2.Start(ctx) Require(t, err) - builder.L2Info = nil - builder.l2StackConfig.DataDir = t.TempDir() - challengerL2tb := builder.BuildL2Blockchain(t).L2B - challengerL2tbInfo := builder.L2Info + challengerL2Info, challengerL2Stack, challengerL2ChainDb, challengerL2ArbDb, challengerL2Blockchain := createL2BlockChainWithStackConfig(t, nil, "", chainConfig, initMessage, nil, nil) challengerRollupAddresses := *asserterRollupAddresses challengerRollupAddresses.Bridge = challengerBridgeAddr challengerRollupAddresses.SequencerInbox = challengerSeqInboxAddr - challengerL2, err := arbnode.CreateNode(ctx, challengerL2tb.Stack, challengerL2tb.ChainDB, challengerL2tb.NodeDB, NewFetcherFromConfig(conf), challengerL2tb.Blockchain, tbL1.Client, &challengerRollupAddresses, nil, nil, nil, fatalErrChan) + challengerL2, err := arbnode.CreateNode(ctx, challengerL2Stack, challengerL2ChainDb, challengerL2ArbDb, NewFetcherFromConfig(conf), challengerL2Blockchain, l1Backend, &challengerRollupAddresses, nil, nil, nil, fatalErrChan) Require(t, err) err = challengerL2.Start(ctx) Require(t, err) - asserterL2tbInfo.GenerateAccount("Destination") - challengerL2tbInfo.SetFullAccountInfo("Destination", asserterL2tbInfo.GetInfoWithPrivKey("Destination")) + asserterL2Info.GenerateAccount("Destination") + challengerL2Info.SetFullAccountInfo("Destination", asserterL2Info.GetInfoWithPrivKey("Destination")) if challengeMsgIdx < 1 || challengeMsgIdx > 3*makeBatch_MsgsPerBatch { Fatal(t, "challengeMsgIdx illegal") } // seqNum := common.Big2 - makeBatch(t, asserterL2, asserterL2tbInfo, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2tbInfo, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-1) + makeBatch(t, asserterL2, asserterL2Info, l1Backend, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2Info, l1Backend, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-1) // seqNum.Add(seqNum, common.Big1) - makeBatch(t, asserterL2, asserterL2tbInfo, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2tbInfo, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch-1) + makeBatch(t, asserterL2, asserterL2Info, l1Backend, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2Info, l1Backend, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch-1) // seqNum.Add(seqNum, common.Big1) - makeBatch(t, asserterL2, asserterL2tbInfo, tbL1.Client, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) - makeBatch(t, challengerL2, challengerL2tbInfo, tbL1.Client, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch*2-1) + makeBatch(t, asserterL2, asserterL2Info, l1Backend, &sequencerTxOpts, asserterSeqInbox, asserterSeqInboxAddr, -1) + makeBatch(t, challengerL2, challengerL2Info, l1Backend, &sequencerTxOpts, challengerSeqInbox, challengerSeqInboxAddr, challengeMsgIdx-makeBatch_MsgsPerBatch*2-1) trueSeqInboxAddr := challengerSeqInboxAddr trueDelayedBridge := challengerBridgeAddr - expectedWinner := builder.L1Info.GetAddress("challenger") + expectedWinner := l1Info.GetAddress("challenger") if asserterIsCorrect { trueSeqInboxAddr = asserterSeqInboxAddr trueDelayedBridge = asserterBridgeAddr - expectedWinner = builder.L1Info.GetAddress("asserter") + expectedWinner = l1Info.GetAddress("asserter") } - ospEntry := DeployOneStepProofEntry(t, ctx, &deployerTxOpts, tbL1.Client) + ospEntry := DeployOneStepProofEntry(t, ctx, &deployerTxOpts, l1Backend) locator, err := server_common.NewMachineLocator("") if err != nil { @@ -361,7 +354,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall t, ctx, &deployerTxOpts, - tbL1.Client, + l1Backend, ospEntry, trueSeqInboxAddr, trueDelayedBridge, @@ -369,13 +362,13 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall asserterStartGlobalState, asserterEndGlobalState, numBlocks, - builder.L1Info.GetAddress("asserter"), - builder.L1Info.GetAddress("challenger"), + l1Info.GetAddress("asserter"), + l1Info.GetAddress("challenger"), ) - confirmLatestBlock(ctx, t, builder.L1Info, tbL1.Client) + confirmLatestBlock(ctx, t, l1Info, l1Backend) - asserterValidator, err := staker.NewStatelessBlockValidator(asserterL2.InboxReader, asserterL2.InboxTracker, asserterL2.TxStreamer, asserterL2.Execution.Recorder, asserterL2tb.NodeDB, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) + asserterValidator, err := staker.NewStatelessBlockValidator(asserterL2.InboxReader, asserterL2.InboxTracker, asserterL2.TxStreamer, asserterL2.Execution.Recorder, asserterL2ArbDb, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) if err != nil { Fatal(t, err) } @@ -388,11 +381,11 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall Fatal(t, err) } defer asserterValidator.Stop() - asserterManager, err := staker.NewChallengeManager(ctx, tbL1.Client, &asserterTxOpts, asserterTxOpts.From, challengeManagerAddr, 1, asserterValidator, 0, 0) + asserterManager, err := staker.NewChallengeManager(ctx, l1Backend, &asserterTxOpts, asserterTxOpts.From, challengeManagerAddr, 1, asserterValidator, 0, 0) if err != nil { Fatal(t, err) } - challengerValidator, err := staker.NewStatelessBlockValidator(challengerL2.InboxReader, challengerL2.InboxTracker, challengerL2.TxStreamer, challengerL2.Execution.Recorder, challengerL2tb.NodeDB, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) + challengerValidator, err := staker.NewStatelessBlockValidator(challengerL2.InboxReader, challengerL2.InboxTracker, challengerL2.TxStreamer, challengerL2.Execution.Recorder, challengerL2ArbDb, nil, StaticFetcherFrom(t, &conf.BlockValidator), valStack) if err != nil { Fatal(t, err) } @@ -405,7 +398,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall Fatal(t, err) } defer challengerValidator.Stop() - challengerManager, err := staker.NewChallengeManager(ctx, tbL1.Client, &challengerTxOpts, challengerTxOpts.From, challengeManagerAddr, 1, challengerValidator, 0, 0) + challengerManager, err := staker.NewChallengeManager(ctx, l1Backend, &challengerTxOpts, challengerTxOpts.From, challengeManagerAddr, 1, challengerValidator, 0, 0) if err != nil { Fatal(t, err) } @@ -417,8 +410,8 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall // This might make gas estimation undersestimate next move. // Invoke a new L1 block, with a new timestamp, before estimating. time.Sleep(time.Second) - SendWaitTestTransactions(t, ctx, tbL1.Client, []*types.Transaction{ - builder.L1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + SendWaitTestTransactions(t, ctx, l1Backend, []*types.Transaction{ + l1Info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), }) if i%2 == 0 { @@ -453,7 +446,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall } } - _, err = EnsureTxSucceeded(ctx, tbL1.Client, tx) + _, err = EnsureTxSucceeded(ctx, l1Backend, tx) if err != nil { if !currentCorrect && strings.Contains(err.Error(), "BAD_SEQINBOX_MESSAGE") { t.Log("challenge complete! Tx failed as expected:", err) @@ -462,7 +455,7 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool, useStubs bool, chall Fatal(t, err) } - confirmLatestBlock(ctx, t, builder.L1Info, tbL1.Client) + confirmLatestBlock(ctx, t, l1Info, l1Backend) winner, err := resultReceiver.Winner(&bind.CallOpts{}) if err != nil { From 31c048b41c528105cd6891d2061232b5bd00054a Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Wed, 4 Oct 2023 15:58:26 -0500 Subject: [PATCH 10/54] refactor Build2ndNode --- system_tests/common_test.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index cc205862a1..01e44dc808 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -187,6 +187,9 @@ func (b *NodeBuilder) Build2ndNode(t *testing.T, params *SecondNodeParams) (*Tes if b.L2 == nil { t.Fatal("builder did not previously build a L2 Node") } + if b.withL1 && b.L1 == nil { + t.Fatal("builder did not previously build a L1 Node") + } if params.nodeConfig == nil { if params.useBuilderNodeConfig { params.nodeConfig = b.nodeConfig @@ -209,17 +212,9 @@ func (b *NodeBuilder) Build2ndNode(t *testing.T, params *SecondNodeParams) (*Tes params.execConfig = b.execConfig } - var stack *node.Node - var l1Info info - if b.withL1 { - if b.L1 == nil { - t.Fatal("builder did not previously build a L1 Node") - } - stack, l1Info = b.L1.Stack, b.L1Info - } l2 := NewTestClient(b.ctx) l2.Client, l2.Node = - Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, stack, l1Info, params.initData, params.nodeConfig, params.execConfig, params.stackConfig) + Create2ndNodeWithConfig(t, b.ctx, b.L2.Node, b.L1.Stack, b.L1Info, params.initData, params.nodeConfig, params.execConfig, params.stackConfig) l2.cleanup = func() { l2.Node.StopAndWait() } return l2, func() { l2.cleanup() } } From 2fb5546c484b6e4ee81828629d53aab13863a455 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Thu, 5 Oct 2023 10:14:30 -0500 Subject: [PATCH 11/54] add ExecutionNode to TestClient --- system_tests/bloom_test.go | 3 +-- system_tests/common_test.go | 12 +++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go index bb284ad5e8..9079fd35f1 100644 --- a/system_tests/bloom_test.go +++ b/system_tests/bloom_test.go @@ -81,9 +81,8 @@ func TestBloom(t *testing.T) { t.Log("counts: ", i, "/", countsNum) } } - execNode := getExecNode(t, builder.L2.Node) for { - sectionSize, sectionNum := execNode.Backend.APIBackend().BloomStatus() + sectionSize, sectionNum := builder.L2.ExecNode.Backend.APIBackend().BloomStatus() if sectionSize != 256 { Fatal(t, "unexpected section size: ", sectionSize) } diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 01e44dc808..80537b7d04 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -69,11 +69,12 @@ type SecondNodeParams struct { } type TestClient struct { - ctx context.Context - Client *ethclient.Client - Backend *eth.Ethereum - Stack *node.Node - Node *arbnode.Node + ctx context.Context + Client *ethclient.Client + Backend *eth.Ethereum + Stack *node.Node + Node *arbnode.Node + ExecNode *gethexec.ExecutionNode // having cleanup() field makes cleanup customizable from default cleanup methods after calling build cleanup func() @@ -174,6 +175,7 @@ func (b *NodeBuilder) Build(t *testing.T) func() { CreateTestL2WithConfig(t, b.ctx, b.L2Info, b.nodeConfig, b.execConfig, b.takeOwnership) b.L2 = l2 } + b.L2.ExecNode = getExecNode(t, b.L2.Node) b.L2.cleanup = func() { b.L2.Node.StopAndWait() } return func() { b.L2.cleanup() From 812bda8b3abff2f690d9ebf8495d1d1ef08d3b11 Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Tue, 10 Oct 2023 15:32:18 -0700 Subject: [PATCH 12/54] Add new metrics for inbox The following metrics are added to track the state currently read from inbox: * arb_inbox_batch * arb_inbox_message --- arbnode/inbox_tracker.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arbnode/inbox_tracker.go b/arbnode/inbox_tracker.go index c82e45fbee..414a9c94a7 100644 --- a/arbnode/inbox_tracker.go +++ b/arbnode/inbox_tracker.go @@ -15,7 +15,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" + "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbstate" "github.com/offchainlabs/nitro/arbutil" @@ -24,6 +26,11 @@ import ( "github.com/offchainlabs/nitro/util/containers" ) +var ( + inboxBatchGauge = metrics.NewRegisteredGauge("arb/inbox/batch", nil) + inboxMessageGauge = metrics.NewRegisteredGauge("arb/inbox/message", nil) +) + type InboxTracker struct { db ethdb.Database txStreamer *TransactionStreamer @@ -676,6 +683,8 @@ func (t *InboxTracker) AddSequencerBatches(ctx context.Context, client arbutil.L "l1Block", latestL1Block, "l1Timestamp", time.Unix(int64(latestTimestamp), 0), ) + inboxBatchGauge.Update(int64(pos)) + inboxMessageGauge.Update(int64(newMessageCount)) if t.validator != nil { t.validator.ReorgToBatchCount(startPos) From a778d5748b857595c1b055d5b8a1b8b630b3377c Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Tue, 10 Oct 2023 16:57:30 -0700 Subject: [PATCH 13/54] Update metric names * arb_inbox_latest_batch * arb_inbox_latest_batch_message --- arbnode/inbox_tracker.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arbnode/inbox_tracker.go b/arbnode/inbox_tracker.go index 414a9c94a7..72e4ba2887 100644 --- a/arbnode/inbox_tracker.go +++ b/arbnode/inbox_tracker.go @@ -27,8 +27,8 @@ import ( ) var ( - inboxBatchGauge = metrics.NewRegisteredGauge("arb/inbox/batch", nil) - inboxMessageGauge = metrics.NewRegisteredGauge("arb/inbox/message", nil) + inboxLatestBatchGauge = metrics.NewRegisteredGauge("arb/inbox/latest/batch", nil) + inboxLatestBatchMessageGauge = metrics.NewRegisteredGauge("arb/inbox/latest/batch/message", nil) ) type InboxTracker struct { @@ -683,8 +683,8 @@ func (t *InboxTracker) AddSequencerBatches(ctx context.Context, client arbutil.L "l1Block", latestL1Block, "l1Timestamp", time.Unix(int64(latestTimestamp), 0), ) - inboxBatchGauge.Update(int64(pos)) - inboxMessageGauge.Update(int64(newMessageCount)) + inboxLatestBatchGauge.Update(int64(pos)) + inboxLatestBatchMessageGauge.Update(int64(newMessageCount)) if t.validator != nil { t.validator.ReorgToBatchCount(startPos) From 4579b57d1cc52d9f9a6d643d3e9f6cbce8a0cdad Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Wed, 11 Oct 2023 12:38:57 +0200 Subject: [PATCH 14/54] Use options struct for batchposter to make callsites more readable --- arbnode/batch_poster.go | 60 ++++++++++++++++++------------- arbnode/node.go | 12 ++++++- system_tests/batch_poster_test.go | 16 ++++++++- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index acf655e4cf..77a839b70a 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -217,68 +217,80 @@ var TestBatchPosterConfig = BatchPosterConfig{ L1BlockBoundBypass: time.Hour, } -func NewBatchPoster(ctx context.Context, dataPosterDB ethdb.Database, l1Reader *headerreader.HeaderReader, inbox *InboxTracker, streamer *TransactionStreamer, syncMonitor *SyncMonitor, config BatchPosterConfigFetcher, deployInfo *chaininfo.RollupAddresses, transactOpts *bind.TransactOpts, daWriter das.DataAvailabilityServiceWriter) (*BatchPoster, error) { - seqInbox, err := bridgegen.NewSequencerInbox(deployInfo.SequencerInbox, l1Reader.Client()) +type BatchPosterOpts struct { + DataPosterDB ethdb.Database + L1Reader *headerreader.HeaderReader + Inbox *InboxTracker + Streamer *TransactionStreamer + SyncMonitor *SyncMonitor + Config BatchPosterConfigFetcher + DeployInfo *chaininfo.RollupAddresses + TransactOpts *bind.TransactOpts + DAWriter das.DataAvailabilityServiceWriter +} + +func NewBatchPoster(ctx context.Context, opts *BatchPosterOpts) (*BatchPoster, error) { + seqInbox, err := bridgegen.NewSequencerInbox(opts.DeployInfo.SequencerInbox, opts.L1Reader.Client()) if err != nil { return nil, err } - bridge, err := bridgegen.NewBridge(deployInfo.Bridge, l1Reader.Client()) + bridge, err := bridgegen.NewBridge(opts.DeployInfo.Bridge, opts.L1Reader.Client()) if err != nil { return nil, err } - if err = config().Validate(); err != nil { + if err = opts.Config().Validate(); err != nil { return nil, err } seqInboxABI, err := bridgegen.SequencerInboxMetaData.GetAbi() if err != nil { return nil, err } - redisClient, err := redisutil.RedisClientFromURL(config().RedisUrl) + redisClient, err := redisutil.RedisClientFromURL(opts.Config().RedisUrl) if err != nil { return nil, err } redisLockConfigFetcher := func() *redislock.SimpleCfg { - simpleRedisLockConfig := config().RedisLock + simpleRedisLockConfig := opts.Config().RedisLock simpleRedisLockConfig.Key = batchPosterSimpleRedisLockKey return &simpleRedisLockConfig } - redisLock, err := redislock.NewSimple(redisClient, redisLockConfigFetcher, func() bool { return syncMonitor.Synced() }) + redisLock, err := redislock.NewSimple(redisClient, redisLockConfigFetcher, func() bool { return opts.SyncMonitor.Synced() }) if err != nil { return nil, err } b := &BatchPoster{ - l1Reader: l1Reader, - inbox: inbox, - streamer: streamer, - syncMonitor: syncMonitor, - config: config, + l1Reader: opts.L1Reader, + inbox: opts.Inbox, + streamer: opts.Streamer, + syncMonitor: opts.SyncMonitor, + config: opts.Config, bridge: bridge, seqInbox: seqInbox, seqInboxABI: seqInboxABI, - seqInboxAddr: deployInfo.SequencerInbox, - gasRefunderAddr: config().gasRefunder, - bridgeAddr: deployInfo.Bridge, - daWriter: daWriter, + seqInboxAddr: opts.DeployInfo.SequencerInbox, + gasRefunderAddr: opts.Config().gasRefunder, + bridgeAddr: opts.DeployInfo.Bridge, + daWriter: opts.DAWriter, redisLock: redisLock, accessList: func(SequencerInboxAccs, AfterDelayedMessagesRead int) types.AccessList { return AccessList(&AccessListOpts{ - SequencerInboxAddr: deployInfo.SequencerInbox, - DataPosterAddr: transactOpts.From, - BridgeAddr: deployInfo.Bridge, - GasRefunderAddr: config().gasRefunder, + SequencerInboxAddr: opts.DeployInfo.SequencerInbox, + DataPosterAddr: opts.TransactOpts.From, + BridgeAddr: opts.DeployInfo.Bridge, + GasRefunderAddr: opts.Config().gasRefunder, SequencerInboxAccs: SequencerInboxAccs, AfterDelayedMessagesRead: AfterDelayedMessagesRead, }) }, } dataPosterConfigFetcher := func() *dataposter.DataPosterConfig { - return &config().DataPoster + return &(opts.Config().DataPoster) } b.dataPoster, err = dataposter.NewDataPoster(ctx, &dataposter.DataPosterOpts{ - Database: dataPosterDB, - HeaderReader: l1Reader, - Auth: transactOpts, + Database: opts.DataPosterDB, + HeaderReader: opts.L1Reader, + Auth: opts.TransactOpts, RedisClient: redisClient, RedisLock: redisLock, Config: dataPosterConfigFetcher, diff --git a/arbnode/node.go b/arbnode/node.go index 5d06264b65..4fbfaf4bb2 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -842,7 +842,17 @@ func createNodeImpl( if txOptsBatchPoster == nil { return nil, errors.New("batchposter, but no TxOpts") } - batchPoster, err = NewBatchPoster(ctx, rawdb.NewTable(arbDb, storage.BatchPosterPrefix), l1Reader, inboxTracker, txStreamer, syncMonitor, func() *BatchPosterConfig { return &configFetcher.Get().BatchPoster }, deployInfo, txOptsBatchPoster, daWriter) + batchPoster, err = NewBatchPoster(ctx, &BatchPosterOpts{ + DataPosterDB: rawdb.NewTable(arbDb, storage.BatchPosterPrefix), + L1Reader: l1Reader, + Inbox: inboxTracker, + Streamer: txStreamer, + SyncMonitor: syncMonitor, + Config: func() *BatchPosterConfig { return &configFetcher.Get().BatchPoster }, + DeployInfo: deployInfo, + TransactOpts: txOptsBatchPoster, + DAWriter: daWriter, + }) if err != nil { return nil, err } diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index 1d705c05ac..4ea2a16c07 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -83,7 +83,19 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { for i := 0; i < parallelBatchPosters; i++ { // Make a copy of the batch poster config so NewBatchPoster calling Validate() on it doesn't race batchPosterConfig := conf.BatchPoster - batchPoster, err := arbnode.NewBatchPoster(ctx, nil, nodeA.L1Reader, nodeA.InboxTracker, nodeA.TxStreamer, nodeA.SyncMonitor, func() *arbnode.BatchPosterConfig { return &batchPosterConfig }, nodeA.DeployInfo, &seqTxOpts, nil) + batchPoster, err := arbnode.NewBatchPoster(ctx, + &arbnode.BatchPosterOpts{ + DataPosterDB: nil, + L1Reader: nodeA.L1Reader, + Inbox: nodeA.InboxTracker, + Streamer: nodeA.TxStreamer, + SyncMonitor: nodeA.SyncMonitor, + Config: func() *arbnode.BatchPosterConfig { return &batchPosterConfig }, + DeployInfo: nodeA.DeployInfo, + TransactOpts: &seqTxOpts, + DAWriter: nil, + }, + ) Require(t, err) batchPoster.Start(ctx) defer batchPoster.StopAndWait() @@ -104,6 +116,8 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { } } + // TODO: factor this out in separate test case and skip it or delete this + // code entirely. // I've locally confirmed that this passes when the clique period is set to 1. // However, setting the clique period to 1 slows everything else (including the L1 deployment for this test) down to a crawl. if false { From cbd5ca85c793881c4dca2faa21d138f364ccc8e8 Mon Sep 17 00:00:00 2001 From: GoodDaisy <90915921+GoodDaisy@users.noreply.github.com> Date: Wed, 11 Oct 2023 21:59:27 +0800 Subject: [PATCH 15/54] fix typos --- arbitrator/prover/test-cases/go/main.go | 2 +- arbnode/dataposter/data_poster.go | 2 +- arbos/addressSet/addressSet_test.go | 2 +- arbos/l1pricing/l1pricing.go | 2 +- arbos/tx_processor.go | 2 +- arbos/util/transfer.go | 4 ++-- cmd/seq-coordinator-manager/seq-coordinator-manager.go | 2 +- precompiles/precompile.go | 2 +- system_tests/seq_coordinator_test.go | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arbitrator/prover/test-cases/go/main.go b/arbitrator/prover/test-cases/go/main.go index 79541e48b0..afed870fea 100644 --- a/arbitrator/prover/test-cases/go/main.go +++ b/arbitrator/prover/test-cases/go/main.go @@ -89,7 +89,7 @@ func main() { verified, err = MerkleSample(data, -1) if err != nil { if verified { - panic("succeded to verify proof invalid") + panic("succeeded to verify proof invalid") } } diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index 912c6c9afc..01827881d9 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -39,7 +39,7 @@ import ( // is initialized with specified sender/signer and keeps nonce of that address // as it posts transactions. // Transactions are also saved in the queue when it's being sent, and when -// persistant storage is used for the queue, after restarting the node +// persistent storage is used for the queue, after restarting the node // dataposter will pick up where it left. // DataPoster must be RLP serializable and deserializable type DataPoster struct { diff --git a/arbos/addressSet/addressSet_test.go b/arbos/addressSet/addressSet_test.go index bc3b46e80f..7d06c74f0b 100644 --- a/arbos/addressSet/addressSet_test.go +++ b/arbos/addressSet/addressSet_test.go @@ -270,7 +270,7 @@ func TestRectifyMapping(t *testing.T) { // Non owner's should not be able to call RectifyMapping err := aset.RectifyMapping(testhelpers.RandomAddress()) if err == nil { - Fail(t, "RectifyMapping was succesfully called by non owner") + Fail(t, "RectifyMapping was successfully called by non owner") } // Corrupt the list and verify if RectifyMapping fixes it diff --git a/arbos/l1pricing/l1pricing.go b/arbos/l1pricing/l1pricing.go index e506f76907..142efbeafe 100644 --- a/arbos/l1pricing/l1pricing.go +++ b/arbos/l1pricing/l1pricing.go @@ -75,7 +75,7 @@ const ( InitialInertia = 10 InitialPerUnitReward = 10 InitialPerBatchGasCostV6 = 100_000 - InitialPerBatchGasCostV12 = 210_000 // overriden as part of the upgrade + InitialPerBatchGasCostV12 = 210_000 // overridden as part of the upgrade ) // one minute at 100000 bytes / sec diff --git a/arbos/tx_processor.go b/arbos/tx_processor.go index 3572042a09..4eeffc679e 100644 --- a/arbos/tx_processor.go +++ b/arbos/tx_processor.go @@ -483,7 +483,7 @@ func (p *TxProcessor) EndTxHook(gasLeft uint64, success bool) { err = util.TransferBalance(&refundFrom, &inner.RefundTo, toRefundAddr, p.evm, scenario, "refund") if err != nil { // Normally the network fee address should be holding any collected fees. - // However, in theory, they could've been transfered out during the redeem attempt. + // However, in theory, they could've been transferred out during the redeem attempt. // If the network fee address doesn't have the necessary balance, log an error and don't give a refund. log.Error(errLog, "err", err, "feeAddress", refundFrom) } diff --git a/arbos/util/transfer.go b/arbos/util/transfer.go index da3243fd8d..3a81181200 100644 --- a/arbos/util/transfer.go +++ b/arbos/util/transfer.go @@ -15,7 +15,7 @@ import ( "github.com/offchainlabs/nitro/util/arbmath" ) -// TransferBalance represents a balance change occuring aside from a call. +// TransferBalance represents a balance change occurring aside from a call. // While most uses will be transfers, setting `from` or `to` to nil will mint or burn funds, respectively. func TransferBalance( from, to *common.Address, @@ -39,7 +39,7 @@ func TransferBalance( } if tracer := evm.Config.Tracer; tracer != nil { if evm.Depth() != 0 && scenario != TracingDuringEVM { - // A non-zero depth implies this transfer is occuring inside EVM execution + // A non-zero depth implies this transfer is occurring inside EVM execution log.Error("Tracing scenario mismatch", "scenario", scenario, "depth", evm.Depth()) return errors.New("tracing scenario mismatch") } diff --git a/cmd/seq-coordinator-manager/seq-coordinator-manager.go b/cmd/seq-coordinator-manager/seq-coordinator-manager.go index a0123a9123..07bc26af2c 100644 --- a/cmd/seq-coordinator-manager/seq-coordinator-manager.go +++ b/cmd/seq-coordinator-manager/seq-coordinator-manager.go @@ -27,7 +27,7 @@ var addSeqForm = tview.NewForm() var priorityForm = tview.NewForm() var nonPriorityForm = tview.NewForm() -// Sequencer coordinator managment UI data store +// Sequencer coordinator management UI data store type manager struct { redisCoordinator *rediscoordinator.RedisCoordinator prioritiesSet map[string]bool diff --git a/precompiles/precompile.go b/precompiles/precompile.go index 77102a95b9..ded90ebdf7 100644 --- a/precompiles/precompile.go +++ b/precompiles/precompile.go @@ -366,7 +366,7 @@ func MakePrecompile(metadata *bind.MetaData, implementer interface{}) (addr, *Pr emitCost := gascost(args) cost := emitCost[0].Interface().(uint64) //nolint:errcheck if !emitCost[1].IsNil() { - // an error occured during gascost() + // an error occurred during gascost() return []reflect.Value{emitCost[1]} } if err := callerCtx.Burn(cost); err != nil { diff --git a/system_tests/seq_coordinator_test.go b/system_tests/seq_coordinator_test.go index 881e3b2658..a213c366cf 100644 --- a/system_tests/seq_coordinator_test.go +++ b/system_tests/seq_coordinator_test.go @@ -197,7 +197,7 @@ func TestRedisSeqCoordinatorPriorities(t *testing.T) { } } - // sequencing suceeds only on the leder + // sequencing succeeds only on the leder for i := arbutil.MessageIndex(0); i < messagesPerRound; i++ { if sequencer := trySequencingEverywhere(); sequencer != currentSequencer { Fatal(t, "unexpected sequencer. expected: ", currentSequencer, " got ", sequencer) From 92f6404cd77ab859d63611d6c6c17db7e9f3c568 Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Wed, 11 Oct 2023 16:07:27 +0200 Subject: [PATCH 16/54] add triedb race test --- system_tests/triedb_race_test.go | 83 ++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 system_tests/triedb_race_test.go diff --git a/system_tests/triedb_race_test.go b/system_tests/triedb_race_test.go new file mode 100644 index 0000000000..468997b181 --- /dev/null +++ b/system_tests/triedb_race_test.go @@ -0,0 +1,83 @@ +package arbtest + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/arbitrum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/util/testhelpers" +) + +func TestTrieDBCommitRace(t *testing.T) { + _ = testhelpers.InitTestLog(t, log.LvlError) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nodeConfig := arbnode.ConfigDefaultL1Test() + nodeConfig.RPC.MaxRecreateStateDepth = arbitrum.InfiniteMaxRecreateStateDepth + nodeConfig.Sequencer.MaxBlockSpeed = 0 + nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 + nodeConfig.Caching.Archive = true + nodeConfig.Caching.BlockCount = 127 + nodeConfig.Caching.BlockAge = 0 + nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 127 + nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 + l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, nil) + cancel = func() { + defer requireClose(t, l1stack) + defer node.StopAndWait() + } + defer cancel() + l2info.GenerateAccount("User2") + bc := node.Execution.Backend.ArbInterface().BlockChain() + + var wg sync.WaitGroup + quit := make(chan struct{}) + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + default: + TransferBalance(t, "Faucet", "User2", common.Big1, l2info, l2client, ctx) + case <-quit: + return + } + } + }() + api := node.Execution.Backend.APIBackend() + blockNumber := 1 + for i := 0; i < 5; i++ { + var roots []common.Hash + for len(roots) < 1024 { + select { + default: + block, err := api.BlockByNumber(ctx, rpc.BlockNumber(blockNumber)) + if err == nil && block != nil { + root := block.Root() + if statedb, err := bc.StateAt(root); err == nil { + err := statedb.Database().TrieDB().Reference(root, common.Hash{}) + Require(t, err) + roots = append(roots, root) + } + blockNumber += 1 + } + case <-quit: + return + } + } + t.Log("dereferencing...") + for _, root := range roots { + err := bc.TrieDB().Dereference(root) + Require(t, err) + time.Sleep(1) + } + } + close(quit) + wg.Wait() +} From 4800578c7de4da406adcf0dbac99d722284b84dd Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Wed, 11 Oct 2023 16:08:13 +0200 Subject: [PATCH 17/54] improve test configs in recreatestate_rpc_test --- system_tests/recreatestate_rpc_test.go | 28 ++++++++++---------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/system_tests/recreatestate_rpc_test.go b/system_tests/recreatestate_rpc_test.go index dbf68c8479..33dde05781 100644 --- a/system_tests/recreatestate_rpc_test.go +++ b/system_tests/recreatestate_rpc_test.go @@ -95,9 +95,8 @@ func TestRecreateStateForRPCNoDepthLimit(t *testing.T) { nodeConfig.Sequencer.MaxBlockSpeed = 0 nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 nodeConfig.Caching.Archive = true - // disable caching of states in BlockChain.stateCache + // disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there nodeConfig.Caching.TrieCleanCache = 0 - nodeConfig.Caching.TrieDirtyCache = 0 nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0 nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 _, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32) @@ -119,7 +118,6 @@ func TestRecreateStateForRPCNoDepthLimit(t *testing.T) { if balance.Cmp(expectedBalance) != 0 { Fatal(t, "unexpected balance result for last block, want: ", expectedBalance, " have: ", balance) } - } func TestRecreateStateForRPCBigEnoughDepthLimit(t *testing.T) { @@ -131,9 +129,8 @@ func TestRecreateStateForRPCBigEnoughDepthLimit(t *testing.T) { nodeConfig.Sequencer.MaxBlockSpeed = 0 nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 nodeConfig.Caching.Archive = true - // disable caching of states in BlockChain.stateCache + // disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there nodeConfig.Caching.TrieCleanCache = 0 - nodeConfig.Caching.TrieDirtyCache = 0 nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0 nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 _, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32) @@ -166,9 +163,8 @@ func TestRecreateStateForRPCDepthLimitExceeded(t *testing.T) { nodeConfig.Sequencer.MaxBlockSpeed = 0 nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 nodeConfig.Caching.Archive = true - // disable caching of states in BlockChain.stateCache + // disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there nodeConfig.Caching.TrieCleanCache = 0 - nodeConfig.Caching.TrieDirtyCache = 0 nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0 nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 _, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32) @@ -201,9 +197,8 @@ func TestRecreateStateForRPCMissingBlockParent(t *testing.T) { nodeConfig.Sequencer.MaxBlockSpeed = 0 nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 nodeConfig.Caching.Archive = true - // disable caching of states in BlockChain.stateCache + // disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there nodeConfig.Caching.TrieCleanCache = 0 - nodeConfig.Caching.TrieDirtyCache = 0 nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0 nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 _, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, headerCacheLimit+5) @@ -247,9 +242,8 @@ func TestRecreateStateForRPCBeyondGenesis(t *testing.T) { nodeConfig.Sequencer.MaxBlockSpeed = 0 nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 nodeConfig.Caching.Archive = true - // disable caching of states in BlockChain.stateCache + // disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there nodeConfig.Caching.TrieCleanCache = 0 - nodeConfig.Caching.TrieDirtyCache = 0 nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0 nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 _, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32) @@ -283,9 +277,9 @@ func TestRecreateStateForRPCBlockNotFoundWhileRecreating(t *testing.T) { nodeConfig.Sequencer.MaxBlockSpeed = 0 nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 nodeConfig.Caching.Archive = true - // disable caching of states in BlockChain.stateCache + // disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there nodeConfig.Caching.TrieCleanCache = 0 - nodeConfig.Caching.TrieDirtyCache = 0 + nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0 nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 _, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, blockCacheLimit+4) @@ -412,6 +406,9 @@ func testSkippingSavingStateAndRecreatingAfterRestart(t *testing.T, cacheConfig } for i := genesis + 1; i <= genesis+uint64(txCount); i += i % 10 { _, err = client.BalanceAt(ctx, GetTestAddressForAccountName(t, "User2"), new(big.Int).SetUint64(i)) + if err != nil { + t.Log("skipBlocks:", skipBlocks, "skipGas:", skipGas) + } Require(t, err) } @@ -425,10 +422,7 @@ func testSkippingSavingStateAndRecreatingAfterRestart(t *testing.T, cacheConfig func TestSkippingSavingStateAndRecreatingAfterRestart(t *testing.T) { cacheConfig := execution.DefaultCachingConfig cacheConfig.Archive = true - // disable caching of states in BlockChain.stateCache - cacheConfig.TrieCleanCache = 0 - cacheConfig.TrieDirtyCache = 0 - // test defaults + //// test defaults testSkippingSavingStateAndRecreatingAfterRestart(t, &cacheConfig, 512) cacheConfig.MaxNumberOfBlocksToSkipStateSaving = 127 From ebfd141982e5f79867a4c5a398524d0c78ecbebb Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Wed, 11 Oct 2023 16:41:53 +0200 Subject: [PATCH 18/54] fix triedb_race_test --- system_tests/triedb_race_test.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/system_tests/triedb_race_test.go b/system_tests/triedb_race_test.go index 468997b181..8174a9b6a2 100644 --- a/system_tests/triedb_race_test.go +++ b/system_tests/triedb_race_test.go @@ -10,7 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" - "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/util/testhelpers" ) @@ -18,23 +18,24 @@ func TestTrieDBCommitRace(t *testing.T) { _ = testhelpers.InitTestLog(t, log.LvlError) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodeConfig := arbnode.ConfigDefaultL1Test() - nodeConfig.RPC.MaxRecreateStateDepth = arbitrum.InfiniteMaxRecreateStateDepth - nodeConfig.Sequencer.MaxBlockSpeed = 0 - nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 - nodeConfig.Caching.Archive = true - nodeConfig.Caching.BlockCount = 127 - nodeConfig.Caching.BlockAge = 0 - nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 127 - nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 - l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nodeConfig, nil, nil) + execConfig := gethexec.ConfigDefaultTest() + execConfig.RPC.MaxRecreateStateDepth = arbitrum.InfiniteMaxRecreateStateDepth + execConfig.Sequencer.MaxBlockSpeed = 0 + execConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110 + execConfig.Caching.Archive = true + execConfig.Caching.BlockCount = 127 + execConfig.Caching.BlockAge = 0 + execConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 127 + execConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0 + l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, execConfig, nil, nil) cancel = func() { defer requireClose(t, l1stack) defer node.StopAndWait() } defer cancel() + execNode := getExecNode(t, node) l2info.GenerateAccount("User2") - bc := node.Execution.Backend.ArbInterface().BlockChain() + bc := execNode.Backend.ArbInterface().BlockChain() var wg sync.WaitGroup quit := make(chan struct{}) @@ -50,7 +51,7 @@ func TestTrieDBCommitRace(t *testing.T) { } } }() - api := node.Execution.Backend.APIBackend() + api := execNode.Backend.APIBackend() blockNumber := 1 for i := 0; i < 5; i++ { var roots []common.Hash From 89a44158d0cff35e2fe692f0a18dbc2fe30e0b39 Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Wed, 11 Oct 2023 16:55:11 +0200 Subject: [PATCH 19/54] set ParentChainReader default config in gethexec.ConfigDefaultTest --- execution/gethexec/node.go | 1 + 1 file changed, 1 insertion(+) diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 1068dda967..8b3874729e 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -109,6 +109,7 @@ func ConfigDefaultTest() *Config { config := ConfigDefault config.Sequencer = TestSequencerConfig config.ForwardingTarget = "null" + config.ParentChainReader = headerreader.TestConfig _ = config.Validate() From df6d1dc4816db2c29b3c825db64381a7af075006 Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Wed, 11 Oct 2023 17:03:23 +0200 Subject: [PATCH 20/54] update geth to version with triedb race fix --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index b4221631e1..7c1903db73 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit b4221631e1e5eac86f01582bd74234e3c0f7f5c7 +Subproject commit 7c1903db73f835fab4cc39f963ceeda6da46d44e From e935a24b545d1573a15d0e6714d19c0062a507a1 Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Wed, 11 Oct 2023 18:58:07 +0200 Subject: [PATCH 21/54] update geth --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index 7c1903db73..89540b1440 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 7c1903db73f835fab4cc39f963ceeda6da46d44e +Subproject commit 89540b1440179a851e5e29672a700851c4237d83 From 5e75c666aaee3c10ffbdcbafa372718258824585 Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Wed, 11 Oct 2023 19:09:51 +0200 Subject: [PATCH 22/54] update geth --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index 89540b1440..3573250ade 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 89540b1440179a851e5e29672a700851c4237d83 +Subproject commit 3573250adec48511a0bc45647061ed6d25c4ae35 From 98c6562b3a79306687117c1267b11e94cb7c71ce Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Wed, 11 Oct 2023 13:40:21 -0500 Subject: [PATCH 23/54] Add --dev flag to easily start up a local L2-only dev chain --- cmd/nitro/init.go | 3 ++- cmd/nitro/nitro.go | 5 ++++- cmd/util/confighelpers/configuration.go | 22 ++++++++++++++++++++++ execution/gethexec/node.go | 3 ++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/cmd/nitro/init.go b/cmd/nitro/init.go index bef0f83d1f..f874b5d71e 100644 --- a/cmd/nitro/init.go +++ b/cmd/nitro/init.go @@ -10,6 +10,7 @@ import ( "fmt" "math/big" "os" + "reflect" "regexp" "runtime" "strings" @@ -296,7 +297,7 @@ func findImportantRoots(ctx context.Context, chainDb ethdb.Database, stack *node return nil, err } if initConfig.Prune == "validator" { - if l1Client == nil { + if l1Client == nil || reflect.ValueOf(l1Client).IsNil() { return nil, errors.New("an L1 connection is required for validator pruning") } callOpts := bind.CallOpts{ diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 285cc3fe86..80b21e5ebe 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -61,7 +61,10 @@ import ( ) func printSampleUsage(name string) { - fmt.Printf("Sample usage: %s --help \n", name) + fmt.Printf("Sample usage: %s [OPTIONS] \n\n", name) + fmt.Printf("Options:\n") + fmt.Printf(" --help\n") + fmt.Printf(" --dev: Start a default L2-only dev chain\n") } func addUnlockWallet(accountManager *accounts.Manager, walletConf *genericconf.WalletConfig) (common.Address, error) { diff --git a/cmd/util/confighelpers/configuration.go b/cmd/util/confighelpers/configuration.go index 18a2b10f2f..6116a492c9 100644 --- a/cmd/util/confighelpers/configuration.go +++ b/cmd/util/confighelpers/configuration.go @@ -138,10 +138,32 @@ func PrintErrorAndExit(err error, usage func(string)) { } } +func devFlagArgs() []string { + args := []string{ + "--init.dev-init", + "--init.dev-init-address", "0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E", + "--node.dangerous.no-l1-listener", + "--node.parent-chain-reader.enable=false", + "--parent-chain.id=1337", + "--chain.id=412346", + "--persistent.chain", "/tmp/dev-test", + "--node.sequencer", + "--node.dangerous.no-sequencer-coordinator", + "--node.staker.enable=false", + "--init.empty=false", + "--http.port", "8547", + "--http.addr", "127.0.0.1", + } + return args +} + func BeginCommonParse(f *flag.FlagSet, args []string) (*koanf.Koanf, error) { for _, arg := range args { if arg == "--version" || arg == "-v" { return nil, ErrVersion + } else if arg == "--dev" { + args = devFlagArgs() + break } } if err := f.Parse(args); err != nil { diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 1068dda967..d7f7a41309 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "reflect" "sync/atomic" "testing" @@ -149,7 +150,7 @@ func CreateExecutionNode( var sequencer *Sequencer var parentChainReader *headerreader.HeaderReader - if l1client != nil { + if l1client != nil && !reflect.ValueOf(l1client).IsNil() { arbSys, _ := precompilesgen.NewArbSys(types.ArbSysAddress, l1client) parentChainReader, err = headerreader.New(ctx, l1client, func() *headerreader.Config { return &configFetcher().ParentChainReader }, arbSys) if err != nil { From 36b722ce7db3a2a7b44c78bd47dea912eba24049 Mon Sep 17 00:00:00 2001 From: Maciej Kulawik Date: Thu, 12 Oct 2023 12:47:37 +0200 Subject: [PATCH 24/54] update geth --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index 3573250ade..202caf5bf9 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 3573250adec48511a0bc45647061ed6d25c4ae35 +Subproject commit 202caf5bf944835ef78b4d7c4ba8b48bdc54d65d From c234d50685f9cb967b9d91ba027f175751b38419 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Thu, 12 Oct 2023 15:08:38 -0500 Subject: [PATCH 25/54] Add a CI step to start up a dev test node --- .github/workflows/docker.yml | 8 ++++++++ .github/workflows/waitForNitro.sh | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100755 .github/workflows/waitForNitro.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6192f65a4e..fe27e6c186 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -59,6 +59,14 @@ jobs: cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max + - name: Start nitro-testnode and wait for rpc to come up + shell: bash + run: | + .nitro-testnode/test-node.bash --init --dev & + jobid=$! + ${{ github.action_path }}/waitForNitro.sh + kill -s SIGKILL $jobid + - name: Print WAVM module root id: module-root run: | diff --git a/.github/workflows/waitForNitro.sh b/.github/workflows/waitForNitro.sh new file mode 100755 index 0000000000..1c71298dde --- /dev/null +++ b/.github/workflows/waitForNitro.sh @@ -0,0 +1,10 @@ +# poll the nitro endpoint until we get a 0 return code +while true +do + curl -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":45678,"method":"eth_chainId","params":[]}' 'http://localhost:8547' + if [ "$?" -eq "0" ]; then + exit 0 + else + sleep 10 + fi +done \ No newline at end of file From 338fe2103f8241b4c00c3dcf3c512de0abd986c3 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Thu, 12 Oct 2023 14:23:15 -0600 Subject: [PATCH 26/54] Don't ignore target/machines for Docker builds --- .dockerignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.dockerignore b/.dockerignore index 05cec369d9..763aeda1be 100644 --- a/.dockerignore +++ b/.dockerignore @@ -13,6 +13,9 @@ solgen/go **/node_modules target/**/* +!target/machines +!target/machines/* +!target/machines/**/* brotli/buildfiles/**/* # these are used by environment outside the docker: From 0c4241a704448525bc94e12715d15c224cc454ed Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Thu, 12 Oct 2023 15:35:01 -0500 Subject: [PATCH 27/54] fix issue --- .github/workflows/docker.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index fe27e6c186..028790fd86 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -62,9 +62,11 @@ jobs: - name: Start nitro-testnode and wait for rpc to come up shell: bash run: | - .nitro-testnode/test-node.bash --init --dev & + cd nitro-testnode + ./test-node.bash --init --dev & jobid=$! - ${{ github.action_path }}/waitForNitro.sh + cd .. + ${{ github.workspace }}/.github/workflows/waitForNitro.sh kill -s SIGKILL $jobid - name: Print WAVM module root From 5f00974dc4997d9c84ca3700b9e9164ed7aec380 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Thu, 12 Oct 2023 16:02:33 -0500 Subject: [PATCH 28/54] use run-nitro-test-node action impl --- .github/workflows/docker.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 028790fd86..d4062cdd47 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -59,16 +59,17 @@ jobs: cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - - name: Start nitro-testnode and wait for rpc to come up + - name: Start background nitro-testnode and wait for rpc to come up shell: bash run: | cd nitro-testnode ./test-node.bash --init --dev & - jobid=$! - cd .. + + - name: Wait for rpc to come up + shell: bash + run: | ${{ github.workspace }}/.github/workflows/waitForNitro.sh - kill -s SIGKILL $jobid - + - name: Print WAVM module root id: module-root run: | From 7c717797b225c7685790167e183437bad1c95dd9 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Thu, 12 Oct 2023 16:57:03 -0500 Subject: [PATCH 29/54] change image name --- .github/workflows/docker.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d4062cdd47..8e439633dd 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -45,7 +45,7 @@ jobs: target: nitro-node push: true context: . - tags: localhost:5000/nitro-node:latest + tags: nitro-node:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max @@ -55,11 +55,11 @@ jobs: target: nitro-node-dev push: true context: . - tags: localhost:5000/nitro-node-dev:latest + tags: nitro-node-dev:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - - name: Start background nitro-testnode and wait for rpc to come up + - name: Start background nitro-testnode shell: bash run: | cd nitro-testnode @@ -75,7 +75,7 @@ jobs: run: | # Unfortunately, `docker cp` seems to always result in a "permission denied" # We work around this by piping a tarball through stdout - docker run --rm --entrypoint tar localhost:5000/nitro-node-dev:latest -cf - target/machines/latest | tar xf - + docker run --rm --entrypoint tar nitro-node-dev:latest -cf - target/machines/latest | tar xf - module_root="$(cat "target/machines/latest/module-root.txt")" echo "name=module-root=$module_root" >> $GITHUB_STATE echo -e "\x1b[1;34mWAVM module root:\x1b[0m $module_root" From c9c731ee008685157532f46c277b6a683b1ebab4 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Thu, 12 Oct 2023 17:52:00 -0500 Subject: [PATCH 30/54] update nitro-testnode pin --- .github/workflows/docker.yml | 7 ++++--- nitro-testnode | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8e439633dd..a6f9c4b9a5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -45,7 +45,7 @@ jobs: target: nitro-node push: true context: . - tags: nitro-node:latest + tags: localhost:5000/nitro-node:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max @@ -55,13 +55,14 @@ jobs: target: nitro-node-dev push: true context: . - tags: nitro-node-dev:latest + tags: localhost:5000/nitro-node-dev:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - name: Start background nitro-testnode shell: bash run: | + docker tag localhost:5000/nitro-node-dev:latest nitro-node-dev-testnode:latest cd nitro-testnode ./test-node.bash --init --dev & @@ -75,7 +76,7 @@ jobs: run: | # Unfortunately, `docker cp` seems to always result in a "permission denied" # We work around this by piping a tarball through stdout - docker run --rm --entrypoint tar nitro-node-dev:latest -cf - target/machines/latest | tar xf - + docker run --rm --entrypoint tar localhost:5000/nitro-node-dev:latest -cf - target/machines/latest | tar xf - module_root="$(cat "target/machines/latest/module-root.txt")" echo "name=module-root=$module_root" >> $GITHUB_STATE echo -e "\x1b[1;34mWAVM module root:\x1b[0m $module_root" diff --git a/nitro-testnode b/nitro-testnode index 7ad12c0f1b..86fc5f6275 160000 --- a/nitro-testnode +++ b/nitro-testnode @@ -1 +1 @@ -Subproject commit 7ad12c0f1be75a72c7360d5258e0090f8225594e +Subproject commit 86fc5f6275c0269b5a5105bf78c1627d03b0ef9e From a809568398360015c35f2c8eb2a0676251c27a88 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Fri, 13 Oct 2023 09:33:48 -0500 Subject: [PATCH 31/54] init only --- .github/workflows/docker.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a6f9c4b9a5..ce92be513b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -62,9 +62,8 @@ jobs: - name: Start background nitro-testnode shell: bash run: | - docker tag localhost:5000/nitro-node-dev:latest nitro-node-dev-testnode:latest cd nitro-testnode - ./test-node.bash --init --dev & + ./test-node.bash --init & - name: Wait for rpc to come up shell: bash From a619d43bbd811870a5c08156959d1689343c1f6f Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Fri, 13 Oct 2023 16:55:09 +0200 Subject: [PATCH 32/54] Implement external signer for dataposter --- arbnode/batch_poster.go | 9 +- arbnode/dataposter/data_poster.go | 153 +++++++++++++------ arbnode/dataposter/dataposter_test.go | 210 ++++++++++++++++++++++++++ arbnode/maintenance.go | 1 + arbnode/node.go | 1 + arbnode/redislock/redis.go | 2 +- broadcastclient/broadcastclient.go | 2 +- cmd/genericconf/config.go | 2 +- cmd/genericconf/server.go | 6 +- cmd/nitro/config_test.go | 19 +++ cmd/nitro/nitro.go | 7 + cmd/rpcsvr/main.go | 134 ++++++++++++++++ das/das.go | 1 + execution/gethexec/node.go | 1 + staker/block_validator.go | 2 +- staker/staker.go | 2 +- util/headerreader/header_reader.go | 1 + util/signature/sign_verify.go | 6 + util/signature/sign_verify_test.go | 6 +- util/signature/verifier.go | 2 +- 20 files changed, 507 insertions(+), 60 deletions(-) create mode 100644 cmd/rpcsvr/main.go diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index 76ff8e6a50..acf655e4cf 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" + "github.com/offchainlabs/nitro/arbnode/dataposter" "github.com/offchainlabs/nitro/arbnode/dataposter/storage" "github.com/offchainlabs/nitro/arbnode/redislock" @@ -47,6 +48,7 @@ import ( var ( batchPosterWalletBalance = metrics.NewRegisteredGaugeFloat64("arb/batchposter/wallet/balanceether", nil) batchPosterGasRefunderBalance = metrics.NewRegisteredGaugeFloat64("arb/batchposter/gasrefunder/balanceether", nil) + batchPosterSimpleRedisLockKey = "node.batch-poster.redis-lock.simple-lock-key" ) type batchPosterPosition struct { @@ -166,7 +168,7 @@ func BatchPosterConfigAddOptions(prefix string, f *pflag.FlagSet) { f.String(prefix+".l1-block-bound", DefaultBatchPosterConfig.L1BlockBound, "only post messages to batches when they're within the max future block/timestamp as of this L1 block tag (\"safe\", \"finalized\", \"latest\", or \"ignore\" to ignore this check)") f.Duration(prefix+".l1-block-bound-bypass", DefaultBatchPosterConfig.L1BlockBoundBypass, "post batches even if not within the layer 1 future bounds if we're within this margin of the max delay") redislock.AddConfigOptions(prefix+".redis-lock", f) - dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f) + dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f, dataposter.DefaultDataPosterConfig) genericconf.WalletConfigAddOptions(prefix+".parent-chain-wallet", f, DefaultBatchPosterConfig.ParentChainWallet.Pathname) } @@ -187,6 +189,7 @@ var DefaultBatchPosterConfig = BatchPosterConfig{ ParentChainWallet: DefaultBatchPosterL1WalletConfig, L1BlockBound: "", L1BlockBoundBypass: time.Hour, + RedisLock: redislock.DefaultCfg, } var DefaultBatchPosterL1WalletConfig = genericconf.WalletConfig{ @@ -235,7 +238,9 @@ func NewBatchPoster(ctx context.Context, dataPosterDB ethdb.Database, l1Reader * return nil, err } redisLockConfigFetcher := func() *redislock.SimpleCfg { - return &config().RedisLock + simpleRedisLockConfig := config().RedisLock + simpleRedisLockConfig.Key = batchPosterSimpleRedisLockKey + return &simpleRedisLockConfig } redisLock, err := redislock.NewSimple(redisClient, redisLockConfigFetcher, func() bool { return syncMonitor.Synced() }) if err != nil { diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index 91bdf39d5f..c8a673ec9c 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" @@ -47,7 +48,7 @@ type DataPoster struct { headerReader *headerreader.HeaderReader client arbutil.L1Interface sender common.Address - signer bind.SignerFn + signer signerFn redisLock AttemptLocker config ConfigFetcher replacementTimes []time.Duration @@ -66,6 +67,11 @@ type DataPoster struct { errorCount map[uint64]int // number of consecutive intermittent errors rbf-ing or sending, per nonce } +// signerFn is a signer function callback when a contract requires a method to +// sign the transaction before submission. +// This can be local or external, hence the context parameter. +type signerFn func(context.Context, common.Address, *types.Transaction) (*types.Transaction, error) + type AttemptLocker interface { AttemptLock(context.Context) bool } @@ -103,13 +109,13 @@ type DataPosterOpts struct { } func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, error) { - initConfig := opts.Config() - replacementTimes, err := parseReplacementTimes(initConfig.ReplacementTimes) + cfg := opts.Config() + replacementTimes, err := parseReplacementTimes(cfg.ReplacementTimes) if err != nil { return nil, err } - if opts.HeaderReader.IsParentChainArbitrum() && !initConfig.UseNoOpStorage { - initConfig.UseNoOpStorage = true + if opts.HeaderReader.IsParentChainArbitrum() && !cfg.UseNoOpStorage { + cfg.UseNoOpStorage = true log.Info("Disabling data poster storage, as parent chain appears to be an Arbitrum chain without a mempool") } encF := func() storage.EncoderDecoderInterface { @@ -120,17 +126,17 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro } var queue QueueStorage switch { - case initConfig.UseNoOpStorage: + case cfg.UseNoOpStorage: queue = &noop.Storage{} case opts.RedisClient != nil: var err error - queue, err = redisstorage.NewStorage(opts.RedisClient, opts.RedisKey, &initConfig.RedisSigner, encF) + queue, err = redisstorage.NewStorage(opts.RedisClient, opts.RedisKey, &cfg.RedisSigner, encF) if err != nil { return nil, err } - case initConfig.UseDBStorage: + case cfg.UseDBStorage: storage := dbstorage.New(opts.Database, func() storage.EncoderDecoderInterface { return &storage.EncoderDecoder{} }) - if initConfig.Dangerous.ClearDBStorage { + if cfg.Dangerous.ClearDBStorage { if err := storage.PruneAll(ctx); err != nil { return nil, err } @@ -139,18 +145,53 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro default: queue = slice.NewStorage(func() storage.EncoderDecoderInterface { return &storage.EncoderDecoder{} }) } - return &DataPoster{ - headerReader: opts.HeaderReader, - client: opts.HeaderReader.Client(), - sender: opts.Auth.From, - signer: opts.Auth.Signer, + dp := &DataPoster{ + headerReader: opts.HeaderReader, + client: opts.HeaderReader.Client(), + sender: opts.Auth.From, + signer: func(_ context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + return opts.Auth.Signer(addr, tx) + }, config: opts.Config, replacementTimes: replacementTimes, metadataRetriever: opts.MetadataRetriever, queue: queue, redisLock: opts.RedisLock, errorCount: make(map[uint64]int), - }, nil + } + if cfg.ExternalSigner.Enabled { + signer, sender, err := externalSigner(ctx, cfg.ExternalSigner.Address, cfg.ExternalSigner.URL) + if err != nil { + return nil, err + } + dp.signer, dp.sender = signer, sender + } + return dp, nil +} + +// externalSigner returns signer function and ethereum address of the signer. +// Returns an error if address isn't specified or if it can't connect to the +// signer RPC server. +func externalSigner(ctx context.Context, addr string, rpcURL string) (signerFn, common.Address, error) { + if addr == "" { + return nil, common.Address{}, errors.New("external signer (From) address specified") + } + sender := common.HexToAddress(addr) + client, err := rpc.DialContext(ctx, rpcURL) + if err != nil { + return nil, common.Address{}, fmt.Errorf("error connecting external signer: %w", err) + } + return func(ctx context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + data, err := tx.MarshalBinary() + if err != nil { + return nil, err + } + var signedTx *types.Transaction + if err := client.CallContext(ctx, &signedTx, "eth_signTransaction", hexutil.Encode(data)); err != nil { + return nil, fmt.Errorf("error calling with context: %w", err) + } + return signedTx, nil + }, sender, nil } func (p *DataPoster) Sender() common.Address { @@ -371,7 +412,7 @@ func (p *DataPoster) PostTransaction(ctx context.Context, dataCreatedAt time.Tim Data: calldata, AccessList: accessList, } - fullTx, err := p.signer(p.sender, types.NewTx(&inner)) + fullTx, err := p.signer(ctx, p.sender, types.NewTx(&inner)) if err != nil { return nil, fmt.Errorf("signing transaction: %w", err) } @@ -450,7 +491,7 @@ func (p *DataPoster) replaceTx(ctx context.Context, prevTx *storage.QueuedTransa newTx.Sent = false newTx.Data.GasFeeCap = newFeeCap newTx.Data.GasTipCap = newTipCap - newTx.FullTx, err = p.signer(p.sender, types.NewTx(&newTx.Data)) + newTx.FullTx, err = p.signer(ctx, p.sender, types.NewTx(&newTx.Data)) if err != nil { return err } @@ -636,20 +677,31 @@ type DataPosterConfig struct { ReplacementTimes string `koanf:"replacement-times"` // This is forcibly disabled if the parent chain is an Arbitrum chain, // so you should probably use DataPoster's waitForL1Finality method instead of reading this field directly. - WaitForL1Finality bool `koanf:"wait-for-l1-finality" reload:"hot"` - MaxMempoolTransactions uint64 `koanf:"max-mempool-transactions" reload:"hot"` - MaxQueuedTransactions int `koanf:"max-queued-transactions" reload:"hot"` - TargetPriceGwei float64 `koanf:"target-price-gwei" reload:"hot"` - UrgencyGwei float64 `koanf:"urgency-gwei" reload:"hot"` - MinFeeCapGwei float64 `koanf:"min-fee-cap-gwei" reload:"hot"` - MinTipCapGwei float64 `koanf:"min-tip-cap-gwei" reload:"hot"` - MaxTipCapGwei float64 `koanf:"max-tip-cap-gwei" reload:"hot"` - NonceRbfSoftConfs uint64 `koanf:"nonce-rbf-soft-confs" reload:"hot"` - AllocateMempoolBalance bool `koanf:"allocate-mempool-balance" reload:"hot"` - UseDBStorage bool `koanf:"use-db-storage"` - UseNoOpStorage bool `koanf:"use-noop-storage"` - LegacyStorageEncoding bool `koanf:"legacy-storage-encoding" reload:"hot"` - Dangerous DangerousConfig `koanf:"dangerous"` + WaitForL1Finality bool `koanf:"wait-for-l1-finality" reload:"hot"` + MaxMempoolTransactions uint64 `koanf:"max-mempool-transactions" reload:"hot"` + MaxQueuedTransactions int `koanf:"max-queued-transactions" reload:"hot"` + TargetPriceGwei float64 `koanf:"target-price-gwei" reload:"hot"` + UrgencyGwei float64 `koanf:"urgency-gwei" reload:"hot"` + MinFeeCapGwei float64 `koanf:"min-fee-cap-gwei" reload:"hot"` + MinTipCapGwei float64 `koanf:"min-tip-cap-gwei" reload:"hot"` + MaxTipCapGwei float64 `koanf:"max-tip-cap-gwei" reload:"hot"` + NonceRbfSoftConfs uint64 `koanf:"nonce-rbf-soft-confs" reload:"hot"` + AllocateMempoolBalance bool `koanf:"allocate-mempool-balance" reload:"hot"` + UseDBStorage bool `koanf:"use-db-storage"` + UseNoOpStorage bool `koanf:"use-noop-storage"` + LegacyStorageEncoding bool `koanf:"legacy-storage-encoding" reload:"hot"` + Dangerous DangerousConfig `koanf:"dangerous"` + ExternalSigner ExternalSignerCfg `koanf:"external-signer"` +} + +type ExternalSignerCfg struct { + // If enabled, this overrides transaction options and uses external signer + // for signing transactions. + Enabled bool `koanf:"enabled"` + // URL of the external signer rpc server. + URL string `koanf:"url"` + // Hex encoded ethereum address of the external signer. + Address string `koanf:"address"` } type DangerousConfig struct { @@ -662,30 +714,37 @@ type DangerousConfig struct { // that flags can be reloaded dynamically. type ConfigFetcher func() *DataPosterConfig -func DataPosterConfigAddOptions(prefix string, f *pflag.FlagSet) { - f.String(prefix+".replacement-times", DefaultDataPosterConfig.ReplacementTimes, "comma-separated list of durations since first posting to attempt a replace-by-fee") - f.Bool(prefix+".wait-for-l1-finality", DefaultDataPosterConfig.WaitForL1Finality, "only treat a transaction as confirmed after L1 finality has been achieved (recommended)") - f.Uint64(prefix+".max-mempool-transactions", DefaultDataPosterConfig.MaxMempoolTransactions, "the maximum number of transactions to have queued in the mempool at once (0 = unlimited)") - f.Int(prefix+".max-queued-transactions", DefaultDataPosterConfig.MaxQueuedTransactions, "the maximum number of unconfirmed transactions to track at once (0 = unlimited)") - f.Float64(prefix+".target-price-gwei", DefaultDataPosterConfig.TargetPriceGwei, "the target price to use for maximum fee cap calculation") - f.Float64(prefix+".urgency-gwei", DefaultDataPosterConfig.UrgencyGwei, "the urgency to use for maximum fee cap calculation") - f.Float64(prefix+".min-fee-cap-gwei", DefaultDataPosterConfig.MinFeeCapGwei, "the minimum fee cap to post transactions at") - f.Float64(prefix+".min-tip-cap-gwei", DefaultDataPosterConfig.MinTipCapGwei, "the minimum tip cap to post transactions at") - f.Float64(prefix+".max-tip-cap-gwei", DefaultDataPosterConfig.MaxTipCapGwei, "the maximum tip cap to post transactions at") - f.Uint64(prefix+".nonce-rbf-soft-confs", DefaultDataPosterConfig.NonceRbfSoftConfs, "the maximum probable reorg depth, used to determine when a transaction will no longer likely need replaced-by-fee") - f.Bool(prefix+".allocate-mempool-balance", DefaultDataPosterConfig.AllocateMempoolBalance, "if true, don't put transactions in the mempool that spend a total greater than the batch poster's balance") - f.Bool(prefix+".use-db-storage", DefaultDataPosterConfig.UseDBStorage, "uses database storage when enabled") - f.Bool(prefix+".use-noop-storage", DefaultDataPosterConfig.UseNoOpStorage, "uses noop storage, it doesn't store anything") - f.Bool(prefix+".legacy-storage-encoding", DefaultDataPosterConfig.LegacyStorageEncoding, "encodes items in a legacy way (as it was before dropping generics)") +func DataPosterConfigAddOptions(prefix string, f *pflag.FlagSet, defaultDataPosterConfig DataPosterConfig) { + f.String(prefix+".replacement-times", defaultDataPosterConfig.ReplacementTimes, "comma-separated list of durations since first posting to attempt a replace-by-fee") + f.Bool(prefix+".wait-for-l1-finality", defaultDataPosterConfig.WaitForL1Finality, "only treat a transaction as confirmed after L1 finality has been achieved (recommended)") + f.Uint64(prefix+".max-mempool-transactions", defaultDataPosterConfig.MaxMempoolTransactions, "the maximum number of transactions to have queued in the mempool at once (0 = unlimited)") + f.Int(prefix+".max-queued-transactions", defaultDataPosterConfig.MaxQueuedTransactions, "the maximum number of unconfirmed transactions to track at once (0 = unlimited)") + f.Float64(prefix+".target-price-gwei", defaultDataPosterConfig.TargetPriceGwei, "the target price to use for maximum fee cap calculation") + f.Float64(prefix+".urgency-gwei", defaultDataPosterConfig.UrgencyGwei, "the urgency to use for maximum fee cap calculation") + f.Float64(prefix+".min-fee-cap-gwei", defaultDataPosterConfig.MinFeeCapGwei, "the minimum fee cap to post transactions at") + f.Float64(prefix+".min-tip-cap-gwei", defaultDataPosterConfig.MinTipCapGwei, "the minimum tip cap to post transactions at") + f.Float64(prefix+".max-tip-cap-gwei", defaultDataPosterConfig.MaxTipCapGwei, "the maximum tip cap to post transactions at") + f.Uint64(prefix+".nonce-rbf-soft-confs", defaultDataPosterConfig.NonceRbfSoftConfs, "the maximum probable reorg depth, used to determine when a transaction will no longer likely need replaced-by-fee") + f.Bool(prefix+".allocate-mempool-balance", defaultDataPosterConfig.AllocateMempoolBalance, "if true, don't put transactions in the mempool that spend a total greater than the batch poster's balance") + f.Bool(prefix+".use-db-storage", defaultDataPosterConfig.UseDBStorage, "uses database storage when enabled") + f.Bool(prefix+".use-noop-storage", defaultDataPosterConfig.UseNoOpStorage, "uses noop storage, it doesn't store anything") + f.Bool(prefix+".legacy-storage-encoding", defaultDataPosterConfig.LegacyStorageEncoding, "encodes items in a legacy way (as it was before dropping generics)") signature.SimpleHmacConfigAddOptions(prefix+".redis-signer", f) addDangerousOptions(prefix+".dangerous", f) + addExternalSignerOptions(prefix+".external-signer", f) } func addDangerousOptions(prefix string, f *pflag.FlagSet) { f.Bool(prefix+".clear-dbstorage", DefaultDataPosterConfig.Dangerous.ClearDBStorage, "clear database storage") } +func addExternalSignerOptions(prefix string, f *pflag.FlagSet) { + f.Bool(prefix+".enabled", DefaultDataPosterConfig.ExternalSigner.Enabled, "enable external signer") + f.String(prefix+".url", DefaultDataPosterConfig.ExternalSigner.URL, "external signer url") + f.String(prefix+".address", DefaultDataPosterConfig.ExternalSigner.Address, "external signer address") +} + var DefaultDataPosterConfig = DataPosterConfig{ ReplacementTimes: "5m,10m,20m,30m,1h,2h,4h,6h,8h,12h,16h,18h,20h,22h", WaitForL1Finality: true, @@ -700,6 +759,7 @@ var DefaultDataPosterConfig = DataPosterConfig{ UseNoOpStorage: false, LegacyStorageEncoding: true, Dangerous: DangerousConfig{ClearDBStorage: false}, + ExternalSigner: ExternalSignerCfg{Enabled: false}, } var DefaultDataPosterConfigForValidator = func() DataPosterConfig { @@ -721,6 +781,7 @@ var TestDataPosterConfig = DataPosterConfig{ AllocateMempoolBalance: true, UseDBStorage: false, UseNoOpStorage: false, + ExternalSigner: ExternalSignerCfg{Enabled: false}, } var TestDataPosterConfigForValidator = func() DataPosterConfig { diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index b8a9c3e499..c4c131c79a 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -1,9 +1,21 @@ package dataposter import ( + "context" + "encoding/json" + "fmt" + "io" + "log" + "math/big" + "net/http" "testing" "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" "github.com/google/go-cmp/cmp" ) @@ -41,3 +53,201 @@ func TestParseReplacementTimes(t *testing.T) { }) } } + +type Args struct { + Name string +} + +func TestRPC(t *testing.T) { + srv, err := newServer() + if err != nil { + fmt.Printf("Erorr creating server: %v", err) + return + } + http.HandleFunc("/", srv.mux) + go func() { + fmt.Println("Server is listening on port 1234...") + t.Errorf("error listening: %v", http.ListenAndServe(":1234", nil)) + }() + + if err != nil { + t.Fatalf("Error creating a server: %v", err) + } + ctx := context.Background() + signer, addr, err := externalSigner(ctx, srv.address.Hex(), "http://127.0.0.1:1234") + if err != nil { + t.Fatalf("Error getting external signer: %v", err) + } + tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, big.NewInt(30000), nil) + signedTx, err := signer(ctx, addr, tx) + if err != nil { + t.Errorf("Error signing transaction: %v", err) + } + if diff := cmp.Diff(signedTx, tx); diff != "" { + t.Errorf("diff: %v\n", diff) + } + +} + +// func setupServer(t *testing.T) { +// t.Skip() +// t.Helper() +// srv, err := newServer() +// if err != nil { +// fmt.Printf("Erorr creating server: %v", err) +// return +// } +// http.HandleFunc("/", srv.mux) +// fmt.Println("Server is listening on port 1234...") +// t.Fatal(http.ListenAndServe(":1234", nil)) +// } + +type SigningService struct{} + +func (h *SigningService) SignTx(r *http.Request, args *Args, reply *string) error { + *reply = "Hello, " + args.Name + "!" + return nil +} + +type server struct { + handlers map[string]func(*json.RawMessage) (string, error) + signerFn bind.SignerFn + address common.Address +} + +type request struct { + ID *json.RawMessage `json:"id"` + Method string `json:"method"` + Params *json.RawMessage `json:"params"` +} + +type response struct { + ID *json.RawMessage `json:"id"` + Result string `json:"result"` +} + +func newServer() (*server, error) { + signer, address, err := setupAccount("/tmp/keystore") + if err != nil { + return nil, err + } + s := &server{ + signerFn: signer, + address: address, + } + s.handlers = map[string]func(*json.RawMessage) (string, error){ + "eth_signTransaction": s.signTransaction, + } + return s, nil +} + +func setupAccount(dir string) (bind.SignerFn, common.Address, error) { + ks := keystore.NewKeyStore( + dir, + keystore.StandardScryptN, + keystore.StandardScryptP, + ) + a, err := ks.NewAccount("password") + if err != nil { + return nil, common.Address{}, fmt.Errorf("creating account account: %w", err) + } + if err := ks.Unlock(a, "password"); err != nil { + return nil, common.Address{}, fmt.Errorf("unlocking account: %w", err) + } + log.Printf("Created account: %s", a.Address.Hex()) + txOpts, err := bind.NewKeyStoreTransactorWithChainID(ks, a, big.NewInt(1)) + if err != nil { + return nil, common.Address{}, fmt.Errorf("creating transactor: %w", err) + } + return txOpts.Signer, a.Address, nil +} + +// UnmarshallFirst unmarshalls slice of params and returns the first one. +// Parameters in Go ethereum RPC calls are marashalled as slices. E.g. +// eth_sendRawTransaction or eth_signTransaction, marshall transaction as a +// slice of transactions in a message: +// https://github.com/ethereum/go-ethereum/blob/0004c6b229b787281760b14fb9460ffd9c2496f1/rpc/client.go#L548 +func unmarshallFirst(params []byte) (any, error) { + var arr []any + if err := json.Unmarshal(params, &arr); err != nil { + return "", fmt.Errorf("unmarshaling first param: %w", err) + } + return arr[0], nil +} + +// func unmarshallTx(params *json.RawMessage) (*types.Transaction, error) { + +// } + +func encodeTx(tx *types.Transaction) (string, error) { + data, err := tx.MarshalBinary() + if err != nil { + return "", err + } + return hexutil.Encode(data), nil +} + +func (s *server) signTransaction(params *json.RawMessage) (string, error) { + param, err := unmarshallFirst(*params) + if err != nil { + return "", err + } + + fmt.Printf("anodar first parameter: %q\n", param) + data, err := hexutil.Decode("0xe280827530832dc6c09400000000000000000000000000000000000000018080808080") + if err != nil { + return "", fmt.Errorf("decoding hex: %w", err) + } + fmt.Printf("decoded data: %v\n", data) + var tx types.Transaction + if err := tx.UnmarshalBinary(data); err != nil { + return "", fmt.Errorf("unmarshaling tx: %w", err) + } + fmt.Printf("tx: %v\n", tx) + return encodeTx(&tx) + // var txs []*types.Transaction + // for _, arg := range args { + // signedTx, err := s.signerFn(s.address, arg) + // if err != nil { + // return "", fmt.Errorf("signing transaction: %w", err) + // } + // txs = append(txs, signedTx) + // } + // enc, err := rlp.EncodeToBytes(txs) + // if err != nil { + // return "", fmt.Errorf("encoding transactions to bytes: %w", err) + // } + // return hexutil.Encode(enc), nil +} + +func (s *server) mux(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "can't read body", http.StatusBadRequest) + return + } + var req request + if err := json.Unmarshal(body, &req); err != nil { + http.Error(w, "can't unmarshal JSON request", http.StatusBadRequest) + return + } + method, ok := s.handlers[req.Method] + if !ok { + http.Error(w, "method not found", http.StatusNotFound) + return + } + result, err := method(req.Params) + if err != nil { + fmt.Printf("error calling method: %v\n", err) + http.Error(w, "error calling method", http.StatusInternalServerError) + return + } + resp := response{ID: req.ID, Result: result} + respBytes, err := json.Marshal(resp) + if err != nil { + http.Error(w, "error encoding response", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(respBytes) +} diff --git a/arbnode/maintenance.go b/arbnode/maintenance.go index f5b937cd06..53d038a0f9 100644 --- a/arbnode/maintenance.go +++ b/arbnode/maintenance.go @@ -78,6 +78,7 @@ func MaintenanceConfigAddOptions(prefix string, f *flag.FlagSet) { var DefaultMaintenanceConfig = MaintenanceConfig{ TimeOfDay: "", + Lock: redislock.DefaultCfg, minutesAfterMidnight: 0, } diff --git a/arbnode/node.go b/arbnode/node.go index bf57b1c004..5d06264b65 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -370,6 +370,7 @@ var ConfigDefault = Config{ Dangerous: DefaultDangerousConfig, TransactionStreamer: DefaultTransactionStreamerConfig, ResourceMgmt: resourcemanager.DefaultConfig, + Maintenance: DefaultMaintenanceConfig, } func ConfigDefaultL1Test() *Config { diff --git a/arbnode/redislock/redis.go b/arbnode/redislock/redis.go index c02476f04a..c8252e059f 100644 --- a/arbnode/redislock/redis.go +++ b/arbnode/redislock/redis.go @@ -42,7 +42,7 @@ func AddConfigOptions(prefix string, f *flag.FlagSet) { f.String(prefix+".my-id", "", "this node's id prefix when acquiring the lock (optional)") f.Duration(prefix+".lockout-duration", DefaultCfg.LockoutDuration, "how long lock is held") f.Duration(prefix+".refresh-duration", DefaultCfg.RefreshDuration, "how long between consecutive calls to redis") - f.String(prefix+".key", prefix+".simple-lock-key", "key for lock") + f.String(prefix+".key", DefaultCfg.Key, "key for lock") f.Bool(prefix+".background-lock", DefaultCfg.BackgroundLock, "should node always try grabing lock in background") } diff --git a/broadcastclient/broadcastclient.go b/broadcastclient/broadcastclient.go index 2649c88192..483b0b3b72 100644 --- a/broadcastclient/broadcastclient.go +++ b/broadcastclient/broadcastclient.go @@ -96,7 +96,7 @@ var DefaultConfig = Config{ RequireChainId: false, RequireFeedVersion: false, Verify: signature.DefultFeedVerifierConfig, - URL: []string{""}, + URL: []string{}, Timeout: 20 * time.Second, EnableCompression: true, } diff --git a/cmd/genericconf/config.go b/cmd/genericconf/config.go index 8e75b61772..c3282fe1af 100644 --- a/cmd/genericconf/config.go +++ b/cmd/genericconf/config.go @@ -33,7 +33,7 @@ func ConfConfigAddOptions(prefix string, f *flag.FlagSet) { var ConfConfigDefault = ConfConfig{ Dump: false, EnvPrefix: "", - File: nil, + File: []string{}, S3: DefaultS3Config, String: "", ReloadInterval: 0, diff --git a/cmd/genericconf/server.go b/cmd/genericconf/server.go index 53560dfdb0..3da027ab27 100644 --- a/cmd/genericconf/server.go +++ b/cmd/genericconf/server.go @@ -26,7 +26,7 @@ var HTTPConfigDefault = HTTPConfig{ Port: 8547, API: append(node.DefaultConfig.HTTPModules, "eth", "arb"), RPCPrefix: node.DefaultConfig.HTTPPathPrefix, - CORSDomain: node.DefaultConfig.HTTPCors, + CORSDomain: []string{}, VHosts: node.DefaultConfig.HTTPVirtualHosts, ServerTimeouts: HTTPServerTimeoutConfigDefault, } @@ -91,7 +91,7 @@ var WSConfigDefault = WSConfig{ Port: 8548, API: append(node.DefaultConfig.WSModules, "eth", "arb"), RPCPrefix: node.DefaultConfig.WSPathPrefix, - Origins: node.DefaultConfig.WSOrigins, + Origins: []string{}, ExposeAll: node.DefaultConfig.WSExposeAll, } @@ -137,7 +137,7 @@ type GraphQLConfig struct { var GraphQLConfigDefault = GraphQLConfig{ Enable: false, - CORSDomain: node.DefaultConfig.GraphQLCors, + CORSDomain: []string{}, VHosts: node.DefaultConfig.GraphQLVirtualHosts, } diff --git a/cmd/nitro/config_test.go b/cmd/nitro/config_test.go index 417b256116..ea04d4eb1f 100644 --- a/cmd/nitro/config_test.go +++ b/cmd/nitro/config_test.go @@ -15,10 +15,29 @@ import ( "time" "github.com/offchainlabs/nitro/cmd/genericconf" + "github.com/offchainlabs/nitro/cmd/util/confighelpers" "github.com/offchainlabs/nitro/util/colors" "github.com/offchainlabs/nitro/util/testhelpers" + + "github.com/r3labs/diff/v3" + flag "github.com/spf13/pflag" ) +func TestEmptyCliConfig(t *testing.T) { + f := flag.NewFlagSet("", flag.ContinueOnError) + NodeConfigAddOptions(f) + k, err := confighelpers.BeginCommonParse(f, []string{}) + Require(t, err) + var emptyCliNodeConfig NodeConfig + err = confighelpers.EndCommonParse(k, &emptyCliNodeConfig) + Require(t, err) + if !reflect.DeepEqual(emptyCliNodeConfig, NodeConfigDefault) { + changelog, err := diff.Diff(emptyCliNodeConfig, NodeConfigDefault) + Require(t, err) + Fail(t, "empty cli config differs from expected default", changelog) + } +} + func TestSeqConfig(t *testing.T) { args := strings.Split("--persistent.chain /tmp/data --init.dev-init --node.parent-chain-reader.enable=false --parent-chain.id 5 --chain.id 421613 --parent-chain.wallet.pathname /l1keystore --parent-chain.wallet.password passphrase --http.addr 0.0.0.0 --ws.addr 0.0.0.0 --node.sequencer --execution.sequencer.enable --node.feed.output.enable --node.feed.output.port 9642", " ") _, _, _, err := ParseNode(context.Background(), args) diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index 9656f7f5ec..285cc3fe86 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -591,16 +591,23 @@ type NodeConfig struct { var NodeConfigDefault = NodeConfig{ Conf: genericconf.ConfConfigDefault, Node: arbnode.ConfigDefault, + Execution: gethexec.ConfigDefault, + Validation: valnode.DefaultValidationConfig, ParentChain: conf.L1ConfigDefault, Chain: conf.L2ConfigDefault, LogLevel: int(log.LvlInfo), LogType: "plaintext", + FileLogging: genericconf.DefaultFileLoggingConfig, Persistent: conf.PersistentConfigDefault, HTTP: genericconf.HTTPConfigDefault, WS: genericconf.WSConfigDefault, IPC: genericconf.IPCConfigDefault, + Auth: genericconf.AuthRPCConfigDefault, + GraphQL: genericconf.GraphQLConfigDefault, Metrics: false, MetricsServer: genericconf.MetricsServerConfigDefault, + Init: InitConfigDefault, + Rpc: genericconf.DefaultRpcConfig, PProf: false, PprofCfg: genericconf.PProfDefault, } diff --git a/cmd/rpcsvr/main.go b/cmd/rpcsvr/main.go new file mode 100644 index 0000000000..5fc0b7fc49 --- /dev/null +++ b/cmd/rpcsvr/main.go @@ -0,0 +1,134 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "log" + "math/big" + "net/http" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/signer/core/apitypes" +) + +type server struct { + handlers map[string]func(*json.RawMessage) (string, error) + signerFn bind.SignerFn + address common.Address +} + +type request struct { + ID *json.RawMessage `json:"id"` + Method string `json:"method"` + Params *json.RawMessage `json:"params"` +} + +type response struct { + ID *json.RawMessage `json:"id"` + Result string `json:"result"` +} + +func new() (*server, error) { + signer, address, err := setupAccount("/tmp/keystore") + if err != nil { + return nil, err + } + s := &server{ + signerFn: signer, + address: address, + } + s.handlers = map[string]func(*json.RawMessage) (string, error){ + "eth_signTransaction": s.signTransaction, + } + return s, nil +} + +func setupAccount(dir string) (bind.SignerFn, common.Address, error) { + ks := keystore.NewKeyStore( + dir, + keystore.StandardScryptN, + keystore.StandardScryptP, + ) + a, err := ks.NewAccount("password") + if err != nil { + return nil, common.Address{}, fmt.Errorf("creating account account: %w", err) + } + if err := ks.Unlock(a, "password"); err != nil { + return nil, common.Address{}, fmt.Errorf("unlocking account: %w", err) + } + log.Printf("Created account: %s", a.Address.Hex()) + txOpts, err := bind.NewKeyStoreTransactorWithChainID(ks, a, big.NewInt(1)) + if err != nil { + return nil, common.Address{}, fmt.Errorf("creating transactor: %w", err) + } + return txOpts.Signer, a.Address, nil +} + +func (s *server) signTransaction(params *json.RawMessage) (string, error) { + var args []apitypes.SendTxArgs + if err := json.Unmarshal(*params, &args); err != nil { + return "", fmt.Errorf("unmarshaling params: %w", err) + } + var txs []*types.Transaction + for _, arg := range args { + signedTx, err := s.signerFn(s.address, arg.ToTransaction()) + if err != nil { + return "", fmt.Errorf("signing transaction: %w", err) + } + txs = append(txs, signedTx) + } + enc, err := rlp.EncodeToBytes(txs) + if err != nil { + return "", fmt.Errorf("encoding transactions to bytes: %w", err) + } + return hexutil.Encode(enc), nil +} + +func (s *server) mux(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "can't read body", http.StatusBadRequest) + return + } + var req request + if err := json.Unmarshal(body, &req); err != nil { + http.Error(w, "can't unmarshal JSON request", http.StatusBadRequest) + return + } + method, ok := s.handlers[req.Method] + if !ok { + http.Error(w, "method not found", http.StatusNotFound) + return + } + result, err := method(req.Params) + if err != nil { + fmt.Printf("error calling method: %v\n", err) + http.Error(w, "error calling method", http.StatusInternalServerError) + return + } + resp := response{ID: req.ID, Result: result} + respBytes, err := json.Marshal(resp) + if err != nil { + http.Error(w, "error encoding response", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(respBytes) +} + +func main() { + srv, err := new() + if err != nil { + fmt.Printf("Erorr creating server: %w", err) + return + } + http.HandleFunc("/", srv.mux) + fmt.Println("Server is listening on port 1234...") + log.Fatal(http.ListenAndServe(":1234", nil)) +} diff --git a/das/das.go b/das/das.go index 208a12cc83..9133b73ea4 100644 --- a/das/das.go +++ b/das/das.go @@ -69,6 +69,7 @@ var DefaultDataAvailabilityConfig = DataAvailabilityConfig{ RestAggregator: DefaultRestfulClientAggregatorConfig, ParentChainConnectionAttempts: 15, PanicOnError: false, + IpfsStorage: DefaultIpfsStorageServiceConfig, } func OptionalAddressFromString(s string) (*common.Address, error) { diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index b29309cdbb..1068dda967 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -91,6 +91,7 @@ var ConfigDefault = Config{ TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second Caching: DefaultCachingConfig, Dangerous: DefaultDangerousConfig, + Forwarder: DefaultNodeForwarderConfig, } func ConfigDefaultNonSequencerTest() *Config { diff --git a/staker/block_validator.go b/staker/block_validator.go index 94bc2a0806..108d6d1d49 100644 --- a/staker/block_validator.go +++ b/staker/block_validator.go @@ -750,7 +750,7 @@ func (v *BlockValidator) iterativeValidationProgress(ctx context.Context, ignore } else if reorg != nil { err := v.Reorg(ctx, *reorg) if err != nil { - log.Error("error trying to rorg validation", "pos", *reorg-1, "err", err) + log.Error("error trying to reorg validation", "pos", *reorg-1, "err", err) v.possiblyFatal(err) } } diff --git a/staker/staker.go b/staker/staker.go index d52d1adc77..4148d0a204 100644 --- a/staker/staker.go +++ b/staker/staker.go @@ -203,7 +203,7 @@ func L1ValidatorConfigAddOptions(prefix string, f *flag.FlagSet) { f.String(prefix+".gas-refunder-address", DefaultL1ValidatorConfig.GasRefunderAddress, "The gas refunder contract address (optional)") f.String(prefix+".redis-url", DefaultL1ValidatorConfig.RedisUrl, "redis url for L1 validator") f.Uint64(prefix+".extra-gas", DefaultL1ValidatorConfig.ExtraGas, "use this much more gas than estimation says is necessary to post transactions") - dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f) + dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f, dataposter.DefaultDataPosterConfigForValidator) redislock.AddConfigOptions(prefix+".redis-lock", f) DangerousConfigAddOptions(prefix+".dangerous", f) genericconf.WalletConfigAddOptions(prefix+".parent-chain-wallet", f, DefaultL1ValidatorConfig.ParentChainWallet.Pathname) diff --git a/util/headerreader/header_reader.go b/util/headerreader/header_reader.go index ab61f8a2ee..ff3b420a1c 100644 --- a/util/headerreader/header_reader.go +++ b/util/headerreader/header_reader.go @@ -81,6 +81,7 @@ func AddOptions(prefix string, f *flag.FlagSet) { f.Bool(prefix+".poll-only", DefaultConfig.PollOnly, "do not attempt to subscribe to header events") f.Bool(prefix+".use-finality-data", DefaultConfig.UseFinalityData, "use l1 data about finalized/safe blocks") f.Duration(prefix+".poll-interval", DefaultConfig.PollInterval, "interval when polling endpoint") + f.Duration(prefix+".subscribe-err-interval", DefaultConfig.SubscribeErrInterval, "interval for subscribe error") f.Duration(prefix+".tx-timeout", DefaultConfig.TxTimeout, "timeout when waiting for a transaction") f.Duration(prefix+".old-header-timeout", DefaultConfig.OldHeaderTimeout, "warns if the latest l1 block is at least this old") } diff --git a/util/signature/sign_verify.go b/util/signature/sign_verify.go index 2911912979..5ed852bfbc 100644 --- a/util/signature/sign_verify.go +++ b/util/signature/sign_verify.go @@ -31,6 +31,12 @@ func SignVerifyConfigAddOptions(prefix string, f *flag.FlagSet) { } var DefaultSignVerifyConfig = SignVerifyConfig{ + ECDSA: DefultFeedVerifierConfig, + SymmetricFallback: false, + SymmetricSign: false, + Symmetric: EmptySimpleHmacConfig, +} +var TestSignVerifyConfig = SignVerifyConfig{ ECDSA: VerifierConfig{ AcceptSequencer: true, }, diff --git a/util/signature/sign_verify_test.go b/util/signature/sign_verify_test.go index 8ecb6e5ccc..916fc03a20 100644 --- a/util/signature/sign_verify_test.go +++ b/util/signature/sign_verify_test.go @@ -17,7 +17,7 @@ func TestSignVerifyModes(t *testing.T) { signingAddr := crypto.PubkeyToAddress(privateKey.PublicKey) dataSigner := DataSignerFromPrivateKey(privateKey) - config := DefaultSignVerifyConfig + config := TestSignVerifyConfig config.SymmetricFallback = false config.SymmetricSign = false config.ECDSA.AcceptSequencer = false @@ -25,14 +25,14 @@ func TestSignVerifyModes(t *testing.T) { signVerifyECDSA, err := NewSignVerify(&config, dataSigner, nil) Require(t, err) - configSymmetric := DefaultSignVerifyConfig + configSymmetric := TestSignVerifyConfig configSymmetric.SymmetricFallback = true configSymmetric.SymmetricSign = true configSymmetric.ECDSA.AcceptSequencer = false signVerifySymmetric, err := NewSignVerify(&configSymmetric, nil, nil) Require(t, err) - configFallback := DefaultSignVerifyConfig + configFallback := TestSignVerifyConfig configFallback.SymmetricFallback = true configFallback.SymmetricSign = false configFallback.ECDSA.AllowedAddresses = []string{signingAddr.Hex()} diff --git a/util/signature/verifier.go b/util/signature/verifier.go index 2bf5b854ed..c2f6529ec6 100644 --- a/util/signature/verifier.go +++ b/util/signature/verifier.go @@ -37,7 +37,7 @@ var ErrMissingSignature = fmt.Errorf("%w: signature not found", ErrSignatureNotV var ErrSignerNotApproved = fmt.Errorf("%w: signer not approved", ErrSignatureNotVerified) func FeedVerifierConfigAddOptions(prefix string, f *flag.FlagSet) { - f.StringArray(prefix+".allowed-addresses", DefultFeedVerifierConfig.AllowedAddresses, "a list of allowed addresses") + f.StringSlice(prefix+".allowed-addresses", DefultFeedVerifierConfig.AllowedAddresses, "a list of allowed addresses") f.Bool(prefix+".accept-sequencer", DefultFeedVerifierConfig.AcceptSequencer, "accept verified message from sequencer") DangerousFeedVerifierConfigAddOptions(prefix+".dangerous", f) } From 42694708bd45b336f3ea88c2490b6bf49a0ebf79 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Fri, 13 Oct 2023 16:56:11 +0200 Subject: [PATCH 33/54] merge master --- arbnode/dataposter/data_poster.go | 20 ++-- arbnode/dataposter/dataposter_test.go | 144 +++++++++----------------- 2 files changed, 63 insertions(+), 101 deletions(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index c8a673ec9c..76787e8c4d 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -20,6 +20,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/go-redis/redis/v8" "github.com/offchainlabs/nitro/arbnode/dataposter/dbstorage" @@ -182,15 +183,20 @@ func externalSigner(ctx context.Context, addr string, rpcURL string) (signerFn, return nil, common.Address{}, fmt.Errorf("error connecting external signer: %w", err) } return func(ctx context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { - data, err := tx.MarshalBinary() - if err != nil { - return nil, err + // According to the "eth_signTransaction" API definition, this shoul be + // RLP encoded transaction object. + // https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_signtransaction + var rlpEncTxStr string + if err := client.CallContext(ctx, &rlpEncTxStr, "eth_signTransaction", tx); err != nil { + return nil, fmt.Errorf("signing transaction: %w", err) } - var signedTx *types.Transaction - if err := client.CallContext(ctx, &signedTx, "eth_signTransaction", hexutil.Encode(data)); err != nil { - return nil, fmt.Errorf("error calling with context: %w", err) + data, err := hexutil.Decode(rlpEncTxStr) + if err != nil { + return nil, fmt.Errorf("error decoding hex: %w", err) } - return signedTx, nil + var signedTx types.Transaction + rlp.DecodeBytes(data, &signedTx) + return &signedTx, nil }, sender, nil } diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index c4c131c79a..6334d2917b 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -5,9 +5,9 @@ import ( "encoding/json" "fmt" "io" - "log" "math/big" "net/http" + "os" "testing" "time" @@ -16,6 +16,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/signer/core/apitypes" "github.com/google/go-cmp/cmp" ) @@ -54,59 +56,32 @@ func TestParseReplacementTimes(t *testing.T) { } } -type Args struct { - Name string -} - -func TestRPC(t *testing.T) { - srv, err := newServer() - if err != nil { - fmt.Printf("Erorr creating server: %v", err) - return - } - http.HandleFunc("/", srv.mux) +func TestExternalSigner(t *testing.T) { + ctx := context.Background() + httpSrv, srv := newServer(ctx, t) + t.Cleanup(func() { httpSrv.Shutdown(ctx) }) go func() { fmt.Println("Server is listening on port 1234...") - t.Errorf("error listening: %v", http.ListenAndServe(":1234", nil)) + if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed { + fmt.Printf("error listening: %v", http.ListenAndServe(":1234", nil)) + } }() - - if err != nil { - t.Fatalf("Error creating a server: %v", err) - } - ctx := context.Background() signer, addr, err := externalSigner(ctx, srv.address.Hex(), "http://127.0.0.1:1234") if err != nil { t.Fatalf("Error getting external signer: %v", err) } - tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, big.NewInt(30000), nil) - signedTx, err := signer(ctx, addr, tx) + tx := types.NewTransaction(13, common.HexToAddress("0x01"), big.NewInt(1), 2, big.NewInt(3), []byte{0x01, 0x02, 0x03}) + got, err := signer(ctx, addr, tx) if err != nil { - t.Errorf("Error signing transaction: %v", err) + t.Fatalf("Error signing transaction with external signer: %v", err) } - if diff := cmp.Diff(signedTx, tx); diff != "" { - t.Errorf("diff: %v\n", diff) + want, err := srv.signerFn(addr, tx) + if err != nil { + t.Fatalf("Error signing transaction: %v", err) + } + if diff := cmp.Diff(want.Hash(), got.Hash()); diff != "" { + t.Errorf("Signing transaction: unexpected diff: %v\n", diff) } - -} - -// func setupServer(t *testing.T) { -// t.Skip() -// t.Helper() -// srv, err := newServer() -// if err != nil { -// fmt.Printf("Erorr creating server: %v", err) -// return -// } -// http.HandleFunc("/", srv.mux) -// fmt.Println("Server is listening on port 1234...") -// t.Fatal(http.ListenAndServe(":1234", nil)) -// } - -type SigningService struct{} - -func (h *SigningService) SignTx(r *http.Request, args *Args, reply *string) error { - *reply = "Hello, " + args.Name + "!" - return nil } type server struct { @@ -123,24 +98,32 @@ type request struct { type response struct { ID *json.RawMessage `json:"id"` - Result string `json:"result"` + Result string `json:"result,omitempty"` } -func newServer() (*server, error) { +// newServer returns http server and server struct that implements RPC methods. +// It sets up an account in temporary directory and cleans up after test is +// done. +func newServer(ctx context.Context, t *testing.T) (*http.Server, *server) { + t.Helper() signer, address, err := setupAccount("/tmp/keystore") if err != nil { - return nil, err - } - s := &server{ - signerFn: signer, - address: address, + t.Fatalf("Error setting up account: %v", err) } + t.Cleanup(func() { os.RemoveAll("/tmp/keystore") }) + + s := &server{signerFn: signer, address: address} s.handlers = map[string]func(*json.RawMessage) (string, error){ "eth_signTransaction": s.signTransaction, } - return s, nil + m := http.NewServeMux() + httpSrv := &http.Server{Addr: ":1234", Handler: m} + m.HandleFunc("/", s.mux) + return httpSrv, s } +// setupAccount creates a new account in a given directory, unlocks it, creates +// signer with that account and returns it along with account address. func setupAccount(dir string) (bind.SignerFn, common.Address, error) { ks := keystore.NewKeyStore( dir, @@ -154,7 +137,6 @@ func setupAccount(dir string) (bind.SignerFn, common.Address, error) { if err := ks.Unlock(a, "password"); err != nil { return nil, common.Address{}, fmt.Errorf("unlocking account: %w", err) } - log.Printf("Created account: %s", a.Address.Hex()) txOpts, err := bind.NewKeyStoreTransactorWithChainID(ks, a, big.NewInt(1)) if err != nil { return nil, common.Address{}, fmt.Errorf("creating transactor: %w", err) @@ -167,57 +149,31 @@ func setupAccount(dir string) (bind.SignerFn, common.Address, error) { // eth_sendRawTransaction or eth_signTransaction, marshall transaction as a // slice of transactions in a message: // https://github.com/ethereum/go-ethereum/blob/0004c6b229b787281760b14fb9460ffd9c2496f1/rpc/client.go#L548 -func unmarshallFirst(params []byte) (any, error) { - var arr []any +func unmarshallFirst(params []byte) (*types.Transaction, error) { + var arr []apitypes.SendTxArgs if err := json.Unmarshal(params, &arr); err != nil { - return "", fmt.Errorf("unmarshaling first param: %w", err) + return nil, fmt.Errorf("unmarshaling first param: %w", err) } - return arr[0], nil -} - -// func unmarshallTx(params *json.RawMessage) (*types.Transaction, error) { - -// } - -func encodeTx(tx *types.Transaction) (string, error) { - data, err := tx.MarshalBinary() - if err != nil { - return "", err + if len(arr) != 1 { + return nil, fmt.Errorf("argument should be a single transaction, but got: %d", len(arr)) } - return hexutil.Encode(data), nil + return arr[0].ToTransaction(), nil } func (s *server) signTransaction(params *json.RawMessage) (string, error) { - param, err := unmarshallFirst(*params) + tx, err := unmarshallFirst(*params) if err != nil { return "", err } - - fmt.Printf("anodar first parameter: %q\n", param) - data, err := hexutil.Decode("0xe280827530832dc6c09400000000000000000000000000000000000000018080808080") + signedTx, err := s.signerFn(s.address, tx) if err != nil { - return "", fmt.Errorf("decoding hex: %w", err) - } - fmt.Printf("decoded data: %v\n", data) - var tx types.Transaction - if err := tx.UnmarshalBinary(data); err != nil { - return "", fmt.Errorf("unmarshaling tx: %w", err) - } - fmt.Printf("tx: %v\n", tx) - return encodeTx(&tx) - // var txs []*types.Transaction - // for _, arg := range args { - // signedTx, err := s.signerFn(s.address, arg) - // if err != nil { - // return "", fmt.Errorf("signing transaction: %w", err) - // } - // txs = append(txs, signedTx) - // } - // enc, err := rlp.EncodeToBytes(txs) - // if err != nil { - // return "", fmt.Errorf("encoding transactions to bytes: %w", err) - // } - // return hexutil.Encode(enc), nil + return "", fmt.Errorf("signing transaction: %w", err) + } + data, err := rlp.EncodeToBytes(signedTx) + if err != nil { + return "", fmt.Errorf("rlp encoding transaction: %w", err) + } + return hexutil.Encode(data), nil } func (s *server) mux(w http.ResponseWriter, r *http.Request) { From c3ed563a94c74dc5025170a57418fca08ee25935 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Fri, 13 Oct 2023 16:58:55 +0200 Subject: [PATCH 34/54] Drop accidentally added server binary for manual testing --- cmd/rpcsvr/main.go | 134 --------------------------------------------- 1 file changed, 134 deletions(-) delete mode 100644 cmd/rpcsvr/main.go diff --git a/cmd/rpcsvr/main.go b/cmd/rpcsvr/main.go deleted file mode 100644 index 5fc0b7fc49..0000000000 --- a/cmd/rpcsvr/main.go +++ /dev/null @@ -1,134 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io" - "log" - "math/big" - "net/http" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/signer/core/apitypes" -) - -type server struct { - handlers map[string]func(*json.RawMessage) (string, error) - signerFn bind.SignerFn - address common.Address -} - -type request struct { - ID *json.RawMessage `json:"id"` - Method string `json:"method"` - Params *json.RawMessage `json:"params"` -} - -type response struct { - ID *json.RawMessage `json:"id"` - Result string `json:"result"` -} - -func new() (*server, error) { - signer, address, err := setupAccount("/tmp/keystore") - if err != nil { - return nil, err - } - s := &server{ - signerFn: signer, - address: address, - } - s.handlers = map[string]func(*json.RawMessage) (string, error){ - "eth_signTransaction": s.signTransaction, - } - return s, nil -} - -func setupAccount(dir string) (bind.SignerFn, common.Address, error) { - ks := keystore.NewKeyStore( - dir, - keystore.StandardScryptN, - keystore.StandardScryptP, - ) - a, err := ks.NewAccount("password") - if err != nil { - return nil, common.Address{}, fmt.Errorf("creating account account: %w", err) - } - if err := ks.Unlock(a, "password"); err != nil { - return nil, common.Address{}, fmt.Errorf("unlocking account: %w", err) - } - log.Printf("Created account: %s", a.Address.Hex()) - txOpts, err := bind.NewKeyStoreTransactorWithChainID(ks, a, big.NewInt(1)) - if err != nil { - return nil, common.Address{}, fmt.Errorf("creating transactor: %w", err) - } - return txOpts.Signer, a.Address, nil -} - -func (s *server) signTransaction(params *json.RawMessage) (string, error) { - var args []apitypes.SendTxArgs - if err := json.Unmarshal(*params, &args); err != nil { - return "", fmt.Errorf("unmarshaling params: %w", err) - } - var txs []*types.Transaction - for _, arg := range args { - signedTx, err := s.signerFn(s.address, arg.ToTransaction()) - if err != nil { - return "", fmt.Errorf("signing transaction: %w", err) - } - txs = append(txs, signedTx) - } - enc, err := rlp.EncodeToBytes(txs) - if err != nil { - return "", fmt.Errorf("encoding transactions to bytes: %w", err) - } - return hexutil.Encode(enc), nil -} - -func (s *server) mux(w http.ResponseWriter, r *http.Request) { - body, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, "can't read body", http.StatusBadRequest) - return - } - var req request - if err := json.Unmarshal(body, &req); err != nil { - http.Error(w, "can't unmarshal JSON request", http.StatusBadRequest) - return - } - method, ok := s.handlers[req.Method] - if !ok { - http.Error(w, "method not found", http.StatusNotFound) - return - } - result, err := method(req.Params) - if err != nil { - fmt.Printf("error calling method: %v\n", err) - http.Error(w, "error calling method", http.StatusInternalServerError) - return - } - resp := response{ID: req.ID, Result: result} - respBytes, err := json.Marshal(resp) - if err != nil { - http.Error(w, "error encoding response", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(respBytes) -} - -func main() { - srv, err := new() - if err != nil { - fmt.Printf("Erorr creating server: %w", err) - return - } - http.HandleFunc("/", srv.mux) - fmt.Println("Server is listening on port 1234...") - log.Fatal(http.ListenAndServe(":1234", nil)) -} From c177f025513f5a17fbaca04c742f01290efb0cc5 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Fri, 13 Oct 2023 17:05:35 +0200 Subject: [PATCH 35/54] Fix linter errors --- arbnode/dataposter/data_poster.go | 4 +++- arbnode/dataposter/dataposter_test.go | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index 76787e8c4d..15044cc4ec 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -195,7 +195,9 @@ func externalSigner(ctx context.Context, addr string, rpcURL string) (signerFn, return nil, fmt.Errorf("error decoding hex: %w", err) } var signedTx types.Transaction - rlp.DecodeBytes(data, &signedTx) + if err := rlp.DecodeBytes(data, &signedTx); err != nil { + return nil, fmt.Errorf("error decoding signed transaction: %w", err) + } return &signedTx, nil }, sender, nil } diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index 6334d2917b..c190337a05 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -59,11 +59,16 @@ func TestParseReplacementTimes(t *testing.T) { func TestExternalSigner(t *testing.T) { ctx := context.Background() httpSrv, srv := newServer(ctx, t) - t.Cleanup(func() { httpSrv.Shutdown(ctx) }) + t.Cleanup(func() { + if err := httpSrv.Shutdown(ctx); err != nil { + t.Fatalf("Error shutting down http server: %v", err) + } + }) go func() { fmt.Println("Server is listening on port 1234...") if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - fmt.Printf("error listening: %v", http.ListenAndServe(":1234", nil)) + t.Errorf("ListenAndServe() unexpected error: %v", err) + return } }() signer, addr, err := externalSigner(ctx, srv.address.Hex(), "http://127.0.0.1:1234") @@ -117,7 +122,7 @@ func newServer(ctx context.Context, t *testing.T) (*http.Server, *server) { "eth_signTransaction": s.signTransaction, } m := http.NewServeMux() - httpSrv := &http.Server{Addr: ":1234", Handler: m} + httpSrv := &http.Server{Addr: ":1234", Handler: m, ReadTimeout: 5 * time.Second} m.HandleFunc("/", s.mux) return httpSrv, s } @@ -201,9 +206,11 @@ func (s *server) mux(w http.ResponseWriter, r *http.Request) { resp := response{ID: req.ID, Result: result} respBytes, err := json.Marshal(resp) if err != nil { - http.Error(w, "error encoding response", http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("error encoding response: %v", err), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") - w.Write(respBytes) + if _, err := w.Write(respBytes); err != nil { + fmt.Printf("error writing response: %v\n", err) + } } From a0fcf8ed97b1ec9d398e7e084c80db6c6b7db308 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Fri, 13 Oct 2023 10:36:22 -0500 Subject: [PATCH 36/54] run int dev in foreground --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ce92be513b..f8d36b780e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -63,7 +63,7 @@ jobs: shell: bash run: | cd nitro-testnode - ./test-node.bash --init & + ./test-node.bash --init --dev - name: Wait for rpc to come up shell: bash From 2f7b86750db92c16b09e1114ab661fde9a06eb80 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Fri, 13 Oct 2023 17:36:52 +0200 Subject: [PATCH 37/54] Make signing method configurable to allow both eth_signTransaction and account_signTransaction --- arbnode/dataposter/data_poster.go | 17 ++++++++++------- arbnode/dataposter/dataposter_test.go | 7 ++++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index 15044cc4ec..11b7a954ed 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -161,7 +161,7 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro errorCount: make(map[uint64]int), } if cfg.ExternalSigner.Enabled { - signer, sender, err := externalSigner(ctx, cfg.ExternalSigner.Address, cfg.ExternalSigner.URL) + signer, sender, err := externalSigner(ctx, &cfg.ExternalSigner) if err != nil { return nil, err } @@ -173,12 +173,12 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro // externalSigner returns signer function and ethereum address of the signer. // Returns an error if address isn't specified or if it can't connect to the // signer RPC server. -func externalSigner(ctx context.Context, addr string, rpcURL string) (signerFn, common.Address, error) { - if addr == "" { +func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, common.Address, error) { + if opts.Address == "" { return nil, common.Address{}, errors.New("external signer (From) address specified") } - sender := common.HexToAddress(addr) - client, err := rpc.DialContext(ctx, rpcURL) + sender := common.HexToAddress(opts.Address) + client, err := rpc.DialContext(ctx, opts.URL) if err != nil { return nil, common.Address{}, fmt.Errorf("error connecting external signer: %w", err) } @@ -710,6 +710,8 @@ type ExternalSignerCfg struct { URL string `koanf:"url"` // Hex encoded ethereum address of the external signer. Address string `koanf:"address"` + // API method name (e.g. eth_signTransaction). + Method string `koanf:"method"` } type DangerousConfig struct { @@ -751,6 +753,7 @@ func addExternalSignerOptions(prefix string, f *pflag.FlagSet) { f.Bool(prefix+".enabled", DefaultDataPosterConfig.ExternalSigner.Enabled, "enable external signer") f.String(prefix+".url", DefaultDataPosterConfig.ExternalSigner.URL, "external signer url") f.String(prefix+".address", DefaultDataPosterConfig.ExternalSigner.Address, "external signer address") + f.String(prefix+".method", DefaultDataPosterConfig.ExternalSigner.Method, "external signer method") } var DefaultDataPosterConfig = DataPosterConfig{ @@ -767,7 +770,7 @@ var DefaultDataPosterConfig = DataPosterConfig{ UseNoOpStorage: false, LegacyStorageEncoding: true, Dangerous: DangerousConfig{ClearDBStorage: false}, - ExternalSigner: ExternalSignerCfg{Enabled: false}, + ExternalSigner: ExternalSignerCfg{Enabled: false, Method: "eth_signTransaction"}, } var DefaultDataPosterConfigForValidator = func() DataPosterConfig { @@ -789,7 +792,7 @@ var TestDataPosterConfig = DataPosterConfig{ AllocateMempoolBalance: true, UseDBStorage: false, UseNoOpStorage: false, - ExternalSigner: ExternalSignerCfg{Enabled: false}, + ExternalSigner: ExternalSignerCfg{Enabled: false, Method: "eth_signTransaction"}, } var TestDataPosterConfigForValidator = func() DataPosterConfig { diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index c190337a05..186c85ec9c 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -71,7 +71,12 @@ func TestExternalSigner(t *testing.T) { return } }() - signer, addr, err := externalSigner(ctx, srv.address.Hex(), "http://127.0.0.1:1234") + signer, addr, err := externalSigner(ctx, + &ExternalSignerCfg{ + Address: srv.address.Hex(), + URL: "http://127.0.0.1:1234", + Method: "eth_signTransaction", + }) if err != nil { t.Fatalf("Error getting external signer: %v", err) } From 62ea1bc582eecfcf12426d997b1b98a426ae75cd Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Fri, 13 Oct 2023 14:07:29 -0500 Subject: [PATCH 38/54] update testnode-pin, fix bugs, test run nitro-testnode on foreground --- execution/gethexec/node.go | 4 ++++ nitro-testnode | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/execution/gethexec/node.go b/execution/gethexec/node.go index 1068dda967..972974b42d 100644 --- a/execution/gethexec/node.go +++ b/execution/gethexec/node.go @@ -73,6 +73,7 @@ func (c *Config) Validate() error { func ConfigAddOptions(prefix string, f *flag.FlagSet) { arbitrum.ConfigAddOptions(prefix+".rpc", f) SequencerConfigAddOptions(prefix+".sequencer", f) + headerreader.AddOptions(prefix+".parent-chain-reader", f) arbitrum.RecordingDatabaseConfigAddOptions(prefix+".recording-database", f) f.String(prefix+".forwarding-target", ConfigDefault.ForwardingTarget, "transaction forwarding target URL, or \"null\" to disable forwarding (iff not sequencer)") AddOptionsForNodeForwarderConfig(prefix+".forwarder", f) @@ -85,6 +86,7 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet) { var ConfigDefault = Config{ RPC: arbitrum.DefaultConfig, Sequencer: DefaultSequencerConfig, + ParentChainReader: headerreader.DefaultConfig, RecordingDatabase: arbitrum.DefaultRecordingDatabaseConfig, ForwardingTarget: "", TxPreChecker: DefaultTxPreCheckerConfig, @@ -96,6 +98,7 @@ var ConfigDefault = Config{ func ConfigDefaultNonSequencerTest() *Config { config := ConfigDefault + config.ParentChainReader = headerreader.Config{} config.Sequencer.Enable = false config.Forwarder = DefaultTestForwarderConfig config.ForwardingTarget = "null" @@ -107,6 +110,7 @@ func ConfigDefaultNonSequencerTest() *Config { func ConfigDefaultTest() *Config { config := ConfigDefault + config.ParentChainReader = headerreader.Config{} config.Sequencer = TestSequencerConfig config.ForwardingTarget = "null" diff --git a/nitro-testnode b/nitro-testnode index 86fc5f6275..aee6ceff9c 160000 --- a/nitro-testnode +++ b/nitro-testnode @@ -1 +1 @@ -Subproject commit 86fc5f6275c0269b5a5105bf78c1627d03b0ef9e +Subproject commit aee6ceff9c9d3fb2749da55a7d7842f23d1bfc8e From 66bec8ef23e694bf5e01b55d5158bfcd99dc4109 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Fri, 13 Oct 2023 14:36:58 -0500 Subject: [PATCH 39/54] run testnode in background --- .github/workflows/docker.yml | 2 +- .github/workflows/waitForNitro.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f8d36b780e..33049d4396 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -63,7 +63,7 @@ jobs: shell: bash run: | cd nitro-testnode - ./test-node.bash --init --dev + ./test-node.bash --init --dev & - name: Wait for rpc to come up shell: bash diff --git a/.github/workflows/waitForNitro.sh b/.github/workflows/waitForNitro.sh index 1c71298dde..e196b38d88 100755 --- a/.github/workflows/waitForNitro.sh +++ b/.github/workflows/waitForNitro.sh @@ -5,6 +5,6 @@ do if [ "$?" -eq "0" ]; then exit 0 else - sleep 10 + sleep 20 fi done \ No newline at end of file From e2b9d7717f8677d3f63c3b76a6728c6320e5aaea Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Fri, 13 Oct 2023 13:35:21 -0700 Subject: [PATCH 40/54] Change L1 to parent chain in DAS help strings --- das/das.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/das/das.go b/das/das.go index 9133b73ea4..910e511083 100644 --- a/das/das.go +++ b/das/das.go @@ -133,9 +133,9 @@ func dataAvailabilityConfigAddOptions(prefix string, f *flag.FlagSet, r role) { IpfsStorageServiceConfigAddOptions(prefix+".ipfs-storage", f) RestfulClientAggregatorConfigAddOptions(prefix+".rest-aggregator", f) - f.String(prefix+".parent-chain-node-url", DefaultDataAvailabilityConfig.ParentChainNodeURL, "URL for L1 node, only used in standalone daserver; when running as part of a node that node's L1 configuration is used") - f.Int(prefix+".parent-chain-connection-attempts", DefaultDataAvailabilityConfig.ParentChainConnectionAttempts, "layer 1 RPC connection attempts (spaced out at least 1 second per attempt, 0 to retry infinitely), only used in standalone daserver; when running as part of a node that node's L1 configuration is used") - f.String(prefix+".sequencer-inbox-address", DefaultDataAvailabilityConfig.SequencerInboxAddress, "L1 address of SequencerInbox contract") + f.String(prefix+".parent-chain-node-url", DefaultDataAvailabilityConfig.ParentChainNodeURL, "URL for parent chain node, only used in standalone daserver; when running as part of a node that node's L1 configuration is used") + f.Int(prefix+".parent-chain-connection-attempts", DefaultDataAvailabilityConfig.ParentChainConnectionAttempts, "parent chain RPC connection attempts (spaced out at least 1 second per attempt, 0 to retry infinitely), only used in standalone daserver; when running as part of a node that node's parent chain configuration is used") + f.String(prefix+".sequencer-inbox-address", DefaultDataAvailabilityConfig.SequencerInboxAddress, "parent chain address of SequencerInbox contract") } func Serialize(c *arbstate.DataAvailabilityCertificate) []byte { From 10717541ba8753997304c9eb8b81684ede1b8b4d Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Fri, 13 Oct 2023 14:33:23 -0700 Subject: [PATCH 41/54] Make clippy happy --- arbitrator/prover/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrator/prover/src/main.rs b/arbitrator/prover/src/main.rs index f820b03f4f..0a2000fc3e 100644 --- a/arbitrator/prover/src/main.rs +++ b/arbitrator/prover/src/main.rs @@ -385,7 +385,7 @@ fn main() -> Result<()> { sum.count += profile.count; let entry = func_profile .entry((module, func)) - .or_insert_with(SimpleProfile::default); + .or_default(); entry.count += sum.count; entry.total_cycles += sum.total_cycles; entry.local_cycles += profile.local_cycles; From 552283aaa9cf7da501b5aab6e22cdf5ab8a18c2e Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Fri, 13 Oct 2023 15:08:56 -0700 Subject: [PATCH 42/54] Make cargo fmt happy --- arbitrator/prover/src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arbitrator/prover/src/main.rs b/arbitrator/prover/src/main.rs index 0a2000fc3e..2c72d0b577 100644 --- a/arbitrator/prover/src/main.rs +++ b/arbitrator/prover/src/main.rs @@ -383,9 +383,7 @@ fn main() -> Result<()> { while let Some((module, func, profile)) = func_stack.pop() { sum.total_cycles += profile.total_cycles; sum.count += profile.count; - let entry = func_profile - .entry((module, func)) - .or_default(); + let entry = func_profile.entry((module, func)).or_default(); entry.count += sum.count; entry.total_cycles += sum.total_cycles; entry.local_cycles += profile.local_cycles; From c27cb4b736814df79d6f5d18ee60ca2ba6a35a5f Mon Sep 17 00:00:00 2001 From: Nodar Date: Mon, 16 Oct 2023 13:18:47 +0200 Subject: [PATCH 43/54] Update arbnode/dataposter/data_poster.go Co-authored-by: Joshua Colvin --- arbnode/dataposter/data_poster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index 11b7a954ed..a54b05c340 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -183,7 +183,7 @@ func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, com return nil, common.Address{}, fmt.Errorf("error connecting external signer: %w", err) } return func(ctx context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { - // According to the "eth_signTransaction" API definition, this shoul be + // According to the "eth_signTransaction" API definition, this should be // RLP encoded transaction object. // https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_signtransaction var rlpEncTxStr string From 46618880e1883f24228746f6b301af44f2dedc26 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Mon, 16 Oct 2023 14:57:06 +0200 Subject: [PATCH 44/54] Check that signed transaction is the one sent for signing --- arbnode/dataposter/data_poster.go | 30 ++++++++++++++------------- arbnode/dataposter/dataposter_test.go | 4 ++-- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index 11b7a954ed..476920978a 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -92,7 +92,7 @@ func parseReplacementTimes(val string) ([]time.Duration, error) { lastReplacementTime = t } if len(res) == 0 { - log.Warn("disabling replace-by-fee for data poster") + log.Warn("Disabling replace-by-fee for data poster") } // To avoid special casing "don't replace again", replace in 10 years. return append(res, time.Hour*24*365*10), nil @@ -160,7 +160,7 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro redisLock: opts.RedisLock, errorCount: make(map[uint64]int), } - if cfg.ExternalSigner.Enabled { + if cfg.ExternalSigner.URL != "" { signer, sender, err := externalSigner(ctx, &cfg.ExternalSigner) if err != nil { return nil, err @@ -182,22 +182,26 @@ func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, com if err != nil { return nil, common.Address{}, fmt.Errorf("error connecting external signer: %w", err) } + + var hasher types.Signer return func(ctx context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { // According to the "eth_signTransaction" API definition, this shoul be // RLP encoded transaction object. // https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_signtransaction - var rlpEncTxStr string - if err := client.CallContext(ctx, &rlpEncTxStr, "eth_signTransaction", tx); err != nil { + var data hexutil.Bytes + if err := client.CallContext(ctx, &data, opts.Method, tx); err != nil { return nil, fmt.Errorf("signing transaction: %w", err) } - data, err := hexutil.Decode(rlpEncTxStr) - if err != nil { - return nil, fmt.Errorf("error decoding hex: %w", err) - } var signedTx types.Transaction if err := rlp.DecodeBytes(data, &signedTx); err != nil { return nil, fmt.Errorf("error decoding signed transaction: %w", err) } + if hasher == nil { + hasher = types.LatestSignerForChainID(tx.ChainId()) + } + if hasher.Hash(tx) != hasher.Hash(&signedTx) { + return nil, fmt.Errorf("transaction: %x from external signer differs from request: %x", hasher.Hash(tx), hasher.Hash(&signedTx)) + } return &signedTx, nil }, sender, nil } @@ -703,10 +707,9 @@ type DataPosterConfig struct { } type ExternalSignerCfg struct { - // If enabled, this overrides transaction options and uses external signer + // URL of the external signer rpc server, if set this overrides transaction + // options and uses external signer // for signing transactions. - Enabled bool `koanf:"enabled"` - // URL of the external signer rpc server. URL string `koanf:"url"` // Hex encoded ethereum address of the external signer. Address string `koanf:"address"` @@ -750,7 +753,6 @@ func addDangerousOptions(prefix string, f *pflag.FlagSet) { } func addExternalSignerOptions(prefix string, f *pflag.FlagSet) { - f.Bool(prefix+".enabled", DefaultDataPosterConfig.ExternalSigner.Enabled, "enable external signer") f.String(prefix+".url", DefaultDataPosterConfig.ExternalSigner.URL, "external signer url") f.String(prefix+".address", DefaultDataPosterConfig.ExternalSigner.Address, "external signer address") f.String(prefix+".method", DefaultDataPosterConfig.ExternalSigner.Method, "external signer method") @@ -770,7 +772,7 @@ var DefaultDataPosterConfig = DataPosterConfig{ UseNoOpStorage: false, LegacyStorageEncoding: true, Dangerous: DangerousConfig{ClearDBStorage: false}, - ExternalSigner: ExternalSignerCfg{Enabled: false, Method: "eth_signTransaction"}, + ExternalSigner: ExternalSignerCfg{}, } var DefaultDataPosterConfigForValidator = func() DataPosterConfig { @@ -792,7 +794,7 @@ var TestDataPosterConfig = DataPosterConfig{ AllocateMempoolBalance: true, UseDBStorage: false, UseNoOpStorage: false, - ExternalSigner: ExternalSignerCfg{Enabled: false, Method: "eth_signTransaction"}, + ExternalSigner: ExternalSignerCfg{}, } var TestDataPosterConfigForValidator = func() DataPosterConfig { diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index 186c85ec9c..4b4768e0b4 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -75,7 +75,7 @@ func TestExternalSigner(t *testing.T) { &ExternalSignerCfg{ Address: srv.address.Hex(), URL: "http://127.0.0.1:1234", - Method: "eth_signTransaction", + Method: "test_signTransaction", }) if err != nil { t.Fatalf("Error getting external signer: %v", err) @@ -124,7 +124,7 @@ func newServer(ctx context.Context, t *testing.T) (*http.Server, *server) { s := &server{signerFn: signer, address: address} s.handlers = map[string]func(*json.RawMessage) (string, error){ - "eth_signTransaction": s.signTransaction, + "test_signTransaction": s.signTransaction, } m := http.NewServeMux() httpSrv := &http.Server{Addr: ":1234", Handler: m, ReadTimeout: 5 * time.Second} From c551ff5595d4d9a56fd31a7b658d756db6f07499 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Mon, 16 Oct 2023 15:00:14 +0200 Subject: [PATCH 45/54] List transactions in correct order in the log line --- arbnode/dataposter/data_poster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index ff17510144..fa7dfec483 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -200,7 +200,7 @@ func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, com hasher = types.LatestSignerForChainID(tx.ChainId()) } if hasher.Hash(tx) != hasher.Hash(&signedTx) { - return nil, fmt.Errorf("transaction: %x from external signer differs from request: %x", hasher.Hash(tx), hasher.Hash(&signedTx)) + return nil, fmt.Errorf("transaction: %x from external signer differs from request: %x", hasher.Hash(&signedTx), hasher.Hash(tx)) } return &signedTx, nil }, sender, nil From 3374afae18b43d4be49c45586185440d65c7a073 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Mon, 16 Oct 2023 16:48:22 +0200 Subject: [PATCH 46/54] Add TLS to the server side, expose optional root certificate path on client side --- arbnode/dataposter/data_poster.go | 35 ++++++++++++++- arbnode/dataposter/dataposter_test.go | 10 +++-- arbnode/dataposter/testdata/localhost.cnf | 52 +++++++++++++++++++++++ arbnode/dataposter/testdata/localhost.crt | 28 ++++++++++++ arbnode/dataposter/testdata/localhost.key | 28 ++++++++++++ 5 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 arbnode/dataposter/testdata/localhost.cnf create mode 100644 arbnode/dataposter/testdata/localhost.crt create mode 100644 arbnode/dataposter/testdata/localhost.key diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index fa7dfec483..56e87e3b29 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -6,9 +6,13 @@ package dataposter import ( "context" + "crypto/tls" + "crypto/x509" "errors" "fmt" "math/big" + "net/http" + "os" "strings" "sync" "time" @@ -170,6 +174,28 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro return dp, nil } +func rpcClient(ctx context.Context, opts *ExternalSignerCfg) (*rpc.Client, error) { + rootCrt, err := os.ReadFile(opts.RootCA) + if err != nil { + return nil, fmt.Errorf("error reading external signer root CA: %w", err) + } + pool := x509.NewCertPool() + pool.AppendCertsFromPEM(rootCrt) + return rpc.DialOptions( + ctx, + opts.URL, + rpc.WithHTTPClient( + &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: pool, + }, + }, + }, + ), + ) +} + // externalSigner returns signer function and ethereum address of the signer. // Returns an error if address isn't specified or if it can't connect to the // signer RPC server. @@ -177,11 +203,12 @@ func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, com if opts.Address == "" { return nil, common.Address{}, errors.New("external signer (From) address specified") } - sender := common.HexToAddress(opts.Address) - client, err := rpc.DialContext(ctx, opts.URL) + + client, err := rpcClient(ctx, opts) if err != nil { return nil, common.Address{}, fmt.Errorf("error connecting external signer: %w", err) } + sender := common.HexToAddress(opts.Address) var hasher types.Signer return func(ctx context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { @@ -715,6 +742,9 @@ type ExternalSignerCfg struct { Address string `koanf:"address"` // API method name (e.g. eth_signTransaction). Method string `koanf:"method"` + // Path to the external signer root CA certificate. + // This allows us to use self-signed certificats on the external signer. + RootCA string `koanf:"root-ca"` } type DangerousConfig struct { @@ -756,6 +786,7 @@ func addExternalSignerOptions(prefix string, f *pflag.FlagSet) { f.String(prefix+".url", DefaultDataPosterConfig.ExternalSigner.URL, "external signer url") f.String(prefix+".address", DefaultDataPosterConfig.ExternalSigner.Address, "external signer address") f.String(prefix+".method", DefaultDataPosterConfig.ExternalSigner.Method, "external signer method") + f.String(prefix+".root-ca", DefaultDataPosterConfig.ExternalSigner.RootCA, "external signer root CA") } var DefaultDataPosterConfig = DataPosterConfig{ diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index 4b4768e0b4..0b3b8cba5c 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -64,18 +64,20 @@ func TestExternalSigner(t *testing.T) { t.Fatalf("Error shutting down http server: %v", err) } }) + cert, key := "./testdata/localhost.crt", "./testdata/localhost.key" go func() { - fmt.Println("Server is listening on port 1234...") - if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - t.Errorf("ListenAndServe() unexpected error: %v", err) + fmt.Println("Server is listening on port 443...") + if err := httpSrv.ListenAndServeTLS(cert, key); err != nil && err != http.ErrServerClosed { + t.Errorf("ListenAndServeTLS() unexpected error: %v", err) return } }() signer, addr, err := externalSigner(ctx, &ExternalSignerCfg{ Address: srv.address.Hex(), - URL: "http://127.0.0.1:1234", + URL: "https://localhost:1234", Method: "test_signTransaction", + RootCA: cert, }) if err != nil { t.Fatalf("Error getting external signer: %v", err) diff --git a/arbnode/dataposter/testdata/localhost.cnf b/arbnode/dataposter/testdata/localhost.cnf new file mode 100644 index 0000000000..41647cc422 --- /dev/null +++ b/arbnode/dataposter/testdata/localhost.cnf @@ -0,0 +1,52 @@ +[req] +default_bits = 2048 +default_keyfile = server-key.pem +distinguished_name = subject +req_extensions = req_ext +x509_extensions = x509_ext +string_mask = utf8only + +[subject] +countryName = CH +countryName_default = CH + +stateOrProvinceName = Zurich +stateOrProvinceName_default = ZH + +localityName = city +localityName_default = Zurich + +organizationName = Offchain Labs +organizationName_default = Offchain Labs + +commonName = offchainlabs.ch +commonName_default = localhost + +emailAddress = Email Address +emailAddress_default = bigdeal@offchainlabs.ch + +[x509_ext] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer + +basicConstraints = CA:FALSE +keyUsage = digitalSignature, keyEncipherment +subjectAltName = @alternate_names +nsComment = "OpenSSL Generated Certificate" + +[req_ext] +subjectKeyIdentifier = hash + +basicConstraints = CA:FALSE +keyUsage = digitalSignature, keyEncipherment +subjectAltName = @alternate_names +nsComment = "OpenSSL Generated Certificate" + +[alternate_names] +DNS.1 = localhost +DNS.2 = 127.0.0.1 + +[alternate_names] +DNS.1 = localhost +DNS.2 = 127.0.0.1 + diff --git a/arbnode/dataposter/testdata/localhost.crt b/arbnode/dataposter/testdata/localhost.crt new file mode 100644 index 0000000000..ca33dfc8cc --- /dev/null +++ b/arbnode/dataposter/testdata/localhost.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEwzCCA6ugAwIBAgIUHx3SdpCP5jXZE7USUqX5uRNFKPIwDQYJKoZIhvcNAQEL +BQAwfzELMAkGA1UEBhMCQ0gxCzAJBgNVBAgMAlpIMQ8wDQYDVQQHDAZadXJpY2gx +FjAUBgNVBAoMDU9mZmNoYWluIExhYnMxEjAQBgNVBAMMCWxvY2FsaG9zdDEmMCQG +CSqGSIb3DQEJARYXYmlnZGVhbEBvZmZjaGFpbmxhYnMuY2gwHhcNMjMxMDE2MTQ0 +MDA1WhcNMjQxMDE1MTQ0MDA1WjB/MQswCQYDVQQGEwJDSDELMAkGA1UECAwCWkgx +DzANBgNVBAcMBlp1cmljaDEWMBQGA1UECgwNT2ZmY2hhaW4gTGFiczESMBAGA1UE +AwwJbG9jYWxob3N0MSYwJAYJKoZIhvcNAQkBFhdiaWdkZWFsQG9mZmNoYWlubGFi +cy5jaDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALg7XwaIh4l2Fp8a +MfNMdTQSMPMR0zpnicVTn/eiozWsqlAKaxmQM3PxJ0oVWW3iJ89p4rv5m+UjK6Dr +vsUQOzl8isgyGCTMnkLtxFlyallDNRDawRcuTPuNI9NkdJm+Zz7HooLzFeBDeS13 +iRPEXr1T/4af9MjOxqFvbw5xBY9k4tc2hPp6q00948gPWKIB9Mz4thoB2Hl2rQBY +X/WhjSnre9o9qoyBO0XAsG0mssBs1vPa9/aEp7C5cDY0HCuM1RIjhXnRpb8lC9VQ +aC+FozDffmm23EGVpLmyPs590UOtVJdTUd6Q0TAT6d7fjCRUJ12DendQf2uMFV90 +u6Yj0zUCAwEAAaOCATUwggExMB0GA1UdDgQWBBT2B3FTGFQ49JyBgDGLoZREOIGD +DTCBqAYDVR0jBIGgMIGdoYGEpIGBMH8xCzAJBgNVBAYTAkNIMQswCQYDVQQIDAJa +SDEPMA0GA1UEBwwGWnVyaWNoMRYwFAYDVQQKDA1PZmZjaGFpbiBMYWJzMRIwEAYD +VQQDDAlsb2NhbGhvc3QxJjAkBgkqhkiG9w0BCQEWF2JpZ2RlYWxAb2ZmY2hhaW5s +YWJzLmNoghQfHdJ2kI/mNdkTtRJSpfm5E0Uo8jAJBgNVHRMEAjAAMAsGA1UdDwQE +AwIFoDAfBgNVHREEGDAWgglsb2NhbGhvc3SCCTEyNy4wLjAuMTAsBglghkgBhvhC +AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwDQYJKoZIhvcNAQEL +BQADggEBAIkhBcnLeeNwUwb+sSG4Qm8JdeplHPMeViNfFIflUfIIYS00JA2q9w8W ++6Nh8s6Dn20lQETUnesYj97BdqzLjFuJYAlblhE+zP8g/3Mkpu+wZAGvQjUIRyGT +C17BEtQQgAnv5pD22jr9hpLl2KowN6Oo1gzilCA+AtMkNZFIGDOxzuIv2u8rSD89 +R/V6UEDMCgusFJnZ/GzKkUNbsrAfNUezNUal+KzMhHGHBwg4jfCNhnAAB43eRtJA +0pSRMMLcUEQnVotXDXYC3DhJmkYp1uXOH/tWs6z9xForOkWFxNMVj+zUWBi7n3Jw +N2BXlb64D96uor13U0dmvQJ72ooJc+A= +-----END CERTIFICATE----- diff --git a/arbnode/dataposter/testdata/localhost.key b/arbnode/dataposter/testdata/localhost.key new file mode 100644 index 0000000000..aad9b40b3d --- /dev/null +++ b/arbnode/dataposter/testdata/localhost.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4O18GiIeJdhaf +GjHzTHU0EjDzEdM6Z4nFU5/3oqM1rKpQCmsZkDNz8SdKFVlt4ifPaeK7+ZvlIyug +677FEDs5fIrIMhgkzJ5C7cRZcmpZQzUQ2sEXLkz7jSPTZHSZvmc+x6KC8xXgQ3kt +d4kTxF69U/+Gn/TIzsahb28OcQWPZOLXNoT6eqtNPePID1iiAfTM+LYaAdh5dq0A +WF/1oY0p63vaPaqMgTtFwLBtJrLAbNbz2vf2hKewuXA2NBwrjNUSI4V50aW/JQvV +UGgvhaMw335pttxBlaS5sj7OfdFDrVSXU1HekNEwE+ne34wkVCddg3p3UH9rjBVf +dLumI9M1AgMBAAECggEAHuc8oyKrQ5xmooUZHGP2pAeqJNfYXAtqoYpLwtUJ9hKy +1e7NdNIKw3fP/J4UrHk7btAm65us8hSCeMGatEErAhNZT0gR4zhcksMCBPQLkVIT ++HINYjdOzAJqoEbRRUnaVT5VDQy8HmyLCtyqhoGR18XbjshNnhKLYKCJ2z0Lrvf2 +3rU7bbt7/rvLitVhxVL8SIe2jWSfIgcEmEAZMigB9WAnUyQ/tAfbPy1I764LLfzD +nLXn7E2OH7GrxkLjOsH9kfERlur7V7IhC9NE/wI0q+rnILRa7Q3+ifRu8qla3bo1 +iyHl1ZmsYJ8Jnzbu9exzZaQmk42OoFPcMFm0mRe+2QKBgQDvRv0Q5JhBuVurkU98 +lzATwEO0uYmeWDMnHzrFSWAKr/x4LNQ9ytSCfe1aLxgOkZq6dQ3TyZiCYzpmwGz9 +K7/gghxmsVDKeCqiGVZOgFAWy7AhQyF6zM60oqqwSvJHhmGTsA/B5LPUiYe9lITW +ZSLVYkOzha7Coa++U8vPzI5VaQKBgQDFG4reFT79j8RKEm9jie6PdRdYMzOSDWty +Gjj5N9Jnlp1k/6RzCxjmp7w7yIorq/7fWZsQtt0UqgayOn25+I8dZeGC0BradUSB +tZbGElxPsF8Jg00ZvvK3G5mpZYDrJCud8Q05EaUZPXv9GuZhozEsTQgylVecVzsN +wyEK8VuZ7QKBgQChx9adUGIdtgzkILiknbh08j8U94mz1SCo5/WdpLHaKAlE29KZ +AQXUQP51Rng2iX4bab9yndCPADZheON3/debHX3EdUkRzFPPC+CN7TW5Y/jvVGtT +kxyDh6Ru1A2iDJr290iAKXjpUB/GL5/tMa5upiTuQYnasOWZgyC/nCf0WQKBgEwn +pRLDMLA1IMjhsInL3BEvU1KvjahLaQ0P1p1rlO6TAcLpBrewPPG5MwACLmhLLtFK +xJ/Dl02Jl8a61KLKxzi7iVLKZuWq00ouR8/FfkcHxOBfC6X74bkff9I0NogjVHrU +jKBVEe3blJEpGIP20mPka1tn2g68oUNi9dxNfm/NAoGAWj/Q0pgnNq0MQ8Lj6m99 +1baaXSo8biks3E3A3cqhHQm/j3SRnkf0lueQW8+r9yR9IWdYFXz5Waq13qK+lopE +KDmww0xr8dyMUYTP1vde7np2XKa/OX3iejDzbI3RcZN/DEV+dCBY8pqHHfaAaESu +fwBWvfD8wtwCZzB3lOZEi80= +-----END PRIVATE KEY----- From 70ab85f039739015e645ab33512f7b051a9cf404 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Mon, 16 Oct 2023 17:22:01 +0200 Subject: [PATCH 47/54] Set min tls verion --- arbnode/dataposter/data_poster.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index 56e87e3b29..eb4cde509f 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -188,7 +188,8 @@ func rpcClient(ctx context.Context, opts *ExternalSignerCfg) (*rpc.Client, error &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ - RootCAs: pool, + MinVersion: tls.VersionTLS12, + RootCAs: pool, }, }, }, From e69e47725fd87db68c5073ee0604732ed40bbc7b Mon Sep 17 00:00:00 2001 From: Tristan Wilson Date: Mon, 16 Oct 2023 17:40:19 +0200 Subject: [PATCH 48/54] Add --log-type option for daserver This adds the ability to have json logs. --- cmd/daserver/daserver.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cmd/daserver/daserver.go b/cmd/daserver/daserver.go index 335aba6a1b..b2f8728a7d 100644 --- a/cmd/daserver/daserver.go +++ b/cmd/daserver/daserver.go @@ -44,6 +44,7 @@ type DAServerConfig struct { Conf genericconf.ConfConfig `koanf:"conf"` LogLevel int `koanf:"log-level"` + LogType string `koanf:"log-type"` Metrics bool `koanf:"metrics"` MetricsServer genericconf.MetricsServerConfig `koanf:"metrics-server"` @@ -62,11 +63,12 @@ var DefaultDAServerConfig = DAServerConfig{ RESTServerTimeouts: genericconf.HTTPServerTimeoutConfigDefault, DataAvailability: das.DefaultDataAvailabilityConfig, Conf: genericconf.ConfConfigDefault, + LogLevel: int(log.LvlInfo), + LogType: "plaintext", Metrics: false, MetricsServer: genericconf.MetricsServerConfigDefault, PProf: false, PprofCfg: genericconf.PProfDefault, - LogLevel: 3, } func main() { @@ -99,6 +101,8 @@ func parseDAServer(args []string) (*DAServerConfig, error) { genericconf.PProfAddOptions("pprof-cfg", f) f.Int("log-level", int(log.LvlInfo), "log level; 1: ERROR, 2: WARN, 3: INFO, 4: DEBUG, 5: TRACE") + f.String("log-type", DefaultDAServerConfig.LogType, "log type (plaintext or json)") + das.DataAvailabilityConfigAddDaserverOptions("data-availability", f) genericconf.ConfConfigAddOptions("conf", f) @@ -178,7 +182,12 @@ func startup() error { confighelpers.PrintErrorAndExit(errors.New("please specify at least one of --enable-rest or --enable-rpc"), printSampleUsage) } - glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) + logFormat, err := genericconf.ParseLogType(serverConfig.LogType) + if err != nil { + flag.Usage() + panic(fmt.Sprintf("Error parsing log type: %v", err)) + } + glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, logFormat)) glogger.Verbosity(log.Lvl(serverConfig.LogLevel)) log.Root().SetHandler(glogger) From c77006ac01ccacabb62a6da9ccf1e2681b93555d Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Mon, 16 Oct 2023 22:55:14 -0600 Subject: [PATCH 49/54] Change default sequencer MaxBlockSpeed to 250ms --- execution/gethexec/sequencer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/execution/gethexec/sequencer.go b/execution/gethexec/sequencer.go index 77442f65e4..61792ed9b5 100644 --- a/execution/gethexec/sequencer.go +++ b/execution/gethexec/sequencer.go @@ -85,7 +85,7 @@ type SequencerConfigFetcher func() *SequencerConfig var DefaultSequencerConfig = SequencerConfig{ Enable: false, - MaxBlockSpeed: time.Millisecond * 100, + MaxBlockSpeed: time.Millisecond * 250, MaxRevertGasReject: params.TxGas + 10000, MaxAcceptableTimestampDelta: time.Hour, Forwarder: DefaultSequencerForwarderConfig, From 34fe2d041d966f6cbbc425b736c5231db0f3a7b0 Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Tue, 17 Oct 2023 19:03:08 +0200 Subject: [PATCH 50/54] Add default method for external signer --- arbnode/dataposter/data_poster.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index fa7dfec483..cf4aab9e37 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -772,7 +772,7 @@ var DefaultDataPosterConfig = DataPosterConfig{ UseNoOpStorage: false, LegacyStorageEncoding: true, Dangerous: DangerousConfig{ClearDBStorage: false}, - ExternalSigner: ExternalSignerCfg{}, + ExternalSigner: ExternalSignerCfg{Method: "eth_signTransaction"}, } var DefaultDataPosterConfigForValidator = func() DataPosterConfig { @@ -794,7 +794,7 @@ var TestDataPosterConfig = DataPosterConfig{ AllocateMempoolBalance: true, UseDBStorage: false, UseNoOpStorage: false, - ExternalSigner: ExternalSignerCfg{}, + ExternalSigner: ExternalSignerCfg{Method: "eth_signTransaction"}, } var TestDataPosterConfigForValidator = func() DataPosterConfig { From f285d2e6e93741c2ee76e36a1aa2f90f915556ea Mon Sep 17 00:00:00 2001 From: Nodar Ambroladze Date: Tue, 17 Oct 2023 19:09:49 +0200 Subject: [PATCH 51/54] Change port 443 back to 1234 --- arbnode/dataposter/dataposter_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index 0b3b8cba5c..519f5f49a2 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -66,7 +66,7 @@ func TestExternalSigner(t *testing.T) { }) cert, key := "./testdata/localhost.crt", "./testdata/localhost.key" go func() { - fmt.Println("Server is listening on port 443...") + fmt.Println("Server is listening on port 1234...") if err := httpSrv.ListenAndServeTLS(cert, key); err != nil && err != http.ErrServerClosed { t.Errorf("ListenAndServeTLS() unexpected error: %v", err) return From 295b465b0d9652e5943c042175c6d3555516a14e Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Thu, 19 Oct 2023 14:00:47 -0700 Subject: [PATCH 52/54] Stop using actions-rs --- .github/workflows/arbitrator-ci.yml | 36 ++++++++------------------- .github/workflows/ci.yml | 23 +++-------------- .github/workflows/codeql-analysis.yml | 9 ++----- .github/workflows/docker.yml | 2 +- 4 files changed, 17 insertions(+), 53 deletions(-) diff --git a/.github/workflows/arbitrator-ci.yml b/.github/workflows/arbitrator-ci.yml index f2b141fb46..8c491a421c 100644 --- a/.github/workflows/arbitrator-ci.yml +++ b/.github/workflows/arbitrator-ci.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-8 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive @@ -49,23 +49,18 @@ jobs: cache-dependency-path: '**/yarn.lock' - name: Install rust stable - uses: actions-rs/toolchain@v1 - id: install-rust + uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: "stable" - override: true components: 'llvm-tools-preview, rustfmt, clippy' + targets: 'wasm32-wasi, wasm32-unknown-unknown' - name: Install grcov - uses: actions-rs/install@v0.1 + uses: jaxxstorm/action-install-gh-release@v1.10.0 with: - crate: grcov - version: latest - use-tool-cache: true - - - name: Install rust wasm targets - run: rustup target add wasm32-wasi wasm32-unknown-unknown + repo: mozilla/grcov + tag: v0.8.18 + extension: "\\.bz2" + cache: enable - name: Cache Rust intermediate build products uses: actions/cache@v3 @@ -148,22 +143,13 @@ jobs: echo RUSTDOCFLAGS="-Cpanic=abort" >> $GITHUB_ENV - name: Clippy check - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all --manifest-path arbitrator/Cargo.toml -- -D warnings + run: cargo clippy --all --manifest-path arbitrator/Cargo.toml -- -D warnings - name: Run rust tests - uses: actions-rs/cargo@v1 - with: - command: test - args: --all --manifest-path arbitrator/Cargo.toml + run: cargo test --all --manifest-path arbitrator/Cargo.toml - name: Rustfmt - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all --manifest-path arbitrator/Cargo.toml -- --check + run: cargo fmt --all --manifest-path arbitrator/Cargo.toml -- --check - name: Make proofs from test cases run: make -j test-gen-proofs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0734aecfd0..022c26d2f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: true @@ -53,27 +53,10 @@ jobs: sudo apt-get update && sudo apt-get install -y lld-14 sudo ln -s /usr/bin/wasm-ld-14 /usr/local/bin/wasm-ld - - name: Install rust wasm32-unknown-unknown - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: "stable" - target: wasm32-unknown-unknown - - - name: Install rust wasm32-wasi - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: "stable" - target: wasm32-wasi - - name: Install rust stable - uses: actions-rs/toolchain@v1 - id: install-rust + uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: "stable" - override: true + targets: 'wasm32-unknown-unknown, wasm32-wasi' - name: Cache Build Products uses: actions/cache@v3 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index cfb5b6eda6..8b2a765f6e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -44,7 +44,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: true @@ -74,12 +74,7 @@ jobs: go-version: 1.20.x - name: Install rust stable - uses: actions-rs/toolchain@v1 - id: install-rust - with: - profile: minimal - toolchain: "stable" - override: true + uses: dtolnay/rust-toolchain@stable - name: Cache Rust Build Products uses: actions/cache@v3 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 33049d4396..dcc76465a7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive From cca0c53c64616044b9e2e5e52bfa457cc0cfc75a Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Thu, 19 Oct 2023 15:00:12 -0700 Subject: [PATCH 53/54] Use latest docker and golangci actions Old versions of docker and golangci actions used deprecated github actions methods `The CODEQL_EXTRACTOR_GO_BUILD_TRACING environment variable has no effect on workflows with manual build steps, so we recommend that you remove it from your workflow.` --- .github/workflows/ci.yml | 2 +- .github/workflows/codeql-analysis.yml | 1 - .github/workflows/docker.yml | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 022c26d2f3..de2a580c93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,7 +108,7 @@ jobs: run: make -j build-node-deps - name: Lint - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 with: version: latest skip-go-installation: true diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8b2a765f6e..8fb9d80c21 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -32,7 +32,6 @@ jobs: contents: read security-events: write env: - CODEQL_EXTRACTOR_GO_BUILD_TRACING: 'on' WABT_VERSION: 1.0.32 strategy: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index dcc76465a7..30ad88d91a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -28,7 +28,7 @@ jobs: submodules: recursive - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v3 with: driver-opts: network=host @@ -40,7 +40,7 @@ jobs: restore-keys: ${{ runner.os }}-buildx- - name: Build nitro-node docker - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v5 with: target: nitro-node push: true @@ -50,7 +50,7 @@ jobs: cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - name: Build nitro-node-dev docker - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v5 with: target: nitro-node-dev push: true From 1e1a378dc52a36cc26ad8ef6a528e7c1ef749890 Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Thu, 19 Oct 2023 15:51:03 -0700 Subject: [PATCH 54/54] Don't use removed lint option `skip-go-installation` is no longer an option for `golangci/golangci-lint-action` --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de2a580c93..f2c4fac84c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,6 @@ jobs: uses: golangci/golangci-lint-action@v3 with: version: latest - skip-go-installation: true skip-pkg-cache: true - name: Custom Lint run: |