API 集成 — 设计

概述

将 Oracle 系统从 mock 硬编码价格替换为 CoinGecko + Binance 双源真实 API,支持 100+ 交易对,并修复关键 keccak256 bug。

核心变更:

  1. 修复 keccak256 使用 DefaultHasher(非密码学哈希)的严重 bug

  2. 引入 PriceSource trait,实现 CoinGecko + Binance 双数据源

  3. 多源聚合:中位数价格、偏差检测、置信度计算、故障转移

  4. 从 bootloader 内存注入改为 operator 优先交易注入(突破 24 slot 限制)

  5. 配置扩展为 [[oracle.symbols]] 表格数组,支持 100+ 交易对


架构

┌─────────────────────────────────────────────────────┐
│                  OracleWiringLayer                    │
│                                                       │
│  ┌──────────┐   ┌──────────────┐   ┌──────────────┐  │
│  │CoinGecko │   │   Binance    │   │  Mock (test) │  │
│  │ Source    │   │   Source     │   │   Source      │  │
│  └─────┬────┘   └──────┬───────┘   └──────┬───────┘  │
│        │               │                   │          │
│        └───────┬───────┘───────────────────┘          │
│                ▼                                       │
│  ┌──────────────────────────────────────────────────┐ │
│  │              PriceAggregator                      │ │
│  │  ├─ parallel fetch (tokio::join!)                │ │
│  │  ├─ median price                                 │ │
│  │  ├─ deviation detection (max_deviation_bps)      │ │
│  │  ├─ confidence scoring (0-100)                   │ │
│  │  └─ failover (min 1 source)                      │ │
│  └───────────────────┬──────────────────────────────┘ │
│                      ▼                                 │
│  ┌──────────────────────────────────────────────────┐ │
│  │              OracleService                        │ │
│  │  ├─ latest_prices: HashMap<String, PriceData>    │ │
│  │  ├─ encode_oracle_calldata() → ABI bytes         │ │
│  │  └─ keccak256 ← sha3 crate (修复!)               │ │
│  └───────────────────┬──────────────────────────────┘ │
│                      ▼                                 │
│  ┌──────────────────────────────────────────────────┐ │
│  │         Operator Priority Transaction             │ │
│  │  State Keeper → OracleHub.batchUpdatePrices()    │ │
│  │  (替代 bootloader memory slot 注入)               │ │
│  └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘

注入方式变更(关键架构决策)

问题: Bootloader 内存 slot 方式(slot 8-31, 共 24 slots = 768 bytes)无法支持 100+ 交易对。每个交易对需要 ~128 bytes(symbolHash + price + confidence + sourceCount),24 slots 最多支持 6 对。

方案: 改为 operator 优先交易注入。State Keeper 在每个 batch 开始时构造一笔 operator 交易,调用 OracleHub.batchUpdatePrices(),数据量无上限。

改动范围:

  • era-core/core/node/state_keeper/ — 不再写入 bootloader memory,改为注入 operator tx 到 batch

  • era-contracts-l1/system-contracts/bootloader/bootloader.yul — 移除 Oracle memory hook

  • OracleHub.sol — 新增 onlyOperator 修饰符(仅允许 operator 地址调用 batchUpdatePrices


模块结构


PriceSource Trait


数据源实现

CoinGecko

  • 免费 API, 无需 key

  • 单次最多 250 个 ids

  • Rate limit: ~30 req/min

  • Symbol 映射: SymbolConfig.coingecko_id (如 "ethereum", "bitcoin")

Binance

  • 免费 API, 无需 key

  • 无 rate limit (合理使用)

  • Symbol 映射: SymbolConfig.binance_symbol (如 "ETHUSDT", "BTCUSDT")

Mock (测试)

保留现有 mock 逻辑,实现 PriceSource trait。配置中通过 sources = ["mock"] 启用。


聚合策略

偏差超阈值处理: 如果双源偏差 > max_deviation_bps(默认 500bps = 5%),标记低置信度但仍使用中位数。不丢弃数据 — operator 交易仍会执行,OracleHub 合约内部有自己的 deviation check。


配置扩展

当前 (baby-chain.toml)

改为

SymbolConfig 结构


keccak256 修复

当前 Bug (service.rs:158-171):

修复:

新增依赖: sha3 = "0.10"


新增依赖


测试策略

单元测试 (~15)

  1. keccak256 正确性 — 与已知向量比较

  2. CoinGeckoSource.fetch_prices — mock HTTP 响应解析

  3. BinanceSource.fetch_prices — mock HTTP 响应解析

  4. CoinGecko 错误处理 — HTTP 超时、非 200、JSON 格式错误

  5. Binance 错误处理 — 同上

  6. PriceAggregator 双源 — 两源价格接近,取中位数

  7. PriceAggregator 单源故障 — 一源失败,使用另一源

  8. PriceAggregator 双源故障 — 返回空

  9. 偏差检测 — 超阈值标记低置信度

  10. 置信度计算 — 2 源 → 高, 1 源 → 低

  11. SymbolConfig 反序列化 — TOML 解析

  12. encode_oracle_calldata — 修复后的 keccak256 验证

  13. 空 symbol 列表 — 不 panic

  14. 价格精度 — f64 → u128 (18 decimals) 转换正确性

  15. MockSource — 返回配置的 mock 价格

集成测试 (~3)

  1. CoinGecko 真实 API#[ignore] 标记,手动运行验证实际 API

  2. Binance 真实 API — 同上

  3. E2E: 配置 → 获取 → 编码 — 完整流程

预计总测试: ~18


文件清单

新建文件

文件
用途

baby-modules/oracle-wiring/src/sources/mod.rs

PriceSource trait + SourcePrice

baby-modules/oracle-wiring/src/sources/coingecko.rs

CoinGecko API 实现

baby-modules/oracle-wiring/src/sources/binance.rs

Binance API 实现

baby-modules/oracle-wiring/src/sources/mock.rs

Mock 数据源 (测试)

baby-modules/oracle-wiring/src/sources/aggregator.rs

多源聚合器

修改文件

文件
改动

baby-modules/oracle-wiring/Cargo.toml

添加 reqwest, sha3, serde_json

baby-modules/oracle-wiring/src/config.rs

SymbolConfig + sources 字段

baby-modules/oracle-wiring/src/service.rs

keccak256 修复, 使用 Aggregator

baby-modules/oracle-wiring/src/wiring.rs

使用 Aggregator 替代 mock

baby-modules/oracle-wiring/src/lib.rs

添加 sources module

config/baby-chain.toml

[[oracle.symbols]] 配置

暂不修改(后续任务)

文件
原因

era-core/core/node/state_keeper/

Operator tx 注入需要深入 State Keeper 内部,单独任务

bootloader.yul

移除 Oracle hook 需要重新编译 bootloader,单独任务

OracleHub.sol

添加 onlyOperator 需要重新部署系统合约,单独任务


交付计划

任务
内容
预估

Task 1

keccak256 修复 + PriceSource trait + SourcePrice

15 min

Task 2

CoinGeckoSource 实现 + 测试

20 min

Task 3

BinanceSource 实现 + 测试

20 min

Task 4

PriceAggregator 聚合器 + 测试

25 min

Task 5

OracleConfig 扩展 + wiring 集成

20 min

Task 6

baby-chain.toml 配置 + 编译验证 + dev-log

15 min

Last updated