Fabric 1.0原始碼分析(25) Orderer
# Fabric 1.0原始碼筆記 之 Orderer
## 1、Orderer概述
Orderer,為排序節點,對所有發往網路中的交易進行排序,將排序後的交易安排配置中的約定整理為塊,之後提交給Committer進行處理。
Orderer程式碼分佈在orderer目錄,目錄結構如下:
* orderer目錄
* main.go,main入口。
* util.go,orderer工具函式。
* metadata目錄,metadata.go實現獲取版本資訊。
* localconfig目錄,config.go,本地配置相關實現。
* ledger目錄,賬本區塊儲存。
* file目錄,賬本區塊檔案儲存。
* json目錄,賬本區塊json檔案儲存。
* ram目錄,賬本區塊記憶體儲存。
* common目錄,通用程式碼。
* bootstrap目錄,初始區塊的提供方式。
# Fabric 1.0原始碼筆記 之 Orderer #orderer start命令實現
## 1、載入命令列工具並解析命令列引數
orderer的命令列工具,基於gopkg.in/alecthomas/kingpin.v2實現,地址:http://gopkg.in/alecthomas/kingpin.v2。
相關程式碼如下
```go
var (
//建立kingpin.Application
app = kingpin.New("orderer", "Hyperledger Fabric orderer node")
//建立子命令start和version
start = app.Command("start", "Start the orderer node").Default()
version = app.Command("version", "Show version information")
)
kingpin.Version("0.0.1")
//解析命令列引數
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
case start.FullCommand():
//orderer start的命令實現,下文展開講解
case version.FullCommand():
//輸出版本資訊
fmt.Println(metadata.GetVersionInfo())
}
//程式碼在orderer/main.go
```
metadata.GetVersionInfo()程式碼如下:
```go
func GetVersionInfo() string {
Version = common.Version //var Version string,全域性變數
if Version == "" {
Version = "development build"
}
return fmt.Sprintf("%s:\n Version: %s\n Go version: %s\n OS/Arch: %s",
ProgramName, Version, runtime.Version(),
fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH))
}
//程式碼在orderer/metadata/metadata.go
```
## 2、載入配置檔案
配置檔案的載入,基於viper實現,即https://github.com/spf13/viper。
```go
conf := config.Load()
//程式碼在orderer/main.go
```
conf := config.Load()程式碼如下:
```go
func Load() *TopLevel {
config := viper.New()
//cf.InitViper作用為載入配置檔案路徑及設定配置檔名稱
cf.InitViper(config, configName) //configName = strings.ToLower(Prefix),其中Prefix = "ORDERER"
config.SetEnvPrefix(Prefix) //Prefix = "ORDERER"
config.AutomaticEnv()
replacer := strings.NewReplacer(".", "_")
config.SetEnvKeyReplacer(replacer)
err := config.ReadInConfig() //載入配置檔案內容
var uconf TopLevel
//將配置檔案內容輸出到結構體中
err = viperutil.EnhancedExactUnmarshal(config, &uconf)
//完成初始化,即檢查空項,並賦預設值
uconf.completeInitialization(filepath.Dir(config.ConfigFileUsed()))
return &uconf
}
//程式碼在orderer/localconfig/config.go
```
TopLevel結構體及本地配置更詳細內容,參考:[Fabric 1.0原始碼筆記 之 Orderer #localconfig(Orderer配置檔案定義)](localconfig.md)
## 3、初始化日誌系統(日誌輸出、日誌格式、日誌級別、sarama日誌)
```go
initializeLoggingLevel(conf)
//程式碼在orderer/main.go
```
initializeLoggingLevel(conf)程式碼如下:
```go
func initializeLoggingLevel(conf *config.TopLevel) {
//初始化日誌輸出物件及輸出格式
flogging.InitBackend(flogging.SetFormat(conf.General.LogFormat), os.Stderr)
//按初始化日誌級別
flogging.InitFromSpec(conf.General.LogLevel)
if conf.Kafka.Verbose {
//sarama為go語言版kafka客戶端
sarama.Logger = log.New(os.Stdout, "[sarama] ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
}
}
//程式碼在orderer/main.go
```
## 4、啟動Go profiling服務(Go語言分析工具)
```go
initializeProfilingService(conf)
//程式碼在orderer/main.go
```
initializeProfilingService(conf)程式碼如下:
```go
func initializeProfilingService(conf *config.TopLevel) {
if conf.General.Profile.Enabled { //是否啟用Go profiling
go func() {
//Go profiling繫結的監聽地址和埠
logger.Info("Starting Go pprof profiling service on:", conf.General.Profile.Address)
//啟動Go profiling服務
logger.Panic("Go pprof service failed:", http.ListenAndServe(conf.General.Profile.Address, nil))
}()
}
}
//程式碼在orderer/main.go
```
## 5、建立Grpc Server
```go
grpcServer := initializeGrpcServer(conf)
//程式碼在orderer/main.go
```
initializeGrpcServer(conf)程式碼如下:
```go
func initializeGrpcServer(conf *config.TopLevel) comm.GRPCServer {
//按conf初始化安全伺服器配置
secureConfig := initializeSecureServerConfig(conf)
//建立net.Listen
lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort))
//建立GRPC Server
grpcServer, err := comm.NewGRPCServerFromListener(lis, secureConfig)
return grpcServer
}
//程式碼在orderer/main.go
```
## 6、初始化本地MSP並獲取簽名
```go
initializeLocalMsp(conf)
signer := localmsp.NewSigner() //return &mspSigner{}
//程式碼在orderer/main.go
```
initializeLocalMsp(conf)程式碼如下:
```go
func initializeLocalMsp(conf *config.TopLevel) {
//從指定目錄載入本地MSP
err := mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
}
//程式碼在orderer/main.go
```
## 7、初始化MultiChain管理器(啟動共識外掛goroutine,接收和處理訊息)
```go
manager := initializeMultiChainManager(conf, signer)
//程式碼在orderer/main.go
```
initializeMultiChainManager(conf, signer)程式碼如下:
```go
func initializeMultiChainManager(conf *config.TopLevel, signer crypto.LocalSigner) multichain.Manager {
lf, _ := createLedgerFactory(conf) //建立LedgerFactory
if len(lf.ChainIDs()) == 0 { //鏈不存在
initializeBootstrapChannel(conf, lf) //初始化引導通道(獲取初始區塊、建立鏈、新增初始區塊)
} else {
//鏈已存在
}
consenters := make(map[string]multichain.Consenter) //共識
consenters["solo"] = solo.New()
consenters["kafka"] = kafka.New(conf.Kafka.TLS, conf.Kafka.Retry, conf.Kafka.Version)
return multichain.NewManagerImpl(lf, consenters, signer) //LedgerFactory、Consenter、簽名
}
//程式碼在orderer/main.go
```
initializeBootstrapChannel(conf, lf)程式碼如下:
```go
func initializeBootstrapChannel(conf *config.TopLevel, lf ledger.Factory) {
var genesisBlock *cb.Block
switch conf.General.GenesisMethod { //初始區塊的提供方式
case "provisional": //根據GenesisProfile提供
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) //獲取ChainID
gl, err := lf.GetOrCreate(chainID) //獲取或建立chain
err = gl.Append(genesisBlock) //追加初始區塊
}
//程式碼在orderer/main.go
```
## 8、註冊orderer service並啟動grpcServer
```go
server := NewServer(manager, signer) //構造server
ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server) //service註冊到grpcServer
grpcServer.Start()
//程式碼在orderer/main.go
```
server := NewServer(manager, signer)程式碼如下:
```go
func NewServer(ml multichain.Manager, signer crypto.LocalSigner) ab.AtomicBroadcastServer {
s := &server{
dh: deliver.NewHandlerImpl(deliverSupport{Manager: ml}),
bh: broadcast.NewHandlerImpl(broadcastSupport{
Manager: ml,
ConfigUpdateProcessor: configupdate.New(ml.SystemChannelID(), configUpdateSupport{Manager: ml}, signer),
}),
}
return s
}
//程式碼在orderer/server.go
```
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
相關文章
- Fabric 1.0原始碼分析(26)Orderer #ledger(Orderer Ledger)原始碼
- Fabric 1.0原始碼分析(28) Orderer #localconfig(Orderer配置檔案定義)原始碼
- Fabric 1.0原始碼分析(29) Orderer #multichain(多鏈支援包)原始碼AI
- Fabric 1.0原始碼分析(30) Orderer #BroadcastServer(Broadcast服務端)原始碼ASTServer服務端
- Fabric 1.0原始碼分析(27) Orderer #configupdate(處理通道配置更新)原始碼
- Fabric 1.0原始碼分析(31) Peer原始碼
- Fabric 1.0原始碼分析(3)Chaincode(鏈碼)原始碼AI
- Fabric 1.0原始碼分析(40) Proposal(提案)原始碼
- Fabric 1.0原始碼分析(14) flogging(Fabric日誌系統)原始碼
- Fabric 1.0原始碼分析(18) Ledger(賬本)原始碼
- Fabric 1.0原始碼分析(43) Tx(Transaction 交易)原始碼
- Fabric 1.0原始碼分析(47)Fabric 1.0.4 go程式碼量統計原始碼Go
- Fabric 1.0原始碼分析(42)scc(系統鏈碼)原始碼
- Fabric 1.0原始碼分析(13)events(事件服務)原始碼事件
- Fabric 1.0原始碼分析(39) policy(背書策略)原始碼
- Fabric 1.0原始碼分析(45)gRPC(Fabric中註冊的gRPC Service)原始碼RPC
- Fabric 1.0原始碼分析(10)consenter(共識外掛)原始碼
- Fabric 1.0原始碼分析(15)gossip(流言演算法)原始碼Go演算法
- Fabric 1.0原始碼分析(23)LevelDB(KV資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(44)Tx #RWSet(讀寫集)原始碼
- Fabric 1.0原始碼分析(5)Chaincode(鏈碼)體系總結原始碼AI
- Fabric 1.0原始碼分析(6)configtx(配置交易) #ChannelConfig(通道配置)原始碼
- Fabric 1.0原始碼分析(20) Ledger #idStore(ledgerID資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(35)Peer #EndorserServer(Endorser服務端)原始碼Server服務端
- Fabric 1.0原始碼分析(36) Peer #EndorserClient(Endorser客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(37) Peer #DeliverClient(Deliver客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(38) Peer #BroadcastClient(Broadcast客戶端)原始碼ASTclient客戶端
- Fabric 1.0原始碼分析(41)putils(protos/utils工具包)原始碼
- Fabric 1.0原始碼分析(2) blockfile(區塊檔案儲存)原始碼BloC
- Fabric 1.0原始碼分析(7)configtx(配置交易) #configtxgen(生成通道配置)原始碼
- Fabric 1.0原始碼分析(9)configtx(配置交易)體系介紹原始碼
- Fabric 1.0原始碼分析(19) Ledger #statedb(狀態資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(21)Ledger #historydb(歷史資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(22)Ledger #blkstorage(block檔案儲存)原始碼BloC
- Fabric 1.0原始碼分析(32) Peer #peer node start命令實現原始碼
- Fabric 1.0原始碼分析(42)scc(系統鏈碼) #cscc(通道相關)原始碼
- Fabric 1.0原始碼分析(4)Chaincode(鏈碼)#platforms(鏈碼語言平臺)原始碼AIPlatform
- Fabric 1.0原始碼分析(11)consenter(共識外掛) #filter(過濾器)原始碼Filter過濾器