美文网首页区块链教程
兄弟连区块链教程Fabric1.0源代码分析Ledger(账本)

兄弟连区块链教程Fabric1.0源代码分析Ledger(账本)

作者: ab6973df9221 | 来源:发表于2018-10-31 14:56 被阅读0次

      兄弟连区块链教程Fabric1.0源代码分析Ledger(账本)二。

    # Fabric 1.0源代码笔记 之 Ledger(账本)

    补充PeerLedger接口嵌入的commonledger.Ledger接口定义如下:

    ```go

    type Ledger interface {

        GetBlockchainInfo() (*common.BlockchainInfo, error) //获取blockchain基本信息

        GetBlockByNumber(blockNumber uint64) (*common.Block, error) //按给定高度获取Block,给定math.MaxUint64将获取最新Block

        GetBlocksIterator(startBlockNumber uint64) (ResultsIterator, error) //获取从startBlockNumber开始的迭代器(包含startBlockNumber),迭代器是阻塞迭代,直到ledger中下一个block可用

        Close() //关闭ledger

        Commit(block *common.Block) error //提交新block

    }

    //代码在common/ledger/ledger_interface.go

    ```

    ValidatedLedger接口暂未定义方法,从PeerLedger筛选出无效交易后,ValidatedLedger表示最终账本。暂时忽略。

    QueryExecutor接口定义:用于执行查询。

    其中Get*方法用于支持KV-based数据模型,ExecuteQuery方法用于支持更丰富的数据和查询支持。

    ```go

    type QueryExecutor interface {

        GetState(namespace string, key string) ([]byte, error) //按namespace和key获取value,对于chaincode,chaincodeId即为namespace

        GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error) //一次调用获取多个key的值

        //获取迭代器,返回包括startKey、但不包括endKeyd的之间所有值

        GetStateRangeScanIterator(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error)

        ExecuteQuery(namespace, query string) (commonledger.ResultsIterator, error) //执行查询并返回迭代器,仅用于查询statedb

        Done() //释放QueryExecutor占用的资源

    }

    //代码在core/ledger/ledger_interface.go

    ```

    HistoryQueryExecutor接口定义:执行历史记录查询。

    ```go

    type HistoryQueryExecutor interface {

        GetHistoryForKey(namespace string, key string) (commonledger.ResultsIterator, error) //按key查历史记录

    }

    //代码在core/ledger/ledger_interface.go

    ```

    TxSimulator接口定义:在"尽可能"最新状态的一致快照上模拟交易。

    其中Set*方法用于支持KV-based数据模型,ExecuteUpdate方法用于支持更丰富的数据和查询支持。

    ```go

    type TxSimulator interface {

        QueryExecutor //嵌入QueryExecutor接口

        SetState(namespace string, key string, value []byte) error //按namespace和key写入value

        DeleteState(namespace string, key string) error //按namespace和key删除

        SetStateMultipleKeys(namespace string, kvs map[string][]byte) error //一次调用设置多个key的值

        ExecuteUpdate(query string) error //ExecuteUpdate用于支持丰富的数据模型

        GetTxSimulationResults() ([]byte, error) //获取模拟交易的结果

    }

    //代码在core/ledger/ledger_interface.go

    ```

    ## 4、kvledger.kvLedger结构体及方法(实现PeerLedger接口)

    kvLedger结构体定义:

    ```go

    type kvLedger struct {

        ledgerID   string //ledgerID

        blockStore blkstorage.BlockStore //blkstorage

        txtmgmt    txmgr.TxMgr //txmgr

        historyDB  historydb.HistoryDB //historyDB

    }

    //代码在core/ledger/kvledger/kv_ledger.go

    ```

    涉及方法如下:

    ```go

    //构造kvLedger

    func newKVLedger(ledgerID string, blockStore blkstorage.BlockStore,versionedDB statedb.VersionedDB, historyDB historydb.HistoryDB) (*kvLedger, error)

    //按最后一个有效块恢复statedb和historydb

    func (l *kvLedger) recoverDBs() error

    //检索指定范围内的块, 并将写入集提交给状态 db 或历史数据库, 或同时

    func (l *kvLedger) recommitLostBlocks(firstBlockNum uint64, lastBlockNum uint64, recoverables ...recoverable) error

    //按交易ID获取交易

    func (l *kvLedger) GetTransactionByID(txID string) (*peer.ProcessedTransaction, error)

    //获取BlockchainInfo

    func (l *kvLedger) GetBlockchainInfo() (*common.BlockchainInfo, error)

    //按区块编号获取块

    func (l *kvLedger) GetBlockByNumber(blockNumber uint64) (*common.Block, error)

    //按起始块获取块迭代器

    func (l *kvLedger) GetBlocksIterator(startBlockNumber uint64) (commonledger.ResultsIterator, error)

    //获取块哈希

    func (l *kvLedger) GetBlockByHash(blockHash []byte) (*common.Block, error)

    //按交易ID获取块

    func (l *kvLedger) GetBlockByTxID(txID string) (*common.Block, error)

    //按交易ID获取交易验证代码

    func (l *kvLedger) GetTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error)

    func (l *kvLedger) Prune(policy commonledger.PrunePolicy) error //暂未实现

    //创建交易模拟器

    func (l *kvLedger) NewTxSimulator() (ledger.TxSimulator, error)

    //创建查询执行器

    func (l *kvLedger) NewQueryExecutor() (ledger.QueryExecutor, error)

    func (l *kvLedger) NewHistoryQueryExecutor() (ledger.HistoryQueryExecutor, error)

    //提交有效块,块写入blkstorage,块中写集加入批处理并更新statedb,写集本身入historyDB

    func (l *kvLedger) Commit(block *common.Block) error

    //创建历史记录查询执行器

    func (l *kvLedger) Close() //关闭

    //代码在core/ledger/kvledger/kv_ledger.go

    ```

    ## 5、kvledger.Provider结构体及方法(实现PeerLedgerProvider接口)

    Provider结构体定义:

    ```go

    type Provider struct {

        idStore            *idStore //idStore

        blockStoreProvider blkstorage.BlockStoreProvider //blkstorage

        vdbProvider        statedb.VersionedDBProvider //statedb

        historydbProvider  historydb.HistoryDBProvider //historydb

    }

    //代码在core/ledger/kvledger/kv_ledger_provider.go

    ```

    * idStore更详细内容,参考:[Fabric 1.0源代码笔记 之 Ledger #idStore(ledgerID数据库)](idstore.md)

    * blkstorage更详细内容,参考:[Fabric 1.0源代码笔记 之 Ledger #blkstorage(block文件存储)](blkstorage.md)

    * statedb更详细内容,参考:[Fabric 1.0源代码笔记 之 Ledger #statedb(状态数据库)](statedb.md)

    * historydb更详细内容,参考:[Fabric 1.0源代码笔记 之 Ledger #historydb(历史数据库)](historydb.md)

    涉及方法如下:

    ```go

    //分别构造idStore、blockStoreProvider、vdbProvider和historydbProvider,并用于构造Provider,并恢复之前未完成创建的Ledger

    func NewProvider() (ledger.PeerLedgerProvider, error)

    //按创世区块创建并打开Ledger,提交创世区块(块入blkstorage,写集更新statedb,写集本身写入historydb),创建ledgerID

    func (provider *Provider) Create(genesisBlock *common.Block) (ledger.PeerLedger, error)

    //调用provider.openInternal(ledgerID),打开Ledger

    func (provider *Provider) Open(ledgerID string) (ledger.PeerLedger, error)

    //按ledgerID打开blkstorage、statedb和historydb,并创建kvledger

    func (provider *Provider) openInternal(ledgerID string) (ledger.PeerLedger, error)

    //ledgerID是否存在

    func (provider *Provider) Exists(ledgerID string) (bool, error)

    //获取ledgerID列表,调取provider.idStore.getAllLedgerIds()

    func (provider *Provider) List() ([]string, error)

    //关闭idStore、blkstorage、statedb、historydb

    func (provider *Provider) Close()

    //检查是否有之前未完成创建的Ledger,并恢复

    func (provider *Provider) recoverUnderConstructionLedger()

    func (provider *Provider) runCleanup(ledgerID string) error //暂时没有实现

    func panicOnErr(err error, mgsFormat string, args ...interface{}) //panicOnErr

    //代码在core/ledger/kvledger/kv_ledger_provider.go

    ```

    ## 6、ledgermgmt(Ledger管理函数)

    全局变量:

    ```go

    var openedLedgers map[string]ledger.PeerLedger //Ledger map,Key为ChainID(即ChannelId或LedgerId)

    var ledgerProvider ledger.PeerLedgerProvider //LedgerProvider

    //代码在core/ledger/ledgermgmt/ledger_mgmt.go

    ```

    Ledger管理函数:

    ```go

    func Initialize() //Ledger初始化,调用initialize(),once.Do确保仅调用一次

    func initialize() //Ledger初始化,包括初始化openedLedgers及ledgerProvider

    //调用ledgerProvider.Create(genesisBlock)创建Ledger,并加入openedLedgers

    func CreateLedger(genesisBlock *common.Block) (ledger.PeerLedger, error)

    //按id取Ledger,并调用ledgerProvider.Open(id)打开Ledger

    func OpenLedger(id string) (ledger.PeerLedger, error)

    //获取ledgerID列表,调取ledgerProvider.List()

    func GetLedgerIDs() ([]string, error)

    //关闭ledgerProvider

    func Close()

    //构造closableLedger

    func wrapLedger(id string, l ledger.PeerLedger) ledger.PeerLedger

    //代码在core/ledger/ledgermgmt/ledger_mgmt.go

    ```

    closableLedger:

    ```go

    type closableLedger struct {

        id string

        ledger.PeerLedger

    }

    func (l *closableLedger) Close() //调取l.closeWithoutLock()

    func (l *closableLedger) closeWithoutLock() //delete(openedLedgers, l.id)

    //代码在core/ledger/ledgermgmt/ledger_mgmt.go

    ```

    欢迎继续关注兄弟连区块链教程http://bt.itxdl.cn/分享!

    相关文章

      网友评论

      本文标题:兄弟连区块链教程Fabric1.0源代码分析Ledger(账本)

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