From f1b50941f0bf5cda1cad5633e6f7691b676830f9 Mon Sep 17 00:00:00 2001 From: Kostas Christidis Date: Thu, 1 Mar 2018 00:01:16 -0500 Subject: [PATCH] [FAB-8584] Prevent deliver panic on closed iterator The file-based ledger implementation of the iterator does not account for the case where another thread may close the iterator, resulting in the return of a (nil, nil) pair (block and error respectively). This changeset addresses that. Change-Id: Id77b311b60a8a3c64c4350fcaf9d3b5bf993bf87 Signed-off-by: Kostas Christidis --- common/ledger/blockledger/file/impl.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/common/ledger/blockledger/file/impl.go b/common/ledger/blockledger/file/impl.go index 0f7ab1e9752..d0ea17789a2 100644 --- a/common/ledger/blockledger/file/impl.go +++ b/common/ledger/blockledger/file/impl.go @@ -26,7 +26,7 @@ import ( "github.com/op/go-logging" ) -const pkgLogID = "orderer/ledger/fileledger" +const pkgLogID = "common/ledger/blockledger/file" var logger *logging.Logger @@ -63,11 +63,16 @@ type fileLedgerIterator struct { commonIterator ledger.ResultsIterator } -// Next blocks until there is a new block available, or returns an error if the -// next block is no longer retrievable +// Next blocks until there is a new block available, or until Close is called. +// It returns an error if the next block is no longer retrievable. func (i *fileLedgerIterator) Next() (*cb.Block, cb.Status) { result, err := i.commonIterator.Next() if err != nil { + logger.Error(err) + return nil, cb.Status_SERVICE_UNAVAILABLE + } + // Cover the case where another thread calls Close on the iterator. + if result == nil { return nil, cb.Status_SERVICE_UNAVAILABLE } return result.(*cb.Block), cb.Status_SUCCESS