github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/tests/reset_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/common/ledger/blkstorage" 14 "github.com/hechain20/hechain/core/ledger" 15 "github.com/hechain20/hechain/core/ledger/kvledger" 16 "github.com/hyperledger/fabric-protos-go/common" 17 "github.com/stretchr/testify/require" 18 ) 19 20 func TestResetAllLedgers(t *testing.T) { 21 env := newEnv(t) 22 defer env.cleanup() 23 env.initLedgerMgmt() 24 // populate ledgers with sample data 25 dataHelper := newSampleDataHelper(t) 26 var genesisBlocks []*common.Block 27 var blockchainsInfo []*common.BlockchainInfo 28 29 // create ledgers and pouplate with sample data 30 // Also, retrieve the genesis blocks and blockchain info for matching later 31 numLedgers := 10 32 ledgerIDs := make([]string, numLedgers) 33 for i := 0; i < numLedgers; i++ { 34 ledgerIDs[i] = fmt.Sprintf("ledger-%d", i) 35 l := env.createTestLedgerFromGenesisBlk(ledgerIDs[i]) 36 dataHelper.populateLedger(l) 37 dataHelper.verifyLedgerContent(l) 38 gb, err := l.lgr.GetBlockByNumber(0) 39 require.NoError(t, err) 40 genesisBlocks = append(genesisBlocks, gb) 41 bcInfo, err := l.lgr.GetBlockchainInfo() 42 require.NoError(t, err) 43 blockchainsInfo = append(blockchainsInfo, bcInfo) 44 } 45 env.closeLedgerMgmt() 46 47 // Reset All kv ledgers 48 rootFSPath := env.initializer.Config.RootFSPath 49 err := kvledger.ResetAllKVLedgers(rootFSPath) 50 require.NoError(t, err) 51 rebuildable := rebuildableStatedb | rebuildableBookkeeper | rebuildableConfigHistory | rebuildableHistoryDB | rebuildableBlockIndex 52 env.verifyRebuilableDirEmpty(rebuildable) 53 env.initLedgerMgmt() 54 preResetHt, err := kvledger.LoadPreResetHeight(rootFSPath, ledgerIDs) 55 require.NoError(t, err) 56 t.Logf("preResetHt = %#v", preResetHt) 57 // open all the ledgers again and verify that 58 // - initial height==1 59 // - compare the genesis block from the one before reset 60 // - resubmit the previous committed blocks from block number 1 onwards 61 // and final blockchainInfo and ledger state same as before reset 62 for i := 0; i < 10; i++ { 63 ledgerID := fmt.Sprintf("ledger-%d", i) 64 l := env.openTestLedger(ledgerID) 65 l.verifyLedgerHeight(1) 66 require.Equal(t, blockchainsInfo[i].Height, preResetHt[ledgerID]) 67 gb, err := l.lgr.GetBlockByNumber(0) 68 require.NoError(t, err) 69 require.Equal(t, genesisBlocks[i], gb) 70 for _, b := range dataHelper.submittedData[ledgerID].Blocks { 71 require.NoError(t, l.lgr.CommitLegacy(b, &ledger.CommitOptions{})) 72 } 73 bcInfo, err := l.lgr.GetBlockchainInfo() 74 require.NoError(t, err) 75 require.Equal(t, blockchainsInfo[i], bcInfo) 76 dataHelper.verifyLedgerContent(l) 77 } 78 79 require.NoError(t, kvledger.ClearPreResetHeight(env.initializer.Config.RootFSPath, ledgerIDs)) 80 preResetHt, err = kvledger.LoadPreResetHeight(env.initializer.Config.RootFSPath, ledgerIDs) 81 require.NoError(t, err) 82 require.Len(t, preResetHt, 0) 83 84 // reset again to test ClearPreResetHeight with different ledgerIDs 85 env.closeLedgerMgmt() 86 err = kvledger.ResetAllKVLedgers(rootFSPath) 87 require.NoError(t, err) 88 env.initLedgerMgmt() 89 // verify LoadPreResetHeight with different ledgerIDs 90 newLedgerIDs := ledgerIDs[:len(ledgerIDs)-3] 91 preResetHt, err = kvledger.LoadPreResetHeight(env.initializer.Config.RootFSPath, newLedgerIDs) 92 require.NoError(t, err) 93 require.Equal(t, numLedgers-3, len(preResetHt)) 94 for i := 0; i < len(preResetHt); i++ { 95 require.Contains(t, preResetHt, fmt.Sprintf("ledger-%d", i)) 96 } 97 // verify preResetHt after ClearPreResetHeight 98 require.NoError(t, kvledger.ClearPreResetHeight(env.initializer.Config.RootFSPath, newLedgerIDs)) 99 preResetHt, err = kvledger.LoadPreResetHeight(env.initializer.Config.RootFSPath, ledgerIDs) 100 require.NoError(t, err) 101 require.Len(t, preResetHt, 3) 102 require.Contains(t, preResetHt, fmt.Sprintf("ledger-%d", 7)) 103 require.Contains(t, preResetHt, fmt.Sprintf("ledger-%d", 8)) 104 require.Contains(t, preResetHt, fmt.Sprintf("ledger-%d", 9)) 105 } 106 107 func TestResetAllLedgersWithBTL(t *testing.T) { 108 env := newEnv(t) 109 defer env.cleanup() 110 env.initLedgerMgmt() 111 l := env.createTestLedgerFromGenesisBlk("ledger1") 112 collConf := []*collConf{{name: "coll1", btl: 0}, {name: "coll2", btl: 1}} 113 114 // deploy cc1 with 'collConf' 115 l.simulateDeployTx("cc1", collConf) 116 blk1 := l.cutBlockAndCommitLegacy() 117 118 // commit pvtdata writes in block 2. 119 l.simulateDataTx("", func(s *simulator) { 120 s.setPvtdata("cc1", "coll1", "key1", "value1") // (key1 would never expire) 121 s.setPvtdata("cc1", "coll2", "key2", "value2") // (key2 would expire at block 4) 122 }) 123 blk2 := l.cutBlockAndCommitLegacy() 124 125 // After commit of block 2 126 l.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 127 l.verifyPvtState("cc1", "coll2", "key2", "value2") // key2 should still exist in the state 128 l.verifyBlockAndPvtDataSameAs(2, blk2) // key1 and key2 should still exist in the pvtdata storage 129 130 // After commit of block 3 131 l.simulateDataTx("", func(s *simulator) { 132 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 133 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 134 }) 135 blk3 := l.cutBlockAndCommitLegacy() 136 137 // After commit of block 4 138 l.simulateDataTx("", func(s *simulator) { 139 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 140 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 141 }) 142 blk4 := l.cutBlockAndCommitLegacy() 143 144 // After commit of block 4 145 l.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 146 l.verifyPvtState("cc1", "coll2", "key2", "") // key2 should have been purged from the state 147 l.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 148 r.pvtdataShouldContain(0, "cc1", "coll1", "key1", "value1") // key1 should still exist in the pvtdata storage 149 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 150 }) 151 152 env.closeLedgerMgmt() 153 154 // reset ledgers to genesis block 155 err := kvledger.ResetAllKVLedgers(env.initializer.Config.RootFSPath) 156 require.NoError(t, err) 157 rebuildable := rebuildableStatedb | rebuildableBookkeeper | rebuildableConfigHistory | rebuildableHistoryDB | rebuildableBlockIndex 158 env.verifyRebuilableDirEmpty(rebuildable) 159 env.initLedgerMgmt() 160 161 // ensure that the reset is executed correctly 162 preResetHt, err := kvledger.LoadPreResetHeight(env.initializer.Config.RootFSPath, []string{"ledger1"}) 163 require.NoError(t, err) 164 t.Logf("preResetHt = %#v", preResetHt) 165 require.Equal(t, uint64(5), preResetHt["ledger1"]) 166 l = env.openTestLedger("ledger1") 167 l.verifyLedgerHeight(1) 168 169 // recommit blocks 170 require.NoError(t, l.lgr.CommitLegacy(blk1, &ledger.CommitOptions{})) 171 require.NoError(t, l.lgr.CommitLegacy(blk2, &ledger.CommitOptions{})) 172 // After the recommit of block 2 173 l.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 174 l.verifyPvtState("cc1", "coll2", "key2", "value2") // key2 should still exist in the state 175 require.NoError(t, l.lgr.CommitLegacy(blk3, &ledger.CommitOptions{})) 176 require.NoError(t, l.lgr.CommitLegacy(blk4, &ledger.CommitOptions{})) 177 178 // after the recommit of block 4 179 l.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 180 l.verifyPvtState("cc1", "coll2", "key2", "") // key2 should have been purged from the state 181 l.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 182 r.pvtdataShouldContain(0, "cc1", "coll1", "key1", "value1") // key1 should still exist in the pvtdata storage 183 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 184 }) 185 } 186 187 func TestResetLedgerWithoutDroppingDBs(t *testing.T) { 188 env := newEnv(t) 189 defer env.cleanup() 190 env.initLedgerMgmt() 191 // populate ledgers with sample data 192 dataHelper := newSampleDataHelper(t) 193 194 // create ledgers and pouplate with sample data 195 l := env.createTestLedgerFromGenesisBlk("ledger-1") 196 dataHelper.populateLedger(l) 197 dataHelper.verifyLedgerContent(l) 198 env.closeLedgerMgmt() 199 200 // Reset All kv ledgers 201 blockstorePath := kvledger.BlockStorePath(env.initializer.Config.RootFSPath) 202 err := blkstorage.ResetBlockStore(blockstorePath) 203 require.NoError(t, err) 204 rebuildable := rebuildableStatedb | rebuildableBookkeeper | rebuildableConfigHistory | rebuildableHistoryDB 205 env.verifyRebuilablesExist(rebuildable) 206 rebuildable = rebuildableBlockIndex 207 env.verifyRebuilableDirEmpty(rebuildable) 208 env.initLedgerMgmt() 209 preResetHt, err := kvledger.LoadPreResetHeight(env.initializer.Config.RootFSPath, []string{"ledger-1"}) 210 t.Logf("preResetHt = %#v", preResetHt) 211 require.NoError(t, err) 212 require.Equal(t, uint64(9), preResetHt["ledger-1"]) 213 _, err = env.ledgerMgr.OpenLedger("ledger-1") 214 // populateLedger() stores 8 block in total 215 require.EqualError(t, err, "the state database [height=9] is ahead of the block store [height=1]. "+ 216 "This is possible when the state database is not dropped after a ledger reset/rollback. "+ 217 "The state database can safely be dropped and will be rebuilt up to block store height upon the next peer start") 218 }