github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/peer/channel/join.go (about) 1 /* 2 Copyright hechain. 2017 All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package channel 8 9 import ( 10 "context" 11 "errors" 12 "fmt" 13 "io/ioutil" 14 15 "github.com/hechain20/hechain/core/scc/cscc" 16 "github.com/hechain20/hechain/internal/peer/common" 17 "github.com/hechain20/hechain/protoutil" 18 pcommon "github.com/hyperledger/fabric-protos-go/common" 19 pb "github.com/hyperledger/fabric-protos-go/peer" 20 "github.com/spf13/cobra" 21 ) 22 23 const commandDescription = "Joins the peer to a channel." 24 25 func joinCmd(cf *ChannelCmdFactory) *cobra.Command { 26 // Set the flags on the channel start command. 27 joinCmd := &cobra.Command{ 28 Use: "join", 29 Short: commandDescription, 30 Long: commandDescription, 31 RunE: func(cmd *cobra.Command, args []string) error { 32 return join(cmd, args, cf) 33 }, 34 } 35 flagList := []string{ 36 "blockpath", 37 } 38 attachFlags(joinCmd, flagList) 39 40 return joinCmd 41 } 42 43 // GBFileNotFoundErr genesis block file not found 44 type GBFileNotFoundErr string 45 46 func (e GBFileNotFoundErr) Error() string { 47 return fmt.Sprintf("genesis block file not found %s", string(e)) 48 } 49 50 // ProposalFailedErr proposal failed 51 type ProposalFailedErr string 52 53 func (e ProposalFailedErr) Error() string { 54 return fmt.Sprintf("proposal failed (err: %s)", string(e)) 55 } 56 57 func getJoinCCSpec() (*pb.ChaincodeSpec, error) { 58 if genesisBlockPath == common.UndefinedParamValue { 59 return nil, errors.New("Must supply genesis block file") 60 } 61 62 gb, err := ioutil.ReadFile(genesisBlockPath) 63 if err != nil { 64 return nil, GBFileNotFoundErr(err.Error()) 65 } 66 // Build the spec 67 input := &pb.ChaincodeInput{Args: [][]byte{[]byte(cscc.JoinChain), gb}} 68 69 spec := &pb.ChaincodeSpec{ 70 Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), 71 ChaincodeId: &pb.ChaincodeID{Name: "cscc"}, 72 Input: input, 73 } 74 75 return spec, nil 76 } 77 78 func executeJoin(cf *ChannelCmdFactory, spec *pb.ChaincodeSpec) (err error) { 79 // Build the ChaincodeInvocationSpec message 80 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 81 82 creator, err := cf.Signer.Serialize() 83 if err != nil { 84 return fmt.Errorf("Error serializing identity for %s: %s", cf.Signer.GetIdentifier(), err) 85 } 86 87 var prop *pb.Proposal 88 prop, _, err = protoutil.CreateProposalFromCIS(pcommon.HeaderType_CONFIG, "", invocation, creator) 89 if err != nil { 90 return fmt.Errorf("Error creating proposal for join %s", err) 91 } 92 93 var signedProp *pb.SignedProposal 94 signedProp, err = protoutil.GetSignedProposal(prop, cf.Signer) 95 if err != nil { 96 return fmt.Errorf("Error creating signed proposal %s", err) 97 } 98 99 var proposalResp *pb.ProposalResponse 100 proposalResp, err = cf.EndorserClient.ProcessProposal(context.Background(), signedProp) 101 if err != nil { 102 return ProposalFailedErr(err.Error()) 103 } 104 105 if proposalResp == nil { 106 return ProposalFailedErr("nil proposal response") 107 } 108 109 if proposalResp.Response.Status != 0 && proposalResp.Response.Status != 200 { 110 return ProposalFailedErr(fmt.Sprintf("bad proposal response %d: %s", proposalResp.Response.Status, proposalResp.Response.Message)) 111 } 112 logger.Info("Successfully submitted proposal to join channel") 113 return nil 114 } 115 116 func join(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error { 117 if genesisBlockPath == common.UndefinedParamValue { 118 return errors.New("Must supply genesis block path") 119 } 120 // Parsing of the command line is done so silence cmd usage 121 cmd.SilenceUsage = true 122 123 var err error 124 if cf == nil { 125 cf, err = InitCmdFactory(EndorserRequired, PeerDeliverNotRequired, OrdererNotRequired) 126 if err != nil { 127 return err 128 } 129 } 130 131 spec, err := getJoinCCSpec() 132 if err != nil { 133 return err 134 } 135 136 return executeJoin(cf, spec) 137 }