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