diff --git a/cmd/chaininfo/arbitrum_chain_info.json b/cmd/chaininfo/arbitrum_chain_info.json index 01b60e9c05..5352f9760f 100644 --- a/cmd/chaininfo/arbitrum_chain_info.json +++ b/cmd/chaininfo/arbitrum_chain_info.json @@ -1,6 +1,5 @@ [ { - "chain-id": 42161, "chain-name": "arb1", "parent-chain-id": 1, "sequencer-url": "https://arb1-sequencer.arbitrum.io/rpc", @@ -50,7 +49,6 @@ } }, { - "chain-id": 42170, "chain-name": "nova", "parent-chain-id": 1, "sequencer-url": "https://nova.arbitrum.io/rpc", @@ -100,7 +98,6 @@ } }, { - "chain-id": 421613, "chain-name": "goerli-rollup", "parent-chain-id": 5, "sequencer-url": "https://goerli-rollup.arbitrum.io/rpc", @@ -149,7 +146,6 @@ } }, { - "chain-id": 412346, "chain-name": "arb-dev-test", "chain-config": { @@ -185,7 +181,6 @@ } }, { - "chain-id": 412347, "chain-name": "anytrust-dev-test", "chain-config": { diff --git a/cmd/chaininfo/chain_info.go b/cmd/chaininfo/chain_info.go index 46e7ada966..c9ffca9830 100644 --- a/cmd/chaininfo/chain_info.go +++ b/cmd/chaininfo/chain_info.go @@ -18,7 +18,6 @@ import ( var DefaultChainInfo []byte type ChainInfo struct { - ChainId uint64 `json:"chain-id"` ChainName string `json:"chain-name"` ParentChainId uint64 `json:"parent-chain-id"` // This is the forwarding target to submit transactions to, called the sequencer URL for clarity @@ -94,7 +93,7 @@ func findChainInfo(chainId uint64, chainName string, chainsInfoBytes []byte) (*C return nil, err } for _, chainInfo := range chainsInfo { - if (chainId == 0 || chainInfo.ChainId == chainId) && (chainName == "" || chainInfo.ChainName == chainName) { + if (chainId == 0 || chainInfo.ChainConfig.ChainID.Uint64() == chainId) && (chainName == "" || chainInfo.ChainName == chainName) { return &chainInfo, nil } } diff --git a/cmd/deploy/deploy.go b/cmd/deploy/deploy.go index 91775ced25..5cecb7d2ad 100644 --- a/cmd/deploy/deploy.go +++ b/cmd/deploy/deploy.go @@ -148,7 +148,6 @@ func main() { } chainsInfo := []chaininfo.ChainInfo{ { - ChainId: chainConfig.ChainID.Uint64(), ChainName: *l2ChainName, ParentChainId: l1ChainId.Uint64(), ChainConfig: &chainConfig, diff --git a/cmd/nitro/nitro.go b/cmd/nitro/nitro.go index f1af1388cf..ae46ff6678 100644 --- a/cmd/nitro/nitro.go +++ b/cmd/nitro/nitro.go @@ -374,12 +374,18 @@ func mainImpl() int { return 1 } + var deferFuncs []func() + defer func() { + for i := range deferFuncs { + deferFuncs[i]() + } + }() + chainDb, l2BlockChain, err := openInitializeChainDb(ctx, stack, nodeConfig, new(big.Int).SetUint64(nodeConfig.L2.ChainID), execution.DefaultCacheConfigFor(stack, &nodeConfig.Node.Caching), l1Client, rollupAddrs) - defer closeDb(chainDb, "chainDb") if l2BlockChain != nil { - // Calling Stop on the blockchain multiple times does nothing - defer l2BlockChain.Stop() + deferFuncs = append(deferFuncs, func() { l2BlockChain.Stop() }) } + deferFuncs = append(deferFuncs, func() { closeDb(chainDb, "chainDb") }) if err != nil { flag.Usage() log.Error("error initializing database", "err", err) @@ -387,7 +393,7 @@ func mainImpl() int { } arbDb, err := stack.OpenDatabase("arbitrumdata", 0, 0, "", false) - defer closeDb(arbDb, "arbDb") + deferFuncs = append(deferFuncs, func() { closeDb(arbDb, "arbDb") }) if err != nil { log.Error("failed to open database", "err", err) return 1 @@ -479,7 +485,8 @@ func mainImpl() int { if err != nil { fatalErrChan <- fmt.Errorf("error starting node: %w", err) } - defer currentNode.StopAndWait() + // remove previous deferFuncs, StopAndWait closes database and blockchain. + deferFuncs = []func(){func() { currentNode.StopAndWait() }} } sigint := make(chan os.Signal, 1) @@ -731,7 +738,7 @@ func applyChainParameters(ctx context.Context, k *koanf.Koanf, chainId uint64, c } chainDefaults := map[string]interface{}{ "persistent.chain": chainInfo.ChainName, - "chain.id": chainInfo.ChainId, + "chain.id": chainInfo.ChainConfig.ChainID.Uint64(), "parent-chain.id": chainInfo.ParentChainId, } if chainInfo.SequencerUrl != "" { diff --git a/system_tests/arbtrace_test.go b/system_tests/arbtrace_test.go index d36b9b2950..78907aa622 100644 --- a/system_tests/arbtrace_test.go +++ b/system_tests/arbtrace_test.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "errors" - "path/filepath" "testing" "time" @@ -132,7 +131,7 @@ func (s *ArbTraceAPIStub) Filter(ctx context.Context, filter *filterRequest) ([] func TestArbTraceForwarding(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ipcPath := filepath.Join(t.TempDir(), "redirect.ipc") + ipcPath := tmpPath(t, "redirect.ipc") var apis []rpc.API apis = append(apis, rpc.API{ Namespace: "arbtrace", diff --git a/system_tests/forwarder_test.go b/system_tests/forwarder_test.go index d4cf0d8eb7..0e5cca319a 100644 --- a/system_tests/forwarder_test.go +++ b/system_tests/forwarder_test.go @@ -32,7 +32,7 @@ const nodesCount = 5 // number of testnodes to create in tests func TestStaticForwarder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - ipcPath := filepath.Join(t.TempDir(), "test.ipc") + ipcPath := tmpPath(t, "test.ipc") ipcConfig := genericconf.IPCConfigDefault ipcConfig.Path = ipcPath stackConfig := stackConfigForTest(t) diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 5e4bca1a64..fa049e4d98 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -52,30 +52,38 @@ func retryableSetup(t *testing.T) ( delayedBridge, err := arbnode.NewDelayedBridge(l1client, l1info.GetAddress("Bridge"), 0) Require(t, err) - lookupSubmitRetryableL2TxHash := func(l1Receipt *types.Receipt) common.Hash { + lookupL2Hash := func(l1Receipt *types.Receipt) common.Hash { messages, err := delayedBridge.LookupMessagesInRange(ctx, l1Receipt.BlockNumber, l1Receipt.BlockNumber, nil) Require(t, err) if len(messages) == 0 { - Fatal(t, "didn't find message for retryable submission") + Fatal(t, "didn't find message for submission") } var submissionTxs []*types.Transaction + msgTypes := map[uint8]bool{ + arbostypes.L1MessageType_SubmitRetryable: true, + arbostypes.L1MessageType_EthDeposit: true, + arbostypes.L1MessageType_L2Message: true, + } + txTypes := map[uint8]bool{ + types.ArbitrumSubmitRetryableTxType: true, + types.ArbitrumDepositTxType: true, + types.ArbitrumContractTxType: true, + } for _, message := range messages { - k := message.Message.Header.Kind - if k != arbostypes.L1MessageType_SubmitRetryable && k != arbostypes.L1MessageType_EthDeposit { + if !msgTypes[message.Message.Header.Kind] { continue } txs, err := arbos.ParseL2Transactions(message.Message, params.ArbitrumDevTestChainConfig().ChainID, nil) Require(t, err) for _, tx := range txs { - if tx.Type() == types.ArbitrumSubmitRetryableTxType || tx.Type() == types.ArbitrumDepositTxType { + if txTypes[tx.Type()] { submissionTxs = append(submissionTxs, tx) } } } if len(submissionTxs) != 1 { - Fatal(t, "expected 1 tx from retryable submission, found", len(submissionTxs)) + Fatal(t, "expected 1 tx from submission, found", len(submissionTxs)) } - return submissionTxs[0].Hash() } @@ -101,7 +109,7 @@ func retryableSetup(t *testing.T) ( l2node.StopAndWait() requireClose(t, l1stack) } - return l2info, l1info, l2client, l1client, delayedInbox, lookupSubmitRetryableL2TxHash, ctx, teardown + return l2info, l1info, l2client, l1client, delayedInbox, lookupL2Hash, ctx, teardown } func TestRetryableNoExist(t *testing.T) { @@ -445,6 +453,61 @@ func TestDepositETH(t *testing.T) { } } +func TestArbitrumContractTx(t *testing.T) { + l2Info, l1Info, l2Client, l1Client, delayedInbox, lookupL2Hash, ctx, teardown := retryableSetup(t) + defer teardown() + faucetL2Addr := util.RemapL1Address(l1Info.GetAddress("Faucet")) + TransferBalanceTo(t, "Faucet", faucetL2Addr, big.NewInt(1e18), l2Info, l2Client, ctx) + + 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) + } + data, err := l2ContractABI.Pack("checkCalls", true, true, false, false, false, false) + if err != nil { + t.Fatalf("Error packing method's call data: %v", err) + } + unsignedTx := types.NewTx(&types.ArbitrumContractTx{ + ChainId: l2Info.Signer.ChainID(), + From: faucetL2Addr, + GasFeeCap: l2Info.GasPrice.Mul(l2Info.GasPrice, big.NewInt(2)), + Gas: 1e6, + To: &l2ContractAddr, + Value: common.Big0, + Data: data, + }) + txOpts := l1Info.GetDefaultTransactOpts("Faucet", ctx) + l1tx, err := delayedInbox.SendContractTransaction( + &txOpts, + arbmath.UintToBig(unsignedTx.Gas()), + unsignedTx.GasFeeCap(), + *unsignedTx.To(), + unsignedTx.Value(), + unsignedTx.Data(), + ) + if err != nil { + t.Fatalf("Error sending unsigned transaction: %v", err) + } + 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, l1Client, l1Info) + txHash := lookupL2Hash(receipt) + receipt, err = WaitForTx(ctx, l2Client, txHash, time.Second*5) + if err != nil { + t.Fatalf("EnsureTxSucceeded(%v) unexpected error: %v", unsignedTx.Hash(), err) + } + if receipt.Status != types.ReceiptStatusSuccessful { + t.Errorf("L2 transaction: %v has failed", receipt.TxHash) + } +} + func TestL1FundedUnsignedTransaction(t *testing.T) { t.Parallel() ctx := context.Background()