详解 OP Stack Rollup 流程及对应代码
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">原文作者:Rayer </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">原文<span style="color: black;">源自</span>:登链社区</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Optimism Bedrock 是 OP Stack 的当前版本。Bedrock 版本<span style="color: black;">供给</span>了用于<span style="color: black;">起步</span>生产质量的 Optimistic Rollup 区块链的工具。此时,OP Stack <span style="color: black;">区别</span>层的 API 仍然与 Stack 的 Rollup 配置紧密耦合。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Op-stack <span style="color: black;">重点</span>的 rollup 由两个服务来承担。</p>
op-batcher:负责将每隔一段时间读取 sequencer 上的交易内容,rollup 到链上 DA
op-proposer:负责将交易状态 rollup 到合约。
Rollup 架构
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q9.itc.cn/q_70/images03/20240606/9fe5cf357de849799e9f6cc07c55cc4d.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">op-batcher </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">op-batcher 执行流程图</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q0.itc.cn/q_70/images03/20240606/ea66664faf9f4a35877e39a889716f0d.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">loadBlocksInfoState 执行<span style="color: black;">规律</span></strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">loadBlocksInfoState 负责读取,从前一次读取的块<span style="color: black;">起始</span>的所有块,即还未读取的块。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其整体流程如下</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q1.itc.cn/q_70/images03/20240606/4fe0c4ff2a9445b5a7b5741213f3e167.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">代码如下:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q7.itc.cn/q_70/images03/20240606/92d5c89b8824478ea2928614bfe80d33.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q0.itc.cn/q_70/images03/20240606/801771703733488cb9bbe169344cd973.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q6.itc.cn/q_70/images03/20240606/6ad1baea176646a0a3aac716a11c32c8.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">loadBlocksIntoState 完<span style="color: black;">成为了</span>以下动作</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">1、获取 sequencer 中的同步状态</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">2、153 行</strong>,调用calculateL2BlockRangeToStore函数</p>
calculateL2BlockRangeToStore 获取并判断需要提交的最新 L2 的 start 和 end 块号,<span style="color: black;">初始</span>的区块为 L2 当前安全的最高块,结束区块为 L2 当前最高的不安全的区块。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">3、164 行</strong>,拿到提交的<span style="color: black;">起始</span>块和结束区块之后,从<span style="color: black;">初始</span>区块<span style="color: black;">起始</span>获取区块信息,调用loadBlockIntoState 函数获取区块</p>
loadBlockIntoState <span style="color: black;">检测</span>区块信息以及 geth 信息,无误后,<strong style="color: blue;">在 200 行</strong>,调用 AddL2Block 函数将区块加到 channelManager 的 blocks *types.Block 中。<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">4、165 行至 168 行</strong>,校验区块<span style="color: black;">是不是</span>需要重新提交,若需要,将 l.lastStoredBlock 置成 eth.BlockID{};173 行,否则就将 l.lastStoredBlock 置成 eth.ToBlockID(block);latestBlock 置成 block;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">5、177 行</strong>,L2BlockToBlockRef 从 L2 块引用源中提取基本的 L2BlockRef 信息,<span style="color: black;">按照</span>区块号判断必要时回退到创世信息</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">publishStateToL1 执行<span style="color: black;">规律</span></strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">publishStateToL1 将队列中的所有交易提交到 L1,直到队列中<span style="color: black;">无</span>交易<span style="color: black;">或</span><span style="color: black;">显现</span>错误为止。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">代码如下:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q5.itc.cn/q_70/images03/20240606/c1a8fe968c7146508ab015b82b29ccbd.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">1、publishStateToL1 会循环将队列里的交易发送到 Layer1 网络。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">2、377 行</strong>调用publishTxToL1。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q5.itc.cn/q_70/images03/20240606/3a081fd322e24fc1b3f702db5999913c.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">publishTxToL1 是提交单个交易到 L1 的<span style="color: black;">规律</span></strong>,publishTxToL1 <span style="color: black;">办法</span>获取要提交的数据数据构建交易发送到 Layer1 网络,并将发送出去的交易扔到 receiptCh chan TxReceipt channel 里面。</p>
<strong style="color: blue;">429 行</strong>,l1Tip:获取当前 L1 提示<span style="color: black;">做为</span> L1BlockRef。假定传递的上下文是生命周期上下文,<span style="color: black;">因此呢</span>它在内部<span style="color: black;">运用</span>网络超时进行包装。
<strong style="color: blue;">434 行</strong>,recordL1Tip:将上一个 L1BlockRef 更换成 l1Tip 获取到的最新的 L1BlockRef<strong style="color: blue;">437 行</strong>,TxData:收集需要 rollup 的交易数据;TxData 返<span style="color: black;">回复</span>提交给 L1 的下一个 tx 数据。<span style="color: black;">日前</span>,<span style="color: black;">每一个</span>事务仅<span style="color: black;">运用</span>一帧。<span style="color: black;">倘若</span>待处理的通道已满,则仅返回该通道的剩余帧,直到成功完全发送到 L1。<span style="color: black;">倘若</span><span style="color: black;">无</span>挂起的帧,它将返回 io.EOF。
<strong style="color: blue;">447 行</strong>,sendTransaction 将交易发送到一层,并把交易发送状态更新到 receiptCh chan TxReceipt channel 里面;sendTransaction <span style="color: black;">运用</span>给定的「数据」创建交易并将其提交到批处理收件箱<span style="color: black;">位置</span>。它<span style="color: black;">日前</span><span style="color: black;">运用</span>底层的「txmgr」来处理交易发送和价格管理。这是一种阻塞<span style="color: black;">办法</span>。<span style="color: black;">不该</span><span style="color: black;">同期</span>调用它。<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">handleReceipt</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">handleReceipt 获取从 channel 处理交易的状态,并将成功处理的交易从 channel 里面移除。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">代码如下:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">op-proposer</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">执行流程图</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q7.itc.cn/q_70/images03/20240606/fdb0d87401a148dc8c68f9becc709d5c.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">仔细</span>执行流程 </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q9.itc.cn/q_70/images03/20240606/555cd93bf6ff45d0ae5e383f8703da1f.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">FetchNextOutputInfo</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">FetchNextOutputInfo: 获取 L2 上的区块的 output,方便后续组装提交。返回的 output 结构如下:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">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"}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">代码如下:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q9.itc.cn/q_70/images03/20240606/678b06222ea64c1aaf79550b3c0b97a2.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<strong style="color: blue;">224 行</strong>,NextBlockNumber:获取下一批次需要提交的区块区间,区间计算为 latestBlockNumber + SUBMISSION_INTERVAL SUBMISSION_INTERVAL 的值<span style="color: black;">能够</span>在<span style="color: black;">安排</span> L2OutputOracle 合约的时候指定。<strong style="color: blue;">230 行</strong>,调用FetchCurrentBlockNumber,<span style="color: black;">得到</span>当前区块的区块号
<strong style="color: blue;">236 行至 241 行</strong>, 上面<span style="color: black;">检测</span>完 nextCheckpointBlock 符合规则之后,调用FetchOutput去 L2 上获取需要提交的 stateRoot
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">FetchCurrentBlockNumber 代码如下:</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q7.itc.cn/q_70/images03/20240606/2ea1e609a550476cbb2fd3fc53225e9c.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">1、254 行</strong>,SyncStatus:获取 L2 块的 SafeL2 和 FinalizedL2 的状态和块信息,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">FetchOutput 代码如下:</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q1.itc.cn/q_70/images03/20240606/f280e6aacb47469ea1b7faffa69945bc.jpeg" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">2、279 行</strong>,OutputAtBlock: <span style="color: black;">按照</span>块高获取 output, 里面<span style="color: black;">包括</span> stateRoot,<span style="color: black;">这儿</span><span style="color: black;">最后</span>是调用 eth_getProof 去计算并获取 stateRoot,代码调用流程<span style="color: black;">能够</span>参考上图。提示: <span style="color: black;">这儿</span>并不是一个块提交一次 stateRoot, 而是<span style="color: black;">按照</span> SUBMISSION_INTERVAL 配置的值来计算一批块的 stateRoot,<span style="color: black;">最后</span>将 stateRoot 提交到 L2OutputOracle 合约</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">send Transaction</strong></p>
sendTransaction:<span style="color: black;">运用</span> output 构建 stateRoot 提交交易,将交易提交到一层链, 下面是交易打包的数据细节
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">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))</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">代码如下:<a style="color: black;"><span style="color: black;">返回<span style="color: black;">外链论坛:www.fok120.com</span>,查看<span style="color: black;">更加多</span></span></a></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">责任编辑:网友投稿</span></p>
可以发布外链的网站 http://www.fok120.com/ 你字句如珍珠,我珍藏这份情。
页:
[1]