作者:Ruben Somsen
來源:https://gist.github.com/RubenSomsen/a02b9071bf81b922dcc9edea7d810b7c
引言
在我最近關於 “SwiftSync” 的研究(中文譯本)中,我意識到,BIP30 有一個尚未解決的共識 bug 。看起來,如果沒有能夠深及 2010 年的區塊鏈重組,就不會觸發這個 bug ,所以它是否嚴重是可以辯論的。我們當前的比特幣客戶端帶有 2013 年的檢查點,所以能夠防止這樣深的重組。但是,一旦我們移除了所有的檢查點,這個 bug 就成為理論上可能被利用的了。
(譯者注:“檢查點” 是一種特殊的維護區塊鏈網絡共識的手段:在客戶端軟件中強制約束某一高度的區塊哈希值應為某個值,如果所得的的區塊的哈希值不是這個值,就拒絕它。在基於工作量證明(PoW)的區塊鏈網絡中,這種手段可用於防止新加入網絡的節點被誘騙到可以低成本製造的惡意區塊鏈上(隨著挖礦機器能力的提升,製造與較為久遠的歷史區塊同等難度的區塊會變得越來越便宜)。儘管有這種正面理由,人們還是傾向於認為,允許存在這種機制可能會給客戶端的開發者太大的權力(擔心這足以讓開發者在實質上決定用戶選擇哪一條區塊鏈)。因此,向來就有在客戶端中消除這種機制的努力。)
從共識檢查的角度看,BIP30 也有一些奇怪,因為它需要遍歷整個 UTXO 集,即使它們與交易所花費的輸入無關。這是低效的,而且讓另類的驗證模式(例如 utreexo、SwiftSync,很可能也會影響到基於零知識證據的系統例如 ZeroSync)的實現變得複雜許多。如果我們可以讓 BIP30 完全退場,那會是一件好事。
並不是非要倡議採取什麼行動(現狀似乎相當不錯),我希望為上述兩者提出解決方案並開啟討論。
1. 共識 bug
有兩筆重合交易被 BIP30 視為例外。後一筆重合交易是區塊高度 91880 的 coinbase 交易。當這筆交易得到處理的時候,區塊高度 91722 的 coinbase 交易就被覆蓋掉了。另一個這樣的情況發生在 91812 和 91842 兩個區塊上。
那麼,當區塊鏈重組到區塊高低 91880 和 91772 之間的時候,問題就會發生。在我們回滾區塊鏈的時候,91880 區塊所創建的輸出會從 UTXO 集中移除。結果是,被覆寫的輸出就從 UTXO 集中完全消失了。而另一個從未見證過這次重組的節點,卻依然保留著這個輸出在自己的集合中(因為它從未被覆寫過)。一旦這個 UTXO 被花費,鏈分叉就會發生。
解決方案 A
我們可以強制,重組不能剛好停留在 91722 區塊和 91880 之間 —— 要麼深到 91722 區塊之前,要麼淺到只在 91880 區塊高度之後。這保證了不論是經歷過重組的區塊,還是新的節點,在自己的 UTXO 集中都不會有這個問題輸出。考慮到這是在 2010 年的挖礦難度下的大約 160 個區塊,這不會是什麼很大的限制。
解決方案 B
在跟 Sjors Provoost 討論我的發現時,他支出,正在被考慮的移除檢查點(自身可被視為一種硬分叉)也是一種改變檢查點以前的共識規則的機會 —— 我們可以在觸及區塊高度 91880 和 91842 的重組時不移除 coinbase 交易,從而修復這個 bug 。除此之外,Sjors 的觀察也開啟了一個問題:我們是否想要改變 2013 年以前的其它共識規則。
2. 讓 BIP30 UTXO 集檢查退場
當前,BIP30 的適用範圍是從創世區塊到 BIP34 激活(區塊高度 227931,2013 年 3 月)。如果這個區塊被重組,BIP30 就會保持無限期適用。BIP34 也有自身的問題,在 “共識清理 BIP” 中得到了解決 —— 你可以自己讀讀,我在這裡就不展開了。
技術上來說,BIP30 僅僅是為了防止出現重合的 未花費 輸出。它是通過檢查已經存在於 UTXO 集中的每一個條目(如有重合就拒絕製造重合的區塊)來保證這一點的(也正是其低效所在)。2010 年出現的兩筆重合交易被硬編碼為例外。在這些規則下,花費一個輸出、然後又重新創建出相同的輸出,是不違反規則的。不過,這似乎從沒發生過。
最後一個要解決的問題是,為什麼如果區塊 227931 被重組,BIP34 就會被棄用。原因是,如不相應棄用,就有可能在 BIP34 激活之前創建出違反 BIP34 規則(確保 coinbase 交易唯一性)的輸出(這也正是共識清理提議嘗試解決的問題)。
理想情況下,讓 BIP30 檢查完全退場(確保即使發生區塊重組也不再需要它)是好事。
解決方案
給定除了那兩個例外,我們並沒有重合交易,我們可以將低效的 BIP30 UTXO 集檢查替換成 coinbae 交易唯一性檢查。我們只需緩存 coinbase 交易的 TXID,並確保 coinbase 交易中沒有重合交易,即可。持續到區塊高度 227931 的檢查只需要大約 7MB 的緩存。然而,因為 BIP34 可能被棄用,BIP30 檢查可能會一直持續,那這樣我們就會有一個不斷增長的緩存。解決方法如下。
除了檢查 coinbase 交易的唯一性,我們也檢查它不會與未來的任何 coinbase 交易衝突(即,不會與 BIP34 和共識清理 BIP 相沖突)。這保證了 BIP34 可以在區塊高度 227931 激活,無論是否會發生重組。
結語
以上是 BIP30 的一些問題以及可能的解決方案。無論我們是否要行動,本文都可作為一種參考。感謝 Antoine Poinsot、Pieter Wuille 和 Sjors Provoost 在本文發表之前的討論。