美文网首页
Hyperledger-Fabric源码分析(ledger-id

Hyperledger-Fabric源码分析(ledger-id

作者: Pillar_Zhong | 来源:发表于2019-03-08 19:05 被阅读0次

idstore里面存的主要是ledgerid与genesisblock的关系,另外也用来判断ledger是否在构建中。实现本身很简单,这里主要还是从使用方的角度来剖析下吧。不然理解不到精髓。

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)
}
  • 很简单,这里的gb就是genesisblock。那什么情况下会调用呢?

创建账本的时候

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里面看看这个id是否已经存在
  • 如果不存在,紧接着去idstore里面保存一个标志位,provider.idStore.setUnderConstructionFlag这里表示这个账本正在创建中。
  • provider.openInternal不用太关注,进去看眼就是拿到各个store的句柄,组成统一的kvledger视图对外提供账本相关的服务。
  • 接下来就是创建账本了。如没有意外的话最后会去除UnderConstructionFlag这个标志,表示至此账本创建成功。

恢复账本的时候

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
}

这里的意义在于,前面创建的时候如果意外宕机,有可能账本新建不成功。这里如果高度为0,说明genesisblock还没有commit,去除unsetUnderConstructionFlag标记。因为你压根就没有开始。

如果高度为1,说明genesisblock已经提交,可以拿到去idstore了。

相关文章

网友评论

      本文标题:Hyperledger-Fabric源码分析(ledger-id

      本文链接:https://www.haomeiwen.com/subject/vpjdpqtx.html