github.com/defanghe/fabric@v2.1.1+incompatible/internal/peer/channel/channel.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package channel 8 9 import ( 10 "strings" 11 "time" 12 13 cb "github.com/hyperledger/fabric-protos-go/common" 14 pb "github.com/hyperledger/fabric-protos-go/peer" 15 "github.com/hyperledger/fabric/common/flogging" 16 "github.com/hyperledger/fabric/internal/peer/common" 17 "github.com/hyperledger/fabric/msp" 18 "github.com/pkg/errors" 19 "github.com/spf13/cobra" 20 "github.com/spf13/pflag" 21 ) 22 23 var logger = flogging.MustGetLogger("channelCmd") 24 25 const ( 26 EndorserRequired bool = true 27 EndorserNotRequired bool = false 28 OrdererRequired bool = true 29 OrdererNotRequired bool = false 30 PeerDeliverRequired bool = true 31 PeerDeliverNotRequired bool = false 32 ) 33 34 var ( 35 // join related variables. 36 genesisBlockPath string 37 38 // create related variables 39 channelID string 40 channelTxFile string 41 outputBlock string 42 timeout time.Duration 43 44 // fetch related variables 45 bestEffort bool 46 ) 47 48 // Cmd returns the cobra command for Node 49 func Cmd(cf *ChannelCmdFactory) *cobra.Command { 50 AddFlags(channelCmd) 51 52 channelCmd.AddCommand(createCmd(cf)) 53 channelCmd.AddCommand(fetchCmd(cf)) 54 channelCmd.AddCommand(joinCmd(cf)) 55 channelCmd.AddCommand(listCmd(cf)) 56 channelCmd.AddCommand(updateCmd(cf)) 57 channelCmd.AddCommand(signconfigtxCmd(cf)) 58 channelCmd.AddCommand(getinfoCmd(cf)) 59 60 return channelCmd 61 } 62 63 // AddFlags adds flags for create and join 64 func AddFlags(cmd *cobra.Command) { 65 common.AddOrdererFlags(cmd) 66 } 67 68 var flags *pflag.FlagSet 69 70 func init() { 71 resetFlags() 72 } 73 74 // Explicitly define a method to facilitate tests 75 func resetFlags() { 76 flags = &pflag.FlagSet{} 77 78 flags.StringVarP(&genesisBlockPath, "blockpath", "b", common.UndefinedParamValue, "Path to file containing genesis block") 79 flags.StringVarP(&channelID, "channelID", "c", common.UndefinedParamValue, "In case of a newChain command, the channel ID to create. It must be all lower case, less than 250 characters long and match the regular expression: [a-z][a-z0-9.-]*") 80 flags.StringVarP(&channelTxFile, "file", "f", "", "Configuration transaction file generated by a tool such as configtxgen for submitting to orderer") 81 flags.StringVarP(&outputBlock, "outputBlock", "", common.UndefinedParamValue, `The path to write the genesis block for the channel. (default ./<channelID>.block)`) 82 flags.DurationVarP(&timeout, "timeout", "t", 10*time.Second, "Channel creation timeout") 83 flags.BoolVarP(&bestEffort, "bestEffort", "", false, "Whether fetch requests should ignore errors and return blocks on a best effort basis") 84 } 85 86 func attachFlags(cmd *cobra.Command, names []string) { 87 cmdFlags := cmd.Flags() 88 for _, name := range names { 89 if flag := flags.Lookup(name); flag != nil { 90 cmdFlags.AddFlag(flag) 91 } else { 92 logger.Fatalf("Could not find flag '%s' to attach to commond '%s'", name, cmd.Name()) 93 } 94 } 95 } 96 97 var channelCmd = &cobra.Command{ 98 Use: "channel", 99 Short: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.", 100 Long: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.", 101 PersistentPreRun: func(cmd *cobra.Command, args []string) { 102 common.InitCmd(cmd, args) 103 common.SetOrdererEnv(cmd, args) 104 }, 105 } 106 107 type BroadcastClientFactory func() (common.BroadcastClient, error) 108 109 type deliverClientIntf interface { 110 GetSpecifiedBlock(num uint64) (*cb.Block, error) 111 GetOldestBlock() (*cb.Block, error) 112 GetNewestBlock() (*cb.Block, error) 113 Close() error 114 } 115 116 // ChannelCmdFactory holds the clients used by ChannelCmdFactory 117 type ChannelCmdFactory struct { 118 EndorserClient pb.EndorserClient 119 Signer msp.SigningIdentity 120 BroadcastClient common.BroadcastClient 121 DeliverClient deliverClientIntf 122 BroadcastFactory BroadcastClientFactory 123 } 124 125 // InitCmdFactory init the ChannelCmdFactory with clients to endorser and orderer according to params 126 func InitCmdFactory(isEndorserRequired, isPeerDeliverRequired, isOrdererRequired bool) (*ChannelCmdFactory, error) { 127 if isPeerDeliverRequired && isOrdererRequired { 128 // this is likely a bug during development caused by adding a new cmd 129 return nil, errors.New("ERROR - only a single deliver source is currently supported") 130 } 131 132 var err error 133 cf := &ChannelCmdFactory{} 134 135 cf.Signer, err = common.GetDefaultSignerFnc() 136 if err != nil { 137 return nil, errors.WithMessage(err, "error getting default signer") 138 } 139 140 cf.BroadcastFactory = func() (common.BroadcastClient, error) { 141 return common.GetBroadcastClientFnc() 142 } 143 144 // for join and list, we need the endorser as well 145 if isEndorserRequired { 146 // creating an EndorserClient with these empty parameters will create a 147 // connection using the values of "peer.address" and 148 // "peer.tls.rootcert.file" 149 cf.EndorserClient, err = common.GetEndorserClientFnc(common.UndefinedParamValue, common.UndefinedParamValue) 150 if err != nil { 151 return nil, errors.WithMessage(err, "error getting endorser client for channel") 152 } 153 } 154 155 // for fetching blocks from a peer 156 if isPeerDeliverRequired { 157 cf.DeliverClient, err = common.NewDeliverClientForPeer(channelID, cf.Signer, bestEffort) 158 if err != nil { 159 return nil, errors.WithMessage(err, "error getting deliver client for channel") 160 } 161 } 162 163 // for create and fetch, we need the orderer as well 164 if isOrdererRequired { 165 if len(strings.Split(common.OrderingEndpoint, ":")) != 2 { 166 return nil, errors.Errorf("ordering service endpoint %s is not valid or missing", common.OrderingEndpoint) 167 } 168 cf.DeliverClient, err = common.NewDeliverClientForOrderer(channelID, cf.Signer, bestEffort) 169 if err != nil { 170 return nil, err 171 } 172 } 173 174 logger.Infof("Endorser and orderer connections initialized") 175 return cf, nil 176 }