github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/gossip/privdata/dataretriever_test.go (about)

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