在智能合約系統(tǒng)的設計中,一種常見的模式是要求客戶端在某個時間節(jié)點前采取某些行為;如果客戶端超過這個時間點(如,某個區(qū)塊高度)沒有響應,則智能合約會采取一些替代行動,而且通常來說是對逾時的客戶端不利的行動。本文中,我的關注點是交互式 rollup 協(xié)議會用到的類似模式 —— 由某一方提出 “斷言(assertion)”,其他人如果覺得斷言有問題,可以在 “挑戰(zhàn)窗口期” 內(nèi)提出挑戰(zhàn);如果挑戰(zhàn)期內(nèi)沒有人提出任何挑戰(zhàn),則這個斷言就會被視為有效的。
這種設計模式在實踐中會遇到的問題是審查攻擊(censorship attack)—— 攻擊者阻撓其他人在時間窗口內(nèi)提出挑戰(zhàn)。在交互式 rollup 協(xié)議中,攻擊者可能會提出虛假的 “斷言”,同時阻止其他人在窗口期發(fā)起挑戰(zhàn),最終導致虛假的斷言反倒成為合法的。
我們也假設,攻擊者必須先投入一筆資金,一旦攻擊失敗,它會失去這筆錢;這樣一來,我們不需要讓系統(tǒng)被成功攻擊概率為零,而只要確保攻擊成功概率足夠小,就不會有人愿意去嘗試攻擊整個系統(tǒng)。
下文,我會總結有關審查攻擊的知識,以及如何對抗審查攻擊,最后給出我對這種風險的看法。
審查攻擊的類型
審查攻擊主要有四種:
分叉:礦工串通(或被賄賂)棄置包含正常挑戰(zhàn)的區(qū)塊,并通過分叉,使另一條沒有包含任何挑戰(zhàn)的區(qū)塊鏈被接受。
閃躲:礦工密謀(或被賄賂)在出塊時不打包正常的挑戰(zhàn)。
干擾:攻擊者通過傳統(tǒng)的拒絕服務攻擊(DoS),使得其他人無法提出挑戰(zhàn)(無法發(fā)出包含挑戰(zhàn)的交易)。
速攻:攻擊者在很短的時間內(nèi)提出大量的鏈上斷言,讓其他人來不及在時間窗口內(nèi)對所有斷言進行檢查和挑戰(zhàn)。
我們一個一個分別討論。
分叉攻擊
分叉攻擊是指在工作量證明(PoW)區(qū)塊鏈上,攻擊者獲得大多數(shù)挖礦算力,并根據(jù)需求使用這些算力來孤立包含挑戰(zhàn)的區(qū)塊。
因為這類攻擊要求攻擊者控制絕大部分算力,所以很難發(fā)起——如果攻擊者能夠輕易獲得大部分算力,表示這條區(qū)塊鏈本身就有很大的問題?;蛘邠Q個角度想,一個能夠控制絕大部分挖礦算力的卡特爾,一方面會導致大家不信任他們所在的區(qū)塊鏈,另一方面,可能也會有比審查攻擊能更快從系統(tǒng)中榨出油水來的辦法。
你可能會說,慢著!算力壟斷者可能并不會高調(diào)地聲張,只是偷偷摸摸地搞審查;如果攻擊者有能力這么做,他們可能會在避免整個區(qū)塊鏈信譽受損的前提下,通過分叉進行審查攻擊。
這里引出第一個問題:審查攻擊對于旁觀者來說,是否易于察覺?為了證明分叉攻擊是顯而易見的,我模擬了分叉。假設攻擊者控制了 60% 的算力,在前三十個區(qū)塊中,出現(xiàn)三條分叉鏈,長度分別是 1、6、5;這和一般的區(qū)塊鏈完全不同。我又做了一次模擬,這次攻擊者控制 55% 的算力,這時候一個較早期的分叉可長達 48 個塊。根據(jù)簡單的數(shù)學模型預測,當壟斷了 60% 的算力,則每 2.5 塊會發(fā)生一次分叉,分叉導致的孤鏈平均長度為 5 ;當壟斷了 55% 的算力,則每 2.2 塊會發(fā)生一次分叉,分叉導致的孤鏈平均長度為 10。
可以看到,隨著壟斷的算力下降,分叉發(fā)生的頻率及孤鏈長度反而增加了;但無論分叉長短,它們的共同之處是(首塊共性):在孤立分支上的首個區(qū)塊一定包含有效挑戰(zhàn),而最終成為主鏈的分支則絕對不會包含這個挑戰(zhàn) —— 提出該挑戰(zhàn)的人一定會發(fā)現(xiàn)這點?。ü粽呖赡軙噲D在更遠處進行分叉來避免首塊共性,但這會導致分支過長,而最終孤立的分支仍包含該挑戰(zhàn)。)所以審查攻擊一旦發(fā)生,就一定會被人發(fā)現(xiàn)。
我不知道你會怎么想,但如果我發(fā)現(xiàn)區(qū)塊鏈中存在算力壟斷現(xiàn)象,而且壟斷者會時不時使用算力干擾應用層協(xié)議,我會感到非常擔憂。如果其他人也有這種疑慮,整個區(qū)塊鏈將不再被用戶所信任——任何 51% 算力攻擊皆會導致這個結果。
換言之,這種攻擊的問題并不是有人會審查你的應用層的交易,而是你所處的區(qū)塊鏈存在算力壟斷者,它可以為了利益不受約束地破壞規(guī)則。對于任何區(qū)塊鏈應用來說,不論 TA 是否采用窗口期設計模式,只要出現(xiàn)了這種算力壟斷,就是毀滅性的打擊。
如果你所在的區(qū)塊鏈可能出現(xiàn)分叉攻擊,你應考慮轉(zhuǎn)移到其他區(qū)塊鏈。
閃躲攻擊
如果算力壟斷者不采用容易被發(fā)現(xiàn)的分叉攻擊,還有別的詭計嗎?有的,就是閃躲攻擊。惡意礦工只要在出塊時,拒絕打包包含挑戰(zhàn)的交易就行了;只要確保挑戰(zhàn)窗口期內(nèi)所產(chǎn)的區(qū)塊,都由惡意礦工產(chǎn)出,攻擊就能成功。
閃躲攻擊成功的可能性有多大?可以這么解釋:當壟斷者控制的算力比例為?f?,挑戰(zhàn)窗口期為?n?個區(qū)塊,則攻擊成功率為?f?n?。舉例來說,壟斷者控制了 90% 的算力,挑戰(zhàn)窗口期為 50 個區(qū)塊,則攻擊成功率為 0.5 %(如果控制了 95% 的算力,攻擊成功率還要維持在 0.5 %,則窗口期要增加為 100 個區(qū)塊)。如果攻擊者要為攻擊失敗支付大量罰金 —— 就像 rolluo 協(xié)議所設計的那樣 —— 他們就不會肆無忌憚地攻擊;而且如果罰沒的錢能返給受害者,大家還會喜聞樂見這些未遂的攻擊。
所以應對閃躲攻擊的辦法是確保挑戰(zhàn)窗口期足夠長,使得攻擊成功概率低至用戶能接受的范圍;假設你能接受的攻擊成功率為?r?,攻擊者至多能控制?f?的算力,則安全的挑戰(zhàn)窗口期為?log(r)/log(f)?個區(qū)塊。
這個建議在現(xiàn)實中也是合理的;假設攻擊者能夠壟斷 99% 的算力,要保證攻擊成功率低至 0.1%,則挑戰(zhàn)窗口期至少要等于 log(0.001)/log(0.99) = 687 個區(qū)塊,對于以太坊來說只需要不到三小時。
干擾攻擊
在干擾攻擊情況下,攻擊者通過“傳統(tǒng)的拒絕服務攻擊”,來阻止其他人發(fā)出挑戰(zhàn);也就是“以 DoS 進行審查攻擊”。
干擾攻擊的問題是,攻擊者必須阻止 “所有” 可能提交挑戰(zhàn)的參與方,如果這些參與方足夠多,則干擾攻擊就很難成功。
對于攻擊者來說還有個壞消息是,其他利益相關方可能會暗中雇用監(jiān)視者 —— 一個暗中觀察協(xié)議運行的中間方,在參與者來不及或難以發(fā)出挑戰(zhàn)時介入,對無效的斷言發(fā)起挑戰(zhàn)。攻擊者沒辦法辨別這些潛伏的監(jiān)視者,也就沒辦法對他們發(fā)起 DoS 。
綜上,對于攻擊者來說,干擾攻擊似乎不是個好選擇。
速攻
速攻指的是,攻擊者發(fā)布大量的斷言,使得其他人來不及在挑戰(zhàn)窗口期內(nèi)檢查所有斷言。
任何的 rollup 協(xié)議都需要有防御速攻的機制,其中一種方法是對提出斷言的頻率進行限制,保證協(xié)議在設定的挑戰(zhàn)窗口期內(nèi)的任何時間點,全網(wǎng)都有足夠的能力去檢查待處理的斷言或挑戰(zhàn)。
這類機制會在一條rollup區(qū)塊鏈上,針對智能合約的處理能力實施一種 “速限手段” ——即使存在某個能快速提出大量斷言的人,他最終也不得不慢下來,確保其他正常參與者能跟上。
所以要衡量一個 rollup 系統(tǒng)的可擴展性,其中一個很重要的指標就是它在保證安全的前提下的最大速度限制;速限指的是一個系統(tǒng)能安全處理事務的速率,而不是某個參與者能夠產(chǎn)出斷言的極限速率。
總結
綜上所述,有三種審查攻擊能夠通過合理的設計或?qū)嵺`來避免。
防范閃躲攻擊:評估攻擊者的資源和風險承受能力,制定合理的挑戰(zhàn)窗口期。
防范干擾攻擊:自行雇用(或通過可信的權威方雇用)潛伏的監(jiān)視者,當你出差池的時候這些監(jiān)視者能夠代替你發(fā)起挑戰(zhàn)。
防范速攻:更細致的設計 rollup 協(xié)議。
關于分叉類型的審查攻擊則很難分析;因為某種程度上來說,成功的分叉攻擊會留下明顯的證據(jù),證明該鏈上存在算力壟斷者,而這些算力壟斷者會更愿意采取其他更快獲得收益的攻擊 —— 比如雙花。任何存在算力壟斷的區(qū)塊鏈都已經(jīng)病入膏肓,那又何必為這種情況下的審查攻擊而操心呢?