github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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/osdi23p228/fabric/core/ledger"
    18  	privdatacommon "github.com/osdi23p228/fabric/gossip/privdata/common"
    19  	"github.com/osdi23p228/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  	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 := assert.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 := assert.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 := assert.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 := assert.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 := assert.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 := assert.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  
   410  func TestNewDataRetriever_FailedObtainConfigHistoryRetriever(t *testing.T) {
   411  	committer := &mocks.Committer{}
   412  
   413  	store := newTransientStore(t)
   414  	defer store.tearDown()
   415  
   416  	ns1 := "testChaincodeName1"
   417  	col1 := "testCollectionName1"
   418  
   419  	result := []*ledger.TxPvtData{
   420  		{
   421  			WriteSet: &rwset.TxPvtReadWriteSet{
   422  				DataModel: rwset.TxReadWriteSet_KV,
   423  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   424  					pvtReadWriteSet(ns1, col1, []byte{1}),
   425  					pvtReadWriteSet(ns1, col1, []byte{2}),
   426  				},
   427  			},
   428  			SeqInBlock: 1,
   429  		},
   430  	}
   431  
   432  	committer.On("LedgerHeight").Return(uint64(10), nil)
   433  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   434  	committer.On("GetConfigHistoryRetriever").Return(nil, errors.New("failed to obtain ConfigHistoryRetriever"))
   435  
   436  	retriever := NewDataRetriever("testchannel", store.store, committer)
   437  
   438  	_, _, err := retriever.CollectionRWSet([]*gossip2.PvtDataDigest{{
   439  		Namespace:  ns1,
   440  		Collection: col1,
   441  		BlockSeq:   uint64(5),
   442  		TxId:       "testTxID",
   443  		SeqInBlock: 1,
   444  	}}, 5)
   445  
   446  	assertion := assert.New(t)
   447  	assertion.Contains(err.Error(), "failed to obtain ConfigHistoryRetriever")
   448  }
   449  
   450  func TestNewDataRetriever_NoCollectionConfig(t *testing.T) {
   451  	committer := &mocks.Committer{}
   452  
   453  	store := newTransientStore(t)
   454  	defer store.tearDown()
   455  
   456  	ns1, ns2 := "testChaincodeName1", "testChaincodeName2"
   457  	col1, col2 := "testCollectionName1", "testCollectionName2"
   458  
   459  	result := []*ledger.TxPvtData{
   460  		{
   461  			WriteSet: &rwset.TxPvtReadWriteSet{
   462  				DataModel: rwset.TxReadWriteSet_KV,
   463  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   464  					pvtReadWriteSet(ns1, col1, []byte{1}),
   465  					pvtReadWriteSet(ns1, col1, []byte{2}),
   466  				},
   467  			},
   468  			SeqInBlock: 1,
   469  		},
   470  		{
   471  			WriteSet: &rwset.TxPvtReadWriteSet{
   472  				DataModel: rwset.TxReadWriteSet_KV,
   473  				NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   474  					pvtReadWriteSet(ns2, col2, []byte{3}),
   475  					pvtReadWriteSet(ns2, col2, []byte{4}),
   476  				},
   477  			},
   478  			SeqInBlock: 2,
   479  		},
   480  	}
   481  
   482  	committer.On("LedgerHeight").Return(uint64(10), nil)
   483  	committer.On("GetPvtDataByNum", uint64(5), mock.Anything).Return(result, nil)
   484  	historyRetreiver := &mocks.ConfigHistoryRetriever{}
   485  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, ns1).
   486  		Return(newCollectionConfig(col1), errors.New("failed to obtain collection config"))
   487  	historyRetreiver.On("MostRecentCollectionConfigBelow", mock.Anything, ns2).
   488  		Return(nil, nil)
   489  	committer.On("GetConfigHistoryRetriever").Return(historyRetreiver, nil)
   490  
   491  	retriever := NewDataRetriever("testchannel", store.store, committer)
   492  	assertion := assert.New(t)
   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 := assert.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 := assert.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  }