github.com/yous1230/fabric@v2.0.0-beta.0.20191224111736-74345bee6ac2+incompatible/orderer/common/cluster/util_test.go (about)

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