區(qū)塊鏈因其去中心化的設(shè)計而犧牲了效率,因此提升執(zhí)行速度一直是急需解決的問題之一。區(qū)塊鏈的「執(zhí)行層」是處理每一筆交易并將其加入鏈中的關(guān)鍵部分。為了加速處理能力,在執(zhí)行層進(jìn)行提升成為核心策略之一,而并行執(zhí)行正是這一方面的重要突破。
傳統(tǒng)的區(qū)塊鏈通常采用串行方式逐筆處理交易,這使得交易速度受到很大限制,尤其在交易密集的網(wǎng)絡(luò)中會引發(fā)擁堵。然而,通過并行執(zhí)行,多個交易可以同時處理,從而大幅提高執(zhí)行效率并減輕鏈上壓力。
為了更好地了解什么是并行,我們將先從執(zhí)行開始介紹,并以 Merge 后 PBS 模式下的以太坊為例,來解釋一下什么是執(zhí)行,同時展示執(zhí)行在整個交易生命周期中所處的位置。
交易執(zhí)行的具體環(huán)節(jié)
- 交易進(jìn)入內(nèi)存池并被篩選和排序:這是交易被提交后的預(yù)處理階段,包含了 Mempool、Searcher 和 Builder 的交互,完成對交易的篩選和排序。
- Builder 構(gòu)建區(qū)塊(但不執(zhí)行):Builder 將有利可圖的交易排列成一個區(qū)塊,以完成對交易的打包和排序。
- Proposer 驗證并提交區(qū)塊:區(qū)塊構(gòu)建完成后,Builder 會將區(qū)塊的提案發(fā)送給 Proposer。Proposer 對區(qū)塊的結(jié)構(gòu)和交易內(nèi)容進(jìn)行驗證,然后正式將區(qū)塊提交到網(wǎng)絡(luò)上,以開始執(zhí)行。
- 執(zhí)行交易:區(qū)塊提交后,節(jié)點逐筆執(zhí)行區(qū)塊內(nèi)的交易。這是狀態(tài)更新的關(guān)鍵階段,每筆交易都會觸發(fā)智能合約調(diào)用、賬戶余額變化或狀態(tài)變更。
- 見證者見證:驗證者對區(qū)塊的執(zhí)行結(jié)果和狀態(tài)根進(jìn)行見證,并將其作為最終確認(rèn)。這確保了區(qū)塊在執(zhí)行層的真實性和有效性,并防止不一致性。
- 狀態(tài)同步:每個節(jié)點會將區(qū)塊的執(zhí)行結(jié)果(如賬戶余額、合約狀態(tài)更新等)同步到自己的本地狀態(tài),執(zhí)行每筆交易后,節(jié)點計算并存儲一個新的狀態(tài)根,用以在下一個區(qū)塊中作為初始狀態(tài)。
當(dāng)然,這只是以區(qū)塊為單位的交易的狀態(tài)同步,為了保持最新的鏈上狀態(tài),通常情況下,節(jié)點會逐個區(qū)塊同步數(shù)據(jù),并持續(xù)驗證區(qū)塊和狀態(tài)。但如果要達(dá)到 POS 機(jī)制下的最終性,還需要聚合者將每個 Slot 中的見證者簽名聚合成一個完整的簽名,并將其傳遞到下一個 Slot 的提議者處,并且驗證者需要在經(jīng)過一個 Epoch 后,基于投票數(shù)量確認(rèn)該 Epoch 內(nèi)的所有區(qū)塊的狀態(tài),形成臨時的共識狀態(tài)檢查點。當(dāng)連續(xù)兩個 Epoch 獲得大多數(shù)驗證者的見證支持后,區(qū)塊和交易才會達(dá)成最終性。
從交易的整個生命周期來看,執(zhí)行發(fā)生在 Proposer 對 Builder 發(fā)送來的區(qū)塊的結(jié)構(gòu)和交易內(nèi)容進(jìn)行驗證后。實際執(zhí)行過程需要對交易逐筆處理,并對相應(yīng)的賬戶或合約狀態(tài)進(jìn)行更新。所有交易執(zhí)行完畢后,Proposer 會計算出一個新的狀態(tài)根(默克爾根),這是對當(dāng)前區(qū)塊所有交易的執(zhí)行結(jié)果和最終全局狀態(tài)的總結(jié)。通俗來說,完整的區(qū)塊執(zhí)行過程包括把以太坊從前一個狀態(tài)變成下一個狀態(tài)的過程中需要完成的一系列計算,從每個交易的執(zhí)行到默克爾根的計算。
順序執(zhí)行
與并行相對的是順序執(zhí)行,也就是目前區(qū)塊鏈較為通用的執(zhí)行方式。通常,交易會按照順序逐步執(zhí)行。當(dāng)一筆交易完成執(zhí)行后,以太坊會將賬戶狀態(tài)及相關(guān)信息(例如余額、合約存儲數(shù)據(jù))更新至賬戶狀態(tài)樹中,新的賬戶狀態(tài)哈希被生成。所有賬戶狀態(tài)樹完成更新后,就會形成被稱為狀態(tài)默克爾根的狀態(tài)樹的根節(jié)點哈希。在完成狀態(tài)默克爾根、交易默克爾根和收據(jù)默克爾根后,區(qū)塊頭就會進(jìn)行哈希計算,生成該區(qū)塊的區(qū)塊哈希。
而在這其中,交易的執(zhí)行順序至關(guān)重要。由于默克爾樹是哈希值的二叉樹,不同順序下形成的默克爾根值會不同。
并行執(zhí)行
在并行執(zhí)行的環(huán)境下,節(jié)點會嘗試對區(qū)塊中的交易進(jìn)行并行處理。并不是按照順序一筆一筆地執(zhí)行交易,而是將交易分配到不同的「執(zhí)行路徑」上,使它們能同時執(zhí)行。通過并行執(zhí)行,系統(tǒng)能夠更高效地處理區(qū)塊中的交易,提高吞吐量。
所有交易執(zhí)行完成后,節(jié)點會將執(zhí)行結(jié)果(即交易影響的狀態(tài)更新)匯總,形成一個新的區(qū)塊狀態(tài)。這個狀態(tài)會被添加到區(qū)塊鏈上,代表鏈上最新的全局狀態(tài)。
狀態(tài)沖突
由于并行會在不同路徑同時處理交易,因此并行的一大難點就是狀態(tài)沖突。即可能存在多個交易在同一時間段內(nèi)對區(qū)塊鏈上的同一部分?jǐn)?shù)據(jù)(狀態(tài))進(jìn)行讀取或?qū)懭氩僮鞯那闆r。這種情況如果處理不當(dāng),會導(dǎo)致執(zhí)行結(jié)果不確定。因為狀態(tài)的更新順序不同,最終的計算結(jié)果也會不同。舉個例子,
假設(shè)有兩個交易,交易 A 和交易 B,它們都試圖對同一個賬戶的余額進(jìn)行更新操作:
- 交易 A:增加賬戶余額 10。
- 交易 B:增加賬戶余額 20。
賬戶初始余額為 100。
如果我們串行執(zhí)行,執(zhí)行順序的結(jié)果是確定的:
1. 先執(zhí)行交易 A,再執(zhí)行交易 B:
- 賬戶余額先增加 10,變?yōu)?110。
- 再增加 20,最終變?yōu)?130。
2. 先執(zhí)行交易 B,再執(zhí)行交易 A:
- 賬戶余額先增加 20,變?yōu)?120。
- 再增加 10,最終變?yōu)?130。
在這兩種順序中,最終余額都是 130,因為系統(tǒng)確保了交易執(zhí)行的順序一致性。
但在并行執(zhí)行環(huán)境下,交易 A 和交易 B 可能同時讀取初始余額 100 并進(jìn)行各自的運(yùn)算:
- 交易 A 讀取到余額為 100,計算后更新余額為 110。
- 交易 B 也讀取到余額為 100,計算后更新余額為 120。
在這種情況下,由于交易同時執(zhí)行,導(dǎo)致最終余額只更新為 120,而不是 130,因為交易 A 和交易 B 的操作「覆蓋」了對方的結(jié)果,產(chǎn)生了狀態(tài)沖突。
這類狀態(tài)沖突問題通常被叫做「數(shù)據(jù)覆蓋」,即當(dāng)交易試圖同時修改相同的數(shù)據(jù)時,可能會相互覆蓋對方的計算結(jié)果,導(dǎo)致最終狀態(tài)不正確。另外一種狀態(tài)沖突可能會導(dǎo)致的問題是無法保證執(zhí)行順序。由于多個交易在不同的時間段完成操作,會造成不同的執(zhí)行順序。順序不同,可能會導(dǎo)致不同的計算結(jié)果,從而使結(jié)果不確定。
為了避免這種不確定性,區(qū)塊鏈并行執(zhí)行系統(tǒng)通常會引入一些沖突檢測和回滾機(jī)制,或提前對交易進(jìn)行依賴性分析,確保它們在不影響最終狀態(tài)一致性的情況下并行執(zhí)行。
樂觀并行與確定性并行
有兩種方法方式來對待可能存在的狀態(tài)沖突問題:確定性并行和樂觀并行。這兩種模式在效率和設(shè)計復(fù)雜性上各有權(quán)衡。
確定性并行需要提前聲明狀態(tài)訪問,驗證者或 sequencer 會在交易排序時檢查聲明的狀態(tài)訪問。如果有多個交易試圖寫入同一狀態(tài),會將這些交易標(biāo)記為沖突,避免同時執(zhí)行。不同的鏈具體實現(xiàn)提前聲明狀態(tài)訪問的形式不同,但一般包括以下幾種方式:
- 通過合約規(guī)范約束:開發(fā)者在智能合約中直接規(guī)定狀態(tài)訪問范圍。例如,ERC-20 代幣轉(zhuǎn)賬需要訪問發(fā)送方和接收方的余額字段。
- 通過交易結(jié)構(gòu)化數(shù)據(jù)聲明:交易中添加專門字段來標(biāo)注狀態(tài)訪問。
- 通過編譯器分析:高級語言的編譯器可以靜態(tài)分析合約代碼,自動生成狀態(tài)訪問集合。
- 通過框架強(qiáng)制聲明:某些框架要求開發(fā)者在調(diào)用函數(shù)時顯式指定需要訪問的狀態(tài)
樂觀并行則會樂觀地先處理交易,等到?jīng)_突發(fā)生時,再將受影響的交易按順序重新執(zhí)行。為了盡可能避免沖突情況的發(fā)生,樂觀并行設(shè)計的核心是通過歷史數(shù)據(jù)、靜態(tài)分析等對狀態(tài)進(jìn)行快速預(yù)判和假設(shè)。即系統(tǒng)在不完全驗證的情況下,假設(shè)某些操作或狀態(tài)更新是有效的,盡量避免等待所有驗證過程,以此提高性能和吞吐量。
雖然樂觀并行能通過一些對狀態(tài)的快速預(yù)判和假設(shè)來盡可能避免沖突發(fā)生,但還是會有一些無法避免的挑戰(zhàn),特別是涉及合約執(zhí)行或跨鏈交易,如果沖突頻繁發(fā)生,重新執(zhí)行可能顯著拖慢系統(tǒng)性能,并增加計算資源消耗。
確定性并行則通過在交易前進(jìn)行狀態(tài)依賴性檢查以避免樂觀并行可能出現(xiàn)的沖突情況,但由于需要在交易提交前準(zhǔn)確聲明狀態(tài)依賴,這對開發(fā)者提出更高要求,從而增加了實現(xiàn)的復(fù)雜性。
EVM 并行困境
對待狀態(tài)沖突不僅有確定性和樂觀之分,在實現(xiàn)并行的具體過程中,還需要從鏈數(shù)據(jù)庫架構(gòu)的角度進(jìn)行考慮。并行中的狀態(tài)沖突問題在默克爾樹架構(gòu)下的 EVM 中就尤為困難。默克爾樹是一個分層哈希結(jié)構(gòu),在每次交易對某個狀態(tài)數(shù)據(jù)進(jìn)行修改后,默克爾樹的根哈希值也需要更新。這種更新過程是遞歸的,從葉子節(jié)點向上逐層計算直至根節(jié)點。由于哈希是不可逆的,即只有當(dāng)下層的數(shù)據(jù)變更完成后才能計算上層,這種特性導(dǎo)致它很難并行更新。
如果兩個交易并行執(zhí)行并訪問同一個狀態(tài)(如賬戶余額),就會造成默克爾樹節(jié)點的沖突。而解決這種沖突通常需要額外的事務(wù)管理機(jī)制,確保在多個分支中都能得到一致的根哈希值。這對 EVM 來說并不容易實現(xiàn),因為它需要在并行化與狀態(tài)一致性間做取舍。
非 EVM 并行解決方案
Solana
不同于以太坊的全局狀態(tài)樹,Solana 采用了賬戶模型。每個賬戶是獨立的存儲空間,存儲在賬本中,因此避免了路徑?jīng)_突問題。
Solana 是確定性并行。在 Solana 中,每筆交易需要在提交時明確聲明將訪問的賬戶和所需的訪問權(quán)限(只讀或讀寫)。這種設(shè)計讓區(qū)塊鏈節(jié)點可以在交易執(zhí)行之前,提前分析每筆交易需要訪問的資源。因為交易在開始執(zhí)行前已明確所有的賬戶依賴關(guān)系,節(jié)點可以判斷哪些交易會訪問相同的賬戶,哪些交易可以安全地并行執(zhí)行,從而實現(xiàn)智能調(diào)度,避免沖突,從而實現(xiàn)并行調(diào)度的基礎(chǔ)。
由于每筆交易在執(zhí)行前就已聲明了需要訪問的賬戶和權(quán)限,Solana 可以檢查交易之間是否存在賬戶依賴關(guān)系(Sealevel 模型)。交易之間如果沒有共享的讀寫賬戶,系統(tǒng)就可以把它們分配到不同的處理器上并行執(zhí)行。
Aptos
Aptos 的并行執(zhí)行設(shè)計與以太坊有很大的不同,它在架構(gòu)和機(jī)制上做出了一些關(guān)鍵創(chuàng)新,主要體現(xiàn)在賬戶模型和狀態(tài)存儲。
以太坊在執(zhí)行交易時需要頻繁更新全局狀態(tài)樹(MPT)。所有賬戶、合約的狀態(tài)都存儲在一個共享的狀態(tài)樹中,任何交易都需要訪問和更新這棵狀態(tài)樹的一部分。而 Aptos 則通過將賬戶劃分為獨立的狀態(tài)單元,每個對象是一個獨立的鍵值對,對象之間可以獨立存在,彼此互不影響,只有明確引用關(guān)系時才會關(guān)聯(lián)。對象之間沒有公共的樹路徑,不會出現(xiàn)鎖競爭,可以完全并行。
Aptos 的底層數(shù)據(jù)結(jié)構(gòu)為 Jellyfish Merkle Tree。每個對象的狀態(tài)最終存儲在 JMT 中,作為獨立的鍵值對。不同于以太坊的 MPT,Jellyfish Merkle Tree 以一種完全二叉樹結(jié)構(gòu)的形式,這種形式使得節(jié)點的存儲路徑和查詢路徑被簡化,大幅降低了驗證時間。并且,每個賬戶在樹中的位置是固定的,且樹中的節(jié)點是獨立存儲的,允許多個賬戶的更新和查找并行進(jìn)行。
Aptos 是樂觀并行,它不需要預(yù)先提供聲明的所有賬戶的依賴關(guān)系。為此,Aptos 使用 Block-STM,Block-STM 會利用預(yù)設(shè)的交易順序來估計依賴性,從而減少中止次數(shù)。
并行 EVM
與非 EVM 并行相比,并行 EVM 在處理狀態(tài)依賴性、沖突檢測、Gas 管理和回滾機(jī)制等問題時,面臨的技術(shù)難度較大。為了更好地理解這一點,我們可以參考一些并行 EVM 項目(如 Sui、Monad、Canto)如何解決這些問題。
Sui
Sui 和 Aptos 一樣,也是使用對象模型來處理狀態(tài),采用每個對象(例如賬戶、智能合約狀態(tài))作為獨立的資源,這些對象通過對象唯一標(biāo)識符來區(qū)分。當(dāng)交易涉及不同的對象時,這些交易可以并行處理,因為它們對不同的狀態(tài)進(jìn)行操作,不會產(chǎn)生直接的沖突。
雖然 Sui 使用對象模型來管理狀態(tài),然而,為了兼容 EVM,Sui 的架構(gòu)通過額外的適配層或抽象機(jī)制,來橋接對象模型和 EVM 的賬戶模型。
在 Sui 中,事務(wù)的調(diào)度使用樂觀并行策略,假設(shè)事務(wù)之間沒有沖突。如果沖突發(fā)生,系統(tǒng)會使用回滾機(jī)制來恢復(fù)狀態(tài)。
Sui 使用了對象模型和狀態(tài)隔離技術(shù),能有效避免狀態(tài)依賴性問題。每個對象作為獨立的資源,不同的交易可以并行執(zhí)行,從而提高了吞吐量和效率。但這種方法的 trade-off 是對象模型的復(fù)雜性和回滾機(jī)制的開銷。如果交易之間發(fā)生沖突,需要對部分狀態(tài)進(jìn)行回滾,這會增加系統(tǒng)的負(fù)擔(dān),并且可能影響并行處理的效率。相較于非 EVM 并行系統(tǒng)(如 Solana),Sui 需要更多的計算和存儲資源來維持高效的并行性。
Monad
與 Sui 一樣,Monad 采用的也是樂觀并行。但 Monad 的樂觀并行在具體交易執(zhí)行前還是會對一些具有依賴關(guān)系的交易進(jìn)行預(yù)測,預(yù)測主要通過 Monad 的靜態(tài)代碼分析器來完成。預(yù)測需要對狀態(tài)進(jìn)行訪問,而以太坊數(shù)據(jù)庫中存儲狀態(tài)的方式使得訪問狀態(tài)非常困難,為了使得并行在狀態(tài)讀取的過程更具效率,Monad 還重構(gòu)了數(shù)據(jù)庫。
Monad 狀態(tài)樹按分區(qū)進(jìn)行劃分,每個分區(qū)維護(hù)自己的狀態(tài)子樹。更新時只需修改相關(guān)分片,無需重建整個狀態(tài)樹。通過狀態(tài)索引表快速定位分區(qū)中的狀態(tài),減少分區(qū)間的交互。
小結(jié)
并行的核心是以多路徑執(zhí)行的方式提高執(zhí)行層執(zhí)行效率,而為了實現(xiàn)多路徑執(zhí)行,鏈則需要進(jìn)行一系列如沖突檢測和回滾機(jī)制以確保它們在不影響最終狀態(tài)一致性的情況下并行執(zhí)行,并對數(shù)據(jù)庫進(jìn)行一定程度的改良。
當(dāng)然,執(zhí)行層效率的提高不局限于并行這一種方式,執(zhí)行環(huán)節(jié)的優(yōu)化還可以通過降低一筆交易對數(shù)據(jù)庫需要的讀寫操作來完成。而整個鏈速度提升涉及的范圍則更為廣泛,還包括了共識層效率的提升。
每個技術(shù)背后都有屬于其特定的限制條件。并行僅是提升效率的方式之一,最終決定是否使用該技術(shù)還需要考慮對于開發(fā)者是否友好,是否能夠以不犧牲去中心化的方式完成等等。技術(shù)的堆疊并非越多越好,至少,對于以太坊而言,并行并沒有那么那么具有吸引力,如果單從提升效率的角度出發(fā),加入并行對于以太坊而言并非是最優(yōu)解,無論是從簡潔性考慮還是以以太坊目前 Rollup 為中心的路線圖來考慮。
以上就是并行區(qū)塊鏈全解:執(zhí)行原理、代表項目及所處周期的詳細(xì)內(nèi)容
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。