區塊鏈教程Fabric1.0源代碼分析Peer peer根命令入口及加載子命令二

  區塊鏈教程Fabric1.0源代碼分析Peer peer根命令入口及加載子命令二。
flogging,即:fabric logging,爲Fabric基於第三方包go-logging封裝的日誌包,go-logging使用方法參考:github.com/op/go-logging
如下代碼爲flogging包的初始化函數:

func init() {
    logger = logging.MustGetLogger(pkgLogID) //創建僅在flogging包內代碼使用的logging.Logger對象
    Reset() //全局變量初始化爲默認值
    initgrpclogger() //初始化gRPC Logger,即創建logging.Logger對象,並用這個對象設置grpclog
}
//代碼在common/flogging/logging.go

init()執行結束後,peer/main.go中調用flogging.InitFromSpec(loggingSpec),將再次初始化全局日誌級別爲loggingSpec,之前默認爲logging.INFO。

func InitFromSpec(spec string) string代碼如下。
其中spec格式爲:[<module>[,<module>...]=]<level>[:[<module>[,<module>...]=]<level>...]。
此處傳入spec爲"",將""模塊日誌級別設置爲defaultLevel,並會將modules初始化爲defaultLevel。

levelAll := defaultLevel //defaultLevel爲logging.INFO
var err error

if spec != "" { //如果spec不爲空,則按既定格式讀取
    fields := strings.Split(spec, ":") //按:分割
    for _, field := range fields {
        split := strings.Split(field, "=") //按=分割
        switch len(split) {
        case 1: //只有level
            if levelAll, err = logging.LogLevel(field); err != nil { //levelAll賦值爲logging.LogLevel枚舉中定義的Level級別
                levelAll = defaultLevel // 如果沒有定義,則使用默認日誌級別
            }
        case 2: //針對module,module...=level,split[0]爲模塊集,split[1]爲要設置的日誌級別
            levelSingle, err := logging.LogLevel(split[1]) //levelSingle賦值爲logging.LogLevel枚舉中定義的Level級別
            modules := strings.Split(split[0], ",") //按,分割獲取模塊名
            for _, module := range modules {
                logging.SetLevel(levelSingle, module) //本條規則中所有模塊日誌級別均設置爲levelSingle
            }
        default:
            //...
        }
    }
}
//代碼在common/flogging/logging.go

flogging(Fabric日誌系統)更詳細信息參考:Fabric 1.0源代碼筆記 之 flogging(Fabric日誌系統)

4、初始化 MSP (Membership Service Provider會員服務提供者)

如下代碼爲初始化MSP,獲取peer.mspConfigPath路徑和peer.localMspId,分別表示MSP的本地路徑(/etc/hyperledger/fabric/msp/)和Peer所關聯的MSP ID,並初始化組織和身份信息。

var mspMgrConfigDir = config.GetPath("peer.mspConfigPath")
var mspID = viper.GetString("peer.localMspId")
err = common.InitCrypto(mspMgrConfigDir, mspID)
//代碼在peer/main.go

/etc/hyperledger/fabric/msp/目錄下包括:admincerts、cacerts、keystore、signcerts、tlscacerts。其中:

  • admincerts:爲管理員證書的PEM文件,如[email protected]
  • cacerts:爲根CA證書的PEM文件,如ca.org1.example.com-cert.pem。
  • keystore:爲具有節點的簽名密鑰的PEM文件,如91e54fccbb82b29d07657f6df9587c966edee6366786d234bbb8c96707ec7c16_sk。
  • signcerts:爲節點X.509證書的PEM文件,如peer1.org1.example.com-cert.pem。
  • tlscacerts:爲TLS根CA證書的PEM文件,如tlsca.org1.example.com-cert.pem。

如下代碼爲common.InitCrypto(mspMgrConfigDir, mspID)的具體實現,peer.BCCSP爲密碼庫相關配置,包括算法和文件路徑等,格式如下:

BCCSP:
    Default: SW
    SW:
        Hash: SHA2
        Security: 256
        FileKeyStore:
            KeyStore:
            
var bccspConfig *factory.FactoryOpts
err = viperutil.EnhancedExactUnmarshalKey("peer.BCCSP", &bccspConfig) //將peer.BCCSP配置信息加載至bccspConfig中
err = mspmgmt.LoadLocalMsp(mspMgrConfigDir, bccspConfig, localMSPID) //從指定目錄中加載本地MSP
//代碼在peer/common/common.go

factory.FactoryOpts定義爲:

