github.com/true-sqn/fabric@v2.1.1+incompatible/core/ledger/kvledger/tests/rollback_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package tests 8 9 import ( 10 "fmt" 11 "testing" 12 13 "github.com/hyperledger/fabric-protos-go/common" 14 "github.com/hyperledger/fabric/core/ledger" 15 "github.com/hyperledger/fabric/core/ledger/kvledger" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 func TestRollbackKVLedger(t *testing.T) { 20 env := newEnv(t) 21 defer env.cleanup() 22 env.initLedgerMgmt() 23 // populate ledgers with sample data 24 dataHelper := newSampleDataHelper(t) 25 var blockchainsInfo []*common.BlockchainInfo 26 27 h := env.newTestHelperCreateLgr("testLedger", t) 28 // populate creates 8 blocks 29 dataHelper.populateLedger(h) 30 dataHelper.verifyLedgerContent(h) 31 bcInfo, err := h.lgr.GetBlockchainInfo() 32 assert.NoError(t, err) 33 blockchainsInfo = append(blockchainsInfo, bcInfo) 34 env.closeLedgerMgmt() 35 36 // Rollback the testLedger (invalid rollback params) 37 err = kvledger.RollbackKVLedger(env.initializer.Config.RootFSPath, "noLedger", 0) 38 assert.Equal(t, "ledgerID [noLedger] does not exist", err.Error()) 39 err = kvledger.RollbackKVLedger(env.initializer.Config.RootFSPath, "testLedger", bcInfo.Height) 40 expectedErr := fmt.Sprintf("target block number [%d] should be less than the biggest block number [%d]", 41 bcInfo.Height, bcInfo.Height-1) 42 assert.Equal(t, expectedErr, err.Error()) 43 44 // Rollback the testLedger (valid rollback params) 45 targetBlockNum := bcInfo.Height - 3 46 err = kvledger.RollbackKVLedger(env.initializer.Config.RootFSPath, "testLedger", targetBlockNum) 47 assert.NoError(t, err) 48 rebuildable := rebuildableStatedb + rebuildableBookkeeper + rebuildableConfigHistory + rebuildableHistoryDB 49 env.verifyRebuilableDoesNotExist(rebuildable) 50 env.initLedgerMgmt() 51 preResetHt, err := kvledger.LoadPreResetHeight(env.initializer.Config.RootFSPath, []string{"testLedger"}) 52 assert.Equal(t, bcInfo.Height, preResetHt["testLedger"]) 53 t.Logf("preResetHt = %#v", preResetHt) 54 55 h = env.newTestHelperOpenLgr("testLedger", t) 56 h.verifyLedgerHeight(targetBlockNum + 1) 57 targetBlockNumIndex := targetBlockNum - 1 58 for _, b := range dataHelper.submittedData["testLedger"].Blocks[targetBlockNumIndex+1:] { 59 // if the pvtData is already present in the pvtdata store, the ledger (during commit) should be 60 // able to fetch them if not passed along with the block. 61 assert.NoError(t, h.lgr.CommitLegacy(b, &ledger.CommitOptions{FetchPvtDataFromLedger: true})) 62 } 63 actualBcInfo, err := h.lgr.GetBlockchainInfo() 64 assert.Equal(t, bcInfo, actualBcInfo) 65 dataHelper.verifyLedgerContent(h) 66 // TODO: extend integration test with BTL support for pvtData. FAB-15704 67 } 68 69 func TestRollbackKVLedgerWithBTL(t *testing.T) { 70 env := newEnv(t) 71 defer env.cleanup() 72 env.initLedgerMgmt() 73 h := env.newTestHelperCreateLgr("ledger1", t) 74 collConf := []*collConf{{name: "coll1", btl: 0}, {name: "coll2", btl: 1}} 75 76 // deploy cc1 with 'collConf' 77 h.simulateDeployTx("cc1", collConf) 78 h.cutBlockAndCommitLegacy() 79 80 // commit pvtdata writes in block 2. 81 h.simulateDataTx("", func(s *simulator) { 82 s.setPvtdata("cc1", "coll1", "key1", "value1") // (key1 would never expire) 83 s.setPvtdata("cc1", "coll2", "key2", "value2") // (key2 would expire at block 4) 84 }) 85 blk2 := h.cutBlockAndCommitLegacy() 86 87 // After commit of block 2 88 h.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 89 h.verifyPvtState("cc1", "coll2", "key2", "value2") // key2 should still exist in the state 90 h.verifyBlockAndPvtDataSameAs(2, blk2) // key1 and key2 should still exist in the pvtdata storage 91 92 // commit 2 more blocks with some random key/vals 93 for i := 0; i < 2; i++ { 94 h.simulateDataTx("", func(s *simulator) { 95 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 96 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 97 }) 98 h.cutBlockAndCommitLegacy() 99 } 100 101 // After commit of block 4 102 h.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 103 h.verifyPvtState("cc1", "coll2", "key2", "") // key2 should have been purged from the state 104 h.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 105 r.pvtdataShouldContain(0, "cc1", "coll1", "key1", "value1") // key1 should still exist in the pvtdata storage 106 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 107 }) 108 109 // commit block 5 with some random key/vals 110 h.simulateDataTx("", func(s *simulator) { 111 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 112 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 113 }) 114 h.cutBlockAndCommitLegacy() 115 env.closeLedgerMgmt() 116 117 // rebuild statedb and bookkeeper 118 err := kvledger.RollbackKVLedger(env.initializer.Config.RootFSPath, "ledger1", 4) 119 assert.NoError(t, err) 120 rebuildable := rebuildableStatedb | rebuildableBookkeeper | rebuildableConfigHistory | rebuildableHistoryDB 121 env.verifyRebuilableDoesNotExist(rebuildable) 122 123 env.initLedgerMgmt() 124 h = env.newTestHelperOpenLgr("ledger1", t) 125 h.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 126 h.verifyPvtState("cc1", "coll2", "key2", "") // key2 should have been purged from the state 127 h.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 128 r.pvtdataShouldContain(0, "cc1", "coll1", "key1", "value1") // key1 should still exist in the pvtdata storage 129 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 130 }) 131 132 // commit block 5 with some random key/vals 133 h.simulateDataTx("", func(s *simulator) { 134 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 135 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 136 }) 137 h.cutBlockAndCommitLegacy() 138 139 // commit pvtdata writes in block 6. 140 h.simulateDataTx("", func(s *simulator) { 141 s.setPvtdata("cc1", "coll1", "key3", "value1") // (key3 would never expire) 142 s.setPvtdata("cc1", "coll2", "key4", "value2") // (key4 would expire at block 8) 143 }) 144 h.cutBlockAndCommitLegacy() 145 146 // commit 2 more blocks with some random key/vals 147 for i := 0; i < 2; i++ { 148 h.simulateDataTx("", func(s *simulator) { 149 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 150 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 151 }) 152 h.cutBlockAndCommitLegacy() 153 } 154 155 // After commit of block 8 156 h.verifyPvtState("cc1", "coll1", "key3", "value1") // key3 should still exist in the state 157 h.verifyPvtState("cc1", "coll2", "key4", "") // key4 should have been purged from the state 158 h.verifyBlockAndPvtData(6, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 159 r.pvtdataShouldContain(0, "cc1", "coll1", "key3", "value1") // key3 should still exist in the pvtdata storage 160 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 161 }) 162 }