Fabric 1.0原始碼分析(22)Ledger #blkstorage(block檔案儲存)

尹成發表於2018-05-20
# 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介面實現,即:FsBlockstoreProvider和fsBlockStore。
    * config.go,結構體Conf,blockStorage路徑和塊檔案大小(預設最大64M)。
    * fs_blockstore.go,BlockStore介面實現,即fsBlockStore,主要為封裝blockfileMgr。
    * fs_blockstore_provider.go,BlockStoreProvider介面實現,即FsBlockstoreProvider。
    
blockfile更詳細內容,參考:[Fabric 1.0原始碼筆記 之 blockfile(區塊檔案儲存)](../blockfile/README.md)。

## 1、核心介面定義

BlockStoreProvider介面定義:提供BlockStore控制程式碼。

```go
type BlockStoreProvider interface {
    CreateBlockStore(ledgerid string) (BlockStore, error) //建立並開啟BlockStore
    OpenBlockStore(ledgerid string) (BlockStore, error) //建立並開啟BlockStore
    Exists(ledgerid string) (bool, error) //ledgerid的Blockstore目錄是否存在
    List() ([]string, error) //獲取已存在的ledgerid列表
    Close() //關閉BlockStore
}
//程式碼在common/ledger/blkstorage/blockstorage.go
```

BlockStore介面定義:

```go
type BlockStore interface {
    AddBlock(block *common.Block) error //新增塊
    GetBlockchainInfo() (*common.BlockchainInfo, error) //獲取區塊鏈當前資訊
    RetrieveBlocks(startNum uint64) (ledger.ResultsIterator, error) //獲取區塊鏈迭代器,可以迴圈遍歷區塊
    RetrieveBlockByHash(blockHash []byte) (*common.Block, error) //根據區塊雜湊獲取塊
    RetrieveBlockByNumber(blockNum uint64) (*common.Block, error) //根據區塊鏈高度獲取塊
    RetrieveTxByID(txID string) (*common.Envelope, error) //根據交易ID獲取交易
    RetrieveTxByBlockNumTranNum(blockNum uint64, tranNum uint64) (*common.Envelope, error) //根據區塊鏈高度和tranNum獲取交易
    RetrieveBlockByTxID(txID string) (*common.Block, error) //根據交易ID獲取塊
    RetrieveTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error) //根據交易ID獲取交易驗證程式碼
    Shutdown() //關閉BlockStore
}
//程式碼在common/ledger/blkstorage/blockstorage.go
```

## 2、Conf

Conf定義如下:

```go
type Conf struct {
    blockStorageDir string //blockStorage路徑
    maxBlockfileSize int //塊檔案大小(預設最大64M)
}

func NewConf(blockStorageDir string, maxBlockfileSize int) *Conf //構造Conf
func (conf *Conf) getIndexDir() string //獲取index路徑,即/var/hyperledger/production/ledgersData/chains/index
func (conf *Conf) getChainsDir() string //獲取chains路徑,即/var/hyperledger/production/ledgersData/chains/chains
func (conf *Conf) getLedgerBlockDir(ledgerid string) string //獲取Ledger Block,如/var/hyperledger/production/ledgersData/chains/chains/mychannel
//程式碼在common/ledger/blkstorage/fsblkstorage/config.go
```

## 3、BlockStore介面實現

BlockStore介面基於檔案系統實現,即fsBlockStore結構體及方法,BlockStore結構體定義如下:

```go
type fsBlockStore struct {
    id string //即ledgerid
    conf *Conf //type Conf struct
    fileMgr *blockfileMgr //區塊檔案儲存
}
//程式碼在common/ledger/blkstorage/fsblkstorage/fs_blockstore.go
```

涉及方法如下:

```go
//構造fsBlockStore
func newFsBlockStore(id string, conf *Conf, indexConfig *blkstorage.IndexConfig, dbHandle *leveldbhelper.DBHandle) *fsBlockStore
//新增塊,store.fileMgr.addBlock(block)
func (store *fsBlockStore) AddBlock(block *common.Block) error
//獲取區塊鏈當前資訊,store.fileMgr.getBlockchainInfo()
func (store *fsBlockStore) GetBlockchainInfo() (*common.BlockchainInfo, error)
//獲取區塊鏈迭代器,可以迴圈遍歷區塊,store.fileMgr.retrieveBlocks(startNum)
func (store *fsBlockStore) RetrieveBlocks(startNum uint64) (ledger.ResultsIterator, error)
//根據區塊雜湊獲取塊,store.fileMgr.retrieveBlockByHash(blockHash)
func (store *fsBlockStore) RetrieveBlockByHash(blockHash []byte) (*common.Block, error)
//根據區塊鏈高度獲取塊,store.fileMgr.retrieveBlockByNumber(blockNum)
func (store *fsBlockStore) RetrieveBlockByNumber(blockNum uint64) (*common.Block, error)
//根據交易ID獲取交易,store.fileMgr.retrieveTransactionByID(txID)
func (store *fsBlockStore) RetrieveTxByID(txID string) (*common.Envelope, error)
//根據區塊鏈高度和tranNum獲取交易,store.fileMgr.retrieveTransactionByBlockNumTranNum(blockNum, tranNum)
func (store *fsBlockStore) RetrieveTxByBlockNumTranNum(blockNum uint64, tranNum uint64) (*common.Envelope, error)
//根據交易ID獲取塊,store.fileMgr.retrieveBlockByTxID(txID)
func (store *fsBlockStore) RetrieveBlockByTxID(txID string) (*common.Block, error)
//根據交易ID獲取交易驗證程式碼,store.fileMgr.retrieveTxValidationCodeByTxID(txID)
func (store *fsBlockStore) RetrieveTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error)
//關閉BlockStore,store.fileMgr.close()
func (store *fsBlockStore) Shutdown()
//程式碼在common/ledger/blkstorage/fsblkstorage/fs_blockstore.go
```

## 4、BlockStoreProvider介面實現

BlockStoreProvider介面實現,即NewProvider結構體及方法。NewProvider結構體定義如下:

```go
type FsBlockstoreProvider struct {
    conf *Conf
    indexConfig *blkstorage.IndexConfig
    leveldbProvider *leveldbhelper.Provider //用於操作index
}
//程式碼在common/ledger/blkstorage/fsblkstorage/fs_blockstore_provider.go
```

涉及方法:

```go
//構造FsBlockstoreProvider
func NewProvider(conf *Conf, indexConfig *blkstorage.IndexConfig) blkstorage.BlockStoreProvider
//建立並開啟BlockStore,同p.OpenBlockStore(ledgerid)
func (p *FsBlockstoreProvider) CreateBlockStore(ledgerid string) (blkstorage.BlockStore, error)
//建立並開啟BlockStore,調取newFsBlockStore(ledgerid, p.conf, p.indexConfig, indexStoreHandle),即構造fsBlockStore
func (p *FsBlockstoreProvider) OpenBlockStore(ledgerid string) (blkstorage.BlockStore, error)
//ledgerid的Blockstore目錄是否存在,如/var/hyperledger/production/ledgersData/chains/chains/mychannel
func (p *FsBlockstoreProvider) Exists(ledgerid string) (bool, error)
//獲取已存在的ledgerid列表,util.ListSubdirs(p.conf.getChainsDir())
func (p *FsBlockstoreProvider) List() ([]string, error)
//關閉BlockStore,目前僅限關閉p.leveldbProvider.Close()
func (p *FsBlockstoreProvider) Close()
//程式碼在common/ledger/blkstorage/fsblkstorage/fs_blockstore_provider.go

```







網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN





網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN

相關文章