跳转至内容

Hummingbot 网关架构 - 第 1 部分

cover

by Martin Kou

更新 (2023 年 2 月): Hummingbot Gateway v2 现在作为一个独立的 Github 仓库提供: https://github.com/hummingbot/gateway。本文中列出的大部分功能现已实现,我们欢迎社区的贡献。

引言

Hummingbot 网关是一种允许 Hummingbot 连接到去中心化交易所(如 Uniswap)的软件。

Hummingbot 网关是与 Hummingbot 分离的软件,因为访问去中心化交易所所需的软件库,例如 Uniswap Smart Order Router,通常不是用 Python 编写的。网关通过向 Hummingbot 暴露一个安全统一的 API 接口,使 Hummingbot 能够访问这些具有不同软件栈的去中心化交易所。此 API 接口也可以被其他潜在的网关客户端使用,例如专有的交易软件。

在这个 Hummingbot Gateway v2 架构系列博客文章中,我们将概述将对 Gateway v2 进行的架构更改,以使其达到生产质量 - 以及为什么需要进行这些更改。

历史

gate-img1Hummingbot 网关于 2020 年中期最初被构想为 Hummingbot 与 Celo、Balancer 和 Terra 交互的接口。虽然去中心化交易所的概念在当时已广为人知,但与现在相比,交易活动相对初级。

因此,原始的 Hummingbot 网关具有相对简单的架构,并且没有考虑在现代 DEX(如 Uniswap)中看到的许多故障模式。例如,卡住的区块链交易。因此,原始的 Hummingbot 网关无法提供生产交易系统所期望的可靠性。

我们决定对 Hummingbot 网关架构进行重大改造。我们将重新设计的 Hummingbot 网关称为 Gateway v2。

网关 V2 设计目标

gate-img2Gateway v2 是对原始 Hummingbot 网关的重新设计,具有以下设计目标:

稳健性和可靠性: 网关在遇到错误和故障时应继续工作;当网关中的操作必须失败时,它应该优雅地失败,而不是灾难性地失败。

用户体验: 网关应该易于设置和配置;一旦设置好网关,它应该在后台可靠地工作,让用户专注于交易。

开发人员体验: 虽然网关 v2 的初始版本将捆绑一些去中心化交易所连接器,但我们预计社区将随着时间的推移对 DEX 连接器、功能请求和错误修复做出大部分贡献。这意味着网关 v2 应该便于社区开发人员开发和测试。

稳健性和可靠性

gate-img3Hummingbot Gateway 和 Hummingbot 本身在本质上更类似于后端系统而非前端系统。特别是,这些系统处理的交易可能产生重大的财务后果。因此,Hummingbot 网关需要构建与大规模后端系统相同或更高的可靠性保障:

  • 高可用性和抗错误能力
  • 良好的测试覆盖率和监控
  • 信息安全

错误弹性

所有依赖其他网络组件的大规模后端系统都会定期遇到错误。然而,后端系统本身不能仅仅因为其某些依赖组件出现故障或返回错误就发生灾难性失败。例如,Google 数据中心的数千个硬盘每天都会发生故障;然而,Google 作为一个整体服务并不会因为周六有上千个硬盘发生故障就失败。

Hummingbot 和 Hummingbot 网关面临类似的挑战,尽管规模较小。交易所 API 和区块链交易经常失败,并且由于与通常的服务器-客户端架构不同,区块链交易有其独特的失败模式。然而,Hummingbot 和 Hummingbot 网关的弹性要求是相同的——仅仅因为以太坊网络拥堵,或者内存池丢弃了你的交易,机器人和网关都不能以灾难性的方式失败。

Nonce

大多数区块链,包括以太坊和所有基于 EVM 的链,都强制执行交易的顺序。这是通过用户交易的唯一 nonce 数字来执行的。特别是,由以太坊地址签名的每笔交易都必须具有唯一且单调递增的 nonce 数字。由地址发送的第一笔交易必须具有 nonce 0,第二笔交易必须具有 nonce 1,以此类推。

网关客户端可能以比区块链网络能够确认和处理它们更快的速度请求 EVM 交易。因此,网关不能依赖从以太坊节点 API 报告的最后 nonce 来创建新交易,否则会有用重复的 nonce 号覆盖最近发送的交易的风险。

在原版 Hummingbot 网关中,所有发出交易的 API 调用都会创建新的区块链交易;此外,还假设底层区块链能够如此快速地处理交易,以至于从 Hummingbot 的角度来看它们似乎是"即时"的。这两个假设在实际的主网链中通常都是不正确的,在那里网络拥堵是常态而非例外。这种不匹配的假设导致原始网关似乎在以太坊测试网或具有快速区块时间的网络上通过了测试——但在以太坊主网上却失败了。

