jev-trader 性能核心:如何在 300ms 内读盘+AI决策+下单?只留 2 次 RPC 往返的终极优化
【免费下载链接】jev-traderOne AI trade decision every Monad block. Jev on Kuru MON-USDC.项目地址: https://gitcode.com/gh_mirrors/je/jev-trader
jev-trader 是一个运行在 Monad 链上的 AI 交易机器人:每个 300ms 区块,TypeSafe 的 Jev 模型都会看一眼 Kuru 交易所的 MON-USDC 订单簿,回答"买还是卖",并由真实钱包挂出一张 post-only 限价单。它的性能目标极其苛刻——读盘、AI 决策、下单必须塞进一个区块。而答案惊人地简洁:整条热路径只保留 2 次 RPC 往返。
⏱️ 300ms 预算:为什么速度是生死线
Monad 的区块时间只有 300ms。jev-trader 的规则是"每块一决策、每块一订单":一旦这个区块里还有上一块的请求没跑完,本块只能记为late(迟到,不下单),并在 src/trader.ts#L89-L93 中直接跳过。
eth_call(读盘)→ AI 决策(~100ms)→ eth_sendRawTransaction(发单)想在这个窗口里跑完三步,唯一的手段就是砍掉一切非必要 RPC。热路径(src/trader.ts#L85-L131)里恰好只剩两发请求:
| 第几次 | RPC 方法 | 干什么 | 公开节点实测 |
|---|---|---|---|
| 1 | eth_call | 一次性读出整个 L2 订单簿 | p50 约 18ms |
| 2 | eth_sendRawTransaction | 发送已签名交易,收到 txHash 即返回 | 毫秒级 |
🎯 第一次往返:一次 eth_call 读完订单簿
官方的 Kuru SDK 读盘要串行发两次eth_call(先getL2Book,再getVaultParams)。但 jev-trader 分析后发现:MON-USDC 市场的 AMM 金库深度为 0,第二次调用纯属浪费延迟。
于是项目在 src/book.ts#L72-L89 手写了一个最小读盘器:直接调getL2Book()的选择子,手动解码 ABI 返回值,并按 SDK 的位级逻辑(floor/ceil到 tick、按价格归组)还原订单簿,保证结果与 SDK逐位一致。如果哪天金库真的上线,两个调用也会被合并进同一个 JSON-RPC 批处理——仍然只有一次 HTTP 往返(src/book.ts#L7-L9)。
🎯 第二次往返:签名即发,发完就走
发单这一步(src/market.ts#L135-L152)同样做了"减法",核心是buildTx(src/market.ts#L175-L182)构造的这笔交易在签名前就万事俱备:
- ❌ 不用
eth_estimateGas——Monad 按 gas limit 收费,limit 在启动时估算一次并硬编码(src/market.ts#L257-L272),之后永不重查; - ❌ 不用
eth_gasPrice——静态 type-2 手续费:MAX_FEE_GWEI封顶 + 2 gwei 优先费,见 src/config.ts#L22-L28; - ❌ 不用
eth_sendRawTransactionSync——同步版要阻塞到交易被 Proposed,白白多等一个区块; - ✅ 本地维护 nonce,
batchUpdate一笔交易同时完成"撤销旧单 + 挂出新单",收到 txHash 立即返回。
回执确认、gas 实际花费、成交(fill)解析,全部在后续区块异步补账(src/trader.ts#L133-L138),从不拖慢当前块的决策。
🧠 AI 决策:吃下剩下的 ~200ms
读盘 ~18ms + 发单 ~毫秒级,中间留给模型约 200ms。Jev 是一个 System One 风格的模型:不输出文本,直接返回带概率的结构化决策,单次推理约 100ms,正好卡进预算(src/model.ts#L59-L77)。模型看到的不是原始报文,而是精心压缩的状态:盘口五档、多档深度、买卖单量差(CVD)、最近 100 块的收益率路径——全部在 src/trader.ts#L219-L243 本地拼装完成,零额外 RPC。
没配 API Key 时会用mock动量模型顶上,它甚至故意sleep80ms 模拟真实推理时长,让管线行为与生产一致(src/model.ts#L80-L98)。
📉 其余一切,全部移出热路径
| 任务 | 频率 | 为什么可以慢 |
|---|---|---|
交易回执轮询eth_getTransactionReceipt | 每块并行发起、异步落地 | 影响的是"上几块的单确认",不影响本块决策 |
交易日志(成交)拉取eth_getLogs | 每块一次,结果异步收割 | 成交由 taker 打穿我们的挂单产生,晚一块入账无妨 |
| gas 价格估算 + 保证金余额 + 金库检查 | 每 200 块 | 都是慢变量 |
| 新区块通知 | WebSocketnewHeads+ 150ms HTTP 轮询兜底 | 合并为"只跑最新块",见 src/chain.ts#L21-L50 |
📊 实测数据:p50 100ms,预算余量 3 倍
官方在 dry-run 下测得:读盘 p50 18ms,整循环 p50 100ms(其中 80ms 还是 mock 模型的推理占位)——也就是说真实场景下整条链路稳定在区块时间的三分之一以内。
项目还配了两个"自证清白"的脚本:
- scripts/bench-read.ts:手写读盘器 vs 官方 SDK,同块逐位对比 + 延迟横评;
- scripts/dry-encode.ts:离线签名买/卖两笔单,断言手编码的
batchUpdatecalldata 与 SDK 完全等价、价格严格对齐 tick 且永不穿盘。
🚀 快速上手
cp .env.example .env bun install bun run start没有PRIVATE_KEY时自动进入 dry-run:真实的盘口、真实的决策、模拟的成交;设置MODEL=jev与TYPESAFE_AI_API_KEY即切换为真 Jev 模型。架构总览见 SPEC.md,入口在 index.ts。
✅ 优化要点清单
- 数清热路径上的每一次网络往返,只留 2 次,其余全异步;
- 能合并的 RPC 就批处理,能省掉的参数查询就在启动时一次算好;
- 手写最小解码器替代 SDK,砍掉业务上不需要的调用,同时用基准脚本保证逐位等价;
- 发完就走:只等 txHash,回执和成交晚一块到账也不影响决策节奏;
- 用 p50 而不是平均值验收:18ms 读盘、100ms 全循环,为 300ms 预算留出 3 倍安全垫。
【免费下载链接】jev-traderOne AI trade decision every Monad block. Jev on Kuru MON-USDC.项目地址: https://gitcode.com/gh_mirrors/je/jev-trader
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考