去中心化交易所中的 C++ 与 Rust:适用场景与效率

去中心化交易所中的 C++ 与 Rust:适用场景与效率

C++、Rust 和去中心化加密货币交易所:适用性和效率

简介

语言争论在加密领域尤其具有误导性,因为系统本身很容易被错误描述。人们说“构建一个 DEX”,就好像去中心化交易所是一个具有一种延迟配置文件、一种信任模型和一种故障的可执行文件。事实上,一个严肃的 DEX 是一个分层的有机体。它可能包括链上逻辑、验证器或节点交互、区块构建意识、内存池监控、市场数据收集、状态模拟、定价、路由、风险检查、操作员仪表板,有时还包括订单簿或匹配相邻服务,这些服务看起来可疑地像带有区块链词汇的传统交易基础设施。

一旦我们承认了分层的现实,C++ 和 Rust 之间的争论就会变得更加平静和有用。正确的问题不是哪种语言值得整个架构作为荣誉点。正确的问题是哪些层受益于 Rust 的安全性和生态系统适应性,哪些层仍然奖励 C++ 的低级性能控制,以及混合设计在哪里停止妥协并开始变得简单、明智。

这个框架很重要,因为去中心化交易系统面临着复杂的压力。某些层因正确性失败、可审计性问题和不安全的状态转换而受到最严厉的惩罚。其他层因延迟、吞吐量和无法足够快地评估机会而受到惩罚。还有一些是运营服务,其真正成本是长期维护和团队速度。一种语言可能非常适合其中一种负担,而对于另一种负担则仅够用。当我们公开承认这一点时,成熟的建筑就开始了。

DEX 是一个堆栈,而不是一个身份声明

第一个也是最重要的修正是概念上的。 DEX 不是一回事。面向 EVM 的 AMM 协议、Solana 原生程序生态系统、应用链永续交换以及对市场条件做出反应的搜索系统都需要不同的工程本能。链上 AMM 逻辑存在于一组约束内。链下模拟器和路线评估器位于另一个模拟器中。从系统角度来看,类似于订单簿的组件或高频搜索基础设施可能看起来更接近经典的交易软件,而不是普通的 Web 应用程序开发。

这就是语言辩论如此迅速地误入歧途的原因。一位工程师指向 Solana 并正确地观察到 Rust 是那里程序开发的自然路径。另一种观点是对延迟敏感的路由或模拟引擎,并正确地观察到 C++ 仍然是一个非常强大的选择。两者在上下文中都是正确的。当每个观察都被夸大为整个堆栈的总理论时,问题就开始了。

一个有用的心理重置是询问每个子系统,它会因为什么样的痛苦而受到惩罚。如果某个组件出错,痛苦是否主要是公共正确性失败?是私人运营成本吗?是否无法在机会结束之前应对快速变化的状态?是审计负担、招聘负担还是基础设施负担?不同的层对这些问题的回答不同,这就是为什么成熟的 DEX 系统往往最终在语言上混合,即使公开辩论渴望纯粹性。

Rust 正确地占据领先地位

Rust 在状态转换、安全规则和生态系统适应性主导架构的情况下最自然地赢得一席之地。在 Rust 优先的区块链环境中,例如 Solana,这成为重心。该语言周围有框架、示例、安全习惯和工具,可帮助协议团队顺应生态系统的规律而不是违背生态系统。对于链上程序来说,契合度比抽象语言比较更重要。如果围绕它的每条严肃的操作路径都期望有其他东西,那么纸面上最好的语言往往是最糟糕的语言。

当长期正确性和可维护性是主要敌人时,Rust 在围绕 DEX 的绿地服务中也很有吸引力。控制平面服务、协调层和某些面向协议的工具可能真正受益于 Rust 鼓励的学科。编译器会捕获错误类别,否则需要流程、警惕和审查文化来在 C++ 中进行控制。这是一个实际的主张。拥有强大 Rust 人才的团队可以尽早降低某些类别的风险,并随着时间的推移保持服务边界更加平静。

