github.com/Hnampk/fabric@v2.1.1+incompatible/core/ledger/kvledger/txmgmt/rwsetutil/rwset_builder_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package rwsetutil
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  
    13  	"github.com/golang/protobuf/proto"
    14  	"github.com/hyperledger/fabric-protos-go/ledger/rwset"
    15  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    16  	"github.com/hyperledger/fabric/common/flogging"
    17  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
    18  	"github.com/hyperledger/fabric/core/ledger/util"
    19  	"github.com/stretchr/testify/assert"
    20  )
    21  
    22  func TestMain(m *testing.M) {
    23  	flogging.ActivateSpec("rwsetutil=debug")
    24  	os.Exit(m.Run())
    25  }
    26  
    27  func TestTxSimulationResultWithOnlyPubData(t *testing.T) {
    28  	rwSetBuilder := NewRWSetBuilder()
    29  
    30  	rwSetBuilder.AddToReadSet("ns1", "key2", version.NewHeight(1, 2))
    31  	rwSetBuilder.AddToReadSet("ns1", "key1", version.NewHeight(1, 1))
    32  	rwSetBuilder.AddToWriteSet("ns1", "key2", []byte("value2"))
    33  
    34  	rqi1 := &kvrwset.RangeQueryInfo{StartKey: "bKey", EndKey: "", ItrExhausted: false, ReadsInfo: nil}
    35  	rqi1.EndKey = "eKey"
    36  	SetRawReads(rqi1, []*kvrwset.KVRead{NewKVRead("bKey1", version.NewHeight(2, 3)), NewKVRead("bKey2", version.NewHeight(2, 4))})
    37  	rqi1.ItrExhausted = true
    38  	rwSetBuilder.AddToRangeQuerySet("ns1", rqi1)
    39  
    40  	rqi2 := &kvrwset.RangeQueryInfo{StartKey: "bKey", EndKey: "", ItrExhausted: false, ReadsInfo: nil}
    41  	rqi2.EndKey = "eKey"
    42  	SetRawReads(rqi2, []*kvrwset.KVRead{NewKVRead("bKey1", version.NewHeight(2, 3)), NewKVRead("bKey2", version.NewHeight(2, 4))})
    43  	rqi2.ItrExhausted = true
    44  	rwSetBuilder.AddToRangeQuerySet("ns1", rqi2)
    45  
    46  	rqi3 := &kvrwset.RangeQueryInfo{StartKey: "bKey", EndKey: "", ItrExhausted: true, ReadsInfo: nil}
    47  	rqi3.EndKey = "eKey1"
    48  	SetRawReads(rqi3, []*kvrwset.KVRead{NewKVRead("bKey1", version.NewHeight(2, 3)), NewKVRead("bKey2", version.NewHeight(2, 4))})
    49  	rwSetBuilder.AddToRangeQuerySet("ns1", rqi3)
    50  
    51  	rwSetBuilder.AddToReadSet("ns2", "key2", version.NewHeight(1, 2))
    52  	rwSetBuilder.AddToWriteSet("ns2", "key3", []byte("value3"))
    53  
    54  	txSimulationResults, err := rwSetBuilder.GetTxSimulationResults()
    55  	assert.NoError(t, err)
    56  
    57  	ns1KVRWSet := &kvrwset.KVRWSet{
    58  		Reads:            []*kvrwset.KVRead{NewKVRead("key1", version.NewHeight(1, 1)), NewKVRead("key2", version.NewHeight(1, 2))},
    59  		RangeQueriesInfo: []*kvrwset.RangeQueryInfo{rqi1, rqi3},
    60  		Writes:           []*kvrwset.KVWrite{newKVWrite("key2", []byte("value2"))}}
    61  
    62  	ns1RWSet := &rwset.NsReadWriteSet{
    63  		Namespace: "ns1",
    64  		Rwset:     serializeTestProtoMsg(t, ns1KVRWSet),
    65  	}
    66  
    67  	ns2KVRWSet := &kvrwset.KVRWSet{
    68  		Reads:            []*kvrwset.KVRead{NewKVRead("key2", version.NewHeight(1, 2))},
    69  		RangeQueriesInfo: nil,
    70  		Writes:           []*kvrwset.KVWrite{newKVWrite("key3", []byte("value3"))}}
    71  
    72  	ns2RWSet := &rwset.NsReadWriteSet{
    73  		Namespace: "ns2",
    74  		Rwset:     serializeTestProtoMsg(t, ns2KVRWSet),
    75  	}
    76  
    77  	expectedTxRWSet := &rwset.TxReadWriteSet{NsRwset: []*rwset.NsReadWriteSet{ns1RWSet, ns2RWSet}}
    78  	assert.Equal(t, expectedTxRWSet, txSimulationResults.PubSimulationResults)
    79  	assert.Nil(t, txSimulationResults.PvtSimulationResults)
    80  	assert.Nil(t, txSimulationResults.PubSimulationResults.NsRwset[0].CollectionHashedRwset)
    81  }
    82  
    83  func TestTxSimulationResultWithPvtData(t *testing.T) {
    84  	rwSetBuilder := NewRWSetBuilder()
    85  	// public rws ns1 + ns2
    86  	rwSetBuilder.AddToReadSet("ns1", "key1", version.NewHeight(1, 1))
    87  	rwSetBuilder.AddToReadSet("ns2", "key1", version.NewHeight(1, 1))
    88  	rwSetBuilder.AddToWriteSet("ns2", "key1", []byte("ns2-key1-value"))
    89  
    90  	// pvt rwset ns1
    91  	rwSetBuilder.AddToHashedReadSet("ns1", "coll1", "key1", version.NewHeight(1, 1))
    92  	rwSetBuilder.AddToHashedReadSet("ns1", "coll2", "key1", version.NewHeight(1, 1))
    93  	rwSetBuilder.AddToPvtAndHashedWriteSet("ns1", "coll2", "key1", []byte("pvt-ns1-coll2-key1-value"))
    94  
    95  	// pvt rwset ns2
    96  	rwSetBuilder.AddToHashedReadSet("ns2", "coll1", "key1", version.NewHeight(1, 1))
    97  	rwSetBuilder.AddToHashedReadSet("ns2", "coll1", "key2", version.NewHeight(1, 1))
    98  	rwSetBuilder.AddToPvtAndHashedWriteSet("ns2", "coll2", "key1", []byte("pvt-ns2-coll2-key1-value"))
    99  
   100  	actualSimRes, err := rwSetBuilder.GetTxSimulationResults()
   101  	assert.NoError(t, err)
   102  
   103  	///////////////////////////////////////////////////////
   104  	// construct the expected pvt rwset and compare with the one present in the txSimulationResults
   105  	///////////////////////////////////////////////////////
   106  	pvt_Ns1_Coll2 := &kvrwset.KVRWSet{
   107  		Writes: []*kvrwset.KVWrite{newKVWrite("key1", []byte("pvt-ns1-coll2-key1-value"))},
   108  	}
   109  
   110  	pvt_Ns2_Coll2 := &kvrwset.KVRWSet{
   111  		Writes: []*kvrwset.KVWrite{newKVWrite("key1", []byte("pvt-ns2-coll2-key1-value"))},
   112  	}
   113  
   114  	expectedPvtRWSet := &rwset.TxPvtReadWriteSet{
   115  		DataModel: rwset.TxReadWriteSet_KV,
   116  		NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   117  			{
   118  				Namespace: "ns1",
   119  				CollectionPvtRwset: []*rwset.CollectionPvtReadWriteSet{
   120  					{
   121  						CollectionName: "coll2",
   122  						Rwset:          serializeTestProtoMsg(t, pvt_Ns1_Coll2),
   123  					},
   124  				},
   125  			},
   126  
   127  			{
   128  				Namespace: "ns2",
   129  				CollectionPvtRwset: []*rwset.CollectionPvtReadWriteSet{
   130  					{
   131  						CollectionName: "coll2",
   132  						Rwset:          serializeTestProtoMsg(t, pvt_Ns2_Coll2),
   133  					},
   134  				},
   135  			},
   136  		},
   137  	}
   138  	assert.Equal(t, expectedPvtRWSet, actualSimRes.PvtSimulationResults)
   139  
   140  	///////////////////////////////////////////////////////
   141  	// construct the public rwset (which will be part of the block) and compare with the one present in the txSimulationResults
   142  	///////////////////////////////////////////////////////
   143  	pub_Ns1 := &kvrwset.KVRWSet{
   144  		Reads: []*kvrwset.KVRead{NewKVRead("key1", version.NewHeight(1, 1))},
   145  	}
   146  
   147  	pub_Ns2 := &kvrwset.KVRWSet{
   148  		Reads:  []*kvrwset.KVRead{NewKVRead("key1", version.NewHeight(1, 1))},
   149  		Writes: []*kvrwset.KVWrite{newKVWrite("key1", []byte("ns2-key1-value"))},
   150  	}
   151  
   152  	hashed_Ns1_Coll1 := &kvrwset.HashedRWSet{
   153  		HashedReads: []*kvrwset.KVReadHash{
   154  			constructTestPvtKVReadHash(t, "key1", version.NewHeight(1, 1))},
   155  	}
   156  
   157  	hashed_Ns1_Coll2 := &kvrwset.HashedRWSet{
   158  		HashedReads: []*kvrwset.KVReadHash{
   159  			constructTestPvtKVReadHash(t, "key1", version.NewHeight(1, 1))},
   160  		HashedWrites: []*kvrwset.KVWriteHash{
   161  			constructTestPvtKVWriteHash(t, "key1", []byte("pvt-ns1-coll2-key1-value")),
   162  		},
   163  	}
   164  
   165  	hashed_Ns2_Coll1 := &kvrwset.HashedRWSet{
   166  		HashedReads: []*kvrwset.KVReadHash{
   167  			constructTestPvtKVReadHash(t, "key1", version.NewHeight(1, 1)),
   168  			constructTestPvtKVReadHash(t, "key2", version.NewHeight(1, 1)),
   169  		},
   170  	}
   171  
   172  	hashed_Ns2_Coll2 := &kvrwset.HashedRWSet{
   173  		HashedWrites: []*kvrwset.KVWriteHash{
   174  			constructTestPvtKVWriteHash(t, "key1", []byte("pvt-ns2-coll2-key1-value")),
   175  		},
   176  	}
   177  
   178  	combined_Ns1 := &rwset.NsReadWriteSet{
   179  		Namespace: "ns1",
   180  		Rwset:     serializeTestProtoMsg(t, pub_Ns1),
   181  		CollectionHashedRwset: []*rwset.CollectionHashedReadWriteSet{
   182  			{
   183  				CollectionName: "coll1",
   184  				HashedRwset:    serializeTestProtoMsg(t, hashed_Ns1_Coll1),
   185  			},
   186  			{
   187  				CollectionName: "coll2",
   188  				HashedRwset:    serializeTestProtoMsg(t, hashed_Ns1_Coll2),
   189  				PvtRwsetHash:   util.ComputeHash(serializeTestProtoMsg(t, pvt_Ns1_Coll2)),
   190  			},
   191  		},
   192  	}
   193  	assert.Equal(t, combined_Ns1, actualSimRes.PubSimulationResults.NsRwset[0])
   194  
   195  	combined_Ns2 := &rwset.NsReadWriteSet{
   196  		Namespace: "ns2",
   197  		Rwset:     serializeTestProtoMsg(t, pub_Ns2),
   198  		CollectionHashedRwset: []*rwset.CollectionHashedReadWriteSet{
   199  			{
   200  				CollectionName: "coll1",
   201  				HashedRwset:    serializeTestProtoMsg(t, hashed_Ns2_Coll1),
   202  			},
   203  			{
   204  				CollectionName: "coll2",
   205  				HashedRwset:    serializeTestProtoMsg(t, hashed_Ns2_Coll2),
   206  				PvtRwsetHash:   util.ComputeHash(serializeTestProtoMsg(t, pvt_Ns2_Coll2)),
   207  			},
   208  		},
   209  	}
   210  	assert.Equal(t, combined_Ns2, actualSimRes.PubSimulationResults.NsRwset[1])
   211  	expectedPubRWSet := &rwset.TxReadWriteSet{
   212  		DataModel: rwset.TxReadWriteSet_KV,
   213  		NsRwset:   []*rwset.NsReadWriteSet{combined_Ns1, combined_Ns2},
   214  	}
   215  	assert.Equal(t, expectedPubRWSet, actualSimRes.PubSimulationResults)
   216  }
   217  
   218  func TestTxSimulationResultWithMetadata(t *testing.T) {
   219  	rwSetBuilder := NewRWSetBuilder()
   220  	// public rws ns1
   221  	rwSetBuilder.AddToReadSet("ns1", "key1", version.NewHeight(1, 1))
   222  	rwSetBuilder.AddToMetadataWriteSet("ns1", "key1",
   223  		map[string][]byte{"metadata2": []byte("ns1-key1-metadata2"), "metadata1": []byte("ns1-key1-metadata1")},
   224  	)
   225  	// public rws ns2
   226  	rwSetBuilder.AddToWriteSet("ns2", "key1", []byte("ns2-key1-value"))
   227  	rwSetBuilder.AddToMetadataWriteSet("ns2", "key1", map[string][]byte{}) // nil/empty-map indicates metadata delete
   228  
   229  	// pvt rwset <ns1, coll1>
   230  	rwSetBuilder.AddToPvtAndHashedWriteSet("ns1", "coll1", "key1", []byte("pvt-ns1-coll1-key1-value"))
   231  	rwSetBuilder.AddToHashedMetadataWriteSet("ns1", "coll1", "key1",
   232  		map[string][]byte{"metadata1": []byte("ns1-coll1-key1-metadata1")})
   233  
   234  	// pvt rwset <ns1, coll2>
   235  	rwSetBuilder.AddToHashedMetadataWriteSet("ns1", "coll2", "key1", nil) // pvt-data metadata delete
   236  
   237  	actualSimRes, err := rwSetBuilder.GetTxSimulationResults()
   238  	assert.NoError(t, err)
   239  
   240  	// construct the expected pvt rwset and compare with the one present in the txSimulationResults
   241  	pvtNs1Coll1 := &kvrwset.KVRWSet{
   242  		Writes:         []*kvrwset.KVWrite{newKVWrite("key1", []byte("pvt-ns1-coll1-key1-value"))},
   243  		MetadataWrites: []*kvrwset.KVMetadataWrite{{Key: "key1"}},
   244  	}
   245  
   246  	pvtNs1Coll2 := &kvrwset.KVRWSet{
   247  		MetadataWrites: []*kvrwset.KVMetadataWrite{{Key: "key1"}},
   248  	}
   249  
   250  	expectedPvtRWSet := &rwset.TxPvtReadWriteSet{
   251  		DataModel: rwset.TxReadWriteSet_KV,
   252  		NsPvtRwset: []*rwset.NsPvtReadWriteSet{
   253  			{
   254  				Namespace: "ns1",
   255  				CollectionPvtRwset: []*rwset.CollectionPvtReadWriteSet{
   256  					{
   257  						CollectionName: "coll1",
   258  						Rwset:          serializeTestProtoMsg(t, pvtNs1Coll1),
   259  					},
   260  					{
   261  						CollectionName: "coll2",
   262  						Rwset:          serializeTestProtoMsg(t, pvtNs1Coll2),
   263  					},
   264  				},
   265  			},
   266  		},
   267  	}
   268  	assert.Equal(t, expectedPvtRWSet, actualSimRes.PvtSimulationResults)
   269  	// construct the public and hashed rwset (which will be part of the block) and compare with the one present in the txSimulationResults
   270  	pubNs1 := &kvrwset.KVRWSet{
   271  		Reads: []*kvrwset.KVRead{NewKVRead("key1", version.NewHeight(1, 1))},
   272  		MetadataWrites: []*kvrwset.KVMetadataWrite{
   273  			{
   274  				Key: "key1",
   275  				Entries: []*kvrwset.KVMetadataEntry{
   276  					{Name: "metadata1", Value: []byte("ns1-key1-metadata1")},
   277  					{Name: "metadata2", Value: []byte("ns1-key1-metadata2")},
   278  				},
   279  			},
   280  		},
   281  	}
   282  
   283  	pubNs2 := &kvrwset.KVRWSet{
   284  		Writes: []*kvrwset.KVWrite{newKVWrite("key1", []byte("ns2-key1-value"))},
   285  		MetadataWrites: []*kvrwset.KVMetadataWrite{
   286  			{
   287  				Key:     "key1",
   288  				Entries: nil,
   289  			},
   290  		},
   291  	}
   292  
   293  	hashedNs1Coll1 := &kvrwset.HashedRWSet{
   294  		HashedWrites: []*kvrwset.KVWriteHash{
   295  			constructTestPvtKVWriteHash(t, "key1", []byte("pvt-ns1-coll1-key1-value")),
   296  		},
   297  		MetadataWrites: []*kvrwset.KVMetadataWriteHash{
   298  			{
   299  				KeyHash: util.ComputeStringHash("key1"),
   300  				Entries: []*kvrwset.KVMetadataEntry{
   301  					{Name: "metadata1", Value: []byte("ns1-coll1-key1-metadata1")},
   302  				},
   303  			},
   304  		},
   305  	}
   306  
   307  	hashedNs1Coll2 := &kvrwset.HashedRWSet{
   308  		MetadataWrites: []*kvrwset.KVMetadataWriteHash{
   309  			{
   310  				KeyHash: util.ComputeStringHash("key1"),
   311  				Entries: nil,
   312  			},
   313  		},
   314  	}
   315  
   316  	pubAndHashCombinedNs1 := &rwset.NsReadWriteSet{
   317  		Namespace: "ns1",
   318  		Rwset:     serializeTestProtoMsg(t, pubNs1),
   319  		CollectionHashedRwset: []*rwset.CollectionHashedReadWriteSet{
   320  			{
   321  				CollectionName: "coll1",
   322  				HashedRwset:    serializeTestProtoMsg(t, hashedNs1Coll1),
   323  				PvtRwsetHash:   util.ComputeHash(serializeTestProtoMsg(t, pvtNs1Coll1)),
   324  			},
   325  			{
   326  				CollectionName: "coll2",
   327  				HashedRwset:    serializeTestProtoMsg(t, hashedNs1Coll2),
   328  				PvtRwsetHash:   util.ComputeHash(serializeTestProtoMsg(t, pvtNs1Coll2)),
   329  			},
   330  		},
   331  	}
   332  	assert.Equal(t, pubAndHashCombinedNs1, actualSimRes.PubSimulationResults.NsRwset[0])
   333  	pubAndHashCombinedNs2 := &rwset.NsReadWriteSet{
   334  		Namespace:             "ns2",
   335  		Rwset:                 serializeTestProtoMsg(t, pubNs2),
   336  		CollectionHashedRwset: nil,
   337  	}
   338  	expectedPubRWSet := &rwset.TxReadWriteSet{
   339  		DataModel: rwset.TxReadWriteSet_KV,
   340  		NsRwset:   []*rwset.NsReadWriteSet{pubAndHashCombinedNs1, pubAndHashCombinedNs2},
   341  	}
   342  	assert.Equal(t, expectedPubRWSet, actualSimRes.PubSimulationResults)
   343  }
   344  
   345  func constructTestPvtKVReadHash(t *testing.T, key string, version *version.Height) *kvrwset.KVReadHash {
   346  	kvReadHash := newPvtKVReadHash(key, version)
   347  	return kvReadHash
   348  }
   349  
   350  func constructTestPvtKVWriteHash(t *testing.T, key string, value []byte) *kvrwset.KVWriteHash {
   351  	_, kvWriteHash := newPvtKVWriteAndHash(key, value)
   352  	return kvWriteHash
   353  }
   354  
   355  func serializeTestProtoMsg(t *testing.T, protoMsg proto.Message) []byte {
   356  	msgBytes, err := proto.Marshal(protoMsg)
   357  	assert.NoError(t, err)
   358  	return msgBytes
   359  }