三個儲存區
已提交區塊
帳本儲存區交易 · 輸出 · 事件 · 寫入集 · 累加器 · 區塊中繼資料
重放與稽核
狀態 KV 儲存區當前值與歷史值,分成十六個分片,高頻狀態另有一層
查詢與執行
狀態 Merkle 儲存區一棵帶版本的稀疏 Merkle 樹,外加追蹤被取代節點的索引
驗證 — 證明
只要取值的讀取,不必為樹走訪付出代價;而一份證明,也不必從一個專為點查詢最佳化的儲存區裡重建出來。
認證
兩種 Merkle 結構做的是不同的工作。帶版本的稀疏 Merkle 樹
累加器
你的鍵及其值
兄弟節點雜湊
兄弟節點雜湊
狀態根,由共識提交
你的交易,或一個事件
交易累加器 · 事件累加器各自承諾到目前為止按順序包含的全部內容
帳本根,由共識提交
樹證明某個值曾是什麼;累加器證明發生了什麼、以何種順序發生。兩者合起來,「這筆交易在鏈上的這個位置」不必持有整條鏈就能證明。
推測狀態
一個區塊的結果,在提交之前就已經存在。與其先寫進持久化的樹、區塊沒提交再撤回來,未提交的狀態改放在一層記憶體內稀疏 Merkle 覆蓋層裡,疊在最近一個已提交版本之上。 執行透過這層覆蓋讀取,看到的是一致的視圖。區塊提交了,覆蓋層就物化下來;沒有提交,覆蓋層直接丟掉,持久化儲存從頭到尾沒被碰過。正是這一點,讓推測執行不會在儲存裡留下殘渣。快取
樹節點在兩個層次上快取:上層是一個感知版本的快取,保持近期版本可定址;底下再一層最近最少使用(LRU)快取。一條交易鏈的存取模式——一小組每個區塊都會碰到的熱點鍵,加上一條極少碰到的長尾——正是這類快取針對的形態。修剪
永久保留每一個版本是一種選擇,不是一項要求。三個相互獨立的修剪器分別針對這三個儲存區運行,各有自己的保留策略:一個針對帳本,一個針對狀態值,一個針對 Merkle 節點。 Merkle 修剪器和狀態值修剪器靠過期索引驅動,而這些索引是和資料同時寫下去的。某個版本一旦取代了某個節點或某個值,被取代的條目就會在該版本上記為過期。於是修剪變成對一個索引做範圍掃描,不必到處搜尋垃圾:寫入方早就講明了什麼會變成可回收,以及在什麼時候。保留策略是維運上的決定,而且有實際後果。修剪得積極的節點,當前狀態提供得很有效率,卻答不了歷史查詢,也沒辦法替一個從更早處起步的節點做狀態同步。歸檔節點保留一切,並為此付出代價。參見運行節點。
備份與還原
這些儲存區可以獨立於運行中的節點備份和還原。正因如此,才有辦法從快照架起一個節點,不必從創世開始重放;也才有辦法拿已提交的根去驗證還原後的節點狀態,而不是只能選擇相信那份備份。後續閱讀
狀態同步
節點怎麼不重放全部歷史就追上這條鏈。
狀態模型
儲存的是什麼,以及哪一種表示是權威。
索引器
從已提交紀錄中重建歷史。
運行節點
節點角色,以及如何諮詢節點營運事宜。