一个有用的反例使这一点站得住脚。团队有时会根据 Rust 在链原生工作中的优势推断,默认情况下每个周围的链外子系统也应该是 Rust。但只有当周围系统具有相同的主要疼痛时,才会出现这种情况。在紧迫的时间压力下反复评估市场状态的热路径模拟器或搜索引擎仍然是加密产品内对性能敏感的本机系统。该链可能是Rust形状,而周围的执行路径仍然是C++形状。

C++ 仍能发挥作用

只要 DEX 不再像应用程序平台,而更像交换基础设施,C++ 就变得很难被取代。市场数据摄取、内存池监听、标准化管道、路径评估、状态模拟、套利搜索、清算引擎和订单簿相邻服务都有一个共同的属性:它们在压力下执行重复的低级工作,并且这些工作通常与内存布局、分配策略、解析器效率、队列行为或 CPU 可预测性密切相关。这就是 C++ 在系统和交易领域的悠久历史仍然发挥重要作用的地方。该语言使工程师能够直接控制数据结构、线程模型、对象生命周期、自定义分配器、矢量友好的布局以及在此类环境中经过实战测试的性能工具。它还受益于更古老、更密集的高性能网络系统示例生态系统、模拟器、解析器、本机网关和硬件意识代码。当人工智能助手帮助解决这些问题时,这种密度会增加优势。

考虑一个搜索者聆听市场信号、模拟路径并决定是否值得追逐机会。有趣的成本很少是孤立的一个公式。有趣的成本是重复、有状态地使用许多由摄取、解码、路由和决策逻辑包围的公式。一些可以避免的副本、一个放置不当的锁或无纪律的队列都可能改变整个路径的经济性。 C++ 为工程师提供了一种非常熟悉的语言来向机器提出确切的问题。在时间压力下通过重复而生存和消亡的系统中,这一点仍然很重要。

经济学改变了答案的语言

这些争论变得过热的原因之一是工程师们说话的方式就好像获胜条件很优雅一样。在 DEX 系统中,获胜条件通常是经济的。延迟很重要,因为错过机会是要付出代价的。效率很重要,因为大规模重复模拟是有成本的。安全很重要,因为不正确的状态转换是有代价的。操作简单性很重要,因为一个不断让操作员感到恐惧的系统是有成本的。一旦用这些术语表达了论点,语言选择就不再是象征性的,而是变成了经济性的。

Rust 通常会收回成本,未来最大的成本将来自硬状态逻辑中的正确性失败,或在没有足够的结构纪律的情况下维护复杂的服务。 C++ 通常会收回成本,其中最大的未来成本将来自于热路径效率低下、重复计算中的过多抽象或与高性能本机基础设施集成的困难。明智的团队会询问哪种成本将在子系统的生命周期中占主导地位,并做出相应的选择。

这一观点还有助于解决一个常见的困惑:结算速度和执行路径速度不是一回事。区块链可能在协议级别具有一组时序特征,而围绕它的链下系统则生活在完全不同的延迟世界中。缓慢的链上结算并不意味着快速的链下评估变得无关紧要。事实上,当机会竞争时,链下速度可能变得更有价值,因为它决定了谁做出反应、谁准确定价以及谁首先提交有用的行动。将这两个时序域扁平化为一个称为速度的概念的工程师通常最终会付出努力。

混合架构通常是成人的答案

一旦允许混合设计受到尊重,许多最重要的 DEX 架构就会变得更容易推理。链上逻辑可以存在于链所期望的语言和框架环境中。控制平面和产品服务可以选择保持维护理智的语言。热路径模拟、路由、市场数据处理或匹配相邻组件可以保持接近性能传统,从而更容易调整和验证。结果并不是意识形态上的妥协。在这个系统中,每个部分都可以针对其实际负担进行优化。

这确实需要成熟。只有当边界明确时,混合系统才是健康的。团队需要清晰的界面、狭窄的责任划分以及对复杂性归属的诚实态度。但无论语言如何,这都是事实。边界混乱的单语言架构并不比边界清晰的双语言架构简单。有时它只是同一困惑的单一语言表达。

