github.com/yimialmonte/fabric@v2.1.1+incompatible/core/peer/deliverevents_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package peer 8 9 import ( 10 "context" 11 "fmt" 12 "io" 13 "strings" 14 "sync" 15 "testing" 16 "time" 17 18 "github.com/golang/protobuf/proto" 19 "github.com/hyperledger/fabric-protos-go/common" 20 "github.com/hyperledger/fabric-protos-go/orderer" 21 "github.com/hyperledger/fabric-protos-go/peer" 22 "github.com/hyperledger/fabric/common/deliver" 23 "github.com/hyperledger/fabric/common/ledger/blockledger" 24 "github.com/hyperledger/fabric/common/metrics/disabled" 25 "github.com/hyperledger/fabric/common/policies" 26 "github.com/hyperledger/fabric/common/util" 27 "github.com/hyperledger/fabric/core/ledger" 28 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil" 29 fake "github.com/hyperledger/fabric/core/peer/mock" 30 "github.com/hyperledger/fabric/protoutil" 31 "github.com/stretchr/testify/assert" 32 "github.com/stretchr/testify/mock" 33 "google.golang.org/grpc/metadata" 34 peer2 "google.golang.org/grpc/peer" 35 ) 36 37 // defaultPolicyCheckerProvider policy checker provider used by default, 38 // generates policy checker which always accepts regardless of arguments 39 // passed in 40 var defaultPolicyCheckerProvider = func(_ string) deliver.PolicyCheckerFunc { 41 return func(_ *common.Envelope, _ string) error { 42 return nil 43 } 44 } 45 46 //go:generate counterfeiter -o mock/peer_ledger.go -fake-name PeerLedger . peerLedger 47 48 type peerLedger interface { 49 ledger.PeerLedger 50 } 51 52 //go:generate counterfeiter -o mock/identity_deserializer_manager.go -fake-name IdentityDeserializerManager . identityDeserializerManager 53 54 type identityDeserializerManager interface { 55 IdentityDeserializerManager 56 } 57 58 //go:generate counterfeiter -o mock/collection_policy_checker.go -fake-name CollectionPolicyChecker . collectionPolicyChecker 59 60 type collectionPolicyChecker interface { 61 CollectionPolicyChecker 62 } 63 64 // mockIterator mock structure implementing 65 // the blockledger.Iterator interface 66 type mockIterator struct { 67 mock.Mock 68 } 69 70 func (m *mockIterator) Next() (*common.Block, common.Status) { 71 args := m.Called() 72 return args.Get(0).(*common.Block), args.Get(1).(common.Status) 73 } 74 75 func (m *mockIterator) ReadyChan() <-chan struct{} { 76 panic("implement me") 77 } 78 79 func (m *mockIterator) Close() { 80 81 } 82 83 // mockReader mock structure implementing 84 // the blockledger.Reader interface 85 type mockReader struct { 86 mock.Mock 87 } 88 89 func (m *mockReader) Iterator(startType *orderer.SeekPosition) (blockledger.Iterator, uint64) { 90 args := m.Called(startType) 91 return args.Get(0).(blockledger.Iterator), args.Get(1).(uint64) 92 } 93 94 func (m *mockReader) Height() uint64 { 95 args := m.Called() 96 return args.Get(0).(uint64) 97 } 98 99 // mockChainSupport 100 type mockChainSupport struct { 101 mock.Mock 102 } 103 104 func (m *mockChainSupport) Sequence() uint64 { 105 return m.Called().Get(0).(uint64) 106 } 107 108 func (m *mockChainSupport) Ledger() ledger.PeerLedger { 109 return m.Called().Get(0).(ledger.PeerLedger) 110 } 111 112 func (m *mockChainSupport) PolicyManager() policies.Manager { 113 panic("implement me") 114 } 115 116 func (m *mockChainSupport) Reader() blockledger.Reader { 117 return m.Called().Get(0).(blockledger.Reader) 118 } 119 120 func (*mockChainSupport) Errored() <-chan struct{} { 121 return make(chan struct{}) 122 } 123 124 // mockChainManager mock implementation of the ChainManager interface 125 type mockChainManager struct { 126 mock.Mock 127 } 128 129 func (m *mockChainManager) GetChain(chainID string) deliver.Chain { 130 args := m.Called(chainID) 131 return args.Get(0).(deliver.Chain) 132 } 133 134 // mockDeliverServer mock implementation of the Deliver_DeliverServer 135 type mockDeliverServer struct { 136 mock.Mock 137 } 138 139 func (m *mockDeliverServer) Context() context.Context { 140 return m.Called().Get(0).(context.Context) 141 } 142 143 func (m *mockDeliverServer) Recv() (*common.Envelope, error) { 144 args := m.Called() 145 if args.Get(0) == nil { 146 return nil, args.Error(1) 147 } 148 return args.Get(0).(*common.Envelope), args.Error(1) 149 } 150 151 func (m *mockDeliverServer) Send(response *peer.DeliverResponse) error { 152 args := m.Called(response) 153 return args.Error(0) 154 } 155 156 func (*mockDeliverServer) RecvMsg(m interface{}) error { 157 panic("implement me") 158 } 159 160 func (*mockDeliverServer) SendHeader(metadata.MD) error { 161 panic("implement me") 162 } 163 164 func (*mockDeliverServer) SendMsg(m interface{}) error { 165 panic("implement me") 166 } 167 168 func (*mockDeliverServer) SetHeader(metadata.MD) error { 169 panic("implement me") 170 } 171 172 func (*mockDeliverServer) SetTrailer(metadata.MD) { 173 panic("implement me") 174 } 175 176 type testConfig struct { 177 channelID string 178 eventName string 179 chaincodeName string 180 txID string 181 payload *common.Payload 182 *assert.Assertions 183 } 184 185 type testCase struct { 186 name string 187 prepare func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) 188 } 189 190 func TestFilteredBlockResponseSenderIsFiltered(t *testing.T) { 191 var fbrs interface{} = &filteredBlockResponseSender{} 192 filtered, ok := fbrs.(deliver.Filtered) 193 assert.True(t, ok, "should be filtered") 194 assert.True(t, filtered.IsFiltered(), "should return true from IsFiltered") 195 } 196 197 func TestEventsServer_DeliverFiltered(t *testing.T) { 198 tests := []testCase{ 199 { 200 name: "Testing deliver of the filtered block events", 201 prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 202 return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 203 wg.Add(2) 204 p := &peer2.Peer{} 205 chaincodeActionPayload, err := createChaincodeAction(config.chaincodeName, config.eventName, config.txID) 206 config.NoError(err) 207 208 chainManager := createDefaultSupportMamangerMock(config, chaincodeActionPayload, nil) 209 // setup mock deliver server 210 deliverServer := &mockDeliverServer{} 211 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 212 213 deliverServer.On("Recv").Return(&common.Envelope{ 214 Payload: protoutil.MarshalOrPanic(config.payload), 215 }, nil).Run(func(_ mock.Arguments) { 216 // once we are getting new message we need to mock 217 // Recv call to get io.EOF to stop the looping for 218 // next message and we can assert for the DeliverResponse 219 // value we are getting from the deliver server 220 deliverServer.Mock = mock.Mock{} 221 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 222 deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF) 223 deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) { 224 defer wg.Done() 225 response := args.Get(0).(*peer.DeliverResponse) 226 switch response.Type.(type) { 227 case *peer.DeliverResponse_Status: 228 config.Equal(common.Status_SUCCESS, response.GetStatus()) 229 case *peer.DeliverResponse_FilteredBlock: 230 block := response.GetFilteredBlock() 231 config.Equal(uint64(0), block.Number) 232 config.Equal(config.channelID, block.ChannelId) 233 config.Equal(1, len(block.FilteredTransactions)) 234 tx := block.FilteredTransactions[0] 235 config.Equal(config.txID, tx.Txid) 236 config.Equal(peer.TxValidationCode_VALID, tx.TxValidationCode) 237 config.Equal(common.HeaderType_ENDORSER_TRANSACTION, tx.Type) 238 transactionActions := tx.GetTransactionActions() 239 config.NotNil(transactionActions) 240 chaincodeActions := transactionActions.ChaincodeActions 241 config.Equal(1, len(chaincodeActions)) 242 config.Equal(config.eventName, chaincodeActions[0].ChaincodeEvent.EventName) 243 config.Equal(config.txID, chaincodeActions[0].ChaincodeEvent.TxId) 244 config.Equal(config.chaincodeName, chaincodeActions[0].ChaincodeEvent.ChaincodeId) 245 default: 246 config.FailNow("Unexpected response type") 247 } 248 }).Return(nil) 249 }) 250 251 return chainManager, deliverServer 252 } 253 }(testConfig{ 254 channelID: "testChainID", 255 eventName: "testEvent", 256 chaincodeName: "mycc", 257 txID: "testID", 258 payload: &common.Payload{ 259 Header: &common.Header{ 260 ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{ 261 ChannelId: "testChainID", 262 Timestamp: util.CreateUtcTimestamp(), 263 }), 264 SignatureHeader: protoutil.MarshalOrPanic(&common.SignatureHeader{}), 265 }, 266 Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{ 267 Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}}, 268 Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}}, 269 Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY, 270 }), 271 }, 272 Assertions: assert.New(t), 273 }), 274 }, 275 { 276 name: "Testing deliver of the filtered block events with nil chaincode action payload", 277 prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 278 return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 279 wg.Add(2) 280 p := &peer2.Peer{} 281 chainManager := createDefaultSupportMamangerMock(config, nil, nil) 282 283 // setup mock deliver server 284 deliverServer := &mockDeliverServer{} 285 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 286 287 deliverServer.On("Recv").Return(&common.Envelope{ 288 Payload: protoutil.MarshalOrPanic(config.payload), 289 }, nil).Run(func(_ mock.Arguments) { 290 // once we are getting new message we need to mock 291 // Recv call to get io.EOF to stop the looping for 292 // next message and we can assert for the DeliverResponse 293 // value we are getting from the deliver server 294 deliverServer.Mock = mock.Mock{} 295 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 296 deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF) 297 deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) { 298 defer wg.Done() 299 response := args.Get(0).(*peer.DeliverResponse) 300 switch response.Type.(type) { 301 case *peer.DeliverResponse_Status: 302 config.Equal(common.Status_SUCCESS, response.GetStatus()) 303 case *peer.DeliverResponse_FilteredBlock: 304 block := response.GetFilteredBlock() 305 config.Equal(uint64(0), block.Number) 306 config.Equal(config.channelID, block.ChannelId) 307 config.Equal(1, len(block.FilteredTransactions)) 308 tx := block.FilteredTransactions[0] 309 config.Equal(config.txID, tx.Txid) 310 config.Equal(peer.TxValidationCode_VALID, tx.TxValidationCode) 311 config.Equal(common.HeaderType_ENDORSER_TRANSACTION, tx.Type) 312 transactionActions := tx.GetTransactionActions() 313 config.NotNil(transactionActions) 314 chaincodeActions := transactionActions.ChaincodeActions 315 // we expecting to get zero chaincode action, 316 // since provided nil payload 317 config.Equal(0, len(chaincodeActions)) 318 default: 319 config.FailNow("Unexpected response type") 320 } 321 }).Return(nil) 322 }) 323 324 return chainManager, deliverServer 325 } 326 }(testConfig{ 327 channelID: "testChainID", 328 eventName: "testEvent", 329 chaincodeName: "mycc", 330 txID: "testID", 331 payload: &common.Payload{ 332 Header: &common.Header{ 333 ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{ 334 ChannelId: "testChainID", 335 Timestamp: util.CreateUtcTimestamp(), 336 }), 337 SignatureHeader: protoutil.MarshalOrPanic(&common.SignatureHeader{}), 338 }, 339 Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{ 340 Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}}, 341 Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}}, 342 Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY, 343 }), 344 }, 345 Assertions: assert.New(t), 346 }), 347 }, 348 { 349 name: "Testing deliver of the filtered block events with nil payload header", 350 prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 351 return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 352 wg.Add(1) 353 p := &peer2.Peer{} 354 chainManager := createDefaultSupportMamangerMock(config, nil, nil) 355 356 // setup mock deliver server 357 deliverServer := &mockDeliverServer{} 358 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 359 360 deliverServer.On("Recv").Return(&common.Envelope{ 361 Payload: protoutil.MarshalOrPanic(config.payload), 362 }, nil).Run(func(_ mock.Arguments) { 363 // once we are getting new message we need to mock 364 // Recv call to get io.EOF to stop the looping for 365 // next message and we can assert for the DeliverResponse 366 // value we are getting from the deliver server 367 deliverServer.Mock = mock.Mock{} 368 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 369 deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF) 370 deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) { 371 defer wg.Done() 372 response := args.Get(0).(*peer.DeliverResponse) 373 switch response.Type.(type) { 374 case *peer.DeliverResponse_Status: 375 config.Equal(common.Status_BAD_REQUEST, response.GetStatus()) 376 case *peer.DeliverResponse_FilteredBlock: 377 config.FailNow("Unexpected response type") 378 default: 379 config.FailNow("Unexpected response type") 380 } 381 }).Return(nil) 382 }) 383 384 return chainManager, deliverServer 385 } 386 }(testConfig{ 387 channelID: "testChainID", 388 eventName: "testEvent", 389 chaincodeName: "mycc", 390 txID: "testID", 391 payload: &common.Payload{ 392 Header: nil, 393 Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{ 394 Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}}, 395 Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}}, 396 Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY, 397 }), 398 }, 399 Assertions: assert.New(t), 400 }), 401 }, 402 } 403 for _, test := range tests { 404 t.Run(test.name, func(t *testing.T) { 405 wg := &sync.WaitGroup{} 406 chainManager, deliverServer := test.prepare(wg) 407 408 metrics := deliver.NewMetrics(&disabled.Provider{}) 409 server := &DeliverServer{ 410 DeliverHandler: deliver.NewHandler(chainManager, time.Second, false, metrics, false), 411 PolicyCheckerProvider: defaultPolicyCheckerProvider, 412 } 413 414 err := server.DeliverFiltered(deliverServer) 415 wg.Wait() 416 // no error expected 417 assert.NoError(t, err) 418 }) 419 } 420 } 421 422 func TestEventsServer_DeliverWithPrivateData(t *testing.T) { 423 fakeDeserializerMgr := &fake.IdentityDeserializerManager{} 424 fakeDeserializerMgr.DeserializerReturns(nil, nil) 425 fakeCollPolicyChecker := &fake.CollectionPolicyChecker{} 426 fakeCollPolicyChecker.CheckCollectionPolicyReturns(true, nil) 427 tests := []testCase{ 428 { 429 name: "Testing deliver block with private data events", 430 prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 431 return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 432 wg.Add(2) 433 p := &peer2.Peer{} 434 chaincodeActionPayload, err := createChaincodeAction(config.chaincodeName, config.eventName, config.txID) 435 config.NoError(err) 436 437 pvtData := []*ledger.TxPvtData{ 438 produceSamplePvtdataOrPanic(0, []string{"ns-0:coll-0", "ns-2:coll-20", "ns-2:coll-21"}), 439 } 440 chainManager := createDefaultSupportMamangerMock(config, chaincodeActionPayload, pvtData) 441 442 deliverServer := &mockDeliverServer{} 443 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 444 deliverServer.On("Recv").Return(&common.Envelope{ 445 Payload: protoutil.MarshalOrPanic(config.payload), 446 }, nil).Run(func(_ mock.Arguments) { 447 // mock Recv calls to get io.EOF to stop the looping for next message 448 deliverServer.Mock = mock.Mock{} 449 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 450 deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF) 451 deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) { 452 defer wg.Done() 453 response := args.Get(0).(*peer.DeliverResponse) 454 switch response.Type.(type) { 455 case *peer.DeliverResponse_Status: 456 config.Equal(common.Status_SUCCESS, response.GetStatus()) 457 case *peer.DeliverResponse_BlockAndPrivateData: 458 blockAndPvtData := response.GetBlockAndPrivateData() 459 block := blockAndPvtData.Block 460 config.Equal(uint64(0), block.Header.Number) 461 config.Equal(1, len(blockAndPvtData.PrivateDataMap)) 462 config.NotNil(blockAndPvtData.PrivateDataMap[uint64(0)]) 463 txPvtRwset := blockAndPvtData.PrivateDataMap[uint64(0)] 464 // expect to have 2 NsPvtRwset (i.e., 2 namespaces) 465 config.Equal(2, len(txPvtRwset.NsPvtRwset)) 466 // check namespace because the index may be out of order 467 for _, nsPvtRwset := range txPvtRwset.NsPvtRwset { 468 switch nsPvtRwset.Namespace { 469 case "ns-0": 470 config.Equal(1, len(nsPvtRwset.CollectionPvtRwset)) 471 config.Equal("coll-0", nsPvtRwset.CollectionPvtRwset[0].CollectionName) 472 case "ns-2": 473 config.Equal(2, len(nsPvtRwset.CollectionPvtRwset)) 474 config.Equal("coll-20", nsPvtRwset.CollectionPvtRwset[0].CollectionName) 475 config.Equal("coll-21", nsPvtRwset.CollectionPvtRwset[1].CollectionName) 476 default: 477 config.FailNow("Wrong namespace " + nsPvtRwset.Namespace) 478 } 479 } 480 default: 481 config.FailNow("Unexpected response type") 482 } 483 }).Return(nil) 484 }) 485 486 return chainManager, deliverServer 487 } 488 }(testConfig{ 489 channelID: "testChainID", 490 eventName: "testEvent", 491 chaincodeName: "mycc", 492 txID: "testID", 493 payload: &common.Payload{ 494 Header: &common.Header{ 495 ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{ 496 ChannelId: "testChainID", 497 Timestamp: util.CreateUtcTimestamp(), 498 }), 499 SignatureHeader: protoutil.MarshalOrPanic(&common.SignatureHeader{}), 500 }, 501 Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{ 502 Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}}, 503 Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}}, 504 Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY, 505 }), 506 }, 507 Assertions: assert.New(t), 508 }), 509 }, 510 { 511 name: "Testing deliver of block with private data events with nil header", 512 prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 513 return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) { 514 wg.Add(1) 515 p := &peer2.Peer{} 516 chainManager := createDefaultSupportMamangerMock(config, nil, nil) 517 518 deliverServer := &mockDeliverServer{} 519 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 520 deliverServer.On("Recv").Return(&common.Envelope{ 521 Payload: protoutil.MarshalOrPanic(config.payload), 522 }, nil).Run(func(_ mock.Arguments) { 523 // mock Recv calls to get io.EOF to stop the looping for next message 524 deliverServer.Mock = mock.Mock{} 525 deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p)) 526 deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF) 527 deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) { 528 defer wg.Done() 529 response := args.Get(0).(*peer.DeliverResponse) 530 switch response.Type.(type) { 531 case *peer.DeliverResponse_Status: 532 config.Equal(common.Status_BAD_REQUEST, response.GetStatus()) 533 case *peer.DeliverResponse_BlockAndPrivateData: 534 config.FailNow("Unexpected response type") 535 default: 536 config.FailNow("Unexpected response type") 537 } 538 }).Return(nil) 539 }) 540 541 return chainManager, deliverServer 542 } 543 }(testConfig{ 544 channelID: "testChainID", 545 eventName: "testEvent", 546 chaincodeName: "mycc", 547 txID: "testID", 548 payload: &common.Payload{ 549 Header: nil, 550 Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{ 551 Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}}, 552 Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}}, 553 Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY, 554 }), 555 }, 556 Assertions: assert.New(t), 557 }), 558 }, 559 } 560 for _, test := range tests { 561 t.Run(test.name, func(t *testing.T) { 562 wg := &sync.WaitGroup{} 563 chainManager, deliverServer := test.prepare(wg) 564 565 metrics := deliver.NewMetrics(&disabled.Provider{}) 566 handler := deliver.NewHandler(chainManager, time.Second, false, metrics, false) 567 server := &DeliverServer{ 568 DeliverHandler: handler, 569 PolicyCheckerProvider: defaultPolicyCheckerProvider, 570 CollectionPolicyChecker: fakeCollPolicyChecker, 571 IdentityDeserializerMgr: fakeDeserializerMgr, 572 } 573 574 err := server.DeliverWithPrivateData(deliverServer) 575 wg.Wait() 576 // no error expected 577 assert.NoError(t, err) 578 }) 579 } 580 } 581 582 func createDefaultSupportMamangerMock(config testConfig, chaincodeActionPayload *peer.ChaincodeActionPayload, pvtData []*ledger.TxPvtData) *mockChainManager { 583 chainManager := &mockChainManager{} 584 iter := &mockIterator{} 585 reader := &mockReader{} 586 chain := &mockChainSupport{} 587 ldgr := &fake.PeerLedger{} 588 589 payload, err := createEndorsement(config.channelID, config.txID, chaincodeActionPayload) 590 config.NoError(err) 591 592 payloadBytes, err := proto.Marshal(payload) 593 config.NoError(err) 594 595 block, err := createTestBlock([]*common.Envelope{{ 596 Payload: payloadBytes, 597 Signature: []byte{}}}) 598 config.NoError(err) 599 600 iter.On("Next").Return(block, common.Status_SUCCESS) 601 reader.On("Iterator", mock.Anything).Return(iter, uint64(1)) 602 reader.On("Height").Return(uint64(1)) 603 chain.On("Sequence").Return(uint64(0)) 604 chain.On("Reader").Return(reader) 605 chain.On("Ledger").Return(ldgr) 606 chainManager.On("GetChain", config.channelID).Return(chain, true) 607 608 ldgr.GetPvtDataByNumReturns(pvtData, nil) 609 610 return chainManager 611 } 612 613 func createEndorsement(channelID string, txID string, chaincodeActionPayload *peer.ChaincodeActionPayload) (*common.Payload, error) { 614 var chActionBytes []byte 615 var err error 616 if chaincodeActionPayload != nil { 617 chActionBytes, err = proto.Marshal(chaincodeActionPayload) 618 if err != nil { 619 return nil, err 620 } 621 } 622 623 // the transaction 624 txBytes, err := proto.Marshal(&peer.Transaction{ 625 Actions: []*peer.TransactionAction{ 626 { 627 Payload: chActionBytes, 628 }, 629 }, 630 }) 631 if err != nil { 632 return nil, err 633 } 634 // channel header 635 chdrBytes, err := proto.Marshal(&common.ChannelHeader{ 636 ChannelId: channelID, 637 TxId: txID, 638 Type: int32(common.HeaderType_ENDORSER_TRANSACTION), 639 }) 640 if err != nil { 641 return nil, err 642 } 643 644 // the payload 645 payload := &common.Payload{ 646 Header: &common.Header{ 647 ChannelHeader: chdrBytes, 648 }, 649 Data: txBytes, 650 } 651 return payload, nil 652 } 653 654 func createChaincodeAction(chaincodeName string, eventName string, txID string) (*peer.ChaincodeActionPayload, error) { 655 // chaincode events 656 eventsBytes, err := proto.Marshal(&peer.ChaincodeEvent{ 657 ChaincodeId: chaincodeName, 658 EventName: eventName, 659 TxId: txID, 660 }) 661 if err != nil { 662 return nil, err 663 } 664 665 // chaincode action 666 actionBytes, err := proto.Marshal(&peer.ChaincodeAction{ 667 ChaincodeId: &peer.ChaincodeID{ 668 Name: chaincodeName, 669 }, 670 Events: eventsBytes, 671 }) 672 if err != nil { 673 return nil, err 674 } 675 676 // proposal response 677 proposalResBytes, err := proto.Marshal(&peer.ProposalResponsePayload{ 678 Extension: actionBytes, 679 }) 680 if err != nil { 681 return nil, err 682 } 683 684 // chaincode action 685 chaincodeActionPayload := &peer.ChaincodeActionPayload{ 686 Action: &peer.ChaincodeEndorsedAction{ 687 ProposalResponsePayload: proposalResBytes, 688 Endorsements: []*peer.Endorsement{}, 689 }, 690 } 691 return chaincodeActionPayload, err 692 } 693 694 func createTestBlock(data []*common.Envelope) (*common.Block, error) { 695 // block 696 block := &common.Block{ 697 Header: &common.BlockHeader{ 698 Number: 0, 699 DataHash: []byte{}, 700 }, 701 Data: &common.BlockData{}, 702 Metadata: &common.BlockMetadata{}, 703 } 704 for _, d := range data { 705 envBytes, err := proto.Marshal(d) 706 if err != nil { 707 return nil, err 708 } 709 710 block.Data.Data = append(block.Data.Data, envBytes) 711 } 712 // making up metadata 713 block.Metadata.Metadata = make([][]byte, 4) 714 block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = make([]byte, len(data)) 715 return block, nil 716 } 717 718 func produceSamplePvtdataOrPanic(txNum uint64, nsColls []string) *ledger.TxPvtData { 719 builder := rwsetutil.NewRWSetBuilder() 720 for _, nsColl := range nsColls { 721 nsCollSplit := strings.Split(nsColl, ":") 722 ns := nsCollSplit[0] 723 coll := nsCollSplit[1] 724 builder.AddToPvtAndHashedWriteSet(ns, coll, fmt.Sprintf("key-%s-%s", ns, coll), []byte(fmt.Sprintf("value-%s-%s", ns, coll))) 725 } 726 simRes, err := builder.GetTxSimulationResults() 727 if err != nil { 728 panic(err) 729 } 730 return &ledger.TxPvtData{SeqInBlock: txNum, WriteSet: simRes.PvtSimulationResults} 731 }