Go-Ethereum
全節點同步僅保留最後 128 個歷史狀態
在研究不同的同步模式及其行為時,我了解到 geth full sync 將重播創世以來的所有交易並保留所有歷史狀態,而快速同步只會下載沒有 stateb 的塊數據,直到最新塊頭之前的大約 100 個塊,然後作為完整節點執行。
我決定以這種方式驗證這些行為:
- 我啟動了一個私有網路,並在沒有交易的情況下挖了 2000 個區塊(但由於 coinbase 交易,礦工的餘額應該會不斷增加)。
- 然後我用不同的目錄和埠啟動了其他 geth 實例。將它們完全快速同步地連接到專用網路節點。
這是我發現的:
- 在完全同步 geth 實例中,我只能查詢
eth.getBalance(eth.accounts[0], <blockNumber>)
最後 128 個塊的狀態(通過呼叫)。- 在快速同步 geth 實例中,我只能查詢最後 64 個塊的狀態。
在這兩種情況下,從舊塊查詢狀態都會導致
missing trie node
錯誤。深入研究程式碼,我發現那些 trie 節點(舊塊的狀態根)根本沒有保存在底層的 leveldb 中。這些行為與我的預期不符。我想知道我的實驗設置是否有問題。是否存在我不知道的預設狀態特里修剪?我正在使用最新的 geth 1.8。歡迎任何指針。
隨著 geth v1.8.0 的發布,行為發生了變化
來自發行說明
跟踪和修剪:預設情況下,最後 128 個塊的狀態保存在記憶體中。大多數州都是垃圾收集的。如果您正在執行區塊瀏覽器或其他依賴於事務跟踪而沒有歸檔節點(–gcmode=archive)的服務,則需要在此視窗內進行跟踪!或者,指定“reexec”跟踪器選項以允許重新生成歷史狀態;理想情況下切換到鍊式跟踪,它可以在所有跟踪的塊中分攤成本。