go_study/fabric-main/internal/peer/lifecycle/chaincode/common.go

137 lines
3.7 KiB
Go

/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"context"
"encoding/json"
"fmt"
"io"
"github.com/golang/protobuf/proto"
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/policydsl"
"github.com/hyperledger/fabric/internal/peer/chaincode"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// EndorserClient defines the interface for sending a proposal
// to an endorser
type EndorserClient interface {
ProcessProposal(ctx context.Context, in *pb.SignedProposal, opts ...grpc.CallOption) (*pb.ProposalResponse, error)
}
// PeerDeliverClient defines the interface for a peer deliver client
type PeerDeliverClient interface {
Deliver(ctx context.Context, opts ...grpc.CallOption) (pb.Deliver_DeliverClient, error)
DeliverFiltered(ctx context.Context, opts ...grpc.CallOption) (pb.Deliver_DeliverClient, error)
}
// Signer defines the interface needed for signing messages
type Signer interface {
Sign(msg []byte) ([]byte, error)
Serialize() ([]byte, error)
}
// Writer defines the interface needed for writing a file
type Writer interface {
WriteFile(string, string, []byte) error
}
func signProposal(proposal *pb.Proposal, signer Signer) (*pb.SignedProposal, error) {
// check for nil argument
if proposal == nil {
return nil, errors.New("proposal cannot be nil")
}
if signer == nil {
return nil, errors.New("signer cannot be nil")
}
proposalBytes, err := proto.Marshal(proposal)
if err != nil {
return nil, errors.Wrap(err, "error marshaling proposal")
}
signature, err := signer.Sign(proposalBytes)
if err != nil {
return nil, err
}
return &pb.SignedProposal{
ProposalBytes: proposalBytes,
Signature: signature,
}, nil
}
func createPolicyBytes(signaturePolicy, channelConfigPolicy string) ([]byte, error) {
if signaturePolicy == "" && channelConfigPolicy == "" {
// no policy, no problem
return nil, nil
}
if signaturePolicy != "" && channelConfigPolicy != "" {
// mo policies, mo problems
return nil, errors.New("cannot specify both \"--signature-policy\" and \"--channel-config-policy\"")
}
var applicationPolicy *pb.ApplicationPolicy
if signaturePolicy != "" {
signaturePolicyEnvelope, err := policydsl.FromString(signaturePolicy)
if err != nil {
return nil, errors.Errorf("invalid signature policy: %s", signaturePolicy)
}
applicationPolicy = &pb.ApplicationPolicy{
Type: &pb.ApplicationPolicy_SignaturePolicy{
SignaturePolicy: signaturePolicyEnvelope,
},
}
}
if channelConfigPolicy != "" {
applicationPolicy = &pb.ApplicationPolicy{
Type: &pb.ApplicationPolicy_ChannelConfigPolicyReference{
ChannelConfigPolicyReference: channelConfigPolicy,
},
}
}
policyBytes := protoutil.MarshalOrPanic(applicationPolicy)
return policyBytes, nil
}
func createCollectionConfigPackage(collectionsConfigFile string) (*pb.CollectionConfigPackage, error) {
var ccp *pb.CollectionConfigPackage
if collectionsConfigFile != "" {
var err error
ccp, _, err = chaincode.GetCollectionConfigFromFile(collectionsConfigFile)
if err != nil {
return nil, errors.WithMessagef(err, "invalid collection configuration in file %s", collectionsConfigFile)
}
}
return ccp, nil
}
func printResponseAsJSON(proposalResponse *pb.ProposalResponse, msg proto.Message, out io.Writer) error {
err := proto.Unmarshal(proposalResponse.Response.Payload, msg)
if err != nil {
return errors.Wrapf(err, "failed to unmarshal proposal response's response payload as type %T", msg)
}
bytes, err := json.MarshalIndent(msg, "", "\t")
if err != nil {
return errors.Wrap(err, "failed to marshal output")
}
fmt.Fprintf(out, "%s\n", string(bytes))
return nil
}