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 }