github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/pkg/gateway/apiutils.go (about) 1 /* 2 Copyright 2021 IBM All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package gateway 8 9 import ( 10 "fmt" 11 12 "github.com/golang/protobuf/proto" 13 "github.com/hechain20/hechain/protoutil" 14 "github.com/hyperledger/fabric-protos-go/common" 15 gp "github.com/hyperledger/fabric-protos-go/gateway" 16 "github.com/hyperledger/fabric-protos-go/peer" 17 "github.com/pkg/errors" 18 "google.golang.org/grpc/codes" 19 "google.golang.org/grpc/status" 20 ) 21 22 func getChannelAndChaincodeFromSignedProposal(signedProposal *peer.SignedProposal) (string, string, bool, error) { 23 if signedProposal == nil { 24 return "", "", false, fmt.Errorf("a signed proposal is required") 25 } 26 proposal, err := protoutil.UnmarshalProposal(signedProposal.ProposalBytes) 27 if err != nil { 28 return "", "", false, err 29 } 30 header, err := protoutil.UnmarshalHeader(proposal.Header) 31 if err != nil { 32 return "", "", false, err 33 } 34 channelHeader, err := protoutil.UnmarshalChannelHeader(header.ChannelHeader) 35 if err != nil { 36 return "", "", false, err 37 } 38 payload, err := protoutil.UnmarshalChaincodeProposalPayload(proposal.Payload) 39 if err != nil { 40 return "", "", false, err 41 } 42 spec, err := protoutil.UnmarshalChaincodeInvocationSpec(payload.Input) 43 if err != nil { 44 return "", "", false, err 45 } 46 47 return channelHeader.ChannelId, spec.ChaincodeSpec.ChaincodeId.Name, len(payload.TransientMap) > 0, nil 48 } 49 50 func newRpcError(code codes.Code, message string, details ...proto.Message) error { 51 st := status.New(code, message) 52 if len(details) != 0 { 53 std, err := st.WithDetails(details...) 54 if err == nil { 55 return std.Err() 56 } // otherwise return the error without the details 57 } 58 return st.Err() 59 } 60 61 func toRpcError(err error, unknownCode codes.Code) error { 62 errStatus := toRpcStatus(err) 63 if errStatus.Code() != codes.Unknown { 64 return errStatus.Err() 65 } 66 67 return status.Error(unknownCode, err.Error()) 68 } 69 70 func toRpcStatus(err error) *status.Status { 71 errStatus, ok := status.FromError(err) 72 if ok { 73 return errStatus 74 } 75 76 return status.FromContextError(err) 77 } 78 79 func errorDetail(e *endpointConfig, msg string) *gp.ErrorDetail { 80 return &gp.ErrorDetail{Address: e.address, MspId: e.mspid, Message: msg} 81 } 82 83 func getResultFromProposalResponse(proposalResponse *peer.ProposalResponse) ([]byte, error) { 84 responsePayload := &peer.ProposalResponsePayload{} 85 if err := proto.Unmarshal(proposalResponse.GetPayload(), responsePayload); err != nil { 86 return nil, errors.Wrap(err, "failed to deserialize proposal response payload") 87 } 88 89 return getResultFromProposalResponsePayload(responsePayload) 90 } 91 92 func getResultFromProposalResponsePayload(responsePayload *peer.ProposalResponsePayload) ([]byte, error) { 93 chaincodeAction := &peer.ChaincodeAction{} 94 if err := proto.Unmarshal(responsePayload.GetExtension(), chaincodeAction); err != nil { 95 return nil, errors.Wrap(err, "failed to deserialize chaincode action") 96 } 97 98 return chaincodeAction.GetResponse().GetPayload(), nil 99 } 100 101 func prepareTransaction(header *common.Header, payload *peer.ChaincodeProposalPayload, action *peer.ChaincodeEndorsedAction) (*common.Envelope, error) { 102 cppNoTransient := &peer.ChaincodeProposalPayload{Input: payload.Input, TransientMap: nil} 103 cppBytes, err := protoutil.GetBytesChaincodeProposalPayload(cppNoTransient) 104 if err != nil { 105 return nil, err 106 } 107 108 cap := &peer.ChaincodeActionPayload{ChaincodeProposalPayload: cppBytes, Action: action} 109 capBytes, err := protoutil.GetBytesChaincodeActionPayload(cap) 110 if err != nil { 111 return nil, err 112 } 113 114 tx := &peer.Transaction{Actions: []*peer.TransactionAction{{Header: header.SignatureHeader, Payload: capBytes}}} 115 txBytes, err := protoutil.GetBytesTransaction(tx) 116 if err != nil { 117 return nil, err 118 } 119 120 payl := &common.Payload{Header: header, Data: txBytes} 121 paylBytes, err := protoutil.GetBytesPayload(payl) 122 if err != nil { 123 return nil, err 124 } 125 126 return &common.Envelope{Payload: paylBytes}, nil 127 }