Fabric 1.0原始碼分析(19) 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介面定義:
```go
type VersionedDBProvider interface {
GetDBHandle(id string) (VersionedDB, error) //獲取VersionedDB控制程式碼
Close() //關閉所有 VersionedDB 例項
}
//程式碼在core/ledger/kvledger/txmgmt/statedb/statedb.go
```
VersionedDB介面定義:
```go
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介面定義:
```go
type ResultsIterator interface {
Next() (QueryResult, error)
Close()
}
type QueryResult interface{}
//程式碼在core/ledger/kvledger/txmgmt/statedb/statedb.go
```
補充CompositeKey、VersionedValue和VersionedKV結構體:
```go
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結構體及方法:
```go
type nsUpdates struct {
m map[string]*VersionedValue //string為Key
}
func newNsUpdates() *nsUpdates//構造nsUpdates
//程式碼在core/ledger/kvledger/txmgmt/statedb/statedb.go
```
UpdateBatch結構體及方法:
```go
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結構體及方法:
```go
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結構體,定義如下:
```go
type versionedDB struct {
db *leveldbhelper.DBHandle //leveldb
dbName string //dbName
}
//程式碼在core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go
```
涉及方法如下:
```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程式碼如下:
```go
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結構體及方法。
```go
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結構體及方法。
```go
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實現
暫略,待補充。
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
相關文章
- Fabric 1.0原始碼分析(21)Ledger #historydb(歷史資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(26)Orderer #ledger(Orderer Ledger)原始碼
- Fabric 1.0原始碼分析(20) Ledger #idStore(ledgerID資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(18) Ledger(賬本)原始碼
- Fabric 1.0原始碼分析(23)LevelDB(KV資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(22)Ledger #blkstorage(block檔案儲存)原始碼BloC
- Fabric 1.0原始碼分析(25) Orderer原始碼
- Fabric 1.0原始碼分析(31) Peer原始碼
- Fabric 1.0原始碼分析(40) Proposal(提案)原始碼
- Fabric 1.0原始碼分析(3)Chaincode(鏈碼)原始碼AI
- Fabric 1.0原始碼分析(43) Tx(Transaction 交易)原始碼
- Fabric 1.0原始碼分析(47)Fabric 1.0.4 go程式碼量統計原始碼Go
- Fabric 1.0原始碼分析(42)scc(系統鏈碼)原始碼
- Fabric 1.0原始碼分析(13)events(事件服務)原始碼事件
- Fabric 1.0原始碼分析(39) policy(背書策略)原始碼
- Fabric 1.0原始碼分析(15)gossip(流言演算法)原始碼Go演算法
- Fabric 1.0原始碼分析(44)Tx #RWSet(讀寫集)原始碼
- Fabric 1.0原始碼分析(14) flogging(Fabric日誌系統)原始碼
- Fabric 1.0原始碼分析(10)consenter(共識外掛)原始碼
- Fabric 1.0原始碼分析(29) Orderer #multichain(多鏈支援包)原始碼AI
- Fabric 1.0原始碼分析(35)Peer #EndorserServer(Endorser服務端)原始碼Server服務端
- Fabric 1.0原始碼分析(36) Peer #EndorserClient(Endorser客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(41)putils(protos/utils工具包)原始碼
- Fabric 1.0原始碼分析(45)gRPC(Fabric中註冊的gRPC Service)原始碼RPC
- Fabric 1.0原始碼分析(5)Chaincode(鏈碼)體系總結原始碼AI
- Fabric 1.0原始碼分析(2) blockfile(區塊檔案儲存)原始碼BloC
- Fabric 1.0原始碼分析(32) Peer #peer node start命令實現原始碼
- Fabric 1.0原始碼分析(42)scc(系統鏈碼) #cscc(通道相關)原始碼
- Fabric 1.0原始碼分析(30) Orderer #BroadcastServer(Broadcast服務端)原始碼ASTServer服務端
- Fabric 1.0原始碼分析(37) Peer #DeliverClient(Deliver客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(38) Peer #BroadcastClient(Broadcast客戶端)原始碼ASTclient客戶端
- Fabric 1.0原始碼分析(4)Chaincode(鏈碼)#platforms(鏈碼語言平臺)原始碼AIPlatform
- Fabric 1.0原始碼分析(27) Orderer #configupdate(處理通道配置更新)原始碼
- Fabric 1.0原始碼分析(33) Peer #peer channel命令及子命令實現原始碼
- Fabric 1.0原始碼分析(1)BCCSP(區塊鏈加密服務提供者)原始碼區塊鏈加密
- Fabric 1.0原始碼分析(9)configtx(配置交易)體系介紹原始碼
- Fabric 1.0原始碼分析(11)consenter(共識外掛) #filter(過濾器)原始碼Filter過濾器
- Fabric 1.0原始碼分析(12)cryptogen(生成組織關係和身份證書)原始碼