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 }