/
main.go
234 lines (208 loc) · 7.74 KB
/
main.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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
_ "net/http/pprof"
"os"
genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
"github.com/hyperledger/fabric/common/configtx/tool/provisional"
"github.com/hyperledger/fabric/common/crypto"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/core/comm"
"github.com/hyperledger/fabric/orderer/common/bootstrap/file"
"github.com/hyperledger/fabric/orderer/kafka"
"github.com/hyperledger/fabric/orderer/ledger"
"github.com/hyperledger/fabric/orderer/localconfig"
"github.com/hyperledger/fabric/orderer/metadata"
"github.com/hyperledger/fabric/orderer/multichain"
"github.com/hyperledger/fabric/orderer/solo"
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"
"github.com/hyperledger/fabric/protos/utils"
"github.com/Shopify/sarama"
"github.com/hyperledger/fabric/common/localmsp"
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
logging "github.com/op/go-logging"
"gopkg.in/alecthomas/kingpin.v2"
)
var logger = logging.MustGetLogger("orderer/main")
//command line flags
var (
app = kingpin.New("orderer", "Hyperledger Fabric orderer node")
start = app.Command("start", "Start the orderer node").Default()
version = app.Command("version", "Show version information")
)
func main() {
// 打印当前orderer节点的版本信息
kingpin.Version("0.0.1")
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
// "start" command
case start.FullCommand():
logger.Infof("Starting %s", metadata.GetVersionInfo())
// 载入配置信息,可在github上查看viper,配置文件在simpleconfig文件下
conf := config.Load()
// 初始化日志级别
initializeLoggingLevel(conf)
// 初始化profile(go语言内置,观察程序运行状态)
initializeProfilingService(conf)
// 初始化grpc服务端
grpcServer := initializeGrpcServer(conf)
// 载入msp证书
initializeLocalMsp(conf)
// msp证书用于签名者实例化
signer := localmsp.NewSigner()
//* 初始化多链manager
manager := initializeMultiChainManager(conf, signer)
//* 实例化服务实现
server := NewServer(manager, signer)
// 绑定服务器 + 服务实现
ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server)
logger.Info("Beginning to serve requests")
// 启动服务
grpcServer.Start()
// "version" command
case version.FullCommand():
fmt.Println(metadata.GetVersionInfo())
}
}
// Set the logging level
func initializeLoggingLevel(conf *config.TopLevel) {
flogging.InitBackend(flogging.SetFormat(conf.General.LogFormat), os.Stderr)
flogging.InitFromSpec(conf.General.LogLevel)
if conf.Kafka.Verbose {
sarama.Logger = log.New(os.Stdout, "[sarama] ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
}
}
// Start the profiling service if enabled.
func initializeProfilingService(conf *config.TopLevel) {
if conf.General.Profile.Enabled {
go func() {
logger.Info("Starting Go pprof profiling service on:", conf.General.Profile.Address)
// The ListenAndServe() call does not return unless an error occurs.
logger.Panic("Go pprof service failed:", http.ListenAndServe(conf.General.Profile.Address, nil))
}()
}
}
func initializeSecureServerConfig(conf *config.TopLevel) comm.SecureServerConfig {
// secure server config
secureConfig := comm.SecureServerConfig{
UseTLS: conf.General.TLS.Enabled,
RequireClientCert: conf.General.TLS.ClientAuthEnabled,
}
// check to see if TLS is enabled
if secureConfig.UseTLS {
logger.Info("Starting orderer with TLS enabled")
// load crypto material from files
serverCertificate, err := ioutil.ReadFile(conf.General.TLS.Certificate)
if err != nil {
logger.Fatalf("Failed to load ServerCertificate file '%s' (%s)",
conf.General.TLS.Certificate, err)
}
serverKey, err := ioutil.ReadFile(conf.General.TLS.PrivateKey)
if err != nil {
logger.Fatalf("Failed to load PrivateKey file '%s' (%s)",
conf.General.TLS.PrivateKey, err)
}
var serverRootCAs, clientRootCAs [][]byte
for _, serverRoot := range conf.General.TLS.RootCAs {
root, err := ioutil.ReadFile(serverRoot)
if err != nil {
logger.Fatalf("Failed to load ServerRootCAs file '%s' (%s)",
err, serverRoot)
}
serverRootCAs = append(serverRootCAs, root)
}
if secureConfig.RequireClientCert {
for _, clientRoot := range conf.General.TLS.ClientRootCAs {
root, err := ioutil.ReadFile(clientRoot)
if err != nil {
logger.Fatalf("Failed to load ClientRootCAs file '%s' (%s)",
err, clientRoot)
}
clientRootCAs = append(clientRootCAs, root)
}
}
secureConfig.ServerKey = serverKey
secureConfig.ServerCertificate = serverCertificate
secureConfig.ServerRootCAs = serverRootCAs
secureConfig.ClientRootCAs = clientRootCAs
}
return secureConfig
}
func initializeBootstrapChannel(conf *config.TopLevel, lf ledger.Factory) {
var genesisBlock *cb.Block
// Select the bootstrapping mechanism
switch conf.General.GenesisMethod {
case "provisional":
genesisBlock = provisional.New(genesisconfig.Load(conf.General.GenesisProfile)).GenesisBlock()
case "file":
genesisBlock = file.New(conf.General.GenesisFile).GenesisBlock()
default:
logger.Panic("Unknown genesis method:", conf.General.GenesisMethod)
}
chainID, err := utils.GetChainIDFromBlock(genesisBlock)
if err != nil {
logger.Fatal("Failed to parse chain ID from genesis block:", err)
}
gl, err := lf.GetOrCreate(chainID)
if err != nil {
logger.Fatal("Failed to create the system chain:", err)
}
err = gl.Append(genesisBlock)
if err != nil {
logger.Fatal("Could not write genesis block to ledger:", err)
}
}
func initializeGrpcServer(conf *config.TopLevel) comm.GRPCServer {
secureConfig := initializeSecureServerConfig(conf)
lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort))
if err != nil {
logger.Fatal("Failed to listen:", err)
}
// Create GRPC server - return if an error occurs
grpcServer, err := comm.NewGRPCServerFromListener(lis, secureConfig)
if err != nil {
logger.Fatal("Failed to return new GRPC server:", err)
}
return grpcServer
}
func initializeLocalMsp(conf *config.TopLevel) {
// Load local MSP
err := mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
if err != nil { // Handle errors reading the config file
logger.Fatal("Failed to initialize local MSP:", err)
}
}
func initializeMultiChainManager(conf *config.TopLevel, signer crypto.LocalSigner) multichain.Manager {
// 创建账本工程, 存储Orderer产生的临时区块 By Three types: File Json Ram
lf, _ := createLedgerFactory(conf)
// Are we bootstrapping?
// 是否有链的存在,即是否产生了创始区块(个人理解)
if len(lf.ChainIDs()) == 0 {
// 启动引导
initializeBootstrapChannel(conf, lf)
} else {
logger.Info("Not bootstrapping because of existing chains")
}
// 实例化共识机制
consenters := make(map[string]multichain.Consenter)
consenters["solo"] = solo.New()
consenters["kafka"] = kafka.New(conf.Kafka.TLS, conf.Kafka.Retry, conf.Kafka.Version)
// 实例化Manager
return multichain.NewManagerImpl(lf, consenters, signer)
}