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