Skip to content

Commit 855f12b

Browse files
authored
Fix newest iterator on empty file ledger (#116)
#### Type of change - Bug fix #### Description When `SeekPosition_Newest` is used on an empty `FileLedger`, `Iterator` computed `Height - 1`, underflowing to `math.MaxUint64`. This makes the iterator request an impossible block number instead of waiting from block zero. - Guard newest seek when ledger height is zero - Start empty-ledger newest iterators at block zero - Add regression coverage for the empty-ledger case #### Related Companion for hyperledger/fabric-x-committer#601. Signed-off-by: Senthilnathan <cendhu@gmail.com>
1 parent 84a244b commit 855f12b

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

common/ledger/blockledger/fileledger/impl.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ func (fl *FileLedger) Iterator(startPosition *ab.SeekPosition) (blockledger.Iter
8080
if err != nil {
8181
logger.Panic(err)
8282
}
83-
newestBlockNumber := info.Height - 1
83+
newestBlockNumber := uint64(0)
84+
if info.Height > 0 {
85+
newestBlockNumber = info.Height - 1
86+
}
8487
if info.BootstrappingSnapshotInfo != nil && newestBlockNumber == info.BootstrappingSnapshotInfo.LastBlockInSnapshot {
8588
newestBlockNumber = info.Height
8689
}

common/ledger/blockledger/fileledger/impl_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type mockBlockStore struct {
6363
defaultError error
6464
getBlockchainInfoError error
6565
retrieveBlockByNumberError error
66+
retrieveBlocksStart uint64
6667
}
6768

6869
func (mbs *mockBlockStore) AddBlock(block *cb.Block) error {
@@ -81,7 +82,8 @@ func (mbs *mockBlockStore) GetBlockchainInfo() (*cb.BlockchainInfo, error) {
8182
return mbs.blockchainInfo, mbs.getBlockchainInfoError
8283
}
8384

84-
func (mbs *mockBlockStore) RetrieveBlocks(_ uint64) (cl.ResultsIterator, error) {
85+
func (mbs *mockBlockStore) RetrieveBlocks(startBlockNumber uint64) (cl.ResultsIterator, error) {
86+
mbs.retrieveBlocksStart = startBlockNumber
8587
return mbs.resultsIterator, mbs.defaultError
8688
}
8789

@@ -324,6 +326,27 @@ func TestBlockRetrievalWithSnapshot(t *testing.T) {
324326
require.Equal(t, nextBlk, blk)
325327
}
326328

329+
func TestNewestIteratorOnEmptyLedgerStartsAtBlockZero(t *testing.T) {
330+
t.Parallel()
331+
332+
resultsIterator := &mockBlockStoreIterator{}
333+
resultsIterator.On("Close").Return()
334+
blockStore := &mockBlockStore{
335+
blockchainInfo: &cb.BlockchainInfo{Height: 0},
336+
resultsIterator: resultsIterator,
337+
}
338+
fl := &FileLedger{
339+
blockStore: blockStore,
340+
signal: make(chan struct{}),
341+
}
342+
343+
it, startingNum := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Newest{}})
344+
defer it.Close()
345+
346+
require.Zero(t, startingNum)
347+
require.Zero(t, blockStore.retrieveBlocksStart)
348+
}
349+
327350
func TestBlockstoreError(t *testing.T) {
328351
// Since this test only ensures failed GetBlockchainInfo
329352
// is properly handled. We don't bother creating fully

0 commit comments

Comments
 (0)