@@ -22,6 +22,8 @@ import (
22
22
"sync"
23
23
"sync/atomic"
24
24
25
+ "github.com/davecgh/go-spew/spew"
26
+
25
27
"github.com/golang/protobuf/proto"
26
28
"github.com/hyperledger/fabric/common/flogging"
27
29
"github.com/hyperledger/fabric/common/ledger/blkstorage"
@@ -112,16 +114,23 @@ func newBlockfileMgr(id string, conf *Conf, indexConfig *blkstorage.IndexConfig,
112
114
if err != nil {
113
115
panic (fmt .Sprintf ("Could not get block file info for current block file from db: %s" , err ))
114
116
}
115
- if cpInfo == nil { //if no cpInfo stored in db initiate to zero
116
- cpInfo = & checkpointInfo {0 , 0 , true , 0 }
117
- err = mgr .saveCurrentInfo (cpInfo , true )
118
- if err != nil {
119
- panic (fmt .Sprintf ("Could not save next block file info to db: %s" , err ))
117
+ if cpInfo == nil {
118
+ logger .Info (`No info about blocks file found in the db.
119
+ This could happen if this is the first time the ledger is constructed or the index is dropped.
120
+ Scanning blocks dir for the latest info` )
121
+ if cpInfo , err = constructCheckpointInfoFromBlockFiles (rootDir ); err != nil {
122
+ panic (fmt .Sprintf ("Could not build checkpoint info from block files: %s" , err ))
120
123
}
124
+ logger .Infof ("Info constructed by scanning the blocks dir = %s" , spew .Sdump (cpInfo ))
125
+ } else {
126
+ logger .Info (`Synching the info about block files` )
127
+ syncCPInfoFromFS (rootDir , cpInfo )
128
+ }
129
+ err = mgr .saveCurrentInfo (cpInfo , true )
130
+ if err != nil {
131
+ panic (fmt .Sprintf ("Could not save next block file info to db: %s" , err ))
121
132
}
122
- //Verify that the checkpoint stored in db is accurate with what is actually stored in block file system
123
- // If not the same, sync the cpInfo and the file system
124
- syncCPInfoFromFS (rootDir , cpInfo )
133
+
125
134
//Open a writer to the file identified by the number and truncate it to only contain the latest block
126
135
// that was completely saved (file system, index, cpinfo, etc)
127
136
currentFileWriter , err := newBlockfileWriter (deriveBlockfilePath (rootDir , cpInfo .latestFileChunkSuffixNum ))
@@ -193,7 +202,7 @@ func syncCPInfoFromFS(rootDir string, cpInfo *checkpointInfo) {
193
202
return
194
203
}
195
204
//Scan the file system to verify that the checkpoint info stored in db is correct
196
- endOffsetLastBlock , numBlocks , err := scanForLastCompleteBlock (
205
+ _ , endOffsetLastBlock , numBlocks , err := scanForLastCompleteBlock (
197
206
rootDir , cpInfo .latestFileChunkSuffixNum , int64 (cpInfo .latestFileChunksize ))
198
207
if err != nil {
199
208
panic (fmt .Sprintf ("Could not open current file for detecting last block in the file: %s" , err ))
@@ -325,25 +334,36 @@ func (mgr *blockfileMgr) syncIndex() error {
325
334
}
326
335
indexEmpty = true
327
336
}
337
+
328
338
//initialize index to file number:zero, offset:zero and blockNum:0
329
339
startFileNum := 0
330
340
startOffset := 0
331
- blockNum := uint64 (0 )
332
341
skipFirstBlock := false
333
342
//get the last file that blocks were added to using the checkpoint info
334
343
endFileNum := mgr .cpInfo .latestFileChunkSuffixNum
344
+ startingBlockNum := uint64 (0 )
345
+
335
346
//if the index stored in the db has value, update the index information with those values
336
347
if ! indexEmpty {
348
+ if lastBlockIndexed == mgr .cpInfo .lastBlockNumber {
349
+ logger .Infof ("Both the block files and indices are in sync." )
350
+ return nil
351
+ }
352
+ logger .Infof ("Last block indexed [%d], Last block present in block files=[%d]" , lastBlockIndexed , mgr .cpInfo .lastBlockNumber )
337
353
var flp * fileLocPointer
338
354
if flp , err = mgr .index .getBlockLocByBlockNum (lastBlockIndexed ); err != nil {
339
355
return err
340
356
}
341
357
startFileNum = flp .fileSuffixNum
342
358
startOffset = flp .locPointer .offset
343
- blockNum = lastBlockIndexed
344
359
skipFirstBlock = true
360
+ startingBlockNum = lastBlockIndexed + 1
361
+ } else {
362
+ logger .Infof ("No block indexed, Last block present in block files=[%d]" , mgr .cpInfo .lastBlockNumber )
345
363
}
346
364
365
+ logger .Infof ("Start building index from block [%d]" , startingBlockNum )
366
+
347
367
//open a blockstream to the file location that was stored in the index
348
368
var stream * blockStream
349
369
if stream , err = newBlockStream (mgr .rootDir , startFileNum , int64 (startOffset ), endFileNum ); err != nil {
@@ -365,6 +385,7 @@ func (mgr *blockfileMgr) syncIndex() error {
365
385
//Should be at the last block already, but go ahead and loop looking for next blockBytes.
366
386
//If there is another block, add it to the index.
367
387
//This will ensure block indexes are correct, for example if peer had crashed before indexes got updated.
388
+ blockIdxInfo := & blockIdxInfo {}
368
389
for {
369
390
if blockBytes , blockPlacementInfo , err = stream .nextBlockBytesAndPlacementInfo (); err != nil {
370
391
return err
@@ -385,7 +406,6 @@ func (mgr *blockfileMgr) syncIndex() error {
385
406
}
386
407
387
408
//Update the blockIndexInfo with what was actually stored in file system
388
- blockIdxInfo := & blockIdxInfo {}
389
409
blockIdxInfo .blockHash = info .blockHeader .Hash ()
390
410
blockIdxInfo .blockNum = info .blockHeader .Number
391
411
blockIdxInfo .flp = & fileLocPointer {fileSuffixNum : blockPlacementInfo .fileNum ,
@@ -397,8 +417,11 @@ func (mgr *blockfileMgr) syncIndex() error {
397
417
if err = mgr .index .indexBlock (blockIdxInfo ); err != nil {
398
418
return err
399
419
}
400
- blockNum ++
420
+ if blockIdxInfo .blockNum % 10000 == 0 {
421
+ logger .Infof ("Indexed block number [%d]" , blockIdxInfo .blockNum )
422
+ }
401
423
}
424
+ logger .Infof ("Finished building index. Last block indexed [%d]" , blockIdxInfo .blockNum )
402
425
return nil
403
426
}
404
427
@@ -581,12 +604,13 @@ func (mgr *blockfileMgr) saveCurrentInfo(i *checkpointInfo, sync bool) error {
581
604
582
605
// scanForLastCompleteBlock scan a given block file and detects the last offset in the file
583
606
// after which there may lie a block partially written (towards the end of the file in a crash scenario).
584
- func scanForLastCompleteBlock (rootDir string , fileNum int , startingOffset int64 ) (int64 , int , error ) {
607
+ func scanForLastCompleteBlock (rootDir string , fileNum int , startingOffset int64 ) ([] byte , int64 , int , error ) {
585
608
//scan the passed file number suffix starting from the passed offset to find the last completed block
586
609
numBlocks := 0
610
+ var lastBlockBytes []byte
587
611
blockStream , errOpen := newBlockfileStream (rootDir , fileNum , startingOffset )
588
612
if errOpen != nil {
589
- return 0 , 0 , errOpen
613
+ return nil , 0 , 0 , errOpen
590
614
}
591
615
defer blockStream .close ()
592
616
var errRead error
@@ -596,6 +620,7 @@ func scanForLastCompleteBlock(rootDir string, fileNum int, startingOffset int64)
596
620
if blockBytes == nil || errRead != nil {
597
621
break
598
622
}
623
+ lastBlockBytes = blockBytes
599
624
numBlocks ++
600
625
}
601
626
if errRead == ErrUnexpectedEndOfBlockfile {
@@ -605,7 +630,7 @@ func scanForLastCompleteBlock(rootDir string, fileNum int, startingOffset int64)
605
630
errRead = nil
606
631
}
607
632
logger .Debugf ("scanForLastCompleteBlock(): last complete block ends at offset=[%d]" , blockStream .currentOffset )
608
- return blockStream .currentOffset , numBlocks , errRead
633
+ return lastBlockBytes , blockStream .currentOffset , numBlocks , errRead
609
634
}
610
635
611
636
// checkpointInfo
0 commit comments