From 6fad840dd57559f079b1dbd18891aac39da49356 Mon Sep 17 00:00:00 2001 From: Diego Date: Mon, 23 Sep 2024 12:31:26 -0300 Subject: [PATCH] Implement GetAuthoritesChangesFromBlock --- dot/state/block_data.go | 21 ++++++++++++++++++--- dot/state/interfaces.go | 1 + dot/state/mocks_test.go | 15 +++++++++++++++ internal/database/database.go | 1 + internal/database/table.go | 4 ++++ lib/grandpa/warp_sync.go | 1 - 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/dot/state/block_data.go b/dot/state/block_data.go index d5ec392669..0ae57faf0b 100644 --- a/dot/state/block_data.go +++ b/dot/state/block_data.go @@ -5,6 +5,7 @@ package state import ( "github.com/ChainSafe/gossamer/lib/common" + "golang.org/x/exp/slices" ) // prefixKey = prefix + hash @@ -88,7 +89,21 @@ func (bs *BlockState) GetJustification(hash common.Hash) ([]byte, error) { } // GetAuthoritesChangesFromBlock retrieves blocks numbers where authority set changes happened -func (bs *BlockState) GetAuthoritesChangesFromBlock(blockNumber uint) ([]uint, error) { - // TODO: complete me - panic("not implemented") +func (bs *BlockState) GetAuthoritesChangesFromBlock(initialBlockNumber uint) ([]uint, error) { + blockNumbers := make([]uint, 0) + iter, err := bs.db.NewPrefixIterator(setIDChangePrefix) + if err != nil { + return nil, err + } + + for iter.Next() { + blockNumber := common.BytesToUint(iter.Value()) + if blockNumber >= initialBlockNumber { + blockNumbers = append(blockNumbers, blockNumber) + } + } + + // To ensure the order of the blocks + slices.Sort(blockNumbers) + return blockNumbers, nil } diff --git a/dot/state/interfaces.go b/dot/state/interfaces.go index 55b3f426fe..bfa630adc4 100644 --- a/dot/state/interfaces.go +++ b/dot/state/interfaces.go @@ -21,6 +21,7 @@ type BlockStateDatabase interface { GetPutDeleter Haser NewBatcher + NewPrefixIterator(prefix []byte) (database.Iterator, error) } // GetPutter has methods to get and put key values. diff --git a/dot/state/mocks_test.go b/dot/state/mocks_test.go index 245d305b73..1ba77e53d9 100644 --- a/dot/state/mocks_test.go +++ b/dot/state/mocks_test.go @@ -133,6 +133,21 @@ func (mr *MockBlockStateDatabaseMockRecorder) NewBatch() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBatch", reflect.TypeOf((*MockBlockStateDatabase)(nil).NewBatch)) } +// NewPrefixIterator mocks base method. +func (m *MockBlockStateDatabase) NewPrefixIterator(arg0 []byte) (database.Iterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewPrefixIterator", arg0) + ret0, _ := ret[0].(database.Iterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewPrefixIterator indicates an expected call of NewPrefixIterator. +func (mr *MockBlockStateDatabaseMockRecorder) NewPrefixIterator(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewPrefixIterator", reflect.TypeOf((*MockBlockStateDatabase)(nil).NewPrefixIterator), arg0) +} + // Put mocks base method. func (m *MockBlockStateDatabase) Put(arg0, arg1 []byte) error { m.ctrl.T.Helper() diff --git a/internal/database/database.go b/internal/database/database.go index b3140a4623..b827c82d2b 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -60,6 +60,7 @@ type Table interface { Path() string NewBatch() Batch NewIterator() (Iterator, error) + NewPrefixIterator(prefix []byte) (Iterator, error) } const DefaultDatabaseDir = "db" diff --git a/internal/database/table.go b/internal/database/table.go index 3c6eb74793..4e03cb393e 100644 --- a/internal/database/table.go +++ b/internal/database/table.go @@ -59,3 +59,7 @@ func (t *table) NewBatch() Batch { func (t *table) NewIterator() (Iterator, error) { return t.db.NewPrefixIterator(t.prefix) } + +func (t *table) NewPrefixIterator(prefix []byte) (Iterator, error) { + return t.db.NewPrefixIterator(append(t.prefix, prefix...)) +} diff --git a/lib/grandpa/warp_sync.go b/lib/grandpa/warp_sync.go index b586fc6a92..90aab2bc22 100644 --- a/lib/grandpa/warp_sync.go +++ b/lib/grandpa/warp_sync.go @@ -45,7 +45,6 @@ func (np *NetworkProvider) Generate(start common.Hash) ([]byte, error) { // the header should contains a standard scheduled change // otherwise the set must have changed through a forced changed, // in which case we stop collecting proofs as the chain of trust in authority handoffs was broken. - header, err := np.backend.GetHeaderByNumber(blockNumber) if err != nil { return nil, err