From 98365803396daab6575f4a94ee7ca2d983df7eb5 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Mon, 11 Apr 2022 10:30:49 -0500 Subject: [PATCH 01/12] Add new NodeInterface method to find the batch containing a block --- arbnode/arb_interface.go | 9 +++ arbnode/node-interface.go | 67 +++++++++++++++++-- arbnode/node.go | 1 + .../src/node-interface/NodeInterface.sol | 7 ++ go-ethereum | 2 +- 5 files changed, 80 insertions(+), 6 deletions(-) diff --git a/arbnode/arb_interface.go b/arbnode/arb_interface.go index a2e626c1a5..8dbc6a78e9 100644 --- a/arbnode/arb_interface.go +++ b/arbnode/arb_interface.go @@ -20,6 +20,7 @@ type TransactionPublisher interface { type ArbInterface struct { txStreamer *TransactionStreamer txPublisher TransactionPublisher + arbNode *Node } func NewArbInterface(txStreamer *TransactionStreamer, txPublisher TransactionPublisher) (*ArbInterface, error) { @@ -29,6 +30,10 @@ func NewArbInterface(txStreamer *TransactionStreamer, txPublisher TransactionPub }, nil } +func (a *ArbInterface) Initialize(n *Node) { + a.arbNode = n +} + func (a *ArbInterface) PublishTransaction(ctx context.Context, tx *types.Transaction) error { return a.txPublisher.PublishTransaction(ctx, tx) } @@ -40,3 +45,7 @@ func (a *ArbInterface) TransactionStreamer() *TransactionStreamer { func (a *ArbInterface) BlockChain() *core.BlockChain { return a.txStreamer.bc } + +func (a *ArbInterface) ArbNode() interface{} { + return a.arbNode +} diff --git a/arbnode/node-interface.go b/arbnode/node-interface.go index 54e1f4554b..63322a38c8 100644 --- a/arbnode/node-interface.go +++ b/arbnode/node-interface.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/arbitrum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -23,10 +24,12 @@ import ( "github.com/offchainlabs/nitro/arbos/arbosState" "github.com/offchainlabs/nitro/arbos/retryables" "github.com/offchainlabs/nitro/arbos/util" + "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/solgen/go/node_interfacegen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" "github.com/offchainlabs/nitro/util/arbmath" "github.com/offchainlabs/nitro/util/merkletree" + "github.com/offchainlabs/nitro/validator" ) type Message = types.Message @@ -48,6 +51,7 @@ func ApplyNodeInterface( estimateMethod := nodeInterface.Methods["estimateRetryableTicket"] outboxMethod := nodeInterface.Methods["constructOutboxProof"] + findBatchMethod := nodeInterface.Methods["findBatchContainingBlock"] calldata := msg.Data() if len(calldata) < 4 { @@ -95,9 +99,7 @@ func ApplyNodeInterface( // ArbitrumSubmitRetryableTx is unsigned so the following won't panic msg, err := types.NewTx(submitTx).AsMessage(types.NewArbitrumSigner(nil), nil) return msg, nil, err - } - - if bytes.Equal(outboxMethod.ID, calldata[:4]) { + } else if bytes.Equal(outboxMethod.ID, calldata[:4]) { inputs, err := outboxMethod.Inputs.Unpack(calldata[4:]) if err != nil { return msg, nil, err @@ -109,10 +111,31 @@ func ApplyNodeInterface( return msg, nil, fmt.Errorf("leaf %v is newer than root of size %v", leaf, size) } - method := nodeInterface.Methods["constructOutboxProof"] - res, err := nodeInterfaceConstructOutboxProof(msg, ctx, size, leaf, backend, method) + res, err := nodeInterfaceConstructOutboxProof(msg, ctx, size, leaf, backend, outboxMethod) return msg, res, err + } else if bytes.Equal(findBatchMethod.ID, calldata[:4]) { + inputs, err := findBatchMethod.Inputs.Unpack(calldata[4:]) + if err != nil { + return msg, nil, err + } + block, _ := inputs[0].(uint64) + batch, err := nodeInterfaceFindBatchContainingBlock(ctx, backend, block) + if err != nil { + return msg, nil, err + } + returnData, err := findBatchMethod.Outputs.Pack(batch) + if err != nil { + return msg, nil, fmt.Errorf("internal error: failed to encode outputs: %w", err) + } + + res := &ExecutionResult{ + UsedGas: 0, + Err: nil, + ReturnData: returnData, + ScheduledTxes: nil, + } + return msg, res, err } return msg, nil, errors.New("method does not exist in NodeInterface.sol") @@ -393,6 +416,40 @@ func nodeInterfaceConstructOutboxProof( return result, nil } +func nodeInterfaceFindBatchContainingBlock(ctx context.Context, backend core.NodeInterfaceBackendAPI, block uint64) (uint64, error) { + apiBackend, ok := backend.(*arbitrum.APIBackend) + if !ok { + return 0, errors.New("API backend isn't Arbitrum") + } + arbNode, ok := apiBackend.GetArbitrumNode().(*Node) + if !ok { + return 0, errors.New("failed to get Arbitrum Node from backend") + } + genesis, err := arbNode.TxStreamer.GetGenesisBlockNumber() + if err != nil { + return 0, err + } + if block <= genesis { + return 0, fmt.Errorf("block %v is part of genesis", block) + } + pos := arbutil.BlockNumberToMessageCount(block, genesis) - 1 + high, err := arbNode.InboxTracker.GetBatchCount() + if err != nil { + return 0, err + } + high-- + latestCount, err := arbNode.InboxTracker.GetBatchMessageCount(high) + if err != nil { + return 0, err + } + latestBlock := arbutil.MessageCountToBlockNumber(latestCount, genesis) + if int64(block) > latestBlock { + return 0, fmt.Errorf("request block %v is after latest block published in batch %v", block, latestBlock) + } + + return validator.FindBatchContainingMessageIndex(arbNode.InboxTracker, pos, high) +} + func init() { nodeInterface, err := abi.JSON(strings.NewReader(node_interfacegen.NodeInterfaceABI)) if err != nil { diff --git a/arbnode/node.go b/arbnode/node.go index 2c9a58240e..378c85e424 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -655,6 +655,7 @@ func CreateNode(stack *node.Node, chainDb ethdb.Database, config *Config, l2Bloc } func (n *Node) Start(ctx context.Context) error { + n.ArbInterface.Initialize(n) err := n.TxPublisher.Initialize(ctx) if err != nil { return err diff --git a/contracts/src/node-interface/NodeInterface.sol b/contracts/src/node-interface/NodeInterface.sol index ee656325a0..c5b5f53b06 100644 --- a/contracts/src/node-interface/NodeInterface.sol +++ b/contracts/src/node-interface/NodeInterface.sol @@ -47,4 +47,11 @@ interface NodeInterface { bytes32 root, bytes32[] memory proof ); + + /** + * @notice Finds the L1 batch containing a requested L2 block, reverting if none does + * @param block The L2 block being queried + * @return batch The L1 block containing the requested L2 block + */ + function findBatchContainingBlock(uint64 block) external view returns (uint64 batch); } diff --git a/go-ethereum b/go-ethereum index ca523002de..d27f19c38b 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit ca523002ded3cbb330d86b3570084e1bb709f499 +Subproject commit d27f19c38b509fa37da948717be23dc0768fa96f From aae3096ad8afea5aeb9691264ea9c1d1724dc75a Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Mon, 11 Apr 2022 10:33:24 -0500 Subject: [PATCH 02/12] Improve error message when block number is too high --- arbnode/node-interface.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbnode/node-interface.go b/arbnode/node-interface.go index 63322a38c8..9f16c417e5 100644 --- a/arbnode/node-interface.go +++ b/arbnode/node-interface.go @@ -444,7 +444,7 @@ func nodeInterfaceFindBatchContainingBlock(ctx context.Context, backend core.Nod } latestBlock := arbutil.MessageCountToBlockNumber(latestCount, genesis) if int64(block) > latestBlock { - return 0, fmt.Errorf("request block %v is after latest block published in batch %v", block, latestBlock) + return 0, fmt.Errorf("requested block %v is after latest on-chain block %v published in batch %v", block, latestBlock, high) } return validator.FindBatchContainingMessageIndex(arbNode.InboxTracker, pos, high) From 7f326fc98b26c1f37fd423e6ce8af73fc744fc57 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Mon, 11 Apr 2022 10:45:40 -0500 Subject: [PATCH 03/12] Add latest block validated node interface method --- arbnode/node-interface.go | 64 +++++++++++++++---- .../src/node-interface/NodeInterface.sol | 7 ++ 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/arbnode/node-interface.go b/arbnode/node-interface.go index 9f16c417e5..2813dfa66d 100644 --- a/arbnode/node-interface.go +++ b/arbnode/node-interface.go @@ -52,6 +52,7 @@ func ApplyNodeInterface( estimateMethod := nodeInterface.Methods["estimateRetryableTicket"] outboxMethod := nodeInterface.Methods["constructOutboxProof"] findBatchMethod := nodeInterface.Methods["findBatchContainingBlock"] + latestValidatedMethod := nodeInterface.Methods["latestValidatedBlockAndHash"] calldata := msg.Data() if len(calldata) < 4 { @@ -120,7 +121,11 @@ func ApplyNodeInterface( } block, _ := inputs[0].(uint64) - batch, err := nodeInterfaceFindBatchContainingBlock(ctx, backend, block) + node, err := arbNodeFromBackend(backend) + if err != nil { + return msg, nil, err + } + batch, err := nodeInterfaceFindBatchContainingBlock(ctx, node, block) if err != nil { return msg, nil, err } @@ -129,6 +134,33 @@ func ApplyNodeInterface( return msg, nil, fmt.Errorf("internal error: failed to encode outputs: %w", err) } + res := &ExecutionResult{ + UsedGas: 0, + Err: nil, + ReturnData: returnData, + ScheduledTxes: nil, + } + return msg, res, err + } else if bytes.Equal(latestValidatedMethod.ID, calldata[:4]) { + _, err := latestValidatedMethod.Inputs.Unpack(calldata[4:]) + if err != nil { + return msg, nil, err + } + + node, err := arbNodeFromBackend(backend) + if err != nil { + return msg, nil, err + } + if node.BlockValidator == nil { + return msg, nil, errors.New("block validator not enabled") + } + + block, hash := node.BlockValidator.LastBlockValidatedAndHash() + returnData, err := latestValidatedMethod.Outputs.Pack(block, hash) + if err != nil { + return msg, nil, fmt.Errorf("internal error: failed to encode outputs: %w", err) + } + res := &ExecutionResult{ UsedGas: 0, Err: nil, @@ -141,6 +173,18 @@ func ApplyNodeInterface( return msg, nil, errors.New("method does not exist in NodeInterface.sol") } +func arbNodeFromBackend(backend core.NodeInterfaceBackendAPI) (*Node, error) { + apiBackend, ok := backend.(*arbitrum.APIBackend) + if !ok { + return nil, errors.New("API backend isn't Arbitrum") + } + arbNode, ok := apiBackend.GetArbitrumNode().(*Node) + if !ok { + return nil, errors.New("failed to get Arbitrum Node from backend") + } + return arbNode, nil +} + var merkleTopic common.Hash var withdrawTopic common.Hash @@ -416,16 +460,8 @@ func nodeInterfaceConstructOutboxProof( return result, nil } -func nodeInterfaceFindBatchContainingBlock(ctx context.Context, backend core.NodeInterfaceBackendAPI, block uint64) (uint64, error) { - apiBackend, ok := backend.(*arbitrum.APIBackend) - if !ok { - return 0, errors.New("API backend isn't Arbitrum") - } - arbNode, ok := apiBackend.GetArbitrumNode().(*Node) - if !ok { - return 0, errors.New("failed to get Arbitrum Node from backend") - } - genesis, err := arbNode.TxStreamer.GetGenesisBlockNumber() +func nodeInterfaceFindBatchContainingBlock(ctx context.Context, node *Node, block uint64) (uint64, error) { + genesis, err := node.TxStreamer.GetGenesisBlockNumber() if err != nil { return 0, err } @@ -433,12 +469,12 @@ func nodeInterfaceFindBatchContainingBlock(ctx context.Context, backend core.Nod return 0, fmt.Errorf("block %v is part of genesis", block) } pos := arbutil.BlockNumberToMessageCount(block, genesis) - 1 - high, err := arbNode.InboxTracker.GetBatchCount() + high, err := node.InboxTracker.GetBatchCount() if err != nil { return 0, err } high-- - latestCount, err := arbNode.InboxTracker.GetBatchMessageCount(high) + latestCount, err := node.InboxTracker.GetBatchMessageCount(high) if err != nil { return 0, err } @@ -447,7 +483,7 @@ func nodeInterfaceFindBatchContainingBlock(ctx context.Context, backend core.Nod return 0, fmt.Errorf("requested block %v is after latest on-chain block %v published in batch %v", block, latestBlock, high) } - return validator.FindBatchContainingMessageIndex(arbNode.InboxTracker, pos, high) + return validator.FindBatchContainingMessageIndex(node.InboxTracker, pos, high) } func init() { diff --git a/contracts/src/node-interface/NodeInterface.sol b/contracts/src/node-interface/NodeInterface.sol index c5b5f53b06..d1e6a4057b 100644 --- a/contracts/src/node-interface/NodeInterface.sol +++ b/contracts/src/node-interface/NodeInterface.sol @@ -54,4 +54,11 @@ interface NodeInterface { * @return batch The L1 block containing the requested L2 block */ function findBatchContainingBlock(uint64 block) external view returns (uint64 batch); + + /** + * @notice Finds the latest validated block (meaning its ancestors have also been validated) + * @return block The latest validated block number + * @return blockHash The corresponding block hash at the time of validation + */ + function latestValidatedBlockAndHash() external view returns (uint64 block, bytes32 blockHash); } From 0b821813a543fb06baaf943f17f164a61d225b0c Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Mon, 11 Apr 2022 11:18:50 -0500 Subject: [PATCH 04/12] Revert "Add latest block validated node interface method" This reverts commit 7f326fc98b26c1f37fd423e6ce8af73fc744fc57. --- arbnode/node-interface.go | 64 ++++--------------- .../src/node-interface/NodeInterface.sol | 7 -- 2 files changed, 14 insertions(+), 57 deletions(-) diff --git a/arbnode/node-interface.go b/arbnode/node-interface.go index 2813dfa66d..9f16c417e5 100644 --- a/arbnode/node-interface.go +++ b/arbnode/node-interface.go @@ -52,7 +52,6 @@ func ApplyNodeInterface( estimateMethod := nodeInterface.Methods["estimateRetryableTicket"] outboxMethod := nodeInterface.Methods["constructOutboxProof"] findBatchMethod := nodeInterface.Methods["findBatchContainingBlock"] - latestValidatedMethod := nodeInterface.Methods["latestValidatedBlockAndHash"] calldata := msg.Data() if len(calldata) < 4 { @@ -121,11 +120,7 @@ func ApplyNodeInterface( } block, _ := inputs[0].(uint64) - node, err := arbNodeFromBackend(backend) - if err != nil { - return msg, nil, err - } - batch, err := nodeInterfaceFindBatchContainingBlock(ctx, node, block) + batch, err := nodeInterfaceFindBatchContainingBlock(ctx, backend, block) if err != nil { return msg, nil, err } @@ -134,33 +129,6 @@ func ApplyNodeInterface( return msg, nil, fmt.Errorf("internal error: failed to encode outputs: %w", err) } - res := &ExecutionResult{ - UsedGas: 0, - Err: nil, - ReturnData: returnData, - ScheduledTxes: nil, - } - return msg, res, err - } else if bytes.Equal(latestValidatedMethod.ID, calldata[:4]) { - _, err := latestValidatedMethod.Inputs.Unpack(calldata[4:]) - if err != nil { - return msg, nil, err - } - - node, err := arbNodeFromBackend(backend) - if err != nil { - return msg, nil, err - } - if node.BlockValidator == nil { - return msg, nil, errors.New("block validator not enabled") - } - - block, hash := node.BlockValidator.LastBlockValidatedAndHash() - returnData, err := latestValidatedMethod.Outputs.Pack(block, hash) - if err != nil { - return msg, nil, fmt.Errorf("internal error: failed to encode outputs: %w", err) - } - res := &ExecutionResult{ UsedGas: 0, Err: nil, @@ -173,18 +141,6 @@ func ApplyNodeInterface( return msg, nil, errors.New("method does not exist in NodeInterface.sol") } -func arbNodeFromBackend(backend core.NodeInterfaceBackendAPI) (*Node, error) { - apiBackend, ok := backend.(*arbitrum.APIBackend) - if !ok { - return nil, errors.New("API backend isn't Arbitrum") - } - arbNode, ok := apiBackend.GetArbitrumNode().(*Node) - if !ok { - return nil, errors.New("failed to get Arbitrum Node from backend") - } - return arbNode, nil -} - var merkleTopic common.Hash var withdrawTopic common.Hash @@ -460,8 +416,16 @@ func nodeInterfaceConstructOutboxProof( return result, nil } -func nodeInterfaceFindBatchContainingBlock(ctx context.Context, node *Node, block uint64) (uint64, error) { - genesis, err := node.TxStreamer.GetGenesisBlockNumber() +func nodeInterfaceFindBatchContainingBlock(ctx context.Context, backend core.NodeInterfaceBackendAPI, block uint64) (uint64, error) { + apiBackend, ok := backend.(*arbitrum.APIBackend) + if !ok { + return 0, errors.New("API backend isn't Arbitrum") + } + arbNode, ok := apiBackend.GetArbitrumNode().(*Node) + if !ok { + return 0, errors.New("failed to get Arbitrum Node from backend") + } + genesis, err := arbNode.TxStreamer.GetGenesisBlockNumber() if err != nil { return 0, err } @@ -469,12 +433,12 @@ func nodeInterfaceFindBatchContainingBlock(ctx context.Context, node *Node, bloc return 0, fmt.Errorf("block %v is part of genesis", block) } pos := arbutil.BlockNumberToMessageCount(block, genesis) - 1 - high, err := node.InboxTracker.GetBatchCount() + high, err := arbNode.InboxTracker.GetBatchCount() if err != nil { return 0, err } high-- - latestCount, err := node.InboxTracker.GetBatchMessageCount(high) + latestCount, err := arbNode.InboxTracker.GetBatchMessageCount(high) if err != nil { return 0, err } @@ -483,7 +447,7 @@ func nodeInterfaceFindBatchContainingBlock(ctx context.Context, node *Node, bloc return 0, fmt.Errorf("requested block %v is after latest on-chain block %v published in batch %v", block, latestBlock, high) } - return validator.FindBatchContainingMessageIndex(node.InboxTracker, pos, high) + return validator.FindBatchContainingMessageIndex(arbNode.InboxTracker, pos, high) } func init() { diff --git a/contracts/src/node-interface/NodeInterface.sol b/contracts/src/node-interface/NodeInterface.sol index d1e6a4057b..c5b5f53b06 100644 --- a/contracts/src/node-interface/NodeInterface.sol +++ b/contracts/src/node-interface/NodeInterface.sol @@ -54,11 +54,4 @@ interface NodeInterface { * @return batch The L1 block containing the requested L2 block */ function findBatchContainingBlock(uint64 block) external view returns (uint64 batch); - - /** - * @notice Finds the latest validated block (meaning its ancestors have also been validated) - * @return block The latest validated block number - * @return blockHash The corresponding block hash at the time of validation - */ - function latestValidatedBlockAndHash() external view returns (uint64 block, bytes32 blockHash); } From 0993a9379caaa54863e8476febc5c15e1771dd99 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Mon, 11 Apr 2022 11:23:08 -0500 Subject: [PATCH 05/12] Add arb_latestValidatedBlock RPC method (and hash variant) --- arbnode/api.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arbnode/api.go b/arbnode/api.go index 1a96cda42d..b8a3387db0 100644 --- a/arbnode/api.go +++ b/arbnode/api.go @@ -5,7 +5,9 @@ package arbnode import ( "context" + "github.com/ethereum/go-ethereum/arbitrum" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/rpc" "github.com/offchainlabs/nitro/validator" @@ -23,3 +25,13 @@ func (a *BlockValidatorAPI) RevalidateBlock(ctx context.Context, blockNum rpc.Bl } return a.val.ValidateBlock(ctx, header) } + +func (a *BlockValidatorAPI) LatestValidatedBlock(ctx context.Context) (uint64, error) { + block := a.val.LastBlockValidated() + return block, nil +} + +func (a *BlockValidatorAPI) LatestValidatedBlockHash(ctx context.Context) (common.Hash, error) { + _, hash := a.val.LastBlockValidatedAndHash() + return hash, nil +} From 4bcebe77aa9a662626cae82bcc8caf59202bb6ba Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Mon, 11 Apr 2022 22:34:57 -0500 Subject: [PATCH 06/12] support marshalling & unmarshalling arbitrum tx types --- .gitignore | 2 +- arbnode/inbox_test.go | 4 ++-- arbos/addressSet/addressSet_test.go | 4 ++-- arbos/addressTable/addressTable_test.go | 4 ++-- arbos/arbosState/common_test.go | 4 ++-- arbos/blockhash/blockhash_test.go | 4 ++-- arbos/blsTable/bls_test.go | 4 ++-- arbos/common_test.go | 4 ++-- arbos/internal_tx.go | 2 +- arbos/l1pricing/common_test.go | 4 ++-- arbos/l2pricing/l2pricing_test.go | 4 ++-- arbstate/geth_test.go | 4 ++-- blsSignatures/blsSignatures_test.go | 7 ++++--- broadcaster/broadcaster_test.go | 4 ++-- das/das_test.go | 4 ++-- go-ethereum | 2 +- precompiles/ArbAddressTable_test.go | 4 ++-- system_tests/common_test.go | 2 +- system_tests/retryable_test.go | 12 ++++++++++++ util/merkletree/common_test.go | 4 ++-- util/testhelpers/testhelpers.go | 4 ++-- validator/common_test.go | 4 ++-- zeroheavy/common_test.go | 4 ++-- 23 files changed, 54 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index df1935cf4a..61d31262fe 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ target/ yarn-error.log das/dasrpc/wireFormat.pb.go das/dasrpc/wireFormat_grpc.pb.go - +local/ diff --git a/arbnode/inbox_test.go b/arbnode/inbox_test.go index 4a2a844e36..041f5e3f09 100644 --- a/arbnode/inbox_test.go +++ b/arbnode/inbox_test.go @@ -196,9 +196,9 @@ func TestTransactionStreamer(t *testing.T) { } } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/addressSet/addressSet_test.go b/arbos/addressSet/addressSet_test.go index b070f0a49a..269ef8b6e8 100644 --- a/arbos/addressSet/addressSet_test.go +++ b/arbos/addressSet/addressSet_test.go @@ -137,9 +137,9 @@ func size(t *testing.T, aset *AddressSet) uint64 { return size } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/addressTable/addressTable_test.go b/arbos/addressTable/addressTable_test.go index f7c69758cb..1dd9441633 100644 --- a/arbos/addressTable/addressTable_test.go +++ b/arbos/addressTable/addressTable_test.go @@ -140,9 +140,9 @@ func size(t *testing.T, atab *AddressTable) uint64 { return size } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/arbosState/common_test.go b/arbos/arbosState/common_test.go index 0370cf9f8c..c4bf070415 100644 --- a/arbos/arbosState/common_test.go +++ b/arbos/arbosState/common_test.go @@ -9,9 +9,9 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/blockhash/blockhash_test.go b/arbos/blockhash/blockhash_test.go index e77f36845f..71f15709d7 100644 --- a/arbos/blockhash/blockhash_test.go +++ b/arbos/blockhash/blockhash_test.go @@ -75,9 +75,9 @@ func TestBlockhash(t *testing.T) { } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/blsTable/bls_test.go b/arbos/blsTable/bls_test.go index eff73b473f..f2a9e22d94 100644 --- a/arbos/blsTable/bls_test.go +++ b/arbos/blsTable/bls_test.go @@ -45,9 +45,9 @@ func TestLegacyBLS(t *testing.T) { } } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/common_test.go b/arbos/common_test.go index d137d71bd5..c3fb070171 100644 --- a/arbos/common_test.go +++ b/arbos/common_test.go @@ -9,9 +9,9 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/internal_tx.go b/arbos/internal_tx.go index 60a35f1da5..aec8792ec5 100644 --- a/arbos/internal_tx.go +++ b/arbos/internal_tx.go @@ -40,7 +40,7 @@ func InternalTxStartBlock( } return &types.ArbitrumInternalTx{ ChainId: chainId, - Type: arbInternalTxStartBlock, + SubType: arbInternalTxStartBlock, Data: data, L2BlockNumber: l2BlockNum, } diff --git a/arbos/l1pricing/common_test.go b/arbos/l1pricing/common_test.go index 26ae2659ed..077790c114 100644 --- a/arbos/l1pricing/common_test.go +++ b/arbos/l1pricing/common_test.go @@ -9,9 +9,9 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbos/l2pricing/l2pricing_test.go b/arbos/l2pricing/l2pricing_test.go index 02246d75cc..a140fcb3a4 100644 --- a/arbos/l2pricing/l2pricing_test.go +++ b/arbos/l2pricing/l2pricing_test.go @@ -155,9 +155,9 @@ func rateEstimate(t *testing.T, pricing *L2PricingState) uint64 { return value } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/arbstate/geth_test.go b/arbstate/geth_test.go index 693c1e72e7..33b11d5235 100644 --- a/arbstate/geth_test.go +++ b/arbstate/geth_test.go @@ -137,9 +137,9 @@ func RunMessagesThroughAPI(t *testing.T, msgs [][]byte, statedb *state.StateDB) } } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/blsSignatures/blsSignatures_test.go b/blsSignatures/blsSignatures_test.go index a1e55ab7a6..34ef17ad9d 100644 --- a/blsSignatures/blsSignatures_test.go +++ b/blsSignatures/blsSignatures_test.go @@ -4,8 +4,9 @@ package blsSignatures import ( - "github.com/offchainlabs/nitro/util/testhelpers" "testing" + + "github.com/offchainlabs/nitro/util/testhelpers" ) func TestValidSignature(t *testing.T) { @@ -106,9 +107,9 @@ func TestSignatureAggregationDifferentMessages(t *testing.T) { } } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/broadcaster/broadcaster_test.go b/broadcaster/broadcaster_test.go index e3589d95b5..a25deb9320 100644 --- a/broadcaster/broadcaster_test.go +++ b/broadcaster/broadcaster_test.go @@ -127,9 +127,9 @@ func TestBroadcasterMessagesRemovedOnConfirmation(t *testing.T) { } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/das/das_test.go b/das/das_test.go index 1726287ad3..2bb64ac537 100644 --- a/das/das_test.go +++ b/das/das_test.go @@ -71,9 +71,9 @@ func TestDASMissingMessage(t *testing.T) { } } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/go-ethereum b/go-ethereum index a4a2312a62..12abba2b20 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit a4a2312a6252d5dc6e8fb43de241208cccffa857 +Subproject commit 12abba2b205b5b34c7acb41b9f2df053f40d9ead diff --git a/precompiles/ArbAddressTable_test.go b/precompiles/ArbAddressTable_test.go index 24ccdbcfbc..d55cb26759 100644 --- a/precompiles/ArbAddressTable_test.go +++ b/precompiles/ArbAddressTable_test.go @@ -162,9 +162,9 @@ func newMockEVMForTesting() *vm.EVM { return evm } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 68cce6f6df..38e4aa370b 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -249,7 +249,7 @@ func CreateTestL2WithConfig(t *testing.T, ctx context.Context, l2Info *Blockchai return l2info, node, client } -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, text ...interface{}) { t.Helper() testhelpers.RequireImpl(t, err, text...) } diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 284be0b01b..2848f65491 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -67,6 +67,18 @@ func retryableSetup(t *testing.T) ( TransferBalance(t, "Faucet", "Burn", discard, l2info, l2client, ctx) teardown := func() { + + // check the integrity of the RPC + blockNum, err := 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)) + Require(t, err, "failed to get L2 block", number, "of", blockNum) + if block.Number().Uint64() != number { + Fail(t, "block number mismatch", number, block.Number().Uint64()) + } + } + cancel() stack.Close() } diff --git a/util/merkletree/common_test.go b/util/merkletree/common_test.go index 02762a5e47..6c05a6f6ea 100644 --- a/util/merkletree/common_test.go +++ b/util/merkletree/common_test.go @@ -9,9 +9,9 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/util/testhelpers/testhelpers.go b/util/testhelpers/testhelpers.go index 2ef694da0f..347757d9e0 100644 --- a/util/testhelpers/testhelpers.go +++ b/util/testhelpers/testhelpers.go @@ -12,10 +12,10 @@ import ( ) // Fail a test should an error occur -func RequireImpl(t *testing.T, err error, text ...string) { +func RequireImpl(t *testing.T, err error, printables ...interface{}) { t.Helper() if err != nil { - t.Fatal(colors.Red, text, err, colors.Clear) + t.Fatal(colors.Red, printables, err, colors.Clear) } } diff --git a/validator/common_test.go b/validator/common_test.go index ca1ea439ae..61a6e3b936 100644 --- a/validator/common_test.go +++ b/validator/common_test.go @@ -9,9 +9,9 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { diff --git a/zeroheavy/common_test.go b/zeroheavy/common_test.go index b7023d05cb..03ab9320fc 100644 --- a/zeroheavy/common_test.go +++ b/zeroheavy/common_test.go @@ -9,9 +9,9 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func Require(t *testing.T, err error, text ...string) { +func Require(t *testing.T, err error, printables ...interface{}) { t.Helper() - testhelpers.RequireImpl(t, err, text...) + testhelpers.RequireImpl(t, err, printables...) } func Fail(t *testing.T, printables ...interface{}) { From 807e81f2ea398d36b127e5f7fe744a40da228682 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Mon, 11 Apr 2022 23:03:29 -0500 Subject: [PATCH 07/12] update pin --- go-ethereum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ethereum b/go-ethereum index 12abba2b20..c6ea63bf74 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 12abba2b205b5b34c7acb41b9f2df053f40d9ead +Subproject commit c6ea63bf749ca914cbf2160c55bd91d30d1efcff From a1c9fe32151b69cbe74b133528d045ef8600dde3 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Mon, 11 Apr 2022 18:43:01 +0300 Subject: [PATCH 08/12] require context in defaultTransactOpts --- system_tests/block_hash_test.go | 2 +- system_tests/common_test.go | 8 ++++---- system_tests/estimation_test.go | 4 ++-- system_tests/fees_test.go | 8 ++++---- system_tests/full_challenge_impl_test.go | 8 ++++---- system_tests/outbox_test.go | 2 +- system_tests/retryable_test.go | 10 +++++----- system_tests/seqinbox_test.go | 2 +- system_tests/staker_test.go | 6 +++--- system_tests/test_info.go | 13 ++++++++----- 10 files changed, 33 insertions(+), 30 deletions(-) diff --git a/system_tests/block_hash_test.go b/system_tests/block_hash_test.go index 0f7aa41508..eb96d5e380 100644 --- a/system_tests/block_hash_test.go +++ b/system_tests/block_hash_test.go @@ -19,7 +19,7 @@ func TestBlockHash(t *testing.T) { l2info, _, l2client, _, _, _, stack := CreateTestNodeOnL1(t, ctx, true) defer stack.Close() - auth := l2info.GetDefaultTransactOpts("Faucet") + auth := l2info.GetDefaultTransactOpts("Faucet", ctx) _, _, simple, err := mocksgen.DeploySimple(&auth, l2client) Require(t, err) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 68cce6f6df..f62e5c8d9d 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -60,7 +60,7 @@ func TransferBalance(t *testing.T, from, to string, amount *big.Int, l2info info func SendSignedTxViaL1(t *testing.T, ctx context.Context, l1info *BlockchainTestInfo, l1client arbutil.L1Interface, l2client arbutil.L1Interface, delayedTx *types.Transaction) *types.Receipt { delayedInboxContract, err := bridgegen.NewInbox(l1info.GetAddress("Inbox"), l1client) Require(t, err) - usertxopts := l1info.GetDefaultTransactOpts("User") + usertxopts := l1info.GetDefaultTransactOpts("User", ctx) txbytes, err := delayedTx.MarshalBinary() Require(t, err) @@ -149,7 +149,7 @@ func DeployOnTestL1(t *testing.T, ctx context.Context, l1info info, l1client cli l1info.PrepareTx("Faucet", "Sequencer", 30000, big.NewInt(9223372036854775807), nil), l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(9223372036854775807), nil)}) - l1TransactionOpts := l1info.GetDefaultTransactOpts("RollupOwner") + l1TransactionOpts := l1info.GetDefaultTransactOpts("RollupOwner", ctx) wasmModuleRoot, err := validator.DefaultNitroMachineConfig.ReadLatestWasmModuleRoot() Require(t, err) addresses, err := arbnode.DeployOnL1(ctx, l1client, &l1TransactionOpts, l1info.GetAddress("Sequencer"), 0, wasmModuleRoot, chainId, arbnode.TestL1ReaderConfig) @@ -198,7 +198,7 @@ func CreateTestNodeOnL1WithConfig(t *testing.T, ctx context.Context, isSequencer addresses := DeployOnTestL1(t, ctx, l1info, l1client, chainConfig.ChainID) var sequencerTxOptsPtr *bind.TransactOpts if isSequencer { - sequencerTxOpts := l1info.GetDefaultTransactOpts("Sequencer") + sequencerTxOpts := l1info.GetDefaultTransactOpts("Sequencer", ctx) sequencerTxOptsPtr = &sequencerTxOpts } @@ -233,7 +233,7 @@ func CreateTestL2WithConfig(t *testing.T, ctx context.Context, l2Info *Blockchai client := ClientForArbBackend(t, node.Backend) if takeOwnership { - debugAuth := l2info.GetDefaultTransactOpts("Owner") + debugAuth := l2info.GetDefaultTransactOpts("Owner", ctx) // make auth a chain owner arbdebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), client) diff --git a/system_tests/estimation_test.go b/system_tests/estimation_test.go index ae46a427e1..b47a84f224 100644 --- a/system_tests/estimation_test.go +++ b/system_tests/estimation_test.go @@ -20,7 +20,7 @@ func TestDeploy(t *testing.T) { defer cancel() l2info, _, client := CreateTestL2(t, ctx) - auth := l2info.GetDefaultTransactOpts("Owner") + auth := l2info.GetDefaultTransactOpts("Owner", ctx) auth.GasMargin = 0 // don't adjust, we want to see if the estimate alone is sufficient _, tx, simple, err := mocksgen.DeploySimple(&auth, client) @@ -46,7 +46,7 @@ func TestEstimate(t *testing.T) { defer cancel() l2info, _, client := CreateTestL2(t, ctx) - auth := l2info.GetDefaultTransactOpts("Owner") + auth := l2info.GetDefaultTransactOpts("Owner", ctx) auth.GasMargin = 0 // don't adjust, we want to see if the estimate alone is sufficient gasPrice := big.NewInt(2 * params.GWei) diff --git a/system_tests/fees_test.go b/system_tests/fees_test.go index 799398015d..e292ecf989 100644 --- a/system_tests/fees_test.go +++ b/system_tests/fees_test.go @@ -26,8 +26,8 @@ func TestTips(t *testing.T) { l2info, _, l2client, l1info, _, l1client, stack := CreateTestNodeOnL1(t, ctx, true) defer stack.Close() - auth := l2info.GetDefaultTransactOpts("Owner") - callOpts := l2info.GetDefaultCallOpts("Owner") + auth := l2info.GetDefaultTransactOpts("Owner", ctx) + callOpts := l2info.GetDefaultCallOpts("Owner", ctx) aggregator := testhelpers.RandomAddress() // get the network fee account @@ -86,7 +86,7 @@ func TestSequencerWontPostWhenNotPreferred(t *testing.T) { defer cancel() l2info, _, client := CreateTestL2(t, ctx) - auth := l2info.GetDefaultTransactOpts("Owner") + auth := l2info.GetDefaultTransactOpts("Owner", ctx) // prefer a 3rd party aggregator arbAggregator, err := precompilesgen.NewArbAggregator(common.HexToAddress("0x6d"), client) @@ -110,7 +110,7 @@ func TestSequencerFeePaid(t *testing.T) { l2info, _, l2client, _, _, _, stack := CreateTestNodeOnL1(t, ctx, true) defer stack.Close() - callOpts := l2info.GetDefaultCallOpts("Owner") + callOpts := l2info.GetDefaultCallOpts("Owner", ctx) // get the network fee account arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("0x6b"), l2client) diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index 8eb4c8444c..4d32b2baeb 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -197,10 +197,10 @@ func RunChallengeTest(t *testing.T, asserterIsCorrect bool) { conf.InboxReader.CheckDelay = time.Second rollupAddresses := DeployOnTestL1(t, ctx, l1Info, l1Backend, chainConfig.ChainID) - deployerTxOpts := l1Info.GetDefaultTransactOpts("deployer") - sequencerTxOpts := l1Info.GetDefaultTransactOpts("sequencer") - asserterTxOpts := l1Info.GetDefaultTransactOpts("asserter") - challengerTxOpts := l1Info.GetDefaultTransactOpts("challenger") + deployerTxOpts := l1Info.GetDefaultTransactOpts("deployer", ctx) + sequencerTxOpts := l1Info.GetDefaultTransactOpts("sequencer", ctx) + asserterTxOpts := l1Info.GetDefaultTransactOpts("asserter", ctx) + challengerTxOpts := l1Info.GetDefaultTransactOpts("challenger", ctx) delayedBridge, tx, _, err := mocksgen.DeployBridgeStub(&deployerTxOpts, l1Backend) Require(t, err) _, err = EnsureTxSucceeded(context.Background(), l1Backend, tx) diff --git a/system_tests/outbox_test.go b/system_tests/outbox_test.go index c31d312bce..105842a29c 100644 --- a/system_tests/outbox_test.go +++ b/system_tests/outbox_test.go @@ -35,7 +35,7 @@ func TestOutboxProofs(t *testing.T) { merkleTopic := arbSysAbi.Events["SendMerkleUpdate"].ID l2info, _, client := CreateTestL2(t, ctx) - auth := l2info.GetDefaultTransactOpts("Owner") + auth := l2info.GetDefaultTransactOpts("Owner", ctx) arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, client) Require(t, err) diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 284be0b01b..4a1201ed4f 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -100,7 +100,7 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { Require(t, err, "failed to deploy NodeInterface") // estimate the gas needed to auto-redeem the retryable - usertxoptsL2 := l2info.GetDefaultTransactOpts("Faucet") + usertxoptsL2 := l2info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL2.NoSend = true usertxoptsL2.GasMargin = 0 tx, err := nodeInterface.EstimateRetryableTicket( @@ -118,7 +118,7 @@ func TestSubmitRetryableImmediateSuccess(t *testing.T) { colors.PrintBlue("estimate: ", estimate) // submit & auto-redeem the retryable using the gas estimate - usertxoptsL1 := l1info.GetDefaultTransactOpts("Faucet") + usertxoptsL1 := l1info.GetDefaultTransactOpts("Faucet", ctx) usertxoptsL1.Value = deposit l1tx, err := delayedInbox.CreateRetryableTicket( &usertxoptsL1, @@ -159,8 +159,8 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { l2info, l1info, l2client, l1client, delayedInbox, lookupSubmitRetryableL2TxHash, ctx, teardown := retryableSetup(t) defer teardown() - ownerTxOpts := l2info.GetDefaultTransactOpts("Owner") - usertxopts := l1info.GetDefaultTransactOpts("Faucet") + ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) + usertxopts := l1info.GetDefaultTransactOpts("Faucet", ctx) usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) simpleAddr, _, simple, err := mocksgen.DeploySimple(&ownerTxOpts, l2client) @@ -238,7 +238,7 @@ func TestSubmissionGasCosts(t *testing.T) { l2info, l1info, l2client, l1client, delayedInbox, _, ctx, teardown := retryableSetup(t) defer teardown() - usertxopts := l1info.GetDefaultTransactOpts("Faucet") + usertxopts := l1info.GetDefaultTransactOpts("Faucet", ctx) usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) l2info.GenerateAccount("Refund") diff --git a/system_tests/seqinbox_test.go b/system_tests/seqinbox_test.go index d54a28a392..619630cc6a 100644 --- a/system_tests/seqinbox_test.go +++ b/system_tests/seqinbox_test.go @@ -55,7 +55,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { seqInbox, err := bridgegen.NewSequencerInbox(l1Info.GetAddress("SequencerInbox"), l1Client) Require(t, err) - seqOpts := l1Info.GetDefaultTransactOpts("Sequencer") + seqOpts := l1Info.GetDefaultTransactOpts("Sequencer", ctx) ownerAddress := l2Info.GetAddress("Owner") var startL2BlockNumber uint64 = 0 diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index 6d6f2857ba..d5529581cb 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -75,17 +75,17 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) } } - deployAuth := l1info.GetDefaultTransactOpts("RollupOwner") + deployAuth := 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") + l1authA := l1info.GetDefaultTransactOpts("ValidatorA", ctx) l1info.GenerateAccount("ValidatorB") TransferBalance(t, "Faucet", "ValidatorB", balance, l1info, l1client, ctx) - l1authB := l1info.GetDefaultTransactOpts("ValidatorB") + l1authB := l1info.GetDefaultTransactOpts("ValidatorB", ctx) valWalletAddrA, err := validator.CreateValidatorWallet(ctx, l2nodeA.DeployInfo.ValidatorWalletCreator, 0, &l1authA, l2nodeA.L1Reader) Require(t, err) diff --git a/system_tests/test_info.go b/system_tests/test_info.go index 41d0b5b5f2..48b5824973 100644 --- a/system_tests/test_info.go +++ b/system_tests/test_info.go @@ -5,13 +5,15 @@ package arbtest import ( "bytes" + "context" "crypto/ecdsa" "errors" - "github.com/offchainlabs/nitro/arbos/l2pricing" - "github.com/offchainlabs/nitro/util" "math/big" "testing" + "github.com/offchainlabs/nitro/arbos/l2pricing" + "github.com/offchainlabs/nitro/util" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -152,7 +154,7 @@ func (b *BlockchainTestInfo) GetInfoWithPrivKey(name string) *AccountInfo { return info } -func (b *BlockchainTestInfo) GetDefaultTransactOpts(name string) bind.TransactOpts { +func (b *BlockchainTestInfo) GetDefaultTransactOpts(name string, ctx context.Context) bind.TransactOpts { b.T.Helper() info := b.GetInfoWithPrivKey(name) return bind.TransactOpts{ @@ -169,12 +171,13 @@ func (b *BlockchainTestInfo) GetDefaultTransactOpts(name string) bind.TransactOp return tx.WithSignature(b.Signer, signature) }, GasMargin: 2000, // adjust by 20% + Context: ctx, } } -func (b *BlockchainTestInfo) GetDefaultCallOpts(name string) *bind.CallOpts { +func (b *BlockchainTestInfo) GetDefaultCallOpts(name string, ctx context.Context) *bind.CallOpts { b.T.Helper() - auth := b.GetDefaultTransactOpts(name) + auth := b.GetDefaultTransactOpts(name, ctx) return &bind.CallOpts{ From: auth.From, } From 19d4e21082e80990e8a53d927266246c21bf66e0 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 12 Apr 2022 14:23:38 +0300 Subject: [PATCH 09/12] merge geth-bloom and manage backend from node --- arbnode/node.go | 7 ++++++- go-ethereum | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index 39a09a6143..6bbb37f076 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -674,7 +674,11 @@ func CreateNode(stack *node.Node, chainDb ethdb.Database, config *Config, l2Bloc } func (n *Node) Start(ctx context.Context) error { - err := n.TxPublisher.Initialize(ctx) + err := n.Backend.Start() + if err != nil { + return err + } + err = n.TxPublisher.Initialize(ctx) if err != nil { return err } @@ -766,6 +770,7 @@ func (n *Node) StopAndWait() { } n.TxStreamer.StopAndWait() n.ArbInterface.BlockChain().Stop() + n.Backend.Stop() } func CreateDefaultStack() (*node.Node, error) { diff --git a/go-ethereum b/go-ethereum index a4a2312a62..a37abe1be5 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit a4a2312a6252d5dc6e8fb43de241208cccffa857 +Subproject commit a37abe1be5bdfadf8560c3c35502f5b242e5ffa8 From 63d185add6726630f12d582485979acc09c53944 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 12 Apr 2022 09:28:29 +0300 Subject: [PATCH 10/12] bloom test --- contracts/src/mocks/Simple.sol | 12 ++++ system_tests/bloom_test.go | 121 +++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 system_tests/bloom_test.go diff --git a/contracts/src/mocks/Simple.sol b/contracts/src/mocks/Simple.sol index 98286a7762..28c2905906 100644 --- a/contracts/src/mocks/Simple.sol +++ b/contracts/src/mocks/Simple.sol @@ -7,10 +7,22 @@ pragma solidity ^0.8.0; contract Simple { uint64 public counter; + event CounterEvent(uint64 count); + event NullEvent(); + function increment() external { counter++; } + function incrementEmit() external { + counter++; + emit CounterEvent(counter); + } + + function emitNullEvent() external { + emit NullEvent(); + } + function checkBlockHashes() external view returns (uint256) { require(blockhash(block.number - 1) != blockhash(block.number - 2), "SAME_BLOCK_HASH"); return block.number; diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go new file mode 100644 index 0000000000..05b14276a2 --- /dev/null +++ b/system_tests/bloom_test.go @@ -0,0 +1,121 @@ +// Copyright 2021-2022, Offchain Labs, Inc. +// For license information, see https://github.com/nitro/blob/master/LICENSE + +package arbtest + +import ( + "context" + "math/big" + "math/rand" + "testing" + "time" + + "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" +) + +func TestBloom(t *testing.T) { + 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() + + l2info.GenerateAccount("User2") + + ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) //Owner + ownerTxOpts.Context = ctx + _, tx, simple, err := mocksgen.DeploySimple(&ownerTxOpts, client) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, client, tx) + Require(t, err) + simpleABI, err := mocksgen.SimpleMetaData.GetAbi() + Require(t, err) + + countsNum := 800 + eventsNum := 20 + nullEventsNum := 50 + + eventCounts := make(map[uint64]struct{}) + nullEventCounts := make(map[uint64]struct{}) + + for i := 0; i < eventsNum; i++ { + count := uint64(rand.Int() % countsNum) + eventCounts[count] = struct{}{} + } + + for i := 0; i < nullEventsNum; i++ { + count := uint64(rand.Int() % countsNum) + nullEventCounts[count] = struct{}{} + } + + for i := 0; i <= countsNum; i++ { + var tx *types.Transaction + var err error + _, sendNullEvent := nullEventCounts[uint64(i)] + if sendNullEvent { + tx, err = simple.EmitNullEvent(&ownerTxOpts) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, client, tx) + Require(t, err) + } + + _, sendEvent := eventCounts[uint64(i)] + if sendEvent { + tx, err = simple.IncrementEmit(&ownerTxOpts) + } else { + tx, err = simple.Increment(&ownerTxOpts) + } + Require(t, err) + _, err = EnsureTxSucceeded(ctx, client, tx) + Require(t, err) + if i%100 == 0 { + t.Log("counts: ", i, "/", countsNum) + } + } + + for { + sectionSize, sectionNum := node.Backend.APIBackend().BloomStatus() + if sectionSize != 256 { + Fail(t, "unexpected section size: ", sectionSize) + } + t.Log("sections: ", sectionNum, "/", uint64(countsNum)/sectionSize) + if sectionSize*(sectionNum+1) > uint64(countsNum) && sectionNum > 1 { + break + } + <-time.After(time.Second) + } + 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 := client.FilterLogs(ctx, nullEventQuery) + Require(t, err) + if len(logs) != len(nullEventCounts) { + Fail(t, "expected ", len(nullEventCounts), " logs, got ", len(logs)) + } + incrementEventQuery := ethereum.FilterQuery{ + Topics: [][]common.Hash{{simpleABI.Events["CounterEvent"].ID}}, + } + logs, err = client.FilterLogs(ctx, incrementEventQuery) + Require(t, err) + if len(logs) != len(eventCounts) { + Fail(t, "expected ", len(eventCounts), " logs, got ", len(logs)) + } + for _, log := range logs { + parsedLog, err := simple.ParseCounterEvent(log) + Require(t, err) + _, expected := eventCounts[parsedLog.Count-1] + if !expected { + Fail(t, "unxpected count in logs: ", parsedLog.Count) + } + } +} From b11b27d0412116275178e842337cb45cfc9f3792 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 12 Apr 2022 17:26:18 +0300 Subject: [PATCH 11/12] linkt fixes --- arbnode/node.go | 4 +++- system_tests/bloom_test.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arbnode/node.go b/arbnode/node.go index 6bbb37f076..1765aee05d 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -770,7 +770,9 @@ func (n *Node) StopAndWait() { } n.TxStreamer.StopAndWait() n.ArbInterface.BlockChain().Stop() - n.Backend.Stop() + if err := n.Backend.Stop(); err != nil { + log.Error("backend stop", "err", err) + } } func CreateDefaultStack() (*node.Node, error) { diff --git a/system_tests/bloom_test.go b/system_tests/bloom_test.go index 05b14276a2..ad6520c715 100644 --- a/system_tests/bloom_test.go +++ b/system_tests/bloom_test.go @@ -28,7 +28,7 @@ func TestBloom(t *testing.T) { l2info.GenerateAccount("User2") - ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) //Owner + ownerTxOpts := l2info.GetDefaultTransactOpts("Owner", ctx) ownerTxOpts.Context = ctx _, tx, simple, err := mocksgen.DeploySimple(&ownerTxOpts, client) Require(t, err) From f036e689148fd1253e9f82c7f4f6b1fd8b2a4d3e Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Tue, 12 Apr 2022 20:47:10 -0500 Subject: [PATCH 12/12] Silence validator context canceled error --- validator/block_validator.go | 4 +++- validator/stateless_block_validator.go | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/validator/block_validator.go b/validator/block_validator.go index 1d53461a5a..e6c46ee4e1 100644 --- a/validator/block_validator.go +++ b/validator/block_validator.go @@ -333,7 +333,9 @@ func (v *BlockValidator) validate(ctx context.Context, validationStatus *validat log.Info("starting validation for block", "blockNr", entry.BlockNumber) gsEnd, delayedMsg, err := v.executeBlock(ctx, entry, preimages, seqMsg, v.validateWasmModuleRoot) if err != nil { - log.Error("Validation of block failed", "err", err) + if !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) { + log.Error("Validation of block failed", "err", err) + } return } gsExpected := entry.expectedEnd() diff --git a/validator/stateless_block_validator.go b/validator/stateless_block_validator.go index e8347f91c3..022737ec9f 100644 --- a/validator/stateless_block_validator.go +++ b/validator/stateless_block_validator.go @@ -346,10 +346,6 @@ func (v *StatelessBlockValidator) executeBlock(ctx context.Context, entry *valid log.Info("validation", "block", entry.BlockNumber, "steps", steps) } if err != nil { - if !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) { - log.Error("running machine failed", "err", err) - panic("Failed to run machine: " + err.Error()) - } return GoGlobalState{}, nil, fmt.Errorf("machine execution failed with error: %w", err) } steps += count