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 }