Hyperledger-fabric的账本存储
2018-11-07 本文已影响1人
golang推广大使
hyperledger-fabric的账本存储
fabric的账本数据主要包含以下4个部分
- 区块数据存储
- 索引数据库
- 历史数据库
- 账本编号库
区块数据存储
区块数据存储支持多种类型:文件、json和内存。
以文件为例:区块数据存储内容如下:
File |
---|
区块数据大小的proto.EncodeVarint编码 |
区块数据的序列化编码 |
区块数据大小的proto.EncodeVarint编码 |
区块数据的序列化编码 |
区块文件名以blockfile_0000
的形式存在,文件的大小设置一个上限,当存储的数据超过上限时会新建一个区块文件,并把区块写入到新的区块文件里。同时还会降checkpointInfo写入到leveldb数据库中,这个leveldb数据库其实也是索引数据库。
索引数据库存储
索引数据库采用leveldb存储,存储的内容如下:
key | val |
---|---|
constructBlockHashKey(blockIdxInfo.blockHash) |
flpBytes (fileLocPointer类型的数据序列化的结果) |
constructBlockNumKey(blockIdxInfo.blockNum) |
flpBytes |
constructTxIDKey(txoffset.txID) |
txFlpBytes |
constructBlockNumTranNumKey(blockIdxInfo.blockNum, uint64(txIterator)) |
txFlpBytes |
constructBlockTxIDKey(txoffset.txID) |
flpBytes |
constructTxValidationCodeIDKey(txoffset.txID) |
[]byte{byte(txsfltr.Flag(idx))} (交易在区块中的索引) |
[]byte("indexCheckpointKey") |
encodeBlockNum(blockIdxInfo.blockNum) |
blkMgrInfoKey |
checkpointInfo的序列化数据 |
上面construct开头的函数基本是给参数添加相应的前缀,其中的前缀和涉及的结构体定义如下:
const (
blockNumIdxKeyPrefix = 'n'
blockHashIdxKeyPrefix = 'h'
txIDIdxKeyPrefix = 't'
blockNumTranNumIdxKeyPrefix = 'a'
blockTxIDIdxKeyPrefix = 'b'
txValidationResultIdxKeyPrefix = 'v'
indexCheckpointKeyStr = "indexCheckpointKey"
)
// checkpointInfo
type checkpointInfo struct {
latestFileChunkSuffixNum int
latestFileChunksize int
isChainEmpty bool
lastBlockNumber uint64
}
// fileLocPointer
type fileLocPointer struct {
fileSuffixNum int
locPointer
}
type locPointer struct {
offset int
bytesLength int
}
历史数据库
账本的历史数据库也采用leveldb作为存储,存储的内容如下
key | val |
---|---|
historydb.ConstructCompositeHistoryKey(ns, writeKey, blockNo, tranNo) |
emptyval |
savePointKey |
height.ToBytes() |
var savePointKey = []byte{0x00}
var emptyValue = []byte{}
type Height struct {
BlockNum uint64
TxNum uint64
}
账本编号数据库
账本编号数据库
key | val |
---|---|
ledgerId | block的序列化值 |