From 4a980a19e0b41b750d775fdaf3057cacfe70de62 Mon Sep 17 00:00:00 2001 From: Alonso Date: Tue, 2 Apr 2024 11:59:24 +0200 Subject: [PATCH 1/8] Fix ResetL1InfoRoot + typos --- aggregator/aggregator.go | 2 +- aggregator/aggregator_test.go | 10 +++++----- aggregator/interfaces.go | 2 +- l1infotree/tree.go | 20 ++++++++++++++++++- state/interfaces.go | 2 +- state/l1infotree.go | 18 +++++++++++++++++ state/pgstatestorage/l1infotree.go | 2 +- .../etrog/processor_l1_sequence_batches.go | 2 +- synchronizer/common/syncinterfaces/state.go | 1 + .../executor_trusted_batch_sync.go | 8 ++++---- synchronizer/synchronizer.go | 10 ++++++++++ test/e2e/forced_batches_vector_shared.go | 2 +- test/e2e/state_test.go | 2 +- tools/genesis/genesisparser/genesisparser.go | 12 +++++------ 14 files changed, 70 insertions(+), 23 deletions(-) diff --git a/aggregator/aggregator.go b/aggregator/aggregator.go index c135f301e9..751ade1ff7 100644 --- a/aggregator/aggregator.go +++ b/aggregator/aggregator.go @@ -1021,7 +1021,7 @@ func (a *Aggregator) buildInputProver(ctx context.Context, batchToVerify *state. if err != nil { return nil, err } - leaves, err := a.State.GetLeafsByL1InfoRoot(ctx, *l1InfoRoot, nil) + leaves, err := a.State.GetLeavesByL1InfoRoot(ctx, *l1InfoRoot, nil) if err != nil { return nil, err } diff --git a/aggregator/aggregator_test.go b/aggregator/aggregator_test.go index a071828a16..9a08afbab5 100644 --- a/aggregator/aggregator_test.go +++ b/aggregator/aggregator_test.go @@ -801,7 +801,7 @@ func TestTryGenerateBatchProof(t *testing.T) { } m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() - m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() + m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) require.NoError(err) m.proverMock.On("BatchProof", expectedInputProver).Return(nil, errBanana).Once() @@ -844,7 +844,7 @@ func TestTryGenerateBatchProof(t *testing.T) { } m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() - m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() + m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) require.NoError(err) m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once() @@ -888,7 +888,7 @@ func TestTryGenerateBatchProof(t *testing.T) { } m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() - m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() + m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) require.NoError(err) m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once() @@ -932,7 +932,7 @@ func TestTryGenerateBatchProof(t *testing.T) { } m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() - m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() + m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) require.NoError(err) m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once() @@ -989,7 +989,7 @@ func TestTryGenerateBatchProof(t *testing.T) { TimestampBatchEtrog: &t, } m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() - m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() + m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) require.NoError(err) m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once() diff --git a/aggregator/interfaces.go b/aggregator/interfaces.go index 0d6b11b7ed..a6e464e3aa 100644 --- a/aggregator/interfaces.go +++ b/aggregator/interfaces.go @@ -65,7 +65,7 @@ type stateInterface interface { CleanupGeneratedProofs(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error CleanupLockedProofs(ctx context.Context, duration string, dbTx pgx.Tx) (int64, error) GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error) - GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) + GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error) GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error) GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error) diff --git a/l1infotree/tree.go b/l1infotree/tree.go index e0c19da6bf..0314df8a68 100644 --- a/l1infotree/tree.go +++ b/l1infotree/tree.go @@ -26,7 +26,7 @@ func NewL1InfoTree(height uint8, initialLeaves [][32]byte) (*L1InfoTree, error) var err error mt.siblings, mt.currentRoot, err = mt.initSiblings(initialLeaves) if err != nil { - log.Error("error initializing si siblings. Error: ", err) + log.Error("error initializing siblings. Error: ", err) return nil, err } log.Debug("Initial count: ", mt.count) @@ -34,6 +34,24 @@ func NewL1InfoTree(height uint8, initialLeaves [][32]byte) (*L1InfoTree, error) return mt, nil } +func (mt *L1InfoTree) ResetL1InfoTree(initialLeaves [][32]byte) (*L1InfoTree, error) { + newMT := &L1InfoTree{ + zeroHashes: mt.zeroHashes, + height: mt.height, + count: uint32(len(initialLeaves)), + } + var err error + newMT.siblings, newMT.currentRoot, err = newMT.initSiblings(initialLeaves) + if err != nil { + log.Error("error initializing siblings. Error: ", err) + return nil, err + } + log.Debug("Reset initial count: ", newMT.count) + log.Debug("Reset initial root: ", newMT.currentRoot) + mt = newMT + return newMT, nil +} + func buildIntermediate(leaves [][32]byte) ([][][]byte, [][32]byte) { var ( nodes [][][]byte diff --git a/state/interfaces.go b/state/interfaces.go index bbd47d1ba5..ac9c2a0a67 100644 --- a/state/interfaces.go +++ b/state/interfaces.go @@ -146,7 +146,7 @@ type storage interface { GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error) GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error) GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error) - GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]L1InfoTreeExitRootStorageEntry, error) + GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]L1InfoTreeExitRootStorageEntry, error) GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error) GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error) GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error) diff --git a/state/l1infotree.go b/state/l1infotree.go index ea89d0e206..1721ed8e58 100644 --- a/state/l1infotree.go +++ b/state/l1infotree.go @@ -87,6 +87,24 @@ func (s *State) AddL1InfoTreeLeaf(ctx context.Context, l1InfoTreeLeaf *L1InfoTre return &entry, nil } +func (s *State) ResetL1InfoTree(ctx context.Context, dbTx pgx.Tx) error { + allLeaves, err := s.GetAllL1InfoRootEntries(ctx, dbTx) + if err != nil { + log.Error("error getting all leaves to reset l1InfoTree. Error: ", err) + return err + } + var leaves [][32]byte + for _, leaf := range allLeaves { + leaves = append(leaves, leaf.Hash()) + } + s.l1InfoTree, err = s.l1InfoTree.ResetL1InfoTree(leaves) + if err != nil { + log.Error("error resetting l1InfoTree. Error: ", err) + return err + } + return nil +} + // GetCurrentL1InfoRoot Return current L1InfoRoot func (s *State) GetCurrentL1InfoRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error) { err := s.buildL1InfoTreeCacheIfNeed(ctx, dbTx) diff --git a/state/pgstatestorage/l1infotree.go b/state/pgstatestorage/l1infotree.go index 450124dde2..ed3fe2dd38 100644 --- a/state/pgstatestorage/l1infotree.go +++ b/state/pgstatestorage/l1infotree.go @@ -112,7 +112,7 @@ func (p *PostgresStorage) GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTr return entry, nil } -func (p *PostgresStorage) GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) { +func (p *PostgresStorage) GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) { // TODO: Optimize this query const getLeafsByL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index FROM state.exit_root diff --git a/synchronizer/actions/etrog/processor_l1_sequence_batches.go b/synchronizer/actions/etrog/processor_l1_sequence_batches.go index aa82c9c791..e1528594d9 100644 --- a/synchronizer/actions/etrog/processor_l1_sequence_batches.go +++ b/synchronizer/actions/etrog/processor_l1_sequence_batches.go @@ -391,7 +391,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) checkTrustedState(ctx context.Context, reason := reorgReasons.String() if p.sync.IsTrustedSequencer() { - log.Errorf("TRUSTED REORG DETECTED! Batch: %d reson:%s", batch.BatchNumber, reason) + log.Errorf("TRUSTED REORG DETECTED! Batch: %d reason:%s", batch.BatchNumber, reason) // Halt function never have to return! it must blocks the process p.halt(ctx, fmt.Errorf("TRUSTED REORG DETECTED! Batch: %d", batch.BatchNumber)) log.Errorf("CRITICAL!!!: Never have to execute this code. Halt function never have to return! it must blocks the process") diff --git a/synchronizer/common/syncinterfaces/state.go b/synchronizer/common/syncinterfaces/state.go index 2895eb0903..e1b62b1fe6 100644 --- a/synchronizer/common/syncinterfaces/state.go +++ b/synchronizer/common/syncinterfaces/state.go @@ -28,6 +28,7 @@ type StateFullInterface interface { AddForcedBatch(ctx context.Context, forcedBatch *state.ForcedBatch, dbTx pgx.Tx) error AddBlock(ctx context.Context, block *state.Block, dbTx pgx.Tx) error Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) error + ResetL1InfoTree(ctx context.Context, dbTx pgx.Tx) error GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*state.Block, error) GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) diff --git a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go index bb1a0798fa..7c89494441 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go @@ -136,13 +136,13 @@ func (b *SyncTrustedBatchExecutorForEtrog) FullProcess(ctx context.Context, data return nil, err } - leafs, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, data.TrustedBatch.BatchL2Data, dbTx) + leaves, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, data.TrustedBatch.BatchL2Data, dbTx) if err != nil { log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err) return nil, err } debugStr := data.DebugPrefix - processBatchResp, err := b.processAndStoreTxs(ctx, b.getProcessRequest(data, leafs, l1InfoRoot), dbTx, debugStr) + processBatchResp, err := b.processAndStoreTxs(ctx, b.getProcessRequest(data, leaves, l1InfoRoot), dbTx, debugStr) if err != nil { log.Error("%s error procesingAndStoringTxs. Error: ", debugStr, err) return nil, err @@ -197,7 +197,7 @@ func (b *SyncTrustedBatchExecutorForEtrog) IncrementalProcess(ctx context.Contex return nil, err } - leafs, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, PartialBatchL2Data, dbTx) + leaves, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, PartialBatchL2Data, dbTx) if err != nil { log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err) // TODO: Need to refine, depending of the response of GetL1InfoTreeDataFromBatchL2Data @@ -205,7 +205,7 @@ func (b *SyncTrustedBatchExecutorForEtrog) IncrementalProcess(ctx context.Contex return nil, syncinterfaces.ErrMissingSyncFromL1 } debugStr := fmt.Sprintf("%s: Batch %d:", data.Mode, uint64(data.TrustedBatch.Number)) - processReq := b.getProcessRequest(data, leafs, l1InfoRoot) + processReq := b.getProcessRequest(data, leaves, l1InfoRoot) processReq.Transactions = PartialBatchL2Data processBatchResp, err := b.processAndStoreTxs(ctx, processReq, dbTx, debugStr) if err != nil { diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 280cfe201f..23ad2b94c3 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -695,6 +695,16 @@ func (s *ClientSynchronizer) resetState(blockNumber uint64) error { log.Error("error processing reorg on eth tx manager. Error: ", err) return err } + err = s.state.ResetL1InfoTree(s.ctx, dbTx) + if err != nil { + rollbackErr := dbTx.Rollback(s.ctx) + if rollbackErr != nil { + log.Errorf("error rolling back state when resetting l1InfoTree. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err) + return rollbackErr + } + log.Error("error resetting the l1InfoTree. Error: ", err) + return err + } err = dbTx.Commit(s.ctx) if err != nil { rollbackErr := dbTx.Rollback(s.ctx) diff --git a/test/e2e/forced_batches_vector_shared.go b/test/e2e/forced_batches_vector_shared.go index e7680bfc74..b84f660fcd 100644 --- a/test/e2e/forced_batches_vector_shared.go +++ b/test/e2e/forced_batches_vector_shared.go @@ -93,7 +93,7 @@ func LaunchTestForcedBatchesVectorFilesGroup(t *testing.T, vectorFilesDir string } log.Info("#######################") - log.Info("# Verifying new leafs #") + log.Info("# Verifying new leaves #") log.Info("#######################") merkleTree := opsman.State().GetTree() for _, expectedNewLeaf := range testCase.ExpectedNewLeafs { diff --git a/test/e2e/state_test.go b/test/e2e/state_test.go index e921597077..20a652547a 100644 --- a/test/e2e/state_test.go +++ b/test/e2e/state_test.go @@ -82,7 +82,7 @@ func TestStateTransition(t *testing.T) { st := opsman.State() - // Check leafs + // Check leaves l2Block, err := st.GetLastL2Block(ctx, nil) require.NoError(t, err) for addrStr, leaf := range testCase.ExpectedNewLeafs { diff --git a/tools/genesis/genesisparser/genesisparser.go b/tools/genesis/genesisparser/genesisparser.go index 27a037ebe0..d6109ff969 100644 --- a/tools/genesis/genesisparser/genesisparser.go +++ b/tools/genesis/genesisparser/genesisparser.go @@ -16,32 +16,32 @@ type GenesisAccountTest struct { // GenesisTest2Actions change format from testvector to the used internaly func GenesisTest2Actions(accounts []GenesisAccountTest) []*state.GenesisAction { - leafs := make([]*state.GenesisAction, 0) + leaves := make([]*state.GenesisAction, 0) for _, acc := range accounts { if len(acc.Balance) != 0 && acc.Balance != "0" { - leafs = append(leafs, &state.GenesisAction{ + leaves = append(leaves, &state.GenesisAction{ Address: acc.Address, Type: int(merkletree.LeafTypeBalance), Value: acc.Balance, }) } if len(acc.Nonce) != 0 && acc.Nonce != "0" { - leafs = append(leafs, &state.GenesisAction{ + leaves = append(leaves, &state.GenesisAction{ Address: acc.Address, Type: int(merkletree.LeafTypeNonce), Value: acc.Nonce, }) } if len(acc.Bytecode) != 0 { - leafs = append(leafs, &state.GenesisAction{ + leaves = append(leaves, &state.GenesisAction{ Address: acc.Address, Type: int(merkletree.LeafTypeCode), Bytecode: acc.Bytecode, }) } for key, value := range acc.Storage { - leafs = append(leafs, &state.GenesisAction{ + leaves = append(leaves, &state.GenesisAction{ Address: acc.Address, Type: int(merkletree.LeafTypeStorage), StoragePosition: key, @@ -49,5 +49,5 @@ func GenesisTest2Actions(accounts []GenesisAccountTest) []*state.GenesisAction { }) } } - return leafs + return leaves } From 47283aef07666241f2ade0aee6a390c82da835a5 Mon Sep 17 00:00:00 2001 From: Alonso Date: Tue, 2 Apr 2024 12:00:20 +0200 Subject: [PATCH 2/8] mocks --- aggregator/mocks/mock_state.go | 6 +-- state/mocks/mock_storage.go | 22 ++++----- .../mocks/state_full_interface.go | 47 +++++++++++++++++++ 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/aggregator/mocks/mock_state.go b/aggregator/mocks/mock_state.go index cfc5b66e7d..24d5768523 100644 --- a/aggregator/mocks/mock_state.go +++ b/aggregator/mocks/mock_state.go @@ -295,12 +295,12 @@ func (_m *StateMock) GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*st return r0, r1 } -// GetLeafsByL1InfoRoot provides a mock function with given fields: ctx, l1InfoRoot, dbTx -func (_m *StateMock) GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) { +// GetLeavesByL1InfoRoot provides a mock function with given fields: ctx, l1InfoRoot, dbTx +func (_m *StateMock) GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) { ret := _m.Called(ctx, l1InfoRoot, dbTx) if len(ret) == 0 { - panic("no return value specified for GetLeafsByL1InfoRoot") + panic("no return value specified for GetLeavesByL1InfoRoot") } var r0 []state.L1InfoTreeExitRootStorageEntry diff --git a/state/mocks/mock_storage.go b/state/mocks/mock_storage.go index 2574697028..d47b4524bd 100644 --- a/state/mocks/mock_storage.go +++ b/state/mocks/mock_storage.go @@ -4947,12 +4947,12 @@ func (_c *StorageMock_GetLatestVirtualBatchTimestamp_Call) RunAndReturn(run func return _c } -// GetLeafsByL1InfoRoot provides a mock function with given fields: ctx, l1InfoRoot, dbTx -func (_m *StorageMock) GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) { +// GetLeavesByL1InfoRoot provides a mock function with given fields: ctx, l1InfoRoot, dbTx +func (_m *StorageMock) GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) { ret := _m.Called(ctx, l1InfoRoot, dbTx) if len(ret) == 0 { - panic("no return value specified for GetLeafsByL1InfoRoot") + panic("no return value specified for GetLeavesByL1InfoRoot") } var r0 []state.L1InfoTreeExitRootStorageEntry @@ -4977,32 +4977,32 @@ func (_m *StorageMock) GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot comm return r0, r1 } -// StorageMock_GetLeafsByL1InfoRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLeafsByL1InfoRoot' -type StorageMock_GetLeafsByL1InfoRoot_Call struct { +// StorageMock_GetLeavesByL1InfoRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLeavesByL1InfoRoot' +type StorageMock_GetLeavesByL1InfoRoot_Call struct { *mock.Call } -// GetLeafsByL1InfoRoot is a helper method to define mock.On call +// GetLeavesByL1InfoRoot is a helper method to define mock.On call // - ctx context.Context // - l1InfoRoot common.Hash // - dbTx pgx.Tx -func (_e *StorageMock_Expecter) GetLeafsByL1InfoRoot(ctx interface{}, l1InfoRoot interface{}, dbTx interface{}) *StorageMock_GetLeafsByL1InfoRoot_Call { - return &StorageMock_GetLeafsByL1InfoRoot_Call{Call: _e.mock.On("GetLeafsByL1InfoRoot", ctx, l1InfoRoot, dbTx)} +func (_e *StorageMock_Expecter) GetLeavesByL1InfoRoot(ctx interface{}, l1InfoRoot interface{}, dbTx interface{}) *StorageMock_GetLeavesByL1InfoRoot_Call { + return &StorageMock_GetLeavesByL1InfoRoot_Call{Call: _e.mock.On("GetLeavesByL1InfoRoot", ctx, l1InfoRoot, dbTx)} } -func (_c *StorageMock_GetLeafsByL1InfoRoot_Call) Run(run func(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx)) *StorageMock_GetLeafsByL1InfoRoot_Call { +func (_c *StorageMock_GetLeavesByL1InfoRoot_Call) Run(run func(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx)) *StorageMock_GetLeavesByL1InfoRoot_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(common.Hash), args[2].(pgx.Tx)) }) return _c } -func (_c *StorageMock_GetLeafsByL1InfoRoot_Call) Return(_a0 []state.L1InfoTreeExitRootStorageEntry, _a1 error) *StorageMock_GetLeafsByL1InfoRoot_Call { +func (_c *StorageMock_GetLeavesByL1InfoRoot_Call) Return(_a0 []state.L1InfoTreeExitRootStorageEntry, _a1 error) *StorageMock_GetLeavesByL1InfoRoot_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *StorageMock_GetLeafsByL1InfoRoot_Call) RunAndReturn(run func(context.Context, common.Hash, pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error)) *StorageMock_GetLeafsByL1InfoRoot_Call { +func (_c *StorageMock_GetLeavesByL1InfoRoot_Call) RunAndReturn(run func(context.Context, common.Hash, pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error)) *StorageMock_GetLeavesByL1InfoRoot_Call { _c.Call.Return(run) return _c } diff --git a/synchronizer/common/syncinterfaces/mocks/state_full_interface.go b/synchronizer/common/syncinterfaces/mocks/state_full_interface.go index f41e906728..1559654641 100644 --- a/synchronizer/common/syncinterfaces/mocks/state_full_interface.go +++ b/synchronizer/common/syncinterfaces/mocks/state_full_interface.go @@ -2343,6 +2343,53 @@ func (_c *StateFullInterface_ResetForkID_Call) RunAndReturn(run func(context.Con return _c } +// ResetL1InfoTree provides a mock function with given fields: ctx, dbTx +func (_m *StateFullInterface) ResetL1InfoTree(ctx context.Context, dbTx pgx.Tx) error { + ret := _m.Called(ctx, dbTx) + + if len(ret) == 0 { + panic("no return value specified for ResetL1InfoTree") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) error); ok { + r0 = rf(ctx, dbTx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// StateFullInterface_ResetL1InfoTree_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResetL1InfoTree' +type StateFullInterface_ResetL1InfoTree_Call struct { + *mock.Call +} + +// ResetL1InfoTree is a helper method to define mock.On call +// - ctx context.Context +// - dbTx pgx.Tx +func (_e *StateFullInterface_Expecter) ResetL1InfoTree(ctx interface{}, dbTx interface{}) *StateFullInterface_ResetL1InfoTree_Call { + return &StateFullInterface_ResetL1InfoTree_Call{Call: _e.mock.On("ResetL1InfoTree", ctx, dbTx)} +} + +func (_c *StateFullInterface_ResetL1InfoTree_Call) Run(run func(ctx context.Context, dbTx pgx.Tx)) *StateFullInterface_ResetL1InfoTree_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(pgx.Tx)) + }) + return _c +} + +func (_c *StateFullInterface_ResetL1InfoTree_Call) Return(_a0 error) *StateFullInterface_ResetL1InfoTree_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *StateFullInterface_ResetL1InfoTree_Call) RunAndReturn(run func(context.Context, pgx.Tx) error) *StateFullInterface_ResetL1InfoTree_Call { + _c.Call.Return(run) + return _c +} + // ResetTrustedState provides a mock function with given fields: ctx, batchNumber, dbTx func (_m *StateFullInterface) ResetTrustedState(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error { ret := _m.Called(ctx, batchNumber, dbTx) From b7822d3a2c12f0714f5d65c83e3ee88098188b07 Mon Sep 17 00:00:00 2001 From: Alonso Date: Tue, 2 Apr 2024 12:57:25 +0200 Subject: [PATCH 3/8] linter --- l1infotree/tree.go | 2 ++ state/l1infotree.go | 1 + 2 files changed, 3 insertions(+) diff --git a/l1infotree/tree.go b/l1infotree/tree.go index 0314df8a68..5268156406 100644 --- a/l1infotree/tree.go +++ b/l1infotree/tree.go @@ -34,7 +34,9 @@ func NewL1InfoTree(height uint8, initialLeaves [][32]byte) (*L1InfoTree, error) return mt, nil } +// ResetL1InfoTree resets the L1InfoTree. func (mt *L1InfoTree) ResetL1InfoTree(initialLeaves [][32]byte) (*L1InfoTree, error) { + log.Info("Resetting L1InfoTree...") newMT := &L1InfoTree{ zeroHashes: mt.zeroHashes, height: mt.height, diff --git a/state/l1infotree.go b/state/l1infotree.go index 1721ed8e58..91478e2929 100644 --- a/state/l1infotree.go +++ b/state/l1infotree.go @@ -87,6 +87,7 @@ func (s *State) AddL1InfoTreeLeaf(ctx context.Context, l1InfoTreeLeaf *L1InfoTre return &entry, nil } +// ResetL1InfoTree resets the L1InfoTree func (s *State) ResetL1InfoTree(ctx context.Context, dbTx pgx.Tx) error { allLeaves, err := s.GetAllL1InfoRootEntries(ctx, dbTx) if err != nil { From 809d54dcaa87078bf0c085055fb80ed84e998480 Mon Sep 17 00:00:00 2001 From: Alonso Date: Tue, 2 Apr 2024 16:48:44 +0200 Subject: [PATCH 4/8] refactor --- state/reset.go | 23 ++++++++++++++------- synchronizer/common/syncinterfaces/state.go | 1 - synchronizer/synchronizer.go | 11 +--------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/state/reset.go b/state/reset.go index 62571250e0..5666005bd7 100644 --- a/state/reset.go +++ b/state/reset.go @@ -3,6 +3,7 @@ package state import ( "context" + "github.com/0xPolygonHermez/zkevm-node/log" "github.com/jackc/pgx/v4" ) @@ -13,12 +14,20 @@ func (s *State) Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) erro // - VerifiedBatches // - Entries in exit_root table err := s.ResetToL1BlockNumber(ctx, blockNumber, dbTx) - if err == nil { - // Discard L1InfoTree cache - // We can't rebuild cache, because we are inside a transaction, so we dont known - // is going to be a commit or a rollback. So is going to be rebuild on the next - // request that needs it. - s.l1InfoTree = nil + if err != nil { + log.Error("error resetting L1BlockNumber. Error: ", err) + return err } - return err + // Reset L1InfoTree siblings and leaves + err = s.ResetL1InfoTree(ctx, dbTx) + if err != nil { + log.Error("error resetting the l1InfoTree. Error: ", err) + return err + } + // Discard L1InfoTree cache + // We can't rebuild cache, because we are inside a transaction, so we dont known + // is going to be a commit or a rollback. So is going to be rebuild on the next + // request that needs it. + s.l1InfoTree = nil + return nil } diff --git a/synchronizer/common/syncinterfaces/state.go b/synchronizer/common/syncinterfaces/state.go index e1b62b1fe6..2895eb0903 100644 --- a/synchronizer/common/syncinterfaces/state.go +++ b/synchronizer/common/syncinterfaces/state.go @@ -28,7 +28,6 @@ type StateFullInterface interface { AddForcedBatch(ctx context.Context, forcedBatch *state.ForcedBatch, dbTx pgx.Tx) error AddBlock(ctx context.Context, block *state.Block, dbTx pgx.Tx) error Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) error - ResetL1InfoTree(ctx context.Context, dbTx pgx.Tx) error GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*state.Block, error) GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 23ad2b94c3..e89c481ce0 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -505,6 +505,7 @@ func (s *ClientSynchronizer) syncBlocksSequential(lastEthBlockSynced *state.Bloc // Call the blockchain to retrieve data header, err := s.etherMan.HeaderByNumber(s.ctx, nil) if err != nil { + log.Error("error getting header of the latest block in L1. Error: ", err) return lastEthBlockSynced, err } lastKnownBlock := header.Number @@ -695,16 +696,6 @@ func (s *ClientSynchronizer) resetState(blockNumber uint64) error { log.Error("error processing reorg on eth tx manager. Error: ", err) return err } - err = s.state.ResetL1InfoTree(s.ctx, dbTx) - if err != nil { - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state when resetting l1InfoTree. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err) - return rollbackErr - } - log.Error("error resetting the l1InfoTree. Error: ", err) - return err - } err = dbTx.Commit(s.ctx) if err != nil { rollbackErr := dbTx.Rollback(s.ctx) From ad0fc81bc91ae6bb285afe12087c74eaa1751e6d Mon Sep 17 00:00:00 2001 From: Alonso Date: Wed, 3 Apr 2024 11:01:33 +0200 Subject: [PATCH 5/8] more robust --- synchronizer/synchronizer.go | 46 ++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index e89c481ce0..3da51cc586 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -487,6 +487,14 @@ func (s *ClientSynchronizer) syncBlocksParallel(lastEthBlockSynced *state.Block) // This function syncs the node from a specific block to the latest func (s *ClientSynchronizer) syncBlocksSequential(lastEthBlockSynced *state.Block) (*state.Block, error) { + // Call the blockchain to retrieve data + header, err := s.etherMan.HeaderByNumber(s.ctx, nil) + if err != nil { + log.Error("error getting header of the latest block in L1. Error: ", err) + return lastEthBlockSynced, err + } + lastKnownBlock := header.Number + // This function will read events fromBlockNum to latestEthBlock. Check reorg to be sure that everything is ok. block, err := s.checkReorg(lastEthBlockSynced) if err != nil { @@ -502,14 +510,6 @@ func (s *ClientSynchronizer) syncBlocksSequential(lastEthBlockSynced *state.Bloc return block, nil } - // Call the blockchain to retrieve data - header, err := s.etherMan.HeaderByNumber(s.ctx, nil) - if err != nil { - log.Error("error getting header of the latest block in L1. Error: ", err) - return lastEthBlockSynced, err - } - lastKnownBlock := header.Number - var fromBlock uint64 if lastEthBlockSynced.BlockNumber > 0 { fromBlock = lastEthBlockSynced.BlockNumber + 1 @@ -723,26 +723,27 @@ hash and has parent. This operation has to be done until a match is found. func (s *ClientSynchronizer) checkReorg(latestBlock *state.Block) (*state.Block, error) { // This function only needs to worry about reorgs if some of the reorganized blocks contained rollup info. latestEthBlockSynced := *latestBlock + reorgedBlock := *latestBlock var depth uint64 for { - block, err := s.etherMan.EthBlockByNumber(s.ctx, latestBlock.BlockNumber) + block, err := s.etherMan.EthBlockByNumber(s.ctx, reorgedBlock.BlockNumber) if err != nil { - log.Errorf("error getting latest block synced from blockchain. Block: %d, error: %v", latestBlock.BlockNumber, err) + log.Errorf("error getting latest block synced from blockchain. Block: %d, error: %v", reorgedBlock.BlockNumber, err) return nil, err } - if block.NumberU64() != latestBlock.BlockNumber { + if block.NumberU64() != reorgedBlock.BlockNumber { err = fmt.Errorf("wrong ethereum block retrieved from blockchain. Block numbers don't match. BlockNumber stored: %d. BlockNumber retrieved: %d", - latestBlock.BlockNumber, block.NumberU64()) + reorgedBlock.BlockNumber, block.NumberU64()) log.Error("error: ", err) return nil, err } // Compare hashes - if (block.Hash() != latestBlock.BlockHash || block.ParentHash() != latestBlock.ParentHash) && latestBlock.BlockNumber > s.genesis.BlockNumber { - log.Infof("checkReorg: Bad block %d hashOk %t parentHashOk %t", latestBlock.BlockNumber, block.Hash() == latestBlock.BlockHash, block.ParentHash() == latestBlock.ParentHash) - log.Debug("[checkReorg function] => latestBlockNumber: ", latestBlock.BlockNumber) - log.Debug("[checkReorg function] => latestBlockHash: ", latestBlock.BlockHash) - log.Debug("[checkReorg function] => latestBlockHashParent: ", latestBlock.ParentHash) - log.Debug("[checkReorg function] => BlockNumber: ", latestBlock.BlockNumber, block.NumberU64()) + if (block.Hash() != reorgedBlock.BlockHash || block.ParentHash() != reorgedBlock.ParentHash) && reorgedBlock.BlockNumber > s.genesis.BlockNumber { + log.Infof("checkReorg: Bad block %d hashOk %t parentHashOk %t", reorgedBlock.BlockNumber, block.Hash() == reorgedBlock.BlockHash, block.ParentHash() == reorgedBlock.ParentHash) + log.Debug("[checkReorg function] => latestBlockNumber: ", reorgedBlock.BlockNumber) + log.Debug("[checkReorg function] => latestBlockHash: ", reorgedBlock.BlockHash) + log.Debug("[checkReorg function] => latestBlockHashParent: ", reorgedBlock.ParentHash) + log.Debug("[checkReorg function] => BlockNumber: ", reorgedBlock.BlockNumber, block.NumberU64()) log.Debug("[checkReorg function] => BlockHash: ", block.Hash()) log.Debug("[checkReorg function] => BlockHashParent: ", block.ParentHash()) depth++ @@ -753,7 +754,8 @@ func (s *ClientSynchronizer) checkReorg(latestBlock *state.Block) (*state.Block, log.Errorf("error creating db transaction to get prevoius blocks") return nil, err } - latestBlock, err = s.state.GetPreviousBlock(s.ctx, depth, dbTx) + lb, err := s.state.GetPreviousBlock(s.ctx, depth, dbTx) + reorgedBlock = *lb errC := dbTx.Commit(s.ctx) if errC != nil { log.Errorf("error committing dbTx, err: %v", errC) @@ -769,16 +771,20 @@ func (s *ClientSynchronizer) checkReorg(latestBlock *state.Block) (*state.Block, log.Warn("error checking reorg: previous block not found in db: ", err) return &state.Block{}, nil } else if err != nil { + log.Error("error getting previousBlock from db. Error: ", err) return nil, err } } else { + log.Debugf("checkReorg: Block %d hashOk %t parentHashOk %t", reorgedBlock.BlockNumber, block.Hash() == reorgedBlock.BlockHash, block.ParentHash() == reorgedBlock.ParentHash) break } } - if latestEthBlockSynced.BlockHash != latestBlock.BlockHash { + if latestEthBlockSynced.BlockHash != reorgedBlock.BlockHash { + latestBlock = &reorgedBlock log.Info("Reorg detected in block: ", latestEthBlockSynced.BlockNumber, " last block OK: ", latestBlock.BlockNumber) return latestBlock, nil } + log.Debugf("No reorg detected in block: %d. BlockHash: %s", latestEthBlockSynced.BlockNumber, latestEthBlockSynced.BlockHash.String()) return nil, nil } From 04305d8cd7d4cdddae06c8f92d4bae1c55056c36 Mon Sep 17 00:00:00 2001 From: Alonso Date: Wed, 3 Apr 2024 14:17:11 +0200 Subject: [PATCH 6/8] Fix comments --- state/l1infotree.go | 34 +++++++--------------------------- state/reset.go | 6 ------ synchronizer/synchronizer.go | 2 +- 3 files changed, 8 insertions(+), 34 deletions(-) diff --git a/state/l1infotree.go b/state/l1infotree.go index 91478e2929..8cac9ea5d7 100644 --- a/state/l1infotree.go +++ b/state/l1infotree.go @@ -3,7 +3,6 @@ package state import ( "context" "errors" - "fmt" "github.com/0xPolygonHermez/zkevm-node/l1infotree" "github.com/0xPolygonHermez/zkevm-node/log" @@ -34,20 +33,20 @@ func (s *State) buildL1InfoTreeCacheIfNeed(ctx context.Context, dbTx pgx.Tx) err if s.l1InfoTree != nil { return nil } - log.Debugf("Building L1InfoTree cache") - allLeaves, err := s.storage.GetAllL1InfoRootEntries(ctx, dbTx) + // Reset L1InfoTree siblings and leaves + allLeaves, err := s.GetAllL1InfoRootEntries(ctx, dbTx) if err != nil { - log.Error("error getting all leaves. Error: ", err) - return fmt.Errorf("error getting all leaves. Error: %w", err) + log.Error("error getting all leaves to reset l1InfoTree. Error: ", err) + return err } var leaves [][32]byte for _, leaf := range allLeaves { leaves = append(leaves, leaf.Hash()) } - mt, err := l1infotree.NewL1InfoTree(uint8(32), leaves) //nolint:gomnd + mt, err := s.l1InfoTree.ResetL1InfoTree(leaves) if err != nil { - log.Error("error creating L1InfoTree. Error: ", err) - return fmt.Errorf("error creating L1InfoTree. Error: %w", err) + log.Error("error resetting l1InfoTree. Error: ", err) + return err } s.l1InfoTree = mt return nil @@ -87,25 +86,6 @@ func (s *State) AddL1InfoTreeLeaf(ctx context.Context, l1InfoTreeLeaf *L1InfoTre return &entry, nil } -// ResetL1InfoTree resets the L1InfoTree -func (s *State) ResetL1InfoTree(ctx context.Context, dbTx pgx.Tx) error { - allLeaves, err := s.GetAllL1InfoRootEntries(ctx, dbTx) - if err != nil { - log.Error("error getting all leaves to reset l1InfoTree. Error: ", err) - return err - } - var leaves [][32]byte - for _, leaf := range allLeaves { - leaves = append(leaves, leaf.Hash()) - } - s.l1InfoTree, err = s.l1InfoTree.ResetL1InfoTree(leaves) - if err != nil { - log.Error("error resetting l1InfoTree. Error: ", err) - return err - } - return nil -} - // GetCurrentL1InfoRoot Return current L1InfoRoot func (s *State) GetCurrentL1InfoRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error) { err := s.buildL1InfoTreeCacheIfNeed(ctx, dbTx) diff --git a/state/reset.go b/state/reset.go index 5666005bd7..655f5f3dd1 100644 --- a/state/reset.go +++ b/state/reset.go @@ -18,12 +18,6 @@ func (s *State) Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) erro log.Error("error resetting L1BlockNumber. Error: ", err) return err } - // Reset L1InfoTree siblings and leaves - err = s.ResetL1InfoTree(ctx, dbTx) - if err != nil { - log.Error("error resetting the l1InfoTree. Error: ", err) - return err - } // Discard L1InfoTree cache // We can't rebuild cache, because we are inside a transaction, so we dont known // is going to be a commit or a rollback. So is going to be rebuild on the next diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 3da51cc586..e8f0f8382f 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -755,7 +755,6 @@ func (s *ClientSynchronizer) checkReorg(latestBlock *state.Block) (*state.Block, return nil, err } lb, err := s.state.GetPreviousBlock(s.ctx, depth, dbTx) - reorgedBlock = *lb errC := dbTx.Commit(s.ctx) if errC != nil { log.Errorf("error committing dbTx, err: %v", errC) @@ -774,6 +773,7 @@ func (s *ClientSynchronizer) checkReorg(latestBlock *state.Block) (*state.Block, log.Error("error getting previousBlock from db. Error: ", err) return nil, err } + reorgedBlock = *lb } else { log.Debugf("checkReorg: Block %d hashOk %t parentHashOk %t", reorgedBlock.BlockNumber, block.Hash() == reorgedBlock.BlockHash, block.ParentHash() == reorgedBlock.ParentHash) break From 2d65e0a5a5338f3ec217597f62ac1635cead3a97 Mon Sep 17 00:00:00 2001 From: Alonso Date: Wed, 3 Apr 2024 16:54:46 +0200 Subject: [PATCH 7/8] Add extra check reorg after calling get information --- synchronizer/synchronizer.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index e8f0f8382f..996bbc3907 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -530,6 +530,22 @@ func (s *ClientSynchronizer) syncBlocksSequential(lastEthBlockSynced *state.Bloc if err != nil { return lastEthBlockSynced, err } + + // Check reorg again to be sure that the chain has not changed between the previous checkReorg and the call GetRollupInfoByBlockRange + block, err := s.checkReorg(lastEthBlockSynced) + if err != nil { + log.Errorf("error checking reorgs. Retrying... Err: %v", err) + return lastEthBlockSynced, fmt.Errorf("error checking reorgs") + } + if block != nil { + err = s.resetState(block.BlockNumber) + if err != nil { + log.Errorf("error resetting the state to a previous block. Retrying... Err: %v", err) + return lastEthBlockSynced, fmt.Errorf("error resetting the state to a previous block") + } + return block, nil + } + start = time.Now() err = s.ProcessBlockRange(blocks, order) metrics.ProcessL1DataTime(time.Since(start)) From e815320bced22dad62455b1803727b36da8f8478 Mon Sep 17 00:00:00 2001 From: Alonso Date: Thu, 4 Apr 2024 08:36:54 +0200 Subject: [PATCH 8/8] Fix non e2e test --- l1infotree/tree.go | 5 ++--- synchronizer/synchronizer_test.go | 10 ++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/l1infotree/tree.go b/l1infotree/tree.go index 5268156406..d3fe48ed2f 100644 --- a/l1infotree/tree.go +++ b/l1infotree/tree.go @@ -38,8 +38,8 @@ func NewL1InfoTree(height uint8, initialLeaves [][32]byte) (*L1InfoTree, error) func (mt *L1InfoTree) ResetL1InfoTree(initialLeaves [][32]byte) (*L1InfoTree, error) { log.Info("Resetting L1InfoTree...") newMT := &L1InfoTree{ - zeroHashes: mt.zeroHashes, - height: mt.height, + zeroHashes: generateZeroHashes(32), // nolint:gomnd + height: 32, // nolint:gomnd count: uint32(len(initialLeaves)), } var err error @@ -50,7 +50,6 @@ func (mt *L1InfoTree) ResetL1InfoTree(initialLeaves [][32]byte) (*L1InfoTree, er } log.Debug("Reset initial count: ", newMT.count) log.Debug("Reset initial root: ", newMT.currentRoot) - mt = newMT return newMT, nil } diff --git a/synchronizer/synchronizer_test.go b/synchronizer/synchronizer_test.go index bdf3b505b6..edd6927025 100644 --- a/synchronizer/synchronizer_test.go +++ b/synchronizer/synchronizer_test.go @@ -260,6 +260,11 @@ func TestForcedBatchEtrog(t *testing.T) { Return(blocks, order, nil). Once() + m.Etherman. + On("EthBlockByNumber", ctx, lastBlock.BlockNumber). + Return(ethBlock, nil). + Once() + m.ZKEVMClient. On("BatchNumber", ctx). Return(uint64(1), nil) @@ -509,6 +514,11 @@ func TestSequenceForcedBatchIncaberry(t *testing.T) { Return(blocks, order, nil). Once() + m.Etherman. + On("EthBlockByNumber", ctx, lastBlock.BlockNumber). + Return(ethBlock, nil). + Once() + m.State. On("BeginStateTransaction", ctx). Return(m.DbTx, nil).