区块链教程Fabric1.0源代码分析Ledger statedb(状态数据库)-兄弟连区块链
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实现
暂略,待补充。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java使用位域进行多标记(状态)管理
Android中位域的应用 在Android中,我们会经常用到或者看到以下这样的代码 : public class ExampleUnitTest { @Test public void gravityTest(LayoutParams params) { // 视图在layout中右下角显示 params.gravity = Gravity.RIGHT | Gravity.BOTTOM; } @Test public void intentFlagTest(Intent intent) { // 清空任务栈中所有旧的activity intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // 如果activity已存在于栈中,清空该activity之上的所有任务 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); } @Test public void windo...
- 下一篇
区块链教程Fabric1.0源代码分析LevelDB KV数据库
Fabric 1.0源代码笔记 之 LevelDB(KV数据库) 1、LevelDB概述 LevelDB是Google开源的持久化KV单机数据库,具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询较少,而写很多的场景。 LevelDB的特点: key和value都是任意长度的字节数组; entry(即一条K-V记录)默认是按照key的字典顺序存储的,当然开发者也可以重载这个排序函数; 提供的基本操作接口:Put()、Delete()、Get()、Batch(); 支持批量操作以原子操作进行; 可以创建数据全景的snapshot(快照),并允许在快照中查找数据; 可以通过前向(或后向)迭代器遍历数据(迭代器会隐含的创建一个snapshot); 自动使用Snappy压缩数据; 可移植性; Fabric中使用了goleveldb包,即https://github.com/syndtr/goleveldb/。 goleveldb的基本操作: 打开数据库,db, err:=leveldb.OpenFile("./db", nil)。作用就是在当前目...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- 设置Eclipse缩进为4个空格,增强代码规范
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能