美文网首页
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