block底層儲存方式

weixin_34146805發表於2018-04-14

Header和Block的主要成員變數,最終還是要儲存在底層資料庫中。Ethereum 選用的是LevelDB, 屬於非關係型資料庫,儲存單元是[k,v]鍵值對。

//core/database_util.go
var (
    headHeaderKey = []byte("LastHeader")
    headBlockKey  = []byte("LastBlock")
    headFastKey   = []byte("LastFast")
    trieSyncKey   = []byte("TrieSync")

    // Data item prefixes (use single byte to avoid mixing data types, avoid `i`).
    headerPrefix        = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
    tdSuffix            = []byte("t") // headerPrefix + num (uint64 big endian) + hash + tdSuffix -> td
    numSuffix           = []byte("n") // headerPrefix + num (uint64 big endian) + numSuffix -> hash
    blockHashPrefix     = []byte("H") // blockHashPrefix + hash -> num (uint64 big endian)
    bodyPrefix          = []byte("b") // bodyPrefix + num (uint64 big endian) + hash -> block body
    blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
    lookupPrefix        = []byte("l") // lookupPrefix + hash -> transaction/receipt lookup metadata
    bloomBitsPrefix     = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits

    preimagePrefix = "secure-key-"              // preimagePrefix + hash -> preimage
    configPrefix   = []byte("ethereum-config-") // config prefix for the db

    // Chain index prefixes (use `i` + single byte to avoid mixing data types).
    BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress

    // used by old db, now only used for conversion
    oldReceiptsPrefix = []byte("receipts-")
    oldTxMetaSuffix   = []byte{0x01}

    ErrChainConfigNotFound = errors.New("ChainConfig not found") // general config not found error

    preimageCounter    = metrics.NewRegisteredCounter("db/preimage/total", nil)
    preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil)
)

| key | value |
| 'h' + num + hash | header's RLP raw data |
| 'h' + num + hash + 't' | td |
| 'h' + num + 'n' | hash |
| 'H' + hash | num |
| 'b' + num + hash | body's RLP raw data |
| 'r' + num + hash | receipts RLP |
| 'l' + hash | tx/receipt lookup metadata |

這裡的hash就是該Block(或Header)物件的RLP雜湊值,在程式碼中也被稱為canonical hash;num是Number的uint64型別,大端(big endian)整型數。可以發現,num 和 hash是key中出現最多的成分;同時num和hash還分別作為value被單獨儲存,而每當此時則另一方必組成key。這些資訊都在強烈的暗示,num(Number)和hash是Block最為重要的兩個屬性:num用來確定Block在整個區塊鏈中所處的位置,hash用來辨識惟一的Block/Header物件

通過以上的設計,Block結構體的所有重要成員,都被儲存進了底層資料庫。當所有Block物件的資訊都已經寫進資料庫後,我們就可以使用BlockChain結構體來處理整個塊鏈。

2

相關文章