了解夜影協議:突破限制的NEAR分片設計

鏈金投研 2021-09-18 09:10:52 阅读数:506

了解 突破 限制 分片

分片是區塊鏈擴容的一個重要方向。

傳統的區塊鏈如以太坊每秒僅能處理20個左右的交易。主要原因是以太坊中每個交易都要在每個節點上執行一遍, 單臺機器的處理能力限制了以太坊的最大TPS。

分片的思路是把所有節點進行分組,每個節點不再參與全部交易的驗證,而是僅驗證一部分的交易,因此可以突破單臺機器處理能力的限制。


br


今天這篇文章將會為大家介紹Near protocol提出的分片方案—夜影協議(Nightshade) 。


分片的基本設計

區塊鏈依靠在所有節點複制所有交易來保證數據的正確性,每個節點如果只驗證一部分,那就明顯會降低安全性。

系統共有10個分片(shard chain), 每個分片鏈由1/10的節點驗證,理論上TPS可以提昇十倍,但安全性也會隨之下降。


br

假設原始的區塊鏈中有51%以上的惡意節點合謀了,才可以破壞整條鏈的狀態,那麼分片後只要有5.1% (51/100) 的惡意節點合謀就足够破壞某個分片上的狀態。


大部分分片方案的應對思路是隨機分配驗證者,只要讓惡意節點不在同一條分片鏈上,他們就無法合謀。


大多數方案選擇用一條獨立的鏈來實現管理分片,處理POS(proof of stake)共識,生成隨機數等等。


就比如以太坊2.0的Beacon chain、PolkaDot的Relay chain、Cosmos的Cosmos Hub。


而Nightshade也使用了一條這樣的Beacon chain (信標鏈)。


一般來說區塊鏈的節點會負責以下任務:


1.處理交易 。

2.Relay 合法的交易和區塊給其他節點 。

3.保存整條鏈的狀態和曆史數據。


以上三點都會影響整個網絡的處理能力。


從長遠來看,狀態存儲的壓力比較大,即使TPS一直保持在20左右,鏈的狀態也會一直增長,但短期來看,區塊鏈處理交易的能力才是更加重要的。


截止發稿,以太坊全狀態大約為100G,大多數節點仍可以輕松處理,但是以太坊的TPS僅有20左右,很難滿足實際需求。


Nightshade的分片也會分割以上提到的三點。分片中的節點僅驗證和傳播與分片相關的交易,並且只存儲和分片相關的狀態。


br


在Nightshade的方案中,分片數量和計算、存儲、網絡等資源為線性關系。


Nightshade對Beacon chain和分片鏈進行了簡化,在Nightshade中僅維護一條區塊鏈,所有分片上的交易都會在這一條鏈上被確認。


一個塊中的交易列錶按照分片數量被分為多個chunks, 每個chunk對應一個分片,分片的驗證者只需要下載和驗證分片的chunk而不需要下載整個塊,系統中沒有節點會驗證整個塊的交易和狀態。


現實中由於網絡因素可能會導致chunks丟失,所以我們允許每個塊中的分片可以對應一個或零個chunk。


出塊


Nightshade中有兩個角色共同維護協議:出塊者和驗證者。


在系統中任何時間點都有w個出塊者和wv個驗證者,系統采用POS (proof of stake),出塊者和驗證者都會質押一定的Token作為不遵守協議時的懲罰。


系統包含n個分片,每個出塊者和驗證者都僅下載和驗證一部分的狀態。


在本文所討論的模型中w=100, wv=10000, n=1000。


系統的參與者可以通過質押大量的Token成為出塊者,一個出塊者會被分配到Sw個分片上(如果Sw=40, 那麼每個分片就會有Sw*w/n=4個出塊者)。


Nightshade中按照Epoch的概念選擇驗證者和出塊者的分片,出塊者需要在Epoch開始前下載分片的狀態,並在整個Epoch中處理分片上的交易。


對於每個分片,都有一個出塊者來負責生成chunk(和該分片相關的交易列錶),在最終的塊裏只會包含交易列錶的merkle root而不會包含完整的交易列錶。


br

同一個分片上的出塊者會輪流出塊,如上面描述的,每個分片上有4個出塊者,則每個出塊者隔4 個塊就要產生一次chunk。