这里还有一个人员配置方面。团队经常认为他们必须选择一种语言,因为跨多个本地领域进行招聘感觉很困难。这种担忧是可以理解的,但它可能成为建筑懒惰的借口。更好的问题是,对性能最敏感的层是否真正需要自己的语言,或者分析器是否尚未证明该成本是合理的。有些团队绝对应该主要停留在 Rust 中,并且只在热门路径已经获得时才引入 C++。其他人已经拥有深厚的 C++ 专业知识,并且会通过将所有内容强制纳入与他们最强大的系统本能不匹配的 Rust 形状的工作流程中来伤害自己。背景再次比声望更重要。

人工智能辅助工程发生了哪些变化

人工智能编码系统的到来实际上增强了而不是削弱了上下文语言选择的理由。在 Rust 优先的区块链生态系统中,代理可以比以前更轻松地帮助构建框架感知的脚手架、常规服务代码和某些类别的重构。但在低级、注重性能的本机子系统中,天平仍然倾向于 C++,原因很简单:那里的公共代码、公共工具和公共集成示例要密集得多。代理目前拥有更多历史材料,可以为 DEX 系统经常需要的各种热路径基础设施生成有用的草稿。

这并不意味着人工智能使 C++ 普遍优越。这意味着旧的生态系统引力现在被新工具放大了。当助手帮助调试 CMake 集成、建议重新设计队列、改进解析器或起草模拟循环基准时,它会受益于公共 C++ 世界的深层本机内存。当助手在 Rust 优先的链上环境中工作时,情况可能恰恰相反。语言决定仍然属于工作量,但人工智能时代使环境密度比以前更加重要。

我的实用建议如果您正在 Rust 优先的生态系统中构建链原生程序,请不要为了语言修辞而与地形作斗争。让 Rust 引领它已经成为正确性、工具和社区实践的自然家园。如果您正在构建行为类似于性能敏感的交换工程的链外基础设施,请将 C++ 保留在加密域的桌面上。让 C++ 完成它仍然做得非常好的工作:快速摄取、重复模拟、严格的路由逻辑和低级系统控制。

如果您的架构确实跨越了两个世界,请毫不尴尬地接受这一事实。假装每个组件都遭受相同类型的故障,并不能让优秀的工程变得更加纯粹。通过为每个组件分配一种尊重其实际工作物理原理的语言,它会变得更强大。

以这种方式解决问题存在着一种平静的乐观态度。它提醒工程师,建筑可以比公共话语更平静。我们不必选择一种语言来永远赢得争论。我们只需为系统的下一个诚实层选择正确的工具即可。这是一种更有利可图的情报。

动手实验室:构建小型 AMM 路线评估器

让我们构建一些小到可以理解、真实到可以触摸的东西。

我们的目标不是重建 Uniswap。我们的目标是感受 DEX 工作如何快速成为重复模拟和比较的问题。

