github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/core/ledger/kvledger/kv_ledger_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package kvledger 8 9 import ( 10 "os" 11 "testing" 12 13 "github.com/golang/protobuf/proto" 14 "github.com/hyperledger/fabric-protos-go/common" 15 "github.com/hyperledger/fabric-protos-go/ledger/queryresult" 16 "github.com/hyperledger/fabric-protos-go/ledger/rwset" 17 "github.com/hyperledger/fabric-protos-go/peer" 18 pb "github.com/hyperledger/fabric-protos-go/peer" 19 "github.com/osdi23p228/fabric/common/flogging" 20 "github.com/osdi23p228/fabric/common/ledger/testutil" 21 "github.com/osdi23p228/fabric/common/util" 22 "github.com/osdi23p228/fabric/core/ledger" 23 lgr "github.com/osdi23p228/fabric/core/ledger" 24 "github.com/osdi23p228/fabric/core/ledger/mock" 25 "github.com/osdi23p228/fabric/core/ledger/pvtdatapolicy" 26 btltestutil "github.com/osdi23p228/fabric/core/ledger/pvtdatapolicy/testutil" 27 "github.com/osdi23p228/fabric/internal/pkg/txflags" 28 "github.com/osdi23p228/fabric/protoutil" 29 "github.com/stretchr/testify/require" 30 ) 31 32 func TestMain(m *testing.M) { 33 flogging.ActivateSpec("lockbasedtxmgr,statevalidator,valimpl,confighistory,pvtstatepurgemgmt=debug") 34 os.Exit(m.Run()) 35 } 36 37 func TestKVLedgerNilHistoryDBProvider(t *testing.T) { 38 kvl := &kvLedger{} 39 qe, err := kvl.NewHistoryQueryExecutor() 40 require.Nil( 41 t, 42 qe, 43 "NewHistoryQueryExecutor should return nil when history db provider is nil", 44 ) 45 require.NoError( 46 t, 47 err, 48 "NewHistoryQueryExecutor should return an error when history db provider is nil", 49 ) 50 } 51 52 func TestKVLedgerBlockStorage(t *testing.T) { 53 conf, cleanup := testConfig(t) 54 defer cleanup() 55 provider := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 56 defer provider.Close() 57 58 bg, gb := testutil.NewBlockGenerator(t, "testLedger", false) 59 gbHash := protoutil.BlockHeaderHash(gb.Header) 60 ledger, err := provider.Create(gb) 61 require.NoError(t, err) 62 defer ledger.Close() 63 64 bcInfo, _ := ledger.GetBlockchainInfo() 65 require.Equal(t, &common.BlockchainInfo{ 66 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil, 67 }, bcInfo) 68 69 txid := util.GenerateUUID() 70 simulator, _ := ledger.NewTxSimulator(txid) 71 simulator.SetState("ns1", "key1", []byte("value1")) 72 simulator.SetState("ns1", "key2", []byte("value2")) 73 simulator.SetState("ns1", "key3", []byte("value3")) 74 simulator.Done() 75 simRes, _ := simulator.GetTxSimulationResults() 76 pubSimBytes, _ := simRes.GetPubSimulationBytes() 77 block1 := bg.NextBlock([][]byte{pubSimBytes}) 78 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{}) 79 80 bcInfo, _ = ledger.GetBlockchainInfo() 81 block1Hash := protoutil.BlockHeaderHash(block1.Header) 82 require.Equal(t, &common.BlockchainInfo{ 83 Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash, 84 }, bcInfo) 85 86 txid = util.GenerateUUID() 87 simulator, _ = ledger.NewTxSimulator(txid) 88 simulator.SetState("ns1", "key1", []byte("value4")) 89 simulator.SetState("ns1", "key2", []byte("value5")) 90 simulator.SetState("ns1", "key3", []byte("value6")) 91 simulator.Done() 92 simRes, _ = simulator.GetTxSimulationResults() 93 pubSimBytes, _ = simRes.GetPubSimulationBytes() 94 block2 := bg.NextBlock([][]byte{pubSimBytes}) 95 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{}) 96 97 bcInfo, _ = ledger.GetBlockchainInfo() 98 block2Hash := protoutil.BlockHeaderHash(block2.Header) 99 require.Equal(t, &common.BlockchainInfo{ 100 Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash}, bcInfo) 101 102 b0, _ := ledger.GetBlockByHash(gbHash) 103 require.True(t, proto.Equal(b0, gb), "proto messages are not equal") 104 105 b1, _ := ledger.GetBlockByHash(block1Hash) 106 require.True(t, proto.Equal(b1, block1), "proto messages are not equal") 107 108 b0, _ = ledger.GetBlockByNumber(0) 109 require.True(t, proto.Equal(b0, gb), "proto messages are not equal") 110 111 b1, _ = ledger.GetBlockByNumber(1) 112 require.Equal(t, block1, b1) 113 114 // get the tran id from the 2nd block, then use it to test GetTransactionByID() 115 txEnvBytes2 := block1.Data.Data[0] 116 txEnv2, err := protoutil.GetEnvelopeFromBlock(txEnvBytes2) 117 require.NoError(t, err, "Error upon GetEnvelopeFromBlock") 118 payload2, err := protoutil.UnmarshalPayload(txEnv2.Payload) 119 require.NoError(t, err, "Error upon GetPayload") 120 chdr, err := protoutil.UnmarshalChannelHeader(payload2.Header.ChannelHeader) 121 require.NoError(t, err, "Error upon GetChannelHeaderFromBytes") 122 txID2 := chdr.TxId 123 processedTran2, err := ledger.GetTransactionByID(txID2) 124 require.NoError(t, err, "Error upon GetTransactionByID") 125 // get the tran envelope from the retrieved ProcessedTransaction 126 retrievedTxEnv2 := processedTran2.TransactionEnvelope 127 require.Equal(t, txEnv2, retrievedTxEnv2) 128 129 // get the tran id from the 2nd block, then use it to test GetBlockByTxID 130 b1, _ = ledger.GetBlockByTxID(txID2) 131 require.True(t, proto.Equal(b1, block1), "proto messages are not equal") 132 133 // get the transaction validation code for this transaction id 134 validCode, _ := ledger.GetTxValidationCodeByTxID(txID2) 135 require.Equal(t, peer.TxValidationCode_VALID, validCode) 136 } 137 138 func TestAddCommitHash(t *testing.T) { 139 conf, cleanup := testConfig(t) 140 defer cleanup() 141 provider := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 142 defer provider.Close() 143 144 bg, gb := testutil.NewBlockGenerator(t, "testLedger", false) 145 gbHash := protoutil.BlockHeaderHash(gb.Header) 146 ledger, err := provider.Create(gb) 147 require.NoError(t, err) 148 defer ledger.Close() 149 150 // metadata associated with the above created geneis block is 151 // empty. Hence, no commitHash would be empty. 152 commitHash, err := ledger.(*kvLedger).lastPersistedCommitHash() 153 require.NoError(t, err) 154 require.Equal(t, commitHash, ledger.(*kvLedger).commitHash) 155 require.Equal(t, len(commitHash), 0) 156 157 bcInfo, _ := ledger.GetBlockchainInfo() 158 require.Equal(t, &common.BlockchainInfo{ 159 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil, 160 }, bcInfo) 161 162 txid := util.GenerateUUID() 163 simulator, _ := ledger.NewTxSimulator(txid) 164 simulator.SetState("ns1", "key1", []byte("value1")) 165 simulator.SetState("ns1", "key2", []byte("value2")) 166 simulator.SetState("ns1", "key3", []byte("value3")) 167 simulator.Done() 168 simRes, _ := simulator.GetTxSimulationResults() 169 pubSimBytes, _ := simRes.GetPubSimulationBytes() 170 block1 := bg.NextBlock([][]byte{pubSimBytes}) 171 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{}) 172 173 commitHash, err = ledger.(*kvLedger).lastPersistedCommitHash() 174 require.NoError(t, err) 175 require.Equal(t, commitHash, ledger.(*kvLedger).commitHash) 176 require.Equal(t, len(commitHash), 32) 177 178 // if the kvledger.commitHash is nil and the block number is > 1, the 179 // commitHash should not be added to the block 180 block2 := bg.NextBlock([][]byte{pubSimBytes}) 181 ledger.(*kvLedger).commitHash = nil 182 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{}) 183 184 commitHash, err = ledger.(*kvLedger).lastPersistedCommitHash() 185 require.NoError(t, err) 186 require.Equal(t, commitHash, ledger.(*kvLedger).commitHash) 187 require.Equal(t, len(commitHash), 0) 188 189 } 190 191 func TestKVLedgerBlockStorageWithPvtdata(t *testing.T) { 192 t.Skip() 193 conf, cleanup := testConfig(t) 194 defer cleanup() 195 provider := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 196 defer provider.Close() 197 198 bg, gb := testutil.NewBlockGenerator(t, "testLedger", false) 199 gbHash := protoutil.BlockHeaderHash(gb.Header) 200 ledger, err := provider.Create(gb) 201 require.NoError(t, err) 202 defer ledger.Close() 203 204 bcInfo, _ := ledger.GetBlockchainInfo() 205 require.Equal(t, &common.BlockchainInfo{ 206 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil, 207 }, bcInfo) 208 209 txid := util.GenerateUUID() 210 simulator, _ := ledger.NewTxSimulator(txid) 211 simulator.SetState("ns1", "key1", []byte("value1")) 212 simulator.SetPrivateData("ns1", "coll1", "key2", []byte("value2")) 213 simulator.SetPrivateData("ns1", "coll2", "key2", []byte("value3")) 214 simulator.Done() 215 simRes, _ := simulator.GetTxSimulationResults() 216 pubSimBytes, _ := simRes.GetPubSimulationBytes() 217 block1 := bg.NextBlockWithTxid([][]byte{pubSimBytes}, []string{txid}) 218 require.NoError(t, ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{})) 219 220 bcInfo, _ = ledger.GetBlockchainInfo() 221 block1Hash := protoutil.BlockHeaderHash(block1.Header) 222 require.Equal(t, &common.BlockchainInfo{ 223 Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash, 224 }, bcInfo) 225 226 txid = util.GenerateUUID() 227 simulator, _ = ledger.NewTxSimulator(txid) 228 simulator.SetState("ns1", "key1", []byte("value4")) 229 simulator.SetState("ns1", "key2", []byte("value5")) 230 simulator.SetState("ns1", "key3", []byte("value6")) 231 simulator.Done() 232 simRes, _ = simulator.GetTxSimulationResults() 233 pubSimBytes, _ = simRes.GetPubSimulationBytes() 234 block2 := bg.NextBlock([][]byte{pubSimBytes}) 235 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{}) 236 237 bcInfo, _ = ledger.GetBlockchainInfo() 238 block2Hash := protoutil.BlockHeaderHash(block2.Header) 239 require.Equal(t, &common.BlockchainInfo{ 240 Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash, 241 }, bcInfo) 242 243 pvtdataAndBlock, _ := ledger.GetPvtDataAndBlockByNum(0, nil) 244 require.Equal(t, gb, pvtdataAndBlock.Block) 245 require.Nil(t, pvtdataAndBlock.PvtData) 246 247 pvtdataAndBlock, _ = ledger.GetPvtDataAndBlockByNum(1, nil) 248 require.Equal(t, block1, pvtdataAndBlock.Block) 249 require.NotNil(t, pvtdataAndBlock.PvtData) 250 require.True(t, pvtdataAndBlock.PvtData[0].Has("ns1", "coll1")) 251 require.True(t, pvtdataAndBlock.PvtData[0].Has("ns1", "coll2")) 252 253 pvtdataAndBlock, _ = ledger.GetPvtDataAndBlockByNum(2, nil) 254 require.Equal(t, block2, pvtdataAndBlock.Block) 255 require.Nil(t, pvtdataAndBlock.PvtData) 256 } 257 258 func TestKVLedgerDBRecovery(t *testing.T) { 259 conf, cleanup := testConfig(t) 260 defer cleanup() 261 nsCollBtlConfs := []*nsCollBtlConfig{ 262 { 263 namespace: "ns", 264 btlConfig: map[string]uint64{"coll": 0}, 265 }, 266 } 267 provider1 := testutilNewProviderWithCollectionConfig( 268 t, 269 nsCollBtlConfs, 270 conf, 271 ) 272 defer provider1.Close() 273 274 testLedgerid := "testLedger" 275 bg, gb := testutil.NewBlockGenerator(t, testLedgerid, false) 276 ledger1, err := provider1.Create(gb) 277 require.NoError(t, err) 278 defer ledger1.Close() 279 280 gbHash := protoutil.BlockHeaderHash(gb.Header) 281 checkBCSummaryForTest(t, ledger1, 282 &bcSummary{ 283 bcInfo: &common.BlockchainInfo{Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil}, 284 }, 285 ) 286 287 // creating and committing the second data block 288 blockAndPvtdata1 := prepareNextBlockForTest(t, ledger1, bg, "SimulateForBlk1", 289 map[string]string{"key1": "value1.1", "key2": "value2.1", "key3": "value3.1"}, 290 map[string]string{"key1": "pvtValue1.1", "key2": "pvtValue2.1", "key3": "pvtValue3.1"}) 291 require.NoError(t, ledger1.CommitLegacy(blockAndPvtdata1, &lgr.CommitOptions{})) 292 checkBCSummaryForTest(t, ledger1, 293 &bcSummary{ 294 bcInfo: &common.BlockchainInfo{Height: 2, 295 CurrentBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata1.Block.Header), 296 PreviousBlockHash: gbHash}, 297 }, 298 ) 299 300 //====================================================================================== 301 // SCENARIO 1: peer writes the second block to the block storage and fails 302 // before committing the block to state DB and history DB 303 //====================================================================================== 304 blockAndPvtdata2 := prepareNextBlockForTest(t, ledger1, bg, "SimulateForBlk2", 305 map[string]string{"key1": "value1.2", "key2": "value2.2", "key3": "value3.2"}, 306 map[string]string{"key1": "pvtValue1.2", "key2": "pvtValue2.2", "key3": "pvtValue3.2"}) 307 308 _, _, err = ledger1.(*kvLedger).txmgr.ValidateAndPrepare(blockAndPvtdata2, true) 309 require.NoError(t, err) 310 require.NoError(t, ledger1.(*kvLedger).commitToPvtAndBlockStore(blockAndPvtdata2)) 311 312 // block storage should be as of block-2 but the state and history db should be as of block-1 313 checkBCSummaryForTest(t, ledger1, 314 &bcSummary{ 315 bcInfo: &common.BlockchainInfo{Height: 3, 316 CurrentBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata2.Block.Header), 317 PreviousBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata1.Block.Header)}, 318 319 stateDBSavePoint: uint64(1), 320 stateDBKVs: map[string]string{"key1": "value1.1", "key2": "value2.1", "key3": "value3.1"}, 321 stateDBPvtKVs: map[string]string{"key1": "pvtValue1.1", "key2": "pvtValue2.1", "key3": "pvtValue3.1"}, 322 323 historyDBSavePoint: uint64(1), 324 historyKey: "key1", 325 historyVals: []string{"value1.1"}, 326 }, 327 ) 328 // Now, assume that peer fails here before committing the transaction to the statedb and historydb 329 ledger1.Close() 330 provider1.Close() 331 332 // Here the peer comes online and calls NewKVLedger to get a handler for the ledger 333 // StateDB and HistoryDB should be recovered before returning from NewKVLedger call 334 provider2 := testutilNewProviderWithCollectionConfig( 335 t, 336 nsCollBtlConfs, 337 conf, 338 ) 339 defer provider2.Close() 340 ledger2, err := provider2.Open(testLedgerid) 341 require.NoError(t, err) 342 defer ledger2.Close() 343 checkBCSummaryForTest(t, ledger2, 344 &bcSummary{ 345 stateDBSavePoint: uint64(2), 346 stateDBKVs: map[string]string{"key1": "value1.2", "key2": "value2.2", "key3": "value3.2"}, 347 stateDBPvtKVs: map[string]string{"key1": "pvtValue1.2", "key2": "pvtValue2.2", "key3": "pvtValue3.2"}, 348 349 historyDBSavePoint: uint64(2), 350 historyKey: "key1", 351 historyVals: []string{"value1.2", "value1.1"}, 352 }, 353 ) 354 355 //====================================================================================== 356 // SCENARIO 2: peer fails after committing the third block to the block storage and state DB 357 // but before committing to history DB 358 //====================================================================================== 359 blockAndPvtdata3 := prepareNextBlockForTest(t, ledger2, bg, "SimulateForBlk3", 360 map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"}, 361 map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"}, 362 ) 363 _, _, err = ledger2.(*kvLedger).txmgr.ValidateAndPrepare(blockAndPvtdata3, true) 364 require.NoError(t, err) 365 require.NoError(t, ledger2.(*kvLedger).commitToPvtAndBlockStore(blockAndPvtdata3)) 366 // committing the transaction to state DB 367 require.NoError(t, ledger2.(*kvLedger).txmgr.Commit()) 368 369 // assume that peer fails here after committing the transaction to state DB but before history DB 370 checkBCSummaryForTest(t, ledger2, 371 &bcSummary{ 372 bcInfo: &common.BlockchainInfo{Height: 4, 373 CurrentBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata3.Block.Header), 374 PreviousBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata2.Block.Header)}, 375 376 stateDBSavePoint: uint64(3), 377 stateDBKVs: map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"}, 378 stateDBPvtKVs: map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"}, 379 380 historyDBSavePoint: uint64(2), 381 historyKey: "key1", 382 historyVals: []string{"value1.2", "value1.1"}, 383 }, 384 ) 385 ledger2.Close() 386 provider2.Close() 387 388 // we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger 389 // history DB should be recovered before returning from NewKVLedger call 390 provider3 := testutilNewProviderWithCollectionConfig( 391 t, 392 nsCollBtlConfs, 393 conf, 394 ) 395 defer provider3.Close() 396 ledger3, err := provider3.Open(testLedgerid) 397 require.NoError(t, err) 398 defer ledger3.Close() 399 400 checkBCSummaryForTest(t, ledger3, 401 &bcSummary{ 402 stateDBSavePoint: uint64(3), 403 stateDBKVs: map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"}, 404 stateDBPvtKVs: map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"}, 405 406 historyDBSavePoint: uint64(3), 407 historyKey: "key1", 408 historyVals: []string{"value1.3", "value1.2", "value1.1"}, 409 }, 410 ) 411 412 // Rare scenario 413 //====================================================================================== 414 // SCENARIO 3: peer fails after committing the fourth block to the block storgae 415 // and history DB but before committing to state DB 416 //====================================================================================== 417 blockAndPvtdata4 := prepareNextBlockForTest(t, ledger3, bg, "SimulateForBlk4", 418 map[string]string{"key1": "value1.4", "key2": "value2.4", "key3": "value3.4"}, 419 map[string]string{"key1": "pvtValue1.4", "key2": "pvtValue2.4", "key3": "pvtValue3.4"}, 420 ) 421 422 _, _, err = ledger3.(*kvLedger).txmgr.ValidateAndPrepare(blockAndPvtdata4, true) 423 require.NoError(t, err) 424 require.NoError(t, ledger3.(*kvLedger).commitToPvtAndBlockStore(blockAndPvtdata4)) 425 require.NoError(t, ledger3.(*kvLedger).historyDB.Commit(blockAndPvtdata4.Block)) 426 427 checkBCSummaryForTest(t, ledger3, 428 &bcSummary{ 429 bcInfo: &common.BlockchainInfo{Height: 5, 430 CurrentBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata4.Block.Header), 431 PreviousBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata3.Block.Header)}, 432 433 stateDBSavePoint: uint64(3), 434 stateDBKVs: map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"}, 435 stateDBPvtKVs: map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"}, 436 437 historyDBSavePoint: uint64(4), 438 historyKey: "key1", 439 historyVals: []string{"value1.4", "value1.3", "value1.2", "value1.1"}, 440 }, 441 ) 442 ledger3.Close() 443 provider3.Close() 444 445 // we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger 446 // state DB should be recovered before returning from NewKVLedger call 447 provider4 := testutilNewProviderWithCollectionConfig( 448 t, 449 nsCollBtlConfs, 450 conf, 451 ) 452 defer provider4.Close() 453 ledger4, err := provider4.Open(testLedgerid) 454 require.NoError(t, err) 455 defer ledger4.Close() 456 checkBCSummaryForTest(t, ledger4, 457 &bcSummary{ 458 stateDBSavePoint: uint64(4), 459 stateDBKVs: map[string]string{"key1": "value1.4", "key2": "value2.4", "key3": "value3.4"}, 460 stateDBPvtKVs: map[string]string{"key1": "pvtValue1.4", "key2": "pvtValue2.4", "key3": "pvtValue3.4"}, 461 462 historyDBSavePoint: uint64(4), 463 historyKey: "key1", 464 historyVals: []string{"value1.4", "value1.3", "value1.2", "value1.1"}, 465 }, 466 ) 467 } 468 469 func TestLedgerWithCouchDbEnabledWithBinaryAndJSONData(t *testing.T) { 470 conf, cleanup := testConfig(t) 471 defer cleanup() 472 provider := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 473 defer provider.Close() 474 bg, gb := testutil.NewBlockGenerator(t, "testLedger", false) 475 gbHash := protoutil.BlockHeaderHash(gb.Header) 476 ledger, err := provider.Create(gb) 477 require.NoError(t, err) 478 defer ledger.Close() 479 480 bcInfo, _ := ledger.GetBlockchainInfo() 481 require.Equal(t, &common.BlockchainInfo{ 482 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil}, bcInfo) 483 484 txid := util.GenerateUUID() 485 simulator, _ := ledger.NewTxSimulator(txid) 486 simulator.SetState("ns1", "key4", []byte("value1")) 487 simulator.SetState("ns1", "key5", []byte("value2")) 488 simulator.SetState("ns1", "key6", []byte("{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")) 489 simulator.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"AIR MAYBE\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")) 490 simulator.Done() 491 simRes, _ := simulator.GetTxSimulationResults() 492 pubSimBytes, _ := simRes.GetPubSimulationBytes() 493 block1 := bg.NextBlock([][]byte{pubSimBytes}) 494 495 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{}) 496 497 bcInfo, _ = ledger.GetBlockchainInfo() 498 block1Hash := protoutil.BlockHeaderHash(block1.Header) 499 require.Equal(t, &common.BlockchainInfo{ 500 Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash}, bcInfo) 501 502 simulationResults := [][]byte{} 503 txid = util.GenerateUUID() 504 simulator, _ = ledger.NewTxSimulator(txid) 505 simulator.SetState("ns1", "key4", []byte("value3")) 506 simulator.SetState("ns1", "key5", []byte("{\"shipmentID\":\"161003PKC7500\",\"customsInvoice\":{\"methodOfTransport\":\"AIR FREIGHT\",\"invoiceNumber\":\"00091623\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")) 507 simulator.SetState("ns1", "key6", []byte("value4")) 508 simulator.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")) 509 simulator.SetState("ns1", "key8", []byte("{\"shipmentID\":\"161003PKC7700\",\"customsInvoice\":{\"methodOfTransport\":\"SHIP\",\"invoiceNumber\":\"00091625\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")) 510 simulator.Done() 511 simRes, _ = simulator.GetTxSimulationResults() 512 pubSimBytes, _ = simRes.GetPubSimulationBytes() 513 simulationResults = append(simulationResults, pubSimBytes) 514 //add a 2nd transaction 515 txid2 := util.GenerateUUID() 516 simulator2, _ := ledger.NewTxSimulator(txid2) 517 simulator2.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"TRAIN\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")) 518 simulator2.SetState("ns1", "key9", []byte("value5")) 519 simulator2.SetState("ns1", "key10", []byte("{\"shipmentID\":\"261003PKC8000\",\"customsInvoice\":{\"methodOfTransport\":\"DONKEY\",\"invoiceNumber\":\"00091626\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")) 520 simulator2.Done() 521 simRes2, _ := simulator2.GetTxSimulationResults() 522 pubSimBytes2, _ := simRes2.GetPubSimulationBytes() 523 simulationResults = append(simulationResults, pubSimBytes2) 524 525 block2 := bg.NextBlock(simulationResults) 526 ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{}) 527 528 bcInfo, _ = ledger.GetBlockchainInfo() 529 block2Hash := protoutil.BlockHeaderHash(block2.Header) 530 require.Equal(t, &common.BlockchainInfo{ 531 Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash, 532 }, bcInfo) 533 534 b0, _ := ledger.GetBlockByHash(gbHash) 535 require.True(t, proto.Equal(b0, gb), "proto messages are not equal") 536 537 b1, _ := ledger.GetBlockByHash(block1Hash) 538 require.True(t, proto.Equal(b1, block1), "proto messages are not equal") 539 540 b2, _ := ledger.GetBlockByHash(block2Hash) 541 require.True(t, proto.Equal(b2, block2), "proto messages are not equal") 542 543 b0, _ = ledger.GetBlockByNumber(0) 544 require.True(t, proto.Equal(b0, gb), "proto messages are not equal") 545 546 b1, _ = ledger.GetBlockByNumber(1) 547 require.True(t, proto.Equal(b1, block1), "proto messages are not equal") 548 549 b2, _ = ledger.GetBlockByNumber(2) 550 require.True(t, proto.Equal(b2, block2), "proto messages are not equal") 551 552 //Similar test has been pushed down to historyleveldb_test.go as well 553 if conf.HistoryDBConfig.Enabled { 554 logger.Debugf("History is enabled\n") 555 qhistory, err := ledger.NewHistoryQueryExecutor() 556 require.NoError(t, err, "Error when trying to retrieve history database executor") 557 558 itr, err2 := qhistory.GetHistoryForKey("ns1", "key7") 559 require.NoError(t, err2, "Error upon GetHistoryForKey") 560 561 var retrievedValue []byte 562 count := 0 563 for { 564 kmod, _ := itr.Next() 565 if kmod == nil { 566 break 567 } 568 retrievedValue = kmod.(*queryresult.KeyModification).Value 569 count++ 570 } 571 require.Equal(t, 3, count) 572 // test the last value in the history matches the first value set for key7 573 expectedValue := []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"AIR MAYBE\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}") 574 require.Equal(t, expectedValue, retrievedValue) 575 576 } 577 } 578 579 func TestPvtDataAPIs(t *testing.T) { 580 conf, cleanup := testConfig(t) 581 defer cleanup() 582 provider := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 583 defer provider.Close() 584 585 ledgerID := "testLedger" 586 bg, gb := testutil.NewBlockGenerator(t, ledgerID, false) 587 gbHash := protoutil.BlockHeaderHash(gb.Header) 588 lgr, err := provider.Create(gb) 589 require.NoError(t, err) 590 defer lgr.Close() 591 lgr.(*kvLedger).pvtdataStore.Init(btlPolicyForSampleData()) 592 593 bcInfo, _ := lgr.GetBlockchainInfo() 594 require.Equal(t, &common.BlockchainInfo{ 595 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil, 596 }, bcInfo) 597 598 kvlgr := lgr.(*kvLedger) 599 600 sampleData := sampleDataWithPvtdataForSelectiveTx(t, bg) 601 for _, sampleDatum := range sampleData { 602 require.NoError(t, kvlgr.commitToPvtAndBlockStore(sampleDatum)) 603 } 604 605 // block 2 has no pvt data 606 pvtdata, err := lgr.GetPvtDataByNum(2, nil) 607 require.NoError(t, err) 608 require.Nil(t, pvtdata) 609 610 // block 5 has no pvt data 611 pvtdata, err = lgr.GetPvtDataByNum(5, nil) 612 require.NoError(t, err) 613 require.Equal(t, 0, len(pvtdata)) 614 615 // block 3 has pvt data for tx 3, 5 and 6. Though the tx 6 616 // is marked as invalid in the block, the pvtData should 617 // have been stored 618 pvtdata, err = lgr.GetPvtDataByNum(3, nil) 619 require.NoError(t, err) 620 require.Equal(t, 3, len(pvtdata)) 621 require.Equal(t, uint64(3), pvtdata[0].SeqInBlock) 622 require.Equal(t, uint64(5), pvtdata[1].SeqInBlock) 623 require.Equal(t, uint64(6), pvtdata[2].SeqInBlock) 624 625 // block 4 has pvt data for tx 4 and 6 only 626 pvtdata, err = lgr.GetPvtDataByNum(4, nil) 627 require.NoError(t, err) 628 require.Equal(t, 2, len(pvtdata)) 629 require.Equal(t, uint64(4), pvtdata[0].SeqInBlock) 630 require.Equal(t, uint64(6), pvtdata[1].SeqInBlock) 631 632 blockAndPvtdata, err := lgr.GetPvtDataAndBlockByNum(3, nil) 633 require.NoError(t, err) 634 require.True(t, proto.Equal(sampleData[2].Block, blockAndPvtdata.Block)) 635 636 blockAndPvtdata, err = lgr.GetPvtDataAndBlockByNum(4, nil) 637 require.NoError(t, err) 638 require.True(t, proto.Equal(sampleData[3].Block, blockAndPvtdata.Block)) 639 640 // pvt data retrieval for block 3 with filter should return filtered pvtdata 641 filter := ledger.NewPvtNsCollFilter() 642 filter.Add("ns-1", "coll-1") 643 blockAndPvtdata, err = lgr.GetPvtDataAndBlockByNum(4, filter) 644 require.NoError(t, err) 645 require.Equal(t, sampleData[3].Block, blockAndPvtdata.Block) 646 // two transactions should be present 647 require.Equal(t, 2, len(blockAndPvtdata.PvtData)) 648 // both tran number 4 and 6 should have only one collection because of filter 649 require.Equal(t, 1, len(blockAndPvtdata.PvtData[4].WriteSet.NsPvtRwset)) 650 require.Equal(t, 1, len(blockAndPvtdata.PvtData[6].WriteSet.NsPvtRwset)) 651 // any other transaction entry should be nil 652 require.Nil(t, blockAndPvtdata.PvtData[2]) 653 654 // test missing data retrieval in the presence of invalid tx. Block 6 had 655 // missing data (for tx4 and tx5). Though tx5 was marked as invalid tx, 656 // both tx4 and tx5 missing data should be returned 657 expectedMissingDataInfo := make(ledger.MissingPvtDataInfo) 658 expectedMissingDataInfo.Add(6, 4, "ns-4", "coll-4") 659 expectedMissingDataInfo.Add(6, 5, "ns-5", "coll-5") 660 missingDataInfo, err := lgr.(*kvLedger).GetMissingPvtDataInfoForMostRecentBlocks(1) 661 require.NoError(t, err) 662 require.Equal(t, expectedMissingDataInfo, missingDataInfo) 663 } 664 665 func TestCrashAfterPvtdataStoreCommit(t *testing.T) { 666 conf, cleanup := testConfig(t) 667 defer cleanup() 668 ccInfoProvider := &mock.DeployedChaincodeInfoProvider{} 669 ccInfoProvider.CollectionInfoReturns(&peer.StaticCollectionConfig{BlockToLive: 0}, nil) 670 provider := testutilNewProvider(conf, t, ccInfoProvider) 671 defer provider.Close() 672 673 ledgerID := "testLedger" 674 bg, gb := testutil.NewBlockGenerator(t, ledgerID, false) 675 gbHash := protoutil.BlockHeaderHash(gb.Header) 676 lgr, err := provider.Create(gb) 677 require.NoError(t, err) 678 defer lgr.Close() 679 680 bcInfo, _ := lgr.GetBlockchainInfo() 681 require.Equal(t, &common.BlockchainInfo{ 682 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil, 683 }, bcInfo) 684 685 sampleData := sampleDataWithPvtdataForAllTxs(t, bg) 686 dataBeforeCrash := sampleData[0:3] 687 dataAtCrash := sampleData[3] 688 689 for _, sampleDatum := range dataBeforeCrash { 690 require.NoError(t, lgr.(*kvLedger).commitToPvtAndBlockStore(sampleDatum)) 691 } 692 blockNumAtCrash := dataAtCrash.Block.Header.Number 693 var pvtdataAtCrash []*ledger.TxPvtData 694 for _, p := range dataAtCrash.PvtData { 695 pvtdataAtCrash = append(pvtdataAtCrash, p) 696 } 697 // call Commit on pvt data store and mimic a crash before committing the block to block store 698 lgr.(*kvLedger).pvtdataStore.Commit(blockNumAtCrash, pvtdataAtCrash, nil) 699 700 // Now, assume that peer fails here before committing the block to blockstore. 701 lgr.Close() 702 provider.Close() 703 704 // mimic peer restart 705 provider1 := testutilNewProvider(conf, t, ccInfoProvider) 706 defer provider1.Close() 707 lgr1, err := provider1.Open(ledgerID) 708 require.NoError(t, err) 709 defer lgr1.Close() 710 711 isPvtStoreAhead, err := lgr1.(*kvLedger).isPvtDataStoreAheadOfBlockStore() 712 require.NoError(t, err) 713 require.True(t, isPvtStoreAhead) 714 715 // When starting the storage after a crash, we should be able to fetch the pvtData from pvtStore 716 testVerifyPvtData(t, lgr1, blockNumAtCrash, dataAtCrash.PvtData) 717 bcInfo, err = lgr.GetBlockchainInfo() 718 require.NoError(t, err) 719 require.Equal(t, blockNumAtCrash, bcInfo.Height) 720 721 // we should be able to write the last block again 722 // to ensure that the pvtdataStore is not updated, we send a different pvtData for 723 // the same block such that we can retrieve the pvtData and compare. 724 expectedPvtData := dataAtCrash.PvtData 725 dataAtCrash.PvtData = make(ledger.TxPvtDataMap) 726 dataAtCrash.PvtData[0] = &ledger.TxPvtData{ 727 SeqInBlock: 0, 728 WriteSet: &rwset.TxPvtReadWriteSet{ 729 NsPvtRwset: []*rwset.NsPvtReadWriteSet{ 730 { 731 Namespace: "ns-1", 732 CollectionPvtRwset: []*rwset.CollectionPvtReadWriteSet{ 733 { 734 CollectionName: "coll-1", 735 Rwset: []byte("pvtdata"), 736 }, 737 }, 738 }, 739 }, 740 }, 741 } 742 require.NoError(t, lgr1.(*kvLedger).commitToPvtAndBlockStore(dataAtCrash)) 743 testVerifyPvtData(t, lgr1, blockNumAtCrash, expectedPvtData) 744 bcInfo, err = lgr1.GetBlockchainInfo() 745 require.NoError(t, err) 746 require.Equal(t, blockNumAtCrash+1, bcInfo.Height) 747 748 isPvtStoreAhead, err = lgr1.(*kvLedger).isPvtDataStoreAheadOfBlockStore() 749 require.NoError(t, err) 750 require.False(t, isPvtStoreAhead) 751 } 752 753 func testVerifyPvtData(t *testing.T, ledger ledger.PeerLedger, blockNum uint64, expectedPvtData lgr.TxPvtDataMap) { 754 pvtdata, err := ledger.GetPvtDataByNum(blockNum, nil) 755 require.NoError(t, err) 756 constructed := constructPvtdataMap(pvtdata) 757 require.Equal(t, len(expectedPvtData), len(constructed)) 758 for k, v := range expectedPvtData { 759 ov, ok := constructed[k] 760 require.True(t, ok) 761 require.Equal(t, v.SeqInBlock, ov.SeqInBlock) 762 require.True(t, proto.Equal(v.WriteSet, ov.WriteSet)) 763 } 764 } 765 766 func TestPvtStoreAheadOfBlockStore(t *testing.T) { 767 conf, cleanup := testConfig(t) 768 defer cleanup() 769 ccInfoProvider := &mock.DeployedChaincodeInfoProvider{} 770 ccInfoProvider.CollectionInfoReturns(&peer.StaticCollectionConfig{BlockToLive: 0}, nil) 771 provider := testutilNewProvider(conf, t, ccInfoProvider) 772 defer provider.Close() 773 774 ledgerID := "testLedger" 775 bg, gb := testutil.NewBlockGenerator(t, ledgerID, false) 776 gbHash := protoutil.BlockHeaderHash(gb.Header) 777 lgr, err := provider.Create(gb) 778 require.NoError(t, err) 779 defer lgr.Close() 780 781 bcInfo, _ := lgr.GetBlockchainInfo() 782 require.Equal(t, &common.BlockchainInfo{ 783 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil, 784 }, bcInfo) 785 786 // when both stores contain genesis block only, isPvtstoreAheadOfBlockstore should be false 787 kvlgr := lgr.(*kvLedger) 788 isPvtStoreAhead, err := kvlgr.isPvtDataStoreAheadOfBlockStore() 789 require.NoError(t, err) 790 require.False(t, isPvtStoreAhead) 791 792 sampleData := sampleDataWithPvtdataForSelectiveTx(t, bg) 793 for _, d := range sampleData[0:9] { // commit block number 0 to 8 794 require.NoError(t, kvlgr.commitToPvtAndBlockStore(d)) 795 } 796 797 isPvtStoreAhead, err = kvlgr.isPvtDataStoreAheadOfBlockStore() 798 require.NoError(t, err) 799 require.False(t, isPvtStoreAhead) 800 801 // close and reopen. 802 lgr.Close() 803 provider.Close() 804 805 provider1 := testutilNewProvider(conf, t, ccInfoProvider) 806 defer provider1.Close() 807 lgr1, err := provider1.Open(ledgerID) 808 require.NoError(t, err) 809 defer lgr1.Close() 810 kvlgr = lgr1.(*kvLedger) 811 812 // as both stores are at the same block height, isPvtstoreAheadOfBlockstore should be false 813 info, err := lgr1.GetBlockchainInfo() 814 require.NoError(t, err) 815 require.Equal(t, uint64(10), info.Height) 816 pvtStoreHt, err := kvlgr.pvtdataStore.LastCommittedBlockHeight() 817 require.NoError(t, err) 818 require.Equal(t, uint64(10), pvtStoreHt) 819 isPvtStoreAhead, err = kvlgr.isPvtDataStoreAheadOfBlockStore() 820 require.NoError(t, err) 821 require.False(t, isPvtStoreAhead) 822 823 lastBlkAndPvtData := sampleData[9] 824 // Add the last block directly to the pvtdataStore but not to blockstore. This would make 825 // the pvtdatastore height greater than the block store height. 826 validTxPvtData, validTxMissingPvtData := constructPvtDataAndMissingData(lastBlkAndPvtData) 827 err = kvlgr.pvtdataStore.Commit(lastBlkAndPvtData.Block.Header.Number, validTxPvtData, validTxMissingPvtData) 828 require.NoError(t, err) 829 830 // close and reopen. 831 lgr1.Close() 832 provider1.Close() 833 834 provider2 := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 835 defer provider2.Close() 836 lgr2, err := provider2.Open(ledgerID) 837 require.NoError(t, err) 838 defer lgr2.Close() 839 kvlgr = lgr2.(*kvLedger) 840 841 // pvtdataStore should be ahead of blockstore 842 info, err = lgr2.GetBlockchainInfo() 843 require.NoError(t, err) 844 require.Equal(t, uint64(10), info.Height) 845 pvtStoreHt, err = kvlgr.pvtdataStore.LastCommittedBlockHeight() 846 require.NoError(t, err) 847 require.Equal(t, uint64(11), pvtStoreHt) 848 isPvtStoreAhead, err = kvlgr.isPvtDataStoreAheadOfBlockStore() 849 require.NoError(t, err) 850 require.True(t, isPvtStoreAhead) 851 852 // bring the height of BlockStore equal to pvtdataStore 853 require.NoError(t, kvlgr.commitToPvtAndBlockStore(lastBlkAndPvtData)) 854 info, err = lgr2.GetBlockchainInfo() 855 require.NoError(t, err) 856 require.Equal(t, uint64(11), info.Height) 857 pvtStoreHt, err = kvlgr.pvtdataStore.LastCommittedBlockHeight() 858 require.NoError(t, err) 859 require.Equal(t, uint64(11), pvtStoreHt) 860 isPvtStoreAhead, err = kvlgr.isPvtDataStoreAheadOfBlockStore() 861 require.NoError(t, err) 862 require.False(t, isPvtStoreAhead) 863 } 864 865 func TestCommitToPvtAndBlockstoreError(t *testing.T) { 866 conf, cleanup := testConfig(t) 867 defer cleanup() 868 ccInfoProvider := &mock.DeployedChaincodeInfoProvider{} 869 ccInfoProvider.CollectionInfoReturns(&peer.StaticCollectionConfig{BlockToLive: 0}, nil) 870 provider1 := testutilNewProvider(conf, t, ccInfoProvider) 871 defer provider1.Close() 872 873 ledgerID := "testLedger" 874 bg, gb := testutil.NewBlockGenerator(t, ledgerID, false) 875 gbHash := protoutil.BlockHeaderHash(gb.Header) 876 lgr1, err := provider1.Create(gb) 877 require.NoError(t, err) 878 defer lgr1.Close() 879 880 bcInfo, _ := lgr1.GetBlockchainInfo() 881 require.Equal(t, &common.BlockchainInfo{ 882 Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil, 883 }, bcInfo) 884 885 kvlgr := lgr1.(*kvLedger) 886 sampleData := sampleDataWithPvtdataForSelectiveTx(t, bg) 887 for _, d := range sampleData[0:9] { // commit block number 1 to 9 888 require.NoError(t, kvlgr.commitToPvtAndBlockStore(d)) 889 } 890 891 // try to write the last block again. The function should return an 892 // error from the private data store. 893 err = kvlgr.commitToPvtAndBlockStore(sampleData[8]) // block 9 894 require.EqualError(t, err, "Expected block number=10, received block number=9") 895 896 lastBlkAndPvtData := sampleData[9] // block 10 897 // Add the block directly to blockstore 898 kvlgr.blockStore.AddBlock(lastBlkAndPvtData.Block) 899 // Adding the same block should cause passing on the error caused by the block storgae 900 err = kvlgr.commitToPvtAndBlockStore(lastBlkAndPvtData) 901 require.EqualError(t, err, "block number should have been 11 but was 10") 902 // At the end, the pvt store status should be changed 903 pvtStoreCommitHt, err := kvlgr.pvtdataStore.LastCommittedBlockHeight() 904 require.NoError(t, err) 905 require.Equal(t, uint64(11), pvtStoreCommitHt) 906 } 907 908 func sampleDataWithPvtdataForSelectiveTx(t *testing.T, bg *testutil.BlockGenerator) []*ledger.BlockAndPvtData { 909 var blockAndpvtdata []*ledger.BlockAndPvtData 910 blocks := bg.NextTestBlocks(10) 911 for i := 0; i < 10; i++ { 912 blockAndpvtdata = append(blockAndpvtdata, &ledger.BlockAndPvtData{Block: blocks[i]}) 913 } 914 915 // txNum 3, 5, 6 in block 2 has pvtdata but txNum 6 is invalid 916 blockAndpvtdata[2].PvtData = samplePvtData(t, []uint64{3, 5, 6}) 917 txFilter := txflags.ValidationFlags(blockAndpvtdata[2].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 918 txFilter.SetFlag(6, pb.TxValidationCode_INVALID_WRITESET) 919 blockAndpvtdata[2].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txFilter 920 921 // txNum 4, 6 in block 3 has pvtdata 922 blockAndpvtdata[3].PvtData = samplePvtData(t, []uint64{4, 6}) 923 924 // txNum 4, 5 in block 5 has missing pvt data but txNum 5 is invalid 925 missingData := make(ledger.TxMissingPvtDataMap) 926 missingData.Add(4, "ns-4", "coll-4", true) 927 missingData.Add(5, "ns-5", "coll-5", true) 928 blockAndpvtdata[5].MissingPvtData = missingData 929 txFilter = txflags.ValidationFlags(blockAndpvtdata[5].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 930 txFilter.SetFlag(5, pb.TxValidationCode_INVALID_WRITESET) 931 blockAndpvtdata[5].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txFilter 932 933 return blockAndpvtdata 934 } 935 936 func sampleDataWithPvtdataForAllTxs(t *testing.T, bg *testutil.BlockGenerator) []*ledger.BlockAndPvtData { 937 var blockAndpvtdata []*ledger.BlockAndPvtData 938 blocks := bg.NextTestBlocks(10) 939 for i := 0; i < 10; i++ { 940 blockAndpvtdata = append(blockAndpvtdata, 941 &ledger.BlockAndPvtData{ 942 Block: blocks[i], 943 PvtData: samplePvtData(t, []uint64{uint64(i), uint64(i + 1)}), 944 }, 945 ) 946 } 947 return blockAndpvtdata 948 } 949 950 func samplePvtData(t *testing.T, txNums []uint64) map[uint64]*ledger.TxPvtData { 951 pvtWriteSet := &rwset.TxPvtReadWriteSet{DataModel: rwset.TxReadWriteSet_KV} 952 pvtWriteSet.NsPvtRwset = []*rwset.NsPvtReadWriteSet{ 953 { 954 Namespace: "ns-1", 955 CollectionPvtRwset: []*rwset.CollectionPvtReadWriteSet{ 956 { 957 CollectionName: "coll-1", 958 Rwset: []byte("RandomBytes-PvtRWSet-ns1-coll1"), 959 }, 960 { 961 CollectionName: "coll-2", 962 Rwset: []byte("RandomBytes-PvtRWSet-ns1-coll2"), 963 }, 964 }, 965 }, 966 } 967 var pvtData []*ledger.TxPvtData 968 for _, txNum := range txNums { 969 pvtData = append(pvtData, &ledger.TxPvtData{SeqInBlock: txNum, WriteSet: pvtWriteSet}) 970 } 971 return constructPvtdataMap(pvtData) 972 } 973 974 func btlPolicyForSampleData() pvtdatapolicy.BTLPolicy { 975 return btltestutil.SampleBTLPolicy( 976 map[[2]string]uint64{ 977 {"ns-1", "coll-1"}: 0, 978 {"ns-1", "coll-2"}: 0, 979 }, 980 ) 981 } 982 983 func prepareNextBlockForTest(t *testing.T, l lgr.PeerLedger, bg *testutil.BlockGenerator, 984 txid string, pubKVs map[string]string, pvtKVs map[string]string) *lgr.BlockAndPvtData { 985 simulator, _ := l.NewTxSimulator(txid) 986 //simulating transaction 987 for k, v := range pubKVs { 988 simulator.SetState("ns", k, []byte(v)) 989 } 990 for k, v := range pvtKVs { 991 simulator.SetPrivateData("ns", "coll", k, []byte(v)) 992 } 993 simulator.Done() 994 simRes, _ := simulator.GetTxSimulationResults() 995 pubSimBytes, _ := simRes.GetPubSimulationBytes() 996 block := bg.NextBlock([][]byte{pubSimBytes}) 997 blkAndPvtData := &lgr.BlockAndPvtData{Block: block} 998 if len(pvtKVs) != 0 { 999 blkAndPvtData.PvtData = lgr.TxPvtDataMap{ 1000 0: {SeqInBlock: 0, WriteSet: simRes.PvtSimulationResults}, 1001 } 1002 } 1003 return blkAndPvtData 1004 } 1005 1006 func checkBCSummaryForTest(t *testing.T, l lgr.PeerLedger, expectedBCSummary *bcSummary) { 1007 if expectedBCSummary.bcInfo != nil { 1008 actualBCInfo, _ := l.GetBlockchainInfo() 1009 require.Equal(t, expectedBCSummary.bcInfo, actualBCInfo) 1010 } 1011 1012 if expectedBCSummary.stateDBSavePoint != 0 { 1013 actualStateDBSavepoint, _ := l.(*kvLedger).txmgr.GetLastSavepoint() 1014 require.Equal(t, expectedBCSummary.stateDBSavePoint, actualStateDBSavepoint.BlockNum) 1015 } 1016 1017 if !(expectedBCSummary.stateDBKVs == nil && expectedBCSummary.stateDBPvtKVs == nil) { 1018 checkStateDBForTest(t, l, expectedBCSummary.stateDBKVs, expectedBCSummary.stateDBPvtKVs) 1019 } 1020 1021 if expectedBCSummary.historyDBSavePoint != 0 { 1022 actualHistoryDBSavepoint, _ := l.(*kvLedger).historyDB.GetLastSavepoint() 1023 require.Equal(t, expectedBCSummary.historyDBSavePoint, actualHistoryDBSavepoint.BlockNum) 1024 } 1025 1026 if expectedBCSummary.historyKey != "" { 1027 checkHistoryDBForTest(t, l, expectedBCSummary.historyKey, expectedBCSummary.historyVals) 1028 } 1029 } 1030 1031 func checkStateDBForTest(t *testing.T, l lgr.PeerLedger, expectedKVs map[string]string, expectedPvtKVs map[string]string) { 1032 simulator, _ := l.NewTxSimulator("checkStateDBForTest") 1033 defer simulator.Done() 1034 for expectedKey, expectedVal := range expectedKVs { 1035 actualVal, _ := simulator.GetState("ns", expectedKey) 1036 require.Equal(t, []byte(expectedVal), actualVal) 1037 } 1038 1039 for expectedPvtKey, expectedPvtVal := range expectedPvtKVs { 1040 actualPvtVal, _ := simulator.GetPrivateData("ns", "coll", expectedPvtKey) 1041 require.Equal(t, []byte(expectedPvtVal), actualPvtVal) 1042 } 1043 } 1044 1045 func checkHistoryDBForTest(t *testing.T, l lgr.PeerLedger, key string, expectedVals []string) { 1046 qhistory, _ := l.NewHistoryQueryExecutor() 1047 itr, _ := qhistory.GetHistoryForKey("ns", key) 1048 var actualVals []string 1049 for { 1050 kmod, err := itr.Next() 1051 require.NoError(t, err, "Error upon Next()") 1052 if kmod == nil { 1053 break 1054 } 1055 retrievedValue := kmod.(*queryresult.KeyModification).Value 1056 actualVals = append(actualVals, string(retrievedValue)) 1057 } 1058 require.Equal(t, expectedVals, actualVals) 1059 } 1060 1061 type bcSummary struct { 1062 bcInfo *common.BlockchainInfo 1063 stateDBSavePoint uint64 1064 stateDBKVs map[string]string 1065 stateDBPvtKVs map[string]string 1066 historyDBSavePoint uint64 1067 historyKey string 1068 historyVals []string 1069 }