github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/gossip/service/gossip_service_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package service
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"net"
    23  	"sync"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/hyperledger/fabric/common/config"
    28  	"github.com/hyperledger/fabric/common/localmsp"
    29  	"github.com/hyperledger/fabric/core/deliverservice"
    30  	"github.com/hyperledger/fabric/core/deliverservice/blocksprovider"
    31  	"github.com/hyperledger/fabric/gossip/api"
    32  	gossipCommon "github.com/hyperledger/fabric/gossip/common"
    33  	"github.com/hyperledger/fabric/gossip/election"
    34  	"github.com/hyperledger/fabric/gossip/gossip"
    35  	"github.com/hyperledger/fabric/gossip/identity"
    36  	"github.com/hyperledger/fabric/gossip/state"
    37  	"github.com/hyperledger/fabric/gossip/util"
    38  	"github.com/hyperledger/fabric/msp/mgmt"
    39  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    40  	peergossip "github.com/hyperledger/fabric/peer/gossip"
    41  	"github.com/hyperledger/fabric/peer/gossip/mocks"
    42  	"github.com/hyperledger/fabric/protos/common"
    43  	"github.com/hyperledger/fabric/protos/peer"
    44  	"github.com/spf13/viper"
    45  	"github.com/stretchr/testify/assert"
    46  	"google.golang.org/grpc"
    47  )
    48  
    49  func init() {
    50  	util.SetupTestLogging()
    51  }
    52  
    53  func TestInitGossipService(t *testing.T) {
    54  	// Test whenever gossip service is indeed singleton
    55  	grpcServer := grpc.NewServer()
    56  	socket, error := net.Listen("tcp", fmt.Sprintf("%s:%d", "", 5611))
    57  	assert.NoError(t, error)
    58  
    59  	go grpcServer.Serve(socket)
    60  	defer grpcServer.Stop()
    61  
    62  	msptesttools.LoadMSPSetupForTesting()
    63  	identity, _ := mgmt.GetLocalSigningIdentityOrPanic().Serialize()
    64  
    65  	wg := sync.WaitGroup{}
    66  	wg.Add(10)
    67  	for i := 0; i < 10; i++ {
    68  		go func() {
    69  			messageCryptoService := peergossip.NewMCS(&mocks.ChannelPolicyManagerGetter{}, localmsp.NewSigner(), mgmt.NewDeserializersManager())
    70  			secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager())
    71  			InitGossipService(identity, "localhost:5611", grpcServer, messageCryptoService,
    72  				secAdv, nil)
    73  
    74  			wg.Done()
    75  		}()
    76  	}
    77  	wg.Wait()
    78  
    79  	defer GetGossipService().Stop()
    80  	gossip := GetGossipService()
    81  
    82  	for i := 0; i < 10; i++ {
    83  		go func(gossipInstance GossipService) {
    84  			assert.Equal(t, gossip, GetGossipService())
    85  		}(gossip)
    86  	}
    87  
    88  	time.Sleep(time.Second * 2)
    89  }
    90  
    91  // Make sure *joinChannelMessage implements the api.JoinChannelMessage
    92  func TestJCMInterface(t *testing.T) {
    93  	_ = api.JoinChannelMessage(&joinChannelMessage{})
    94  }
    95  
    96  func TestLeaderElectionWithDeliverClient(t *testing.T) {
    97  
    98  	//Test check if leader election works with mock deliver service instance
    99  	//Configuration set to use dynamic leader election
   100  	//10 peers started, added to channel and at the end we check if only for one peer
   101  	//mockDeliverService.StartDeliverForChannel was invoked
   102  
   103  	viper.Set("peer.gossip.useLeaderElection", true)
   104  	viper.Set("peer.gossip.orgLeader", false)
   105  
   106  	n := 10
   107  	gossips := startPeers(t, n, 20000)
   108  
   109  	channelName := "chanA"
   110  	peerIndexes := make([]int, n)
   111  	for i := 0; i < n; i++ {
   112  		peerIndexes[i] = i
   113  	}
   114  	addPeersToChannel(t, n, 20000, channelName, gossips, peerIndexes)
   115  
   116  	waitForFullMembership(t, gossips, n, time.Second*20, time.Second*2)
   117  
   118  	services := make([]*electionService, n)
   119  
   120  	for i := 0; i < n; i++ {
   121  		deliverServiceFactory := &mockDeliverServiceFactory{
   122  			service: &mockDeliverService{
   123  				running: make(map[string]bool),
   124  			},
   125  		}
   126  		gossips[i].(*gossipServiceImpl).deliveryFactory = deliverServiceFactory
   127  		deliverServiceFactory.service.running[channelName] = false
   128  
   129  		gossips[i].InitializeChannel(channelName, &mockLedgerInfo{1}, []string{"localhost:5005"})
   130  		service, exist := gossips[i].(*gossipServiceImpl).leaderElection[channelName]
   131  		assert.True(t, exist, "Leader election service should be created for peer %d and channel %s", i, channelName)
   132  		services[i] = &electionService{nil, false, 0}
   133  		services[i].LeaderElectionService = service
   134  	}
   135  
   136  	// Is single leader was elected.
   137  	assert.True(t, waitForLeaderElection(t, services, time.Second*30, time.Second*2), "One leader should be selected")
   138  
   139  	startsNum := 0
   140  	for i := 0; i < n; i++ {
   141  		// Is mockDeliverService.StartDeliverForChannel in current peer for the specific channel was invoked
   142  		if gossips[i].(*gossipServiceImpl).deliveryService.(*mockDeliverService).running[channelName] {
   143  			startsNum++
   144  		}
   145  	}
   146  
   147  	assert.Equal(t, 1, startsNum, "Only for one peer delivery client should start")
   148  
   149  	stopPeers(gossips)
   150  }
   151  
   152  func TestWithStaticDeliverClientLeader(t *testing.T) {
   153  
   154  	//Tests check if static leader flag works ok.
   155  	//Leader election flag set to false, and static leader flag set to true
   156  	//Two gossip service instances (peers) created.
   157  	//Each peer is added to channel and should run mock delivery client
   158  	//After that each peer added to another client and it should run deliver client for this channel as well.
   159  
   160  	viper.Set("peer.gossip.useLeaderElection", false)
   161  	viper.Set("peer.gossip.orgLeader", true)
   162  
   163  	n := 2
   164  	gossips := startPeers(t, n, 20000)
   165  
   166  	channelName := "chanA"
   167  	peerIndexes := make([]int, n)
   168  	for i := 0; i < n; i++ {
   169  		peerIndexes[i] = i
   170  	}
   171  
   172  	addPeersToChannel(t, n, 20000, channelName, gossips, peerIndexes)
   173  
   174  	waitForFullMembership(t, gossips, n, time.Second*30, time.Second*2)
   175  
   176  	deliverServiceFactory := &mockDeliverServiceFactory{
   177  		service: &mockDeliverService{
   178  			running: make(map[string]bool),
   179  		},
   180  	}
   181  
   182  	for i := 0; i < n; i++ {
   183  		gossips[i].(*gossipServiceImpl).deliveryFactory = deliverServiceFactory
   184  		deliverServiceFactory.service.running[channelName] = false
   185  		gossips[i].InitializeChannel(channelName, &mockLedgerInfo{1}, []string{"localhost:5005"})
   186  	}
   187  
   188  	for i := 0; i < n; i++ {
   189  		assert.NotNil(t, gossips[i].(*gossipServiceImpl).deliveryService, "Delivery service not initiated in peer %d", i)
   190  		assert.True(t, gossips[i].(*gossipServiceImpl).deliveryService.(*mockDeliverService).running[channelName], "Block deliverer not started for peer %d", i)
   191  	}
   192  
   193  	channelName = "chanB"
   194  	for i := 0; i < n; i++ {
   195  		deliverServiceFactory.service.running[channelName] = false
   196  		gossips[i].InitializeChannel(channelName, &mockLedgerInfo{1}, []string{"localhost:5005"})
   197  	}
   198  
   199  	for i := 0; i < n; i++ {
   200  		assert.NotNil(t, gossips[i].(*gossipServiceImpl).deliveryService, "Delivery service not initiated in peer %d", i)
   201  		assert.True(t, gossips[i].(*gossipServiceImpl).deliveryService.(*mockDeliverService).running[channelName], "Block deliverer not started for peer %d", i)
   202  	}
   203  
   204  	stopPeers(gossips)
   205  }
   206  
   207  func TestWithStaticDeliverClientNotLeader(t *testing.T) {
   208  	viper.Set("peer.gossip.useLeaderElection", false)
   209  	viper.Set("peer.gossip.orgLeader", false)
   210  
   211  	n := 2
   212  	gossips := startPeers(t, n, 20000)
   213  
   214  	channelName := "chanA"
   215  	peerIndexes := make([]int, n)
   216  	for i := 0; i < n; i++ {
   217  		peerIndexes[i] = i
   218  	}
   219  
   220  	addPeersToChannel(t, n, 20000, channelName, gossips, peerIndexes)
   221  
   222  	waitForFullMembership(t, gossips, n, time.Second*30, time.Second*2)
   223  
   224  	deliverServiceFactory := &mockDeliverServiceFactory{
   225  		service: &mockDeliverService{
   226  			running: make(map[string]bool),
   227  		},
   228  	}
   229  
   230  	for i := 0; i < n; i++ {
   231  		gossips[i].(*gossipServiceImpl).deliveryFactory = deliverServiceFactory
   232  		deliverServiceFactory.service.running[channelName] = false
   233  		gossips[i].InitializeChannel(channelName, &mockLedgerInfo{1}, []string{"localhost:5005"})
   234  	}
   235  
   236  	for i := 0; i < n; i++ {
   237  		assert.NotNil(t, gossips[i].(*gossipServiceImpl).deliveryService, "Delivery service not initiated in peer %d", i)
   238  		assert.False(t, gossips[i].(*gossipServiceImpl).deliveryService.(*mockDeliverService).running[channelName], "Block deliverer should not be started for peer %d", i)
   239  	}
   240  
   241  	stopPeers(gossips)
   242  }
   243  
   244  func TestWithStaticDeliverClientBothStaticAndLeaderElection(t *testing.T) {
   245  	viper.Set("peer.gossip.useLeaderElection", true)
   246  	viper.Set("peer.gossip.orgLeader", true)
   247  
   248  	n := 2
   249  	gossips := startPeers(t, n, 20000)
   250  
   251  	channelName := "chanA"
   252  	peerIndexes := make([]int, n)
   253  	for i := 0; i < n; i++ {
   254  		peerIndexes[i] = i
   255  	}
   256  
   257  	addPeersToChannel(t, n, 20000, channelName, gossips, peerIndexes)
   258  
   259  	waitForFullMembership(t, gossips, n, time.Second*30, time.Second*2)
   260  
   261  	deliverServiceFactory := &mockDeliverServiceFactory{
   262  		service: &mockDeliverService{
   263  			running: make(map[string]bool),
   264  		},
   265  	}
   266  
   267  	for i := 0; i < n; i++ {
   268  		gossips[i].(*gossipServiceImpl).deliveryFactory = deliverServiceFactory
   269  		assert.Panics(t, func() {
   270  			gossips[i].InitializeChannel(channelName, &mockLedgerInfo{1}, []string{"localhost:5005"})
   271  		}, "Dynamic leader lection based and static connection to ordering service can't exist simultaniosly")
   272  	}
   273  
   274  	stopPeers(gossips)
   275  }
   276  
   277  type mockDeliverServiceFactory struct {
   278  	service *mockDeliverService
   279  }
   280  
   281  func (mf *mockDeliverServiceFactory) Service(g GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) {
   282  	return mf.service, nil
   283  }
   284  
   285  type mockDeliverService struct {
   286  	running map[string]bool
   287  }
   288  
   289  func (ds *mockDeliverService) StartDeliverForChannel(chainID string, ledgerInfo blocksprovider.LedgerInfo) error {
   290  	ds.running[chainID] = true
   291  	return nil
   292  }
   293  
   294  func (ds *mockDeliverService) StopDeliverForChannel(chainID string) error {
   295  	ds.running[chainID] = false
   296  	return nil
   297  }
   298  
   299  func (ds *mockDeliverService) Stop() {
   300  }
   301  
   302  type mockLedgerInfo struct {
   303  	Height uint64
   304  }
   305  
   306  // LedgerHeight returns mocked value to the ledger height
   307  func (li *mockLedgerInfo) LedgerHeight() (uint64, error) {
   308  	return li.Height, nil
   309  }
   310  
   311  // Commit block to the ledger
   312  func (li *mockLedgerInfo) Commit(block *common.Block) error {
   313  	return nil
   314  }
   315  
   316  // Gets blocks with sequence numbers provided in the slice
   317  func (li *mockLedgerInfo) GetBlocks(blockSeqs []uint64) []*common.Block {
   318  	return make([]*common.Block, 0)
   319  }
   320  
   321  // Closes committing service
   322  func (li *mockLedgerInfo) Close() {
   323  }
   324  
   325  func TestLeaderElectionWithRealGossip(t *testing.T) {
   326  
   327  	// Spawn 10 gossip instances with single channel and inside same organization
   328  	// Run leader election on top of each gossip instance and check that only one leader chosen
   329  	// Create another channel includes sub-set of peers over same gossip instances {1,3,5,7}
   330  	// Run additional leader election services for new channel
   331  	// Check correct leader still exist for first channel and new correct leader chosen in second channel
   332  	// Stop gossip instances of leader peers for both channels and see that new leader chosen for both
   333  
   334  	// Creating gossip service instances for peers
   335  	n := 10
   336  	gossips := startPeers(t, n, 20000)
   337  
   338  	// Joining all peers to first channel
   339  	channelName := "chanA"
   340  	peerIndexes := make([]int, n)
   341  	for i := 0; i < n; i++ {
   342  		peerIndexes[i] = i
   343  	}
   344  	addPeersToChannel(t, n, 20000, channelName, gossips, peerIndexes)
   345  
   346  	waitForFullMembership(t, gossips, n, time.Second*30, time.Second*2)
   347  
   348  	logger.Warning("Starting leader election services")
   349  
   350  	//Starting leader election services
   351  	services := make([]*electionService, n)
   352  
   353  	for i := 0; i < n; i++ {
   354  		services[i] = &electionService{nil, false, 0}
   355  		services[i].LeaderElectionService = gossips[i].(*gossipServiceImpl).newLeaderElectionComponent(channelName, services[i].callback)
   356  	}
   357  
   358  	logger.Warning("Waiting for leader election")
   359  
   360  	assert.True(t, waitForLeaderElection(t, services, time.Second*30, time.Second*2), "One leader should be selected")
   361  
   362  	startsNum := 0
   363  	for i := 0; i < n; i++ {
   364  		// Is callback function was invoked by this leader election service instance
   365  		if services[i].callbackInvokeRes {
   366  			startsNum++
   367  		}
   368  	}
   369  	//Only leader should invoke callback function, so it is double check that only one leader exists
   370  	assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanA")
   371  
   372  	// Adding some peers to new channel and creating leader election services for peers in new channel
   373  	// Expecting peer 1 (first in list of election services) to become leader of second channel
   374  	secondChannelPeerIndexes := []int{1, 3, 5, 7}
   375  	secondChannelName := "chanB"
   376  	secondChannelServices := make([]*electionService, len(secondChannelPeerIndexes))
   377  	addPeersToChannel(t, n, 20000, secondChannelName, gossips, secondChannelPeerIndexes)
   378  
   379  	for idx, i := range secondChannelPeerIndexes {
   380  		secondChannelServices[idx] = &electionService{nil, false, 0}
   381  		secondChannelServices[idx].LeaderElectionService = gossips[i].(*gossipServiceImpl).newLeaderElectionComponent(secondChannelName, secondChannelServices[idx].callback)
   382  	}
   383  
   384  	assert.True(t, waitForLeaderElection(t, secondChannelServices, time.Second*30, time.Second*2), "One leader should be selected for chanB")
   385  	assert.True(t, waitForLeaderElection(t, services, time.Second*30, time.Second*2), "One leader should be selected for chanA")
   386  
   387  	startsNum = 0
   388  	for i := 0; i < n; i++ {
   389  		if services[i].callbackInvokeRes {
   390  			startsNum++
   391  		}
   392  	}
   393  	assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanA")
   394  
   395  	startsNum = 0
   396  	for i := 0; i < len(secondChannelServices); i++ {
   397  		if secondChannelServices[i].callbackInvokeRes {
   398  			startsNum++
   399  		}
   400  	}
   401  	assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanB")
   402  
   403  	//Stopping 2 gossip instances(peer 0 and peer 1), should init re-election
   404  	//Now peer 2 become leader for first channel and peer 3 for second channel
   405  
   406  	logger.Warning("Killing 2 peers, initiation new leader election")
   407  
   408  	stopPeers(gossips[:2])
   409  
   410  	waitForFullMembership(t, gossips[2:], n-2, time.Second*30, time.Second*2)
   411  
   412  	assert.True(t, waitForLeaderElection(t, services[2:], time.Second*30, time.Second*2), "One leader should be selected after re-election - chanA")
   413  	assert.True(t, waitForLeaderElection(t, secondChannelServices[1:], time.Second*30, time.Second*2), "One leader should be selected after re-election - chanB")
   414  
   415  	startsNum = 0
   416  	for i := 2; i < n; i++ {
   417  		if services[i].callbackInvokeRes {
   418  			startsNum++
   419  		}
   420  	}
   421  	assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called after re-election - chanA")
   422  
   423  	startsNum = 0
   424  	for i := 1; i < len(secondChannelServices); i++ {
   425  		if secondChannelServices[i].callbackInvokeRes {
   426  			startsNum++
   427  		}
   428  	}
   429  	assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called after re-election - chanB")
   430  
   431  	stopServices(secondChannelServices)
   432  	stopServices(services)
   433  	stopPeers(gossips[2:])
   434  }
   435  
   436  type electionService struct {
   437  	election.LeaderElectionService
   438  	callbackInvokeRes   bool
   439  	callbackInvokeCount int
   440  }
   441  
   442  func (es *electionService) callback(isLeader bool) {
   443  	es.callbackInvokeRes = isLeader
   444  	es.callbackInvokeCount = es.callbackInvokeCount + 1
   445  }
   446  
   447  type joinChanMsg struct {
   448  }
   449  
   450  // SequenceNumber returns the sequence number of the block this joinChanMsg
   451  // is derived from
   452  func (jmc *joinChanMsg) SequenceNumber() uint64 {
   453  	return uint64(time.Now().UnixNano())
   454  }
   455  
   456  // Members returns the organizations of the channel
   457  func (jmc *joinChanMsg) Members() []api.OrgIdentityType {
   458  	return []api.OrgIdentityType{orgInChannelA}
   459  }
   460  
   461  // AnchorPeersOf returns the anchor peers of the given organization
   462  func (jmc *joinChanMsg) AnchorPeersOf(org api.OrgIdentityType) []api.AnchorPeer {
   463  	return []api.AnchorPeer{}
   464  }
   465  
   466  func waitForFullMembership(t *testing.T, gossips []GossipService, peersNum int, timeout time.Duration, testPollInterval time.Duration) bool {
   467  	end := time.Now().Add(timeout)
   468  	var correctPeers int
   469  	for time.Now().Before(end) {
   470  		correctPeers = 0
   471  		for _, g := range gossips {
   472  			if len(g.Peers()) == (peersNum - 1) {
   473  				correctPeers++
   474  			}
   475  		}
   476  		if correctPeers == peersNum {
   477  			return true
   478  		}
   479  		time.Sleep(testPollInterval)
   480  	}
   481  	logger.Warningf("Only %d peers have full membership", correctPeers)
   482  	return false
   483  }
   484  
   485  func waitForMultipleLeadersElection(t *testing.T, services []*electionService, leadersNum int, timeout time.Duration, testPollInterval time.Duration) bool {
   486  	logger.Warning("Waiting for", leadersNum, "leaders")
   487  	end := time.Now().Add(timeout)
   488  	correctNumberOfLeadersFound := false
   489  	leaders := 0
   490  	for time.Now().Before(end) {
   491  		leaders = 0
   492  		for _, s := range services {
   493  			if s.IsLeader() {
   494  				leaders++
   495  			}
   496  		}
   497  		if leaders == leadersNum {
   498  			if correctNumberOfLeadersFound {
   499  				return true
   500  			}
   501  			correctNumberOfLeadersFound = true
   502  		} else {
   503  			correctNumberOfLeadersFound = false
   504  		}
   505  		time.Sleep(testPollInterval)
   506  	}
   507  	logger.Warning("Incorrect number of leaders", leaders)
   508  	for i, s := range services {
   509  		logger.Warning("Peer at index", i, "is leader", s.IsLeader())
   510  	}
   511  	return false
   512  }
   513  
   514  func waitForLeaderElection(t *testing.T, services []*electionService, timeout time.Duration, testPollInterval time.Duration) bool {
   515  	return waitForMultipleLeadersElection(t, services, 1, timeout, testPollInterval)
   516  }
   517  
   518  func waitUntilOrFailBlocking(t *testing.T, f func(), timeout time.Duration) {
   519  	successChan := make(chan struct{}, 1)
   520  	go func() {
   521  		f()
   522  		successChan <- struct{}{}
   523  	}()
   524  	select {
   525  	case <-time.NewTimer(timeout).C:
   526  		break
   527  	case <-successChan:
   528  		return
   529  	}
   530  	util.PrintStackTrace()
   531  	assert.Fail(t, "Timeout expired!")
   532  }
   533  
   534  func stopServices(services []*electionService) {
   535  	stoppingWg := sync.WaitGroup{}
   536  	stoppingWg.Add(len(services))
   537  	for i, sI := range services {
   538  		go func(i int, s_i election.LeaderElectionService) {
   539  			defer stoppingWg.Done()
   540  			s_i.Stop()
   541  		}(i, sI)
   542  	}
   543  	stoppingWg.Wait()
   544  	time.Sleep(time.Second * time.Duration(2))
   545  }
   546  
   547  func stopPeers(peers []GossipService) {
   548  	stoppingWg := sync.WaitGroup{}
   549  	stoppingWg.Add(len(peers))
   550  	for i, pI := range peers {
   551  		go func(i int, p_i GossipService) {
   552  			defer stoppingWg.Done()
   553  			p_i.Stop()
   554  		}(i, pI)
   555  	}
   556  	stoppingWg.Wait()
   557  	time.Sleep(time.Second * time.Duration(2))
   558  }
   559  
   560  func addPeersToChannel(t *testing.T, n int, portPrefix int, channel string, peers []GossipService, peerIndexes []int) {
   561  	jcm := &joinChanMsg{}
   562  
   563  	wg := sync.WaitGroup{}
   564  	for _, i := range peerIndexes {
   565  		wg.Add(1)
   566  		go func(i int) {
   567  			peers[i].JoinChan(jcm, gossipCommon.ChainID(channel))
   568  			peers[i].UpdateChannelMetadata([]byte("bla bla"), gossipCommon.ChainID(channel))
   569  			wg.Done()
   570  		}(i)
   571  	}
   572  	waitUntilOrFailBlocking(t, wg.Wait, time.Second*10)
   573  }
   574  
   575  func startPeers(t *testing.T, n int, portPrefix int) []GossipService {
   576  
   577  	peers := make([]GossipService, n)
   578  	wg := sync.WaitGroup{}
   579  	for i := 0; i < n; i++ {
   580  		wg.Add(1)
   581  		go func(i int) {
   582  
   583  			peers[i] = newGossipInstance(portPrefix, i, 100, 0, 1, 2, 3, 4, 5)
   584  			wg.Done()
   585  		}(i)
   586  	}
   587  	waitUntilOrFailBlocking(t, wg.Wait, time.Second*10)
   588  
   589  	return peers
   590  }
   591  
   592  func newGossipInstance(portPrefix int, id int, maxMsgCount int, boot ...int) GossipService {
   593  	port := id + portPrefix
   594  	conf := &gossip.Config{
   595  		BindPort:                   port,
   596  		BootstrapPeers:             bootPeers(portPrefix, boot...),
   597  		ID:                         fmt.Sprintf("p%d", id),
   598  		MaxBlockCountToStore:       maxMsgCount,
   599  		MaxPropagationBurstLatency: time.Duration(500) * time.Millisecond,
   600  		MaxPropagationBurstSize:    20,
   601  		PropagateIterations:        1,
   602  		PropagatePeerNum:           3,
   603  		PullInterval:               time.Duration(2) * time.Second,
   604  		PullPeerNum:                5,
   605  		InternalEndpoint:           fmt.Sprintf("localhost:%d", port),
   606  		ExternalEndpoint:           fmt.Sprintf("1.2.3.4:%d", port),
   607  		PublishCertPeriod:          time.Duration(4) * time.Second,
   608  		PublishStateInfoInterval:   time.Duration(1) * time.Second,
   609  		RequestStateInfoInterval:   time.Duration(1) * time.Second,
   610  	}
   611  	selfId := api.PeerIdentityType(conf.InternalEndpoint)
   612  	cryptoService := &naiveCryptoService{}
   613  	idMapper := identity.NewIdentityMapper(cryptoService, selfId)
   614  
   615  	gossip := gossip.NewGossipServiceWithServer(conf, &orgCryptoService{}, cryptoService,
   616  		idMapper, selfId, nil)
   617  
   618  	gossipService := &gossipServiceImpl{
   619  		gossipSvc:       gossip,
   620  		chains:          make(map[string]state.GossipStateProvider),
   621  		leaderElection:  make(map[string]election.LeaderElectionService),
   622  		deliveryFactory: &deliveryFactoryImpl{},
   623  		idMapper:        idMapper,
   624  		peerIdentity:    api.PeerIdentityType(conf.InternalEndpoint),
   625  	}
   626  
   627  	return gossipService
   628  }
   629  
   630  func bootPeers(portPrefix int, ids ...int) []string {
   631  	peers := []string{}
   632  	for _, id := range ids {
   633  		peers = append(peers, fmt.Sprintf("localhost:%d", id+portPrefix))
   634  	}
   635  	return peers
   636  }
   637  
   638  type naiveCryptoService struct {
   639  }
   640  
   641  type orgCryptoService struct {
   642  }
   643  
   644  // OrgByPeerIdentity returns the OrgIdentityType
   645  // of a given peer identity
   646  func (*orgCryptoService) OrgByPeerIdentity(identity api.PeerIdentityType) api.OrgIdentityType {
   647  	return orgInChannelA
   648  }
   649  
   650  // Verify verifies a JoinChanMessage, returns nil on success,
   651  // and an error on failure
   652  func (*orgCryptoService) Verify(joinChanMsg api.JoinChannelMessage) error {
   653  	return nil
   654  }
   655  
   656  // VerifyByChannel verifies a peer's signature on a message in the context
   657  // of a specific channel
   658  func (*naiveCryptoService) VerifyByChannel(_ gossipCommon.ChainID, _ api.PeerIdentityType, _, _ []byte) error {
   659  	return nil
   660  }
   661  
   662  func (*naiveCryptoService) ValidateIdentity(peerIdentity api.PeerIdentityType) error {
   663  	return nil
   664  }
   665  
   666  // GetPKIidOfCert returns the PKI-ID of a peer's identity
   667  func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) gossipCommon.PKIidType {
   668  	return gossipCommon.PKIidType(peerIdentity)
   669  }
   670  
   671  // VerifyBlock returns nil if the block is properly signed,
   672  // else returns error
   673  func (*naiveCryptoService) VerifyBlock(chainID gossipCommon.ChainID, seqNum uint64, signedBlock []byte) error {
   674  	return nil
   675  }
   676  
   677  // Sign signs msg with this peer's signing key and outputs
   678  // the signature if no error occurred.
   679  func (*naiveCryptoService) Sign(msg []byte) ([]byte, error) {
   680  	return msg, nil
   681  }
   682  
   683  // Verify checks that signature is a valid signature of message under a peer's verification key.
   684  // If the verification succeeded, Verify returns nil meaning no error occurred.
   685  // If peerCert is nil, then the signature is verified against this peer's verification key.
   686  func (*naiveCryptoService) Verify(peerIdentity api.PeerIdentityType, signature, message []byte) error {
   687  	equal := bytes.Equal(signature, message)
   688  	if !equal {
   689  		return fmt.Errorf("Wrong signature:%v, %v", signature, message)
   690  	}
   691  	return nil
   692  }
   693  
   694  var orgInChannelA = api.OrgIdentityType("ORG1")
   695  
   696  func TestInvalidInitialization(t *testing.T) {
   697  	// Test whenever gossip service is indeed singleton
   698  	grpcServer := grpc.NewServer()
   699  	socket, error := net.Listen("tcp", fmt.Sprintf("%s:%d", "", 7611))
   700  	assert.NoError(t, error)
   701  
   702  	go grpcServer.Serve(socket)
   703  	defer grpcServer.Stop()
   704  
   705  	secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager())
   706  	InitGossipService(api.PeerIdentityType("IDENTITY"), "localhost:7611", grpcServer,
   707  		&naiveCryptoService{}, secAdv, nil)
   708  	gService := GetGossipService().(*gossipServiceImpl)
   709  	defer gService.Stop()
   710  
   711  	dc, err := gService.deliveryFactory.Service(gService, []string{}, &naiveCryptoService{})
   712  	assert.Nil(t, dc)
   713  	assert.Error(t, err)
   714  
   715  	dc, err = gService.deliveryFactory.Service(gService, []string{"localhost:1984"}, &naiveCryptoService{})
   716  	assert.NotNil(t, dc)
   717  	assert.NoError(t, err)
   718  }
   719  
   720  func TestChannelConfig(t *testing.T) {
   721  	// Test whenever gossip service is indeed singleton
   722  	grpcServer := grpc.NewServer()
   723  	socket, error := net.Listen("tcp", fmt.Sprintf("%s:%d", "", 6611))
   724  	assert.NoError(t, error)
   725  
   726  	go grpcServer.Serve(socket)
   727  	defer grpcServer.Stop()
   728  
   729  	secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager())
   730  	InitGossipService(api.PeerIdentityType("IDENTITY"), "localhost:6611", grpcServer,
   731  		&naiveCryptoService{}, secAdv, nil)
   732  	gService := GetGossipService().(*gossipServiceImpl)
   733  	defer gService.Stop()
   734  
   735  	jcm := &joinChannelMessage{seqNum: 1, members2AnchorPeers: map[string][]api.AnchorPeer{
   736  		"A": {{Host: "host", Port: 5000}},
   737  	}}
   738  
   739  	assert.Equal(t, uint64(1), jcm.SequenceNumber())
   740  
   741  	mc := &mockConfig{
   742  		sequence: 1,
   743  		orgs: map[string]config.ApplicationOrg{
   744  			string(orgInChannelA): &appGrp{
   745  				mspID:       string(orgInChannelA),
   746  				anchorPeers: []*peer.AnchorPeer{},
   747  			},
   748  		},
   749  	}
   750  	gService.JoinChan(jcm, gossipCommon.ChainID("A"))
   751  	gService.configUpdated(mc)
   752  	assert.True(t, gService.amIinChannel(string(orgInChannelA), mc))
   753  }