HyperLedgerFabric源碼解讀(3)-certstore

關(guān)于gossip中證書/身份存儲(chǔ)的內(nèi)容
package gossip

// 傳播所有的身份信息
// certStore supports pull dissemination of identity messages
type certStore struct {
    selfIdentity api.PeerIdentityType   // peer自身的身份
    idMapper     identity.Mapper        // 公鑰和身份的映射關(guān)系:公鑰PKIid :身份
    pull         pull.Mediator          // 獲取消息中介
    logger       util.Logger
    mcs          api.MessageCryptoService // 信息加密服務(wù)
}
// 新建身份存儲(chǔ)
func newCertStore(puller pull.Mediator,     // PullEngine的包裝類 提供獲取同步相關(guān)的方法
    idMapper identity.Mapper,               // <PKIid, Certificates/identifies> 公鑰ID 與 證書或身份的映射
    selfIdentity api.PeerIdentityType,      // 自身標(biāo)識(shí)
    mcs api.MessageCryptoService) *certStore {  // 信息加密服務(wù)
    // 獲取對(duì)應(yīng)身份的公鑰UD
    selfPKIID := idMapper.GetPKIidOfCert(selfIdentity)
    //
    logger := util.GetLogger(util.LoggingGossipModule, string(selfPKIID))

    certStore := &certStore{
        mcs:          mcs,              // 信息加密服務(wù)
        pull:         puller,           // 獲取者
        idMapper:     idMapper,         // 本地公鑰驻子、身份/證書映射器
        selfIdentity: selfIdentity,     // 自身標(biāo)識(shí)
        logger:       logger,
    }
    // 添加自身公鑰ID與身份的關(guān)聯(lián)關(guān)系
    if err := certStore.idMapper.Put(selfPKIID, selfIdentity); err != nil {
        certStore.logger.Panicf("Failed associating self PKIID to cert: %+v", errors.WithStack(err))
    }

    // 創(chuàng)建身份信息
    selfIDMsg, err := certStore.createIdentityMessage()
    if err != nil {
        certStore.logger.Panicf("Failed creating self identity message: %+v", errors.WithStack(err))
    }
    // 添加到獲取中間代理上 并將注冊一個(gè)鉤子到指定類型的消息(RegisterMsgHook)
    puller.Add(selfIDMsg)
    puller.RegisterMsgHook(pull.RequestMsgType, func(_ []string, msgs []*proto.SignedGossipMessage, _ proto.ReceivedMessage) {
        // 遍歷簽名的Gossip Message 獲取每個(gè)消息里面的每個(gè)對(duì)等節(jié)點(diǎn)peer的公鑰ID 憔杨、身份證書; 并將公鑰ID 效拭、身份證書放到映射表中
        for _, msg := range msgs {
            pkiID := common.PKIidType(msg.GetPeerIdentity().PkiId)
            cert := api.PeerIdentityType(msg.GetPeerIdentity().Cert)
            if err := certStore.idMapper.Put(pkiID, cert); err != nil {
                certStore.logger.Warningf("Failed adding identity %v, reason %+v", cert, errors.WithStack(err))
            }
        }
    })
    return certStore
}
// 處理消息
func (cs *certStore) handleMessage(msg proto.ReceivedMessage) {
    // 獲取GossipMessage的更新數(shù)據(jù)
    if update := msg.GetGossipMessage().GetDataUpdate(); update != nil {
        // 提取更新的數(shù)據(jù) 并解碼Envelope轉(zhuǎn)為對(duì)應(yīng)的gossip message簽名消息
        for _, env := range update.Data {
            m, err := env.ToGossipMessage()
            if err != nil {
                cs.logger.Warningf("Data update contains an invalid message: %+v", errors.WithStack(err))
                return
            }
            // 轉(zhuǎn)換的簽名gossip message是否是身份信息
            if !m.IsIdentityMsg() {
                cs.logger.Warning("Got a non-identity message:", m, "aborting")
                return
            }
            // 檢驗(yàn)身份信息的有效性
            if err := cs.validateIdentityMsg(m); err != nil {
                cs.logger.Warningf("Failed validating identity message: %+v", errors.WithStack(err))
                return
            }
        }
    }
    // 通過獲取中間代理處理消息
    cs.pull.HandleMessage(msg)
}
// 驗(yàn)證身份消息
func (cs *certStore) validateIdentityMsg(msg *proto.SignedGossipMessage) error {
    // 從簽名消息SignedGossipMessage中提取對(duì)等節(jié)點(diǎn)peer的身份
    idMsg := msg.GetPeerIdentity()
    if idMsg == nil {
        return errors.Errorf("Identity empty: %+v", msg)
    }
    // 提取對(duì)等節(jié)點(diǎn)peer身份信息中的公鑰ID
    pkiID := idMsg.PkiId
    // 提取對(duì)等節(jié)點(diǎn)peer身份信息中的證書
    cert := idMsg.Cert
    // 根據(jù)對(duì)等節(jié)點(diǎn)peer的身份類型提取對(duì)應(yīng)的證書公鑰ID
    calculatedPKIID := cs.mcs.GetPKIidOfCert(api.PeerIdentityType(cert))
    // 聲明的公鑰ID
    claimedPKIID := common.PKIidType(pkiID)
    // 對(duì)比計(jì)算的公鑰ID  和 聲明的公鑰id進(jìn)行比較,判斷計(jì)算的公鑰ID是否與對(duì)等節(jié)點(diǎn)peer的身份信息的內(nèi)容匹配
    if !bytes.Equal(calculatedPKIID, claimedPKIID) {
        return errors.Errorf("Calculated pkiID doesn't match identity: calculated: %v, claimedPKI-ID: %v", calculatedPKIID, claimedPKIID)
    }

    // 定義檢驗(yàn)函數(shù):通過消息加密服務(wù)(Message Crypto Service )
    verifier := func(peerIdentity []byte, signature, message []byte) error {
        return cs.mcs.Verify(api.PeerIdentityType(peerIdentity), signature, message)
    }

    // 檢驗(yàn)消息
    err := msg.Verify(cert, verifier)
    if err != nil {
        return errors.Wrap(err, "Failed verifying message")
    }
    // 驗(yàn)證身份
    return cs.mcs.ValidateIdentity(api.PeerIdentityType(idMsg.Cert))
}
// 創(chuàng)建身份消息
func (cs *certStore) createIdentityMessage() (*proto.SignedGossipMessage, error) {
    // 對(duì)等節(jié)點(diǎn)身份
    pi := &proto.PeerIdentity{
        Cert:     cs.selfIdentity,   // 自身身份(標(biāo)識(shí))
        Metadata: nil,               // 元數(shù)據(jù)
        PkiId:    cs.idMapper.GetPKIidOfCert(cs.selfIdentity), // 從映射表中獲取公鑰ID
    }
    // Gossip消息
    m := &proto.GossipMessage{
        Channel: nil,                       // 通道
        Nonce:   0,                         //
        Tag:     proto.GossipMessage_EMPTY, // gossip message的標(biāo)記
        Content: &proto.GossipMessage_PeerIdentity{  // 對(duì)等節(jié)點(diǎn)身份Gossip消息的內(nèi)容:對(duì)等節(jié)點(diǎn)身份內(nèi)容
            PeerIdentity: pi,
        },
    }
    signer := func(msg []byte) ([]byte, error) {  // 消息簽名函數(shù)
        return cs.idMapper.Sign(msg)
    }
    sMsg := &proto.SignedGossipMessage{          // 簽名后的gossip message
        GossipMessage: m,
    }
    _, err := sMsg.Sign(signer)                 // 綁定簽名和消息
    return sMsg, errors.WithStack(err)         // 返回簽名后的gossip 消息 作為身份消息
}
// 異常節(jié)點(diǎn)
func (cs *certStore) suspectPeers(isSuspected api.PeerSuspector) {
    cs.idMapper.SuspectPeers(isSuspected)
}
// 關(guān)閉證書存儲(chǔ): 獲取中間代理關(guān)閉卦洽、公鑰和身份映射關(guān)閉
func (cs *certStore) stop() {
    cs.pull.Stop()
    cs.idMapper.Stop()
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末织盼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子净赴,更是在濱河造成了極大的恐慌,老刑警劉巖罩润,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玖翅,死亡現(xiàn)場離奇詭異,居然都是意外死亡割以,警方通過查閱死者的電腦和手機(jī)金度,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來严沥,“玉大人猜极,你說我怎么就攤上這事∽>” “怎么了魔吐?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長莱找。 經(jīng)常有香客問我酬姆,道長,這世上最難降的妖魔是什么奥溺? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任辞色,我火速辦了婚禮,結(jié)果婚禮上浮定,老公的妹妹穿的比我還像新娘相满。我一直安慰自己,他們只是感情好桦卒,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布立美。 她就那樣靜靜地躺著,像睡著了一般方灾。 火紅的嫁衣襯著肌膚如雪建蹄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天裕偿,我揣著相機(jī)與錄音洞慎,去河邊找鬼。 笑死嘿棘,一個(gè)胖子當(dāng)著我的面吹牛劲腿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸟妙,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼焦人,長吁一口氣:“原來是場噩夢啊……” “哼挥吵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起垃瞧,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤蔫劣,失蹤者是張志新(化名)和其女友劉穎坪郭,沒想到半個(gè)月后个从,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歪沃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年嗦锐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沪曙。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奕污,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出液走,到底是詐尸還是另有隱情碳默,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布缘眶,位于F島的核電站嘱根,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏巷懈。R本人自食惡果不足惜该抒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顶燕。 院中可真熱鬧凑保,春花似錦、人聲如沸涌攻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恳谎。三九已至芝此,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惠爽,已是汗流浹背癌蓖。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婚肆,地道東北人租副。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像较性,于是被迫代替她去往敵國和親用僧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子结胀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)责循,斷路器糟港,智...
    卡卡羅2017閱讀 134,715評(píng)論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,322評(píng)論 25 707
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,952評(píng)論 2 89
  • 南抖音,北快手院仿。 猝不及防今年成了抖音元年秸抚。 小豬佩奇不再是動(dòng)畫片,成了「社會(huì)人兒」的象征歹垫。 滿街排隊(duì)最多就是被抖...
    Ruueryee閱讀 388評(píng)論 0 0
  • “沒有功勞,但我有苦勞啊” 這句話暮芭,想必大家都很熟悉鹿驼,可能我們自己也說過,但這樣的邏輯一定正確嗎辕宏? 你做一件事的目...
    Mr波波閱讀 888評(píng)論 0 0