type FactoryOpts struct {
    ProviderName string  `mapstructure:"default" json:"default" yaml:"Default"`
    SwOpts       *SwOpts `mapstructure:"SW,omitempty" json:"SW,omitempty" yaml:"SwOpts"`
}
//FactoryOpts代碼在bccsp/factory/nopkcs11.go,本目錄下另有代碼文件pkcs11.go,在-tags "nopkcs11"條件下二選一編譯。
type SwOpts struct {
    // Default algorithms when not specified (Deprecated?)
    SecLevel   int    `mapstructure:"security" json:"security" yaml:"Security"`
    HashFamily string `mapstructure:"hash" json:"hash" yaml:"Hash"`

    // Keystore Options
    Ephemeral     bool               `mapstructure:"tempkeys,omitempty" json:"tempkeys,omitempty"`
    FileKeystore  *FileKeystoreOpts  `mapstructure:"filekeystore,omitempty" json:"filekeystore,omitempty" yaml:"FileKeyStore"`
    DummyKeystore *DummyKeystoreOpts `mapstructure:"dummykeystore,omitempty" json:"dummykeystore,omitempty"`
}
type FileKeystoreOpts struct {
    KeyStorePath string `mapstructure:"keystore" yaml:"KeyStore"`
}
//SwOpts和FileKeystoreOpts代碼均在bccsp/factory/swfactory.go

如下代碼爲viperutil.EnhancedExactUnmarshalKey("peer.BCCSP", &bccspConfig)的具體實現,getKeysRecursively爲遞歸讀取peer.BCCSP配置信息。
mapstructure爲第三方包:github.com/mitchellh/mapstructure,用於將map[string]interface{}轉換爲struct。
示例代碼:https://godoc.org/github.com/mitchellh/mapstructure#example-Decode--WeaklyTypedInput

func EnhancedExactUnmarshalKey(baseKey string, output interface{}) error {
    m := make(map[string]interface{})
    m[baseKey] = nil
    leafKeys := getKeysRecursively("", viper.Get, m)

    config := &mapstructure.DecoderConfig{
        Metadata:         nil,
        Result:           output,
        WeaklyTypedInput: true,
    }
    decoder, err := mapstructure.NewDecoder(config)
    return decoder.Decode(leafKeys[baseKey])
}
//代碼在common/viperutil/config_util.go

如下代碼爲mspmgmt.LoadLocalMsp(mspMgrConfigDir, bccspConfig, localMSPID)的具體實現,從指定目錄中加載本地MSP。

conf, err := msp.GetLocalMspConfig(dir, bccspConfig, mspID) //獲取本地MSP配置,序列化後寫入msp.MSPConfig,即conf
return GetLocalMSP().Setup(conf) //調取msp.NewBccspMsp()創建bccspmsp實例,調取bccspmsp.Setup(conf)解碼conf.Config並設置bccspmsp
//代碼在msp/mgmt/mgmt.go

如下代碼爲msp.GetLocalMspConfig(dir, bccspConfig, mspID)的具體實現。
SetupBCCSPKeystoreConfig()核心代碼爲bccspConfig.SwOpts.FileKeystore = &factory.FileKeystoreOpts{KeyStorePath: keystoreDir},目的是在FileKeystore或KeyStorePath爲空時設置默認值。

signcertDir := filepath.Join(dir, signcerts) //signcerts爲"signcerts",signcertDir即/etc/hyperledger/fabric/msp/signcerts/
keystoreDir := filepath.Join(dir, keystore) //keystore爲"keystore",keystoreDir即/etc/hyperledger/fabric/msp/keystore/
bccspConfig = SetupBCCSPKeystoreConfig(bccspConfig, keystoreDir) //設置bccspConfig.SwOpts.Ephemeral = false和bccspConfig.SwOpts.FileKeystore = &factory.FileKeystoreOpts{KeyStorePath: keystoreDir}
    //bccspConfig.SwOpts.Ephemeral是否短暫的
err := factory.InitFactories(bccspConfig) //初始化bccsp factory,並創建bccsp實例
signcert, err := getPemMaterialFromDir(signcertDir) //讀取X.509證書的PEM文件
sigid := &msp.SigningIdentityInfo{PublicSigner: signcert[0], PrivateSigner: nil} //構造SigningIdentityInfo
return getMspConfig(dir, ID, sigid) //分別讀取cacerts、admincerts、tlscacerts文件,以及config.yaml中組織信息,構造msp.FabricMSPConfig,序列化後用於構造msp.MSPConfig
//代碼在msp/configbuilder.go

factory.InitFactories(bccspConfig)及BCCSP(區塊鏈加密服務提供者)更詳細內容,參考:Fabric 1.0源代碼筆記 之 BCCSP(區塊鏈加密服務提供者)

至此,peer/main.go結束,接下來將進入peer/node/start.go中serve(args)函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章