github.com/kaituanwang/hyperledger@v2.0.1+incompatible/orderer/common/multichannel/chainsupport_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package multichannel
     8  
     9  import (
    10  	"testing"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	"github.com/hyperledger/fabric-protos-go/common"
    14  	"github.com/hyperledger/fabric-protos-go/orderer"
    15  	"github.com/hyperledger/fabric/bccsp/sw"
    16  	"github.com/hyperledger/fabric/common/channelconfig"
    17  	"github.com/hyperledger/fabric/common/deliver/mock"
    18  	mockblockledger "github.com/hyperledger/fabric/common/ledger/blockledger/mocks"
    19  	"github.com/hyperledger/fabric/common/policies"
    20  	"github.com/hyperledger/fabric/core/config/configtest"
    21  	"github.com/hyperledger/fabric/internal/configtxgen/encoder"
    22  	"github.com/hyperledger/fabric/internal/configtxgen/genesisconfig"
    23  	msgprocessormocks "github.com/hyperledger/fabric/orderer/common/msgprocessor/mocks"
    24  	"github.com/hyperledger/fabric/orderer/common/multichannel/mocks"
    25  	"github.com/hyperledger/fabric/protoutil"
    26  	"github.com/pkg/errors"
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  //go:generate counterfeiter -o mocks/policy_manager.go --fake-name PolicyManager . policyManager
    31  
    32  type policyManager interface {
    33  	policies.Manager
    34  }
    35  
    36  //go:generate counterfeiter -o mocks/policy.go --fake-name Policy . policy
    37  
    38  type policy interface {
    39  	policies.Policy
    40  }
    41  
    42  func TestChainSupportBlock(t *testing.T) {
    43  	ledger := &mockblockledger.ReadWriter{}
    44  	ledger.On("Height").Return(uint64(100))
    45  	iterator := &mock.BlockIterator{}
    46  	iterator.NextReturns(&common.Block{Header: &common.BlockHeader{Number: 99}}, common.Status_SUCCESS)
    47  	ledger.On("Iterator", &orderer.SeekPosition{
    48  		Type: &orderer.SeekPosition_Specified{
    49  			Specified: &orderer.SeekSpecified{Number: 99},
    50  		},
    51  	}).Return(iterator, uint64(99))
    52  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    53  	assert.NoError(t, err)
    54  	cs := &ChainSupport{
    55  		ledgerResources: &ledgerResources{ReadWriter: ledger},
    56  		BCCSP:           cryptoProvider,
    57  	}
    58  
    59  	assert.Nil(t, cs.Block(100))
    60  	assert.Equal(t, uint64(99), cs.Block(99).Header.Number)
    61  }
    62  
    63  type mutableResourcesMock struct {
    64  	*mocks.Resources
    65  	newConsensusMetadataVal []byte
    66  }
    67  
    68  func (*mutableResourcesMock) Update(*channelconfig.Bundle) {
    69  	panic("implement me")
    70  }
    71  
    72  func (mrm *mutableResourcesMock) CreateBundle(channelID string, c *common.Config) (channelconfig.Resources, error) {
    73  	mockOrderer := &mocks.OrdererConfig{}
    74  	mockOrderer.ConsensusMetadataReturns(mrm.newConsensusMetadataVal)
    75  	mockResources := &mocks.Resources{}
    76  	mockResources.OrdererConfigReturns(mockOrderer, true)
    77  
    78  	return mockResources, nil
    79  
    80  }
    81  
    82  func TestVerifyBlockSignature(t *testing.T) {
    83  	mockResources := &mocks.Resources{}
    84  	mockValidator := &mocks.ConfigTXValidator{}
    85  	mockValidator.ChannelIDReturns("mychannel")
    86  	mockResources.ConfigtxValidatorReturns(mockValidator)
    87  
    88  	mockPolicy := &mocks.Policy{}
    89  	mockPolicyManager := &mocks.PolicyManager{}
    90  	mockResources.PolicyManagerReturns(mockPolicyManager)
    91  
    92  	ms := &mutableResourcesMock{
    93  		Resources: mockResources,
    94  	}
    95  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    96  	assert.NoError(t, err)
    97  	cs := &ChainSupport{
    98  		ledgerResources: &ledgerResources{
    99  			configResources: &configResources{
   100  				mutableResources: ms,
   101  				bccsp:            cryptoProvider,
   102  			},
   103  		},
   104  		BCCSP: cryptoProvider,
   105  	}
   106  
   107  	// Scenario I: Policy manager isn't initialized
   108  	// and thus policy cannot be found
   109  	mockPolicyManager.GetPolicyReturns(nil, false)
   110  	err = cs.VerifyBlockSignature([]*protoutil.SignedData{}, nil)
   111  	assert.EqualError(t, err, "policy /Channel/Orderer/BlockValidation wasn't found")
   112  
   113  	mockPolicyManager.GetPolicyReturns(mockPolicy, true)
   114  	// Scenario II: Policy manager finds policy, but it evaluates
   115  	// to error.
   116  	mockPolicy.EvaluateSignedDataReturns(errors.New("invalid signature"))
   117  	err = cs.VerifyBlockSignature([]*protoutil.SignedData{}, nil)
   118  	assert.EqualError(t, err, "block verification failed: invalid signature")
   119  
   120  	// Scenario III: Policy manager finds policy, and it evaluates to success
   121  	mockPolicy.EvaluateSignedDataReturns(nil)
   122  	assert.NoError(t, cs.VerifyBlockSignature([]*protoutil.SignedData{}, nil))
   123  
   124  	// Scenario IV: A bad config envelope is passed
   125  	err = cs.VerifyBlockSignature([]*protoutil.SignedData{}, &common.ConfigEnvelope{})
   126  	assert.EqualError(t, err, "channelconfig Config cannot be nil")
   127  
   128  	// Scenario V: A valid config envelope is passed
   129  	assert.NoError(t, cs.VerifyBlockSignature([]*protoutil.SignedData{}, testConfigEnvelope(t)))
   130  
   131  }
   132  
   133  func TestConsensusMetadataValidation(t *testing.T) {
   134  	oldConsensusMetadata := []byte("old consensus metadata")
   135  	newConsensusMetadata := []byte("new consensus metadata")
   136  	mockValidator := &mocks.ConfigTXValidator{}
   137  	mockValidator.ChannelIDReturns("mychannel")
   138  	mockValidator.ProposeConfigUpdateReturns(testConfigEnvelope(t), nil)
   139  	mockOrderer := &mocks.OrdererConfig{}
   140  	mockOrderer.ConsensusMetadataReturns(oldConsensusMetadata)
   141  	mockResources := &mocks.Resources{}
   142  	mockResources.ConfigtxValidatorReturns(mockValidator)
   143  	mockResources.OrdererConfigReturns(mockOrderer, true)
   144  
   145  	ms := &mutableResourcesMock{
   146  		Resources:               mockResources,
   147  		newConsensusMetadataVal: newConsensusMetadata,
   148  	}
   149  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   150  	assert.NoError(t, err)
   151  	mv := &msgprocessormocks.MetadataValidator{}
   152  	cs := &ChainSupport{
   153  		ledgerResources: &ledgerResources{
   154  			configResources: &configResources{
   155  				mutableResources: ms,
   156  				bccsp:            cryptoProvider,
   157  			},
   158  		},
   159  		MetadataValidator: mv,
   160  		BCCSP:             cryptoProvider,
   161  	}
   162  
   163  	// case 1: valid consensus metadata update
   164  	_, err = cs.ProposeConfigUpdate(&common.Envelope{})
   165  	assert.NoError(t, err)
   166  
   167  	// validate arguments to ValidateConsensusMetadata
   168  	assert.Equal(t, 1, mv.ValidateConsensusMetadataCallCount())
   169  	om, nm, nc := mv.ValidateConsensusMetadataArgsForCall(0)
   170  	assert.False(t, nc)
   171  	assert.Equal(t, oldConsensusMetadata, om)
   172  	assert.Equal(t, newConsensusMetadata, nm)
   173  
   174  	// case 2: invalid consensus metadata update
   175  	mv.ValidateConsensusMetadataReturns(errors.New("bananas"))
   176  	_, err = cs.ProposeConfigUpdate(&common.Envelope{})
   177  	assert.EqualError(t, err, "consensus metadata update for channel config update is invalid: bananas")
   178  }
   179  
   180  func testConfigEnvelope(t *testing.T) *common.ConfigEnvelope {
   181  	conf := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir())
   182  	group, err := encoder.NewChannelGroup(conf)
   183  	assert.NoError(t, err)
   184  	group.Groups["Orderer"].Values["ConsensusType"].Value, err = proto.Marshal(&orderer.ConsensusType{
   185  		Metadata: []byte("new consensus metadata"),
   186  	})
   187  	assert.NoError(t, err)
   188  	assert.NotNil(t, group)
   189  	return &common.ConfigEnvelope{
   190  		Config: &common.Config{
   191  			ChannelGroup: group,
   192  		},
   193  	}
   194  }