github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/handlers/validation/builtin/v20/validation_logic_test.go (about)

     1  /*
     2  Copyright hechain. 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/hechain20/hechain/bccsp/sw"
    16  	commonerrors "github.com/hechain20/hechain/common/errors"
    17  	"github.com/hechain20/hechain/common/policydsl"
    18  	"github.com/hechain20/hechain/core/committer/txvalidator/v14"
    19  	"github.com/hechain20/hechain/core/common/ccprovider"
    20  	validation "github.com/hechain20/hechain/core/handlers/validation/api/capabilities"
    21  	vs "github.com/hechain20/hechain/core/handlers/validation/api/state"
    22  	"github.com/hechain20/hechain/core/handlers/validation/builtin/v20/mocks"
    23  	"github.com/hechain20/hechain/msp"
    24  	mspmgmt "github.com/hechain20/hechain/msp/mgmt"
    25  	msptesttools "github.com/hechain20/hechain/msp/mgmt/testtools"
    26  	"github.com/hechain20/hechain/protoutil"
    27  	"github.com/hyperledger/fabric-protos-go/common"
    28  	"github.com/hyperledger/fabric-protos-go/peer"
    29  	"github.com/stretchr/testify/mock"
    30  	"github.com/stretchr/testify/require"
    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  		} else {
    94  			return nil, fmt.Errorf("could not retrieve namespace %s", namespace)
    95  		}
    96  	}
    97  	sf := &mocks.StateFetcher{}
    98  	sf.FetchStateReturns(vs, nil)
    99  	return newCustomValidationInstance(sf, &mocks.Capabilities{})
   100  }
   101  
   102  func newCustomValidationInstance(sf vs.StateFetcher, c validation.Capabilities) *Validator {
   103  	sbvm := &mocks.StateBasedValidator{}
   104  	sbvm.On("PreValidate", mock.Anything, mock.Anything, mock.Anything).Return(nil)
   105  	sbvm.On("PostValidate", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   106  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   107  
   108  	mockCR := &mocks.CollectionResources{}
   109  	mockCR.On("CollectionValidationInfo", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil, nil)
   110  
   111  	is := &mocks.IdentityDeserializer{}
   112  	pe := &txvalidator.PolicyEvaluator{
   113  		IdentityDeserializer: mspmgmt.GetManagerForChain("testchannelid"),
   114  	}
   115  	v := New(c, sf, is, pe, mockCR)
   116  
   117  	v.stateBasedValidator = sbvm
   118  	return v
   119  }
   120  
   121  func TestStateBasedValidationFailure(t *testing.T) {
   122  	sbvm := &mocks.StateBasedValidator{}
   123  	sbvm.On("PreValidate", mock.Anything, mock.Anything, mock.Anything).Return(nil)
   124  	sbvm.On("PostValidate", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
   125  
   126  	mockCR := &mocks.CollectionResources{}
   127  	mockCR.On("CollectionValidationInfo", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil, nil)
   128  
   129  	sf := &mocks.StateFetcher{}
   130  	is := &mocks.IdentityDeserializer{}
   131  	pe := &txvalidator.PolicyEvaluator{
   132  		IdentityDeserializer: mspmgmt.GetManagerForChain("testchannelid"),
   133  	}
   134  	v := New(&mocks.Capabilities{}, sf, is, pe, mockCR)
   135  	v.stateBasedValidator = sbvm
   136  
   137  	tx, err := createTx(false)
   138  	if err != nil {
   139  		t.Fatalf("createTx returned err %s", err)
   140  	}
   141  
   142  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   143  	if err != nil {
   144  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   145  	}
   146  
   147  	policy, err := getSignedByMSPMemberPolicy(mspid)
   148  	if err != nil {
   149  		t.Fatalf("failed getting policy, err %s", err)
   150  	}
   151  
   152  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   153  
   154  	// bad path: policy validation error
   155  	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()
   156  	err = v.Validate(b, "foo", 0, 0, policy)
   157  	require.Error(t, err)
   158  	require.IsType(t, &commonerrors.VSCCEndorsementPolicyError{}, err)
   159  
   160  	// bad path: execution error
   161  	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()
   162  	err = v.Validate(b, "foo", 0, 0, policy)
   163  	require.Error(t, err)
   164  	require.IsType(t, &commonerrors.VSCCExecutionFailureError{}, err)
   165  
   166  	// good path: signed by the right MSP
   167  	sbvm.On("Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
   168  	err = v.Validate(b, "foo", 0, 0, policy)
   169  	require.NoError(t, err)
   170  }
   171  
   172  func TestInvoke(t *testing.T) {
   173  	v := newValidationInstance(make(map[string]map[string][]byte))
   174  
   175  	// broken Envelope
   176  	var err error
   177  	b := &common.Block{Data: &common.BlockData{Data: [][]byte{[]byte("a")}}, Header: &common.BlockHeader{}}
   178  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   179  	require.Error(t, err)
   180  
   181  	// (still) broken Envelope
   182  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(&common.Envelope{Payload: []byte("barf")})}}, Header: &common.BlockHeader{}}
   183  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   184  	require.Error(t, err)
   185  
   186  	// (still) broken Envelope
   187  	e := protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: []byte("barf")}})})
   188  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   189  	err = v.Validate(b, "foo", 0, 0, []byte("a"))
   190  	require.Error(t, err)
   191  
   192  	tx, err := createTx(false)
   193  	if err != nil {
   194  		t.Fatalf("createTx returned err %s", err)
   195  	}
   196  
   197  	envBytes, err := protoutil.GetBytesEnvelope(tx)
   198  	if err != nil {
   199  		t.Fatalf("GetBytesEnvelope returned err %s", err)
   200  	}
   201  
   202  	policy, err := getSignedByMSPMemberPolicy(mspid)
   203  	if err != nil {
   204  		t.Fatalf("failed getting policy, err %s", err)
   205  	}
   206  
   207  	// broken type
   208  	e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})})
   209  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   210  	err = v.Validate(b, "foo", 0, 0, policy)
   211  	require.Error(t, err)
   212  
   213  	// broken tx payload
   214  	e = protoutil.MarshalOrPanic(&common.Envelope{Payload: protoutil.MarshalOrPanic(&common.Payload{Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_ORDERER_TRANSACTION)})}})})
   215  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{e}}, Header: &common.BlockHeader{}}
   216  	err = v.Validate(b, "foo", 0, 0, policy)
   217  	require.Error(t, err)
   218  
   219  	// good path: signed by the right MSP
   220  	b = &common.Block{Data: &common.BlockData{Data: [][]byte{envBytes}}, Header: &common.BlockHeader{}}
   221  	err = v.Validate(b, "foo", 0, 0, policy)
   222  	require.NoError(t, err)
   223  }
   224  
   225  func TestToApplicationPolicyTranslator_Translate(t *testing.T) {
   226  	tr := &toApplicationPolicyTranslator{}
   227  	res, err := tr.Translate(nil)
   228  	require.NoError(t, err)
   229  	require.Nil(t, res)
   230  
   231  	res, err = tr.Translate([]byte("barf"))
   232  	require.Error(t, err)
   233  	require.Contains(t, err.Error(), "could not unmarshal signature policy envelope: unexpected EOF")
   234  	require.Nil(t, res)
   235  
   236  	res, err = tr.Translate(protoutil.MarshalOrPanic(policydsl.SignedByMspMember("the right honourable member for Ipswich")))
   237  	require.NoError(t, err)
   238  	require.Equal(t, res, protoutil.MarshalOrPanic(&peer.ApplicationPolicy{
   239  		Type: &peer.ApplicationPolicy_SignaturePolicy{
   240  			SignaturePolicy: policydsl.SignedByMspMember("the right honourable member for Ipswich"),
   241  		},
   242  	}))
   243  }
   244  
   245  var (
   246  	id        msp.SigningIdentity
   247  	sid       []byte
   248  	mspid     string
   249  	channelID string = "testchannelid"
   250  )
   251  
   252  func TestMain(m *testing.M) {
   253  	code := -1
   254  	defer func() {
   255  		os.Exit(code)
   256  	}()
   257  	testDir, err := ioutil.TempDir("", "v1.3-validation")
   258  	if err != nil {
   259  		fmt.Printf("Could not create temp dir: %s", err)
   260  		return
   261  	}
   262  	defer os.RemoveAll(testDir)
   263  	ccprovider.SetChaincodesPath(testDir)
   264  
   265  	// setup the MSP manager so that we can sign/verify
   266  	msptesttools.LoadMSPSetupForTesting()
   267  
   268  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   269  	if err != nil {
   270  		fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err)
   271  		return
   272  	}
   273  
   274  	id, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
   275  	if err != nil {
   276  		fmt.Printf("GetDefaultSigningIdentity failed with err %s", err)
   277  		return
   278  	}
   279  
   280  	sid, err = id.Serialize()
   281  	if err != nil {
   282  		fmt.Printf("Serialize failed with err %s", err)
   283  		return
   284  	}
   285  
   286  	// determine the MSP identifier for the first MSP in the default chain
   287  	var msp msp.MSP
   288  	mspMgr := mspmgmt.GetManagerForChain(channelID)
   289  	msps, err := mspMgr.GetMSPs()
   290  	if err != nil {
   291  		fmt.Printf("Could not retrieve the MSPs for the chain manager, err %s", err)
   292  		return
   293  	}
   294  	if len(msps) == 0 {
   295  		fmt.Printf("At least one MSP was expected")
   296  		return
   297  	}
   298  	for _, m := range msps {
   299  		msp = m
   300  		break
   301  	}
   302  	mspid, err = msp.GetIdentifier()
   303  	if err != nil {
   304  		fmt.Printf("Failure getting the msp identifier, err %s", err)
   305  		return
   306  	}
   307  
   308  	// also set the MSP for the "test" chain
   309  	mspmgmt.XXXSetMSPManager("mycc", mspmgmt.GetManagerForChain("testchannelid"))
   310  
   311  	code = m.Run()
   312  }