-
Notifications
You must be signed in to change notification settings - Fork 8.9k
/
support.go
109 lines (97 loc) · 3.61 KB
/
support.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package lscc
import (
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/common/policydsl"
"github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/hyperledger/fabric/msp/mgmt"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
)
type SupportImpl struct {
GetMSPIDs MSPIDsGetter
}
// PutChaincodeToLocalStorage stores the supplied chaincode
// package to local storage (i.e. the file system)
func (s *SupportImpl) PutChaincodeToLocalStorage(ccpack ccprovider.CCPackage) error {
if err := ccpack.PutChaincodeToFS(); err != nil {
return errors.Errorf("error installing chaincode code %s:%s(%s)", ccpack.GetChaincodeData().Name, ccpack.GetChaincodeData().Version, err)
}
return nil
}
// GetChaincodeFromLocalStorage retrieves the chaincode package
// for the requested chaincode, specified by name and version
func (s *SupportImpl) GetChaincodeFromLocalStorage(ccNameVersion string) (ccprovider.CCPackage, error) {
return ccprovider.GetChaincodeFromFS(ccNameVersion)
}
// GetChaincodesFromLocalStorage returns an array of all chaincode
// data that have previously been persisted to local storage
func (s *SupportImpl) GetChaincodesFromLocalStorage() (*pb.ChaincodeQueryResponse, error) {
return ccprovider.GetInstalledChaincodes()
}
// GetInstantiationPolicy returns the instantiation policy for the
// supplied chaincode (or the channel's default if none was specified)
func (s *SupportImpl) GetInstantiationPolicy(channel string, ccpack ccprovider.CCPackage) ([]byte, error) {
var ip []byte
var err error
// if ccpack is a SignedCDSPackage, return its IP, otherwise use a default IP
sccpack, isSccpack := ccpack.(*ccprovider.SignedCDSPackage)
if isSccpack {
ip = sccpack.GetInstantiationPolicy()
if ip == nil {
return nil, errors.Errorf("instantiation policy cannot be nil for a SignedCCDeploymentSpec")
}
} else {
// the default instantiation policy allows any of the channel MSP admins
// to be able to instantiate
mspids := s.GetMSPIDs(channel)
p := policydsl.SignedByAnyAdmin(mspids)
ip, err = protoutil.Marshal(p)
if err != nil {
return nil, errors.Errorf("error marshalling default instantiation policy")
}
}
return ip, nil
}
// CheckInstantiationPolicy checks whether the supplied signed proposal
// complies with the supplied instantiation policy
func (s *SupportImpl) CheckInstantiationPolicy(signedProp *pb.SignedProposal, chainName string, instantiationPolicy []byte) error {
// create a policy object from the policy bytes
mgr := mgmt.GetManagerForChain(chainName)
if mgr == nil {
return errors.Errorf("error checking chaincode instantiation policy: MSP manager for channel %s not found", chainName)
}
npp := cauthdsl.NewPolicyProvider(mgr)
instPol, _, err := npp.NewPolicy(instantiationPolicy)
if err != nil {
return err
}
proposal, err := protoutil.UnmarshalProposal(signedProp.ProposalBytes)
if err != nil {
return err
}
// get the signature header of the proposal
header, err := protoutil.UnmarshalHeader(proposal.Header)
if err != nil {
return err
}
shdr, err := protoutil.UnmarshalSignatureHeader(header.SignatureHeader)
if err != nil {
return err
}
// construct signed data we can evaluate the instantiation policy against
sd := []*protoutil.SignedData{{
Data: signedProp.ProposalBytes,
Identity: shdr.Creator,
Signature: signedProp.Signature,
}}
err = instPol.EvaluateSignedData(sd)
if err != nil {
return errors.WithMessage(err, "instantiation policy violation")
}
return nil
}