區塊鏈教程Fabric1.0原始碼分析blockfile區塊檔案儲存體一

來源:互聯網
上載者:User

標籤:items   tin   sig   buffer   and   filename   大小   addm   res   

Fabric 1.0原始碼筆記 之 blockfile(區塊檔案儲存體)1、blockfile概述

blockfile,即Fabric區塊鏈區塊檔案儲存體,預設目錄/var/hyperledger/production/ledgersData/chains,含index和chains兩個子目錄。
其中index為索引目錄,採用leveldb實現。而chains為各ledger的區塊鏈檔案,子目錄以ledgerid為名,使用檔案系統實現。
區塊檔案以blockfile_為首碼,最大大小預設64M。

blockfile,相關代碼集中在common/ledger/blkstorage/fsblkstorage目錄,目錄結構如下:

  • blockfile_mgr.go,blockfileMgr和checkpointInfo結構體及方法。
  • block_stream.go,blockfileStream、blockStream、blockPlacementInfo結構體及方法。
  • blockfile_rw.go,blockfileWriter和blockfileReader結構體及方法(blockfileReader未使用)。
  • blockindex.go,index介面定義,index介面實現即blockIndex結構體及方法定義,以及blockIdxInfo、locPointer、fileLocPointer結構體及方法。
  • blockfile_helper.go,定義了4個工具函數,constructCheckpointInfoFromBlockFiles、retrieveLastFileSuffix、isBlockFileName、getFileInfoOrPanic。
    作用分別為:掃描最新的blockfile並重新構造檢查點資訊、擷取最新的檔案尾碼、根據檔案首碼判斷是否為區塊檔案、擷取檔案狀態資訊。
  • block_serialization.go,block序列化相關工具函數。
  • blocks_itr.go,blocksItr結構體及方法。
2、Block結構體定、以及Block序列化2.1、Block相關結構體

Block結構體:

