github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/peer/channel/join.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package channel 18 19 import ( 20 "errors" 21 "fmt" 22 "io/ioutil" 23 24 "github.com/hyperledger/fabric/core/scc/cscc" 25 "github.com/hyperledger/fabric/peer/common" 26 pcommon "github.com/hyperledger/fabric/protos/common" 27 pb "github.com/hyperledger/fabric/protos/peer" 28 putils "github.com/hyperledger/fabric/protos/utils" 29 "github.com/spf13/cobra" 30 "golang.org/x/net/context" 31 ) 32 33 const commandDescription = "Joins the peer to a chain." 34 35 func joinCmd(cf *ChannelCmdFactory) *cobra.Command { 36 // Set the flags on the channel start command. 37 joinCmd := &cobra.Command{ 38 Use: "join", 39 Short: commandDescription, 40 Long: commandDescription, 41 RunE: func(cmd *cobra.Command, args []string) error { 42 return join(cmd, args, cf) 43 }, 44 } 45 flagList := []string{ 46 "blockpath", 47 } 48 attachFlags(joinCmd, flagList) 49 50 return joinCmd 51 } 52 53 //GBFileNotFoundErr genesis block file not found 54 type GBFileNotFoundErr string 55 56 func (e GBFileNotFoundErr) Error() string { 57 return fmt.Sprintf("genesis block file not found %s", string(e)) 58 } 59 60 //ProposalFailedErr proposal failed 61 type ProposalFailedErr string 62 63 func (e ProposalFailedErr) Error() string { 64 return fmt.Sprintf("proposal failed (err: %s)", string(e)) 65 } 66 67 func getJoinCCSpec() (*pb.ChaincodeSpec, error) { 68 if genesisBlockPath == common.UndefinedParamValue { 69 return nil, errors.New("Must supply genesis block file") 70 } 71 72 gb, err := ioutil.ReadFile(genesisBlockPath) 73 if err != nil { 74 return nil, GBFileNotFoundErr(err.Error()) 75 } 76 // Build the spec 77 input := &pb.ChaincodeInput{Args: [][]byte{[]byte(cscc.JoinChain), gb}} 78 79 spec := &pb.ChaincodeSpec{ 80 Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), 81 ChaincodeId: &pb.ChaincodeID{Name: "cscc"}, 82 Input: input, 83 } 84 85 return spec, nil 86 } 87 88 func executeJoin(cf *ChannelCmdFactory) (err error) { 89 spec, err := getJoinCCSpec() 90 if err != nil { 91 return err 92 } 93 94 // Build the ChaincodeInvocationSpec message 95 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 96 97 creator, err := cf.Signer.Serialize() 98 if err != nil { 99 return fmt.Errorf("Error serializing identity for %s: %s", cf.Signer.GetIdentifier(), err) 100 } 101 102 var prop *pb.Proposal 103 prop, _, err = putils.CreateProposalFromCIS(pcommon.HeaderType_CONFIG, "", invocation, creator) 104 if err != nil { 105 return fmt.Errorf("Error creating proposal for join %s", err) 106 } 107 108 var signedProp *pb.SignedProposal 109 signedProp, err = putils.GetSignedProposal(prop, cf.Signer) 110 if err != nil { 111 return fmt.Errorf("Error creating signed proposal %s", err) 112 } 113 114 var proposalResp *pb.ProposalResponse 115 proposalResp, err = cf.EndorserClient.ProcessProposal(context.Background(), signedProp) 116 if err != nil { 117 return ProposalFailedErr(err.Error()) 118 } 119 120 if proposalResp == nil { 121 return ProposalFailedErr("nil proposal response") 122 } 123 124 if proposalResp.Response.Status != 0 && proposalResp.Response.Status != 200 { 125 return ProposalFailedErr(fmt.Sprintf("bad proposal response %d", proposalResp.Response.Status)) 126 } 127 logger.Infof("Peer joined the channel!") 128 return nil 129 } 130 131 func join(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error { 132 if genesisBlockPath == common.UndefinedParamValue { 133 return errors.New("Must supply genesis block path") 134 } 135 136 var err error 137 if cf == nil { 138 cf, err = InitCmdFactory(EndorserRequired, OrdererNotRequired) 139 if err != nil { 140 return err 141 } 142 } 143 return executeJoin(cf) 144 }