Hyperledger-Fabric源碼分析(ledger-idstore)

idstore里面存的主要是ledgerid與genesisblock的關(guān)系,另外也用來(lái)判斷l(xiāng)edger是否在構(gòu)建中。實(shí)現(xiàn)本身很簡(jiǎn)單,這里主要還是從使用方的角度來(lái)剖析下吧。不然理解不到精髓。

createLedgerID

func (s *idStore) createLedgerID(ledgerID string, gb *common.Block) error {
    key := s.encodeLedgerKey(ledgerID)
    var val []byte
    var err error
    if val, err = s.db.Get(key); err != nil {
        return err
    }
    if val != nil {
        return ErrLedgerIDExists
    }
    if val, err = proto.Marshal(gb); err != nil {
        return err
    }
    batch := &leveldb.Batch{}
    batch.Put(key, val)
    batch.Delete(underConstructionLedgerKey)
    return s.db.WriteBatch(batch, true)
}
  • 很簡(jiǎn)單,這里的gb就是genesisblock。那什么情況下會(huì)調(diào)用呢?

創(chuàng)建賬本的時(shí)候

func (provider *Provider) Create(genesisBlock *common.Block) (ledger.PeerLedger, error) {
    ledgerID, err := utils.GetChainIDFromBlock(genesisBlock)
    if err != nil {
        return nil, err
    }
    exists, err := provider.idStore.ledgerIDExists(ledgerID)
    ...
    if err = provider.idStore.setUnderConstructionFlag(ledgerID); err != nil {
        return nil, err
    }
    lgr, err := provider.openInternal(ledgerID)
    ...
    panicOnErr(provider.idStore.createLedgerID(ledgerID, genesisBlock), "Error while marking ledger as created")
    return lgr, nil
}
  • 可以看到,首先拿到gb里面的chainid也就是賬本id。
  • 去idstore里面看看這個(gè)id是否已經(jīng)存在
  • 如果不存在,緊接著去idstore里面保存一個(gè)標(biāo)志位,provider.idStore.setUnderConstructionFlag這里表示這個(gè)賬本正在創(chuàng)建中。
  • provider.openInternal不用太關(guān)注,進(jìn)去看眼就是拿到各個(gè)store的句柄,組成統(tǒng)一的kvledger視圖對(duì)外提供賬本相關(guān)的服務(wù)。
  • 接下來(lái)就是創(chuàng)建賬本了。如沒(méi)有意外的話最后會(huì)去除UnderConstructionFlag這個(gè)標(biāo)志,表示至此賬本創(chuàng)建成功。

恢復(fù)賬本的時(shí)候

func (provider *Provider) recoverUnderConstructionLedger() {
   ledgerID, err := provider.idStore.getUnderConstructionFlag()
   panicOnErr(err, "Error while checking whether the under construction flag is set")
   if ledgerID == "" {
      logger.Debugf("No under construction ledger found. Quitting recovery")
      return
   }
   ledger, err := provider.openInternal(ledgerID)
   bcInfo, err := ledger.GetBlockchainInfo()
   ledger.Close()

   switch bcInfo.Height {
   case 0:
      panicOnErr(provider.runCleanup(ledgerID), "Error while running cleanup for ledger id [%s]", ledgerID)
      panicOnErr(provider.idStore.unsetUnderConstructionFlag(), "Error while unsetting under construction flag")
   case 1:
      genesisBlock, err := ledger.GetBlockByNumber(0)
      panicOnErr(err, "Error while retrieving genesis block from blockchain for ledger [%s]", ledgerID)
      panicOnErr(provider.idStore.createLedgerID(ledgerID, genesisBlock), "Error while adding ledgerID [%s] to created list", ledgerID)
   default:
      panic(errors.Errorf(
         "data inconsistency: under construction flag is set for ledger [%s] while the height of the blockchain is [%d]",
         ledgerID, bcInfo.Height))
   }
   return
}

這里的意義在于,前面創(chuàng)建的時(shí)候如果意外宕機(jī),有可能賬本新建不成功。這里如果高度為0,說(shuō)明genesisblock還沒(méi)有commit,去除unsetUnderConstructionFlag標(biāo)記。因?yàn)槟銐焊蜎](méi)有開(kāi)始。

如果高度為1,說(shuō)明genesisblock已經(jīng)提交,可以拿到去idstore了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容