
詳解 OP Stack Rollup 流程及對應代碼
TechFlow Selected深潮精選

詳解 OP Stack Rollup 流程及對應代碼
OP Stack 是標準化、共享和開源的開發堆棧,為 Optimism 提供支持,由 Optimism Collective 維護。
撰文:Rayer
Optimism Bedrock 是 OP Stack 的當前版本。Bedrock 版本提供了用於啟動生產質量的 Optimistic Rollup 區塊鏈的工具。此時,OP Stack 不同層的 API 仍然與 Stack 的 Rollup 配置緊密耦合。
Op-stack 主要的 rollup 由兩個服務來承擔。
-
op-batcher:負責將每隔一段時間讀取 sequencer 上的交易內容,rollup 到鏈上 DA
-
op-proposer:負責將交易狀態 rollup 到合約。
Rollup 架構
op-batcher
op-batcher 執行流程圖

loadBlocksInfoState 執行邏輯
loadBlocksInfoState 負責讀取,從前一次讀取的塊開始的所有塊,即還未讀取的塊。
其整體流程如下

代碼如下:



loadBlocksIntoState 完成了以下動作
1、獲取 sequencer 中的同步狀態
2、153 行,調用calculateL2BlockRangeToStore函數
-
calculateL2BlockRangeToStore 獲取並判斷需要提交的最新 L2 的 start 和 end 塊號,起始的區塊為 L2 當前安全的最高塊,結束區塊為 L2 當前最高的不安全的區塊。
3、164 行,拿到提交的開始塊和結束區塊之後,從起始區塊開始獲取區塊信息,調用loadBlockIntoState 函數獲取區塊
-
loadBlockIntoState 檢查區塊信息以及 geth 信息,無誤後,在 200 行,調用
AddL2Block函數將區塊加到 channelManager 的 blocks []*types.Block 中。
4、165 行至 168 行,校驗區塊是否需要重新提交,若需要,將 l.lastStoredBlock 置成 eth.BlockID{};173 行,否則就將 l.lastStoredBlock 置成 eth.ToBlockID(block);latestBlock 置成 block;
5、177 行,L2BlockToBlockRef從 L2 塊引用源中提取基本的 L2BlockRef 信息,根據區塊號判斷必要時回退到創世信息
publishStateToL1 執行邏輯
publishStateToL1 將隊列中的所有交易提交到 L1,直到隊列中沒有交易或者出現錯誤為止。
代碼如下:

1、publishStateToL1 會循環將隊列裡的交易發送到 Layer1 網絡。
2、377 行調用publishTxToL1。

publishTxToL1 是提交單個交易到 L1 的邏輯,publishTxToL1 方法獲取要提交的數據數據構建交易發送到 Layer1 網絡,並將發送出去的交易扔到 receiptCh chan TxReceipt[T] channel 裡面。
-
429 行,
l1Tip:獲取當前 L1 提示作為 L1BlockRef。假定傳遞的上下文是生命週期上下文,因此它在內部使用網絡超時進行包裝。 -
434 行,
recordL1Tip:將上一個 L1BlockRef 更換成 l1Tip 獲取到的最新的 L1BlockRef -
437 行,
TxData:收集需要 rollup 的交易數據;TxData 返回應提交給 L1 的下一個 tx 數據。目前,每個事務僅使用一幀。如果待處理的通道已滿,則僅返回該通道的剩餘幀,直到成功完全發送到 L1。如果沒有掛起的幀,它將返回 io.EOF。 -
447 行,
sendTransaction將交易發送到一層,並把交易發送狀態更新到 receiptCh chan TxReceipt[T] channel 裡面;sendTransaction 使用給定的「數據」創建交易並將其提交到批處理收件箱地址。它目前使用底層的「txmgr」來處理交易發送和價格管理。這是一種阻塞方法。不應同時調用它。
handleReceipt
handleReceipt 獲取從 channel 處理交易的狀態,並將成功處理的交易從 channel 裡面移除。
代碼如下:
op-proposer
執行流程圖
詳細執行流程

FetchNextOutputInfo
FetchNextOutputInfo: 獲取 L2 上的區塊的 output,方便後續組裝提交。返回的 output 結構如下:
type OutputResponse struct {Version Bytes32 json:"version"OutputRoot Bytes32 json:"outputRoot"BlockRef L2BlockRef json:"blockRef"WithdrawalStorageRoot common.Hash json:"withdrawalStorageRoot"StateRoot common.Hash json:"stateRoot"Status *SyncStatus json:"syncStatus"}
代碼如下:

-
224 行,NextBlockNumber:獲取下一批次需要提交的區塊區間,區間計算為 latestBlockNumber() + SUBMISSION_INTERVAL SUBMISSION_INTERVAL 的值可以在部署 L2OutputOracle 合約的時候指定。
-
230 行,調用
FetchCurrentBlockNumber,獲得當前區塊的區塊號 -
236 行至 241 行, 上面檢查完 nextCheckpointBlock 符合規則之後,調用
FetchOutput去 L2 上獲取需要提交的 stateRoot
FetchCurrentBlockNumber 代碼如下:

1、254 行,SyncStatus:獲取 L2 塊的 SafeL2 和 FinalizedL2 的狀態和塊信息,
FetchOutput 代碼如下:

2、279 行,OutputAtBlock: 根據塊高獲取 output, 裡面包含 stateRoot,這裡最終是調用 eth_getProof 去計算並獲取 stateRoot,代碼調用流程可以參考上圖。提示: 這裡並不是一個塊提交一次 stateRoot, 而是根據 SUBMISSION_INTERVAL 配置的值來計算一批塊的 stateRoot,最終將 stateRoot 提交到 L2OutputOracle 合約
send Transaction
-
sendTransaction:使用 output 構建 stateRoot 提交交易,將交易提交到一層鏈, 下面是交易打包的數據細節
return abi.Pack( "proposeL2Output", output.OutputRoot, new(big.Int).SetUint64(output.BlockRef.Number), output.Status.CurrentL1.Hash, new(big.Int).SetUint64(output.Status.CurrentL1.Number))
代碼如下:

歡迎加入深潮 TechFlow 官方社群
Telegram 訂閱群:https://t.me/TechFlowDaily
Twitter 官方帳號:https://x.com/TechFlowPost
Twitter 英文帳號:https://x.com/BlockFlow_News















