区块链教程Fabric1.0源代码分析Ledger statedb(状态数据库)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了区块链教程Fabric1.0源代码分析Ledger statedb(状态数据库),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7814字,纯文字阅读大概需要12分钟。
内容图文
Fabric 1.0源代码笔记 之 Ledger #statedb(状态数据库)
1、statedb概述
statedb,或VersionedDB,即状态数据库,存储了交易(transaction)日志中所有键的最新值,也称世界状态(world state)。
可选择基于leveldb或cauchdb实现。
statedb,代码分布在core/ledger/kvledger/txmgmt/statedb目录下,目录结构如下:
- statedb.go,定义了核心接口VersionedDBProvider、VersionedDB、ResultsIterator和QueryResult,以及UpdateBatch和nsIterator结构体及方法。
- util.go,包括工具函数EncodeValue和DecodeValue的实现。
- stateleveldb目录,VersionedDBProvider和VersionedDB接口的leveldb版本实现,即stateleveldb.VersionedDBProvider和stateleveldb.versionedDB结构体及方法。
- statecouchdb目录,VersionedDBProvider和VersionedDB接口的couchdb版本实现,即statecouchdb.VersionedDBProvider和statecouchdb.VersionedDB结构体及方法。
2、核心接口定义
VersionedDBProvider接口定义:
type VersionedDBProvider interface {
????GetDBHandle(id string) (VersionedDB, error) //获取VersionedDB句柄
????Close() //关闭所有 VersionedDB 实例
}
//代码在core/ledger/kvledger/txmgmt/statedb/statedb.go
VersionedDB接口定义:
type VersionedDB interface {
????//获取给定命名空间和键的值
????GetState(namespace string, key string) (*VersionedValue, error)
????//在单个调用中获取多个键的值
????GetStateMultipleKeys(namespace string, keys []string) ([]*VersionedValue, error)
????//返回一个迭代器, 其中包含给定键范围之间的所有键值(包括startKey,不包括endKey)
????GetStateRangeScanIterator(namespace string, startKey string, endKey string) (ResultsIterator, error)
????//执行给定的查询并返回迭代器
????ExecuteQuery(namespace, query string) (ResultsIterator, error)
????//批处理应用
????ApplyUpdates(batch *UpdateBatch, height *version.Height) error
????//返回statedb一致的最高事务的高度
????GetLatestSavePoint() (*version.Height, error)
????//测试数据库是否支持这个key(leveldb支持任何字节, 而couchdb只支持utf-8字符串)
????ValidateKey(key string) error
????//打开db
????Open() error
????//关闭db
????Close()
}
//代码在core/ledger/kvledger/txmgmt/statedb/statedb.go
ResultsIterator和QueryResult接口定义:
type ResultsIterator interface {
????Next() (QueryResult, error)
????Close()
}
type QueryResult interface{}
//代码在core/ledger/kvledger/txmgmt/statedb/statedb.go
补充CompositeKey、VersionedValue和VersionedKV结构体:
type CompositeKey struct {
????Namespace string //命名空间
????Key string //Key
}
type VersionedValue struct {
????Value []byte //Value
????Version *version.Height //版本
}
type VersionedKV struct {
????CompositeKey //嵌入CompositeKey
????VersionedValue //嵌入VersionedValue
}
//代码在core/ledger/kvledger/txmgmt/statedb/statedb.go
nsUpdates结构体及方法:
type nsUpdates struct {
????m map[string]*VersionedValue //string为Key
}
func newNsUpdates() *nsUpdates//构造nsUpdates
//代码在core/ledger/kvledger/txmgmt/statedb/statedb.go
UpdateBatch结构体及方法:
type UpdateBatch struct {
????updates map[string]*nsUpdates //string为Namespace
}
//构造UpdateBatch
func NewUpdateBatch() *UpdateBatch
//按namespace和key获取Value
func (batch *UpdateBatch) Get(ns string, key string) *VersionedValue
//按namespace和key添加Value
func (batch *UpdateBatch) Put(ns string, key string, value []byte, version *version.Height)
//按namespace和key删除Value,即置为nil
func (batch *UpdateBatch) Delete(ns string, key string, version *version.Height)
//按namespace和key查找是否存在
func (batch *UpdateBatch) Exists(ns string, key string) bool
//获取更新的namespace列表
func (batch *UpdateBatch) GetUpdatedNamespaces() []string
//按namespace获取nsUpdates
func (batch *UpdateBatch) GetUpdates(ns string) map[string]*VersionedValue
//构造nsIterator
func (batch *UpdateBatch) GetRangeScanIterator(ns string, startKey string, endKey string) ResultsIterator
//按namespace获取或创建nsUpdates
func (batch *UpdateBatch) getOrCreateNsUpdates(ns string) *nsUpdates
//代码在core/ledger/kvledger/txmgmt/statedb/statedb.go
nsIterator结构体及方法:
type nsIterator struct {
????ns string //namespace
????nsUpdates *nsUpdates //batch.updates[ns]
????sortedKeys []string //nsUpdates.m中key排序
????nextIndex int //startKey
????lastIndex int //endKey
}
//构造nsIterator
func newNsIterator(ns string, startKey string, endKey string, batch *UpdateBatch) *nsIterator
func (itr *nsIterator) Next() (QueryResult, error) //按itr.nextIndex获取VersionedKV
func (itr *nsIterator) Close() // do nothing
//代码在core/ledger/kvledger/txmgmt/statedb/statedb.go
3、statedb基于leveldb实现
3.1、VersionedDB接口实现
VersionedDB接口实现,即versionedDB结构体,定义如下:
type versionedDB struct {
????db *leveldbhelper.DBHandle //leveldb
????dbName string //dbName
}
//代码在core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go
涉及方法如下:
//构造versionedDB
func newVersionedDB(db *leveldbhelper.DBHandle, dbName string) *versionedDB
func (vdb *versionedDB) Open() error // do nothing
func (vdb *versionedDB) Close() // do nothing
func (vdb *versionedDB) ValidateKey(key string) error // do nothing
//按namespace和key获取Value
func (vdb *versionedDB) GetState(namespace string, key string) (*statedb.VersionedValue, error)
//在单个调用中获取多个键的值
func (vdb *versionedDB) GetStateMultipleKeys(namespace string, keys []string) ([]*statedb.VersionedValue, error)
//返回一个迭代器, 其中包含给定键范围之间的所有键值(包括startKey,不包括endKey)
func (vdb *versionedDB) GetStateRangeScanIterator(namespace string, startKey string, endKey string) (statedb.ResultsIterator, error)
//leveldb不支持ExecuteQuery方法
func (vdb *versionedDB) ExecuteQuery(namespace, query string) (statedb.ResultsIterator, error)
//批处理应用
func (vdb *versionedDB) ApplyUpdates(batch *statedb.UpdateBatch, height *version.Height) error
//返回statedb一致的最高事务的高度
func (vdb *versionedDB) GetLatestSavePoint() (*version.Height, error)
//拼接ns和key,ns []byte{0x00} key
func constructCompositeKey(ns string, key string) []byte
//分割ns和key,分割符[]byte{0x00}
func splitCompositeKey(compositeKey []byte) (string, string)
//代码在core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go
func (vdb versionedDB) ApplyUpdates(batch statedb.UpdateBatch, height *version.Height) error代码如下:
dbBatch := leveldbhelper.NewUpdateBatch()
namespaces := batch.GetUpdatedNamespaces() //获取更新的namespace列表
for _, ns := range namespaces {
????updates := batch.GetUpdates(ns) //按namespace获取nsUpdates
????for k, vv := range updates {
????????compositeKey := constructCompositeKey(ns, k) //拼接ns和key
????????if vv.Value == nil {
????????????dbBatch.Delete(compositeKey)
????????} else {
????????????dbBatch.Put(compositeKey, statedb.EncodeValue(vv.Value, vv.Version))
????????}
????}
}
//statedb一致的最高事务的高度
dbBatch.Put(savePointKey, height.ToBytes()) //var savePointKey = []byte{0x00}
err := vdb.db.WriteBatch(dbBatch, true)
//代码在core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go
3.2、ResultsIterator接口实现
ResultsIterator接口实现,即kvScanner结构体及方法。
type kvScanner struct {
????namespace string
????dbItr iterator.Iterator
}
//构造kvScanner
func newKVScanner(namespace string, dbItr iterator.Iterator) *kvScanner
//迭代获取statedb.VersionedKV
func (scanner *kvScanner) Next() (statedb.QueryResult, error)
func (scanner *kvScanner) Close() //释放迭代器
//代码在core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go
3.3、VersionedDBProvider接口实现
VersionedDBProvider接口实现,即VersionedDBProvider结构体及方法。
type VersionedDBProvider struct {
????dbProvider *leveldbhelper.Provider
}
func NewVersionedDBProvider() *VersionedDBProvider //构造VersionedDBProvider
//获取statedb.VersionedDB
func (provider *VersionedDBProvider) GetDBHandle(dbName string) (statedb.VersionedDB, error)
func (provider *VersionedDBProvider) Close() //关闭statedb.VersionedDB
//代码在core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go
4、statedb基于cauchdb实现
暂略,待补充。
内容总结
以上是互联网集市为您收集整理的区块链教程Fabric1.0源代码分析Ledger statedb(状态数据库)全部内容,希望文章能够帮你解决区块链教程Fabric1.0源代码分析Ledger statedb(状态数据库)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。