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