Skip to content

Commit

Permalink
[FAB-3525] Fix config block retrieval
Browse files Browse the repository at this point in the history
Upon startup peer was scanning all blocks for each
channel's config block. This was extremely
inefficient for large chains.
This change navigates directly to the config block
based on the last block's metadata which has a pointer
to the last config block.

Change-Id: Ia570f4d64df135e99a24a4206006bb969c7e4476
Signed-off-by: David Enyeart <enyeart@us.ibm.com>
  • Loading branch information
denyeart committed May 10, 2017
1 parent 132817b commit 5ad9463
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 36 deletions.
60 changes: 25 additions & 35 deletions core/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package peer
import (
"errors"
"fmt"
"math"
"net"
"sync"

Expand Down Expand Up @@ -145,41 +144,32 @@ func InitChain(cid string) {
}

func getCurrConfigBlockFromLedger(ledger ledger.PeerLedger) (*common.Block, error) {
// Config blocks contain only 1 transaction, so we look for 1-tx
// blocks and check the transaction type
var envelope *common.Envelope
var tx *common.Payload
var block *common.Block
var err error
var currBlockNumber uint64 = math.MaxUint64
for currBlockNumber >= 0 {
if block, err = ledger.GetBlockByNumber(currBlockNumber); err != nil {
return nil, err
}
if block.Data != nil && len(block.Data.Data) == 1 {
if envelope, err = utils.ExtractEnvelope(block, 0); err != nil {
peerLogger.Warning("Failed to get Envelope from Block %d.", block.Header.Number)
currBlockNumber = block.Header.Number - 1
continue
}
if tx, err = utils.ExtractPayload(envelope); err != nil {
peerLogger.Warning("Failed to get Payload from Block %d.", block.Header.Number)
currBlockNumber = block.Header.Number - 1
continue
}
chdr, err := utils.UnmarshalChannelHeader(tx.Header.ChannelHeader)
if err != nil {
peerLogger.Warning("Failed to get ChannelHeader from Block %d, error %s.", block.Header.Number, err)
currBlockNumber = block.Header.Number - 1
continue
}
if chdr.Type == int32(common.HeaderType_CONFIG) {
return block, nil
}
}
currBlockNumber = block.Header.Number - 1
peerLogger.Debugf("Getting config block")

// get last block. Last block number is Height-1
blockchainInfo, err := ledger.GetBlockchainInfo()
if err != nil {
return nil, err
}
return nil, fmt.Errorf("Failed to find config block.")
lastBlock, err := ledger.GetBlockByNumber(blockchainInfo.Height - 1)
if err != nil {
return nil, err
}

// get most recent config block location from last block metadata
configBlockIndex, err := utils.GetLastConfigIndexFromBlock(lastBlock)
if err != nil {
return nil, err
}

// get most recent config block
configBlock, err := ledger.GetBlockByNumber(configBlockIndex)
if err != nil {
return nil, err
}

peerLogger.Debugf("Got config block[%d]", configBlockIndex)
return configBlock, nil
}

// createChain creates a new chain object and insert it into the chains
Expand Down
5 changes: 4 additions & 1 deletion core/peer/peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,11 @@ func TestCreateChainFromBlock(t *testing.T) {
t.Fatalf("failed to get correct ledger")
}

// Config block from ledger
// Get config block from ledger
block, err = getCurrConfigBlockFromLedger(ledger)
assert.NoError(t, err, "Failed to get config block from ledger")
assert.NotNil(t, block, "Config block should not be nil")
assert.Equal(t, uint64(0), block.Header.Number, "config block should have been block 0")

// Bad ledger
ledger = GetLedger("BogusChain")
Expand Down

0 comments on commit 5ad9463

Please sign in to comment.