Mantle节点、Batcher、Proposer和工具的增量审计

本次审计涵盖了op-node, op-batcher, op-proposer, op-chain-ops和op-service组件的三个pull request,共发现12个问题,包括1个中等严重性问题,以及多个低严重性和提示信息,重点关注MantleDA集成和代码质量提升,建议加强QA流程和测试覆盖。

目录

概要

TypeLayer 2TimelineFrom 2024-02-12To 2024-02-28LanguagesGoTotal Issues12 (3 resolved)Critical Severity Issues0 (0 resolved)High Severity Issues0 (0 resolved)Medium Severity Issues1 (1 resolved)Low Severity Issues9 (0 resolved)Notes & Additional Information2 (2 resolved)

范围

我们审计了三个拉取请求,范围包括 op-nodeop-batcherop-proposerop-chain-opsop-service 组件:

拉取请求 #72,从基础提交 68f2533 到头部提交 bb0ff70。范围包括以下文件:

 mantle-v2
├── op-batcher
│   ├── batcher
│   │   ├── batch_submitter.go
│   │   ├── channel_manager.go
│   │   ├── config.go
│   │   ├── driver_da.go
│   │   └── driver.go
│   ├── common
│   │   ├── types.go
│   │   └── utils.go
│   ├── flags
│   │   └── flags.go
│   └── metrics
│       ├── metrics.go
│       └── noop.go
├── op-chain-ops
│   ├── cmd
│   │   ├── check-migration
│   │   │   └── main.go
│   │   ├── op-migrate
│   │   │   └── main.go
│   │   ├── rollover
│   │   │   └── main.go
│   │   └── withdrawals
│   │       └── main.go
│   ├── crossdomain
│   │   ├── encoding.go
│   │   ├── hashing.go
│   │   ├── legacy_abi.go
│   │   ├── legacy_withdrawal.go
│   │   ├── message.go
│   │   ├── migrate.go
│   │   ├── params.go
│   │   ├── withdrawal.go
│   │   ├── withdrawals.go
│   │   └── witness.go
│   ├── eof
│   │   └── eof_crawler.go
│   ├── ether
│   │   ├── addresses.go
│   │   ├── cli.go
│   │   ├── migrate.go
│   │   └── storage.go
│   ├── genesis
│   │   ├── check.go
│   │   ├── config.go
│   │   ├── db_migration.go
│   │   ├── genesis.go
│   │   ├── layer_one.go
│   │   ├── layer_two.go
│   │   └── setters.go
│   ├── immutables
│   │   └── immutables.go
│   └── util
│       └── util.go
├── op-node
│   ├── chaincfg
│   │   └── chains.go
│   ├── cmd
│   │   └── genesis
│   │       └── cmd.go
│   ├── eth
│   │   ├── sync_status.go
│   │   └── types.go
│   ├── flags
│   │   └── flags.go
│   ├── metrics
│   │   └── metrics.go
│   ├── node
│   │   ├── config.go
│   │   └── node.go
│   ├── rollup
│   │   ├── da
│   │   │   └── datastore.go
│   │   ├── derive
│   │   │   ├── attributes.go
│   │   │   ├── calldata_source.go
│   │   │   ├── channel_bank.go
│   │   │   ├── channel_in_reader.go
│   │   │   ├── deposit_log.go
│   │   │   ├── engine_consolidate.go
│   │   │   ├── engine_queue.go
│   │   │   ├── error.go
│   │   │   ├── frame.go
│   │   │   ├── l1_block_info.go
│   │   │   ├── l1_retrieval.go
│   │   │   ├── l2block_util.go
│   │   │   ├── payload_util.go
│   │   │   ├── pipeline.go
│   │   │   └── system_config.go
│   │   ├── driver
│   │   │   ├── driver.go
│   │   │   └── state.go
│   │   ├── sync
│   │   │   ├── config.go
│   │   │   └── start.go
│   │   └── types.go
│   ├── service.go
│   ├── service_mantle.go
│   ├── sources
│   │   └── sync_client.go
│   └── withdrawals
│       └── utils.go
└── op-service
    ├── crypto
    │   └── signature.go
    └── txmgr
        └── cli.go

拉取请求 #89,从基础提交 5e3886c 到头部提交 76959dd。范围包括以下文件:

 mantle-v2
└── op-node
    └── rollup
        └── derive
            ├── deposit_log.go
            └── l1_block_info.go

拉取请求 #98,从基础提交 0f0861b 到头部提交 365f02a。范围包括以下文件:

 mantle-v2
└── op-chain-ops
    ├── genesis
    │   └── config.go
    └── immutables
        └── immutables.go

系统概览

Mantle V2 是一种以太坊二层(L2)扩展解决方案,它使用欺诈证明而不是有效性证明来保障安全。 该协议旨在提供低交易费用和高吞吐量,同时保持完全的 EVM 兼容性。 Mantle V2 构建于以太坊之上,使用 OP Stack,因此与 Optimism 有许多相似之处。 op-nodeop-batcherop-proposer 组件共同构成共识层,该共识层保持链的运行并将所有其他一层和二层组件粘合在一起(尽管不存在以太坊理解的共识)。 将执行层 op-geth 添加到此集合中,就构成了 Mantle 网络。

