深度探索區塊鏈/分佈式帳本存儲(5)

一。概述

 

二。讀寫集

(一)。交易模擬和讀寫集

      

(二)。交易驗證和世界狀態更新

(三)。模擬和驗證示例

 

三。帳本編號

超級帳本支持多帳本(詳細內容參考第7章實現數據隔離的多鏈及多通道),每一個帳本的數據是分開存儲的。數據庫

帳本編號(LedgerID)的數據存儲在LevelDB數據庫中,只是記錄了有哪些版本,建立新的帳本會檢查是否有相同的帳本編號存在,數組

這保證了全局惟一性。帳本編號庫並不存儲與區塊相關的數據。這和區塊索引不同。數據結構

四。帳本數據

帳本數據(Ledger)是以二進制文件的形式存儲的,每一個帳本數據存儲在不一樣的目錄下。app

後面內容都是在已經區分了帳本的狀況下再對數據進行查詢的。區塊鏈

基於文件系統的區塊存儲實現了以下功能接口。優化

【1】。帳本存儲管理atom

A。提交區塊到帳本(AddBlock)spa

B。獲取區塊鏈信息(GetBlockchainInfo)設計

C。獲取區塊數據(RetrieveBlocks)3d

D。關閉區塊存儲(Shutdown)

【2】。索引管理:跟蹤區塊和交易保存在哪一個文件。

A。根據哈希值獲取區塊(RetrieveBlockByHash)

B。根據區塊編號獲取區塊(RetrieveBlockByNumber)

C。根據交易編號獲取交易(RetrieveTxByID)

D。根據區塊編號和交易編號獲取交易(RetrieveTxByBlockNumTranNum)

E。根據交易編號獲取區塊(RetrieveBlockByTxID)

F。根據交易編號獲取交易驗證碼(RetrieveTxValidationCodeByTxID)

帳本數據的全部操做都是經過區塊文件管理器(blockfileMgr)實現的,定義以下:

type blockfileMgr struct{
 rootDir         String     //區塊鏈中區塊存儲的根目錄
 conf            *Conf     //配置信息
 db              *leveldbhelper.DBHandle    //數據庫指針
 index           index        //區塊索引接口
 cpInfo          *checkpointInfo       //區塊檢查點信息
 cpInfoCond          *sync.Cond          //條件變量
 currentFileWriter      *blockfileWriter       //當前寫入區塊文件的指針
 bcInfo                 atomic.Value         //區塊鏈信息
}

區塊文件管理器實現的功能分爲幾類:

【1】帳本數據存儲管理

A。肯定文件存儲在哪一個目錄

B。肯定區塊存儲在哪一個文件

【2】檢查點管理:跟蹤最新持久化存儲的文件

【3】索引管理:跟蹤區塊和交易保存在哪一個文件

(一)。帳本數據存儲

(二)。帳本數據讀取

(三)。交易模擬執行

五。區塊索引

(一)。文件位置指針

     

(二)。索引的同步過程

六。狀態數據

(一)。LevelDB

    

(二)。CouchDB

        "data":"$rawJSON"

       }

在超級帳本中:

【1】若是存儲的類型是JSON,且JSONValue的data字段是狀態值通過JSON序列化後的內容,則CouchDoc中的Attachments爲空;

【2】若是存儲的類型是字節數組,則JSONValue只保存版本信息,data字段爲空,狀態值放在Attachments的AttachmentBytes中,Attachments的Name爲「valueBytes」,ContentType爲「application/octet-stream」。在獲取時根據data字段是否爲空能夠判斷出存儲的狀態值類型,最後獲得存儲的版本和狀態值。

條件查詢是基於LevelDB的狀態數據庫所沒有的功能進行的。查詢前會對查詢條件進行轉換,增長「data.」前綴和查詢記錄限制等,查詢結果還會默認增長「_id」"version""chaincodeid"。好比原始的查詢條件爲:

{

  "selector":{

    "owner":{

      "$seq":"tom"

    }

  },

     「fields」:[

    "owner",

    "asset_name",

    "color",

    "size"

       ],

  "sort":[

    "size",

    "color"

    ]

}

轉換後的查詢條件爲:

{

  "selector":{

    "$and":[

      {

        "chaincodeid":"marble"

      },

      {

            

(三)基於狀態數據的區塊驗證

七。歷史數據

歷史信息記錄最細的粒度就是交易,若在一個交易中屢次對同一個writeKey更新數據,則會以第一次數據爲準,歷史信息實際存儲的信息是固定的空字節數組[]byte{}。

更新區塊信息的時候,會同步更新檢查點信息,保存的內容是最新的區塊高度和最大的交易序號,檢查點信息用來判斷歷史信息的狀態是不是最新的。

八。數據恢復

區塊的提交過程分爲3個步驟:

【1】。先保存區塊到文件存儲的帳本數據中

【2】。而後更新狀態數據

【3】。最後更新歷史信息數據

這3個步驟是順序執行的,在這個過程當中有文件的操做,也有數據庫的操做,因此在任何一個步驟均可能出現錯誤或者中斷。恢復的過程會根據帳本數據記錄的區塊信息和狀態數據,歷史信息數據的檢查點進行比較,從新提交檢查點以後的區塊信息,保持帳本數據的一致性。

本章小結:

本章介紹了Hyperledger Fabric 1.0的數據存儲,包括帳本數據(Ledger)、區塊索引(Index)、狀態數據(state Database)、歷史數據(Hisotry database)等存儲結構。目前的數據存儲存在較大的優化空間,帳本數據結構的設計帶來的開銷很大,最新的版本並無實現帳本載剪(Ledger Prune)功能,不能進行歸檔,也不能刪除無效交易,因此會致使存儲空間持續增加。

相關文章
相關標籤/搜索