跨分片交易


上文描述的分片方案中不同分片之間狀態是完全隔離的,無法進行跨分片的交易。


舉一個簡單的例子,Alice想要轉賬給Bob,如果他們在同一個分片中,則交易可以正常處理。


但如果Alice和Bob在不同的分片,則每個分片的驗證者都缺失了一部分狀態,無法完成這筆交易的驗證。


有兩類方法可以支持跨分片交易:


一、同步。在同一個塊進行與跨分片交易相關的多個分片的狀態更新,驗證者們通過與其他分片上的節點合作來處理交易。


二、异步。异步的完成跨分片交易的狀態更新,比如某個分片先更新一部分狀態,另一個分片再更新其餘的狀態。


這種方式非常簡單並且易於協作,Cosmos、 Ethereum serenity (以太坊 2.0)、Near、Kadena等都采用的异步方案。


br


區塊鏈或分片的互操作性在分片以外的場景也非常重要。分片的場景下每個分片是同構的,且可以借助Beacon chain協調,所以跨分片的設計相比跨鏈會更容易一些。


Nightshade中則采用了收據交易的概念。發起跨鏈交易時首先在一個分片上執行交易,這個交易隨後被打包在分片的chunk裏,當chunk被打包到塊中時,會生成一個收據交易。


驗證者將這個收據交易發送到下一個需要更新的分片上執行。如果這筆交易需要更新更多的分片上的狀態,則會重複以上過程。


這個方案有可能會導致某個特定的分片成為熱點,大量的收據交易需要發送到這個分片上,導致分片的處理能力不够。


為了解决這個問題Nightshade會在chunk中記錄最後處理的跨鏈交易的進度:


塊和分片以及處理到了哪個收據交易,下一個塊的chunk就會繼續處理接下來的收據交易。


如果待處理的收據交易數量實在太多,超過了一定限制的話,系統會禁止再發送新的跨鏈交易。


狀態驗證


分片的核心思想是驗證者不用去下載和驗證所有的狀態。當節點與分片交互時,如何在不下載分片的情况下確定其狀態是一個難題。


有個簡單的方案:


假設整個系統總共有1000個驗證節點,如果其中惡意節點不超過20%,那麼當我們從中隨機挑選200個節點組成分片時,惡意節點占比在1/3以上的可能性就幾乎可以忽略。(惡意節點在1/3以下保證了分片可以使用BFT類共識)。


在這個簡單的假設中,每個Epoch的驗證者都會去詢問之前的一組驗證者,並獲取到主鏈的信息。


而BFT類共識保證惡意節點在1/3以下時,塊是合法的,且不會產生分叉。


因此我們只需從最初的狀態去檢查驗證者的簽名,就可以確定這條鏈的合法性。


br


簡單方案只考慮了系統初始時有固定數量的惡意節點,但如果我們引入一個新的假設:


在系統運行時,誠實的驗證者也可以被腐化為惡意節點,這個簡單方案就無法正常工作了。


攻擊者僅需腐化一個分片中2/3n+1的驗證者就可以生成非法的狀態。這種安全性對於區塊鏈來說顯然太弱了。


Nightshade在BFT共識之上增加了挑戰機制來提昇安全性。任何的參與者檢測到一個chunk包含非法狀態時,都可以提供一個證明對chunk的出塊者進行懲罰,同時獲取獎勵。


因為系統中大多數節點是沒有非法chunk的分片狀態的,所以證明中必須要包含足够的信息。


Nightshade要求在chunk中保存每一個交易執行後分片狀態的merkle root,這樣挑戰者只需要找到第一個非法的狀態,並從前一個狀態進行驗證就可以證明chunk是非法的。


br


Nightshade通過隱藏具體的驗證者來進一步降低驗證者被腐化的可能性。


這個想法類似於Algorand的方案,但需要注意的是,即使隱藏了驗證者,一個攻擊者仍能通過廣播來倡議驗證者進行合謀。


當誠實的驗證者發現倡議合謀的廣播消息時,可以下載攻擊者想要攻擊的分片並進行監控,這樣即使合謀成功,誠實的驗證者也可以立刻發送挑戰來懲罰攻擊者。


Nightshade用以下方法來隱藏驗證者:


