github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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/osdi23p228/fabric/core/ledger" 14 "github.com/osdi23p228/fabric/core/ledger/kvledger" 15 "github.com/stretchr/testify/assert" 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 h := env.newTestHelperCreateLgr("testLedger", t) 26 // populate creates 8 blocks 27 dataHelper.populateLedger(h) 28 dataHelper.verifyLedgerContent(h) 29 bcInfo, err := h.lgr.GetBlockchainInfo() 30 assert.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 assert.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 assert.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 assert.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 assert.NoError(t, err) 50 assert.Equal(t, bcInfo.Height, preResetHt["testLedger"]) 51 t.Logf("preResetHt = %#v", preResetHt) 52 53 h = env.newTestHelperOpenLgr("testLedger", t) 54 h.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 assert.NoError(t, h.lgr.CommitLegacy(b, &ledger.CommitOptions{FetchPvtDataFromLedger: true})) 60 } 61 actualBcInfo, err := h.lgr.GetBlockchainInfo() 62 assert.Equal(t, bcInfo, actualBcInfo) 63 dataHelper.verifyLedgerContent(h) 64 // TODO: extend integration test with BTL support for pvtData. FAB-15704 65 } 66 67 func TestRollbackKVLedgerWithBTL(t *testing.T) { 68 env := newEnv(t) 69 defer env.cleanup() 70 env.initLedgerMgmt() 71 h := env.newTestHelperCreateLgr("ledger1", t) 72 collConf := []*collConf{{name: "coll1", btl: 0}, {name: "coll2", btl: 1}} 73 74 // deploy cc1 with 'collConf' 75 h.simulateDeployTx("cc1", collConf) 76 h.cutBlockAndCommitLegacy() 77 78 // commit pvtdata writes in block 2. 79 h.simulateDataTx("", func(s *simulator) { 80 s.setPvtdata("cc1", "coll1", "key1", "value1") // (key1 would never expire) 81 s.setPvtdata("cc1", "coll2", "key2", "value2") // (key2 would expire at block 4) 82 }) 83 blk2 := h.cutBlockAndCommitLegacy() 84 85 // After commit of block 2 86 h.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 87 h.verifyPvtState("cc1", "coll2", "key2", "value2") // key2 should still exist in the state 88 h.verifyBlockAndPvtDataSameAs(2, blk2) // key1 and key2 should still exist in the pvtdata storage 89 90 // commit 2 more blocks with some random key/vals 91 for i := 0; i < 2; i++ { 92 h.simulateDataTx("", func(s *simulator) { 93 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 94 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 95 }) 96 h.cutBlockAndCommitLegacy() 97 } 98 99 // After commit of block 4 100 h.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 101 h.verifyPvtState("cc1", "coll2", "key2", "") // key2 should have been purged from the state 102 h.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 103 r.pvtdataShouldContain(0, "cc1", "coll1", "key1", "value1") // key1 should still exist in the pvtdata storage 104 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 105 }) 106 107 // commit block 5 with some random key/vals 108 h.simulateDataTx("", func(s *simulator) { 109 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 110 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 111 }) 112 h.cutBlockAndCommitLegacy() 113 env.closeLedgerMgmt() 114 115 // rebuild statedb and bookkeeper 116 err := kvledger.RollbackKVLedger(env.initializer.Config.RootFSPath, "ledger1", 4) 117 assert.NoError(t, err) 118 rebuildable := rebuildableStatedb | rebuildableBookkeeper | rebuildableConfigHistory | rebuildableHistoryDB 119 env.verifyRebuilableDirEmpty(rebuildable) 120 121 env.initLedgerMgmt() 122 h = env.newTestHelperOpenLgr("ledger1", t) 123 h.verifyPvtState("cc1", "coll1", "key1", "value1") // key1 should still exist in the state 124 h.verifyPvtState("cc1", "coll2", "key2", "") // key2 should have been purged from the state 125 h.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 126 r.pvtdataShouldContain(0, "cc1", "coll1", "key1", "value1") // key1 should still exist in the pvtdata storage 127 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 128 }) 129 130 // commit block 5 with some random key/vals 131 h.simulateDataTx("", func(s *simulator) { 132 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 133 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 134 }) 135 h.cutBlockAndCommitLegacy() 136 137 // commit pvtdata writes in block 6. 138 h.simulateDataTx("", func(s *simulator) { 139 s.setPvtdata("cc1", "coll1", "key3", "value1") // (key3 would never expire) 140 s.setPvtdata("cc1", "coll2", "key4", "value2") // (key4 would expire at block 8) 141 }) 142 h.cutBlockAndCommitLegacy() 143 144 // commit 2 more blocks with some random key/vals 145 for i := 0; i < 2; i++ { 146 h.simulateDataTx("", func(s *simulator) { 147 s.setPvtdata("cc1", "coll1", "someOtherKey", "someOtherVal") 148 s.setPvtdata("cc1", "coll2", "someOtherKey", "someOtherVal") 149 }) 150 h.cutBlockAndCommitLegacy() 151 } 152 153 // After commit of block 8 154 h.verifyPvtState("cc1", "coll1", "key3", "value1") // key3 should still exist in the state 155 h.verifyPvtState("cc1", "coll2", "key4", "") // key4 should have been purged from the state 156 h.verifyBlockAndPvtData(6, nil, func(r *retrievedBlockAndPvtdata) { // retrieve the pvtdata for block 2 from pvtdata storage 157 r.pvtdataShouldContain(0, "cc1", "coll1", "key3", "value1") // key3 should still exist in the pvtdata storage 158 r.pvtdataShouldNotContain("cc1", "coll2") // <cc1, coll2> shold have been purged from the pvtdata storage 159 }) 160 }