github.com/anjalikarhana/fabric@v2.1.1+incompatible/core/handlers/validation/builtin/v20/validation_logic_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package v20
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"testing"
    14  
    15  	"github.com/hyperledger/fabric-protos-go/common"
    16  	"github.com/hyperledger/fabric-protos-go/peer"
    17  	"github.com/hyperledger/fabric/bccsp/sw"
    18  	commonerrors "github.com/hyperledger/fabric/common/errors"
    19  	"github.com/hyperledger/fabric/common/policydsl"
    20  	"github.com/hyperledger/fabric/core/committer/txvalidator/v14"
    21  	"github.com/hyperledger/fabric/core/common/ccprovider"
    22  	validation "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities"
    23  	vs "github.com/hyperledger/fabric/core/handlers/validation/api/state"
    24  	"github.com/hyperledger/fabric/core/handlers/validation/builtin/v20/mocks"
    25  	"github.com/hyperledger/fabric/msp"
    26  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    27  	msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
    28  	"github.com/hyperledger/fabric/protoutil"
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/mock"
    31  )
    32  
    33  //go:generate counterfeiter -o mocks/capabilities.go -fake-name Capabilities . capabilities
    34  
    35  type capabilities interface {
    36  	validation.Capabilities
    37  }
    38  
    39  //go:generate counterfeiter -o mocks/state.go -fake-name State . state
    40  
    41  type state interface {
    42  	vs.State
    43  }
    44  
    45  //go:generate counterfeiter -o mocks/state_fetcher.go -fake-name StateFetcher . stateFetcher
    46  
    47  type stateFetcher interface {
    48  	vs.StateFetcher
    49  }
    50  
    51  func createTx(endorsedByDuplicatedIdentity bool) (*common.Envelope, error) {
    52  	ccid := &peer.ChaincodeID{Name: "foo", Version: "v1"}
    53  	cis := &peer.ChaincodeInvocationSpec{ChaincodeSpec: &peer.ChaincodeSpec{ChaincodeId: ccid}}
    54  
    55  	prop, _, err := protoutil.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, "testchannelid", cis, sid)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &peer.Response{Status: 200}, []byte("res"), nil, ccid, id)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	var env *common.Envelope
    66  	if endorsedByDuplicatedIdentity {
    67  		env, err = protoutil.CreateSignedTx(prop, id, presp, presp)
    68  	} else {
    69  		env, err = protoutil.CreateSignedTx(prop, id, presp)
    70  	}
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	return env, err
    75  }
    76  
    77  func getSignedByMSPMemberPolicy(mspID string) ([]byte, error) {
    78  	p := policydsl.SignedByMspMember(mspID)
    79  
    80  	b, err := protoutil.Marshal(p)
    81  	if err != nil {
    82  		return nil, fmt.Errorf("Could not marshal policy, err %s", err)
    83  	}
    84  
    85  	return b, err
    86  }
    87  
    88  func newValidationInstance(state map[string]map[string][]byte) *Validator {
    89  	vs := &mocks.State{}
    90  	vs.GetStateMultipleKeysStub = func(namespace string, keys []string) ([][]byte, error) {
    91  		if ns, ok := state[namespace]; ok {
    92  			return [][]byte{ns[keys[0]]}, nil
    93  
    94  		} else {
    95  			return nil, fmt.Errorf("could not retrieve namespace %s", namespace)
    96  		}
    97  	}
    98  	sf := &mocks.StateFetcher{}
    99  	sf.FetchStateReturns(vs, nil)
   100  	return newCustomValidationInstance(sf, &mocks.Capabilities{})
   101  }
   102  
   103  func newCustomValidationInstance(sf vs.StateFetcher, c validation.Capabilities) *Validator {
   104  	sbvm := &mocks.StateBasedValidator{}
   105  	sbvm.On("PreValidate", mock.Anything, mock.Anything, mock.Anything).Return(nil)
   106  	sbvm.On("PostValidate", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   107  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   108  
   109  	mockCR := &mocks.CollectionResources{}
   110  	mockCR.On("CollectionValidationInfo", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil, nil)
   111  
   112  	is := &mocks.IdentityDeserializer{}
   113  	pe := &txvalidator.PolicyEvaluator{
   114  		IdentityDeserializer: mspmgmt.GetManagerForChain("testchannelid"),
   115  	}
   116  	v := New(c, sf, is, pe, mockCR)
   117  
   118  	v.stateBasedValidator = sbvm
   119  	return v
   120  }
   121  
   122  func TestStateBasedValidationFailure(t *testing.T) {
   123  	sbvm := &mocks.StateBasedValidator{}
   124  	sbvm.On("PreValidate", mock.Anything, mock.Anything, mock.Anything).Return(nil)
   125  	sbvm.On("PostValidate", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   126  
   127  	mockCR := &mocks.CollectionResources{}
   128  	mockCR.On("CollectionValidationInfo", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil, nil)
   129  
   130  	sf := &mocks.StateFetcher{}
   131  	is := &mocks.IdentityDeserializer{}
   132  	pe := &txvalidator.PolicyEvaluator{
   133  		IdentityDeserializer: mspmgmt.GetManagerForChain("testchannelid"),
   134  	}
   135  	v := New(&mocks.Capabilities{}, sf, is, pe, mockCR)
   136  	v.stateBasedValidator = sbvm
   137  
   138  	tx, err := createTx(false)
   139  	if err != nil {
   140  		t.Fatalf("createTx returned err %s", err)
   141  	}
   142  
   143  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   144  	if err != nil {
   145  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   146  	}
   147  
   148  	policy, err := getSignedByMSPMemberPolicy(mspid)
   149  	if err != nil {
   150  		t.Fatalf("failed getting policy, err %s", err)
   151  	}
   152  
   153  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   154  
   155  	// bad path: policy validation error
   156  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&commonerrors.VSCCEndorsementPolicyError{Err: fmt.Errorf("some sbe validation err")}).Once()
   157  	err = v.Validate(b, "foo", 0, 0, policy)
   158  	assert.Error(t, err)
   159  	assert.IsType(t, &commonerrors.VSCCEndorsementPolicyError{}, err)
   160  
   161  	// bad path: execution error
   162  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&commonerrors.VSCCExecutionFailureError{Err: fmt.Errorf("some sbe validation err")}).Once()
   163  	err = v.Validate(b, "foo", 0, 0, policy)
   164  	assert.Error(t, err)
   165  	assert.IsType(t, &commonerrors.VSCCExecutionFailureError{}, err)
   166  
   167  	// good path: signed by the right MSP
   168  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
   169  	err = v.Validate(b, "foo", 0, 0, policy)
   170  	assert.NoError(t, err)
   171  }
   172  
   173  func TestInvoke(t *testing.T) {
   174  	v := newValidationInstance(make(map[string]map[string][]byte))
   175  
   176  	// broken Envelope
   177  	var err error
   178  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{[]byte("a")}}, Header: &common.BlockHeader{}}
   179  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   180  	assert.Error(t, err)
   181  
   182  	// (still) broken Envelope
   183  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{Payload: []byte("barf")})}}, Header: &common.BlockHeader{}}
   184  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   185  	assert.Error(t, err)
   186  
   187  	// (still) broken Envelope
   188  	e := protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: []byte("barf")}})})
   189  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   190  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   191  	assert.Error(t, err)
   192  
   193  	tx, err := createTx(false)
   194  	if err != nil {
   195  		t.Fatalf("createTx returned err %s", err)
   196  	}
   197  
   198  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   199  	if err != nil {
   200  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   201  	}
   202  
   203  	policy, err := getSignedByMSPMemberPolicy(mspid)
   204  	if err != nil {
   205  		t.Fatalf("failed getting policy, err %s", err)
   206  	}
   207  
   208  	// broken type
   209  	e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})})
   210  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   211  	err = v.Validate(b, "foo", 0, 0, policy)
   212  	assert.Error(t, err)
   213  
   214  	// broken tx payload
   215  	e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})})
   216  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   217  	err = v.Validate(b, "foo", 0, 0, policy)
   218  	assert.Error(t, err)
   219  
   220  	// good path: signed by the right MSP
   221  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   222  	err = v.Validate(b, "foo", 0, 0, policy)
   223  	assert.NoError(t, err)
   224  }
   225  
   226  func TestToApplicationPolicyTranslator_Translate(t *testing.T) {
   227  	tr := &toApplicationPolicyTranslator{}
   228  	res, err := tr.Translate(nil)
   229  	assert.NoError(t, err)
   230  	assert.Nil(t, res)
   231  
   232  	res, err = tr.Translate([]byte("barf"))
   233  	assert.Error(t, err)
   234  	assert.Contains(t, err.Error(), "could not unmarshal signature policy envelope: unexpected EOF")
   235  	assert.Nil(t, res)
   236  
   237  	res, err = tr.Translate(protoutil.MarshalOrPanic(policydsl.SignedByMspMember("the right honourable member for Ipswich")))
   238  	assert.NoError(t, err)
   239  	assert.Equal(t, res, protoutil.MarshalOrPanic(&peer.ApplicationPolicy{
   240  		Type: &peer.ApplicationPolicy_SignaturePolicy{
   241  			SignaturePolicy: policydsl.SignedByMspMember("the right honourable member for Ipswich"),
   242  		},
   243  	}))
   244  }
   245  
   246  var id msp.SigningIdentity
   247  var sid []byte
   248  var mspid string
   249  var channelID string = "testchannelid"
   250  
   251  type mockPolicyChecker struct{}
   252  
   253  func (c *mockPolicyChecker) CheckPolicy(channelID, policyName string, signedProp *peer.SignedProposal) error {
   254  	return nil
   255  }
   256  
   257  func (c *mockPolicyChecker) CheckPolicyBySignedData(channelID, policyName string, sd []*protoutil.SignedData) error {
   258  	return nil
   259  }
   260  
   261  func (c *mockPolicyChecker) CheckPolicyNoChannel(policyName string, signedProp *peer.SignedProposal) error {
   262  	return nil
   263  }
   264  
   265  func TestMain(m *testing.M) {
   266  	code := -1
   267  	defer func() {
   268  		os.Exit(code)
   269  	}()
   270  	testDir, err := ioutil.TempDir("", "v1.3-validation")
   271  	if err != nil {
   272  		fmt.Printf("Could not create temp dir: %s", err)
   273  		return
   274  	}
   275  	defer os.RemoveAll(testDir)
   276  	ccprovider.SetChaincodesPath(testDir)
   277  
   278  	// setup the MSP manager so that we can sign/verify
   279  	msptesttools.LoadMSPSetupForTesting()
   280  
   281  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   282  	if err != nil {
   283  		fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err)
   284  		return
   285  	}
   286  
   287  	id, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
   288  	if err != nil {
   289  		fmt.Printf("GetSigningIdentity failed with err %s", err)
   290  		return
   291  	}
   292  
   293  	sid, err = id.Serialize()
   294  	if err != nil {
   295  		fmt.Printf("Serialize failed with err %s", err)
   296  		return
   297  	}
   298  
   299  	// determine the MSP identifier for the first MSP in the default chain
   300  	var msp msp.MSP
   301  	mspMgr := mspmgmt.GetManagerForChain(channelID)
   302  	msps, err := mspMgr.GetMSPs()
   303  	if err != nil {
   304  		fmt.Printf("Could not retrieve the MSPs for the chain manager, err %s", err)
   305  		return
   306  	}
   307  	if len(msps) == 0 {
   308  		fmt.Printf("At least one MSP was expected")
   309  		return
   310  	}
   311  	for _, m := range msps {
   312  		msp = m
   313  		break
   314  	}
   315  	mspid, err = msp.GetIdentifier()
   316  	if err != nil {
   317  		fmt.Printf("Failure getting the msp identifier, err %s", err)
   318  		return
   319  	}
   320  
   321  	// also set the MSP for the "test" chain
   322  	mspmgmt.XXXSetMSPManager("mycc", mspmgmt.GetManagerForChain("testchannelid"))
   323  
   324  	code = m.Run()
   325  }