github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/gossip/service/gossip_service_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package service 8 9 import ( 10 "bytes" 11 "fmt" 12 "io/ioutil" 13 "net" 14 "os" 15 "testing" 16 "time" 17 18 "github.com/hyperledger/fabric-protos-go/common" 19 "github.com/hyperledger/fabric-protos-go/peer" 20 transientstore2 "github.com/hyperledger/fabric-protos-go/transientstore" 21 "github.com/osdi23p228/fabric/bccsp/factory" 22 "github.com/osdi23p228/fabric/bccsp/sw" 23 "github.com/osdi23p228/fabric/common/channelconfig" 24 "github.com/osdi23p228/fabric/common/flogging" 25 "github.com/osdi23p228/fabric/common/metrics/disabled" 26 "github.com/osdi23p228/fabric/core/deliverservice" 27 "github.com/osdi23p228/fabric/core/ledger" 28 "github.com/osdi23p228/fabric/core/transientstore" 29 "github.com/osdi23p228/fabric/gossip/api" 30 gcomm "github.com/osdi23p228/fabric/gossip/comm" 31 gossipcommon "github.com/osdi23p228/fabric/gossip/common" 32 "github.com/osdi23p228/fabric/gossip/discovery" 33 "github.com/osdi23p228/fabric/gossip/election" 34 "github.com/osdi23p228/fabric/gossip/gossip" 35 "github.com/osdi23p228/fabric/gossip/gossip/algo" 36 "github.com/osdi23p228/fabric/gossip/gossip/channel" 37 gossipmetrics "github.com/osdi23p228/fabric/gossip/metrics" 38 "github.com/osdi23p228/fabric/gossip/privdata" 39 "github.com/osdi23p228/fabric/gossip/state" 40 "github.com/osdi23p228/fabric/gossip/util" 41 peergossip "github.com/osdi23p228/fabric/internal/peer/gossip" 42 "github.com/osdi23p228/fabric/internal/peer/gossip/mocks" 43 "github.com/osdi23p228/fabric/internal/pkg/comm" 44 "github.com/osdi23p228/fabric/internal/pkg/identity" 45 "github.com/osdi23p228/fabric/internal/pkg/peer/blocksprovider" 46 "github.com/osdi23p228/fabric/internal/pkg/peer/orderers" 47 "github.com/osdi23p228/fabric/msp/mgmt" 48 msptesttools "github.com/osdi23p228/fabric/msp/mgmt/testtools" 49 "github.com/stretchr/testify/assert" 50 "github.com/stretchr/testify/require" 51 "google.golang.org/grpc" 52 ) 53 54 const TIMEOUT = 45 * time.Second 55 56 func init() { 57 util.SetupTestLogging() 58 } 59 60 //go:generate counterfeiter -o mocks/signer_serializer.go --fake-name SignerSerializer . signerSerializer 61 62 type signerSerializer interface { 63 identity.SignerSerializer 64 } 65 66 type testTransientStore struct { 67 storeProvider transientstore.StoreProvider 68 Store *transientstore.Store 69 tempdir string 70 } 71 72 func newTransientStore(t *testing.T) *testTransientStore { 73 s := &testTransientStore{} 74 var err error 75 s.tempdir, err = ioutil.TempDir("", "ts") 76 if err != nil { 77 t.Fatalf("Failed to create test directory, got err %s", err) 78 return s 79 } 80 s.storeProvider, err = transientstore.NewStoreProvider(s.tempdir) 81 if err != nil { 82 t.Fatalf("Failed to open store, got err %s", err) 83 return s 84 } 85 s.Store, err = s.storeProvider.OpenStore("test") 86 if err != nil { 87 t.Fatalf("Failed to open store, got err %s", err) 88 return s 89 } 90 return s 91 } 92 93 func (s *testTransientStore) tearDown() { 94 s.storeProvider.Close() 95 os.RemoveAll(s.tempdir) 96 } 97 98 func (s *testTransientStore) Persist(txid string, blockHeight uint64, 99 privateSimulationResultsWithConfig *transientstore2.TxPvtReadWriteSetWithConfigInfo) error { 100 return s.Store.Persist(txid, blockHeight, privateSimulationResultsWithConfig) 101 } 102 103 func (s *testTransientStore) GetTxPvtRWSetByTxid(txid string, filter ledger.PvtNsCollFilter) (privdata.RWSetScanner, error) { 104 return s.Store.GetTxPvtRWSetByTxid(txid, filter) 105 } 106 107 func TestInitGossipService(t *testing.T) { 108 grpcServer := grpc.NewServer() 109 endpoint, socket := getAvailablePort(t) 110 111 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 112 assert.NoError(t, err) 113 114 err = msptesttools.LoadMSPSetupForTesting() 115 require.NoError(t, err) 116 signer := mgmt.GetLocalSigningIdentityOrPanic(cryptoProvider) 117 118 messageCryptoService := peergossip.NewMCS(&mocks.ChannelPolicyManagerGetter{}, signer, mgmt.NewDeserializersManager(cryptoProvider), cryptoProvider) 119 secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager(cryptoProvider)) 120 gossipConfig, err := gossip.GlobalConfig(endpoint, nil) 121 assert.NoError(t, err) 122 123 grpcClient, err := comm.NewGRPCClient(comm.ClientConfig{}) 124 require.NoError(t, err) 125 126 gossipService, err := New( 127 signer, 128 gossipmetrics.NewGossipMetrics(&disabled.Provider{}), 129 endpoint, 130 grpcServer, 131 messageCryptoService, 132 secAdv, 133 nil, 134 comm.NewCredentialSupport(), 135 grpcClient, 136 gossipConfig, 137 &ServiceConfig{}, 138 &privdata.PrivdataConfig{}, 139 &deliverservice.DeliverServiceConfig{ 140 ReConnectBackoffThreshold: deliverservice.DefaultReConnectBackoffThreshold, 141 ReconnectTotalTimeThreshold: deliverservice.DefaultReConnectTotalTimeThreshold, 142 }, 143 ) 144 assert.NoError(t, err) 145 146 go grpcServer.Serve(socket) 147 defer grpcServer.Stop() 148 149 defer gossipService.Stop() 150 } 151 152 // Make sure *joinChannelMessage implements the api.JoinChannelMessage 153 func TestJCMInterface(t *testing.T) { 154 _ = api.JoinChannelMessage(&joinChannelMessage{}) 155 } 156 157 func TestLeaderElectionWithDeliverClient(t *testing.T) { 158 //Test check if leader election works with mock deliver service instance 159 //Configuration set to use dynamic leader election 160 //10 peers started, added to channel and at the end we check if only for one peer 161 //mockDeliverService.StartDeliverForChannel was invoked 162 163 n := 10 164 serviceConfig := &ServiceConfig{ 165 UseLeaderElection: true, 166 OrgLeader: false, 167 ElectionStartupGracePeriod: election.DefStartupGracePeriod, 168 ElectionMembershipSampleInterval: election.DefMembershipSampleInterval, 169 ElectionLeaderAliveThreshold: election.DefLeaderAliveThreshold, 170 ElectionLeaderElectionDuration: election.DefLeaderElectionDuration, 171 } 172 gossips := startPeers(serviceConfig, n, 0, 1, 2, 3, 4) 173 174 channelName := "chanA" 175 peerIndexes := make([]int, n) 176 for i := 0; i < n; i++ { 177 peerIndexes[i] = i 178 } 179 addPeersToChannel(channelName, gossips, peerIndexes) 180 181 waitForFullMembershipOrFailNow(t, channelName, gossips, n, TIMEOUT, time.Second*2) 182 183 services := make([]*electionService, n) 184 185 store := newTransientStore(t) 186 defer store.tearDown() 187 188 for i := 0; i < n; i++ { 189 deliverServiceFactory := &mockDeliverServiceFactory{ 190 service: &mockDeliverService{ 191 running: make(map[string]bool), 192 }, 193 } 194 gossips[i].deliveryFactory = deliverServiceFactory 195 deliverServiceFactory.service.running[channelName] = false 196 197 gossips[i].InitializeChannel(channelName, orderers.NewConnectionSource(flogging.MustGetLogger("peer.orderers"), nil), store.Store, Support{ 198 Committer: &mockLedgerInfo{1}, 199 }) 200 service, exist := gossips[i].leaderElection[channelName] 201 assert.True(t, exist, "Leader election service should be created for peer %d and channel %s", i, channelName) 202 services[i] = &electionService{nil, false, 0} 203 services[i].LeaderElectionService = service 204 } 205 206 // Is single leader was elected. 207 assert.True(t, waitForLeaderElection(services, time.Second*30, time.Second*2), "One leader should be selected") 208 209 startsNum := 0 210 for i := 0; i < n; i++ { 211 // Is mockDeliverService.StartDeliverForChannel in current peer for the specific channel was invoked 212 if gossips[i].deliveryService[channelName].(*mockDeliverService).running[channelName] { 213 startsNum++ 214 } 215 } 216 217 assert.Equal(t, 1, startsNum, "Only for one peer delivery client should start") 218 219 stopPeers(gossips) 220 } 221 222 func TestWithStaticDeliverClientLeader(t *testing.T) { 223 // Tests check if static leader flag works ok. 224 // Leader election flag set to false, and static leader flag set to true 225 // Two gossip service instances (peers) created. 226 // Each peer is added to channel and should run mock delivery client 227 // After that each peer added to another client and it should run deliver client for this channel as well. 228 229 serviceConfig := &ServiceConfig{ 230 UseLeaderElection: false, 231 OrgLeader: true, 232 ElectionStartupGracePeriod: election.DefStartupGracePeriod, 233 ElectionMembershipSampleInterval: election.DefMembershipSampleInterval, 234 ElectionLeaderAliveThreshold: election.DefLeaderAliveThreshold, 235 ElectionLeaderElectionDuration: election.DefLeaderElectionDuration, 236 } 237 n := 2 238 gossips := startPeers(serviceConfig, n, 0, 1) 239 channelName := "chanA" 240 peerIndexes := make([]int, n) 241 for i := 0; i < n; i++ { 242 peerIndexes[i] = i 243 } 244 addPeersToChannel(channelName, gossips, peerIndexes) 245 246 waitForFullMembershipOrFailNow(t, channelName, gossips, n, TIMEOUT, time.Second*2) 247 248 store := newTransientStore(t) 249 defer store.tearDown() 250 251 deliverServiceFactory := &mockDeliverServiceFactory{ 252 service: &mockDeliverService{ 253 running: make(map[string]bool), 254 }, 255 } 256 257 for i := 0; i < n; i++ { 258 gossips[i].deliveryFactory = deliverServiceFactory 259 deliverServiceFactory.service.running[channelName] = false 260 gossips[i].InitializeChannel(channelName, orderers.NewConnectionSource(flogging.MustGetLogger("peer.orderers"), nil), store.Store, Support{ 261 Committer: &mockLedgerInfo{1}, 262 }) 263 } 264 265 for i := 0; i < n; i++ { 266 assert.NotNil(t, gossips[i].deliveryService[channelName], "Delivery service for channel %s not initiated in peer %d", channelName, i) 267 assert.True(t, gossips[i].deliveryService[channelName].(*mockDeliverService).running[channelName], "Block deliverer not started for peer %d", i) 268 } 269 270 channelName = "chanB" 271 for i := 0; i < n; i++ { 272 deliverServiceFactory.service.running[channelName] = false 273 gossips[i].InitializeChannel(channelName, orderers.NewConnectionSource(flogging.MustGetLogger("peer.orderers"), nil), store.Store, Support{ 274 Committer: &mockLedgerInfo{1}, 275 }) 276 } 277 278 for i := 0; i < n; i++ { 279 assert.NotNil(t, gossips[i].deliveryService[channelName], "Delivery service for channel %s not initiated in peer %d", channelName, i) 280 assert.True(t, gossips[i].deliveryService[channelName].(*mockDeliverService).running[channelName], "Block deliverer not started for peer %d", i) 281 } 282 283 stopPeers(gossips) 284 } 285 286 func TestWithStaticDeliverClientNotLeader(t *testing.T) { 287 288 serviceConfig := &ServiceConfig{ 289 UseLeaderElection: false, 290 OrgLeader: false, 291 ElectionStartupGracePeriod: election.DefStartupGracePeriod, 292 ElectionMembershipSampleInterval: election.DefMembershipSampleInterval, 293 ElectionLeaderAliveThreshold: election.DefLeaderAliveThreshold, 294 ElectionLeaderElectionDuration: election.DefLeaderElectionDuration, 295 } 296 n := 2 297 gossips := startPeers(serviceConfig, n, 0, 1) 298 299 channelName := "chanA" 300 peerIndexes := make([]int, n) 301 for i := 0; i < n; i++ { 302 peerIndexes[i] = i 303 } 304 305 addPeersToChannel(channelName, gossips, peerIndexes) 306 307 waitForFullMembershipOrFailNow(t, channelName, gossips, n, TIMEOUT, time.Second*2) 308 309 store := newTransientStore(t) 310 defer store.tearDown() 311 312 deliverServiceFactory := &mockDeliverServiceFactory{ 313 service: &mockDeliverService{ 314 running: make(map[string]bool), 315 }, 316 } 317 318 for i := 0; i < n; i++ { 319 gossips[i].deliveryFactory = deliverServiceFactory 320 deliverServiceFactory.service.running[channelName] = false 321 gossips[i].InitializeChannel(channelName, orderers.NewConnectionSource(flogging.MustGetLogger("peer.orderers"), nil), store.Store, Support{ 322 Committer: &mockLedgerInfo{1}, 323 }) 324 } 325 326 for i := 0; i < n; i++ { 327 assert.NotNil(t, gossips[i].deliveryService[channelName], "Delivery service for channel %s not initiated in peer %d", channelName, i) 328 assert.False(t, gossips[i].deliveryService[channelName].(*mockDeliverService).running[channelName], "Block deliverer should not be started for peer %d", i) 329 } 330 331 stopPeers(gossips) 332 } 333 334 func TestWithStaticDeliverClientBothStaticAndLeaderElection(t *testing.T) { 335 336 serviceConfig := &ServiceConfig{ 337 UseLeaderElection: true, 338 OrgLeader: true, 339 ElectionStartupGracePeriod: election.DefStartupGracePeriod, 340 ElectionMembershipSampleInterval: election.DefMembershipSampleInterval, 341 ElectionLeaderAliveThreshold: election.DefLeaderAliveThreshold, 342 ElectionLeaderElectionDuration: election.DefLeaderElectionDuration, 343 } 344 n := 2 345 gossips := startPeers(serviceConfig, n, 0, 1) 346 347 channelName := "chanA" 348 peerIndexes := make([]int, n) 349 for i := 0; i < n; i++ { 350 peerIndexes[i] = i 351 } 352 353 addPeersToChannel(channelName, gossips, peerIndexes) 354 355 waitForFullMembershipOrFailNow(t, channelName, gossips, n, TIMEOUT, time.Second*2) 356 357 store := newTransientStore(t) 358 defer store.tearDown() 359 360 deliverServiceFactory := &mockDeliverServiceFactory{ 361 service: &mockDeliverService{ 362 running: make(map[string]bool), 363 }, 364 } 365 366 for i := 0; i < n; i++ { 367 gossips[i].deliveryFactory = deliverServiceFactory 368 assert.Panics(t, func() { 369 gossips[i].InitializeChannel(channelName, orderers.NewConnectionSource(flogging.MustGetLogger("peer.orderers"), nil), store.Store, Support{ 370 Committer: &mockLedgerInfo{1}, 371 }) 372 }, "Dynamic leader election based and static connection to ordering service can't exist simultaneously") 373 } 374 375 stopPeers(gossips) 376 } 377 378 type mockDeliverServiceFactory struct { 379 service *mockDeliverService 380 } 381 382 func (mf *mockDeliverServiceFactory) Service(GossipServiceAdapter, *orderers.ConnectionSource, api.MessageCryptoService, bool) deliverservice.DeliverService { 383 return mf.service 384 } 385 386 type mockDeliverService struct { 387 running map[string]bool 388 } 389 390 func (ds *mockDeliverService) StartDeliverForChannel(chainID string, ledgerInfo blocksprovider.LedgerInfo, finalizer func()) error { 391 ds.running[chainID] = true 392 return nil 393 } 394 395 func (ds *mockDeliverService) StopDeliverForChannel(chainID string) error { 396 ds.running[chainID] = false 397 return nil 398 } 399 400 func (ds *mockDeliverService) Stop() { 401 } 402 403 type mockLedgerInfo struct { 404 Height uint64 405 } 406 407 func (li *mockLedgerInfo) GetConfigHistoryRetriever() (ledger.ConfigHistoryRetriever, error) { 408 panic("implement me") 409 } 410 411 func (li *mockLedgerInfo) GetMissingPvtDataTracker() (ledger.MissingPvtDataTracker, error) { 412 panic("implement me") 413 } 414 415 func (li *mockLedgerInfo) GetPvtDataByNum(blockNum uint64, filter ledger.PvtNsCollFilter) ([]*ledger.TxPvtData, error) { 416 panic("implement me") 417 } 418 419 func (li *mockLedgerInfo) CommitLegacy(blockAndPvtData *ledger.BlockAndPvtData, commitOpts *ledger.CommitOptions) error { 420 panic("implement me") 421 } 422 423 func (li *mockLedgerInfo) CommitPvtDataOfOldBlocks(reconciledPvtdata []*ledger.ReconciledPvtdata, unreconciled ledger.MissingPvtDataInfo) ([]*ledger.PvtdataHashMismatch, error) { 424 panic("implement me") 425 } 426 427 func (li *mockLedgerInfo) GetPvtDataAndBlockByNum(seqNum uint64) (*ledger.BlockAndPvtData, error) { 428 panic("implement me") 429 } 430 431 // LedgerHeight returns mocked value to the ledger height 432 func (li *mockLedgerInfo) LedgerHeight() (uint64, error) { 433 return li.Height, nil 434 } 435 436 func (li *mockLedgerInfo) DoesPvtDataInfoExistInLedger(blkNum uint64) (bool, error) { 437 return false, nil 438 } 439 440 // Commit block to the ledger 441 func (li *mockLedgerInfo) Commit(block *common.Block) error { 442 return nil 443 } 444 445 // Gets blocks with sequence numbers provided in the slice 446 func (li *mockLedgerInfo) GetBlocks(blockSeqs []uint64) []*common.Block { 447 return make([]*common.Block, 0) 448 } 449 450 // Closes committing service 451 func (li *mockLedgerInfo) Close() { 452 } 453 454 func TestLeaderElectionWithRealGossip(t *testing.T) { 455 // Spawn 10 gossip instances with single channel and inside same organization 456 // Run leader election on top of each gossip instance and check that only one leader chosen 457 // Create another channel includes sub-set of peers over same gossip instances {1,3,5,7} 458 // Run additional leader election services for new channel 459 // Check correct leader still exist for first channel and new correct leader chosen in second channel 460 // Stop gossip instances of leader peers for both channels and see that new leader chosen for both 461 462 // Creating gossip service instances for peers 463 serviceConfig := &ServiceConfig{ 464 UseLeaderElection: false, 465 OrgLeader: false, 466 ElectionStartupGracePeriod: election.DefStartupGracePeriod, 467 ElectionMembershipSampleInterval: election.DefMembershipSampleInterval, 468 ElectionLeaderAliveThreshold: election.DefLeaderAliveThreshold, 469 ElectionLeaderElectionDuration: election.DefLeaderElectionDuration, 470 } 471 472 n := 10 473 gossips := startPeers(serviceConfig, n, 0, 1, 2, 3, 4) 474 // Joining all peers to first channel 475 channelName := "chanA" 476 peerIndexes := make([]int, n) 477 for i := 0; i < n; i++ { 478 peerIndexes[i] = i 479 } 480 addPeersToChannel(channelName, gossips, peerIndexes) 481 482 waitForFullMembershipOrFailNow(t, channelName, gossips, n, TIMEOUT, time.Second*2) 483 484 logger.Warning("Starting leader election services") 485 486 //Starting leader election services 487 services := make([]*electionService, n) 488 489 electionMetrics := gossipmetrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics 490 491 for i := 0; i < n; i++ { 492 services[i] = &electionService{nil, false, 0} 493 services[i].LeaderElectionService = gossips[i].newLeaderElectionComponent(channelName, services[i].callback, electionMetrics) 494 } 495 496 logger.Warning("Waiting for leader election") 497 498 assert.True(t, waitForLeaderElection(services, time.Second*30, time.Second*2), "One leader should be selected") 499 500 startsNum := 0 501 for i := 0; i < n; i++ { 502 // Is callback function was invoked by this leader election service instance 503 if services[i].callbackInvokeRes { 504 startsNum++ 505 } 506 } 507 //Only leader should invoke callback function, so it is double check that only one leader exists 508 assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanA") 509 510 // Adding some peers to new channel and creating leader election services for peers in new channel 511 // Expecting peer 1 (first in list of election services) to become leader of second channel 512 secondChannelPeerIndexes := []int{1, 3, 5, 7} 513 secondChannelName := "chanB" 514 secondChannelServices := make([]*electionService, len(secondChannelPeerIndexes)) 515 addPeersToChannel(secondChannelName, gossips, secondChannelPeerIndexes) 516 517 secondChannelGossips := make([]*gossipGRPC, 0) 518 for _, i := range secondChannelPeerIndexes { 519 secondChannelGossips = append(secondChannelGossips, gossips[i]) 520 } 521 waitForFullMembershipOrFailNow(t, secondChannelName, secondChannelGossips, len(secondChannelGossips), TIMEOUT, time.Millisecond*100) 522 523 for idx, i := range secondChannelPeerIndexes { 524 secondChannelServices[idx] = &electionService{nil, false, 0} 525 secondChannelServices[idx].LeaderElectionService = 526 gossips[i].newLeaderElectionComponent(secondChannelName, secondChannelServices[idx].callback, electionMetrics) 527 } 528 529 assert.True(t, waitForLeaderElection(secondChannelServices, time.Second*30, time.Second*2), "One leader should be selected for chanB") 530 assert.True(t, waitForLeaderElection(services, time.Second*30, time.Second*2), "One leader should be selected for chanA") 531 532 startsNum = 0 533 for i := 0; i < n; i++ { 534 if services[i].callbackInvokeRes { 535 startsNum++ 536 } 537 } 538 assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanA") 539 540 startsNum = 0 541 for i := 0; i < len(secondChannelServices); i++ { 542 if secondChannelServices[i].callbackInvokeRes { 543 startsNum++ 544 } 545 } 546 assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanB") 547 548 //Stopping 2 gossip instances(peer 0 and peer 1), should init re-election 549 //Now peer 2 become leader for first channel and peer 3 for second channel 550 551 logger.Warning("Killing 2 peers, initiation new leader election") 552 553 stopPeers(gossips[:2]) 554 555 waitForFullMembershipOrFailNow(t, channelName, gossips[2:], n-2, TIMEOUT, time.Millisecond*100) 556 waitForFullMembershipOrFailNow(t, secondChannelName, secondChannelGossips[1:], len(secondChannelGossips)-1, TIMEOUT, time.Millisecond*100) 557 558 assert.True(t, waitForLeaderElection(services[2:], time.Second*30, time.Second*2), "One leader should be selected after re-election - chanA") 559 assert.True(t, waitForLeaderElection(secondChannelServices[1:], time.Second*30, time.Second*2), "One leader should be selected after re-election - chanB") 560 561 startsNum = 0 562 for i := 2; i < n; i++ { 563 if services[i].callbackInvokeRes { 564 startsNum++ 565 } 566 } 567 assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called after re-election - chanA") 568 569 startsNum = 0 570 for i := 1; i < len(secondChannelServices); i++ { 571 if secondChannelServices[i].callbackInvokeRes { 572 startsNum++ 573 } 574 } 575 assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called after re-election - chanB") 576 577 stopServices(secondChannelServices) 578 stopServices(services) 579 stopPeers(gossips[2:]) 580 } 581 582 type electionService struct { 583 election.LeaderElectionService 584 callbackInvokeRes bool 585 callbackInvokeCount int 586 } 587 588 func (es *electionService) callback(isLeader bool) { 589 es.callbackInvokeRes = isLeader 590 es.callbackInvokeCount = es.callbackInvokeCount + 1 591 } 592 593 type joinChanMsg struct { 594 } 595 596 // SequenceNumber returns the sequence number of the block this joinChanMsg 597 // is derived from 598 func (jmc *joinChanMsg) SequenceNumber() uint64 { 599 return uint64(time.Now().UnixNano()) 600 } 601 602 // Members returns the organizations of the channel 603 func (jmc *joinChanMsg) Members() []api.OrgIdentityType { 604 return []api.OrgIdentityType{orgInChannelA} 605 } 606 607 // AnchorPeersOf returns the anchor peers of the given organization 608 func (jmc *joinChanMsg) AnchorPeersOf(org api.OrgIdentityType) []api.AnchorPeer { 609 return []api.AnchorPeer{} 610 } 611 612 func waitForFullMembershipOrFailNow(t *testing.T, channel string, gossips []*gossipGRPC, peersNum int, timeout time.Duration, testPollInterval time.Duration) { 613 end := time.Now().Add(timeout) 614 var correctPeers int 615 for time.Now().Before(end) { 616 correctPeers = 0 617 for _, g := range gossips { 618 if len(g.PeersOfChannel(gossipcommon.ChannelID(channel))) == (peersNum - 1) { 619 correctPeers++ 620 } 621 } 622 if correctPeers == peersNum { 623 return 624 } 625 time.Sleep(testPollInterval) 626 } 627 t.Fatalf("Failed to establish full channel membership. Only %d out of %d peers have full membership", correctPeers, peersNum) 628 } 629 630 func waitForMultipleLeadersElection(services []*electionService, leadersNum int, timeout time.Duration, testPollInterval time.Duration) bool { 631 logger.Warning("Waiting for", leadersNum, "leaders") 632 end := time.Now().Add(timeout) 633 correctNumberOfLeadersFound := false 634 leaders := 0 635 for time.Now().Before(end) { 636 leaders = 0 637 for _, s := range services { 638 if s.IsLeader() { 639 leaders++ 640 } 641 } 642 if leaders == leadersNum { 643 if correctNumberOfLeadersFound { 644 return true 645 } 646 correctNumberOfLeadersFound = true 647 } else { 648 correctNumberOfLeadersFound = false 649 } 650 time.Sleep(testPollInterval) 651 } 652 logger.Warning("Incorrect number of leaders", leaders) 653 for i, s := range services { 654 logger.Warning("Peer at index", i, "is leader", s.IsLeader()) 655 } 656 return false 657 } 658 659 func waitForLeaderElection(services []*electionService, timeout time.Duration, testPollInterval time.Duration) bool { 660 return waitForMultipleLeadersElection(services, 1, timeout, testPollInterval) 661 } 662 663 func stopServices(services []*electionService) { 664 for _, service := range services { 665 service.Stop() 666 } 667 } 668 669 func stopPeers(peers []*gossipGRPC) { 670 for _, peer := range peers { 671 peer.Stop() 672 } 673 } 674 675 func addPeersToChannel(channel string, peers []*gossipGRPC, peerIndexes []int) { 676 jcm := &joinChanMsg{} 677 678 for _, i := range peerIndexes { 679 peers[i].JoinChan(jcm, gossipcommon.ChannelID(channel)) 680 peers[i].UpdateLedgerHeight(0, gossipcommon.ChannelID(channel)) 681 } 682 } 683 684 func startPeers(serviceConfig *ServiceConfig, n int, boot ...int) []*gossipGRPC { 685 var ports []int 686 var grpcs []*comm.GRPCServer 687 var certs []*gossipcommon.TLSCertificates 688 var secDialOpts []api.PeerSecureDialOpts 689 690 for i := 0; i < n; i++ { 691 port, grpc, cert, secDialOpt, _ := util.CreateGRPCLayer() 692 ports = append(ports, port) 693 grpcs = append(grpcs, grpc) 694 certs = append(certs, cert) 695 secDialOpts = append(secDialOpts, secDialOpt) 696 } 697 698 var bootPorts []int 699 for _, index := range boot { 700 bootPorts = append(bootPorts, ports[index]) 701 } 702 703 peers := make([]*gossipGRPC, n) 704 for i := 0; i < n; i++ { 705 peers[i] = newGossipInstance(serviceConfig, ports[i], i, grpcs[i], certs[i], secDialOpts[i], 100, bootPorts...) 706 } 707 708 return peers 709 } 710 711 func newGossipInstance(serviceConfig *ServiceConfig, port int, id int, gRPCServer *comm.GRPCServer, certs *gossipcommon.TLSCertificates, 712 secureDialOpts api.PeerSecureDialOpts, maxMsgCount int, bootPorts ...int) *gossipGRPC { 713 conf := &gossip.Config{ 714 BindPort: port, 715 BootstrapPeers: bootPeers(bootPorts...), 716 ID: fmt.Sprintf("p%d", id), 717 MaxBlockCountToStore: maxMsgCount, 718 MaxPropagationBurstLatency: time.Duration(500) * time.Millisecond, 719 MaxPropagationBurstSize: 20, 720 PropagateIterations: 1, 721 PropagatePeerNum: 3, 722 PullInterval: time.Duration(2) * time.Second, 723 PullPeerNum: 5, 724 InternalEndpoint: fmt.Sprintf("127.0.0.1:%d", port), 725 ExternalEndpoint: fmt.Sprintf("1.2.3.4:%d", port), 726 PublishCertPeriod: time.Duration(4) * time.Second, 727 PublishStateInfoInterval: time.Duration(1) * time.Second, 728 RequestStateInfoInterval: time.Duration(1) * time.Second, 729 TimeForMembershipTracker: time.Second * 5, 730 TLSCerts: certs, 731 DigestWaitTime: algo.DefDigestWaitTime, 732 RequestWaitTime: algo.DefRequestWaitTime, 733 ResponseWaitTime: algo.DefResponseWaitTime, 734 DialTimeout: gcomm.DefDialTimeout, 735 ConnTimeout: gcomm.DefConnTimeout, 736 RecvBuffSize: gcomm.DefRecvBuffSize, 737 SendBuffSize: gcomm.DefSendBuffSize, 738 MsgExpirationTimeout: channel.DefMsgExpirationTimeout, 739 AliveTimeInterval: discovery.DefAliveTimeInterval, 740 AliveExpirationTimeout: discovery.DefAliveExpirationTimeout, 741 AliveExpirationCheckInterval: discovery.DefAliveExpirationCheckInterval, 742 ReconnectInterval: time.Duration(1) * time.Second, 743 MaxConnectionAttempts: discovery.DefMaxConnectionAttempts, 744 MsgExpirationFactor: discovery.DefMsgExpirationFactor, 745 } 746 selfID := api.PeerIdentityType(conf.InternalEndpoint) 747 cryptoService := &naiveCryptoService{} 748 metrics := gossipmetrics.NewGossipMetrics(&disabled.Provider{}) 749 gossip := gossip.New( 750 conf, 751 gRPCServer.Server(), 752 &orgCryptoService{}, 753 cryptoService, 754 selfID, 755 secureDialOpts, 756 metrics, 757 nil, 758 ) 759 go gRPCServer.Start() 760 761 secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager(factory.GetDefault())) 762 gossipService := &GossipService{ 763 mcs: cryptoService, 764 gossipSvc: gossip, 765 chains: make(map[string]state.GossipStateProvider), 766 leaderElection: make(map[string]election.LeaderElectionService), 767 privateHandlers: make(map[string]privateHandler), 768 deliveryService: make(map[string]deliverservice.DeliverService), 769 deliveryFactory: &deliveryFactoryImpl{ 770 credentialSupport: comm.NewCredentialSupport(), 771 }, 772 peerIdentity: api.PeerIdentityType(conf.InternalEndpoint), 773 secAdv: secAdv, 774 metrics: metrics, 775 serviceConfig: serviceConfig, 776 privdataConfig: privdata.GlobalConfig(), 777 } 778 779 return &gossipGRPC{GossipService: gossipService, grpc: gRPCServer} 780 } 781 782 type gossipGRPC struct { 783 *GossipService 784 grpc *comm.GRPCServer 785 } 786 787 func (g *gossipGRPC) Stop() { 788 g.GossipService.Stop() 789 g.grpc.Stop() 790 } 791 792 func bootPeers(ports ...int) []string { 793 var peers []string 794 for _, port := range ports { 795 peers = append(peers, fmt.Sprintf("127.0.0.1:%d", port)) 796 } 797 return peers 798 } 799 800 func getAvailablePort(t *testing.T) (endpoint string, ll net.Listener) { 801 ll, err := net.Listen("tcp", "127.0.0.1:0") 802 assert.NoError(t, err) 803 endpoint = ll.Addr().String() 804 return endpoint, ll 805 } 806 807 type naiveCryptoService struct { 808 } 809 810 type orgCryptoService struct { 811 } 812 813 // OrgByPeerIdentity returns the OrgIdentityType 814 // of a given peer identity 815 func (*orgCryptoService) OrgByPeerIdentity(identity api.PeerIdentityType) api.OrgIdentityType { 816 return orgInChannelA 817 } 818 819 // Verify verifies a JoinChanMessage, returns nil on success, 820 // and an error on failure 821 func (*orgCryptoService) Verify(joinChanMsg api.JoinChannelMessage) error { 822 return nil 823 } 824 825 func (naiveCryptoService) Expiration(peerIdentity api.PeerIdentityType) (time.Time, error) { 826 return time.Now().Add(time.Hour), nil 827 } 828 829 // VerifyByChannel verifies a peer's signature on a message in the context 830 // of a specific channel 831 func (*naiveCryptoService) VerifyByChannel(_ gossipcommon.ChannelID, _ api.PeerIdentityType, _, _ []byte) error { 832 return nil 833 } 834 835 func (*naiveCryptoService) ValidateIdentity(peerIdentity api.PeerIdentityType) error { 836 return nil 837 } 838 839 // GetPKIidOfCert returns the PKI-ID of a peer's identity 840 func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) gossipcommon.PKIidType { 841 return gossipcommon.PKIidType(peerIdentity) 842 } 843 844 // VerifyBlock returns nil if the block is properly signed, 845 // else returns error 846 func (*naiveCryptoService) VerifyBlock(chainID gossipcommon.ChannelID, seqNum uint64, signedBlock *common.Block) error { 847 return nil 848 } 849 850 // Sign signs msg with this peer's signing key and outputs 851 // the signature if no error occurred. 852 func (*naiveCryptoService) Sign(msg []byte) ([]byte, error) { 853 return msg, nil 854 } 855 856 // Verify checks that signature is a valid signature of message under a peer's verification key. 857 // If the verification succeeded, Verify returns nil meaning no error occurred. 858 // If peerCert is nil, then the signature is verified against this peer's verification key. 859 func (*naiveCryptoService) Verify(peerIdentity api.PeerIdentityType, signature, message []byte) error { 860 equal := bytes.Equal(signature, message) 861 if !equal { 862 return fmt.Errorf("Wrong signature:%v, %v", signature, message) 863 } 864 return nil 865 } 866 867 var orgInChannelA = api.OrgIdentityType("ORG1") 868 869 func TestInvalidInitialization(t *testing.T) { 870 grpcServer := grpc.NewServer() 871 endpoint, socket := getAvailablePort(t) 872 873 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 874 assert.NoError(t, err) 875 876 mockSignerSerializer := &mocks.SignerSerializer{} 877 mockSignerSerializer.SerializeReturns(api.PeerIdentityType("peer-identity"), nil) 878 secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager(cryptoProvider)) 879 gossipConfig, err := gossip.GlobalConfig(endpoint, nil) 880 assert.NoError(t, err) 881 882 grpcClient, err := comm.NewGRPCClient(comm.ClientConfig{}) 883 require.NoError(t, err) 884 885 gossipService, err := New( 886 mockSignerSerializer, 887 gossipmetrics.NewGossipMetrics(&disabled.Provider{}), 888 endpoint, 889 grpcServer, 890 &naiveCryptoService{}, 891 secAdv, 892 nil, 893 comm.NewCredentialSupport(), 894 grpcClient, 895 gossipConfig, 896 &ServiceConfig{}, 897 &privdata.PrivdataConfig{}, 898 &deliverservice.DeliverServiceConfig{ 899 PeerTLSEnabled: false, 900 ReConnectBackoffThreshold: deliverservice.DefaultReConnectBackoffThreshold, 901 ReconnectTotalTimeThreshold: deliverservice.DefaultReConnectTotalTimeThreshold, 902 }, 903 ) 904 assert.NoError(t, err) 905 gService := gossipService 906 defer gService.Stop() 907 908 go grpcServer.Serve(socket) 909 defer grpcServer.Stop() 910 911 dc := gService.deliveryFactory.Service(gService, orderers.NewConnectionSource(flogging.MustGetLogger("peer.orderers"), nil), &naiveCryptoService{}, false) 912 assert.NotNil(t, dc) 913 } 914 915 func TestChannelConfig(t *testing.T) { 916 // Test whenever gossip service is indeed singleton 917 grpcServer := grpc.NewServer() 918 endpoint, socket := getAvailablePort(t) 919 920 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 921 assert.NoError(t, err) 922 923 mockSignerSerializer := &mocks.SignerSerializer{} 924 mockSignerSerializer.SerializeReturns(api.PeerIdentityType(string(orgInChannelA)), nil) 925 secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager(cryptoProvider)) 926 gossipConfig, err := gossip.GlobalConfig(endpoint, nil) 927 assert.NoError(t, err) 928 929 grpcClient, err := comm.NewGRPCClient(comm.ClientConfig{}) 930 assert.NoError(t, err) 931 932 gossipService, err := New( 933 mockSignerSerializer, 934 gossipmetrics.NewGossipMetrics(&disabled.Provider{}), 935 endpoint, 936 grpcServer, 937 &naiveCryptoService{}, 938 secAdv, 939 nil, 940 nil, 941 grpcClient, 942 gossipConfig, 943 &ServiceConfig{}, 944 &privdata.PrivdataConfig{}, 945 &deliverservice.DeliverServiceConfig{ 946 ReConnectBackoffThreshold: deliverservice.DefaultReConnectBackoffThreshold, 947 ReconnectTotalTimeThreshold: deliverservice.DefaultReConnectTotalTimeThreshold, 948 }, 949 ) 950 assert.NoError(t, err) 951 gService := gossipService 952 defer gService.Stop() 953 954 go grpcServer.Serve(socket) 955 defer grpcServer.Stop() 956 957 jcm := &joinChannelMessage{seqNum: 1, members2AnchorPeers: map[string][]api.AnchorPeer{ 958 "A": {{Host: "host", Port: 5000}}, 959 }} 960 961 assert.Equal(t, uint64(1), jcm.SequenceNumber()) 962 963 mc := &mockConfig{ 964 sequence: 1, 965 orgs: map[string]channelconfig.ApplicationOrg{ 966 string(orgInChannelA): &appGrp{ 967 mspID: string(orgInChannelA), 968 anchorPeers: []*peer.AnchorPeer{{Host: "localhost", Port: 2001}}, 969 }, 970 }, 971 } 972 gService.JoinChan(jcm, gossipcommon.ChannelID("A")) 973 // use mock secAdv so that gService.secAdv.OrgByPeerIdentity can return the matched identity 974 gService.secAdv = &secAdvMock{} 975 gService.updateAnchors(mc) 976 assert.True(t, gService.amIinChannel(string(orgInChannelA), mc)) 977 assert.True(t, gService.anchorPeerTracker.IsAnchorPeer("localhost:2001")) 978 assert.False(t, gService.anchorPeerTracker.IsAnchorPeer("localhost:5000")) 979 }