Rust```cpp

include <cmath>

include <iomanip>

include <iostream>

include <string>

include <vector>

struct Pool { std::string name; double reserve_in; double reserve_out; double fee; // 0.003 for 0.3% };

double swap_out(const Pool& p, double amount_in) { const double effective_in = amount_in (1.0 - p.fee); return (effective_in p.reserve_out) / (p.reserve_in + effective_in); }

double two_hop(const Pool& a, const Pool& b, double amount_in) { const double mid = swap_out(a, amount_in); return swap_out(b, mid); }

int main() { Pool eth_usdc_a{"ETH/USDC pool A", 500.0, 1750000.0, 0.003}; Pool eth_usdc_b{"ETH/USDC pool B", 650.0, 2262000.0, 0.0005}; Pool usdc_dai{"USDC/DAI stable pool", 900000.0, 901200.0, 0.0001};

const double trade_eth = 4.0;

const double direct_a = swap_out(eth_usdc_a, trade_eth);
const double direct_b = swap_out(eth_usdc_b, trade_eth);
const double routed = two_hop(eth_usdc_b, usdc_dai, trade_eth);

std::cout << std::fixed << std::setprecision(4);
std::cout << "Input: " << trade_eth << " ETH\n";
std::cout << "Direct via " << eth_usdc_a.name << ": " << direct_a << " USDC\n";
std::cout << "Direct via " << eth_usdc_b.name << ": " << direct_b << " USDC\n";
std::cout << "Two-hop via " << eth_usdc_b.name << " -> " << usdc_dai.name
          << ": " << routed << " DAI\n";

if (direct_b > direct_a) {
    std::cout << "Best direct route: " << eth_usdc_b.name << "\n";
} else {
    std::cout << "Best direct route: " << eth_usdc_a.name << "\n";
}

}



在 Linux 或 macOS 上:```bash
g++ -O2 -std=c++20 -o amm_router main.cpp
./amm_router
```在 Windows 上:```powershell
cl /O2 /std:c++20 main.cpp
.\main.exe
```### 为什么这很重要

即使是这个小程序也已经暗示了链下 DEX 工作的真实形态:

* 重复路径评估
* 费用意识比较
* 状态相关的输出
* 正确性和速度之间的恒定张力

将其扩展到数百个池、频繁的状态更新和对抗性的计时压力,您就会开始明白为什么语言选择很快就不再是抽象的了。


## 爱好者测试任务

1. 添加滑点容忍并拒绝有效输出低于配置阈值的路由。
2. 扩展程序以比较五个或十个池(而不是两个)并分析时间的流逝情况。
3. 添加一个循环,以稍微改变保留的方式重新评估路由一百万次,并测量“玩具”路由器如何开始类似于真正的热路径。
4. 用结构化数字日志记录替换浮点输出格式,并观察实际路由逻辑周围出现了多少“非数学”工作。
5. 添加 Rust 或其他语言的第二个版本,并将原始运行时与模拟循环成为工作中心后语言的舒适度进行比较。

这是一个很好的练习,因为它揭示了一些微妙的东西:在交换软件中,有趣的困难通常在于同时重复、有状态、对延迟敏感地使用许多普通公式。


## 总结

C++ 和 Rust 都属于去中心化交易所工程,但它们属于那里的原因不同。 Rust 在生态系统和层级中赢得信任,其中状态安全、可审计性和链原生工作流程是核心。 C++ 赢得了各层的信任,其中的工作再次开始看起来像交换基础设施:重复模拟、市场数据处理、路由、搜索和其他热路径系统,这些系统奖励对内存、调度和性能验证的严格控制。

因此,最有用的问题不是哪种语言赢得了整个堆栈。这是我们实际设计的层以及该层最不能承受的故障类型。一旦诚实地提出这个问题,架构通常会变得更加清晰,并且争论也会变得不那么意识形态化。设计良好的 DEX 很少是语言纯粹性的纪念碑。它是组件的实用安排,每个组件都用最尊重其承载负担的语言编写。

## 参考文献

1. Uniswap v3 白皮书:Rust
2. Uniswap v3 核心存储库:C++
3.Ethereum.org MEV 文档:Solana
4. Solana 程序概述:SDK
5. Solana Rust 程序开发:[https://solana.com/docs/programs/rust](https://solana.com/docs/programs/rust)
6. 锚定文档:[https://www.anchor-lang.com/docs](https://www.anchor-lang.com/docs)
7. dYdX 链文档:[https://docs.dydx.exchange/](https://docs.dydx.exchange/)
8. dYdX 集成文档:[https://docs.dydx.xyz/](https://docs.dydx.xyz/)
9. 链下订单簿上的 dYdX 链上结算:[https://integral.dydx.exchange/dydx-closes-10m-series-b-investment/](https://integral.dydx.exchange/dydx-closes-10m-series-b-investment/)
10. Cosmos SDK 文档:[https://docs.cosmos.network/](https://docs.cosmos.network/)
## 当系统已经处于压力下时会是什么样子

当团队希望季度安静时,去中心化基础设施的语言选择往往变得紧迫。一项功能已经呈现在客户面前,或者一个平台已经具有内部依赖性,并且系统选择了特定的一周来揭示其优雅的理论和运行时行为已经礼貌地分开生活。这就是为什么这么多严肃的工程工作都是从协调开始的。团队需要将其认为系统所做的事情与系统在负载、变化和截止日期下实际所做的事情相协调,这会让每个人都稍微更有创造力,但稍微不那么明智。

在加密系统工程中,最重要的情况通常是搜索器和模拟器后端、延迟敏感的路由服务以及链下风险和结算基础设施。这些情况会带来技术、预算、信任、路线图,有时甚至是声誉后果。当多个团队依赖技术问题并且没有人能够完全解释为什么它不断产生噪音、延迟和成本时,技术问题在政治上就会变得更大。

这就是为什么我们建议从运营压力和交付现实的角度来看待这个问题。设计可能在理论上很漂亮,但在操作上却是毁灭性的。另一种设计可能几乎是无聊的,但却可以使产品继续前进多年,因为它是可测量的、可修复的,并且诚实地进行权衡。认真的工程师学会更喜欢第二类。它减少了史诗般的演讲,也减少了紧急回顾,每个人都用被动语态说话,没有人记得谁批准了这条捷径。

## 始终如一的实践

第一个持久的做法是不断衡量一条有代表性的路径。团队通常会在定义将改变决策的信号之前收集广泛的遥测数据。选择真正重要的道路,反复衡量,拒绝让讨论变成装饰性的故事讲述。在围绕 DEX 基础设施中的语言选择进行工作时,有用的衡量标准通常是热路径确定性、操作清晰度、互操作界面和模拟真实性。一旦这些决定变得可见,其余的决定就会变得更加人性化,不再那么神秘。第二个持久的做法是将证据与承诺分开。在系统得出结论之前,工程师常常被迫说方向是正确的。抵制这种压力。首先建立一个狭义的证明,尤其是当主题与客户或金钱密切相关时。经过验证的小改进比未经验证的大目标具有更大的商业价值。这听起来很明显,直到季度末审查将假设变成最后期限,并且整个组织开始将乐观情绪视为日程安排工件。

第三个持久的做法是用所有权语言撰写建议。一段说“提高绩效”或“加强界限”的段落在情感上令人愉快,但在操作上毫无用处。一个段落说明了谁更改了什么、按什么顺序、在什么回滚条件下更改,这些内容实际上在周一早上仍然存在。这是很多技术写作失败的地方。它希望听起来先进,而不是可调度。

## 节省时间的反例

当地的成功并不能证明已经准备好迎接更艰难的环境。在扩展这个想法之前,团队必须升级测量规则并证明相同的行为在更大的压力下仍然存在。

另一个反例是工具通货膨胀。一个新的分析器、一个新的运行时、一个新的仪表板、一个新的代理、一个新的自动化层、一个承诺协调旧包装器的新包装器。这些事情本质上都不是坏事。问题是当他们被要求补偿一个没有人明确命名的边界时会发生什么。然后,系统就会变得更加仪器化、更加令人印象深刻,并且只是偶尔更容易理解。团队很快就能感受到这一点。即使没有这样的措辞,他们也能察觉到堆栈何时成为决策的昂贵替代品。

第三个反例是将人工审查视为自动化的失败。在实际系统中,人工审查通常是保持自动化在商业上可接受的控制措施。成熟的团队知道在哪里积极自动化以及在哪里保持批准或解释可见。不成熟的团队希望机器做所有事情,因为“一切”在幻灯片中听起来都很高效。然后第一个严重事件到来,突然之间,带着转换体验的诚意重新发现了手动审核。

## 我们推荐的交付模式

好的工作首先是通过足够强大的技术阅读来减轻压力,以阻止循环辩论。下一个有界实施改进了一条重要路径,并且复测使工程和领导层能够清楚地了解方向。这个顺序比确切的工具选择更重要,因为它将技术技能转化为前进的动力。

实际上,我们建议缩小第一个周期:收集工件,产生一个硬诊断,发布一个有限的更改,复测真实路径,并用简单的语言编写下一个决策。简单的语言很重要。团队很少会后悔清晰度。团队常常会在收据到达之前后悔给自己留下了深刻的印象。

这也是语气很重要的地方。强大的技术工作听起来应该像以前遇到过生产一样。冷静、精确、精确地进行权衡和证据。该音调携带操作信号。它表明该团队了解系统工程的古老真理:机器速度很快,路线图很脆弱,迟早要为每一个允许保持诗意的假设付出代价。
## 在准备就绪之前我们将使用的清单

在加密系统工程中,准备就绪不是一种情绪。这是一个带有后果的清单。在我们称 DEX 基础设施中的语言选择工作已准备好进行更广泛的推广之前,我们希望以尽可能最好的方式让一些事情变得无聊。我们想要一条在代表性负载下表现可预测的路径。我们想要一组不矛盾的测量结果。我们希望团队知道边界在哪里以及打破它意味着什么。我们希望工作的输出足够清晰,以便实施室之外的人仍然可以从中做出正确的决定。

该清单通常涉及热路径确定性、操作清晰度、互操作表面和模拟真实性。在昂贵的意外事件投入生产之前,使用该清单来测试解释质量、现场弹性和回滚清晰度。

这也是团队发现他们是否正在解决真正的问题或只是在其周围排练能力的地方。许多技术努力都感觉很成功,直到有人要求提供可重复性、生产证据或会影响预算的决定。在那一刻,弱的工作变得模糊,而强的工作变得异常简单。平淡就好。平淡通常意味着系统已经不再依赖魅力。

## 我们建议如何谈论结果

最终的解释应该足够简短,以便在领导会议上通过,并且足够具体,以便在工程审查中通过。这比听起来更难。过于技术性的语言隐藏了顺序。过于简化的语言隐藏着风险。正确的中间立场是以一种听起来平静而不是胜利的方式描述路径、证据、有限的变化以及下一步建议的步骤。

我们推荐这样的结构。首先,说明评估了什么路径以及它为何重要。其次,说出该路径的错误或不确定之处。第三,说明更改、测量或验证的内容。第四,说出尚未解决的问题以及下一步投资将购买什么。这种结构之所以有效,是因为它尊重工程和购买行为。工程师想要细节。团队需要排序。当下一步明确时,每个人都会受益。以这种方式说话的隐藏好处是文化。清楚地解释技术工作的团队通常也会更清楚地执行它。他们不再将模糊性视为复杂性。他们变得更难用行话打动人心,而更容易通过困难的系统获得信任。这是工程成熟度中最被低估的形式之一。
## 我们仍然拒绝伪造的内容

即使系统改进后,成熟的团队也会在加密系统工程中保持不确定性。弱测量需要更清晰的证据,硬边界需要简单的语言,更平静的演示需要真正的操作准备。必须减少一些不确定性;有些必须诚实地命名。令人困惑的是这两项工作是如何令人尊敬的项目变成了昂贵的寓言。

同样的规则也适用于 DEX 基础设施中有关语言选择的决策。如果团队仍然缺乏可重复的基准、值得信赖的回滚路径或关键接口的明确所有者,那么最有用的输出可能是更明确的“否”或更窄的下一步,而不是更大的承诺。这种纪律使技术工作与其要改进的现实保持一致。

以这种方式工作会有一种奇怪的轻松感。一旦系统不再依赖乐观的故事讲述,工程对话就会变得更简单,即使工作仍然很困难。在生产中,这通常被视为一种小形式的恩典。
## 关于 Dex 基础设施规划的附加说明

DEX 基础设施中良好的语言划分通常在纸面上看起来很适度。一种语言在可预测性、遗留使用或原始系统熟悉度方面占据着最重要的位置。另一个拥有边界纪律和更新的组件隔离使交付故事更健康的地方。错误在于试图将语言选择变成意识形态。交易系统不关心意识形态。他们关心丢失的数据包、不稳定的队列、错误的模拟信心以及假装其他情况的发票。

这就是为什么我们推荐架构图来准确显示语言的交汇点、如何测试这些接缝以及属于每一方的操作指标。如果混合的 C++/Rust 堆栈无法用一张冷静的图表来解释操作,那么它可能还没有准备好。如果可以清楚地解释,混合堆栈通常看起来就不再那么奇特了。它看起来就像是愿意选择合身而不是时尚的工程师。
Philip P.

Philip P., CTO

返回博客

联系方式

开始对话

几条清晰的线条就足够了。描述一下系统、压力、被阻碍的决策。或者直接写信给midgard@stofu.io。

0 / 10000
未选择文件