@@ -11,6 +11,7 @@ import (
11
11
12
12
"github.com/hyperledger/fabric/common/ledger/blkstorage"
13
13
"github.com/hyperledger/fabric/common/ledger/testutil"
14
+ "github.com/hyperledger/fabric/common/ledger/util/leveldbhelper"
14
15
"github.com/hyperledger/fabric/common/metrics/disabled"
15
16
"github.com/hyperledger/fabric/protos/common"
16
17
"github.com/hyperledger/fabric/protos/peer"
@@ -300,6 +301,48 @@ func TestDuplicateTxIDDuringRollback(t *testing.T) {
300
301
blkfileMgrWrapper .testGetTransactionByTxID ("tx0" , blocks [2 ].Data .Data [0 ], nil )
301
302
}
302
303
304
+ func TestRollbackTxIDMissingFromIndex (t * testing.T ) {
305
+ // Polpulate block store with four blocks
306
+ path := testPath ()
307
+ blocks := testutil .ConstructTestBlocks (t , 4 )
308
+ testutil .SetTxID (t , blocks [3 ], 0 , "blk3_tx0" )
309
+
310
+ env := newTestEnv (t , NewConf (path , 0 ))
311
+ defer env .Cleanup ()
312
+ blkfileMgrWrapper := newTestBlockfileWrapper (env , "testLedger" )
313
+
314
+ blkfileMgrWrapper .addBlocks (blocks )
315
+ expectedBlockchainInfo := & common.BlockchainInfo {
316
+ Height : 4 ,
317
+ CurrentBlockHash : protoutil .BlockHeaderHash (blocks [3 ].Header ),
318
+ PreviousBlockHash : protoutil .BlockHeaderHash (blocks [2 ].Header ),
319
+ }
320
+ actualBlockchainInfo := blkfileMgrWrapper .blockfileMgr .getBlockchainInfo ()
321
+ assert .Equal (t , expectedBlockchainInfo , actualBlockchainInfo )
322
+ blkfileMgrWrapper .testGetTransactionByTxID ("blk3_tx0" , blocks [3 ].Data .Data [0 ], nil )
323
+
324
+ // Delete index entries for a tx
325
+ testutilDeleteTxFromIndex (t , blkfileMgrWrapper .blockfileMgr .db , 3 , 0 , "blk3_tx0" )
326
+ env .provider .Close ()
327
+ blkfileMgrWrapper .close ()
328
+
329
+ // Rollback to block 2
330
+ indexConfig := & blkstorage.IndexConfig {AttrsToIndex : attrsToIndex }
331
+ err := Rollback (path , "testLedger" , 2 , indexConfig )
332
+ assert .NoError (t , err )
333
+
334
+ // Reopen blockstorage and assert basic functionality
335
+ env = newTestEnv (t , NewConf (path , 0 ))
336
+ blkfileMgrWrapper = newTestBlockfileWrapper (env , "testLedger" )
337
+ expectedBlockchainInfo = & common.BlockchainInfo {
338
+ Height : 3 ,
339
+ CurrentBlockHash : protoutil .BlockHeaderHash (blocks [2 ].Header ),
340
+ PreviousBlockHash : protoutil .BlockHeaderHash (blocks [1 ].Header ),
341
+ }
342
+ actualBlockchainInfo = blkfileMgrWrapper .blockfileMgr .getBlockchainInfo ()
343
+ assert .Equal (t , expectedBlockchainInfo , actualBlockchainInfo )
344
+ }
345
+
303
346
func assertBlockStoreRollback (t * testing.T , path , ledgerID string , maxFileSize int , blocks []* common.Block ,
304
347
rollbackedToBlkNum uint64 , lastFileSuffixNum int , indexConfig * blkstorage.IndexConfig ) {
305
348
@@ -350,3 +393,27 @@ func assertBlockStoreRollback(t *testing.T, path, ledgerID string, maxFileSize i
350
393
env .provider .Close ()
351
394
blkfileMgrWrapper .close ()
352
395
}
396
+
397
+ func testutilDeleteTxFromIndex (t * testing.T , db * leveldbhelper.DBHandle , blkNum , txNum uint64 , txID string ) {
398
+ indexKeys := [][]byte {
399
+ constructTxIDKey (txID ),
400
+ constructBlockNumTranNumKey (blkNum , txNum ),
401
+ constructBlockTxIDKey (txID ),
402
+ constructTxValidationCodeIDKey (txID ),
403
+ }
404
+
405
+ batch := leveldbhelper .NewUpdateBatch ()
406
+ for _ , key := range indexKeys {
407
+ value , err := db .Get (key )
408
+ assert .NoError (t , err )
409
+ assert .NotNil (t , value )
410
+ batch .Delete (key )
411
+ }
412
+ db .WriteBatch (batch , true )
413
+
414
+ for _ , key := range indexKeys {
415
+ value , err := db .Get (key )
416
+ assert .NoError (t , err )
417
+ assert .Nil (t , value )
418
+ }
419
+ }
0 commit comments