EIP-7928引入了區塊級訪問列表 (BAL),以改進 L1 上的並行執行。除了擴展之外,BAL 還為提議者承諾協議(尤其是執行預置)奠定了更簡單的基礎。BAL 不再依賴於多個 Merkle Patricia Tries 中的碎片化證明,而是提供了所有可與承諾綁定的交易後值的規範記錄。
話雖如此,當前的 EIP-7928 規範並不直接適用於高效的EVM 級證明。本文旨在鼓勵使用 BAL 進行預配置,重點介紹為使其易於證明而提出的規範變更,並概述Discord 中正在討論的複雜性權衡。
動機
執行預置機制允許提議者(或委託人)在交易上鍊之前就向用戶提供關於交易結果的早期承諾。這將預確認時間縮短至從提議者到用戶只需一次“ping”,從而提供比共識協議更快的用戶體驗。用戶無需等待區塊確認,而是在收到可信的執行預置後即可自信地採取行動。
如今,可信承諾要求能夠以無需信任的方式證明承諾何時被違背,以便對已綁定的預置合約強制執行鏈上罰沒條件(例如,使用URC )。這些證明分散在多個 trie 中:用於包含/排序的交易 trie、用於執行成功的收據 trie、用於 nonce 或餘額變化的賬戶 trie,以及用於存儲的狀態 trie。這種方法雖然可行,但存在碎片化問題,需要定製的證明邏輯,並且粒度有限。
碎片化:完整覆蓋需要對每個修改狀態進行多次嘗試並提交值。
邏輯:每個承諾都會做出不同的承諾並影響不同的狀態,需要自定義邏輯。
粒度:這些樹只記錄應用所有交易後的狀態,這意味著中間狀態更新(例如,第四次交易後 Alice 的餘額)無法直接證明。
一些提議的設計針對 1) 和 3) 進行了改進,如果事後狀態與用戶預期不符,則撤銷交易,例如“以至少 0.98 ETH 的價格出售 1000 USDC ” 。雖然實用,但這將負擔轉移到了合約開發者身上,他們必須手動編碼這些條件。實際上,它類似於意圖式編程,每個操作都帶有定製的有效性條件。
通過提供交易級狀態差異的規範記錄,BAL 提供了一種更簡單的構建提議者承諾協議的原語。執行預置可以表示為對BAL子集的承諾,並且可以根據規範BAL證明承諾的違反。這使得承諾的推理、執行和標準化更加簡單,從而降低了協議設計者和用戶的摩擦。因此,一個有效利用 BAL 的通用提議者承諾協議可以涵蓋當今所有的預置用例。
今日 BAL
BAL是一個 RLP 編碼的List[AccountChanges]
,其中AccountChanges
對象記錄了每筆交易中地址 nonce、餘額、存儲空間和/或代碼的狀態變化。通過迭代應用所有AccountChanges
,客戶端可以確定性地並行重建每個受影響賬戶在整個The Block中的演變過程。
這足以解決我們執行預置所面臨的挑戰:
碎片化:僅需要BAL做出承諾,無需多次嘗試邏輯:單個通用協議足以捕獲當今所有的預配置用例,而無需意圖式編程。粒度:AccountChanges
對象允許對每個交易狀態差異做出承諾。
電流限制
顯然,BAL 可以改進預配置協議;然而,挑戰在於如何編碼 BAL。根據當前的 EIP-7928 規範,BAL 採用 RLP 編碼,並且The Block塊頭包含BAL哈希值。
這使得向 EVM 證明承諾被違反變得非常繁瑣。用戶需要將整個BAL作為調用數據 (calldata) 傳遞,將其哈希值與父區塊哈希值進行驗證,然後手動進行 RLP 解碼以找到衝突值。目前,未壓縮的BAL大小約為 100KB,在調用數據的限制範圍內。鑑於承諾被違反的情況很少發生,因此這種做法並非不合理。
擬議的 EIP 變更(更難)
隨著區塊和 BAL 規模的擴大,將BAL作為調用數據傳遞的成本將更加昂貴。擬議的變更將使從 EVM 證明BAL成員身份變得更加容易。
由於執行客戶端不太可能使用 SSZ 來編碼BAL,因此另一種方法是將BAL編碼為其自己的 MPT ,正如 Toni 所建議的那樣。The Block塊頭將包含BAL根而不是哈希值,從而可以針對 EIP-2935 父哈希進行高效的 MPT 證明。
理想的預置文件編碼應該包含兩層 trie。外層 trie 將bal_index
(又稱交易索引)鍵映射到subTrieRoot
值,其中每個bal_index
代表一個唯一的交易索引。內層subTrie
包含涵蓋所有不同賬戶變更的唯一鍵:
RLP(["balance_change", address])
RLP(["storage_change", address, slot])
RLP(["nonce_change", address])
RLP([“code_change”, address])
其值包含 RLP 編碼的交易後數據(即RLP([uint256])
)。
這將允許預協商者對交易後狀態差異做出簡潔的承諾,即對給定bal_index
的子subTrieRoot
進行簽名。證明承諾被違背,就簡化為證明該bal_index
處的實際子subTrieRoot
與簽名的子樹根 (subTrieRoot) 不同。子subTrie
中單個賬戶的變更已從承諾協議中抽象出來。
這比現在的情況要簡單得多,因為現在的情況是,預協商者需要對交易涉及的每個位置,在多次嘗試中提交後狀態差異。現在,每筆交易都會被壓縮成一個單一的、整齊打包的subTrieRoot
。
然而,這種方法需要引入另一個 trie,這增加了 EIP 的複雜性。
提議的 EIP 變更(更簡單)
假設The Block塊頭仍然提交到 RLP 編碼的BAL哈希,稍微重構一下BAL佈局就可以大大簡化提交。本提案使用bal_index
而不是賬戶來索引BAL ,這樣BAL就被編碼為 RLP 編碼的List[TransactionDiff]
。
TransactionDiff
將包含給定交易的所有 nonce、餘額、存儲和代碼更改。這將把多個AccountChanges
值中的承諾合併到一個TransactionDiff
中,其功能類似於先前提案中的subTrieRoot
。
簡潔地提交TransactionDiff
將使連續區塊構建更加現實,因為錢包和 PBS 管道的其餘部分可以在應用執行預置後跟上最新狀態。
BAL 的其他好處
主流 Rollup 已經在嘗試通過諸如Shreds 、 Flashblocks和Frags等承諾方案來加快確認速度,以改善用戶體驗。目前,這些方案依賴於第三方實現,並且承諾需要完全信任排序器。
BAL 標準化了這種模式:使用 BAL 的 rollup 不再需要維護自己的自定義承諾方案,用戶可以更輕鬆地從可信承諾中受益。實際上,BAL 體現了實踐中已經開始發生的事情。
Vitalik 指出, BAL作為一種 MPT 方法,允許部分無狀態節點僅驗證他們關心的 BAL 部分的證明,即我的餘額在The Block過程中是如何變化的。
執行預置是有效載荷分塊等思想的非協議前身。