op-node 组件负责派生二层区块链,这意味着它监听特定的一层事件和二层交易,并通过不断将此数据分组到批次中并将其传递到执行客户端以生成二层块来保持链的运行。 反过来,op-batcher 组件监听 op-node 以获取新的批次,将这些批次分组到通道中,压缩它们,将它们拆分为帧,并将帧发布到数据可用性层。

op-proposer 组件监听 op-node 以获取所谓的二层输出根,这些输出根是Merkle根。 然后将这些根发布到一层,以便一层上的智能合约可以接收来自二层的消息。 这包括 ERC-20 代币桥接以及通用消息传递。 op-chain-ops 组件是一种工具,有助于链的管理。 op-service 组件包含代码库其他部分使用的通用实用程序。

变更概要

下面介绍按拉取请求和组件分组的范围内组件的变更摘要。

拉取请求 #72

op-node

  • MantleDA 现在用作数据可用性提供程序。 在此之前,使用的是以太坊 calldata。
  • 引入了基础费用参数。 它在以太坊上的 SystemConfig 合约中设置,然后作为每个 L2 块的第一个交易的一部分以及其他 SystemConfig 参数传递到执行层。
  • requestsChannelBufferSize 常数从 128 增加到 1024,并且更改了处理相应通道的逻辑。
  • unsafeL2PayloadsChannelBufferSize 常数从 10 增加到 4096,并且更改了处理相应通道的逻辑。
  • 合并了来自上游存储库的几项改进。

op-batcher

  • MantleDA 现在用作数据可用性提供程序。 在此之前,使用的是以太坊 calldata。

op-proposer

  • 无更改

op-chain-ops

  • 添加了对 GasPriceOracle 合约的支持。
  • 添加了对 MNT 作为原生代币的支持。

op-service

  • op-service 组件的更新包括支持以太坊操作中的 Google Cloud Platform (GCP) 的密钥管理服务 (KMS)。 如果期望使用 Cloud HSM,则引入了新的配置参数以简化流程。

拉取请求 #89

op-node

  • 添加了已存入交易事件的新版本。 特别是,添加了编组和解组功能。

op-batcher、op-proposer、op-chain-ops 和 op-service

  • 无更改。

拉取请求 #98

op-chain-ops

  • 添加了 L1_MNT_ADDRESS 常数。

op-node、op-batcher、op-proposer 和 op-service

  • 无更改。

安全模型与信任假设

在此次参与中,MantleDA 被视为一个黑盒,因为我们没有获得对系统文档、测试或开发实例的访问权限。 同样,我们也假设范围内代码正确使用 MantleDA。

话虽如此,MantleDA 是一项新兴技术,因此出现错误的几率更高。 从 MantleDA 中断或故障中恢复的当前方法是停止排序器,在配置文件中将数据可用性切换到以太坊 calldata,然后再次启动排序器。 这意味着没有自动回退机制,并且如果发生此类中断,Mantle 区块链将会失去活性,直到使用新配置重新启动排序器。

特权角色

op-batcher 组件使用私钥与 MantleDA 合约交互,该合约定义了应使用哪些 MantleDA blob 来派生二层链。

中等严重性

ID 为 1 的数据无法从 Mantle DA 检索

OP-NodeRetrievalFramesFromDa 函数实现了从 Mantle DA 检索帧的逻辑。 它需要一个 dataStoreId 值,该值经过检查以验证它是否等于或小于 0。 由于 calldata_source 使用dataStoreId 减 1 调用 RetrievalFramesFromDa,因此无法尝试使用等于 1 的 dataStoreId 从 Mantle DA 检索数据。

考虑删除 RetrievalFramesFromDa 函数中的检查以允许处理值为 0 的 dataStoreId。 此外,由于 dataStoreId 的类型为 uint32,因此不能小于 0,因此该检查变得不必要。

更新:拉取请求 #117 中已解决。

低等严重性

RequestL2Range 不会返回错误如果通道已满

RequestL2Range 函数对一系列 L2 块进行排队,并且如果通道已满则提前返回。 但是,在这种情况下,它不会返回错误,这意味着将处理部分数据。

考虑在通道已满的情况下返回错误,以便调用者了解情况。

更新: 已确认,未解决。 Mantle 团队表示:

不是有效的问题。

如果没有新行,Witness Data Reader 会跳过最后一行

OP-Chain-Ops 的 ReadWitnessData 函数利用 bufioNewReader 迭代文件并检索所有条目。 为了读取每一行,该函数采用 ReadString,该函数读取直到遇到新行。 但是,这种方法存在一个问题 - 如果文件的最后一行缺少新行字符(文本文件 witness.txt 就是这种情况),则读取器将触发 EOF 错误, 导致提前跳出循环,未能读取最后一行。

考虑重新设计函数逻辑,以便即使最后一行没有以新行结尾,也可以正确读取最后一行。

更新: 已确认,未解决。 Mantle 团队表示:

已确认,仅用于升级,不会修复。

