Utxo

CCoinsViewDB::GetHeadBlocks 有什麼用?

  • January 30, 2018

我有很多Google,資訊很少,與程式碼註釋混淆

Retrieve the range of blocks that may have been only partially written. If the database is in a consistent state, the result is the empty vector. Otherwise, a two-element vector is returned consisting of the new and the old block hash, in that order.

為什麼存在新舊塊,它們的功能?

比特幣核心做這個叫做非原子刷新的事情。這意味著數據庫不是自動更新(即同時寫入所有內容,或者什麼都不寫入),而是隨著時間的推移將數據寫入其中。如果數據庫崩潰,使用非原子刷新,會有一些數據寫入,還有一些數據沒有寫入。這與原子刷新不同,原子刷新要麼寫入所有數據,要麼不寫入。

非原子刷新允許比特幣核心跳過對其已經驗證的內容的驗證,然後在崩潰或不干淨的關閉後將內容刷新到數據庫中。但是為了知道它已經驗證到哪裡,它必須儲存該塊雜湊(它已經驗證到哪里以及它正在刷新到哪裡)。它還必須儲存它開始的塊(數據庫在刷新開始時知道的塊)。

這就是GetHeadBlocks()進來的地方。當比特幣核心開始刷新時,它首先寫入這兩個塊,數據庫頭所在的舊塊,以及刷新完成後數據庫頭所在的新塊。如果發生非正常關閉或數據庫崩潰,這些值已經寫入數據庫,因此它可以將這些值從數據庫中提取出來,知道它最後一次已知的良好數據庫狀態在哪裡,並且知道它已經驗證到哪裡,所以它可以跳過完全驗證,只建構數據庫數據並刷新它。如果沒有不干淨的關閉或崩潰,GetHeadBlocks()將返回一個空向量。


例如,假設數據庫位於塊 50,並且正在刷新到塊 60。當它開始刷新時,塊 50 和 60 的雜湊被寫入數據庫。假設電腦在只刷新到塊 55 時突然斷電。當節點重新啟動時,它會呼叫GetHeadBlocks()並獲取塊 50 和 60 的雜湊值。現在它知道當它不干淨地關閉時它處於刷新中間. 因此,它會重建從塊 50 到 60 的數據庫,但不執行完全驗證。然後它會刷新剩餘的數據並從寫入它們的位置刪除塊 50 和 60 的雜湊值。

你的答案在於程式碼。

檢查 GetHeadBlocks 的使用位置.. <https://dev.visucore.com/bitcoin/doxygen/class_c_coins_view_d_b.html>

呼叫者圖表明它正在被 CCoinsViewDB::BatchWrite 使用。如果最新的 head 與作為參數傳遞的雜湊塊不匹配,則 BatchWrite 中的斷言語句將中止函式執行。

我的 30 秒研究似乎表明,當它處於同步狀態時,它將返回新舊塊的塊雜湊。BatchWrite 還負責更新最佳塊雜湊(檢查 doxygen)。

引用自:https://bitcoin.stackexchange.com/questions/66898