/
channel.go
184 lines (152 loc) · 5.48 KB
/
channel.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//<developer>
// <name>linapex 曹一峰</name>
// <email>linapex@163.com</email>
// <wx>superexc</wx>
// <qqgroup>128148617</qqgroup>
// <url>https://jsq.ink</url>
// <role>pku engineer</role>
// <date>2019-03-16 19:40:32</date>
//</624456107649142784>
/*
版权所有IBM公司。保留所有权利。
SPDX许可证标识符:Apache-2.0
**/
package channel
import (
"strings"
"time"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/peer/common"
cb "github.com/hyperledger/fabric/protos/common"
pb "github.com/hyperledger/fabric/protos/peer"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var logger = flogging.MustGetLogger("channelCmd")
const (
EndorserRequired bool = true
EndorserNotRequired bool = false
OrdererRequired bool = true
OrdererNotRequired bool = false
PeerDeliverRequired bool = true
PeerDeliverNotRequired bool = false
)
var (
//联接相关变量。
genesisBlockPath string
//创建相关变量
channelID string
channelTxFile string
outputBlock string
timeout time.Duration
)
//cmd返回node的cobra命令
func Cmd(cf *ChannelCmdFactory) *cobra.Command {
AddFlags(channelCmd)
channelCmd.AddCommand(createCmd(cf))
channelCmd.AddCommand(fetchCmd(cf))
channelCmd.AddCommand(joinCmd(cf))
channelCmd.AddCommand(listCmd(cf))
channelCmd.AddCommand(updateCmd(cf))
channelCmd.AddCommand(signconfigtxCmd(cf))
channelCmd.AddCommand(getinfoCmd(cf))
return channelCmd
}
//AddFlags添加用于创建和联接的标志
func AddFlags(cmd *cobra.Command) {
common.AddOrdererFlags(cmd)
}
var flags *pflag.FlagSet
func init() {
resetFlags()
}
//明确定义一种方法来促进测试
func resetFlags() {
flags = &pflag.FlagSet{}
flags.StringVarP(&genesisBlockPath, "blockpath", "b", common.UndefinedParamValue, "Path to file containing genesis block")
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.-]*")
flags.StringVarP(&channelTxFile, "file", "f", "", "Configuration transaction file generated by a tool such as configtxgen for submitting to orderer")
flags.StringVarP(&outputBlock, "outputBlock", "", common.UndefinedParamValue, `The path to write the genesis block for the channel. (default ./<channelID>.block)`)
flags.DurationVarP(&timeout, "timeout", "t", 5*time.Second, "Channel creation timeout")
}
func attachFlags(cmd *cobra.Command, names []string) {
cmdFlags := cmd.Flags()
for _, name := range names {
if flag := flags.Lookup(name); flag != nil {
cmdFlags.AddFlag(flag)
} else {
logger.Fatalf("Could not find flag '%s' to attach to commond '%s'", name, cmd.Name())
}
}
}
var channelCmd = &cobra.Command{
Use: "channel",
Short: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.",
Long: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
common.InitCmd(cmd, args)
common.SetOrdererEnv(cmd, args)
},
}
type BroadcastClientFactory func() (common.BroadcastClient, error)
type deliverClientIntf interface {
GetSpecifiedBlock(num uint64) (*cb.Block, error)
GetOldestBlock() (*cb.Block, error)
GetNewestBlock() (*cb.Block, error)
Close() error
}
//channelCmdFactory保留channelCmdFactory使用的客户端
type ChannelCmdFactory struct {
EndorserClient pb.EndorserClient
Signer msp.SigningIdentity
BroadcastClient common.BroadcastClient
DeliverClient deliverClientIntf
BroadcastFactory BroadcastClientFactory
}
//initcmdfactory根据参数初始化带有客户机的channelCmdfactory以背书人和订购人
func InitCmdFactory(isEndorserRequired, isPeerDeliverRequired, isOrdererRequired bool) (*ChannelCmdFactory, error) {
if isPeerDeliverRequired && isOrdererRequired {
//这可能是由于添加新的命令而导致的开发过程中的错误。
return nil, errors.New("ERROR - only a single deliver source is currently supported")
}
var err error
cf := &ChannelCmdFactory{}
cf.Signer, err = common.GetDefaultSignerFnc()
if err != nil {
return nil, errors.WithMessage(err, "error getting default signer")
}
cf.BroadcastFactory = func() (common.BroadcastClient, error) {
return common.GetBroadcastClientFnc()
}
//对于加入和列出,我们也需要背书人。
if isEndorserRequired {
//使用这些空参数创建一个背书客户端将创建一个
//使用“peer.address”和
//“对等.tls.rootcert.file”
cf.EndorserClient, err = common.GetEndorserClientFnc(common.UndefinedParamValue, common.UndefinedParamValue)
if err != nil {
return nil, errors.WithMessage(err, "error getting endorser client for channel")
}
}
//用于从对等机获取块
if isPeerDeliverRequired {
cf.DeliverClient, err = common.NewDeliverClientForPeer(channelID)
if err != nil {
return nil, errors.WithMessage(err, "error getting deliver client for channel")
}
}
//对于创建和获取,我们也需要订购者
if isOrdererRequired {
if len(strings.Split(common.OrderingEndpoint, ":")) != 2 {
return nil, errors.Errorf("ordering service endpoint %s is not valid or missing", common.OrderingEndpoint)
}
cf.DeliverClient, err = common.NewDeliverClientForOrderer(channelID)
if err != nil {
return nil, err
}
}
logger.Infof("Endorser and orderer connections initialized")
return cf, nil
}