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  }