github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/tests/v1x_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  	"os"
    12  	"path"
    13  	"path/filepath"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/hechain20/hechain/common/ledger/testutil"
    18  	"github.com/hechain20/hechain/core/ledger"
    19  	"github.com/hechain20/hechain/core/ledger/kvledger"
    20  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statedb/statecouchdb"
    21  	"github.com/hechain20/hechain/core/ledger/mock"
    22  	"github.com/hechain20/hechain/protoutil"
    23  	"github.com/hyperledger/fabric-protos-go/common"
    24  	protopeer "github.com/hyperledger/fabric-protos-go/peer"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  // Test data used in the tests in this file was generated by v1.1 code https://gerrit.hyperledger.org/r/#/c/22749/6/core/ledger/kvledger/tests/v11_generate_test.go@22
    29  // Folder, "testdata/v11/sample_ledgers" contains the data that was generated before commit hash feature was added.
    30  // Folder, "testdata/v11/sample_ledgers_with_commit_hashes" contains the data that was generated after commit hash feature was added.
    31  
    32  // TestV11 tests that a ledgersData folder created by v1.1 can be used with future releases after upgrading dbs.
    33  // The test data was generated by v1.1 code https://github.com/hechain20/hechain/blob/release-1.1/core/ledger/kvledger/tests/v11_generate_test.go#L22
    34  func TestV11(t *testing.T) {
    35  	env := newEnv(t)
    36  	defer env.cleanup()
    37  
    38  	ledgerFSRoot := env.initializer.Config.RootFSPath
    39  	// pass false so that 'ledgersData' directory will not be created when unzipped to ledgerFSRoot
    40  	require.NoError(t, testutil.Unzip("testdata/v11/sample_ledgers/ledgersData.zip", ledgerFSRoot, false))
    41  
    42  	require.NoError(t, kvledger.UpgradeDBs(env.initializer.Config))
    43  	// do not include bookkeeper and confighistory dbs since the v11 ledger doesn't have these dbs
    44  	rebuildable := rebuildableStatedb | rebuildableHistoryDB | rebuildableBlockIndex
    45  	env.verifyRebuilableDirEmpty(rebuildable)
    46  
    47  	env.initLedgerMgmt()
    48  
    49  	l1, l2 := env.openTestLedger("ledger1"), env.openTestLedger("ledger2")
    50  	dataHelper := &v1xSampleDataHelper{sampleDataVersion: "v1.1", t: t}
    51  
    52  	dataHelper.verify(l1)
    53  	dataHelper.verify(l2)
    54  
    55  	// rebuild and verify again
    56  	env.ledgerMgr.Close()
    57  	require.NoError(t, kvledger.RebuildDBs(env.initializer.Config))
    58  	env.verifyRebuilableDirEmpty(rebuildable)
    59  	env.initLedgerMgmt()
    60  
    61  	l1, l2 = env.openTestLedger("ledger1"), env.openTestLedger("ledger2")
    62  	dataHelper.verify(l1)
    63  	dataHelper.verify(l2)
    64  
    65  	l1.verifyCommitHashNotExists()
    66  	l2.verifyCommitHashNotExists()
    67  	l1.simulateDataTx("txid1_with_new_binary", func(s *simulator) {
    68  		s.setState("cc1", "new_key", "new_value")
    69  	})
    70  
    71  	// add a new block and the new block should not contain a commit hash
    72  	// because the previously committed block from 1.1 code did not contain commit hash
    73  	l1.cutBlockAndCommitLegacy()
    74  	l1.verifyCommitHashNotExists()
    75  }
    76  
    77  func TestV11CommitHashes(t *testing.T) {
    78  	testCases := []struct {
    79  		description               string
    80  		v11SampleDataPath         string
    81  		preResetCommitHashExists  bool
    82  		resetFunc                 func(h *testLedger, ledgerFSRoot string)
    83  		postResetCommitHashExists bool
    84  	}{
    85  		{
    86  			"Reset (no existing CommitHash)",
    87  			"testdata/v11/sample_ledgers/ledgersData.zip",
    88  			false,
    89  			func(h *testLedger, ledgerFSRoot string) {
    90  				require.NoError(t, kvledger.ResetAllKVLedgers(ledgerFSRoot))
    91  			},
    92  			true,
    93  		},
    94  
    95  		{
    96  			"Rollback to genesis block (no existing CommitHash)",
    97  			"testdata/v11/sample_ledgers/ledgersData.zip",
    98  			false,
    99  			func(h *testLedger, ledgerFSRoot string) {
   100  				require.NoError(t, kvledger.RollbackKVLedger(ledgerFSRoot, h.lgrid, 0))
   101  			},
   102  			true,
   103  		},
   104  
   105  		{
   106  			"Rollback to block other than genesis block (no existing CommitHash)",
   107  			"testdata/v11/sample_ledgers/ledgersData.zip",
   108  			false,
   109  			func(h *testLedger, ledgerFSRoot string) {
   110  				require.NoError(t, kvledger.RollbackKVLedger(ledgerFSRoot, h.lgrid, h.currentHeight()/2+1))
   111  			},
   112  			false,
   113  		},
   114  
   115  		{
   116  			"Reset (existing CommitHash)",
   117  			"testdata/v11/sample_ledgers_with_commit_hashes/ledgersData.zip",
   118  			true,
   119  			func(h *testLedger, ledgerFSRoot string) {
   120  				require.NoError(t, kvledger.ResetAllKVLedgers(ledgerFSRoot))
   121  			},
   122  			true,
   123  		},
   124  
   125  		{
   126  			"Rollback to genesis block (existing CommitHash)",
   127  			"testdata/v11/sample_ledgers_with_commit_hashes/ledgersData.zip",
   128  			true,
   129  			func(h *testLedger, ledgerFSRoot string) {
   130  				require.NoError(t, kvledger.RollbackKVLedger(ledgerFSRoot, h.lgrid, 0))
   131  			},
   132  			true,
   133  		},
   134  
   135  		{
   136  			"Rollback to block other than genesis block (existing CommitHash)",
   137  			"testdata/v11/sample_ledgers_with_commit_hashes/ledgersData.zip",
   138  			true,
   139  			func(h *testLedger, ledgerFSRoot string) {
   140  				require.NoError(t, kvledger.RollbackKVLedger(ledgerFSRoot, h.lgrid, h.currentHeight()/2+1))
   141  			},
   142  			true,
   143  		},
   144  	}
   145  
   146  	for _, testCase := range testCases {
   147  		t.Run(
   148  			testCase.description,
   149  			func(t *testing.T) {
   150  				testV11CommitHashes(
   151  					t,
   152  					testCase.v11SampleDataPath,
   153  					testCase.preResetCommitHashExists,
   154  					testCase.resetFunc,
   155  					testCase.postResetCommitHashExists,
   156  				)
   157  			})
   158  	}
   159  }
   160  
   161  func testV11CommitHashes(t *testing.T,
   162  	v11DataPath string,
   163  	preResetCommitHashExists bool,
   164  	resetFunc func(*testLedger, string),
   165  	postResetCommitHashExists bool,
   166  ) {
   167  	env := newEnv(t)
   168  	defer env.cleanup()
   169  
   170  	ledgerFSRoot := env.initializer.Config.RootFSPath
   171  	// pass false so that 'ledgersData' directory will not be created when unzipped to ledgerFSRoot
   172  	require.NoError(t, testutil.Unzip(v11DataPath, ledgerFSRoot, false))
   173  
   174  	require.NoError(t, kvledger.UpgradeDBs(env.initializer.Config))
   175  	// do not include bookkeeper and confighistory dbs since the v11 ledger doesn't have these dbs
   176  	rebuildable := rebuildableStatedb | rebuildableHistoryDB | rebuildableBlockIndex
   177  	env.verifyRebuilableDirEmpty(rebuildable)
   178  
   179  	env.initLedgerMgmt()
   180  	h := env.openTestLedger("ledger1")
   181  	blocksAndPvtData := h.retrieveCommittedBlocksAndPvtdata(0, h.currentHeight()-1)
   182  
   183  	var commitHashPreReset []byte
   184  	if preResetCommitHashExists {
   185  		commitHashPreReset = h.currentCommitHash()
   186  		h.verifyCommitHashExists()
   187  	} else {
   188  		h.verifyCommitHashNotExists()
   189  	}
   190  
   191  	env.closeLedgerMgmt()
   192  	resetFunc(h, ledgerFSRoot)
   193  	env.initLedgerMgmt()
   194  
   195  	h = env.openTestLedger("ledger1")
   196  	for i := int(h.currentHeight()); i < len(blocksAndPvtData); i++ {
   197  		d := blocksAndPvtData[i]
   198  		// add metadata slot for commit hash, as this would have be missing in the blocks from 1.1 prior to this feature
   199  		for len(d.Block.Metadata.Metadata) < int(common.BlockMetadataIndex_COMMIT_HASH)+1 {
   200  			d.Block.Metadata.Metadata = append(d.Block.Metadata.Metadata, []byte{})
   201  		}
   202  		// set previous block hash, as this is not present in the test blocks from 1.1
   203  		d.Block.Header.PreviousHash = protoutil.BlockHeaderHash(blocksAndPvtData[i-1].Block.Header)
   204  		require.NoError(t, h.lgr.CommitLegacy(d, &ledger.CommitOptions{FetchPvtDataFromLedger: true}))
   205  	}
   206  
   207  	if preResetCommitHashExists {
   208  		commitHashPostReset := h.currentCommitHash()
   209  		require.Equal(t, commitHashPreReset, commitHashPostReset)
   210  	}
   211  	if postResetCommitHashExists {
   212  		h.verifyCommitHashExists()
   213  	} else {
   214  		h.verifyCommitHashNotExists()
   215  	}
   216  
   217  	bcInfo, err := h.lgr.GetBlockchainInfo()
   218  	require.NoError(t, err)
   219  	h.committer.blkgen.lastNum = bcInfo.Height - 1
   220  	h.committer.blkgen.lastHash = bcInfo.CurrentBlockHash
   221  
   222  	h.simulateDataTx("txid1_with_new_binary", func(s *simulator) {
   223  		s.setState("cc1", "new_key", "new_value")
   224  	})
   225  	h.cutBlockAndCommitLegacy()
   226  
   227  	if postResetCommitHashExists {
   228  		h.verifyCommitHashExists()
   229  	} else {
   230  		h.verifyCommitHashNotExists()
   231  	}
   232  }
   233  
   234  // TestV13WithStateCouchdb tests that a ledgersData folder and couchdb data created by v1.3 can be read by latest fabric version after upgrading dbs.
   235  // The test data was generated by v1.3 code https://gerrit.hyperledger.org/r/#/c/fabric/+/34078/3/core/ledger/kvledger/tests/v13_generate_test.go@60
   236  func TestV13WithStateCouchdb(t *testing.T) {
   237  	env := newEnv(t)
   238  	defer env.cleanup()
   239  
   240  	ledgerFSRoot := env.initializer.Config.RootFSPath
   241  	// pass false so that 'ledgersData' directory will not be created when unzipped to ledgerFSRoot
   242  	require.NoError(t, testutil.Unzip("testdata/v13_statecouchdb/sample_ledgers/ledgersData.zip", ledgerFSRoot, false))
   243  
   244  	couchdbConfig, cleanup := startCouchDBWithV13Data(t, ledgerFSRoot)
   245  	defer cleanup()
   246  	env.initializer.Config.StateDBConfig.StateDatabase = ledger.CouchDB
   247  	env.initializer.Config.StateDBConfig.CouchDB = couchdbConfig
   248  	env.initializer.HealthCheckRegistry = &mock.HealthCheckRegistry{}
   249  	env.initializer.ChaincodeLifecycleEventProvider = &mock.ChaincodeLifecycleEventProvider{}
   250  
   251  	require.NoError(t, kvledger.UpgradeDBs(env.initializer.Config))
   252  	require.True(t, statecouchdb.IsEmpty(t, couchdbConfig))
   253  	rebuildable := rebuildableBookkeeper | rebuildableConfigHistory | rebuildableHistoryDB | rebuildableBlockIndex
   254  	env.verifyRebuilableDirEmpty(rebuildable)
   255  
   256  	env.initLedgerMgmt()
   257  
   258  	h1, h2 := env.openTestLedger("ledger1"), env.openTestLedger("ledger2")
   259  	dataHelper := &v1xSampleDataHelper{sampleDataVersion: "v1.3", t: t}
   260  	dataHelper.verify(h1)
   261  	dataHelper.verify(h2)
   262  
   263  	// rebuild and verify again
   264  	env.ledgerMgr.Close()
   265  	require.NoError(t, kvledger.RebuildDBs(env.initializer.Config))
   266  	require.True(t, statecouchdb.IsEmpty(t, couchdbConfig))
   267  	env.verifyRebuilableDirEmpty(rebuildable)
   268  	env.initLedgerMgmt()
   269  
   270  	h1, h2 = env.openTestLedger("ledger1"), env.openTestLedger("ledger2")
   271  	dataHelper.verify(h1)
   272  	dataHelper.verify(h2)
   273  }
   274  
   275  // TestInitLedgerPanicWithV11Data tests init ledger panic cases caused by ledger dbs in old formats.
   276  // It tests stateleveldb.
   277  func TestInitLedgerPanicWithV11Data(t *testing.T) {
   278  	env := newEnv(t)
   279  	defer env.cleanup()
   280  
   281  	ledgerFSRoot := env.initializer.Config.RootFSPath
   282  	require.NoError(t, testutil.Unzip("testdata/v11/sample_ledgers/ledgersData.zip", ledgerFSRoot, false))
   283  	testInitLedgerPanic(t, env, ledgerFSRoot, nil)
   284  }
   285  
   286  // TestInitLedgerPanicWithV13Data tests init ledger panic cases caused by ledger dbs in old formats.
   287  // It tests statecouchdb.
   288  func TestInitLedgerPanicWithV13Data(t *testing.T) {
   289  	env := newEnv(t)
   290  	defer env.cleanup()
   291  
   292  	ledgerFSRoot := env.initializer.Config.RootFSPath
   293  	// pass false so that 'ledgersData' directory will not be created when unzipped to ledgerFSRoot
   294  	require.NoError(t, testutil.Unzip("testdata/v13_statecouchdb/sample_ledgers/ledgersData.zip", ledgerFSRoot, false))
   295  
   296  	couchdbConfig, cleanup := startCouchDBWithV13Data(t, ledgerFSRoot)
   297  	defer cleanup()
   298  	env.initializer.Config.StateDBConfig.StateDatabase = ledger.CouchDB
   299  	env.initializer.Config.StateDBConfig.CouchDB = couchdbConfig
   300  	env.initializer.HealthCheckRegistry = &mock.HealthCheckRegistry{}
   301  	env.initializer.ChaincodeLifecycleEventProvider = &mock.ChaincodeLifecycleEventProvider{}
   302  	testInitLedgerPanic(t, env, ledgerFSRoot, couchdbConfig)
   303  }
   304  
   305  // Verify init ledger panic due to old DB formats. Drop each DB after panic so that we can test panic for next DB.
   306  func testInitLedgerPanic(t *testing.T, env *env, ledgerFSRoot string, couchdbConfig *ledger.CouchDBConfig) {
   307  	t.Logf("verifying that a panic occurs because idStore has old format and then reformat the idstore to proceed")
   308  	idStorePath := kvledger.LedgerProviderPath(ledgerFSRoot)
   309  	require.PanicsWithValue(
   310  		t,
   311  		fmt.Sprintf("Error in instantiating ledger provider: unexpected format. db info = [leveldb for channel-IDs at [%s]], data format = [], expected format = [2.0]",
   312  			idStorePath),
   313  		func() { env.initLedgerMgmt() },
   314  		"A panic should occur because idstore is in format 1.x",
   315  	)
   316  	kvledger.UpgradeIDStoreFormat(t, ledgerFSRoot)
   317  
   318  	t.Logf("verifying that a panic occurs because blockstore index has old format and then drop the idstore to proceed")
   319  	blkIndexPath := path.Join(kvledger.BlockStorePath(ledgerFSRoot), "index")
   320  	require.PanicsWithValue(
   321  		t,
   322  		fmt.Sprintf("Error in instantiating ledger provider: unexpected format. db info = [leveldb at [%s]], data format = [], expected format = [2.0]",
   323  			blkIndexPath),
   324  		func() { env.initLedgerMgmt() },
   325  		"A panic should occur because block store index is in format 1.x",
   326  	)
   327  	require.NoError(t, os.RemoveAll(blkIndexPath))
   328  
   329  	t.Logf("verifying that a panic occurs because historydb has old format and then drop the historydb to proceed")
   330  	historyDBPath := kvledger.HistoryDBPath(ledgerFSRoot)
   331  	require.PanicsWithValue(
   332  		t,
   333  		fmt.Sprintf("Error in instantiating ledger provider: unexpected format. db info = [leveldb at [%s]], data format = [], expected format = [2.0]",
   334  			historyDBPath),
   335  		func() { env.initLedgerMgmt() },
   336  		"A panic should occur because history is in format 1.x",
   337  	)
   338  	require.NoError(t, os.RemoveAll(historyDBPath))
   339  
   340  	if couchdbConfig == nil {
   341  		t.Logf("verifying that a panic occurs because stateleveldb has old format and then drop the statedb to proceed")
   342  		stateLevelDBPath := kvledger.StateDBPath(ledgerFSRoot)
   343  		require.PanicsWithValue(
   344  			t,
   345  			fmt.Sprintf(
   346  				"Error in instantiating ledger provider: unexpected format. db info = [leveldb at [%s]], data format = [], expected format = [2.0]",
   347  				stateLevelDBPath,
   348  			),
   349  			func() { env.initLedgerMgmt() },
   350  			"A panic should occur because statedb is in format 1.x",
   351  		)
   352  		require.NoError(t, os.RemoveAll(stateLevelDBPath))
   353  	} else {
   354  		t.Logf("verifying that a panic occurs because statecouchdb has old format and then drop the statedb to proceed")
   355  		require.PanicsWithValue(
   356  			t,
   357  			"Error in instantiating ledger provider: unexpected format. db info = [CouchDB for state database], data format = [], expected format = [2.0]",
   358  			func() { env.initLedgerMgmt() },
   359  			"A panic should occur because statedb is in format 1.x",
   360  		)
   361  		require.NoError(t, statecouchdb.DropApplicationDBs(couchdbConfig))
   362  	}
   363  }
   364  
   365  func startCouchDBWithV13Data(t *testing.T, ledgerFSRoot string) (*ledger.CouchDBConfig, func()) {
   366  	// unzip couchdb data to prepare the mount dir
   367  	couchdbDataUnzipDir := filepath.Join(ledgerFSRoot, "couchdbData")
   368  	require.NoError(t, os.Mkdir(couchdbDataUnzipDir, os.ModePerm))
   369  	require.NoError(t, testutil.Unzip("testdata/v13_statecouchdb/sample_ledgers/couchdbData.zip", couchdbDataUnzipDir, false))
   370  
   371  	// prepare the local.d mount dir to overwrite the number of shards and nodes so that they match the couchdb data generated from v1.3
   372  	localdHostDir := filepath.Join(ledgerFSRoot, "local.d")
   373  	require.NoError(t, os.MkdirAll(localdHostDir, os.ModePerm))
   374  	require.NoError(t, testutil.CopyDir("testdata/v13_statecouchdb/couchdb_etc/local.d", localdHostDir, true))
   375  
   376  	// start couchdb using couchdbDataUnzipDir and localdHostDir as mount dirs
   377  	couchdbBinds := []string{
   378  		fmt.Sprintf("%s:%s", couchdbDataUnzipDir, "/opt/couchdb/data"),
   379  		fmt.Sprintf("%s:%s", localdHostDir, "/opt/couchdb/etc/local.d"),
   380  	}
   381  	couchAddress, cleanup := statecouchdb.StartCouchDB(t, couchdbBinds)
   382  
   383  	// set required config data to use state couchdb
   384  	couchdbConfig := &ledger.CouchDBConfig{
   385  		Address:             couchAddress,
   386  		Username:            "admin",
   387  		Password:            "adminpw",
   388  		MaxRetries:          3,
   389  		MaxRetriesOnStartup: 3,
   390  		RequestTimeout:      10 * time.Second,
   391  		RedoLogPath:         filepath.Join(ledgerFSRoot, "couchdbRedoLogs"),
   392  	}
   393  
   394  	return couchdbConfig, cleanup
   395  }
   396  
   397  // v1xSampleDataHelper provides a set of functions to verify the ledger (after upgraded to latest data format).
   398  // It verifies the ledger under the assumption that the ledger was generated by the specific generation code from v1.1 or v1.3.
   399  // For v1.1, the sample ledger data was generated by https://github.com/hechain20/hechain/blob/release-1.1/core/ledger/kvledger/tests/v11_generate_test.go#L22
   400  // This generate function constructed two ledgers and populateed the ledgers using this code
   401  // (https://github.com/hechain20/hechain/blob/release-1.1/core/ledger/kvledger/tests/sample_data_helper.go#L55)
   402  // For v1.3, the sample ledger data was generated by CR (https://gerrit.hyperledger.org/r/#/c/fabric/+/34078/3/core/ledger/kvledger/tests/v13_generate_test.go@60).
   403  // This generate function constructed two ledgers and populated the ledgers using this code
   404  // (https://github.com/hechain20/hechain/blob/release-1.3/core/ledger/kvledger/tests/sample_data_helper.go#L55)
   405  type v1xSampleDataHelper struct {
   406  	sampleDataVersion string
   407  	t                 *testing.T
   408  }
   409  
   410  func (d *v1xSampleDataHelper) verify(h *testLedger) {
   411  	d.verifyState(h)
   412  	d.verifyBlockAndPvtdata(h)
   413  	d.verifyGetTransactionByID(h)
   414  	d.verifyConfigHistory(h)
   415  	d.verifyHistory(h)
   416  }
   417  
   418  func (d *v1xSampleDataHelper) verifyState(h *testLedger) {
   419  	lgrid := h.lgrid
   420  	h.verifyPubState("cc1", "key1", d.sampleVal("value13", lgrid))
   421  	h.verifyPubState("cc1", "key2", "")
   422  	h.verifyPvtState("cc1", "coll1", "key3", d.sampleVal("value14", lgrid))
   423  	h.verifyPvtState("cc1", "coll1", "key4", "")
   424  	h.verifyPvtState("cc1", "coll2", "key3", d.sampleVal("value09", lgrid))
   425  	h.verifyPvtState("cc1", "coll2", "key4", d.sampleVal("value10", lgrid))
   426  
   427  	h.verifyPubState("cc2", "key1", d.sampleVal("value03", lgrid))
   428  	h.verifyPubState("cc2", "key2", d.sampleVal("value04", lgrid))
   429  	h.verifyPvtState("cc2", "coll1", "key3", d.sampleVal("value07", lgrid))
   430  	h.verifyPvtState("cc2", "coll1", "key4", d.sampleVal("value08", lgrid))
   431  	h.verifyPvtState("cc2", "coll2", "key3", d.sampleVal("value11", lgrid))
   432  	h.verifyPvtState("cc2", "coll2", "key4", d.sampleVal("value12", lgrid))
   433  }
   434  
   435  func (d *v1xSampleDataHelper) verifyHistory(h *testLedger) {
   436  	lgrid := h.lgrid
   437  	expectedHistoryCC1Key1 := []string{
   438  		d.sampleVal("value13", lgrid),
   439  		d.sampleVal("value01", lgrid),
   440  	}
   441  	h.verifyHistory("cc1", "key1", expectedHistoryCC1Key1)
   442  }
   443  
   444  func (d *v1xSampleDataHelper) verifyConfigHistory(h *testLedger) {
   445  	lgrid := h.lgrid
   446  	h.verifyMostRecentCollectionConfigBelow(10, "cc1",
   447  		&expectedCollConfInfo{5, d.sampleCollConf2(lgrid, "cc1")})
   448  
   449  	h.verifyMostRecentCollectionConfigBelow(5, "cc1",
   450  		&expectedCollConfInfo{3, d.sampleCollConf1(lgrid, "cc1")})
   451  
   452  	h.verifyMostRecentCollectionConfigBelow(10, "cc2",
   453  		&expectedCollConfInfo{5, d.sampleCollConf2(lgrid, "cc2")})
   454  
   455  	h.verifyMostRecentCollectionConfigBelow(5, "cc2",
   456  		&expectedCollConfInfo{3, d.sampleCollConf1(lgrid, "cc2")})
   457  }
   458  
   459  func (d *v1xSampleDataHelper) verifyBlockAndPvtdata(h *testLedger) {
   460  	lgrid := h.lgrid
   461  	h.verifyBlockAndPvtData(2, nil, func(r *retrievedBlockAndPvtdata) {
   462  		r.hasNumTx(2)
   463  		r.hasNoPvtdata()
   464  	})
   465  
   466  	h.verifyBlockAndPvtData(4, nil, func(r *retrievedBlockAndPvtdata) {
   467  		r.hasNumTx(2)
   468  		r.pvtdataShouldContain(0, "cc1", "coll1", "key3", d.sampleVal("value05", lgrid))
   469  		r.pvtdataShouldContain(1, "cc2", "coll1", "key3", d.sampleVal("value07", lgrid))
   470  	})
   471  }
   472  
   473  func (d *v1xSampleDataHelper) verifyGetTransactionByID(h *testLedger) {
   474  	h.verifyTxValidationCode("txid7", protopeer.TxValidationCode_VALID)
   475  	h.verifyTxValidationCode("txid8", protopeer.TxValidationCode_MVCC_READ_CONFLICT)
   476  }
   477  
   478  func (d *v1xSampleDataHelper) sampleVal(val, ledgerid string) string {
   479  	return fmt.Sprintf("%s:%s", val, ledgerid)
   480  }
   481  
   482  func (d *v1xSampleDataHelper) sampleCollConf1(ledgerid, ccName string) []*collConf {
   483  	switch d.sampleDataVersion {
   484  	case "v1.1":
   485  		return []*collConf{
   486  			{name: "coll1", members: []string{"org1", "org2"}},
   487  			{name: ledgerid, members: []string{"org1", "org2"}},
   488  			{name: ccName, members: []string{"org1", "org2"}},
   489  		}
   490  	case "v1.3":
   491  		return []*collConf{
   492  			{name: "coll1"},
   493  			{name: ledgerid},
   494  			{name: ccName},
   495  		}
   496  	default:
   497  		// should not happen
   498  		require.Failf(d.t, "sample data version %s is wrong", d.sampleDataVersion)
   499  		return nil
   500  	}
   501  }
   502  
   503  func (d *v1xSampleDataHelper) sampleCollConf2(ledgerid string, ccName string) []*collConf {
   504  	switch d.sampleDataVersion {
   505  	case "v1.1":
   506  		return []*collConf{
   507  			{name: "coll1", members: []string{"org1", "org2"}},
   508  			{name: "coll2", members: []string{"org1", "org2"}},
   509  			{name: ledgerid, members: []string{"org1", "org2"}},
   510  			{name: ccName, members: []string{"org1", "org2"}},
   511  		}
   512  	case "v1.3":
   513  		return []*collConf{
   514  			{name: "coll1"},
   515  			{name: "coll2"},
   516  			{name: ledgerid},
   517  			{name: ccName},
   518  		}
   519  	default:
   520  		// should not happen
   521  		require.Failf(d.t, "sample data version %s is wrong", d.sampleDataVersion)
   522  		return nil
   523  	}
   524  }