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