区块链教程Fabric1.0源代码分析Ledger historydb历史数据库
1、historydb概述
historydb,用于存储所有块读写集中写集的内容。
代码分布在core/ledger/kvledger/history/historydb目录下,目录结构如下:
- historydb.go,定义核心接口HistoryDBProvider和HistoryDB。
- histmgr_helper.go,historydb工具函数。
- historyleveldb目录,historydb基于leveldb的实现。
* historyleveldb.go,HistoryDBProvider和HistoryDB接口实现,即historyleveldb.HistoryDBProvider和historyleveldb.historyDB结构体及方法。
* historyleveldb_query_executer.go,定义LevelHistoryDBQueryExecutor和historyScanner结构体及方法。
2、核心接口定义
HistoryDBProvider接口定义:
type HistoryDBProvider interface { GetDBHandle(id string) (HistoryDB, error) //获取HistoryDB Close() //关闭所有HistoryDB } //代码在core/ledger/kvledger/history/historydb/historydb.go
HistoryDB接口定义:
type HistoryDB interface { //构造 LevelHistoryDBQueryExecutor NewHistoryQueryExecutor(blockStore blkstorage.BlockStore) (ledger.HistoryQueryExecutor, error) //提交Block入historyDB Commit(block *common.Block) error //获取savePointKey,即version.Height GetLastSavepoint() (*version.Height, error) //是否应该恢复,比较lastAvailableBlock和Savepoint ShouldRecover(lastAvailableBlock uint64) (bool, uint64, error) //提交丢失的块 CommitLostBlock(block *common.Block) error } //代码在core/ledger/kvledger/history/historydb/historydb.go
补充ledger.HistoryQueryExecutor接口定义:执行历史记录查询。
type HistoryQueryExecutor interface { GetHistoryForKey(namespace string, key string) (commonledger.ResultsIterator, error) //按key查历史记录 } //代码在core/ledger/ledger_interface.go
3、historydb工具函数
//构造复合HistoryKey,ns 0x00 key 0x00 blocknum trannum func ConstructCompositeHistoryKey(ns string, key string, blocknum uint64, trannum uint64) []byte //构造部分复合HistoryKey,ns 0x00 key 0x00 0xff func ConstructPartialCompositeHistoryKey(ns string, key string, endkey bool) []byte //按分隔符separator,分割bytesToSplit func SplitCompositeHistoryKey(bytesToSplit []byte, separator []byte) ([]byte, []byte) //代码在core/ledger/kvledger/history/historydb/histmgr_helper.go
4、HistoryDB接口实现
HistoryDB接口实现,即historyleveldb.historyDB结构体及方法。historyDB结构体定义如下:
type historyDB struct { db *leveldbhelper.DBHandle //leveldb dbName string //dbName } //代码在core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb.go
涉及方法如下:
//构造historyDB func newHistoryDB(db *leveldbhelper.DBHandle, dbName string) *historyDB //do nothing func (historyDB *historyDB) Open() error //do nothing func (historyDB *historyDB) Close() //提交Block入historyDB,将读写集中写集入库,并更新savePointKey func (historyDB *historyDB) Commit(block *common.Block) error //构造 LevelHistoryDBQueryExecutor func (historyDB *historyDB) NewHistoryQueryExecutor(blockStore blkstorage.BlockStore) (ledger.HistoryQueryExecutor, error) 获取savePointKey,即version.Height func (historyDB *historyDB) GetLastSavepoint() (*version.Height, error) //是否应该恢复,比较lastAvailableBlock和Savepoint func (historyDB *historyDB) ShouldRecover(lastAvailableBlock uint64) (bool, uint64, error) //提交丢失的块,即调用historyDB.Commit(block) func (historyDB *historyDB) CommitLostBlock(block *common.Block) error //代码在core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb.go
func (historyDB historyDB) Commit(block common.Block) error代码如下:
blockNo := block.Header.Number //区块编号 var tranNo uint64 //交易编号,初始化值为0 dbBatch := leveldbhelper.NewUpdateBatch() //leveldb批量更新 //交易验证代码,type TxValidationFlags []uint8 //交易筛选器 txsFilter := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) if len(txsFilter) == 0 { txsFilter = util.NewTxValidationFlags(len(block.Data.Data)) block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter } for _, envBytes := range block.Data.Data { if txsFilter.IsInvalid(int(tranNo)) { //检查指定的交易是否有效 tranNo++ continue } //[]byte反序列化为Envelope env, err := putils.GetEnvelopeFromBlock(envBytes) payload, err := putils.GetPayload(env) //e.Payload反序列化为Payload //[]byte反序列化为ChannelHeader chdr, err := putils.UnmarshalChannelHeader(payload.Header.ChannelHeader) if common.HeaderType(chdr.Type) == common.HeaderType_ENDORSER_TRANSACTION { //背书交易,type HeaderType int32 respPayload, err := putils.GetActionFromEnvelope(envBytes) //获取ChaincodeAction txRWSet := &rwsetutil.TxRwSet{} err = txRWSet.FromProtoBytes(respPayload.Results) //[]byte反序列化后构造NsRwSet,加入txRWSet.NsRwSets for _, nsRWSet := range txRWSet.NsRwSets { ns := nsRWSet.NameSpace for _, kvWrite := range nsRWSet.KvRwSet.Writes { writeKey := kvWrite.Key //txRWSet中写集入库 compositeHistoryKey := historydb.ConstructCompositeHistoryKey(ns, writeKey, blockNo, tranNo) dbBatch.Put(compositeHistoryKey, emptyValue) } } } else { logger.Debugf("Skipping transaction [%d] since it is not an endorsement transaction\n", tranNo) } tranNo++ } height := version.NewHeight(blockNo, tranNo) dbBatch.Put(savePointKey, height.ToBytes()) err := historyDB.db.WriteBatch(dbBatch, true) //代码在core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb.go
Tx(Transaction 交易)相关更详细内容,参考:Fabric 1.0源代码笔记 之 Tx(Transaction 交易)
5、HistoryDBProvider接口实现
HistoryDBProvider接口实现,即historyleveldb.HistoryDBProvider结构体和方法。
type HistoryDBProvider struct { dbProvider *leveldbhelper.Provider } //构造HistoryDBProvider func NewHistoryDBProvider() *HistoryDBProvider //获取HistoryDB func (provider *HistoryDBProvider) GetDBHandle(dbName string) (historydb.HistoryDB, error) //关闭所有HistoryDB句柄,调取provider.dbProvider.Close() func (provider *HistoryDBProvider) Close() //代码在core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb.go
6、LevelHistoryDBQueryExecutor和historyScanner结构体及方法
LevelHistoryDBQueryExecutor结构体及方法:实现ledger.HistoryQueryExecutor接口。
type LevelHistoryDBQueryExecutor struct { historyDB *historyDB blockStore blkstorage.BlockStore //用于传递给historyScanner } //按key查historyDB,调用q.historyDB.db.GetIterator(compositeStartKey, compositeEndKey) func (q *LevelHistoryDBQueryExecutor) GetHistoryForKey(namespace string, key string) (commonledger.ResultsIterator, error) //代码在core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb_query_executer.go
historyScanner结构体及方法:实现ledger.ResultsIterator接口。
type historyScanner struct { compositePartialKey []byte //ns 0x00 key 0x00 namespace string key string dbItr iterator.Iterator //leveldb迭代器 blockStore blkstorage.BlockStore } //构造historyScanner func newHistoryScanner(compositePartialKey []byte, namespace string, key string, dbItr iterator.Iterator, blockStore blkstorage.BlockStore) *historyScanner //按迭代器中key取blockNum和tranNum,再按blockNum和tranNum从blockStore中取Envelope,然后从Envelope的txRWSet.NsRwSets中按key查找并构造queryresult.KeyModification func (scanner *historyScanner) Next() (commonledger.QueryResult, error) func (scanner *historyScanner) Close() //scanner.dbItr.Release() 从Envelope的txRWSet.NsRwSets中按key查找并构造queryresult.KeyModification func getKeyModificationFromTran(tranEnvelope *common.Envelope, namespace string, key string) (commonledger.QueryResult, error) //代码在core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb_query_executer.go
补充queryresult.KeyModification:
type KeyModification struct { TxId string //交易ID,ChannelHeader.TxId Value []byte //读写集中Value,KVWrite.Value Timestamp *google_protobuf.Timestamp //ChannelHeader.Timestamp IsDelete bool //KVWrite.IsDelete } //代码在protos/ledger/queryresult/kv_query_result.pb.go
感谢关注兄弟连区块链教程分享!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
区块链教程Fabric1.0源代码分析Ledger blkstorage block文件存储-兄弟连区块链
区块链教程Fabric1.0源代码分析Ledger blkstorage block文件存储,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。 Fabric 1.0源代码笔记 之 Ledger #blkstorage(block文件存储) blkstorage概述 blkstorage,默认目录/var/hyperledger/production/ledgersData/chains,含index和chains两个子目录。其中index为索引目录,采用leveldb实现。而chains为各ledger的区块链文件,子目录以ledgerid为名,使用文件系统实现。 blkstorage相关代码在common/ledger/blkstorage目录,目录结构如下: blockstorage.go,定义核心接口BlockStoreProvider和BlockStore。 fsblkstorage目录,BlockStoreProvider和BlockStore接...
- 下一篇
区块链教程Fabric1.0源代码分析ledgerID数据库-兄弟连区块链教程
1、idStore概述 Fabric支持创建多个Ledger,不同Ledger以ledgerID区分。 多个ledgerID及其创世区块存储在idStore数据库中,idStore数据库基于leveldb实现。 idStore默认使用路径:/var/hyperledger/production/ledgersData/ledgerProvider/。 idStore库中特殊key "underConstructionLedgerKey",用于标志最新在建的ledgerID,ledgerID创建成功后或失败时该标志将清除,另外此标志也用于异常时按ledgerID恢复数据。 idStore相关代码集中在core/ledger/kvledger/kv_ledger_provider.go。 2、idStore结构体定义 leveldbhelper更详细内容,参考:Fabric 1.0源代码笔记 之 LevelDB(KV数据库) type idStore struct { db *leveldbhelper.DB } //代码在core/ledger/kvledger/kv_ledger_pr...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS6,CentOS7官方镜像安装Oracle11G
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS关闭SELinux安全模块
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Hadoop3单机部署,实现最简伪集群