type Block struct {????Header   *BlockHeader //BlockHeader????Data     *BlockData //BlockData????Metadata *BlockMetadata}func (m *Block) GetHeader() *BlockHeader //擷取BlockHeader,即m.Headerfunc (m *Block) GetData() *BlockData //擷取BlockData,即m.Datafunc (m *Block) GetMetadata() *BlockMetadata //m.Metadata//代碼在protos/common/common.pb.go

BlockHeader結構體:

type BlockHeader struct {????Number       uint64 //區塊編號????PreviousHash []byte //前一個區塊雜湊????DataHash     []byte //當前區塊雜湊}func (m *BlockHeader) GetNumber() uint64 //擷取區塊編號,即m.Numberfunc (m *BlockHeader) GetPreviousHash() []byte //擷取前一個區塊雜湊,即m.PreviousHashfunc (m *BlockHeader) GetDataHash() []byte //擷取當前區塊雜湊,即m.DataHash//代碼在protos/common/common.pb.go

BlockData結構體:

type BlockData struct {????Data [][]byte //Data,儲存體交易資訊}func (m *BlockData) GetData() [][]byte //擷取Data,即m.Data//代碼在protos/common/common.pb.go

BlockMetadata結構體:

type BlockMetadata struct {????Metadata [][]byte //K/V均為[]byte格式}func (m *BlockMetadata) GetMetadata() [][]byte //m.Metadata//代碼在protos/common/common.pb.go

補充BlockMetadataIndex:

type BlockMetadataIndex int32const (????BlockMetadataIndex_SIGNATURES          BlockMetadataIndex = 0????BlockMetadataIndex_LAST_CONFIG         BlockMetadataIndex = 1????BlockMetadataIndex_TRANSACTIONS_FILTER BlockMetadataIndex = 2????BlockMetadataIndex_ORDERER             BlockMetadataIndex = 3)
2.2、Block序列化

serializedBlockInfo結構體定義及工具函數:

type serializedBlockInfo struct {????blockHeader *common.BlockHeader //BlockHeader????txOffsets   []*txindexInfo //交易索引資訊????metadata    *common.BlockMetadata}type txindexInfo struct {????txID string //交易ID????loc  *locPointer //檔案指標}//序列化區塊,返回序列化後位元組,以及serializedBlockInfo(含BlockHeader和交易索引資訊)func serializeBlock(block *common.Block) ([]byte, *serializedBlockInfo, error)//還原序列化區塊,構建Block結構體func deserializeBlock(serializedBlockBytes []byte) (*common.Block, error)//還原序列化區塊,並構造serializedBlockInfofunc extractSerializedBlockInfo(serializedBlockBytes []byte) (*serializedBlockInfo, error)//序列化中添加BlockHeader,即Number、DataHash和PreviousHashfunc addHeaderBytes(blockHeader *common.BlockHeader, buf *proto.Buffer) error//序列化中添加BlockData,並從BlockData中解析txid,返回交易索引資訊數組func addDataBytes(blockData *common.BlockData, buf *proto.Buffer) ([]*txindexInfo, error)//序列化中添加Metadatafunc addMetadataBytes(blockMetadata *common.BlockMetadata, buf *proto.Buffer) error//還原序列化出BlockHeaderfunc extractHeader(buf *ledgerutil.Buffer) (*common.BlockHeader, error)//還原序列化出BlockData,並返回交易索引資訊數組func extractData(buf *ledgerutil.Buffer) (*common.BlockData, []*txindexInfo, error)//還原序列化出Metadatafunc extractMetadata(buf *ledgerutil.Buffer) (*common.BlockMetadata, error)//從BlockData中解析出交易IDfunc extractTxID(txEnvelopBytes []byte) (string, error)//代碼在common/ledger/blkstorage/fsblkstorage/block_serialization.go
3、checkpointInfo結構體定義及方法

checkpointInfo,即檢查點資訊,結構體定義如下:

type checkpointInfo struct {????latestFileChunkSuffixNum int //最新的區塊檔案尾碼,如blockfile_000000????latestFileChunksize      int //最新的區塊檔案大小????isChainEmpty             bool //是否空鏈????lastBlockNumber          uint64 //最新的區塊編號}//代碼在common/ledger/blkstorage/fsblkstorage/blockfile_mgr.go

涉及方法如下:

func (i *checkpointInfo) marshal() ([]byte, error) //checkpointInfo序列化func (i *checkpointInfo) unmarshal(b []byte) error //checkpointInfo還原序列化func (i *checkpointInfo) String() string //轉換為string//代碼在common/ledger/blkstorage/fsblkstorage/blockfile_mgr.go
4、blockfileStream相關結構體及方法4.1、blockfileStream

blockfileStream定義如下:

type blockfileStream struct {????fileNum       int //blockfile檔案尾碼????file          *os.File //os.File????reader        *bufio.Reader //bufio.Reader????currentOffset int64 //當前位移量}//代碼在common/ledger/blkstorage/fsblkstorage/block_stream.go

涉及方法如下:

//構造blockfileStreamfunc newBlockfileStream(rootDir string, fileNum int, startOffset int64) (*blockfileStream, error) func (s *blockfileStream) nextBlockBytes() ([]byte, error) //下一個塊,調取s.nextBlockBytesAndPlacementInfo()//下一個塊和位置資訊func (s *blockfileStream) nextBlockBytesAndPlacementInfo() ([]byte, *blockPlacementInfo, error) func (s *blockfileStream) close() error //關閉blockfileStream//代碼在common/ledger/blkstorage/fsblkstorage/block_stream.go

func (s blockfileStream) nextBlockBytesAndPlacementInfo() ([]byte, blockPlacementInfo, error) 代碼如下:

var lenBytes []bytevar err errorvar fileInfo os.FileInfomoreContentAvailable := truefileInfo, err = s.file.Stat() //擷取檔案狀態remainingBytes := fileInfo.Size() - s.currentOffset //檔案讀取剩餘位元組peekBytes := 8if remainingBytes < int64(peekBytes) { //剩餘位元組小於8,按實際剩餘位元組,否則按8????peekBytes = int(remainingBytes)????moreContentAvailable = false}//儲存形式:前n位儲存block長度length,之後length位為實際blocklenBytes, err = s.reader.Peek(peekBytes) //Peek 返回緩衝的一個切片,該切片引用緩衝中前 peekBytes 個位元組的資料length, n := proto.DecodeVarint(lenBytes) //從切片中讀取 varint 編碼的整數,它返回整數和被消耗的位元組數。????err = s.reader.Discard(n) //丟棄儲存block長度length的前n位????blockBytes := make([]byte, length)????_, err = io.ReadAtLeast(s.reader, blockBytes, int(length))????blockPlacementInfo := &blockPlacementInfo{????????fileNum:          s.fileNum,????????blockStartOffset: s.currentOffset,????????blockBytesOffset: s.currentOffset + int64(n)}????s.currentOffset += int64(n) + int64(length)????return blockBytes, blockPlacementInfo, nil//代碼在common/ledger/blkstorage/fsblkstorage/block_stream.go

補充blockPlacementInfo:塊位置資訊

type blockPlacementInfo struct {????fileNum          int //塊檔案尾碼????blockStartOffset int64 //n+length,n之前????blockBytesOffset int64 //n+length,length之前}//代碼在common/ledger/blkstorage/fsblkstorage/block_stream.go
5、blockfileWriter結構體定義及方法
type blockfileWriter struct {????filePath string //路徑????file     *os.File //os.File}func newBlockfileWriter(filePath string) (*blockfileWriter, error) //構造blockfileWriter,並調用writer.open()func (w *blockfileWriter) truncateFile(targetSize int) error //截取檔案func (w *blockfileWriter) append(b []byte, sync bool) error //追加檔案func (w *blockfileWriter) open() error //開啟檔案func (w *blockfileWriter) close() error //關閉檔案//代碼在common/ledger/blkstorage/fsblkstorage/blockfile_rw.go
6、blockIndex相關結構體及方法6.1、index介面定義
type index interface {????getLastBlockIndexed() (uint64, error) //擷取最後一個塊索引(或編號)????indexBlock(blockIdxInfo *blockIdxInfo) error //索引區塊????getBlockLocByHash(blockHash []byte) (*fileLocPointer, error) //根據區塊雜湊,擷取檔案區塊指標????getBlockLocByBlockNum(blockNum uint64) (*fileLocPointer, error) //根據區塊編號,擷取檔案區塊指標????getTxLoc(txID string) (*fileLocPointer, error) //根據交易ID,擷取檔案交易指標????getTXLocByBlockNumTranNum(blockNum uint64, tranNum uint64) (*fileLocPointer, error) //根據區塊編號和交易編號,擷取檔案交易指標????getBlockLocByTxID(txID string) (*fileLocPointer, error)//根據交易ID,擷取檔案區塊指標????getTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error)//根據交易ID,擷取交易驗證代碼}//代碼在common/ledger/blkstorage/fsblkstorage/blockindex.go
6.2、blockIndex結構體

blockIndex結構體定義如下:

type blockIndex struct {????indexItemsMap map[blkstorage.IndexableAttr]bool //index屬性對應????db            *leveldbhelper.DBHandle //index leveldb操作}//代碼在common/ledger/blkstorage/fsblkstorage/blockindex.go

補充IndexableAttr:

const (????IndexableAttrBlockNum         = IndexableAttr("BlockNum")????IndexableAttrBlockHash        = IndexableAttr("BlockHash")????IndexableAttrTxID             = IndexableAttr("TxID")????IndexableAttrBlockNumTranNum  = IndexableAttr("BlockNumTranNum")????IndexableAttrBlockTxID        = IndexableAttr("BlockTxID")????IndexableAttrTxValidationCode = IndexableAttr("TxValidationCode"))//代碼在common/ledger/blkstorage/blockstorage.go

區塊鏈教程Fabric1.0原始碼分析blockfile區塊檔案儲存體一

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.