ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Optimism op-node batch_decoder:从 L1 批次交易中还原 Channel 的离线调试工具

Optimism op-node batch_decoder:从 L1 批次交易中还原 Channel 的离线调试工具 Optimism op-node batch_decoder从 L1 批次交易中还原 Channel 的离线调试工具【免费下载链接】optimismOptimism is Ethereum, scaled.项目地址: https://gitcode.com/GitHub_Trending/op/optimismbatch_decoder是 Optimism monorepo 中op-node自带的一个离线调试工具用于排查 batcher批次提交器与 op-node 之间的数据链路它拉取链上发往 Batch Inbox 合约的交易将其解码为 frame再重组为 channel最终还原出其中承载的批次。读完本文你将掌握该工具的三阶段工作流fetch / reassemble / force-close、各命令行参数的含义与默认值、落盘 JSON 的数据结构以及一套可直接复制的jq分析命令用于定位批次提交异常。设计哲学基于磁盘 JSON 的两阶段处理batch_decoder的设计目标是简单且灵活它把尽可能多的数据分析工作交给其他工具尤其是jq核心思路是围绕磁盘上的 JSON 文件做文章见 README第一阶段fetch触网拉取指定 L1 块区间内所有发往 batch inbox 地址的交易。这一步就把交易解码成 frame并连同元信息一起记录。第二阶段reassemble离线把缓存目录里的 frame 重新组装成 channel并写出带元数据的 channel 文件——这一步完全不触网因此可以反复运行、自由调整。这种拆分让网络请求只发生一次即使后续分析需要多次迭代改解码逻辑、换 jq 查询fetch 的结果都可以复用。两个阶段的产物落盘后文件命名即天然索引——交易文件以交易哈希命名channel 文件以 Channel ID 命名。数据模型交易与 channel 的 JSON 结构理解落盘 JSON 是熟练使用该工具的前提两个结构分别在 fetch/fetch.go 与 reassemble/reassemble.go 中定义。TransactionWithMetadatafetch 产物每个被识别为批次提交的交易写成一个tx_hash.json字段包括字段JSON key含义TxIndextx_index交易在区块内的索引InboxAddrinbox_address批次 inbox 地址BlockNumber/BlockHash/BlockTimeblock_number等包含区块信息Sender/ValidSendersender/valid_sender交易发送者及其是否为已知 batcherFrames/ValidFramesframes/valid_data解码出的 frame 列表、每段数据是否解析成功FrameErrsframe_parse_errorframe 解析错误信息Txtx原始交易完整序列化ChannelWithMetadatareassemble 产物每个重组出的 channel 写成一个channel_id.json字段包括idChannel IDis_readychannel 是否已收到闭合帧是否 readyinvalid_frames/invalid_batchesframe 拼接或批次解码过程中是否出现异常frames每个 frame 附带transaction_hash、inclusion_block、timestamp、block_hash等元数据batches/batch_types/compr_algos从 channel 中还原出的批次对象、批次类型序列、压缩算法序列。命令一fetch —— 拉取并解码 L1 批次交易batch_decoder fetch拉取给定 L1 块区间内发往 batch inbox 地址的全部交易以交易哈希为文件名写成 JSON。入口实现在 main.go核心逻辑在 Batches。参数说明参数必填默认值说明--start是-起始块号含--end是-结束块号不含--l1是-L1 RPC URL支持环境变量L1_RPC--l1.beacon否-L1 Beacon 节点 HTTP 端点支持环境变量L1_BEACON--l2-chain-id二选一-L2 链 ID从 superchain-registry 加载 inbox 与 sender--inbox/--sender二选一-手动指定 Batch Inbox 地址与 Batcher 地址--out否/tmp/batch_decoder/transactions_cache交易 JSON 缓存目录--concurrent-requests否10抓取 L1 时的并发度两种定位批次链路的方式提供--l2-chain-id时工具调用 LoadOPStackRollupConfig 从 superchain-registry 中取出BatchInboxAddress与Genesis.SystemConfig.BatcherAddr省去手工查合约地址否则必须同时提供--inbox与--sender两者缺一会直接报错 either --l2-chain-id or both --inbox and --sender must be set。源码层面的关键细节并发抓取Batches使用errgroup.SetLimit(concurrentRequests)限制并发逐块调用fetchBatchesPerBlock每块有独立的 10 秒超时。Blob 交易Ecotone 之后post-ecotone 的 channel frame 走 EIP-4844 blob 交易承载。fetch 时若遇到 blob 交易而未提供--l1.beacon会打印 Unable to handle blob transaction 并跳过若提供了 Beacon 端点则通过beacon.GetBlobsByHash取回 blob 并还原为数据段。因此分析 Ecotone 之后的主网数据时必须配置--l1.beacon。frame 解码对每段数据调用 ParseFrames。L1 交易数据的序列化格式为data DerivationVersion0 Frame(s)要求首字节为 version 0、至少解析出一个 frame 且无剩余字节。有效性标记发送者不在BatchSenders白名单中或任一数据段解析失败都会把该交易标记为 invalid但仍写入磁盘ValidSender/ValidFrames字段记录原因方便事后排查。命令二reassemble —— 离线重组 channel 并解码批次batch_decoder reassemble遍历缓存目录中所有 frame将其按 Channel ID 分组重组为 channel写出以 Channel ID 命名的 JSON 文件每个 channel 可以包含多个批次。核心实现在 Channels。参数说明参数必填默认值说明--in否/tmp/batch_decoder/transactions_cachefetch 输出的交易缓存目录--out否/tmp/batch_decoder/channel_cachechannel JSON 输出目录--l2-chain-id二选一-从 superchain-registry 加载 rollup 配置--rollup-config二选一rollup.json本地 rollup 配置 JSON 路径不使用--l2-chain-id时必须设置重组与批次解码流程ProcessFrames 对每个 channel 执行以下逻辑排序frame 先按块号区块内交易索引排序以匹配链上派生顺序见 LoadFrames再按FrameNumber排序。回放加帧逐个调用ch.AddFrame若 channel 已 ready 却还有多余帧、或加帧报错标记invalid_frames。批次解码仅当 channel ready 时用BatchReader迭代读取批次并依据批次类型分派Singular 批次直接derive.GetSingularBatch解出父哈希、epoch、交易列表等Span 批次调用 DeriveSpanBatch 做本地派生——这正是 README 中提到的对 span batchbatch_decoder依据 rollup 配置中的L2BlockTime、L2GenesisTime与L2ChainID本地推导出完整批次main.go 中L2ChainID、L2GenesisTime、L2BlockTime均取自 rollup 配置对 singular 批次则不做派生、按原样存储。结果落盘无论成功与否都写出ChannelWithMetadata失败情况体现在invalid_batches、invalid_frames布尔字段上而不是报错退出——这对批量分析非常友好。命令三force-close —— 生成强制闭合交易数据batch_decoder force-close生成一段可直接从 batcher 地址发往 batch inbox 的交易数据用于强制闭合指定 channel从而让后续 channel 无需等待超时即可被读取。实现见 main.go。参数说明参数必填默认值说明--id是-要闭合的 Channel ID--inbox否0x0000...0000零地址Batch Inbox 地址零地址表示不过滤、加载缓存中全部 frame--in否/tmp/batch_decoder/transactions_cachefetch 输出的交易缓存目录它依赖fetch的结果因为闭合交易的数据形态取决于 channel 的链上状态见 ForceCloseTxDatachannel 尚未闭合帧序列中没有IsLast帧直接生成一个指向该 channel 的空闭合帧frame 0 位置、IsLasttrue即可channel 已闭合但缺帧需要为[0, closeNumber]中缺失的每个 frame 编号各生成一个空帧IsLastfalse补齐后再闭合——这就是 README 强调的已闭合但缺帧时帧的生成方式与简单闭合不同的原因。生成的交易数据以十六进制打印到 stdout可复制后用 batcher 钱包签名发送。注意该命令只是创建交易数据实际广播、签名、gas 费用由操作者自行完成。jq 分析手册README 原版命令完整保留jq是与batch_decoder搭配的核心分析工具以下是 README 提供的速查命令$TX_DIR为 fetch 输出目录、$CHANNEL_DIR/$CHANNEL_FILE为 reassemble 输出# Pretty print a JSON file jq . $JSON_FILE # Print the number of valid invalid transactions jq .valid_data $TX_DIR/* | sort | uniq -c # Select all transactions that have invalid data then print the transaction hash jq select(.valid_data false)|.tx.hash $TX_DIR # Select all channels that are not ready and then get the id and inclusion block tx hash of the first frame. jq select(.is_ready false)|[.id, .frames[0].inclusion_block, .frames[0].transaction_hash] $CHANNEL_DIR # Show all of the frames in a channel without seeing the batches or frame data jq del(.batches)|del(.frames[]|.frame.data) $CHANNEL_FILE # Show all batches (without timestamps) in a channel jq .batches|del(.[]|.Transactions) $CHANNEL_FILE典型排查路径先用fetch统计 invalid 交易占比确认是发送者异常还是数据损坏再对未 ready 的 channel 定位其首帧的包含块与交易哈希回到 L1 上核对 batcher 行为最后用最后两条命令在不被 frame 原始数据淹没的前提下检查 channel 骨架。已知局限与 RoadmapREADME 末尾给出了两条规划中的增强对应内部任务 CLI-3565、CLI-3560将批次从 channel 中进一步拆分存储进ChannelWithMetadata记录交易字节用量、未压缩总字节数与压缩后字节数二者并不相同反转ChannelWithMetadata的索引方式使块号/块哈希能映射到提交它们的 channel。此外从源码结构看当前版本还有几点适用边界值得注意fetch 只处理 version 0 的 frame 序列化格式ParseFrames 的注释说明当前仅支持该版本--l2-chain-id依赖仓库内嵌的 superchain-registry 配置因此目标链需已收录在 registry 中未收录的链应改用--inbox/--sender与--rollup-config手动指定。整体而言batch_decoder是一个以JSON 落盘 离线二次加工为骨架的实用排障工具fetch 保证链上事实只抓取一次reassemble 提供可重复的解码视角force-close 则把卡住的 channel转化为一条可直接发送的修复交易。【免费下载链接】optimismOptimism is Ethereum, scaled.项目地址: https://gitcode.com/GitHub_Trending/op/optimism创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表