缺少类型转换

OP-Chains-Ops 的 NewWithdrawal 函数返回一个填充了值的 Withdrawal 结构体。 类型为 hexutil.BytesData 字段被赋值为类型为 []bytedata。 但是,赋值的值应首先使用 hexutil.Bytes 函数转换为正确的类型。

考虑将 data 参数转换为 hexutil.Bytes 类型。

更新: 未解决。 Mantle 团队表示:

不是有效的问题。

测试崩溃并失败

测试套件没有彻底覆盖提议的更改。 此外,有多个测试失败,使得难以确认实现的正确性。 以下组件需要额外的测试:

  • op-node
  • op-batcher
  • op-chain-ops

考虑审查上述组件的测试套件以提高代码质量。

更新: 未解决。

缺少输入验证

类型为 big.IntBaseFee 参数检查是否为 nil。 但是,big.Int 可以是负数,这对于 BaseFee 来说没有意义,因为它应该始终为正数。

考虑检查 BaseFee 参数是否为 nil 以及是否为正数,就像其他 big.Int 参数一样(例如,链 ID 经过验证是否大于 0 且不等于 0)。

更新: 已确认,将解决。

OP-Batcher 启动时 Mantle DA 状态未清除

启动 OP-Batcher 后,状态已清除,但 Mantle DA 状态未清除。

考虑调用 clearMantleDAStatus 函数来清除 Mantle DA 状态。

更新: 已确认,未解决。

使用 Sleep 等待通道准备就绪

使用 sleep 等待 0.1 ms 以使 sequencerChstepReqCh 准备就绪。 虽然这可能会缓解测试环境中的问题,但它在生产环境中的行为可能会有所不同,在生产环境中,负载可能会有所不同,因此 sleep 时间可能无法提供所需的效果。

考虑重构代码以避免使用 sleep,而是使用更可靠的机制来同步通道。

更新: 未解决。 Mantle 团队表示:

不是有效的问题。

缺少联系 Mantle DA 的连接超时

已实现的到 Mantle DA 的连接缺少定义的超时选项。 当服务器接受连接但未能响应调用时,这可能会导致问题。 存在以下到 Mantle DA 的连接:

考虑将超时机制添加到以上列出的连接。

更新: 已确认,将解决。

与 Mantle DA 的未加密连接

已实现的到 Mantle DA 的连接是未加密的。 在生产环境中,通常建议加密连接。 存在以下到 Mantle DA 的未加密连接:

考虑改用加密连接。

更新: 已确认,将解决。

注释 & 补充信息

排版错误

在整个代码库中,发现了几个排版错误:

考虑解决上述排版错误。

更新:拉取请求 #124 中已解决。

代码清晰度

在整个代码库中,发现了几个冗余和不清晰的代码实例:

  • datastore.go 中定义的 NewMantleDataStore 函数始终将 error 作为 nil 返回。 因此,没有必要返回它并稍后检查它
  • NewMantleDataStoreConfig 函数返回一个配置和一个错误。 但是,错误始终为 nil,这使得返回错误变得不必要。
  • MockDataStoreConfig 变量未在任何地方使用,应将其删除。
  • marshalDepositVersion1 函数未在任何地方使用,可以将其删除。
  • getFramesByDataStoreId 函数中,从回复中检索数据两次。 考虑调用 GetData 一次,然后在 log.Debug 和 return 语句中使用它。
  • getFramesFromIndexerByDataStoreId 函数中,从回复中检索数据两次。 考虑调用 GetData 一次,然后在 log.Debug 和 return 语句中使用它。
  • 两个 if 语句 检查 BaseFee 是否不等于 0。 考虑将第二个 if 语句移动到第一个 if 语句块中,并删除不必要的检查。
  • 如果 ds.cfg.MantleDaSwitch if 语句 使用仅具有 true 和 false 分支的 if 语句可能会更容易阅读,其中 true 分支包含用于处理 MantleDA 的代码,而 else 分支包含用于以太坊 calldata 的代码。
  • 对代码库的重大更新之一是添加了 MNT 值,该值更改了协议以处理 MNTValueETHValue。 正确的编码以 MNTValue 参数开始,后跟 ETHValue 参数。 但是,在多个位置,结构的初始化顺序相反。 虽然这不会引起问题,因为使用了参数名称,但它确实会阻碍可读性。 考虑在 DecodeWithdrawalTransaction 函数中更改 MNTValueETHValue 参数的顺序。

更新:拉取请求 #125 中已解决。

结论

此次审计发现了一个中等严重性的问题,以及其他几个较低严重性的问题。 我们提供了各种建议来增强代码库的质量和文档。 我们还强烈建议 Mantle 在上线之前实施更广泛的 QA 程序和测试,以防止潜在的未发现的漏洞被利用。 在代码的测试有限的区域(例如与 Mantle DA 的集成)中,这一点尤其重要。 在整个审计期间,Mantle 团队非常支持,并及时回答了问题。

  • 原文链接: blog.openzeppelin.com/ma...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OpenZeppelin
OpenZeppelin
江湖只有他的大名,没有他的介绍。