1.在每個Epoch開始前,驗證者使用VRF(可驗證隨機方法)確定被分配到的分片,並在Epoch中負責驗證這些分片。


2.所有的驗證者都在區塊上簽名,而非在chunk上簽名。


驗證者有可能不去真正下載分片狀態並執行驗證,而是通過從網絡中觀察其他驗證者的消息並進行重複來獲利。


采用這種策略的驗證者沒有給網絡帶來任何額外的安全性。


為了防止這種行為,我們要求驗證者首先提交一個承諾,承諾中要麼包含一條消息確定chunk的交易都是合法的,要麼包含對某個非法狀態的挑戰。


驗證者需要等待一定的時間後再去揭露實際提交內容,任何提交錯誤的驗證結果,以及無法揭露承諾內容的驗證者都會被懲罰。


數據可見性


數據可見性是區塊鏈分片設計的另一個難題。即使有了複雜的驗證和挑戰機制,攻擊者仍然有作惡空間。


br


同一個分片上的驗證者還可以共謀作惡,只發布chunk header而不發布完整的chunk內容。


因為主鏈只會對chunk做確認而不會對其驗證(如果驗證每個chunk,分片就沒有意義了)。


所以主鏈的驗證者無法判斷chunk的內容是否被發布,出塊者仍會把chunk包含在塊中。


如果這些chunk包含了非法的狀態,即使有誠實的節點對其產生懷疑,因為chunk的內容沒有發布,節點也無法生成挑戰證明。


NightShade的解决方案是選擇引入了擦除碼(Erasure Codes, 方案與PolkaDot和以太坊 2.0類似),擦除碼允許我們在一部分數據不可見時仍能恢複整個區塊。


我們對協議進行修改。當一個出塊者生成了新的 chunk時,同時也要對chunk的內容生成擦除碼。


br


Chunk的出塊者把擦除碼分割成w份(系統中出塊者的數量),並用merkle tree計算每一個碎片,然後把merkle root保存在chunk header裏。


Chunk的出塊者隨後通過onepart消息(用來發送擦除碼的碎片)把擦除碼碎片按照每人一份發送給所有出塊者,消息包含:


chunk header、擦除碼碎片的編號、擦除碼碎片的內容、擦除碼碎片的merkle proof以及出塊者對這條消息的簽名。


當主鏈的出塊者收到塊時,會檢查是否已經收到了塊中所有chunks的onepart消息,如果沒有則需要等待全部消息接受完成後再繼續處理。


等到主鏈出塊者確定每個chunks都收到了對應的onepart消息之後,就會向peers請求每個chunks其餘的擦除碼碎片,並重新構建chunks。


如果出塊者無法成功構建chunks, 或者無法獲取某個chunk的onepart消息的話,就會停止處理該塊。


反之,如果出塊者能够成功的構建出完整的chunks的話,則可以確定chunks的完整內容的確被發布了,Chunk header如果包含了非法狀態,那麼任何節點都可以對其生成挑戰證明。


br

但是當前的協議仍有一個問題,主鏈出塊者有可能在收集完所有的onepart消息之前就進行了簽名。


這樣出塊者仍會收到出塊獎勵,但不會受到任何懲罰,當大多數節點采取了這種策略時,數據可見性就無法得到保證了。


為了解决這個問題,chunk出塊者需要對每個擦除碼碎片分配顏色(紅色或藍色),並且將顏色保存為bitmask與chunk的內容一起編碼成擦除碼。


當chunk出塊者發送onepart消息時同時也會附上碎片的顏色,並且擦除碼碎片的merkle root也會同顏色一起計算。


主鏈出塊者對塊簽名時,需要在簽名中包含所有紅色的chunks碎片組成的bitmask。


因為完整的bitmask只存在於擦除碼中,主鏈的出塊者只有通過擦除碼重新構造chunk內容和bitmask才能獲取正確的顏色。


因此,主鏈出塊者必須確保自己接收到了所有的onepart消息,且能正確構造所有chunks內容,才可以確保簽名是正確的。


如果出塊者沒有收到某個onepart消息卻仍然簽名,則有50%的概率猜錯顏色從而被懲罰。


投資有風險,本文觀點和意見僅代錶作者本人,並不構成任何建議。

版权声明:本文为[鏈金投研]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210918091051696S.html