Gateway v2 将带来以下架构变更,以考虑现实世界以太坊区块链的工作方式:

  1. 所有发出交易的 API 将变得对 nonce 敏感——以便可以使用更高的 gas 费用重试或取消未确认或卡住的区块链交易。
  2. 在 Hummingbot 或网关客户端快速批量发出交易的情况下——网关将在本地跟踪使用的最新 nonce,以确保新交易以递增的 nonce 发出,而不是相互覆盖。
  3. 本地 nonce 跟踪管理器将在快速本地数据库中存储最新 nonce,以确保网关崩溃和重启时能够正确自愈。

卡住和丢弃的交易

今天几乎所有的区块链都使用交易费用和内存池的概念来优先处理要包含到新区块中的交易。由于矿工或验证者会自动优先处理高费用交易,因此标记为较低费用的交易通常会被延迟甚至丢弃。

这在考虑区块链交易必须按顺序执行时会带来额外的问题。假设我已经向以太坊网络发送了带有随机数 3、4、5 的交易。如果交易 3 被卡住,那么在交易 3 被处理之前,交易 4 和 5 无法被处理。因此,只要有一个交易被区块链卡住或丢弃,就会导致所有后续交易被卡住或丢弃。

这种交易语义与通常的服务器 API 调用语义非常不同。网关在这里的工作是将区块链交易的不可靠语义桥接到通常可靠的 API 调用语义——以便 API 客户端可以将部分处理复杂性交给网关,或者至少能够及时了解并响应交易事件(包括错误和被卡住)。

Gateway v2 将进行以下更改以允许取消或重试被卡住的交易:

  1. /poll API 将携带额外的响应字段,以处理尚未存在于内存池中的交易、卡在内存池中的交易,以及已确认的交易。
  2. 一个新/cancelAPI,允许取消被卡住的交易。

所有发出交易的 API,包括/cancel,将接受maxFeePerGas

maxPriorityFeePerGasnonce参数,以允许 Hummingbot 以不同的 Gas 成本重试被卡住的交易。

  1. 此外,如maxPriorityFeePerGas参数所暗示的,我们正在增加对 EIP-1559 交易的支持。

区块链节点错误

区块链节点 API 调用(例如所有 ethers.js 调用)可能会失败。最常见的原因是网络中断。网关在面对节点 API 错误时应该优雅地失败,而不是灾难性地失败。它还应在日志中提供信息性错误,以便让 Hummingbot 端或独立网关日志中的用户获得可见性。

在原始 Hummingbot 网关中,来自区块链节点 API 交互的错误通常会产生令人困惑用户的晦涩错误日志。虽然原始 Hummingbot 网关在执行区块链操作时确实会捕获错误,但它没有明确捕获区块链节点错误等常见错误类别并为这些情况提供可读的日志消息。

Gateway v2 将增加对区块链节点错误的测试覆盖。它还将为节点错误情况提供改进的错误日志记录,以确保 Hummingbot 端的用户将收到可读且可操作的错误消息。

节点 API 速率限制

这是一个更具体但也常见的节点错误案例。像 Infura 这样的节点服务带有 API 速率限制——一旦超过,网关客户端将被临时禁止。我们可以做两件主要的事情来减少对区块链节点的 API 调用次数——减少调用次数和监控。

原始 Hummingbot 网关没有考虑到像 Infura 这样的常见服务的节点 API 速率限制,因此超过 API 速率限制并被禁止成为原始 Hummingbot 网关中最常见的错误之一。

Gateway v2 将进行以下架构更改,以减少对像 Infura 这样的节点服务的 API 调用次数,并监控随时间推移的 API 调用次数:

  1. 对 Hummingbot 重复的区块链信息轮询调用的缓存逻辑,这在新区块到达之前节省节点 API 调用很有用。
  2. 每 5 分钟监控对区块链节点的 API 调用次数的指标,这将有助于捕获 Hummingbot 端或网关内部未检测到的 API 调用消耗大户。

测试覆盖和监控

测试用例和监控指标对于任何有弹性且可靠的软件来说都是硬币的另一面。总的来说,我们只有通过测试用例和指标不断衡量软件在不同情况下的行为,才能提高软件的可靠性。

虽然原始的 Hummingbot 网关带有一些测试用例——但它们对于发现问题是无用的,因为几乎所有的测试都只关注了正常情况。结果是,大多数错误路径都没有被测试,有效的测试覆盖率很差。

