From 432148328e90792203822d46b92eb173379e2f9a Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Tue, 21 Nov 2023 14:28:36 +0000 Subject: [PATCH] Fix the msg bus deploy at genesis (#1652) * Fix the msg bus deploy at genesis * tests * remove ports on same test * remove more test ports * lint --- go/enclave/components/batch_executor.go | 11 ++--- go/enclave/nodetype/sequencer.go | 44 +++++++++++++++---- integration/obscuroscan/obscuroscan_test.go | 8 ++-- tools/walletextension/test/utils.go | 6 +-- .../test/wallet_extension_test.go | 42 ++++++++---------- 5 files changed, 65 insertions(+), 46 deletions(-) diff --git a/go/enclave/components/batch_executor.go b/go/enclave/components/batch_executor.go index a015182012..82e804b625 100644 --- a/go/enclave/components/batch_executor.go +++ b/go/enclave/components/batch_executor.go @@ -208,7 +208,8 @@ func (executor *batchExecutor) ComputeBatch(context *BatchExecutionContext, fail return nil, fmt.Errorf("failed adding cross chain data to batch. Cause: %w", err) } - executor.populateHeader(©Batch, allReceipts(txReceipts, ccReceipts)) + allReceipts := append(txReceipts, ccReceipts...) + executor.populateHeader(©Batch, allReceipts) if failForEmptyBatch && len(txReceipts) == 0 && len(ccReceipts) == 0 && @@ -220,7 +221,7 @@ func (executor *batchExecutor) ComputeBatch(context *BatchExecutionContext, fail } // the logs and receipts produced by the EVM have the wrong hash which must be adjusted - for _, receipt := range txReceipts { + for _, receipt := range allReceipts { receipt.BlockHash = copyBatch.Hash() for _, l := range receipt.Logs { l.BlockHash = copyBatch.Hash() @@ -229,7 +230,7 @@ func (executor *batchExecutor) ComputeBatch(context *BatchExecutionContext, fail return &ComputedBatch{ Batch: ©Batch, - Receipts: txReceipts, + Receipts: allReceipts, Commit: func(deleteEmptyObjects bool) (gethcommon.Hash, error) { executor.stateDBMutex.Lock() defer executor.stateDBMutex.Unlock() @@ -429,10 +430,6 @@ func (executor *batchExecutor) processTransactions( return executedTransactions, excludedTransactions, txReceipts, nil } -func allReceipts(txReceipts []*types.Receipt, depositReceipts []*types.Receipt) types.Receipts { - return append(txReceipts, depositReceipts...) -} - type sortByTxIndex []*types.Receipt func (c sortByTxIndex) Len() int { return len(c) } diff --git a/go/enclave/nodetype/sequencer.go b/go/enclave/nodetype/sequencer.go index cc01427a72..c8dd9dc6a0 100644 --- a/go/enclave/nodetype/sequencer.go +++ b/go/enclave/nodetype/sequencer.go @@ -164,12 +164,33 @@ func (s *sequencer) createGenesisBatch(block *common.L1Block) error { return err } - // make sure the mempool queuing system is initialized before adding the msg bus tx to it - time.Sleep(time.Second) + // produce batch #2 which has the message bus and any other system contracts + cb, err := s.produceBatch( + batch.Header.SequencerOrderNo.Add(batch.Header.SequencerOrderNo, big.NewInt(1)), + block.Hash(), + batch.Hash(), + common.L2Transactions{msgBusTx}, + uint64(time.Now().Unix()), + false, + ) + if err != nil { + if errors.Is(err, components.ErrNoTransactionsToProcess) { + // skip batch production when there are no transactions to process + // todo: this might be a useful event to track for metrics (skipping batch production because empty batch) + s.logger.Debug("Skipping batch production, no transactions to execute") + return nil + } + return fmt.Errorf(" failed producing batch. Cause: %w", err) + } - if err = s.mempool.Add(msgBusTx); err != nil { - return fmt.Errorf("failed to queue message bus creation transaction to genesis - %w", err) + if len(cb.Receipts) == 0 || cb.Receipts[0].TxHash.Hex() != msgBusTx.Hash().Hex() { + err = fmt.Errorf("message Bus contract not minted - no receipts in batch") + s.logger.Error(err.Error()) + return err } + + s.logger.Info("Message Bus Contract minted successfully", "address", cb.Receipts[0].ContractAddress.Hex()) + return nil } @@ -232,7 +253,14 @@ func (s *sequencer) createNewHeadBatch(l1HeadBlock *common.L1Block, skipBatchIfE return nil } -func (s *sequencer) produceBatch(sequencerNo *big.Int, l1Hash common.L1BlockHash, headBatch common.L2BatchHash, transactions common.L2Transactions, batchTime uint64, failForEmptyBatch bool) (*core.Batch, error) { +func (s *sequencer) produceBatch( + sequencerNo *big.Int, + l1Hash common.L1BlockHash, + headBatch common.L2BatchHash, + transactions common.L2Transactions, + batchTime uint64, + failForEmptyBatch bool, +) (*components.ComputedBatch, error) { cb, err := s.batchProducer.ComputeBatch(&components.BatchExecutionContext{ BlockPtr: l1Hash, ParentPtr: headBatch, @@ -268,7 +296,7 @@ func (s *sequencer) produceBatch(sequencerNo *big.Int, l1Hash common.L1BlockHash return nil, fmt.Errorf("unable to remove tx from mempool - %w", err) } - return cb.Batch, nil + return cb, nil } // StoreExecutedBatch - stores an executed batch in one go. This can be done for the sequencer because it is guaranteed @@ -359,11 +387,11 @@ func (s *sequencer) duplicateBatches(l1Head *types.Block, nonCanonicalL1Path []c } sequencerNo = sequencerNo.Add(sequencerNo, big.NewInt(1)) // create the duplicate and store/broadcast it, recreate batch even if it was empty - b, err := s.produceBatch(sequencerNo, l1Head.ParentHash(), currentHead, orphanBatch.Transactions, orphanBatch.Header.Time, false) + cb, err := s.produceBatch(sequencerNo, l1Head.ParentHash(), currentHead, orphanBatch.Transactions, orphanBatch.Header.Time, false) if err != nil { return fmt.Errorf("could not produce batch. Cause %w", err) } - currentHead = b.Hash() + currentHead = cb.Batch.Hash() s.logger.Info("Duplicated batch", log.BatchHashKey, currentHead) } diff --git a/integration/obscuroscan/obscuroscan_test.go b/integration/obscuroscan/obscuroscan_test.go index 1ae51db8fa..b8feb958fe 100644 --- a/integration/obscuroscan/obscuroscan_test.go +++ b/integration/obscuroscan/obscuroscan_test.go @@ -81,12 +81,12 @@ func TestObscuroscan(t *testing.T) { statusCode, body, err := fasthttp.Get(nil, fmt.Sprintf("%s/count/contracts/", serverAddress)) assert.NoError(t, err) assert.Equal(t, 200, statusCode) - assert.Equal(t, "{\"count\":1}", string(body)) + assert.Equal(t, "{\"count\":2}", string(body)) statusCode, body, err = fasthttp.Get(nil, fmt.Sprintf("%s/count/transactions/", serverAddress)) assert.NoError(t, err) assert.Equal(t, 200, statusCode) - assert.Equal(t, "{\"count\":5}", string(body)) + assert.Equal(t, "{\"count\":6}", string(body)) statusCode, body, err = fasthttp.Get(nil, fmt.Sprintf("%s/items/batch/latest/", serverAddress)) assert.NoError(t, err) @@ -120,8 +120,8 @@ func TestObscuroscan(t *testing.T) { publicTxsObj := publicTxsRes{} err = json.Unmarshal(body, &publicTxsObj) assert.NoError(t, err) - assert.Equal(t, 5, len(publicTxsObj.Result.TransactionsData)) - assert.Equal(t, uint64(5), publicTxsObj.Result.Total) + assert.Equal(t, 6, len(publicTxsObj.Result.TransactionsData)) + assert.Equal(t, uint64(6), publicTxsObj.Result.Total) statusCode, body, err = fasthttp.Get(nil, fmt.Sprintf("%s/items/batches/?offset=0&size=10", serverAddress)) assert.NoError(t, err) diff --git a/tools/walletextension/test/utils.go b/tools/walletextension/test/utils.go index 30df181267..b56b53cb3c 100644 --- a/tools/walletextension/test/utils.go +++ b/tools/walletextension/test/utils.go @@ -31,7 +31,7 @@ import ( const jsonID = "1" -func createWalExtCfg(connectPort, wallHTTPPort, wallWSPort int) *config.Config { +func createWalExtCfg(connectPort, wallHTTPPort, wallWSPort int) *config.Config { //nolint: unparam testDBPath, err := os.CreateTemp("", "") if err != nil { panic("could not create persistence file for wallet extension tests") @@ -61,7 +61,7 @@ func createWalExt(t *testing.T, walExtCfg *config.Config) func() error { } // Creates an RPC layer that the wallet extension can connect to. Returns a handle to shut down the host. -func createDummyHost(t *testing.T, wsRPCPort int) (*DummyAPI, func() error) { +func createDummyHost(t *testing.T, wsRPCPort int) (*DummyAPI, func() error) { //nolint: unparam dummyAPI := NewDummyAPI() cfg := gethnode.Config{ WSHost: common.Localhost, @@ -124,7 +124,7 @@ func makeHTTPEthJSONReqWithPath(port int, path string) []byte { } // Makes an Ethereum JSON RPC request over HTTP and returns the response body with userID query paremeter. -func makeHTTPEthJSONReqWithUserID(port int, method string, params interface{}, userID string) []byte { +func makeHTTPEthJSONReqWithUserID(port int, method string, params interface{}, userID string) []byte { //nolint: unparam reqBody := prepareRequestBody(method, params) return makeRequestHTTP(fmt.Sprintf("http://%s:%d/v1/?u=%s", common.Localhost, port, userID), reqBody) } diff --git a/tools/walletextension/test/wallet_extension_test.go b/tools/walletextension/test/wallet_extension_test.go index 85281d586d..1b811bc742 100644 --- a/tools/walletextension/test/wallet_extension_test.go +++ b/tools/walletextension/test/wallet_extension_test.go @@ -18,9 +18,7 @@ import ( const ( errFailedDecrypt = "could not decrypt bytes with viewing key" dummyParams = "dummyParams" - jsonKeyTopics = "topics" _hostWSPort = integration.StartPortWalletExtensionUnitTest - _testOffset = 100 // offset each test by a multiplier of the offset to avoid port colision. ie: hostPort := _hostWSPort + _testOffset*2 ) type testHelper struct { @@ -41,14 +39,13 @@ func TestWalletExtension(t *testing.T) { "canRegisterViewingKeyAndMakeRequestsOverWebsockets": canRegisterViewingKeyAndMakeRequestsOverWebsockets, } { t.Run(name, func(t *testing.T) { - hostPort := _hostWSPort + i*_testOffset - dummyAPI, shutDownHost := createDummyHost(t, hostPort) - shutdownWallet := createWalExt(t, createWalExtCfg(hostPort, hostPort+1, hostPort+2)) + dummyAPI, shutDownHost := createDummyHost(t, _hostWSPort) + shutdownWallet := createWalExt(t, createWalExtCfg(_hostWSPort, _hostWSPort+1, _hostWSPort+2)) h := &testHelper{ - hostPort: hostPort, - walletHTTPPort: hostPort + 1, - walletWSPort: hostPort + 2, + hostPort: _hostWSPort, + walletHTTPPort: _hostWSPort + 1, + walletWSPort: _hostWSPort + 2, hostAPI: dummyAPI, } @@ -173,14 +170,13 @@ func canRegisterViewingKeyAndMakeRequestsOverWebsockets(t *testing.T, testHelper } func TestCannotInvokeSensitiveMethodsWithoutViewingKey(t *testing.T) { - hostPort := _hostWSPort + _testOffset*7 - walletHTTPPort := hostPort + 1 - walletWSPort := hostPort + 2 + walletHTTPPort := _hostWSPort + 1 + walletWSPort := _hostWSPort + 2 - _, shutdownHost := createDummyHost(t, hostPort) + _, shutdownHost := createDummyHost(t, _hostWSPort) defer shutdownHost() //nolint: errcheck - shutdownWallet := createWalExt(t, createWalExtCfg(hostPort, walletHTTPPort, walletWSPort)) + shutdownWallet := createWalExt(t, createWalExtCfg(_hostWSPort, walletHTTPPort, walletWSPort)) defer shutdownWallet() //nolint: errcheck conn, err := openWSConn(walletWSPort) @@ -202,13 +198,12 @@ func TestCannotInvokeSensitiveMethodsWithoutViewingKey(t *testing.T) { } func TestKeysAreReloadedWhenWalletExtensionRestarts(t *testing.T) { - hostPort := _hostWSPort + _testOffset*8 - walletHTTPPort := hostPort + 1 - walletWSPort := hostPort + 2 + walletHTTPPort := _hostWSPort + 1 + walletWSPort := _hostWSPort + 2 - dummyAPI, shutdownHost := createDummyHost(t, hostPort) + dummyAPI, shutdownHost := createDummyHost(t, _hostWSPort) defer shutdownHost() //nolint: errcheck - walExtCfg := createWalExtCfg(hostPort, walletHTTPPort, walletWSPort) + walExtCfg := createWalExtCfg(_hostWSPort, walletHTTPPort, walletWSPort) shutdownWallet := createWalExt(t, walExtCfg) addr, viewingKeyBytes, signature := simulateViewingKeyRegister(t, walletHTTPPort, walletWSPort, false) @@ -278,13 +273,12 @@ func TestKeysAreReloadedWhenWalletExtensionRestarts(t *testing.T) { //} func TestGetStorageAtForReturningUserID(t *testing.T) { - hostPort := _hostWSPort + _testOffset*8 - walletHTTPPort := hostPort + 1 - walletWSPort := hostPort + 2 + walletHTTPPort := _hostWSPort + 1 + walletWSPort := _hostWSPort + 2 - createDummyHost(t, hostPort) - walExtCfg := createWalExtCfg(hostPort, walletHTTPPort, walletWSPort) - createWalExtCfg(hostPort, walletHTTPPort, walletWSPort) + createDummyHost(t, _hostWSPort) + walExtCfg := createWalExtCfg(_hostWSPort, walletHTTPPort, walletWSPort) + createWalExtCfg(_hostWSPort, walletHTTPPort, walletWSPort) createWalExt(t, walExtCfg) // create userID