github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/peer/channel/channel.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 "fmt" 21 "strings" 22 23 "github.com/inklabsfoundation/inkchain/common/flogging" 24 "github.com/inklabsfoundation/inkchain/msp" 25 "github.com/inklabsfoundation/inkchain/peer/common" 26 ab "github.com/inklabsfoundation/inkchain/protos/orderer" 27 pb "github.com/inklabsfoundation/inkchain/protos/peer" 28 "github.com/spf13/cobra" 29 "github.com/spf13/pflag" 30 "golang.org/x/net/context" 31 "google.golang.org/grpc" 32 "google.golang.org/grpc/credentials" 33 ) 34 35 const ( 36 channelFuncName = "channel" 37 shortDes = "Operate a channel: create|fetch|join|list|update." 38 longDes = "Operate a channel: create|fetch|join|list|update." 39 ) 40 41 var logger = flogging.MustGetLogger("channelCmd") 42 43 type OrdererRequirement bool 44 type EndorserRequirement bool 45 46 const ( 47 EndorserRequired EndorserRequirement = true 48 EndorserNotRequired EndorserRequirement = false 49 OrdererRequired OrdererRequirement = true 50 OrdererNotRequired OrdererRequirement = false 51 ) 52 53 var ( 54 // join related variables. 55 genesisBlockPath string 56 57 // create related variables 58 chainID string 59 channelTxFile string 60 orderingEndpoint string 61 tls bool 62 caFile string 63 timeout int 64 ) 65 66 // Cmd returns the cobra command for Node 67 func Cmd(cf *ChannelCmdFactory) *cobra.Command { 68 AddFlags(channelCmd) 69 70 channelCmd.AddCommand(createCmd(cf)) 71 channelCmd.AddCommand(fetchCmd(cf)) 72 channelCmd.AddCommand(joinCmd(cf)) 73 channelCmd.AddCommand(listCmd(cf)) 74 channelCmd.AddCommand(updateCmd(cf)) 75 channelCmd.AddCommand(signconfigtxCmd(cf)) 76 77 return channelCmd 78 } 79 80 // AddFlags adds flags for create and join 81 func AddFlags(cmd *cobra.Command) { 82 flags := cmd.PersistentFlags() 83 84 flags.StringVarP(&orderingEndpoint, "orderer", "o", "", "Ordering service endpoint") 85 flags.BoolVarP(&tls, "tls", "", false, "Use TLS when communicating with the orderer endpoint") 86 flags.StringVarP(&caFile, "cafile", "", "", "Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint") 87 } 88 89 var flags *pflag.FlagSet 90 91 func init() { 92 resetFlags() 93 } 94 95 // Explicitly define a method to facilitate tests 96 func resetFlags() { 97 flags = &pflag.FlagSet{} 98 99 flags.StringVarP(&genesisBlockPath, "blockpath", "b", common.UndefinedParamValue, "Path to file containing genesis block") 100 flags.StringVarP(&chainID, "channelID", "c", common.UndefinedParamValue, "In case of a newChain command, the channel ID to create.") 101 flags.StringVarP(&channelTxFile, "file", "f", "", "Configuration transaction file generated by a tool such as configtxgen for submitting to orderer") 102 flags.IntVarP(&timeout, "timeout", "t", 5, "Channel creation timeout") 103 } 104 105 func attachFlags(cmd *cobra.Command, names []string) { 106 cmdFlags := cmd.Flags() 107 for _, name := range names { 108 if flag := flags.Lookup(name); flag != nil { 109 cmdFlags.AddFlag(flag) 110 } else { 111 logger.Fatalf("Could not find flag '%s' to attach to commond '%s'", name, cmd.Name()) 112 } 113 } 114 } 115 116 var channelCmd = &cobra.Command{ 117 Use: channelFuncName, 118 Short: fmt.Sprint(shortDes), 119 Long: fmt.Sprint(longDes), 120 } 121 122 type BroadcastClientFactory func() (common.BroadcastClient, error) 123 124 // ChannelCmdFactory holds the clients used by ChannelCmdFactory 125 type ChannelCmdFactory struct { 126 EndorserClient pb.EndorserClient 127 Signer msp.SigningIdentity 128 BroadcastClient common.BroadcastClient 129 DeliverClient deliverClientIntf 130 BroadcastFactory BroadcastClientFactory 131 } 132 133 // InitCmdFactory init the ChannelCmdFactory with clients to endorser and orderer according to params 134 func InitCmdFactory(isEndorserRequired EndorserRequirement, isOrdererRequired OrdererRequirement) (*ChannelCmdFactory, error) { 135 var err error 136 137 cmdFact := &ChannelCmdFactory{} 138 139 cmdFact.Signer, err = common.GetDefaultSignerFnc() 140 if err != nil { 141 return nil, fmt.Errorf("Error getting default signer: %s", err) 142 } 143 144 cmdFact.BroadcastFactory = func() (common.BroadcastClient, error) { 145 return common.GetBroadcastClientFnc(orderingEndpoint, tls, caFile) 146 } 147 148 //for join and list, we need the endorser as well 149 if isEndorserRequired { 150 cmdFact.EndorserClient, err = common.GetEndorserClientFnc() 151 if err != nil { 152 return nil, fmt.Errorf("Error getting endorser client %s: %s", channelFuncName, err) 153 } 154 } 155 156 //for create and fetch, we need the orderer as well 157 if isOrdererRequired { 158 if len(strings.Split(orderingEndpoint, ":")) != 2 { 159 return nil, fmt.Errorf("Ordering service endpoint %s is not valid or missing", orderingEndpoint) 160 } 161 162 var opts []grpc.DialOption 163 // check for TLS 164 if tls { 165 if caFile != "" { 166 creds, err := credentials.NewClientTLSFromFile(caFile, "") 167 if err != nil { 168 return nil, fmt.Errorf("Error connecting to %s due to %s", orderingEndpoint, err) 169 } 170 opts = append(opts, grpc.WithTransportCredentials(creds)) 171 } 172 } else { 173 opts = append(opts, grpc.WithInsecure()) 174 } 175 conn, err := grpc.Dial(orderingEndpoint, opts...) 176 if err != nil { 177 return nil, err 178 } 179 180 client, err := ab.NewAtomicBroadcastClient(conn).Deliver(context.TODO()) 181 if err != nil { 182 return nil, fmt.Errorf("Error connecting due to %s", err) 183 } 184 185 cmdFact.DeliverClient = newDeliverClient(conn, client, chainID) 186 } 187 logger.Infof("Endorser and orderer connections initialized") 188 return cmdFact, nil 189 }