github.com/true-sqn/fabric@v2.1.1+incompatible/gossip/privdata/dataretriever_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package privdata
     8  
     9  import (
    10  	"errors"
    11  	"testing"
    12  
    13  	gossip2 "github.com/hyperledger/fabric-protos-go/gossip"
    14  	"github.com/hyperledger/fabric-protos-go/ledger/rwset"
    15  	"github.com/hyperledger/fabric-protos-go/peer"
    16  	"github.com/hyperledger/fabric-protos-go/transientstore"
    17  	"github.com/hyperledger/fabric/core/ledger"
    18  	privdatacommon "github.com/hyperledger/fabric/gossip/privdata/common"
    19  	"github.com/hyperledger/fabric/gossip/privdata/mocks"
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/mock"
    22  )
    23  
    24  /*
    25  	Test checks following scenario, it tries to obtain private data for
    26  	given block sequence which is greater than available ledger height,
    27  	hence data should be looked up directly from transient store
    28  */
    29  func TestNewDataRetriever_GetDataFromTransientStore(t *testing.T) {
    30  	t.Parallel()
    31  	committer := &mocks.Committer{}
    32  
    33  	store := newTransientStore(t)
    34  	defer store.tearDown()
    35  
    36  	namespace := "testChaincodeName1"
    37  	collectionName := "testCollectionName"
    38  	txID := "testTxID"
    39  
    40  	committer.On("LedgerHeight").Return(uint64(1), nil)
    41  
    42  	retriever := NewDataRetriever(store.store, committer)
    43  
    44  	store.Persist(txID, 2, &transientstore.TxPvtReadWriteSetWithConfigInfo{
    45  		PvtRwset: &rwset.TxPvtReadWriteSet{
    46  			DataModel: rwset.TxReadWriteSet_KV,
    47  			NsPvtRwset: []*rwset.NsPvtReadWriteSet{
    48  				pvtReadWriteSet(namespace, collectionName, []byte{1, 2}),
    49  				pvtReadWriteSet(namespace, collectionName, []byte{3, 4}),
    50  			},
    51  		},
    52  		CollectionConfigs: map[string]*peer.CollectionConfigPackage{
    53  			namespace: {
    54  				Config: []*peer.CollectionConfig{
    55  					{
    56  						Payload: &peer.CollectionConfig_StaticCollectionConfig{
    57  							StaticCollectionConfig: &peer.StaticCollectionConfig{
    58  								Name: collectionName,
    59  							},
    60  						},
    61  					},
    62  				},
    63  			},
    64  		},
    65  	})
    66  
    67  	// Request digest for private data which is greater than current ledger height
    68  	// to make it query transient store for missed private data
    69  	rwSets, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
    70  		Namespace:  namespace,
    71  		Collection: collectionName,
    72  		BlockSeq:   2,
    73  		TxId:       txID,
    74  		SeqInBlock: 1,
    75  	}}, 2)
    76  
    77  	assertion := assert.New(t)
    78  	assertion.NoError(err)
    79  	assertion.NotEmpty(rwSets)
    80  	dig2pvtRWSet := rwSets[privdatacommon.DigKey{
    81  		Namespace:  namespace,
    82  		Collection: collectionName,
    83  		BlockSeq:   2,
    84  		TxId:       txID,
    85  		SeqInBlock: 1,
    86  	}]
    87  	assertion.NotNil(dig2pvtRWSet)
    88  	pvtRWSets := dig2pvtRWSet.RWSet
    89  	assertion.Equal(2, len(pvtRWSets))
    90  
    91  	var mergedRWSet []byte
    92  	for _, rws := range pvtRWSets {
    93  		mergedRWSet = append(mergedRWSet, rws...)
    94  	}
    95  
    96  	assertion.Equal([]byte{1, 2, 3, 4}, mergedRWSet)
    97  }
    98  
    99  /*
   100  	Simple test case where available ledger height is greater than
   101  	requested block sequence and therefore private data will be retrieved
   102  	from the ledger rather than transient store as data being committed
   103  */
   104  func TestNewDataRetriever_GetDataFromLedger(t *testing.T) {
   105  	t.Parallel()
   106  	committer := &mocks.Committer{}
   107  
   108  	store := newTransientStore(t)
   109  	defer store.tearDown()
   110  
   111  	namespace := "testChaincodeName1"
   112  	collectionName := "testCollectionName"
   113  
   114  	result := []*ledger.TxPvtData{{
   115  		WriteSet: &rwset.TxPvtReadWriteSet{
   116  			DataModel: rwset.TxReadWriteSet_KV,
   117  			NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   118  				pvtReadWriteSet(namespace, collectionName, []byte{1, 2}),
   119  				pvtReadWriteSet(namespace, collectionName, []byte{3, 4}),
   120  			},
   121  		},
   122  		SeqInBlock: 1,
   123  	}}
   124  
   125  	committer.On("LedgerHeight").Return(uint64(10), nil)
   126  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   127  
   128  	historyRetreiver := &mocks.ConfigHistoryRetriever{}
   129  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, namespace).Return(newCollectionConfig(collectionName), nil)
   130  	committer.On("GetConfigHistoryRetriever").Return(historyRetreiver, nil)
   131  
   132  	retriever := NewDataRetriever(store.store, committer)
   133  
   134  	// Request digest for private data which is greater than current ledger height
   135  	// to make it query ledger for missed private data
   136  	rwSets, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   137  		Namespace:  namespace,
   138  		Collection: collectionName,
   139  		BlockSeq:   uint64(5),
   140  		TxId:       "testTxID",
   141  		SeqInBlock: 1,
   142  	}}, uint64(5))
   143  
   144  	assertion := assert.New(t)
   145  	assertion.NoError(err)
   146  	assertion.NotEmpty(rwSets)
   147  	pvtRWSet := rwSets[privdatacommon.DigKey{
   148  		Namespace:  namespace,
   149  		Collection: collectionName,
   150  		BlockSeq:   5,
   151  		TxId:       "testTxID",
   152  		SeqInBlock: 1,
   153  	}]
   154  	assertion.NotEmpty(pvtRWSet)
   155  	assertion.Equal(2, len(pvtRWSet.RWSet))
   156  
   157  	var mergedRWSet []byte
   158  	for _, rws := range pvtRWSet.RWSet {
   159  		mergedRWSet = append(mergedRWSet, rws...)
   160  	}
   161  
   162  	assertion.Equal([]byte{1, 2, 3, 4}, mergedRWSet)
   163  }
   164  
   165  func TestNewDataRetriever_FailGetPvtDataFromLedger(t *testing.T) {
   166  	t.Parallel()
   167  	committer := &mocks.Committer{}
   168  
   169  	store := newTransientStore(t)
   170  	defer store.tearDown()
   171  
   172  	namespace := "testChaincodeName1"
   173  	collectionName := "testCollectionName"
   174  
   175  	committer.On("LedgerHeight").Return(uint64(10), nil)
   176  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).
   177  		Return(nil, errors.New("failing retrieving private data"))
   178  
   179  	retriever := NewDataRetriever(store.store, committer)
   180  
   181  	// Request digest for private data which is greater than current ledger height
   182  	// to make it query transient store for missed private data
   183  	rwSets, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   184  		Namespace:  namespace,
   185  		Collection: collectionName,
   186  		BlockSeq:   uint64(5),
   187  		TxId:       "testTxID",
   188  		SeqInBlock: 1,
   189  	}}, uint64(5))
   190  
   191  	assertion := assert.New(t)
   192  	assertion.Error(err)
   193  	assertion.Empty(rwSets)
   194  }
   195  
   196  func TestNewDataRetriever_GetOnlyRelevantPvtData(t *testing.T) {
   197  	t.Parallel()
   198  	committer := &mocks.Committer{}
   199  
   200  	store := newTransientStore(t)
   201  	defer store.tearDown()
   202  
   203  	namespace := "testChaincodeName1"
   204  	collectionName := "testCollectionName"
   205  
   206  	result := []*ledger.TxPvtData{{
   207  		WriteSet: &rwset.TxPvtReadWriteSet{
   208  			DataModel: rwset.TxReadWriteSet_KV,
   209  			NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   210  				pvtReadWriteSet(namespace, collectionName, []byte{1}),
   211  				pvtReadWriteSet(namespace, collectionName, []byte{2}),
   212  				pvtReadWriteSet("invalidNamespace", collectionName, []byte{0, 0}),
   213  				pvtReadWriteSet(namespace, "invalidCollectionName", []byte{0, 0}),
   214  			},
   215  		},
   216  		SeqInBlock: 1,
   217  	}}
   218  
   219  	committer.On("LedgerHeight").Return(uint64(10), nil)
   220  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   221  	historyRetreiver := &mocks.ConfigHistoryRetriever{}
   222  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, namespace).Return(newCollectionConfig(collectionName), nil)
   223  	committer.On("GetConfigHistoryRetriever").Return(historyRetreiver, nil)
   224  
   225  	retriever := NewDataRetriever(store.store, committer)
   226  
   227  	// Request digest for private data which is greater than current ledger height
   228  	// to make it query transient store for missed private data
   229  	rwSets, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   230  		Namespace:  namespace,
   231  		Collection: collectionName,
   232  		BlockSeq:   uint64(5),
   233  		TxId:       "testTxID",
   234  		SeqInBlock: 1,
   235  	}}, 5)
   236  
   237  	assertion := assert.New(t)
   238  	assertion.NoError(err)
   239  	assertion.NotEmpty(rwSets)
   240  	pvtRWSet := rwSets[privdatacommon.DigKey{
   241  		Namespace:  namespace,
   242  		Collection: collectionName,
   243  		BlockSeq:   5,
   244  		TxId:       "testTxID",
   245  		SeqInBlock: 1,
   246  	}]
   247  	assertion.NotEmpty(pvtRWSet)
   248  	assertion.Equal(2, len(pvtRWSet.RWSet))
   249  
   250  	var mergedRWSet []byte
   251  	for _, rws := range pvtRWSet.RWSet {
   252  		mergedRWSet = append(mergedRWSet, rws...)
   253  	}
   254  
   255  	assertion.Equal([]byte{1, 2}, mergedRWSet)
   256  }
   257  
   258  func TestNewDataRetriever_GetMultipleDigests(t *testing.T) {
   259  	t.Parallel()
   260  	committer := &mocks.Committer{}
   261  
   262  	store := newTransientStore(t)
   263  	defer store.tearDown()
   264  
   265  	ns1, ns2 := "testChaincodeName1", "testChaincodeName2"
   266  	col1, col2 := "testCollectionName1", "testCollectionName2"
   267  
   268  	result := []*ledger.TxPvtData{
   269  		{
   270  			WriteSet: &rwset.TxPvtReadWriteSet{
   271  				DataModel: rwset.TxReadWriteSet_KV,
   272  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   273  					pvtReadWriteSet(ns1, col1, []byte{1}),
   274  					pvtReadWriteSet(ns1, col1, []byte{2}),
   275  					pvtReadWriteSet("invalidNamespace", col1, []byte{0, 0}),
   276  					pvtReadWriteSet(ns1, "invalidCollectionName", []byte{0, 0}),
   277  				},
   278  			},
   279  			SeqInBlock: 1,
   280  		},
   281  		{
   282  			WriteSet: &rwset.TxPvtReadWriteSet{
   283  				DataModel: rwset.TxReadWriteSet_KV,
   284  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   285  					pvtReadWriteSet(ns2, col2, []byte{3}),
   286  					pvtReadWriteSet(ns2, col2, []byte{4}),
   287  					pvtReadWriteSet("invalidNamespace", col2, []byte{0, 0}),
   288  					pvtReadWriteSet(ns2, "invalidCollectionName", []byte{0, 0}),
   289  				},
   290  			},
   291  			SeqInBlock: 2,
   292  		},
   293  		{
   294  			WriteSet: &rwset.TxPvtReadWriteSet{
   295  				DataModel: rwset.TxReadWriteSet_KV,
   296  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   297  					pvtReadWriteSet(ns1, col1, []byte{5}),
   298  					pvtReadWriteSet(ns2, col2, []byte{6}),
   299  					pvtReadWriteSet("invalidNamespace", col2, []byte{0, 0}),
   300  					pvtReadWriteSet(ns2, "invalidCollectionName", []byte{0, 0}),
   301  				},
   302  			},
   303  			SeqInBlock: 3,
   304  		},
   305  	}
   306  
   307  	committer.On("LedgerHeight").Return(uint64(10), nil)
   308  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   309  	historyRetreiver := &mocks.ConfigHistoryRetriever{}
   310  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, ns1).Return(newCollectionConfig(col1), nil)
   311  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, ns2).Return(newCollectionConfig(col2), nil)
   312  	committer.On("GetConfigHistoryRetriever").Return(historyRetreiver, nil)
   313  
   314  	retriever := NewDataRetriever(store.store, committer)
   315  
   316  	// Request digest for private data which is greater than current ledger height
   317  	// to make it query transient store for missed private data
   318  	rwSets, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   319  		Namespace:  ns1,
   320  		Collection: col1,
   321  		BlockSeq:   uint64(5),
   322  		TxId:       "testTxID",
   323  		SeqInBlock: 1,
   324  	}, {
   325  		Namespace:  ns2,
   326  		Collection: col2,
   327  		BlockSeq:   uint64(5),
   328  		TxId:       "testTxID",
   329  		SeqInBlock: 2,
   330  	}}, 5)
   331  
   332  	assertion := assert.New(t)
   333  	assertion.NoError(err)
   334  	assertion.NotEmpty(rwSets)
   335  	assertion.Equal(2, len(rwSets))
   336  
   337  	pvtRWSet := rwSets[privdatacommon.DigKey{
   338  		Namespace:  ns1,
   339  		Collection: col1,
   340  		BlockSeq:   5,
   341  		TxId:       "testTxID",
   342  		SeqInBlock: 1,
   343  	}]
   344  	assertion.NotEmpty(pvtRWSet)
   345  	assertion.Equal(2, len(pvtRWSet.RWSet))
   346  
   347  	var mergedRWSet []byte
   348  	for _, rws := range pvtRWSet.RWSet {
   349  		mergedRWSet = append(mergedRWSet, rws...)
   350  	}
   351  
   352  	pvtRWSet = rwSets[privdatacommon.DigKey{
   353  		Namespace:  ns2,
   354  		Collection: col2,
   355  		BlockSeq:   5,
   356  		TxId:       "testTxID",
   357  		SeqInBlock: 2,
   358  	}]
   359  	assertion.NotEmpty(pvtRWSet)
   360  	assertion.Equal(2, len(pvtRWSet.RWSet))
   361  	for _, rws := range pvtRWSet.RWSet {
   362  		mergedRWSet = append(mergedRWSet, rws...)
   363  	}
   364  
   365  	assertion.Equal([]byte{1, 2, 3, 4}, mergedRWSet)
   366  }
   367  
   368  func TestNewDataRetriever_EmptyWriteSet(t *testing.T) {
   369  	t.Parallel()
   370  	committer := &mocks.Committer{}
   371  
   372  	store := newTransientStore(t)
   373  	defer store.tearDown()
   374  
   375  	ns1 := "testChaincodeName1"
   376  	col1 := "testCollectionName1"
   377  
   378  	result := []*ledger.TxPvtData{
   379  		{
   380  			SeqInBlock: 1,
   381  		},
   382  	}
   383  
   384  	committer.On("LedgerHeight").Return(uint64(10), nil)
   385  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   386  	historyRetreiver := &mocks.ConfigHistoryRetriever{}
   387  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, ns1).Return(newCollectionConfig(col1), nil)
   388  	committer.On("GetConfigHistoryRetriever").Return(historyRetreiver, nil)
   389  
   390  	retriever := NewDataRetriever(store.store, committer)
   391  
   392  	rwSets, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   393  		Namespace:  ns1,
   394  		Collection: col1,
   395  		BlockSeq:   uint64(5),
   396  		TxId:       "testTxID",
   397  		SeqInBlock: 1,
   398  	}}, 5)
   399  
   400  	assertion := assert.New(t)
   401  	assertion.NoError(err)
   402  	assertion.NotEmpty(rwSets)
   403  
   404  	pvtRWSet := rwSets[privdatacommon.DigKey{
   405  		Namespace:  ns1,
   406  		Collection: col1,
   407  		BlockSeq:   5,
   408  		TxId:       "testTxID",
   409  		SeqInBlock: 1,
   410  	}]
   411  	assertion.NotEmpty(pvtRWSet)
   412  	assertion.Empty(pvtRWSet.RWSet)
   413  
   414  }
   415  
   416  func TestNewDataRetriever_FailedObtainConfigHistoryRetriever(t *testing.T) {
   417  	t.Parallel()
   418  	committer := &mocks.Committer{}
   419  
   420  	store := newTransientStore(t)
   421  	defer store.tearDown()
   422  
   423  	ns1 := "testChaincodeName1"
   424  	col1 := "testCollectionName1"
   425  
   426  	result := []*ledger.TxPvtData{
   427  		{
   428  			WriteSet: &rwset.TxPvtReadWriteSet{
   429  				DataModel: rwset.TxReadWriteSet_KV,
   430  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   431  					pvtReadWriteSet(ns1, col1, []byte{1}),
   432  					pvtReadWriteSet(ns1, col1, []byte{2}),
   433  				},
   434  			},
   435  			SeqInBlock: 1,
   436  		},
   437  	}
   438  
   439  	committer.On("LedgerHeight").Return(uint64(10), nil)
   440  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   441  	committer.On("GetConfigHistoryRetriever").Return(nil, errors.New("failed to obtain ConfigHistoryRetriever"))
   442  
   443  	retriever := NewDataRetriever(store.store, committer)
   444  
   445  	_, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   446  		Namespace:  ns1,
   447  		Collection: col1,
   448  		BlockSeq:   uint64(5),
   449  		TxId:       "testTxID",
   450  		SeqInBlock: 1,
   451  	}}, 5)
   452  
   453  	assertion := assert.New(t)
   454  	assertion.Contains(err.Error(), "failed to obtain ConfigHistoryRetriever")
   455  }
   456  
   457  func TestNewDataRetriever_NoCollectionConfig(t *testing.T) {
   458  	t.Parallel()
   459  	committer := &mocks.Committer{}
   460  
   461  	store := newTransientStore(t)
   462  	defer store.tearDown()
   463  
   464  	ns1, ns2 := "testChaincodeName1", "testChaincodeName2"
   465  	col1, col2 := "testCollectionName1", "testCollectionName2"
   466  
   467  	result := []*ledger.TxPvtData{
   468  		{
   469  			WriteSet: &rwset.TxPvtReadWriteSet{
   470  				DataModel: rwset.TxReadWriteSet_KV,
   471  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   472  					pvtReadWriteSet(ns1, col1, []byte{1}),
   473  					pvtReadWriteSet(ns1, col1, []byte{2}),
   474  				},
   475  			},
   476  			SeqInBlock: 1,
   477  		},
   478  		{
   479  			WriteSet: &rwset.TxPvtReadWriteSet{
   480  				DataModel: rwset.TxReadWriteSet_KV,
   481  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   482  					pvtReadWriteSet(ns2, col2, []byte{3}),
   483  					pvtReadWriteSet(ns2, col2, []byte{4}),
   484  				},
   485  			},
   486  			SeqInBlock: 2,
   487  		},
   488  	}
   489  
   490  	committer.On("LedgerHeight").Return(uint64(10), nil)
   491  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   492  	historyRetreiver := &mocks.ConfigHistoryRetriever{}
   493  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, ns1).
   494  		Return(newCollectionConfig(col1), errors.New("failed to obtain collection config"))
   495  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, ns2).
   496  		Return(nil, nil)
   497  	committer.On("GetConfigHistoryRetriever").Return(historyRetreiver, nil)
   498  
   499  	retriever := NewDataRetriever(store.store, committer)
   500  	assertion := assert.New(t)
   501  
   502  	_, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   503  		Namespace:  ns1,
   504  		Collection: col1,
   505  		BlockSeq:   uint64(5),
   506  		TxId:       "testTxID",
   507  		SeqInBlock: 1,
   508  	}}, 5)
   509  	assertion.Error(err)
   510  	assertion.Contains(err.Error(), "cannot find recent collection config update below block sequence")
   511  
   512  	_, _, err = retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   513  		Namespace:  ns2,
   514  		Collection: col2,
   515  		BlockSeq:   uint64(5),
   516  		TxId:       "testTxID",
   517  		SeqInBlock: 2,
   518  	}}, 5)
   519  	assertion.Error(err)
   520  	assertion.Contains(err.Error(), "no collection config update below block sequence")
   521  }
   522  
   523  func TestNewDataRetriever_FailedGetLedgerHeight(t *testing.T) {
   524  	t.Parallel()
   525  	committer := &mocks.Committer{}
   526  
   527  	store := newTransientStore(t)
   528  	defer store.tearDown()
   529  
   530  	ns1 := "testChaincodeName1"
   531  	col1 := "testCollectionName1"
   532  
   533  	committer.On("LedgerHeight").Return(uint64(0), errors.New("failed to read ledger height"))
   534  	retriever := NewDataRetriever(store.store, committer)
   535  
   536  	_, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   537  		Namespace:  ns1,
   538  		Collection: col1,
   539  		BlockSeq:   uint64(5),
   540  		TxId:       "testTxID",
   541  		SeqInBlock: 1,
   542  	}}, 5)
   543  
   544  	assertion := assert.New(t)
   545  	assertion.Error(err)
   546  	assertion.Contains(err.Error(), "failed to read ledger height")
   547  }
   548  
   549  func TestNewDataRetriever_EmptyPvtRWSetInTransientStore(t *testing.T) {
   550  	t.Parallel()
   551  	committer := &mocks.Committer{}
   552  
   553  	store := newTransientStore(t)
   554  	defer store.tearDown()
   555  
   556  	namespace := "testChaincodeName1"
   557  	collectionName := "testCollectionName"
   558  
   559  	committer.On("LedgerHeight").Return(uint64(1), nil)
   560  
   561  	retriever := NewDataRetriever(store.store, committer)
   562  
   563  	rwSets, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   564  		Namespace:  namespace,
   565  		Collection: collectionName,
   566  		BlockSeq:   2,
   567  		TxId:       "testTxID",
   568  		SeqInBlock: 1,
   569  	}}, 2)
   570  
   571  	assertion := assert.New(t)
   572  	assertion.NoError(err)
   573  	assertion.NotEmpty(rwSets)
   574  	assertion.Empty(rwSets[privdatacommon.DigKey{
   575  		Namespace:  namespace,
   576  		Collection: collectionName,
   577  		BlockSeq:   2,
   578  		TxId:       "testTxID",
   579  		SeqInBlock: 1,
   580  	}])
   581  }
   582  
   583  func newCollectionConfig(collectionName string) *ledger.CollectionConfigInfo {
   584  	return &ledger.CollectionConfigInfo{
   585  		CollectionConfig: &peer.CollectionConfigPackage{
   586  			Config: []*peer.CollectionConfig{
   587  				{
   588  					Payload: &peer.CollectionConfig_StaticCollectionConfig{
   589  						StaticCollectionConfig: &peer.StaticCollectionConfig{
   590  							Name: collectionName,
   591  						},
   592  					},
   593  				},
   594  			},
   595  		},
   596  	}
   597  }
   598  
   599  func pvtReadWriteSet(ns string, collectionName string, data []byte) *rwset.NsPvtReadWriteSet {
   600  	return &rwset.NsPvtReadWriteSet{
   601  		Namespace: ns,
   602  		CollectionPvtRwset: []*rwset.CollectionPvtReadWriteSet{{
   603  			CollectionName: collectionName,
   604  			Rwset:          data,
   605  		}},
   606  	}
   607  }