Skip to content

Commit ca95604

Browse files
manish-sethicendhu
authored andcommitted
Fix rollback bug
FAB-15963 #done Change-Id: I3bb168e8e678530ee809acc4fbfee103f228526c Signed-off-by: manish <manish.sethi@gmail.com> Signed-off-by: senthil <cendhu@gmail.com> (cherry picked from commit 61199ed)
1 parent c208c57 commit ca95604

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

common/ledger/blkstorage/fsblkstorage/rollback.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ func populateBlockInfoWithDuplicateTxids(blockInfo *serializedBlockInfo, placeme
145145

146146
for _, txOffset := range blockInfo.txOffsets {
147147
blockLoc, err := indexStore.getBlockLocByTxID(txOffset.txID)
148+
// There is a situations where the txid entries for a config transaction may not present in the index. This is caused
149+
// by the fact that in the data produced by a release proior to 1.4.2, the txID for a config transaction is used as
150+
// an empty string. However, in the data produced by release 1.4.2 (and up), the real txID is used by computing in the
151+
// indexing code. So, a mismatch is possible where the generated txID is not present in the index
152+
if err == blkstorage.ErrNotFoundInIndex {
153+
logger.Warnf("TxID [%s] not found in index... skipping this TxID", txOffset.txID)
154+
continue
155+
}
148156
if err != nil {
149157
return err
150158
}

common/ledger/blkstorage/fsblkstorage/rollback_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/hyperledger/fabric/common/ledger/blkstorage"
1313
"github.com/hyperledger/fabric/common/ledger/testutil"
14+
"github.com/hyperledger/fabric/common/ledger/util/leveldbhelper"
1415
"github.com/hyperledger/fabric/common/metrics/disabled"
1516
"github.com/hyperledger/fabric/protos/common"
1617
"github.com/hyperledger/fabric/protos/peer"
@@ -300,6 +301,48 @@ func TestDuplicateTxIDDuringRollback(t *testing.T) {
300301
blkfileMgrWrapper.testGetTransactionByTxID("tx0", blocks[2].Data.Data[0], nil)
301302
}
302303

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+
303346
func assertBlockStoreRollback(t *testing.T, path, ledgerID string, maxFileSize int, blocks []*common.Block,
304347
rollbackedToBlkNum uint64, lastFileSuffixNum int, indexConfig *blkstorage.IndexConfig) {
305348

@@ -350,3 +393,27 @@ func assertBlockStoreRollback(t *testing.T, path, ledgerID string, maxFileSize i
350393
env.provider.Close()
351394
blkfileMgrWrapper.close()
352395
}
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

Comments
 (0)