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  }