github.com/renegr87/renegr87@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 }