Hyperledger 源碼分析之 Fabric
Orderer 節點啟動通過 orderer 包下的 main() 方法實現,會進一步調用到 orderer/common/server 包中的 Main() 方法。
核心代碼如下所示。
// Main is the entry point of orderer processfunc Main() { fullCmd := kingpin.MustParse(app.Parse(os.Args[1:])) // "version" command if fullCmd == version.FullCommand() { fmt.Println(metadata.GetVersionInfo()) return } conf := config.Load() initializeLoggingLevel(conf) initializeLocalMsp(conf) Start(fullCmd, conf)}
包括配置初始化過程和核心啟動過程兩個部分:
config.Load():從本地設定檔和環境變數中讀取配置資訊,構建配置樹結構。
initializeLoggingLevel(conf):配置記錄層級。
initializeLocalMsp(conf):配置 MSP 結構。
Start():完成啟動後的核心工作。 整體過程
核心啟動過程都在 orderer/common/server包中的 Start() 方法,如下圖所示。
Start() 方法會初始化 gRPC 服務需要的結構,然後啟動服務。
核心代碼如下所示。
func Start(cmd string, conf *config.TopLevel) { logger.Debugf("Start()") signer := localmsp.NewSigner() manager := initializeMultichannelRegistrar(conf, signer) server := NewServer(manager, signer, &conf.Debug) switch cmd { case start.FullCommand(): // "start" command logger.Infof("Starting %s", metadata.GetVersionInfo()) initializeProfilingService(conf) grpcServer := initializeGrpcServer(conf) ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server) logger.Info("Beginning to serve requests") grpcServer.Start() case benchmark.FullCommand(): // "benchmark" command logger.Info("Starting orderer in benchmark mode") benchmarkServer := performance.GetBenchmarkServer() benchmarkServer.RegisterService(server) benchmarkServer.Start() }}
包括兩大部分:
gRPC 服務結構初始化;
gRPC 服務啟動。 gRPC 服務結構初始化
包括建立新的 MSP 簽名結構,初始化 Registrar 結構來管理各個賬本結構,啟動共識過程,以及建立 gRPC 服務端結構。
核心過程包括:
signer := localmsp.NewSigner() // 初始化簽名結構manager := initializeMultichannelRegistrar(conf, signer) // 初始化賬本管理器(Registrar)結構
其中,initializeMultichannelRegistrar(conf, signer) 方法最為關鍵,核心代碼如下:
func initializeMultichannelRegistrar(conf *config.TopLevel, signer crypto.LocalSigner) *multichannel.Registrar { // 建立賬本操作的工廠結構 lf, _ := createLedgerFactory(conf) // 如果是新啟動情況,建立系統通道的賬本結構 if len(lf.ChainIDs()) == 0 { logger.Debugf("There is no chain, hence we must be in bootstrapping") initializeBootstrapChannel(conf, lf) } else { logger.Info("Not bootstrapping because of existing chains") } //初始化共識外掛程式 consenters := make(map[string]consensus.Consenter) consenters["solo"] = solo.New() consenters["kafka"] = kafka.New(conf.Kafka.TLS, conf.Kafka.Retry, conf.Kafka.Version, conf.Kafka.Verbose) // 建立各個賬本的管理器(Registrar)結構,並啟動共識過程 return multichannel.NewRegistrar(lf, consenters, signer)}
利用傳入的配置資訊和簽名資訊完成如下步驟:
建立賬本操作的工廠結構;
如果是新啟動情況,利用給定的系統初始區塊檔案初始化系統通道的相關結構;
完成共識外掛程式(包括 solo 和 kafka 兩種)的初始化;
multichannel.NewRegistrar(lf, consenters, signer)
方法會掃描本地賬本資料(此時至少已存在系統通道),建立 Registrar 結構,並為每個賬本都啟動共識(如 Kafka 排序)過程。
說明:Registrar 結構(位於 orderer.common.multichannel 包)是 Orderer 組件中最核心的結構,管理了 Orderer 中所有的賬本、共識外掛程式等資料結構。 建立 Registrar 結構並啟動共識過程
NewRegistrar(lf, consenters, signer) 方法位於 orderer.common.multichannel 包,負責初始化鏈支援、訊息處理器等重要資料結構,並為各個賬本啟動共識過程。
核心代碼如下:
existingChains := ledgerFactory.ChainIDs()for _, chainID := range existingChains { if _, ok := ledgerResources.ConsortiumsConfig(); ok { // 如果是系統賬本 chain := newChainSupport(r, ledgerResources, consenters, signer) chain.Processor = msgprocessor.NewSystemChannel(chain, r.templator, msgprocessor.CreateSystemChannelFilters(r, chain)) r.chains[chainID] = chain r.systemChannelID = chainID r.systemChannel = chain defer chain.start() // 啟動共識過程 else