github.com/true-sqn/fabric@v2.1.1+incompatible/core/ledger/kvledger/tests/sample_data_helper.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 protopeer "github.com/hyperledger/fabric-protos-go/peer" 14 "github.com/hyperledger/fabric/core/ledger" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 type submittedData map[string]*submittedLedgerData 19 20 type submittedLedgerData struct { 21 Blocks []*ledger.BlockAndPvtData 22 Txs []*txAndPvtdata 23 } 24 25 func (s submittedData) initForLedger(lgrid string) { 26 ld := s[lgrid] 27 if ld == nil { 28 ld = &submittedLedgerData{} 29 s[lgrid] = ld 30 } 31 } 32 33 func (s submittedData) recordSubmittedBlks(lgrid string, blk ...*ledger.BlockAndPvtData) { 34 s.initForLedger(lgrid) 35 s[lgrid].Blocks = append(s[lgrid].Blocks, blk...) 36 } 37 38 func (s submittedData) recordSubmittedTxs(lgrid string, tx ...*txAndPvtdata) { 39 s.initForLedger(lgrid) 40 s[lgrid].Txs = append(s[lgrid].Txs, tx...) 41 } 42 43 type sampleDataHelper struct { 44 submittedData submittedData 45 assert *assert.Assertions 46 t *testing.T 47 } 48 49 func newSampleDataHelper(t *testing.T) *sampleDataHelper { 50 return &sampleDataHelper{make(submittedData), assert.New(t), t} 51 } 52 53 func (d *sampleDataHelper) populateLedger(h *testhelper) { 54 lgrid := h.lgrid 55 // blk1 deploys 2 chaincodes 56 txdeploy1 := h.simulateDeployTx("cc1", nil) 57 txdeploy2 := h.simulateDeployTx("cc2", nil) 58 blk1 := h.cutBlockAndCommitLegacy() 59 60 // blk2 contains 2 public data txs 61 txdata1 := h.simulateDataTx("txid1", func(s *simulator) { 62 s.setState("cc1", "key1", d.sampleVal("value01", lgrid)) 63 s.setState("cc1", "key2", d.sampleVal("value02", lgrid)) 64 }) 65 66 txdata2 := h.simulateDataTx("txid2", func(s *simulator) { 67 s.setState("cc2", "key1", d.sampleVal("value03", lgrid)) 68 s.setState("cc2", "key2", d.sampleVal("value04", lgrid)) 69 }) 70 blk2 := h.cutBlockAndCommitLegacy() 71 72 // blk3 upgrades both chaincodes 73 txupgrade1 := h.simulateUpgradeTx("cc1", d.sampleCollConf1(lgrid, "cc1")) 74 txupgrade2 := h.simulateUpgradeTx("cc2", d.sampleCollConf1(lgrid, "cc2")) 75 blk3 := h.cutBlockAndCommitLegacy() 76 77 // blk4 contains 2 data txs with private data 78 txdata3 := h.simulateDataTx("txid3", func(s *simulator) { 79 s.setPvtdata("cc1", "coll1", "key3", d.sampleVal("value05", lgrid)) 80 s.setPvtdata("cc1", "coll1", "key4", d.sampleVal("value06", lgrid)) 81 }) 82 txdata4 := h.simulateDataTx("txid4", func(s *simulator) { 83 s.setPvtdata("cc2", "coll1", "key3", d.sampleVal("value07", lgrid)) 84 s.setPvtdata("cc2", "coll1", "key4", d.sampleVal("value08", lgrid)) 85 }) 86 blk4 := h.cutBlockAndCommitLegacy() 87 88 // blk5 upgrades both chaincodes 89 txupgrade3 := h.simulateUpgradeTx("cc1", d.sampleCollConf2(lgrid, "cc1")) 90 txupgrade4 := h.simulateDeployTx("cc2", d.sampleCollConf2(lgrid, "cc2")) 91 blk5 := h.cutBlockAndCommitLegacy() 92 93 // blk6 contains 2 data txs with private data 94 txdata5 := h.simulateDataTx("txid5", func(s *simulator) { 95 s.setPvtdata("cc1", "coll2", "key3", d.sampleVal("value09", lgrid)) 96 s.setPvtdata("cc1", "coll2", "key4", d.sampleVal("value10", lgrid)) 97 }) 98 txdata6 := h.simulateDataTx("txid6", func(s *simulator) { 99 s.setPvtdata("cc2", "coll2", "key3", d.sampleVal("value11", lgrid)) 100 s.setPvtdata("cc2", "coll2", "key4", d.sampleVal("value12", lgrid)) 101 }) 102 blk6 := h.cutBlockAndCommitLegacy() 103 104 // blk7 contains one data txs 105 txdata7 := h.simulateDataTx("txid7", func(s *simulator) { 106 s.setState("cc1", "key1", d.sampleVal("value13", lgrid)) 107 s.DeleteState("cc1", "key2") 108 s.setPvtdata("cc1", "coll1", "key3", d.sampleVal("value14", lgrid)) 109 s.DeletePrivateData("cc1", "coll1", "key4") 110 }) 111 h.simulatedTrans = nil 112 113 // blk8 contains one data txs that should be marked as invalid because of mvcc conflict with tx in blk7 114 txdata8 := h.simulateDataTx("txid8", func(s *simulator) { 115 s.getState("cc1", "key1") 116 s.setState("cc1", "key1", d.sampleVal("value15", lgrid)) 117 }) 118 blk7 := h.committer.cutBlockAndCommitLegacy([]*txAndPvtdata{txdata7}, nil) 119 blk8 := h.cutBlockAndCommitLegacy() 120 121 d.submittedData.recordSubmittedBlks(lgrid, 122 blk1, blk2, blk3, blk4, blk5, blk6, blk7, blk8) 123 d.submittedData.recordSubmittedTxs(lgrid, 124 txdeploy1, txdeploy2, txdata1, txdata2, txupgrade1, txupgrade2, 125 txdata3, txdata4, txupgrade3, txupgrade4, txdata5, txdata6, txdata7, txdata8) 126 } 127 128 func (d *sampleDataHelper) verifyLedgerContent(h *testhelper) { 129 d.verifyState(h) 130 d.verifyConfigHistory(h) 131 d.verifyBlockAndPvtdata(h) 132 d.verifyGetTransactionByID(h) 133 // TODO: add verifyHistory() -- FAB-15733 134 135 // the submitted data could not be available if the test ledger is loaded from disk in a fresh run 136 // (e.g., a backup of a test lesger from a previous fabric version) 137 if len(d.submittedData) != 0 { 138 d.t.Log("Verifying using submitted data") 139 d.verifyBlockAndPvtdataUsingSubmittedData(h) 140 d.verifyGetTransactionByIDUsingSubmittedData(h) 141 } else { 142 d.t.Log("Skipping verifying using submitted data") 143 } 144 } 145 146 func (d *sampleDataHelper) verifyState(h *testhelper) { 147 lgrid := h.lgrid 148 h.verifyPubState("cc1", "key1", d.sampleVal("value13", lgrid)) 149 h.verifyPubState("cc1", "key2", "") 150 h.verifyPvtState("cc1", "coll1", "key3", d.sampleVal("value14", lgrid)) 151 h.verifyPvtState("cc1", "coll1", "key4", "") 152 h.verifyPvtState("cc1", "coll2", "key3", d.sampleVal("value09", lgrid)) 153 h.verifyPvtState("cc1", "coll2", "key4", d.sampleVal("value10", lgrid)) 154 155 h.verifyPubState("cc2", "key1", d.sampleVal("value03", lgrid)) 156 h.verifyPubState("cc2", "key2", d.sampleVal("value04", lgrid)) 157 h.verifyPvtState("cc2", "coll1", "key3", d.sampleVal("value07", lgrid)) 158 h.verifyPvtState("cc2", "coll1", "key4", d.sampleVal("value08", lgrid)) 159 h.verifyPvtState("cc2", "coll2", "key3", d.sampleVal("value11", lgrid)) 160 h.verifyPvtState("cc2", "coll2", "key4", d.sampleVal("value12", lgrid)) 161 } 162 163 func (d *sampleDataHelper) verifyConfigHistory(h *testhelper) { 164 lgrid := h.lgrid 165 h.verifyMostRecentCollectionConfigBelow(10, "cc1", 166 &expectedCollConfInfo{5, d.sampleCollConf2(lgrid, "cc1")}) 167 168 h.verifyMostRecentCollectionConfigBelow(5, "cc1", 169 &expectedCollConfInfo{3, d.sampleCollConf1(lgrid, "cc1")}) 170 171 h.verifyMostRecentCollectionConfigBelow(10, "cc2", 172 &expectedCollConfInfo{5, d.sampleCollConf2(lgrid, "cc2")}) 173 174 h.verifyMostRecentCollectionConfigBelow(5, "cc2", 175 &expectedCollConfInfo{3, d.sampleCollConf1(lgrid, "cc2")}) 176 } 177 178 func (d *sampleDataHelper) verifyBlockAndPvtdata(h *testhelper) { 179 lgrid := h.lgrid 180 h.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) { 181 r.hasNumTx(2) 182 r.hasNoPvtdata() 183 }) 184 185 h.verifyBlockAndPvtData(4, nil, func(r *retrievedBlockAndPvtdata) { 186 r.hasNumTx(2) 187 r.pvtdataShouldContain(0, "cc1", "coll1", "key3", d.sampleVal("value05", lgrid)) 188 r.pvtdataShouldContain(1, "cc2", "coll1", "key3", d.sampleVal("value07", lgrid)) 189 }) 190 } 191 192 func (d *sampleDataHelper) verifyGetTransactionByID(h *testhelper) { 193 h.verifyTxValidationCode("txid7", protopeer.TxValidationCode_VALID) 194 h.verifyTxValidationCode("txid8", protopeer.TxValidationCode_MVCC_READ_CONFLICT) 195 } 196 197 func (d *sampleDataHelper) verifyBlockAndPvtdataUsingSubmittedData(h *testhelper) { 198 lgrid := h.lgrid 199 submittedData := d.submittedData[lgrid] 200 for _, submittedBlk := range submittedData.Blocks { 201 blkNum := submittedBlk.Block.Header.Number 202 if blkNum != 8 { 203 h.verifyBlockAndPvtDataSameAs(uint64(blkNum), submittedBlk) 204 } else { 205 h.verifyBlockAndPvtData(uint64(8), nil, func(r *retrievedBlockAndPvtdata) { 206 r.sameBlockHeaderAndData(submittedBlk.Block) 207 r.containsValidationCode(0, protopeer.TxValidationCode_MVCC_READ_CONFLICT) 208 }) 209 } 210 } 211 } 212 213 func (d *sampleDataHelper) verifyGetTransactionByIDUsingSubmittedData(h *testhelper) { 214 lgrid := h.lgrid 215 for _, submittedTx := range d.submittedData[lgrid].Txs { 216 expectedValidationCode := protopeer.TxValidationCode_VALID 217 if submittedTx.Txid == "txid8" { 218 expectedValidationCode = protopeer.TxValidationCode_MVCC_READ_CONFLICT 219 } 220 h.verifyGetTransactionByID(submittedTx.Txid, 221 &protopeer.ProcessedTransaction{TransactionEnvelope: submittedTx.Envelope, ValidationCode: int32(expectedValidationCode)}) 222 } 223 } 224 225 func (d *sampleDataHelper) sampleVal(val, ledgerid string) string { 226 return fmt.Sprintf("%s:%s", val, ledgerid) 227 } 228 229 func (d *sampleDataHelper) sampleCollConf1(ledgerid, ccName string) []*collConf { 230 return []*collConf{ 231 {name: "coll1", members: []string{"org1", "org2"}}, 232 {name: ledgerid, members: []string{"org1", "org2"}}, 233 {name: ccName, members: []string{"org1", "org2"}}, 234 } 235 } 236 237 func (d *sampleDataHelper) sampleCollConf2(ledgerid string, ccName string) []*collConf { 238 return []*collConf{ 239 {name: "coll1", members: []string{"org1", "org2"}}, 240 {name: "coll2", members: []string{"org1", "org2"}}, 241 {name: ledgerid, members: []string{"org1", "org2"}}, 242 {name: ccName, members: []string{"org1", "org2"}}, 243 } 244 }