github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/cluster/util_test.go (about)

     1  /*
     2  Copyright hechain. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package cluster_test
     8  
     9  import (
    10  	"bytes"
    11  	"crypto/x509"
    12  	"encoding/pem"
    13  	"errors"
    14  	"fmt"
    15  	"io/ioutil"
    16  	"strings"
    17  	"sync"
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/golang/protobuf/proto"
    22  	"github.com/hechain20/hechain/bccsp/sw"
    23  	"github.com/hechain20/hechain/common/capabilities"
    24  	"github.com/hechain20/hechain/common/channelconfig"
    25  	"github.com/hechain20/hechain/common/configtx"
    26  	"github.com/hechain20/hechain/common/configtx/test"
    27  	"github.com/hechain20/hechain/common/crypto/tlsgen"
    28  	"github.com/hechain20/hechain/common/flogging"
    29  	"github.com/hechain20/hechain/common/policies"
    30  	"github.com/hechain20/hechain/core/config/configtest"
    31  	"github.com/hechain20/hechain/internal/configtxgen/encoder"
    32  	"github.com/hechain20/hechain/internal/configtxgen/genesisconfig"
    33  	"github.com/hechain20/hechain/internal/pkg/comm"
    34  	"github.com/hechain20/hechain/orderer/common/cluster"
    35  	"github.com/hechain20/hechain/orderer/common/cluster/mocks"
    36  	"github.com/hechain20/hechain/protoutil"
    37  	"github.com/hyperledger/fabric-protos-go/common"
    38  	"github.com/hyperledger/fabric-protos-go/msp"
    39  	"github.com/stretchr/testify/mock"
    40  	"github.com/stretchr/testify/require"
    41  	"go.uber.org/zap"
    42  	"go.uber.org/zap/zapcore"
    43  )
    44  
    45  //go:generate counterfeiter -o mocks/policy.go --fake-name Policy . policy
    46  
    47  type policy interface {
    48  	policies.Policy
    49  }
    50  
    51  //go:generate counterfeiter -o mocks/policy_manager.go --fake-name PolicyManager . policyManager
    52  
    53  type policyManager interface {
    54  	policies.Manager
    55  }
    56  
    57  func TestParallelStubActivation(t *testing.T) {
    58  	// Scenario: Activate the stub from different goroutines in parallel.
    59  	stub := &cluster.Stub{}
    60  	var wg sync.WaitGroup
    61  	n := 100
    62  	wg.Add(n)
    63  	instance := &cluster.RemoteContext{}
    64  	var activationCount int
    65  	maybeCreateInstance := func() (*cluster.RemoteContext, error) {
    66  		activationCount++
    67  		return instance, nil
    68  	}
    69  
    70  	for i := 0; i < n; i++ {
    71  		go func() {
    72  			defer wg.Done()
    73  			stub.Activate(maybeCreateInstance)
    74  		}()
    75  	}
    76  	wg.Wait()
    77  	activatedStub := stub.RemoteContext
    78  	// Ensure the instance is the reference we stored
    79  	// and not any other reference, i.e - it wasn't
    80  	// copied by value.
    81  	require.True(t, activatedStub == instance)
    82  	// Ensure the method was invoked only once.
    83  	require.Equal(t, activationCount, 1)
    84  }
    85  
    86  func TestDialerCustomKeepAliveOptions(t *testing.T) {
    87  	ca, err := tlsgen.NewCA()
    88  	require.NoError(t, err)
    89  
    90  	clientKeyPair, err := ca.NewClientCertKeyPair()
    91  	require.NoError(t, err)
    92  	clientConfig := comm.ClientConfig{
    93  		KaOpts: comm.KeepaliveOptions{
    94  			ClientTimeout: time.Second * 12345,
    95  		},
    96  		DialTimeout: time.Millisecond * 100,
    97  		SecOpts: comm.SecureOptions{
    98  			RequireClientCert: true,
    99  			Key:               clientKeyPair.Key,
   100  			Certificate:       clientKeyPair.Cert,
   101  			ServerRootCAs:     [][]byte{ca.CertBytes()},
   102  			UseTLS:            true,
   103  			ClientRootCAs:     [][]byte{ca.CertBytes()},
   104  		},
   105  	}
   106  
   107  	dialer := &cluster.PredicateDialer{Config: clientConfig}
   108  	timeout := dialer.Config.KaOpts.ClientTimeout
   109  	require.Equal(t, time.Second*12345, timeout)
   110  }
   111  
   112  func TestPredicateDialerUpdateRootCAs(t *testing.T) {
   113  	node1 := newTestNode(t)
   114  	defer node1.stop()
   115  
   116  	anotherTLSCA, err := tlsgen.NewCA()
   117  	require.NoError(t, err)
   118  
   119  	dialer := &cluster.PredicateDialer{
   120  		Config: node1.clientConfig,
   121  	}
   122  	dialer.Config.SecOpts.ServerRootCAs = [][]byte{anotherTLSCA.CertBytes()}
   123  	dialer.Config.DialTimeout = time.Second
   124  	dialer.Config.AsyncConnect = false
   125  
   126  	_, err = dialer.Dial(node1.srv.Address(), nil)
   127  	require.Error(t, err)
   128  
   129  	// Update root TLS CAs asynchronously to make sure we don't have a data race.
   130  	go func() {
   131  		dialer.UpdateRootCAs(node1.clientConfig.SecOpts.ServerRootCAs)
   132  	}()
   133  
   134  	// Eventually we should succeed connecting.
   135  	for i := 0; i < 10; i++ {
   136  		conn, err := dialer.Dial(node1.srv.Address(), nil)
   137  		if err == nil {
   138  			conn.Close()
   139  			return
   140  		}
   141  	}
   142  
   143  	require.Fail(t, "could not connect after 10 attempts despite changing TLS CAs")
   144  }
   145  
   146  func TestDialerBadConfig(t *testing.T) {
   147  	emptyCertificate := []byte("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----")
   148  	dialer := &cluster.PredicateDialer{
   149  		Config: comm.ClientConfig{
   150  			SecOpts: comm.SecureOptions{
   151  				UseTLS:        true,
   152  				ServerRootCAs: [][]byte{emptyCertificate},
   153  			},
   154  		},
   155  	}
   156  	_, err := dialer.Dial("127.0.0.1:8080", func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
   157  		return nil
   158  	})
   159  	require.ErrorContains(t, err, "error adding root certificate")
   160  }
   161  
   162  func TestDERtoPEM(t *testing.T) {
   163  	ca, err := tlsgen.NewCA()
   164  	require.NoError(t, err)
   165  	keyPair, err := ca.NewServerCertKeyPair("localhost")
   166  	require.NoError(t, err)
   167  	require.Equal(t, cluster.DERtoPEM(keyPair.TLSCert.Raw), string(keyPair.Cert))
   168  }
   169  
   170  func TestStandardDialer(t *testing.T) {
   171  	emptyCertificate := []byte("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----")
   172  	certPool := [][]byte{emptyCertificate}
   173  	config := comm.ClientConfig{SecOpts: comm.SecureOptions{UseTLS: true, ServerRootCAs: certPool}}
   174  	standardDialer := &cluster.StandardDialer{
   175  		Config: config,
   176  	}
   177  	_, err := standardDialer.Dial(cluster.EndpointCriteria{Endpoint: "127.0.0.1:8080", TLSRootCAs: certPool})
   178  	require.ErrorContains(t, err, "error adding root certificate")
   179  }
   180  
   181  func TestVerifyBlockSignature(t *testing.T) {
   182  	verifier := &mocks.BlockVerifier{}
   183  	var nilConfigEnvelope *common.ConfigEnvelope
   184  	verifier.On("VerifyBlockSignature", mock.Anything, nilConfigEnvelope).Return(nil)
   185  
   186  	block := createBlockChain(3, 3)[0]
   187  
   188  	// The block should have a valid structure
   189  	err := cluster.VerifyBlockSignature(block, verifier, nil)
   190  	require.NoError(t, err)
   191  
   192  	for _, testCase := range []struct {
   193  		name          string
   194  		mutateBlock   func(*common.Block) *common.Block
   195  		errorContains string
   196  	}{
   197  		{
   198  			name:          "nil metadata",
   199  			errorContains: "no metadata in block",
   200  			mutateBlock: func(block *common.Block) *common.Block {
   201  				block.Metadata = nil
   202  				return block
   203  			},
   204  		},
   205  		{
   206  			name:          "zero metadata slice",
   207  			errorContains: "no metadata in block",
   208  			mutateBlock: func(block *common.Block) *common.Block {
   209  				block.Metadata.Metadata = nil
   210  				return block
   211  			},
   212  		},
   213  		{
   214  			name:          "nil metadata",
   215  			errorContains: "failed unmarshalling medatata for signatures",
   216  			mutateBlock: func(block *common.Block) *common.Block {
   217  				block.Metadata.Metadata[0] = []byte{1, 2, 3}
   218  				return block
   219  			},
   220  		},
   221  		{
   222  			name:          "bad signature header",
   223  			errorContains: "failed unmarshalling signature header",
   224  			mutateBlock: func(block *common.Block) *common.Block {
   225  				metadata := protoutil.GetMetadataFromBlockOrPanic(block, common.BlockMetadataIndex_SIGNATURES)
   226  				metadata.Signatures[0].SignatureHeader = []byte{1, 2, 3}
   227  				block.Metadata.Metadata[common.BlockMetadataIndex_SIGNATURES] = protoutil.MarshalOrPanic(metadata)
   228  				return block
   229  			},
   230  		},
   231  	} {
   232  		testCase := testCase
   233  		t.Run(testCase.name, func(t *testing.T) {
   234  			// Create a copy of the block
   235  			blockCopy := &common.Block{}
   236  			err := proto.Unmarshal(protoutil.MarshalOrPanic(block), blockCopy)
   237  			require.NoError(t, err)
   238  			// Mutate the block to sabotage it
   239  			blockCopy = testCase.mutateBlock(blockCopy)
   240  			err = cluster.VerifyBlockSignature(blockCopy, verifier, nil)
   241  			require.Contains(t, err.Error(), testCase.errorContains)
   242  		})
   243  	}
   244  }
   245  
   246  func TestVerifyBlockHash(t *testing.T) {
   247  	var start uint64 = 3
   248  	var end uint64 = 23
   249  
   250  	verify := func(blockchain []*common.Block) error {
   251  		for i := 0; i < len(blockchain); i++ {
   252  			err := cluster.VerifyBlockHash(i, blockchain)
   253  			if err != nil {
   254  				return err
   255  			}
   256  		}
   257  		return nil
   258  	}
   259  
   260  	// Verify that createBlockChain() creates a valid blockchain
   261  	require.NoError(t, verify(createBlockChain(start, end)))
   262  
   263  	twoBlocks := createBlockChain(2, 3)
   264  	twoBlocks[0].Header = nil
   265  	require.EqualError(t, cluster.VerifyBlockHash(1, twoBlocks), "previous block header is nil")
   266  
   267  	// Index out of bounds
   268  	blockchain := createBlockChain(start, end)
   269  	err := cluster.VerifyBlockHash(100, blockchain)
   270  	require.EqualError(t, err, "index 100 out of bounds (total 21 blocks)")
   271  
   272  	for _, testCase := range []struct {
   273  		name                string
   274  		mutateBlockSequence func([]*common.Block) []*common.Block
   275  		errorContains       string
   276  	}{
   277  		{
   278  			name:          "non consecutive sequences",
   279  			errorContains: "sequences 12 and 666 were received consecutively",
   280  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   281  				blockSequence[len(blockSequence)/2].Header.Number = 666
   282  				assignHashes(blockSequence)
   283  				return blockSequence
   284  			},
   285  		},
   286  		{
   287  			name: "data hash mismatch",
   288  			errorContains: "computed hash of block (13) (dcb2ec1c5e482e4914cb953ff8eedd12774b244b12912afbe6001ba5de9ff800)" +
   289  				" doesn't match claimed hash (07)",
   290  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   291  				blockSequence[len(blockSequence)/2].Header.DataHash = []byte{7}
   292  				return blockSequence
   293  			},
   294  		},
   295  		{
   296  			name: "prev hash mismatch",
   297  			errorContains: "block [12]'s hash " +
   298  				"(866351705f1c2f13e10d52ead9d0ca3b80689ede8cc8bf70a6d60c67578323f4) " +
   299  				"mismatches block [13]'s prev block hash (07)",
   300  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   301  				blockSequence[len(blockSequence)/2].Header.PreviousHash = []byte{7}
   302  				return blockSequence
   303  			},
   304  		},
   305  		{
   306  			name:          "nil block header",
   307  			errorContains: "missing block header",
   308  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   309  				blockSequence[0].Header = nil
   310  				return blockSequence
   311  			},
   312  		},
   313  	} {
   314  		testCase := testCase
   315  		t.Run(testCase.name, func(t *testing.T) {
   316  			blockchain := createBlockChain(start, end)
   317  			blockchain = testCase.mutateBlockSequence(blockchain)
   318  			err := verify(blockchain)
   319  			require.EqualError(t, err, testCase.errorContains)
   320  		})
   321  	}
   322  }
   323  
   324  func TestVerifyBlocks(t *testing.T) {
   325  	var sigSet1 []*protoutil.SignedData
   326  	var sigSet2 []*protoutil.SignedData
   327  
   328  	configEnvelope1 := &common.ConfigEnvelope{
   329  		Config: &common.Config{
   330  			Sequence: 1,
   331  		},
   332  	}
   333  	configEnvelope2 := &common.ConfigEnvelope{
   334  		Config: &common.Config{
   335  			Sequence: 2,
   336  		},
   337  	}
   338  	configTransaction := func(envelope *common.ConfigEnvelope) *common.Envelope {
   339  		return &common.Envelope{
   340  			Payload: protoutil.MarshalOrPanic(&common.Payload{
   341  				Data: protoutil.MarshalOrPanic(envelope),
   342  				Header: &common.Header{
   343  					ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{
   344  						Type: int32(common.HeaderType_CONFIG),
   345  					}),
   346  				},
   347  			}),
   348  		}
   349  	}
   350  
   351  	for _, testCase := range []struct {
   352  		name                  string
   353  		configureVerifier     func(*mocks.BlockVerifier)
   354  		mutateBlockSequence   func([]*common.Block) []*common.Block
   355  		expectedError         string
   356  		verifierExpectedCalls int
   357  	}{
   358  		{
   359  			name: "empty sequence",
   360  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   361  				return nil
   362  			},
   363  			expectedError: "buffer is empty",
   364  		},
   365  		{
   366  			name: "prev hash mismatch",
   367  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   368  				blockSequence[len(blockSequence)/2].Header.PreviousHash = []byte{7}
   369  				return blockSequence
   370  			},
   371  			expectedError: "block [74]'s hash " +
   372  				"(5cb4bd1b6a73f81afafd96387bb7ff4473c2425929d0862586f5fbfa12d762dd) " +
   373  				"mismatches block [75]'s prev block hash (07)",
   374  		},
   375  		{
   376  			name: "bad signature",
   377  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   378  				return blockSequence
   379  			},
   380  			configureVerifier: func(verifier *mocks.BlockVerifier) {
   381  				var nilEnvelope *common.ConfigEnvelope
   382  				verifier.On("VerifyBlockSignature", mock.Anything, nilEnvelope).Return(errors.New("bad signature"))
   383  			},
   384  			expectedError:         "bad signature",
   385  			verifierExpectedCalls: 1,
   386  		},
   387  		{
   388  			name: "block that its type cannot be classified",
   389  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   390  				blockSequence[len(blockSequence)/2].Data = &common.BlockData{
   391  					Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{})},
   392  				}
   393  				blockSequence[len(blockSequence)/2].Header.DataHash = protoutil.BlockDataHash(blockSequence[len(blockSequence)/2].Data)
   394  				assignHashes(blockSequence)
   395  				return blockSequence
   396  			},
   397  			expectedError: "nil header in payload",
   398  		},
   399  		{
   400  			name: "config blocks in the sequence need to be verified and one of them is improperly signed",
   401  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   402  				var err error
   403  				// Put a config transaction in block n / 4
   404  				blockSequence[len(blockSequence)/4].Data = &common.BlockData{
   405  					Data: [][]byte{protoutil.MarshalOrPanic(configTransaction(configEnvelope1))},
   406  				}
   407  				blockSequence[len(blockSequence)/4].Header.DataHash = protoutil.BlockDataHash(blockSequence[len(blockSequence)/4].Data)
   408  
   409  				// Put a config transaction in block n / 2
   410  				blockSequence[len(blockSequence)/2].Data = &common.BlockData{
   411  					Data: [][]byte{protoutil.MarshalOrPanic(configTransaction(configEnvelope2))},
   412  				}
   413  				blockSequence[len(blockSequence)/2].Header.DataHash = protoutil.BlockDataHash(blockSequence[len(blockSequence)/2].Data)
   414  
   415  				assignHashes(blockSequence)
   416  
   417  				sigSet1, err = cluster.SignatureSetFromBlock(blockSequence[len(blockSequence)/4])
   418  				require.NoError(t, err)
   419  				sigSet2, err = cluster.SignatureSetFromBlock(blockSequence[len(blockSequence)/2])
   420  				require.NoError(t, err)
   421  
   422  				return blockSequence
   423  			},
   424  			configureVerifier: func(verifier *mocks.BlockVerifier) {
   425  				var nilEnvelope *common.ConfigEnvelope
   426  				// The first config block, validates correctly.
   427  				verifier.On("VerifyBlockSignature", sigSet1, nilEnvelope).Return(nil).Once()
   428  				// However, the second config block - validates incorrectly.
   429  				confEnv1 := &common.ConfigEnvelope{}
   430  				proto.Unmarshal(protoutil.MarshalOrPanic(configEnvelope1), confEnv1)
   431  				verifier.On("VerifyBlockSignature", sigSet2, confEnv1).Return(errors.New("bad signature")).Once()
   432  			},
   433  			expectedError:         "bad signature",
   434  			verifierExpectedCalls: 2,
   435  		},
   436  		{
   437  			name: "config block in the sequence needs to be verified, and it is properly signed",
   438  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   439  				var err error
   440  				// Put a config transaction in block n / 4
   441  				blockSequence[len(blockSequence)/4].Data = &common.BlockData{
   442  					Data: [][]byte{protoutil.MarshalOrPanic(configTransaction(configEnvelope1))},
   443  				}
   444  				blockSequence[len(blockSequence)/4].Header.DataHash = protoutil.BlockDataHash(blockSequence[len(blockSequence)/4].Data)
   445  
   446  				assignHashes(blockSequence)
   447  
   448  				sigSet1, err = cluster.SignatureSetFromBlock(blockSequence[len(blockSequence)/4])
   449  				require.NoError(t, err)
   450  
   451  				sigSet2, err = cluster.SignatureSetFromBlock(blockSequence[len(blockSequence)-1])
   452  				require.NoError(t, err)
   453  
   454  				return blockSequence
   455  			},
   456  			configureVerifier: func(verifier *mocks.BlockVerifier) {
   457  				var nilEnvelope *common.ConfigEnvelope
   458  				confEnv1 := &common.ConfigEnvelope{}
   459  				proto.Unmarshal(protoutil.MarshalOrPanic(configEnvelope1), confEnv1)
   460  				verifier.On("VerifyBlockSignature", sigSet1, nilEnvelope).Return(nil).Once()
   461  				verifier.On("VerifyBlockSignature", sigSet2, confEnv1).Return(nil).Once()
   462  			},
   463  			// We have a single config block in the 'middle' of the chain, so we have 2 verifications total:
   464  			// The last block, and the config block.
   465  			verifierExpectedCalls: 2,
   466  		},
   467  		{
   468  			name: "last two blocks are config blocks, last block only verified once",
   469  			mutateBlockSequence: func(blockSequence []*common.Block) []*common.Block {
   470  				var err error
   471  				// Put a config transaction in block n-2 and in n-1
   472  				blockSequence[len(blockSequence)-2].Data = &common.BlockData{
   473  					Data: [][]byte{protoutil.MarshalOrPanic(configTransaction(configEnvelope1))},
   474  				}
   475  				blockSequence[len(blockSequence)-2].Header.DataHash = protoutil.BlockDataHash(blockSequence[len(blockSequence)-2].Data)
   476  
   477  				blockSequence[len(blockSequence)-1].Data = &common.BlockData{
   478  					Data: [][]byte{protoutil.MarshalOrPanic(configTransaction(configEnvelope2))},
   479  				}
   480  				blockSequence[len(blockSequence)-1].Header.DataHash = protoutil.BlockDataHash(blockSequence[len(blockSequence)-1].Data)
   481  
   482  				assignHashes(blockSequence)
   483  
   484  				sigSet1, err = cluster.SignatureSetFromBlock(blockSequence[len(blockSequence)-2])
   485  				require.NoError(t, err)
   486  
   487  				sigSet2, err = cluster.SignatureSetFromBlock(blockSequence[len(blockSequence)-1])
   488  				require.NoError(t, err)
   489  
   490  				return blockSequence
   491  			},
   492  			configureVerifier: func(verifier *mocks.BlockVerifier) {
   493  				var nilEnvelope *common.ConfigEnvelope
   494  				confEnv1 := &common.ConfigEnvelope{}
   495  				proto.Unmarshal(protoutil.MarshalOrPanic(configEnvelope1), confEnv1)
   496  				verifier.On("VerifyBlockSignature", sigSet1, nilEnvelope).Return(nil).Once()
   497  				// We ensure that the signature set of the last block is verified using the config envelope of the block
   498  				// before it.
   499  				verifier.On("VerifyBlockSignature", sigSet2, confEnv1).Return(nil).Once()
   500  				// Note that we do not record a call to verify the last block, with the config envelope extracted from the block itself.
   501  			},
   502  			// We have 2 config blocks, yet we only verify twice- the first config block, and the next config block, but no more,
   503  			// since the last block is a config block.
   504  			verifierExpectedCalls: 2,
   505  		},
   506  	} {
   507  		testCase := testCase
   508  		t.Run(testCase.name, func(t *testing.T) {
   509  			blockchain := createBlockChain(50, 100)
   510  			blockchain = testCase.mutateBlockSequence(blockchain)
   511  			verifier := &mocks.BlockVerifier{}
   512  			if testCase.configureVerifier != nil {
   513  				testCase.configureVerifier(verifier)
   514  			}
   515  			err := cluster.VerifyBlocks(blockchain, verifier)
   516  			if testCase.expectedError != "" {
   517  				require.EqualError(t, err, testCase.expectedError)
   518  			} else {
   519  				require.NoError(t, err)
   520  			}
   521  		})
   522  	}
   523  }
   524  
   525  func assignHashes(blockchain []*common.Block) {
   526  	for i := 1; i < len(blockchain); i++ {
   527  		blockchain[i].Header.PreviousHash = protoutil.BlockHeaderHash(blockchain[i-1].Header)
   528  	}
   529  }
   530  
   531  func createBlockChain(start, end uint64) []*common.Block {
   532  	newBlock := func(seq uint64) *common.Block {
   533  		sHdr := &common.SignatureHeader{
   534  			Creator: []byte{1, 2, 3},
   535  			Nonce:   []byte{9, 5, 42, 66},
   536  		}
   537  		block := protoutil.NewBlock(seq, nil)
   538  		blockSignature := &common.MetadataSignature{
   539  			SignatureHeader: protoutil.MarshalOrPanic(sHdr),
   540  		}
   541  		block.Metadata.Metadata[common.BlockMetadataIndex_SIGNATURES] = protoutil.MarshalOrPanic(&common.Metadata{
   542  			Value: nil,
   543  			Signatures: []*common.MetadataSignature{
   544  				blockSignature,
   545  			},
   546  		})
   547  
   548  		txn := protoutil.MarshalOrPanic(&common.Envelope{
   549  			Payload: protoutil.MarshalOrPanic(&common.Payload{
   550  				Header: &common.Header{},
   551  			}),
   552  		})
   553  		block.Data.Data = append(block.Data.Data, txn)
   554  		return block
   555  	}
   556  	var blockchain []*common.Block
   557  	for seq := uint64(start); seq <= uint64(end); seq++ {
   558  		block := newBlock(seq)
   559  		block.Data.Data = append(block.Data.Data, make([]byte, 100))
   560  		block.Header.DataHash = protoutil.BlockDataHash(block.Data)
   561  		blockchain = append(blockchain, block)
   562  	}
   563  	assignHashes(blockchain)
   564  	return blockchain
   565  }
   566  
   567  func TestEndpointconfigFromConfigBlockGreenPath(t *testing.T) {
   568  	t.Run("global endpoints", func(t *testing.T) {
   569  		block, err := test.MakeGenesisBlock("mychannel")
   570  		require.NoError(t, err)
   571  
   572  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   573  		require.NoError(t, err)
   574  		// For a block that doesn't have per org endpoints,
   575  		// we take the global endpoints
   576  		injectGlobalOrdererEndpoint(t, block, "globalEndpoint")
   577  		endpointConfig, err := cluster.EndpointconfigFromConfigBlock(block, cryptoProvider)
   578  		require.NoError(t, err)
   579  		require.Len(t, endpointConfig, 1)
   580  		require.Equal(t, "globalEndpoint", endpointConfig[0].Endpoint)
   581  
   582  		bl, _ := pem.Decode(endpointConfig[0].TLSRootCAs[0])
   583  		cert, err := x509.ParseCertificate(bl.Bytes)
   584  		require.NoError(t, err)
   585  
   586  		require.True(t, cert.IsCA)
   587  	})
   588  
   589  	t.Run("per org endpoints", func(t *testing.T) {
   590  		block, err := test.MakeGenesisBlock("mychannel")
   591  		require.NoError(t, err)
   592  
   593  		// Make a second config.
   594  		gConf := genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir())
   595  		gConf.Orderer.Capabilities = map[string]bool{
   596  			capabilities.OrdererV2_0: true,
   597  		}
   598  		channelGroup, err := encoder.NewChannelGroup(gConf)
   599  		require.NoError(t, err)
   600  
   601  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   602  		require.NoError(t, err)
   603  		bundle, err := channelconfig.NewBundle("mychannel", &common.Config{ChannelGroup: channelGroup}, cryptoProvider)
   604  		require.NoError(t, err)
   605  
   606  		msps, err := bundle.MSPManager().GetMSPs()
   607  		require.NoError(t, err)
   608  		caBytes := msps["SampleOrg"].GetTLSRootCerts()[0]
   609  
   610  		require.NoError(t, err)
   611  		injectAdditionalTLSCAEndpointPair(t, block, "anotherEndpoint", caBytes, "fooOrg")
   612  		endpointConfig, err := cluster.EndpointconfigFromConfigBlock(block, cryptoProvider)
   613  		require.NoError(t, err)
   614  		// And ensure that the endpoints that are taken, are the per org ones.
   615  		require.Len(t, endpointConfig, 2)
   616  		for _, endpoint := range endpointConfig {
   617  			// If this is the original organization (and not the clone),
   618  			// the TLS CA is 'caBytes' read from the second block.
   619  			if endpoint.Endpoint == "anotherEndpoint" {
   620  				require.Len(t, endpoint.TLSRootCAs, 1)
   621  				require.Equal(t, caBytes, endpoint.TLSRootCAs[0])
   622  				continue
   623  			}
   624  			// Else, our endpoints are from the original org, and the TLS CA is something else.
   625  			require.NotEqual(t, caBytes, endpoint.TLSRootCAs[0])
   626  			// The endpoints we expect to see are something else.
   627  			require.Equal(t, 0, strings.Index(endpoint.Endpoint, "127.0.0.1:"))
   628  			bl, _ := pem.Decode(endpoint.TLSRootCAs[0])
   629  			cert, err := x509.ParseCertificate(bl.Bytes)
   630  			require.NoError(t, err)
   631  			require.True(t, cert.IsCA)
   632  		}
   633  	})
   634  }
   635  
   636  func TestEndpointconfigFromConfigBlockFailures(t *testing.T) {
   637  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   638  	require.NoError(t, err)
   639  
   640  	t.Run("nil block", func(t *testing.T) {
   641  		certs, err := cluster.EndpointconfigFromConfigBlock(nil, cryptoProvider)
   642  		require.Nil(t, certs)
   643  		require.EqualError(t, err, "nil block")
   644  	})
   645  
   646  	t.Run("nil block data", func(t *testing.T) {
   647  		certs, err := cluster.EndpointconfigFromConfigBlock(&common.Block{}, cryptoProvider)
   648  		require.Nil(t, certs)
   649  		require.EqualError(t, err, "block data is nil")
   650  	})
   651  
   652  	t.Run("no envelope", func(t *testing.T) {
   653  		certs, err := cluster.EndpointconfigFromConfigBlock(&common.Block{
   654  			Data: &common.BlockData{},
   655  		}, cryptoProvider)
   656  		require.Nil(t, certs)
   657  		require.EqualError(t, err, "envelope index out of bounds")
   658  	})
   659  
   660  	t.Run("bad envelope", func(t *testing.T) {
   661  		certs, err := cluster.EndpointconfigFromConfigBlock(&common.Block{
   662  			Data: &common.BlockData{
   663  				Data: [][]byte{{}},
   664  			},
   665  		}, cryptoProvider)
   666  		require.Nil(t, certs)
   667  		require.EqualError(t, err, "failed extracting bundle from envelope: envelope header cannot be nil")
   668  	})
   669  }
   670  
   671  func TestConfigFromBlockBadInput(t *testing.T) {
   672  	for _, testCase := range []struct {
   673  		name          string
   674  		block         *common.Block
   675  		expectedError string
   676  	}{
   677  		{
   678  			name:          "nil block",
   679  			expectedError: "empty block",
   680  			block:         nil,
   681  		},
   682  		{
   683  			name:          "nil block data",
   684  			expectedError: "empty block",
   685  			block:         &common.Block{},
   686  		},
   687  		{
   688  			name:          "no data in block",
   689  			expectedError: "empty block",
   690  			block:         &common.Block{Data: &common.BlockData{}},
   691  		},
   692  		{
   693  			name:          "invalid payload",
   694  			expectedError: "error unmarshalling Envelope: proto: common.Envelope: illegal tag 0 (wire type 1)",
   695  			block:         &common.Block{Data: &common.BlockData{Data: [][]byte{{1, 2, 3}}}},
   696  		},
   697  		{
   698  			name:          "bad genesis block",
   699  			expectedError: "invalid config envelope: proto: common.ConfigEnvelope: illegal tag 0 (wire type 1)",
   700  			block: &common.Block{
   701  				Header: &common.BlockHeader{}, Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{
   702  					Payload: protoutil.MarshalOrPanic(&common.Payload{
   703  						Data: []byte{1, 2, 3},
   704  					}),
   705  				})}},
   706  			},
   707  		},
   708  		{
   709  			name:          "invalid envelope in block",
   710  			expectedError: "error unmarshalling Envelope: proto: common.Envelope: illegal tag 0 (wire type 1)",
   711  			block:         &common.Block{Data: &common.BlockData{Data: [][]byte{{1, 2, 3}}}},
   712  		},
   713  		{
   714  			name:          "invalid payload in block envelope",
   715  			expectedError: "error unmarshalling Payload: proto: common.Payload: illegal tag 0 (wire type 1)",
   716  			block: &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{
   717  				Payload: []byte{1, 2, 3},
   718  			})}}},
   719  		},
   720  		{
   721  			name:          "invalid channel header",
   722  			expectedError: "error unmarshalling ChannelHeader: proto: common.ChannelHeader: illegal tag 0 (wire type 1)",
   723  			block: &common.Block{
   724  				Header: &common.BlockHeader{Number: 1},
   725  				Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{
   726  					Payload: protoutil.MarshalOrPanic(&common.Payload{
   727  						Header: &common.Header{
   728  							ChannelHeader: []byte{1, 2, 3},
   729  						},
   730  					}),
   731  				})}},
   732  			},
   733  		},
   734  		{
   735  			name:          "invalid config block",
   736  			expectedError: "invalid config envelope: proto: common.ConfigEnvelope: illegal tag 0 (wire type 1)",
   737  			block: &common.Block{
   738  				Header: &common.BlockHeader{},
   739  				Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{
   740  					Payload: protoutil.MarshalOrPanic(&common.Payload{
   741  						Data: []byte{1, 2, 3},
   742  						Header: &common.Header{
   743  							ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{
   744  								Type: int32(common.HeaderType_CONFIG),
   745  							}),
   746  						},
   747  					}),
   748  				})}},
   749  			},
   750  		},
   751  	} {
   752  		t.Run(testCase.name, func(t *testing.T) {
   753  			conf, err := cluster.ConfigFromBlock(testCase.block)
   754  			require.Nil(t, conf)
   755  			require.EqualError(t, err, testCase.expectedError)
   756  		})
   757  	}
   758  }
   759  
   760  func TestBlockValidationPolicyVerifier(t *testing.T) {
   761  	config := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir())
   762  	group, err := encoder.NewChannelGroup(config)
   763  	require.NoError(t, err)
   764  	require.NotNil(t, group)
   765  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   766  	require.NoError(t, err)
   767  
   768  	validConfigEnvelope := &common.ConfigEnvelope{
   769  		Config: &common.Config{
   770  			ChannelGroup: group,
   771  		},
   772  	}
   773  
   774  	for _, testCase := range []struct {
   775  		description   string
   776  		expectedError string
   777  		envelope      *common.ConfigEnvelope
   778  		policyMap     map[string]policies.Policy
   779  		policy        policies.Policy
   780  	}{
   781  		/**
   782  		{
   783  			description:   "policy not found",
   784  			expectedError: "policy /Channel/Orderer/BlockValidation wasn't found",
   785  		},
   786  		*/
   787  		{
   788  			description:   "policy evaluation fails",
   789  			expectedError: "invalid signature",
   790  			policy: &mocks.Policy{
   791  				EvaluateSignedDataStub: func([]*protoutil.SignedData) error {
   792  					return errors.New("invalid signature")
   793  				},
   794  			},
   795  		},
   796  		{
   797  			description:   "bad config envelope",
   798  			expectedError: "config must contain a channel group",
   799  			policy:        &mocks.Policy{},
   800  			envelope:      &common.ConfigEnvelope{Config: &common.Config{}},
   801  		},
   802  		{
   803  			description: "good config envelope overrides custom policy manager",
   804  			policy: &mocks.Policy{
   805  				EvaluateSignedDataStub: func([]*protoutil.SignedData) error {
   806  					return errors.New("invalid signature")
   807  				},
   808  			},
   809  			envelope: validConfigEnvelope,
   810  		},
   811  	} {
   812  		t.Run(testCase.description, func(t *testing.T) {
   813  			mockPolicyManager := &mocks.PolicyManager{}
   814  			if testCase.policy != nil {
   815  				mockPolicyManager.GetPolicyReturns(testCase.policy, true)
   816  			} else {
   817  				mockPolicyManager.GetPolicyReturns(nil, false)
   818  			}
   819  			mockPolicyManager.GetPolicyReturns(testCase.policy, true)
   820  			verifier := &cluster.BlockValidationPolicyVerifier{
   821  				Logger:    flogging.MustGetLogger("test"),
   822  				Channel:   "mychannel",
   823  				PolicyMgr: mockPolicyManager,
   824  				BCCSP:     cryptoProvider,
   825  			}
   826  
   827  			err := verifier.VerifyBlockSignature(nil, testCase.envelope)
   828  			if testCase.expectedError != "" {
   829  				require.EqualError(t, err, testCase.expectedError)
   830  			} else {
   831  				require.NoError(t, err)
   832  			}
   833  		})
   834  	}
   835  }
   836  
   837  func TestBlockVerifierAssembler(t *testing.T) {
   838  	config := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir())
   839  	group, err := encoder.NewChannelGroup(config)
   840  	require.NoError(t, err)
   841  	require.NotNil(t, group)
   842  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   843  	require.NoError(t, err)
   844  
   845  	t.Run("Good config envelope", func(t *testing.T) {
   846  		bva := &cluster.BlockVerifierAssembler{BCCSP: cryptoProvider}
   847  		verifier, err := bva.VerifierFromConfig(&common.ConfigEnvelope{
   848  			Config: &common.Config{
   849  				ChannelGroup: group,
   850  			},
   851  		}, "mychannel")
   852  		require.NoError(t, err)
   853  
   854  		require.NoError(t, verifier.VerifyBlockSignature(nil, nil))
   855  	})
   856  
   857  	t.Run("Bad config envelope", func(t *testing.T) {
   858  		bva := &cluster.BlockVerifierAssembler{BCCSP: cryptoProvider}
   859  		_, err := bva.VerifierFromConfig(&common.ConfigEnvelope{}, "mychannel")
   860  		require.EqualError(t, err, "failed extracting bundle from envelope: channelconfig Config cannot be nil")
   861  	})
   862  }
   863  
   864  func TestLastConfigBlock(t *testing.T) {
   865  	blockRetriever := &mocks.BlockRetriever{}
   866  	blockRetriever.On("Block", uint64(42)).Return(&common.Block{})
   867  	blockRetriever.On("Block", uint64(666)).Return(nil)
   868  
   869  	for _, testCase := range []struct {
   870  		name           string
   871  		block          *common.Block
   872  		blockRetriever cluster.BlockRetriever
   873  		expectedError  string
   874  	}{
   875  		{
   876  			name:           "nil block",
   877  			expectedError:  "nil block",
   878  			blockRetriever: blockRetriever,
   879  		},
   880  		{
   881  			name:          "nil support",
   882  			expectedError: "nil blockRetriever",
   883  			block:         &common.Block{},
   884  		},
   885  		{
   886  			name:           "nil metadata",
   887  			expectedError:  "failed to retrieve metadata: no metadata in block",
   888  			blockRetriever: blockRetriever,
   889  			block:          &common.Block{},
   890  		},
   891  		{
   892  			name: "no block with index",
   893  			block: &common.Block{
   894  				Metadata: &common.BlockMetadata{
   895  					Metadata: [][]byte{{}, protoutil.MarshalOrPanic(&common.Metadata{
   896  						Value: protoutil.MarshalOrPanic(&common.LastConfig{Index: 666}),
   897  					})},
   898  				},
   899  			},
   900  			expectedError:  "unable to retrieve last config block [666]",
   901  			blockRetriever: blockRetriever,
   902  		},
   903  		{
   904  			name: "valid last config block",
   905  			block: &common.Block{
   906  				Metadata: &common.BlockMetadata{
   907  					Metadata: [][]byte{{}, protoutil.MarshalOrPanic(&common.Metadata{
   908  						Value: protoutil.MarshalOrPanic(&common.LastConfig{Index: 42}),
   909  					})},
   910  				},
   911  			},
   912  			blockRetriever: blockRetriever,
   913  		},
   914  	} {
   915  		testCase := testCase
   916  		t.Run(testCase.name, func(t *testing.T) {
   917  			block, err := cluster.LastConfigBlock(testCase.block, testCase.blockRetriever)
   918  			if testCase.expectedError == "" {
   919  				require.NoError(t, err)
   920  				require.NotNil(t, block)
   921  				return
   922  			}
   923  			require.EqualError(t, err, testCase.expectedError)
   924  			require.Nil(t, block)
   925  		})
   926  	}
   927  }
   928  
   929  func TestVerificationRegistryRegisterVerifier(t *testing.T) {
   930  	blockBytes, err := ioutil.ReadFile("testdata/mychannel.block")
   931  	require.NoError(t, err)
   932  
   933  	block := &common.Block{}
   934  	require.NoError(t, proto.Unmarshal(blockBytes, block))
   935  
   936  	verifier := &mocks.BlockVerifier{}
   937  
   938  	verifierFactory := &mocks.VerifierFactory{}
   939  	verifierFactory.On("VerifierFromConfig",
   940  		mock.Anything, "mychannel").Return(verifier, nil)
   941  
   942  	registry := &cluster.VerificationRegistry{
   943  		Logger:             flogging.MustGetLogger("test"),
   944  		VerifiersByChannel: make(map[string]cluster.BlockVerifier),
   945  		VerifierFactory:    verifierFactory,
   946  	}
   947  
   948  	var loadCount int
   949  	registry.LoadVerifier = func(chain string) cluster.BlockVerifier {
   950  		require.Equal(t, "mychannel", chain)
   951  		loadCount++
   952  		return verifier
   953  	}
   954  
   955  	v := registry.RetrieveVerifier("mychannel")
   956  	require.Nil(t, v)
   957  
   958  	registry.RegisterVerifier("mychannel")
   959  	v = registry.RetrieveVerifier("mychannel")
   960  	require.Equal(t, verifier, v)
   961  	require.Equal(t, 1, loadCount)
   962  
   963  	// If the verifier exists, this is a no-op
   964  	registry.RegisterVerifier("mychannel")
   965  	require.Equal(t, 1, loadCount)
   966  }
   967  
   968  func TestVerificationRegistry(t *testing.T) {
   969  	blockBytes, err := ioutil.ReadFile("testdata/mychannel.block")
   970  	require.NoError(t, err)
   971  
   972  	block := &common.Block{}
   973  	require.NoError(t, proto.Unmarshal(blockBytes, block))
   974  
   975  	flogging.ActivateSpec("test=DEBUG")
   976  	defer flogging.Reset()
   977  
   978  	verifier := &mocks.BlockVerifier{}
   979  
   980  	for _, testCase := range []struct {
   981  		description           string
   982  		verifiersByChannel    map[string]cluster.BlockVerifier
   983  		blockCommitted        *common.Block
   984  		channelCommitted      string
   985  		channelRetrieved      string
   986  		expectedVerifier      cluster.BlockVerifier
   987  		verifierFromConfig    cluster.BlockVerifier
   988  		verifierFromConfigErr error
   989  		loggedMessages        map[string]struct{}
   990  	}{
   991  		{
   992  			description:      "bad block",
   993  			blockCommitted:   &common.Block{},
   994  			channelRetrieved: "foo",
   995  			channelCommitted: "foo",
   996  			loggedMessages: map[string]struct{}{
   997  				"Failed parsing block of channel foo: empty block, content: " +
   998  					"{\n\t\"data\": null,\n\t\"header\": null,\n\t\"metadata\": null\n}\n": {},
   999  				"No verifier for channel foo exists": {},
  1000  			},
  1001  			expectedVerifier: nil,
  1002  		},
  1003  		{
  1004  			description:      "not a config block",
  1005  			blockCommitted:   createBlockChain(5, 5)[0],
  1006  			channelRetrieved: "foo",
  1007  			channelCommitted: "foo",
  1008  			loggedMessages: map[string]struct{}{
  1009  				"No verifier for channel foo exists":                             {},
  1010  				"Committed block [5] for channel foo that is not a config block": {},
  1011  			},
  1012  			expectedVerifier: nil,
  1013  		},
  1014  		{
  1015  			description:           "valid block but verifier from config fails",
  1016  			blockCommitted:        block,
  1017  			verifierFromConfigErr: errors.New("invalid MSP config"),
  1018  			channelRetrieved:      "bar",
  1019  			channelCommitted:      "bar",
  1020  			loggedMessages: map[string]struct{}{
  1021  				"Failed creating a verifier from a " +
  1022  					"config block for channel bar: invalid MSP config, " +
  1023  					"content: " + cluster.BlockToString(block): {},
  1024  				"No verifier for channel bar exists": {},
  1025  			},
  1026  			expectedVerifier: nil,
  1027  		},
  1028  		{
  1029  			description:        "valid block and verifier from config succeeds but wrong channel retrieved",
  1030  			blockCommitted:     block,
  1031  			verifierFromConfig: verifier,
  1032  			channelRetrieved:   "foo",
  1033  			channelCommitted:   "bar",
  1034  			loggedMessages: map[string]struct{}{
  1035  				"No verifier for channel foo exists":         {},
  1036  				"Committed config block [0] for channel bar": {},
  1037  			},
  1038  			expectedVerifier:   nil,
  1039  			verifiersByChannel: make(map[string]cluster.BlockVerifier),
  1040  		},
  1041  		{
  1042  			description:        "valid block and verifier from config succeeds",
  1043  			blockCommitted:     block,
  1044  			verifierFromConfig: verifier,
  1045  			channelRetrieved:   "bar",
  1046  			channelCommitted:   "bar",
  1047  			loggedMessages: map[string]struct{}{
  1048  				"Committed config block [0] for channel bar": {},
  1049  			},
  1050  			expectedVerifier:   verifier,
  1051  			verifiersByChannel: make(map[string]cluster.BlockVerifier),
  1052  		},
  1053  	} {
  1054  		t.Run(testCase.description, func(t *testing.T) {
  1055  			verifierFactory := &mocks.VerifierFactory{}
  1056  			verifierFactory.On("VerifierFromConfig",
  1057  				mock.Anything, testCase.channelCommitted).Return(testCase.verifierFromConfig, testCase.verifierFromConfigErr)
  1058  
  1059  			registry := &cluster.VerificationRegistry{
  1060  				Logger:             flogging.MustGetLogger("test"),
  1061  				VerifiersByChannel: testCase.verifiersByChannel,
  1062  				VerifierFactory:    verifierFactory,
  1063  			}
  1064  
  1065  			loggedEntriesByMethods := make(map[string]struct{})
  1066  			// Configure the logger to collect the message logged
  1067  			registry.Logger = registry.Logger.WithOptions(zap.Hooks(func(entry zapcore.Entry) error {
  1068  				loggedEntriesByMethods[entry.Message] = struct{}{}
  1069  				return nil
  1070  			}))
  1071  
  1072  			registry.BlockCommitted(testCase.blockCommitted, testCase.channelCommitted)
  1073  			verifier := registry.RetrieveVerifier(testCase.channelRetrieved)
  1074  
  1075  			require.Equal(t, testCase.loggedMessages, loggedEntriesByMethods)
  1076  			require.Equal(t, testCase.expectedVerifier, verifier)
  1077  		})
  1078  	}
  1079  }
  1080  
  1081  func TestLedgerInterceptor(t *testing.T) {
  1082  	block := &common.Block{}
  1083  
  1084  	ledger := &mocks.LedgerWriter{}
  1085  	ledger.On("Append", block).Return(nil).Once()
  1086  
  1087  	var intercepted bool
  1088  
  1089  	var interceptedLedger cluster.LedgerWriter = &cluster.LedgerInterceptor{
  1090  		Channel:      "mychannel",
  1091  		LedgerWriter: ledger,
  1092  		InterceptBlockCommit: func(b *common.Block, channel string) {
  1093  			require.Equal(t, block, b)
  1094  			require.Equal(t, "mychannel", channel)
  1095  			intercepted = true
  1096  		},
  1097  	}
  1098  
  1099  	err := interceptedLedger.Append(block)
  1100  	require.NoError(t, err)
  1101  	require.True(t, intercepted)
  1102  	ledger.AssertCalled(t, "Append", block)
  1103  }
  1104  
  1105  func injectAdditionalTLSCAEndpointPair(t *testing.T, block *common.Block, endpoint string, tlsCA []byte, orgName string) {
  1106  	// Unwrap the layers until we reach the orderer addresses
  1107  	env, err := protoutil.ExtractEnvelope(block, 0)
  1108  	require.NoError(t, err)
  1109  	payload, err := protoutil.UnmarshalPayload(env.Payload)
  1110  	require.NoError(t, err)
  1111  	confEnv, err := configtx.UnmarshalConfigEnvelope(payload.Data)
  1112  	require.NoError(t, err)
  1113  	ordererGrp := confEnv.Config.ChannelGroup.Groups[channelconfig.OrdererGroupKey].Groups
  1114  	// Get the first orderer org config
  1115  	var firstOrdererConfig *common.ConfigGroup
  1116  	for _, grp := range ordererGrp {
  1117  		firstOrdererConfig = grp
  1118  		break
  1119  	}
  1120  	// Duplicate it.
  1121  	secondOrdererConfig := proto.Clone(firstOrdererConfig).(*common.ConfigGroup)
  1122  	ordererGrp[orgName] = secondOrdererConfig
  1123  	// Reach the FabricMSPConfig buried in it.
  1124  	mspConfig := &msp.MSPConfig{}
  1125  	err = proto.Unmarshal(secondOrdererConfig.Values[channelconfig.MSPKey].Value, mspConfig)
  1126  	require.NoError(t, err)
  1127  
  1128  	fabricConfig := &msp.FabricMSPConfig{}
  1129  	err = proto.Unmarshal(mspConfig.Config, fabricConfig)
  1130  	require.NoError(t, err)
  1131  
  1132  	// Plant the given TLS CA in it.
  1133  	fabricConfig.TlsRootCerts = [][]byte{tlsCA}
  1134  	// No intermediate root CAs, to make the test simpler.
  1135  	fabricConfig.TlsIntermediateCerts = nil
  1136  	// Rename it.
  1137  	fabricConfig.Name = orgName
  1138  
  1139  	// Pack the MSP config back into the config
  1140  	secondOrdererConfig.Values[channelconfig.MSPKey].Value = protoutil.MarshalOrPanic(&msp.MSPConfig{
  1141  		Config: protoutil.MarshalOrPanic(fabricConfig),
  1142  		Type:   mspConfig.Type,
  1143  	})
  1144  
  1145  	// Inject the endpoint
  1146  	ordererOrgProtos := &common.OrdererAddresses{
  1147  		Addresses: []string{endpoint},
  1148  	}
  1149  	secondOrdererConfig.Values[channelconfig.EndpointsKey].Value = protoutil.MarshalOrPanic(ordererOrgProtos)
  1150  
  1151  	// Fold everything back into the block
  1152  	payload.Data = protoutil.MarshalOrPanic(confEnv)
  1153  	env.Payload = protoutil.MarshalOrPanic(payload)
  1154  	block.Data.Data[0] = protoutil.MarshalOrPanic(env)
  1155  }
  1156  
  1157  func TestEndpointCriteriaString(t *testing.T) {
  1158  	// The top cert is the issuer of the bottom cert
  1159  	certs := `-----BEGIN CERTIFICATE-----
  1160  MIIBozCCAUigAwIBAgIQMXmzUnikiAZDr4VsrBL+rzAKBggqhkjOPQQDAjAxMS8w
  1161  LQYDVQQFEyY2NTc2NDA3Njc5ODcwOTA3OTEwNDM5NzkxMTAwNzA0Mzk3Njg3OTAe
  1162  Fw0xOTExMTEyMDM5MDRaFw0yOTExMDkyMDM5MDRaMDExLzAtBgNVBAUTJjY1NzY0
  1163  MDc2Nzk4NzA5MDc5MTA0Mzk3OTExMDA3MDQzOTc2ODc5MFkwEwYHKoZIzj0CAQYI
  1164  KoZIzj0DAQcDQgAEzBBkRvWgasCKf1pejwpOu+1Fv9FffOZMHnna/7lfMrAqOs8d
  1165  HMDVU7mSexu7YNTpAwm4vkdHXi35H8zlVABTxaNCMEAwDgYDVR0PAQH/BAQDAgGm
  1166  MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/
  1167  MAoGCCqGSM49BAMCA0kAMEYCIQCXqXoYLAJN9diIdGxPlRQJgJLju4brWXZfyt3s
  1168  E9TjFwIhAOuUJjcOchdP6UA9WLnVWciEo1Omf59NgfHL1gUPb/t6
  1169  -----END CERTIFICATE-----
  1170  -----BEGIN CERTIFICATE-----
  1171  MIIBpDCCAUqgAwIBAgIRAIyvtL0z1xQ+NecXeH1HmmAwCgYIKoZIzj0EAwIwMTEv
  1172  MC0GA1UEBRMmNjU3NjQwNzY3OTg3MDkwNzkxMDQzOTc5MTEwMDcwNDM5NzY4Nzkw
  1173  HhcNMTkxMTExMjAzOTA0WhcNMTkxMTEyMjAzOTA0WjAyMTAwLgYDVQQFEycxODcw
  1174  MDQyMzcxODQwMjY5Mzk2ODUxNzk1NzM3MzIyMTc2OTA3MjAwWTATBgcqhkjOPQIB
  1175  BggqhkjOPQMBBwNCAARZBFDBOfC7T9RbsX+PgyE6sM7ocuwn6krIGjc00ICivFgQ
  1176  qdHMU7hiswiYwSvwh9MDHlprCRW3ycSgEYQgKU5to0IwQDAOBgNVHQ8BAf8EBAMC
  1177  BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA8GA1UdEQQIMAaHBH8A
  1178  AAEwCgYIKoZIzj0EAwIDSAAwRQIhAK6G7qr/ClszCFP25gsflA31+7eoss5vi3o4
  1179  qz8bY+s6AiBvO0aOfE8M4ibjmRE4vSXo0+gkOIJKqZcmiRdnJSr8Xw==
  1180  -----END CERTIFICATE-----`
  1181  
  1182  	epc := cluster.EndpointCriteria{
  1183  		Endpoint:   "orderer.example.com:7050",
  1184  		TLSRootCAs: [][]byte{[]byte(certs)},
  1185  	}
  1186  
  1187  	actual := fmt.Sprint(epc)
  1188  	expected := `{"CAs":[{"Expired":false,"Issuer":"self","Subject":"SERIALNUMBER=65764076798709079104397911007043976879"},{"Expired":true,"Issuer":"SERIALNUMBER=65764076798709079104397911007043976879","Subject":"SERIALNUMBER=187004237184026939685179573732217690720"}],"Endpoint":"orderer.example.com:7050"}`
  1189  	require.Equal(t, expected, actual)
  1190  }
  1191  
  1192  func TestComparisonMemoizer(t *testing.T) {
  1193  	var invocations int
  1194  
  1195  	m := &cluster.ComparisonMemoizer{
  1196  		MaxEntries: 5,
  1197  		F: func(a, b []byte) bool {
  1198  			invocations++
  1199  			return bytes.Equal(a, b)
  1200  		},
  1201  	}
  1202  
  1203  	// Warm-up cache
  1204  	for i := 0; i < 5; i++ {
  1205  		notSame := m.Compare([]byte{byte(i)}, []byte{1, 2, 3})
  1206  		require.False(t, notSame)
  1207  		require.Equal(t, i+1, invocations)
  1208  	}
  1209  
  1210  	// Ensure lookups are cached
  1211  	for i := 0; i < 5; i++ {
  1212  		notSame := m.Compare([]byte{byte(i)}, []byte{1, 2, 3})
  1213  		require.False(t, notSame)
  1214  		require.Equal(t, 5, invocations)
  1215  	}
  1216  
  1217  	// Put a new entry which will cause a cache miss
  1218  	same := m.Compare([]byte{5}, []byte{5})
  1219  	require.True(t, same)
  1220  	require.Equal(t, 6, invocations)
  1221  
  1222  	// Keep adding more and more elements to the cache and ensure it stays smaller than its size
  1223  	for i := 0; i < 20; i++ {
  1224  		odd := m.Compare([]byte{byte(1)}, []byte{byte(i % 2)})
  1225  		require.Equal(t, i%2 != 0, odd)
  1226  		require.LessOrEqual(t, m.Size(), int(m.MaxEntries))
  1227  	}
  1228  }