1. 程式人生 > >區塊鏈教程Fabric1.0源代碼分析Ledger(賬本)二

區塊鏈教程Fabric1.0源代碼分析Ledger(賬本)二

tle ani inf one 獲取 fab 同時 無效 模擬器

區塊鏈教程Fabric1.0源代碼分析Ledger(賬本)二。

Fabric 1.0源代碼筆記 之 Ledger(賬本)

補充PeerLedger接口嵌入的commonledger.Ledger接口定義如下:

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方法用於支持更豐富的數據和查詢支持。

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接口定義:執行歷史記錄查詢。

type HistoryQueryExecutor interface {
????GetHistoryForKey(namespace string, key string) (commonledger.ResultsIterator, error) //按key查歷史記錄
}
//代碼在core/ledger/ledger_interface.go

TxSimulator接口定義:在"盡可能"最新狀態的一致快照上模擬交易。
其中Set*方法用於支持KV-based數據模型,ExecuteUpdate方法用於支持更豐富的數據和查詢支持。

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結構體定義:

type kvLedger struct {
????ledgerID   string //ledgerID
????blockStore blkstorage.BlockStore //blkstorage
????txtmgmt    txmgr.TxMgr //txmgr
????historyDB  historydb.HistoryDB //historyDB
}
//代碼在core/ledger/kvledger/kv_ledger.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結構體定義:

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數據庫)
  • blkstorage更詳細內容,參考:Fabric 1.0源代碼筆記 之 Ledger #blkstorage(block文件存儲)
  • statedb更詳細內容,參考:Fabric 1.0源代碼筆記 之 Ledger #statedb(狀態數據庫)
  • historydb更詳細內容,參考:Fabric 1.0源代碼筆記 之 Ledger #historydb(歷史數據庫)

涉及方法如下:

//分別構造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管理函數)

全局變量:

var openedLedgers map[string]ledger.PeerLedger //Ledger map,Key為ChainID(即ChannelId或LedgerId)
var ledgerProvider ledger.PeerLedgerProvider //LedgerProvider
//代碼在core/ledger/ledgermgmt/ledger_mgmt.go

Ledger管理函數:

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:

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

-

區塊鏈教程Fabric1.0源代碼分析Ledger(賬本)二