From 9067d026f340c217f2ad58d397d322e85a2e2646 Mon Sep 17 00:00:00 2001 From: joanestebanr <129153821+joanestebanr@users.noreply.github.com> Date: Thu, 16 May 2024 05:19:17 +0200 Subject: [PATCH] implements #49 --- synchronizer/common/syncinterfaces/storage.go | 1 + .../mocks/storage_block_reader_interface.go | 60 ++++++++++++ synchronizer/mocks/storage_interface.go | 60 ++++++++++++ synchronizer/mocks/storage_sync_queries.go | 60 ++++++++++++ .../mocks/synchronizer_block_querier.go | 96 +++++++++++++++++++ synchronizer/synchronizer.go | 14 +++ synchronizer/synchronizer_queries.go | 10 ++ synchronizer/types.go | 1 - 8 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 synchronizer/mocks/synchronizer_block_querier.go diff --git a/synchronizer/common/syncinterfaces/storage.go b/synchronizer/common/syncinterfaces/storage.go index 73295cb..18e2a6d 100644 --- a/synchronizer/common/syncinterfaces/storage.go +++ b/synchronizer/common/syncinterfaces/storage.go @@ -18,6 +18,7 @@ type StorageBlockReaderInterface interface { AddBlock(ctx context.Context, block *entities.L1Block, dbTx stateTxType) error GetPreviousBlock(ctx context.Context, offset uint64, fromBlockNumber *uint64, dbTx stateTxType) (*entities.L1Block, error) GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx stateTxType) (*entities.L1Block, error) + GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx stateTxType) (*entities.L1Block, error) } type StorageForkIDInterface interface { diff --git a/synchronizer/mocks/storage_block_reader_interface.go b/synchronizer/mocks/storage_block_reader_interface.go index 6e1d2c8..8b09cf6 100644 --- a/synchronizer/mocks/storage_block_reader_interface.go +++ b/synchronizer/mocks/storage_block_reader_interface.go @@ -70,6 +70,66 @@ func (_c *StorageBlockReaderInterface_AddBlock_Call) RunAndReturn(run func(conte return _c } +// GetBlockByNumber provides a mock function with given fields: ctx, blockNumber, dbTx +func (_m *StorageBlockReaderInterface) GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx entities.Tx) (*entities.L1Block, error) { + ret := _m.Called(ctx, blockNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetBlockByNumber") + } + + var r0 *entities.L1Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, entities.Tx) (*entities.L1Block, error)); ok { + return rf(ctx, blockNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, entities.Tx) *entities.L1Block); ok { + r0 = rf(ctx, blockNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*entities.L1Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, entities.Tx) error); ok { + r1 = rf(ctx, blockNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StorageBlockReaderInterface_GetBlockByNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlockByNumber' +type StorageBlockReaderInterface_GetBlockByNumber_Call struct { + *mock.Call +} + +// GetBlockByNumber is a helper method to define mock.On call +// - ctx context.Context +// - blockNumber uint64 +// - dbTx entities.Tx +func (_e *StorageBlockReaderInterface_Expecter) GetBlockByNumber(ctx interface{}, blockNumber interface{}, dbTx interface{}) *StorageBlockReaderInterface_GetBlockByNumber_Call { + return &StorageBlockReaderInterface_GetBlockByNumber_Call{Call: _e.mock.On("GetBlockByNumber", ctx, blockNumber, dbTx)} +} + +func (_c *StorageBlockReaderInterface_GetBlockByNumber_Call) Run(run func(ctx context.Context, blockNumber uint64, dbTx entities.Tx)) *StorageBlockReaderInterface_GetBlockByNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(entities.Tx)) + }) + return _c +} + +func (_c *StorageBlockReaderInterface_GetBlockByNumber_Call) Return(_a0 *entities.L1Block, _a1 error) *StorageBlockReaderInterface_GetBlockByNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StorageBlockReaderInterface_GetBlockByNumber_Call) RunAndReturn(run func(context.Context, uint64, entities.Tx) (*entities.L1Block, error)) *StorageBlockReaderInterface_GetBlockByNumber_Call { + _c.Call.Return(run) + return _c +} + // GetFirstUncheckedBlock provides a mock function with given fields: ctx, fromBlockNumber, dbTx func (_m *StorageBlockReaderInterface) GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx entities.Tx) (*entities.L1Block, error) { ret := _m.Called(ctx, fromBlockNumber, dbTx) diff --git a/synchronizer/mocks/storage_interface.go b/synchronizer/mocks/storage_interface.go index 6c481f1..fbd1770 100644 --- a/synchronizer/mocks/storage_interface.go +++ b/synchronizer/mocks/storage_interface.go @@ -276,6 +276,66 @@ func (_c *StorageInterface_GetAllL1InfoTreeLeaves_Call) RunAndReturn(run func(co return _c } +// GetBlockByNumber provides a mock function with given fields: ctx, blockNumber, dbTx +func (_m *StorageInterface) GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx entities.Tx) (*entities.L1Block, error) { + ret := _m.Called(ctx, blockNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetBlockByNumber") + } + + var r0 *entities.L1Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, entities.Tx) (*entities.L1Block, error)); ok { + return rf(ctx, blockNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, entities.Tx) *entities.L1Block); ok { + r0 = rf(ctx, blockNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*entities.L1Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, entities.Tx) error); ok { + r1 = rf(ctx, blockNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StorageInterface_GetBlockByNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlockByNumber' +type StorageInterface_GetBlockByNumber_Call struct { + *mock.Call +} + +// GetBlockByNumber is a helper method to define mock.On call +// - ctx context.Context +// - blockNumber uint64 +// - dbTx entities.Tx +func (_e *StorageInterface_Expecter) GetBlockByNumber(ctx interface{}, blockNumber interface{}, dbTx interface{}) *StorageInterface_GetBlockByNumber_Call { + return &StorageInterface_GetBlockByNumber_Call{Call: _e.mock.On("GetBlockByNumber", ctx, blockNumber, dbTx)} +} + +func (_c *StorageInterface_GetBlockByNumber_Call) Run(run func(ctx context.Context, blockNumber uint64, dbTx entities.Tx)) *StorageInterface_GetBlockByNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(entities.Tx)) + }) + return _c +} + +func (_c *StorageInterface_GetBlockByNumber_Call) Return(_a0 *entities.L1Block, _a1 error) *StorageInterface_GetBlockByNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StorageInterface_GetBlockByNumber_Call) RunAndReturn(run func(context.Context, uint64, entities.Tx) (*entities.L1Block, error)) *StorageInterface_GetBlockByNumber_Call { + _c.Call.Return(run) + return _c +} + // GetFirstUncheckedBlock provides a mock function with given fields: ctx, fromBlockNumber, dbTx func (_m *StorageInterface) GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx entities.Tx) (*entities.L1Block, error) { ret := _m.Called(ctx, fromBlockNumber, dbTx) diff --git a/synchronizer/mocks/storage_sync_queries.go b/synchronizer/mocks/storage_sync_queries.go index 31a8346..d95604c 100644 --- a/synchronizer/mocks/storage_sync_queries.go +++ b/synchronizer/mocks/storage_sync_queries.go @@ -120,6 +120,66 @@ func (_c *storageSyncQueries_AddSequencedBatches_Call) RunAndReturn(run func(con return _c } +// GetBlockByNumber provides a mock function with given fields: ctx, blockNumber, dbTx +func (_m *storageSyncQueries) GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx entities.Tx) (*entities.L1Block, error) { + ret := _m.Called(ctx, blockNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetBlockByNumber") + } + + var r0 *entities.L1Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, entities.Tx) (*entities.L1Block, error)); ok { + return rf(ctx, blockNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, entities.Tx) *entities.L1Block); ok { + r0 = rf(ctx, blockNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*entities.L1Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, entities.Tx) error); ok { + r1 = rf(ctx, blockNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// storageSyncQueries_GetBlockByNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlockByNumber' +type storageSyncQueries_GetBlockByNumber_Call struct { + *mock.Call +} + +// GetBlockByNumber is a helper method to define mock.On call +// - ctx context.Context +// - blockNumber uint64 +// - dbTx entities.Tx +func (_e *storageSyncQueries_Expecter) GetBlockByNumber(ctx interface{}, blockNumber interface{}, dbTx interface{}) *storageSyncQueries_GetBlockByNumber_Call { + return &storageSyncQueries_GetBlockByNumber_Call{Call: _e.mock.On("GetBlockByNumber", ctx, blockNumber, dbTx)} +} + +func (_c *storageSyncQueries_GetBlockByNumber_Call) Run(run func(ctx context.Context, blockNumber uint64, dbTx entities.Tx)) *storageSyncQueries_GetBlockByNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(entities.Tx)) + }) + return _c +} + +func (_c *storageSyncQueries_GetBlockByNumber_Call) Return(_a0 *entities.L1Block, _a1 error) *storageSyncQueries_GetBlockByNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *storageSyncQueries_GetBlockByNumber_Call) RunAndReturn(run func(context.Context, uint64, entities.Tx) (*entities.L1Block, error)) *storageSyncQueries_GetBlockByNumber_Call { + _c.Call.Return(run) + return _c +} + // GetFirstUncheckedBlock provides a mock function with given fields: ctx, fromBlockNumber, dbTx func (_m *storageSyncQueries) GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx entities.Tx) (*entities.L1Block, error) { ret := _m.Called(ctx, fromBlockNumber, dbTx) diff --git a/synchronizer/mocks/synchronizer_block_querier.go b/synchronizer/mocks/synchronizer_block_querier.go new file mode 100644 index 0000000..b7e6d52 --- /dev/null +++ b/synchronizer/mocks/synchronizer_block_querier.go @@ -0,0 +1,96 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_synchronizer + +import ( + context "context" + + synchronizer "github.com/0xPolygonHermez/zkevm-synchronizer-l1/synchronizer" + mock "github.com/stretchr/testify/mock" +) + +// SynchronizerBlockQuerier is an autogenerated mock type for the SynchronizerBlockQuerier type +type SynchronizerBlockQuerier struct { + mock.Mock +} + +type SynchronizerBlockQuerier_Expecter struct { + mock *mock.Mock +} + +func (_m *SynchronizerBlockQuerier) EXPECT() *SynchronizerBlockQuerier_Expecter { + return &SynchronizerBlockQuerier_Expecter{mock: &_m.Mock} +} + +// GetL1BlockByNumber provides a mock function with given fields: ctx, blockNumber +func (_m *SynchronizerBlockQuerier) GetL1BlockByNumber(ctx context.Context, blockNumber uint64) (*synchronizer.L1Block, error) { + ret := _m.Called(ctx, blockNumber) + + if len(ret) == 0 { + panic("no return value specified for GetL1BlockByNumber") + } + + var r0 *synchronizer.L1Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64) (*synchronizer.L1Block, error)); ok { + return rf(ctx, blockNumber) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64) *synchronizer.L1Block); ok { + r0 = rf(ctx, blockNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*synchronizer.L1Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok { + r1 = rf(ctx, blockNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SynchronizerBlockQuerier_GetL1BlockByNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL1BlockByNumber' +type SynchronizerBlockQuerier_GetL1BlockByNumber_Call struct { + *mock.Call +} + +// GetL1BlockByNumber is a helper method to define mock.On call +// - ctx context.Context +// - blockNumber uint64 +func (_e *SynchronizerBlockQuerier_Expecter) GetL1BlockByNumber(ctx interface{}, blockNumber interface{}) *SynchronizerBlockQuerier_GetL1BlockByNumber_Call { + return &SynchronizerBlockQuerier_GetL1BlockByNumber_Call{Call: _e.mock.On("GetL1BlockByNumber", ctx, blockNumber)} +} + +func (_c *SynchronizerBlockQuerier_GetL1BlockByNumber_Call) Run(run func(ctx context.Context, blockNumber uint64)) *SynchronizerBlockQuerier_GetL1BlockByNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64)) + }) + return _c +} + +func (_c *SynchronizerBlockQuerier_GetL1BlockByNumber_Call) Return(_a0 *synchronizer.L1Block, _a1 error) *SynchronizerBlockQuerier_GetL1BlockByNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SynchronizerBlockQuerier_GetL1BlockByNumber_Call) RunAndReturn(run func(context.Context, uint64) (*synchronizer.L1Block, error)) *SynchronizerBlockQuerier_GetL1BlockByNumber_Call { + _c.Call.Return(run) + return _c +} + +// NewSynchronizerBlockQuerier creates a new instance of SynchronizerBlockQuerier. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewSynchronizerBlockQuerier(t interface { + mock.TestingT + Cleanup(func()) +}) *SynchronizerBlockQuerier { + mock := &SynchronizerBlockQuerier{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 4c354d5..839e47a 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -51,6 +51,20 @@ type SynchronizerL1InfoTreeQuerier interface { GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash) ([]L1InfoTreeLeaf, error) } +type L1Block struct { + BlockNumber uint64 + BlockHash common.Hash + ParentHash common.Hash + ReceivedAt time.Time + Checked bool // The block is safe (have past the safe point, e.g. Finalized in L1) + HasEvents bool // This block have events from the rollup + SyncVersion string +} + +type SynchronizerBlockQuerier interface { + GetL1BlockByNumber(ctx context.Context, blockNumber uint64) (*L1Block, error) +} + type SequencedBatches struct { FromBatchNumber uint64 ToBatchNumber uint64 diff --git a/synchronizer/synchronizer_queries.go b/synchronizer/synchronizer_queries.go index 2380a1a..c16f153 100644 --- a/synchronizer/synchronizer_queries.go +++ b/synchronizer/synchronizer_queries.go @@ -21,6 +21,7 @@ type storageSyncQueries interface { syncinterfaces.StorageBlockReaderInterface syncinterfaces.StorageSequenceBatchesInterface syncinterfaces.StorageVirtualBatchInterface + syncinterfaces.StorageBlockReaderInterface } type SyncrhronizerQueries struct { @@ -97,3 +98,12 @@ func (s *SyncrhronizerQueries) GetLastestVirtualBatchNumber(ctx context.Context) } return lastBatchNumber, nil } + +func (s *SyncrhronizerQueries) GetL1BlockByBlock(ctx context.Context, blockNumber uint64) (*L1Block, error) { + block, err := s.storage.GetBlockByNumber(ctx, blockNumber, nil) + if block == nil { + return nil, err + } + res := L1Block(*block) + return &res, err +} diff --git a/synchronizer/types.go b/synchronizer/types.go index e73638c..f3752c2 100644 --- a/synchronizer/types.go +++ b/synchronizer/types.go @@ -4,5 +4,4 @@ import ( "github.com/0xPolygonHermez/zkevm-synchronizer-l1/state/entities" ) -type L1Block = entities.L1Block type stateTxType = entities.Tx