@@ -18,9 +18,11 @@ package fsblkstorage
18
18
19
19
import (
20
20
"fmt"
21
+ "sync"
21
22
"sync/atomic"
22
23
23
24
"github.com/golang/protobuf/proto"
25
+ "github.com/hyperledger/fabric/core/ledger/blkstorage"
24
26
"github.com/hyperledger/fabric/core/ledger/util"
25
27
"github.com/hyperledger/fabric/core/ledger/util/db"
26
28
"github.com/hyperledger/fabric/protos"
@@ -46,11 +48,12 @@ type blockfileMgr struct {
46
48
defaultCF * gorocksdb.ColumnFamilyHandle
47
49
index index
48
50
cpInfo * checkpointInfo
51
+ cpInfoCond * sync.Cond
49
52
currentFileWriter * blockfileWriter
50
53
bcInfo atomic.Value
51
54
}
52
55
53
- func newBlockfileMgr (conf * Conf ) * blockfileMgr {
56
+ func newBlockfileMgr (conf * Conf , indexConfig * blkstorage. IndexConfig ) * blockfileMgr {
54
57
rootDir := conf .blockfilesDir
55
58
_ , err := util .CreateDirIfMissing (rootDir )
56
59
if err != nil {
@@ -69,7 +72,7 @@ func newBlockfileMgr(conf *Conf) *blockfileMgr {
69
72
panic (fmt .Sprintf ("Could not save next block file info to db: %s" , err ))
70
73
}
71
74
}
72
- updateCPInfo (conf , cpInfo )
75
+ syncCPInfoFromFS (conf , cpInfo )
73
76
currentFileWriter , err := newBlockfileWriter (deriveBlockfilePath (rootDir , cpInfo .latestFileChunkSuffixNum ))
74
77
if err != nil {
75
78
panic (fmt .Sprintf ("Could not open writer to current file: %s" , err ))
@@ -79,9 +82,10 @@ func newBlockfileMgr(conf *Conf) *blockfileMgr {
79
82
panic (fmt .Sprintf ("Could not truncate current file to known size in db: %s" , err ))
80
83
}
81
84
82
- mgr .index = newBlockIndex (db , db .GetCFHandle (blockIndexCF ))
85
+ mgr .index = newBlockIndex (indexConfig , db , db .GetCFHandle (blockIndexCF ))
83
86
mgr .cpInfo = cpInfo
84
87
mgr .currentFileWriter = currentFileWriter
88
+ mgr .cpInfoCond = sync .NewCond (& sync.Mutex {})
85
89
mgr .syncIndex ()
86
90
87
91
// init BlockchainInfo
@@ -119,7 +123,7 @@ func initDB(conf *Conf) *db.DB {
119
123
return dbInst
120
124
}
121
125
122
- func updateCPInfo (conf * Conf , cpInfo * checkpointInfo ) {
126
+ func syncCPInfoFromFS (conf * Conf , cpInfo * checkpointInfo ) {
123
127
logger .Debugf ("Starting checkpoint=%s" , cpInfo )
124
128
rootDir := conf .blockfilesDir
125
129
filePath := deriveBlockfilePath (rootDir , cpInfo .latestFileChunkSuffixNum )
@@ -156,23 +160,24 @@ func (mgr *blockfileMgr) close() {
156
160
}
157
161
158
162
func (mgr * blockfileMgr ) moveToNextFile () {
159
- nextFileInfo := & checkpointInfo {
163
+ cpInfo := & checkpointInfo {
160
164
latestFileChunkSuffixNum : mgr .cpInfo .latestFileChunkSuffixNum + 1 ,
161
- latestFileChunksize : 0 }
165
+ latestFileChunksize : 0 ,
166
+ lastBlockNumber : mgr .cpInfo .lastBlockNumber }
162
167
163
168
nextFileWriter , err := newBlockfileWriter (
164
- deriveBlockfilePath (mgr .rootDir , nextFileInfo .latestFileChunkSuffixNum ))
169
+ deriveBlockfilePath (mgr .rootDir , cpInfo .latestFileChunkSuffixNum ))
165
170
166
171
if err != nil {
167
172
panic (fmt .Sprintf ("Could not open writer to next file: %s" , err ))
168
173
}
169
174
mgr .currentFileWriter .close ()
170
- err = mgr .saveCurrentInfo (nextFileInfo , true )
175
+ err = mgr .saveCurrentInfo (cpInfo , true )
171
176
if err != nil {
172
177
panic (fmt .Sprintf ("Could not save next block file info to db: %s" , err ))
173
178
}
174
- mgr .cpInfo = nextFileInfo
175
179
mgr .currentFileWriter = nextFileWriter
180
+ mgr .updateCheckpoint (cpInfo )
176
181
}
177
182
178
183
func (mgr * blockfileMgr ) addBlock (block * protos.Block2 ) error {
@@ -207,26 +212,30 @@ func (mgr *blockfileMgr) addBlock(block *protos.Block2) error {
207
212
return fmt .Errorf ("Error while appending block to file: %s" , err )
208
213
}
209
214
210
- mgr .cpInfo .latestFileChunksize += totalBytesToAppend
211
- mgr .cpInfo .lastBlockNumber ++
212
- err = mgr .saveCurrentInfo (mgr .cpInfo , false )
213
- if err != nil {
214
- mgr .cpInfo .latestFileChunksize -= totalBytesToAppend
215
- truncateErr := mgr .currentFileWriter .truncateFile (mgr .cpInfo .latestFileChunksize )
215
+ currentCPInfo := mgr .cpInfo
216
+ newCPInfo := & checkpointInfo {
217
+ latestFileChunkSuffixNum : currentCPInfo .latestFileChunkSuffixNum ,
218
+ latestFileChunksize : currentCPInfo .latestFileChunksize + totalBytesToAppend ,
219
+ lastBlockNumber : currentCPInfo .lastBlockNumber + 1 }
220
+ if err = mgr .saveCurrentInfo (newCPInfo , false ); err != nil {
221
+ truncateErr := mgr .currentFileWriter .truncateFile (currentCPInfo .latestFileChunksize )
216
222
if truncateErr != nil {
217
223
panic (fmt .Sprintf ("Error in truncating current file to known size after an error in saving checkpoint info: %s" , err ))
218
224
}
219
225
return fmt .Errorf ("Error while saving current file info to db: %s" , err )
220
226
}
221
- blockFLP := & fileLocPointer {fileSuffixNum : mgr .cpInfo .latestFileChunkSuffixNum }
227
+
228
+ blockFLP := & fileLocPointer {fileSuffixNum : newCPInfo .latestFileChunkSuffixNum }
222
229
blockFLP .offset = currentOffset
223
230
// shift the txoffset because we prepend length of bytes before block bytes
224
231
for i := 0 ; i < len (txOffsets ); i ++ {
225
232
txOffsets [i ] += len (blockBytesEncodedLen )
226
233
}
227
234
mgr .index .indexBlock (& blockIdxInfo {
228
- blockNum : mgr . cpInfo .lastBlockNumber , blockHash : blockHash ,
235
+ blockNum : newCPInfo .lastBlockNumber , blockHash : blockHash ,
229
236
flp : blockFLP , txOffsets : txOffsets })
237
+
238
+ mgr .updateCheckpoint (newCPInfo )
230
239
mgr .updateBlockchainInfo (blockHash , block )
231
240
return nil
232
241
}
@@ -291,6 +300,14 @@ func (mgr *blockfileMgr) getBlockchainInfo() *protos.BlockchainInfo {
291
300
return mgr .bcInfo .Load ().(* protos.BlockchainInfo )
292
301
}
293
302
303
+ func (mgr * blockfileMgr ) updateCheckpoint (cpInfo * checkpointInfo ) {
304
+ mgr .cpInfoCond .L .Lock ()
305
+ defer mgr .cpInfoCond .L .Unlock ()
306
+ mgr .cpInfo = cpInfo
307
+ logger .Debugf ("Broadcasting about update checkpointInfo: %s" , cpInfo )
308
+ mgr .cpInfoCond .Broadcast ()
309
+ }
310
+
294
311
func (mgr * blockfileMgr ) updateBlockchainInfo (latestBlockHash []byte , latestBlock * protos.Block2 ) {
295
312
currentBCInfo := mgr .getBlockchainInfo ()
296
313
newBCInfo := & protos.BlockchainInfo {
@@ -328,18 +345,8 @@ func (mgr *blockfileMgr) retrieveSerBlockByNumber(blockNum uint64) (*protos.SerB
328
345
return mgr .fetchSerBlock (loc )
329
346
}
330
347
331
- func (mgr * blockfileMgr ) retrieveBlocks (startNum uint64 , endNum uint64 ) (* BlocksItr , error ) {
332
- var lp * fileLocPointer
333
- var err error
334
- if lp , err = mgr .index .getBlockLocByBlockNum (startNum ); err != nil {
335
- return nil , err
336
- }
337
- var stream * blockStream
338
- if stream , err = newBlockStream (mgr .rootDir , lp .fileSuffixNum ,
339
- int64 (lp .offset ), mgr .cpInfo .latestFileChunkSuffixNum ); err != nil {
340
- return nil , err
341
- }
342
- return newBlockItr (stream , int (endNum - startNum )+ 1 ), nil
348
+ func (mgr * blockfileMgr ) retrieveBlocks (startNum uint64 ) (* BlocksItr , error ) {
349
+ return newBlockItr (mgr , startNum ), nil
343
350
}
344
351
345
352
func (mgr * blockfileMgr ) retrieveTransactionByID (txID string ) (* protos.Transaction2 , error ) {
0 commit comments