github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/txmgmt/validation/tx_ops_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package validation
     8  
     9  import (
    10  	"testing"
    11  
    12  	"github.com/hechain20/hechain/core/ledger/internal/version"
    13  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/privacyenabledstate"
    14  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/rwsetutil"
    15  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statemetadata"
    16  	"github.com/hechain20/hechain/core/ledger/util"
    17  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestTxOps(t *testing.T) {
    22  	require := require.New(t)
    23  
    24  	txops := txOps{}
    25  	key1 := compositeKey{"ns1", "", "key1"}
    26  	key2 := compositeKey{"ns1", "coll2", "key2"}
    27  	key3 := compositeKey{"ns1", "coll3", "key3"}
    28  	key4 := compositeKey{"ns1", "coll4", "key4"}
    29  
    30  	txops.upsert(key1, []byte("key1-value1"))
    31  	require.True(txops[key1].isOnlyUpsert())
    32  
    33  	txops.upsert(key2, []byte("key2-value2"))
    34  	require.True(txops[key2].isOnlyUpsert())
    35  	txops.metadataUpdate(key2, []byte("key2-metadata"))
    36  	require.False(txops[key2].isOnlyUpsert())
    37  	require.True(txops[key2].isUpsertAndMetadataUpdate())
    38  
    39  	txops.upsert(key3, []byte("key3-value"))
    40  	require.True(txops[key3].isOnlyUpsert())
    41  	txops.metadataDelete(key3)
    42  	require.False(txops[key3].isOnlyUpsert())
    43  	require.True(txops[key3].isUpsertAndMetadataUpdate())
    44  
    45  	txops.delete(key4)
    46  	require.True(txops[key4].isDelete())
    47  }
    48  
    49  func TestTxOpsPreparationValueUpdate(t *testing.T) {
    50  	testDBEnv := privacyenabledstate.LevelDBTestEnv{}
    51  	testDBEnv.Init(t)
    52  	defer testDBEnv.Cleanup()
    53  	db := testDBEnv.GetDBHandle("TestDB")
    54  
    55  	ck1, ck2, ck3 :=
    56  		compositeKey{ns: "ns1", key: "key1"},
    57  		compositeKey{ns: "ns1", key: "key2"},
    58  		compositeKey{ns: "ns1", key: "key3"}
    59  
    60  	updateBatch := privacyenabledstate.NewUpdateBatch()
    61  	updateBatch.PubUpdates.Put(ck1.ns, ck1.key, []byte("value1"), version.NewHeight(1, 1)) // write key1 with only value
    62  	updateBatch.PubUpdates.PutValAndMetadata(                                              // write key2 with value and metadata
    63  		ck2.ns, ck2.key,
    64  		[]byte("value2"),
    65  		testutilSerializedMetadata(t, map[string][]byte{"metadata2": []byte("metadata2")}),
    66  		version.NewHeight(1, 2))
    67  
    68  	require.NoError(t, db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(1, 2))) // write the above initial state to db
    69  	precedingUpdates := newPubAndHashUpdates()
    70  
    71  	rwset := testutilBuildRwset( // A sample rwset {upsert key1, key2, key3}
    72  		t,
    73  		map[compositeKey][]byte{
    74  			ck1: []byte("value1_new"),
    75  			ck2: []byte("value2_new"),
    76  			ck3: []byte("value3_new"),
    77  		},
    78  		nil,
    79  	)
    80  
    81  	txOps, err := prepareTxOps(rwset, precedingUpdates, db)
    82  	require.NoError(t, err)
    83  	require.Len(t, txOps, 3)
    84  
    85  	ck1ExpectedKeyOps := &keyOps{ // finally, key1 should have only new value
    86  		flag:  upsertVal,
    87  		value: []byte("value1_new"),
    88  	}
    89  
    90  	ck2ExpectedKeyOps := &keyOps{ // key2 should have new value and existing metadata
    91  		flag:     upsertVal,
    92  		value:    []byte("value2_new"),
    93  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata2": []byte("metadata2")}),
    94  	}
    95  
    96  	ck3ExpectedKeyOps := &keyOps{ // key3 should have new value
    97  		flag:  upsertVal,
    98  		value: []byte("value3_new"),
    99  	}
   100  
   101  	require.Equal(t, ck1ExpectedKeyOps, txOps[ck1])
   102  	require.Equal(t, ck2ExpectedKeyOps, txOps[ck2])
   103  	require.Equal(t, ck3ExpectedKeyOps, txOps[ck3])
   104  }
   105  
   106  func TestTxOpsPreparationMetadataUpdates(t *testing.T) {
   107  	testDBEnv := privacyenabledstate.LevelDBTestEnv{}
   108  	testDBEnv.Init(t)
   109  	defer testDBEnv.Cleanup()
   110  	db := testDBEnv.GetDBHandle("TestDB")
   111  
   112  	ck1, ck2, ck3 :=
   113  		compositeKey{ns: "ns1", key: "key1"},
   114  		compositeKey{ns: "ns1", key: "key2"},
   115  		compositeKey{ns: "ns1", key: "key3"}
   116  
   117  	updateBatch := privacyenabledstate.NewUpdateBatch()
   118  	updateBatch.PubUpdates.Put(ck1.ns, ck1.key, []byte("value1"), version.NewHeight(1, 1)) // write key1 with only value
   119  	updateBatch.PubUpdates.PutValAndMetadata(                                              // write key2 with value and metadata
   120  		ck2.ns, ck2.key,
   121  		[]byte("value2"),
   122  		testutilSerializedMetadata(t, map[string][]byte{"metadata2": []byte("metadata2")}),
   123  		version.NewHeight(1, 2))
   124  
   125  	require.NoError(t, db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(1, 2))) // write the above initial state to db
   126  	precedingUpdates := newPubAndHashUpdates()
   127  
   128  	rwset := testutilBuildRwset( // A sample rwset {update metadta for the three keys}
   129  		t,
   130  		nil,
   131  		map[compositeKey]map[string][]byte{
   132  			ck1: {"metadata1": []byte("metadata1_new")},
   133  			ck2: {"metadata2": []byte("metadata2_new")},
   134  			ck3: {"metadata3": []byte("metadata3_new")},
   135  		},
   136  	)
   137  
   138  	txOps, err := prepareTxOps(rwset, precedingUpdates, db)
   139  	require.NoError(t, err)
   140  	require.Len(t, txOps, 2) // key3 should have been removed from the txOps because, the key3 does not exist and only metadata is being updated
   141  
   142  	ck1ExpectedKeyOps := &keyOps{ // finally, key1 should have only existing value and new metadata
   143  		flag:     metadataUpdate,
   144  		value:    []byte("value1"),
   145  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata1": []byte("metadata1_new")}),
   146  	}
   147  
   148  	ck2ExpectedKeyOps := &keyOps{ // key2 should have existing value and new metadata
   149  		flag:     metadataUpdate,
   150  		value:    []byte("value2"),
   151  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata2": []byte("metadata2_new")}),
   152  	}
   153  
   154  	require.Equal(t, ck1ExpectedKeyOps, txOps[ck1])
   155  	require.Equal(t, ck2ExpectedKeyOps, txOps[ck2])
   156  }
   157  
   158  func TestTxOpsPreparationMetadataDelete(t *testing.T) {
   159  	testDBEnv := privacyenabledstate.LevelDBTestEnv{}
   160  	testDBEnv.Init(t)
   161  	defer testDBEnv.Cleanup()
   162  	db := testDBEnv.GetDBHandle("TestDB")
   163  
   164  	ck1, ck2, ck3 :=
   165  		compositeKey{ns: "ns1", key: "key1"},
   166  		compositeKey{ns: "ns1", key: "key2"},
   167  		compositeKey{ns: "ns1", key: "key3"}
   168  
   169  	updateBatch := privacyenabledstate.NewUpdateBatch()
   170  	updateBatch.PubUpdates.Put(ck1.ns, ck1.key, []byte("value1"), version.NewHeight(1, 1)) // write key1 with only value
   171  	updateBatch.PubUpdates.PutValAndMetadata(                                              // write key2 with value and metadata
   172  		ck2.ns, ck2.key,
   173  		[]byte("value2"),
   174  		testutilSerializedMetadata(t, map[string][]byte{"metadata2": []byte("metadata2")}),
   175  		version.NewHeight(1, 2))
   176  
   177  	require.NoError(t, db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(1, 2))) // write the above initial state to db
   178  	precedingUpdates := newPubAndHashUpdates()
   179  
   180  	rwset := testutilBuildRwset( // A sample rwset {delete metadata for the three keys}
   181  		t,
   182  		nil,
   183  		map[compositeKey]map[string][]byte{
   184  			ck1: {},
   185  			ck2: {},
   186  			ck3: {},
   187  		},
   188  	)
   189  
   190  	txOps, err := prepareTxOps(rwset, precedingUpdates, db)
   191  	require.NoError(t, err)
   192  	require.Len(t, txOps, 2) // key3 should have been removed from the txOps because, the key3 does not exist and only metadata is being updated
   193  
   194  	ck1ExpectedKeyOps := &keyOps{ // finally, key1 should have only existing value and no metadata
   195  		flag:  metadataDelete,
   196  		value: []byte("value1"),
   197  	}
   198  
   199  	ck2ExpectedKeyOps := &keyOps{ // key2 should have existing value and no metadata
   200  		flag:  metadataDelete,
   201  		value: []byte("value2"),
   202  	}
   203  
   204  	require.Equal(t, ck1ExpectedKeyOps, txOps[ck1])
   205  	require.Equal(t, ck2ExpectedKeyOps, txOps[ck2])
   206  }
   207  
   208  func TestTxOpsPreparationMixedUpdates(t *testing.T) {
   209  	testDBEnv := privacyenabledstate.LevelDBTestEnv{}
   210  	testDBEnv.Init(t)
   211  	defer testDBEnv.Cleanup()
   212  	db := testDBEnv.GetDBHandle("TestDB")
   213  
   214  	ck1, ck2, ck3, ck4 :=
   215  		compositeKey{ns: "ns1", key: "key1"},
   216  		compositeKey{ns: "ns1", key: "key2"},
   217  		compositeKey{ns: "ns1", key: "key3"},
   218  		compositeKey{ns: "ns1", key: "key4"}
   219  
   220  	updateBatch := privacyenabledstate.NewUpdateBatch()
   221  	updateBatch.PubUpdates.Put(ck1.ns, ck1.key, []byte("value1"), version.NewHeight(1, 1)) // write key1 with only value
   222  	updateBatch.PubUpdates.Put(ck2.ns, ck2.key, []byte("value2"), version.NewHeight(1, 2)) // write key2 with only value
   223  	updateBatch.PubUpdates.PutValAndMetadata(                                              // write key3 with value and metadata
   224  		ck3.ns, ck3.key,
   225  		[]byte("value3"),
   226  		testutilSerializedMetadata(t, map[string][]byte{"metadata3": []byte("metadata3")}),
   227  		version.NewHeight(1, 3))
   228  	updateBatch.PubUpdates.PutValAndMetadata( // write key4 with value and metadata
   229  		ck4.ns, ck4.key,
   230  		[]byte("value4"),
   231  		testutilSerializedMetadata(t, map[string][]byte{"metadata4": []byte("metadata4")}),
   232  		version.NewHeight(1, 4))
   233  
   234  	require.NoError(t, db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(1, 2))) // write the above initial state to db
   235  
   236  	precedingUpdates := newPubAndHashUpdates()
   237  
   238  	rwset := testutilBuildRwset( // A sample rwset {key1:only value update, key2: value and metadata update, key3: only metadata update, key4: only value update}
   239  		t,
   240  		map[compositeKey][]byte{
   241  			ck1: []byte("value1_new"),
   242  			ck2: []byte("value2_new"),
   243  			ck4: []byte("value4_new"),
   244  		},
   245  		map[compositeKey]map[string][]byte{
   246  			ck2: {"metadata2": []byte("metadata2_new")},
   247  			ck3: {"metadata3": []byte("metadata3_new")},
   248  		},
   249  	)
   250  
   251  	txOps, err := prepareTxOps(rwset, precedingUpdates, db)
   252  	require.NoError(t, err)
   253  	require.Len(t, txOps, 4)
   254  
   255  	ck1ExpectedKeyOps := &keyOps{ // finally, key1 should have only new value
   256  		flag:  upsertVal,
   257  		value: []byte("value1_new"),
   258  	}
   259  
   260  	ck2ExpectedKeyOps := &keyOps{ // key2 should have new value and new metadata
   261  		flag:     upsertVal + metadataUpdate,
   262  		value:    []byte("value2_new"),
   263  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata2": []byte("metadata2_new")}),
   264  	}
   265  
   266  	ck3ExpectedKeyOps := &keyOps{ // key3 should have existing value and new metadata
   267  		flag:     metadataUpdate,
   268  		value:    []byte("value3"),
   269  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata3": []byte("metadata3_new")}),
   270  	}
   271  
   272  	ck4ExpectedKeyOps := &keyOps{ // key4 should have new value and existing metadata
   273  		flag:     upsertVal,
   274  		value:    []byte("value4_new"),
   275  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata4": []byte("metadata4")}),
   276  	}
   277  
   278  	require.Equal(t, ck1ExpectedKeyOps, txOps[ck1])
   279  	require.Equal(t, ck2ExpectedKeyOps, txOps[ck2])
   280  	require.Equal(t, ck3ExpectedKeyOps, txOps[ck3])
   281  	require.Equal(t, ck4ExpectedKeyOps, txOps[ck4])
   282  }
   283  
   284  func TestTxOpsPreparationPvtdataHashes(t *testing.T) {
   285  	testDBEnv := privacyenabledstate.LevelDBTestEnv{}
   286  	testDBEnv.Init(t)
   287  	defer testDBEnv.Cleanup()
   288  	db := testDBEnv.GetDBHandle("TestDB")
   289  
   290  	ck1, ck2, ck3, ck4 :=
   291  		compositeKey{ns: "ns1", coll: "coll1", key: "key1"},
   292  		compositeKey{ns: "ns1", coll: "coll1", key: "key2"},
   293  		compositeKey{ns: "ns1", coll: "coll1", key: "key3"},
   294  		compositeKey{ns: "ns1", coll: "coll1", key: "key4"}
   295  
   296  	ck1Hash, ck2Hash, ck3Hash, ck4Hash :=
   297  		compositeKey{ns: "ns1", coll: "coll1", key: string(util.ComputeStringHash("key1"))},
   298  		compositeKey{ns: "ns1", coll: "coll1", key: string(util.ComputeStringHash("key2"))},
   299  		compositeKey{ns: "ns1", coll: "coll1", key: string(util.ComputeStringHash("key3"))},
   300  		compositeKey{ns: "ns1", coll: "coll1", key: string(util.ComputeStringHash("key4"))}
   301  
   302  	updateBatch := privacyenabledstate.NewUpdateBatch()
   303  
   304  	updateBatch.HashUpdates.Put(ck1.ns, ck1.coll, util.ComputeStringHash(ck1.key),
   305  		util.ComputeStringHash("value1"), version.NewHeight(1, 1)) // write key1 with only value
   306  
   307  	updateBatch.HashUpdates.Put(ck2.ns, ck2.coll, util.ComputeStringHash(ck2.key),
   308  		util.ComputeStringHash("value2"), version.NewHeight(1, 2)) // write key2 with only value
   309  
   310  	updateBatch.HashUpdates.PutValAndMetadata( // write key3 with value and metadata
   311  		ck3.ns, ck3.coll, string(util.ComputeStringHash(ck3.key)),
   312  		util.ComputeStringHash("value3"),
   313  		testutilSerializedMetadata(t, map[string][]byte{"metadata3": []byte("metadata3")}),
   314  		version.NewHeight(1, 3))
   315  
   316  	updateBatch.HashUpdates.PutValAndMetadata( // write key4 with value and metadata
   317  		ck4.ns, ck4.coll, string(util.ComputeStringHash(ck4.key)),
   318  		util.ComputeStringHash("value4"),
   319  		testutilSerializedMetadata(t, map[string][]byte{"metadata4": []byte("metadata4")}),
   320  		version.NewHeight(1, 4))
   321  
   322  	require.NoError(t, db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(1, 2))) // write the above initial state to db
   323  
   324  	precedingUpdates := newPubAndHashUpdates()
   325  	rwset := testutilBuildRwset( // A sample rwset {key1:only value update, key2: value and metadata update, key3: only metadata update, key4: only value update}
   326  		t,
   327  		map[compositeKey][]byte{
   328  			ck1: []byte("value1_new"),
   329  			ck2: []byte("value2_new"),
   330  			ck4: []byte("value4_new"),
   331  		},
   332  		map[compositeKey]map[string][]byte{
   333  			ck2: {"metadata2": []byte("metadata2_new")},
   334  			ck3: {"metadata3": []byte("metadata3_new")},
   335  		},
   336  	)
   337  
   338  	txOps, err := prepareTxOps(rwset, precedingUpdates, db)
   339  	require.NoError(t, err)
   340  	require.Len(t, txOps, 4)
   341  
   342  	ck1ExpectedKeyOps := &keyOps{ // finally, key1 should have only new value
   343  		flag:  upsertVal,
   344  		value: util.ComputeStringHash("value1_new"),
   345  	}
   346  
   347  	ck2ExpectedKeyOps := &keyOps{ // key2 should have new value and new metadata
   348  		flag:     upsertVal + metadataUpdate,
   349  		value:    util.ComputeStringHash("value2_new"),
   350  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata2": []byte("metadata2_new")}),
   351  	}
   352  
   353  	ck3ExpectedKeyOps := &keyOps{ // key3 should have existing value and new metadata
   354  		flag:     metadataUpdate,
   355  		value:    util.ComputeStringHash("value3"),
   356  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata3": []byte("metadata3_new")}),
   357  	}
   358  
   359  	ck4ExpectedKeyOps := &keyOps{ // key4 should have new value and existing metadata
   360  		flag:     upsertVal,
   361  		value:    util.ComputeStringHash("value4_new"),
   362  		metadata: testutilSerializedMetadata(t, map[string][]byte{"metadata4": []byte("metadata4")}),
   363  	}
   364  
   365  	require.Equal(t, ck1ExpectedKeyOps, txOps[ck1Hash])
   366  	require.Equal(t, ck2ExpectedKeyOps, txOps[ck2Hash])
   367  	require.Equal(t, ck3ExpectedKeyOps, txOps[ck3Hash])
   368  	require.Equal(t, ck4ExpectedKeyOps, txOps[ck4Hash])
   369  }
   370  
   371  // TestInterpretNilValueKVWritesAsDelete - See FAB-18386
   372  func TestInterpretNilValueKVWritesAsDelete(t *testing.T) {
   373  	testcases := []struct {
   374  		name                  string
   375  		rwset                 *rwsetutil.TxRwSet
   376  		compositeKeysToVerify []compositeKey
   377  	}{
   378  		{
   379  			name: "public_keys_writes",
   380  			rwset: &rwsetutil.TxRwSet{
   381  				NsRwSets: []*rwsetutil.NsRwSet{
   382  					{
   383  						NameSpace: "ns1",
   384  						KvRwSet: &kvrwset.KVRWSet{
   385  							Writes: []*kvrwset.KVWrite{
   386  								{
   387  									Key:      "key1",
   388  									IsDelete: true,
   389  								},
   390  								{
   391  									Key:      "key2",
   392  									IsDelete: false,
   393  									Value:    []byte{},
   394  								},
   395  							},
   396  						},
   397  					},
   398  				},
   399  			},
   400  			compositeKeysToVerify: []compositeKey{
   401  				{ns: "ns1", key: "key1"},
   402  				{ns: "ns1", key: "key2"},
   403  			},
   404  		},
   405  		{
   406  			name: "private_keys_hashes_writes",
   407  			rwset: &rwsetutil.TxRwSet{
   408  				NsRwSets: []*rwsetutil.NsRwSet{
   409  					{
   410  						NameSpace: "ns1",
   411  						KvRwSet:   &kvrwset.KVRWSet{},
   412  						CollHashedRwSets: []*rwsetutil.CollHashedRwSet{
   413  							{
   414  								CollectionName: "coll1",
   415  								HashedRwSet: &kvrwset.HashedRWSet{
   416  									HashedWrites: []*kvrwset.KVWriteHash{
   417  										{
   418  											KeyHash:  util.ComputeStringHash("key1"),
   419  											IsDelete: true,
   420  										},
   421  										{
   422  											KeyHash:  util.ComputeStringHash("key2"),
   423  											IsDelete: false,
   424  										},
   425  										{
   426  											KeyHash:   util.ComputeStringHash("key3"),
   427  											IsDelete:  false,
   428  											ValueHash: util.ComputeHash([]byte{}),
   429  										},
   430  									},
   431  								},
   432  							},
   433  						},
   434  					},
   435  				},
   436  			},
   437  			compositeKeysToVerify: []compositeKey{
   438  				{ns: "ns1", coll: "coll1", key: string(util.ComputeStringHash("key1"))},
   439  				{ns: "ns1", coll: "coll1", key: string(util.ComputeStringHash("key2"))},
   440  				{ns: "ns1", coll: "coll1", key: string(util.ComputeStringHash("key3"))},
   441  			},
   442  		},
   443  	}
   444  
   445  	for _, tc := range testcases {
   446  		t.Run(tc.name, func(t *testing.T) {
   447  			txOps := txOps{}
   448  			err := txOps.applyTxRwset(tc.rwset)
   449  			require.NoError(t, err)
   450  
   451  			for _, keyToVerify := range tc.compositeKeysToVerify {
   452  				require.Equal(t,
   453  					&keyOps{flag: keyDelete},
   454  					txOps[keyToVerify],
   455  				)
   456  			}
   457  		})
   458  	}
   459  }
   460  
   461  func testutilBuildRwset(t *testing.T,
   462  	kvWrites map[compositeKey][]byte,
   463  	metadataWrites map[compositeKey]map[string][]byte) *rwsetutil.TxRwSet {
   464  	rwsetBuilder := rwsetutil.NewRWSetBuilder()
   465  	for kvwrite, val := range kvWrites {
   466  		if kvwrite.coll == "" {
   467  			rwsetBuilder.AddToWriteSet(kvwrite.ns, kvwrite.key, val)
   468  		} else {
   469  			rwsetBuilder.AddToPvtAndHashedWriteSet(kvwrite.ns, kvwrite.coll, kvwrite.key, val)
   470  		}
   471  	}
   472  
   473  	for metadataWrite, metadataVal := range metadataWrites {
   474  		if metadataWrite.coll == "" {
   475  			rwsetBuilder.AddToMetadataWriteSet(metadataWrite.ns, metadataWrite.key, metadataVal)
   476  		} else {
   477  			rwsetBuilder.AddToHashedMetadataWriteSet(metadataWrite.ns, metadataWrite.coll, metadataWrite.key, metadataVal)
   478  		}
   479  	}
   480  	return rwsetBuilder.GetTxReadWriteSet()
   481  }
   482  
   483  func testutilSerializedMetadata(t *testing.T, metadataMap map[string][]byte) []byte {
   484  	metadataEntries := []*kvrwset.KVMetadataEntry{}
   485  	for metadataK, metadataV := range metadataMap {
   486  		metadataEntries = append(metadataEntries, &kvrwset.KVMetadataEntry{Name: metadataK, Value: metadataV})
   487  	}
   488  	metadataBytes, err := statemetadata.Serialize(metadataEntries)
   489  	require.NoError(t, err)
   490  	return metadataBytes
   491  }