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