節點如何找到活動鏈?
假設使用者加入比特幣網路並下載區塊鏈的最新狀態(所有塊,包括分叉/叔塊)。該使用者如何找到/確定他們應該在其上建構的活動區塊鏈?我不是在問難度級別或投入鏈的工作量,而是關於這個使用者如何找到最長的鏈並確定不再有鏈。
我想這樣做的簡單(也是唯一?)方法是檢查使用者擁有的每個塊,然後開始建構投入最多工作的塊。然而,由於節點還儲存了許多分叉,因此評估比特幣存在的每個區塊及其“路徑”可能需要一段時間(並且隨著時間的推移會持續更長的時間)。
一個潛在的“捷徑”是簡單地查找最近的塊,例如。搜尋在過去 48 小時內送出的塊,然後從那裡獲取最長的有效鏈,但是如何決定特定的時間範圍?(24h?48?上週?上個月?)理論上仍然有可能目前最長的鏈已經發布很久了,其他節點試圖忽略它的惡意行為,所以這種做法似乎並不在我看來有效。
我知道比特幣使用 LevelDB 儲存有關塊的元數據以便快速查找,這將有助於加快對所有塊的評估,但是比特幣的程式碼是否有更實用的方法?
此外,這個評估是在每次使用者啟動時從頭開始(即從創世塊)完成的,還是有關最長鏈的資訊是否儲存在磁碟上的某個位置以便使用者重新加入時快速檢索?
當新節點加入網路時,它將從 DNS 種子中查找節點。它會聯繫到它所聽到的多個節點,並依次向它們詢問更多的節點。新節點向每個對等節點詢問他們的最佳鏈提示,然後開始同步它首先聽到的最佳鏈提示的標頭。塊頭只有 80 個字節(與完整的塊相比很小),但已經允許檢查該鏈上的所有塊是否已連接並且塊是否滿足難度標準。
從那時起,節點驗證每個塊以驗證是否遵循了共識規則。如果發現他們遵循的最佳鏈提示損害了任何共識規則,則丟棄第一個無效的塊,並且遵循該鏈的對等點斷開連接。從那時起最好的鏈提示是通過查詢剩餘的(符合規則的)對等點來找到的。最後,節點會發現累積難度最大的有效鏈。
Bitcoin Core 的每個版本都會為該
assumevalid
參數設置一個預設值,該值是最近發布之前的一個塊。當同步到那個塊時,使用的節點assumevalid
會假設到那個塊的歷史是有效的。他們仍然會計算所有的 UTXO 集轉換並在任何地方檢查難度,但不會檢查直到該塊的交易的簽名。