在接下来的章节中,我们将讨论(1)需要测试什么,(2)测试应如何构建,以及(3)应实施什么样的监控。

测试什么

我们无法为绝对每条逻辑路径实现测试,特别是在开始阶段。因此,讨论什么类型的测试应优先考虑及其原因很重要。

正常用户流程:这些包括测试 Hummingbot 和网关正常运行中使用的所有逻辑路径。这包括但不限于测试获取 gas 成本、获取资产价格、创建订单、获取交易状态等操作的正常流程。

常见错误流程:这些包括测试 Hummingbot 和网关正常运行中常遇到的错误路径。这包括但不限于进行节点 API 调用时的网络错误、交易未在区块链上注册、ETH 不足以支付 gas 成本、余额不足以创建订单等。

回归测试:错误修复,特别是那些涉及代码内部逻辑问题的修复(而不是诸如拼写错误之类的问题)——应附带单元测试用例,以确保在进一步代码更改后不会再次出现。虽然这在早期开发中可能看起来很麻烦,但回归测试将在后期为工程团队节省大量时间,避免重复修复错误。

测试夹具

除非我们有可靠的方式在测试用例中重现或模拟常见错误流程,否则很难测试它们。目前已知没有可靠的方法来持续诱使区块链给我们错误——所以模拟是唯一的方法。这意味着需要一些测试夹具来模拟来自区块链或区块链相关库(例如 Uniswap 订单路由器)的各种响应。

我们可能还需要将测试夹具扩展到后续的成功案例测试——同样,因为区块链操作本质上是不可靠的——所以也没有已知的方法让它不给我们错误。

我们将首先构建一小套能够模拟失败情况的原型单元测试用例。一旦有了这些,我们就能够在相同夹具架构基础上编写更多的单元测试用例。

监控

仅仅依靠用户错误报告来衡量复杂后端系统的稳定性是不够的。通常需要被动监控指标来确保现代系统的质量。除了监控可靠性外,指标还可以帮助我们更好地了解网关在实际使用中的情况——这可以帮助我们更好地制定产品路线图。

单元测试覆盖率监控:网关 v2 在早期阶段将目标设为 30% 到 40% 的单元测试覆盖率,并随着项目成熟逐步将测试覆盖率提升到 60% 以上。这与我们用于 Hummingbot 项目的测试覆盖率轨迹相似。

重要逻辑流程的使用和错误指标

这些包括错误计数、错误日志或可能导致错误的指标,例如前面讨论的每 5 分钟的节点 API 调用次数。Gateway v2 将携带匿名遥测数据用于使用和错误指标,以便在用户报告错误之前,Hummingbot 团队就能了解软件发布中的新错误。

遥测数据只会在用户同意的情况下在 Gateway v2 上启用,并且收集的所有指标数据将以匿名方式存储。

信息安全

gate-img5由于网关 API 调用通常以明文形式携带钱包私钥,因此确保网关和网关客户端(包括 Hummingbot)在向对方发送任何数据之前相互认证非常重要。

原始的 Hummingbot 网关已经具备双方的 SSL 认证,这已经为防止恶意软件尝试拦截传输中的私钥提供了一些保护。然而,原始的 Hummingbot 网关保护 SSL 私钥密码短语的机制较弱,我们将在 Gateway v2 中加强 SSL 私钥的安全性。

以下是 Gateway v2 将在信息安全方面进行的更改:

更好的 SSL 私钥密码短语保护

  • Hummingbot 端:密码短语将使用 Hummingbot 密码加密,而不是作为配置文件之一中的明文设置。
  • Gateway 端:密码短语将被隔离在自己的文件中,并具有0600UNIX 权限——而不是混入其他配置文件中。这类似于 SSL 私钥密码短语通常在 Web 服务器中的保护方式。

消除在网关 API 调用中传递钱包私钥的需要

  • 我们最终将迁移到使用 Hummingbot 和 Gateway v2 之间共享的加密钱包文件,而不是在 API 请求中传递钱包私钥。这将在 Gateway v2 首次公开发布之后的后续版本中实现。
  • 由于加密钱包文件仍然依赖于密码短语,上述第 1 点中概述的密码短语安全功能仍将继续适用。

结论

这标志着 Hummingbot Gateway v2 架构博客系列的第 1 部分结束,在这里我们讨论了将在 Hummingbot Gateway v2 的鲁棒性和可靠性方面进行的改进。目标是将 Gateway v2 转变为适合构建高价值加密货币交易系统的生产就绪软件。

在博客系列的下一部分,我们将讨论我们在 Gateway v2 的用户体验和开发者体验方面计划进行的改进。

请参阅本文的第 2 部分