0x11 Deposit & Withdraw (Mock Chain)
🇺🇸 English | 🇨🇳 中文
🇺🇸 English
📦 Code Changes: View Diff
Core Objective: Implement the Funding Layer (Deposit & Withdraw) using a Mock Chain Architecture to validate asset flows without external blockchain dependencies.
1. Background & Architecture
We have a high-performance Matching Engine (Phase I) and a Product Layer (Accounts/Auth, Phase II). Now we add the Funding Layer to allow assets to enter and leave the system.
1.1 The “Mock Chain” Strategy
Instead of syncing 500GB of Bitcoin data, we implement a Simulator for Phase 0x11.
- Goal: Validate internal logic (Balance Credit, Risk Check, Idempotency).
- Method:
MockBtcChainandMockEvmChaintraits that simulate RPC calls.
graph LR
User[User] -->|API Request| Gateway
Gateway -->|Risk Check| FundingService
FundingService -->|Command| ME[Matching Engine]
FundingService -.->|Simulated RPC| MockChain[Mock Chain Adapter]
MockChain -.->|Callback| FundingService
1.2 Phase Plan
| Chapter | Topic | Status |
|---|---|---|
| 0x11 | Deposit & Withdraw (Mock) | ✅ Completed |
| 0x11-a | Real Chain Integration | 🚧 Construction |
2. Core Implementation
2.1 Funding Service (src/funding/service.rs)
The central orchestrator for all funding operations.
- Deposit: Receives “Mock Event”, checks idempotency, credits user balance via matching engine.
- Withdraw: Authenticates user, locks funds in engine, simulates broadcast, updates DB.
2.2 Chain Adapter Trait (src/funding/chain_adapter.rs)
We abstract blockchain specifics behind a trait:
#![allow(unused)]
fn main() {
#[async_trait]
pub trait ChainClient: Send + Sync {
async fn generate_address(&self, user_id: i64) -> Result<String, ChainError>;
async fn broadcast_withdraw(&self, to: &str, amount: &str) -> Result<String, ChainError>;
// ... validation methods
}
}
2.3 Database Schema (Migration)
Key tables added in migrations/010_deposit_withdraw.sql:
deposit_history: Tracks incoming transactions (Key:tx_hash).withdraw_history: Tracks outgoing requests (Key:request_id).user_addresses: MapsUser <-> Asset <-> Address.
3. Data Flow
3.1 Deposit Flow (Mock)
- Trigger:
POST /internal/mock/deposit { user_id, asset, amount } - Idempotency: Check if
tx_hashexists indeposit_history. - Engine Execution: Send
OrderAction::Depositto Match Engine. - Result: User Balance increases.
#![allow(unused)]
fn main() {
// src/funding/deposit.rs
pub async fn process_deposit(...) {
if db.exists(tx_hash).await? { return Ok(()); }
// Command Engine
engine.execute(Deposit(user_id, asset, amount)).await?;
// Persist
db.insert_deposit(..., "SUCCESS").await?;
}
}
3.2 Withdraw Flow
- Request:
POST /api/v1/private/withdraw/apply - Risk Check: 2FA (Future), Whitelist, Balance Check.
- Engine Lock: Send
OrderAction::WithdrawLock(Instant deduction). - Broadcast: Call
mock_chain.broadcast(). - Finalize: Update
withdraw_historywithtx_hash.
4. Verification
We verified this phase using a comprehensive E2E script.
4.1 Verification Script
Run the master script to verify the full lifecycle:
./scripts/verify_funding_trading_flow.sh
Scenario Covered:
- Register User A & B.
- Deposit BTC to User A (Mock).
- Transfer internal funds.
- Trade (Buy/Sell) to change balances.
- Withdraw USDT from User B.
- Audit: Check DB consistency.
4.2 Security Validation
- Address Validation: Strict Regex for
0x...(ETH) and1/3/bc1...(BTC). - Internal Auth: Mock endpoints protected by
X-Internal-Secret.
Warning
SECURITY ADVISORY: The
/internal/mock/depositendpoint is a major security risk as it allows direct balance manipulation. It is currently protected by a secret but MUST be removed entirely once the Phase 0x11-a Sentinel (blockchain scanner) is fully integrated and stable.
Summary
Phase 0x11 establishes the “Financial Highways” of the exchange. By using a Mock Chain, we isolated the complex internal logic (Accounting, Risk, Idempotency) from the external chaos of real blockchains.
Key Achievement:
A complete, idempotent Asset Inflow/Outflow system that is “Blockchain Agnostic”.
Next Step:
Phase 0x11-a: Replace the “Mock Adapter” with a “Real Node Sentinel” (Bitcoin Core / Anvil).
🇨🇳 中文
📦 代码变更: 查看 Diff
核心目标:实现 资金层 (Funding Layer) (充值与提现),使用 模拟链架构 (Mock Chain) 来验证资金流转,而不依赖外部区块链环境。
1. 背景与架构
我们已经拥有了高性能的 撮合引擎 (Phase I) 和 产品层 (账户/鉴权, Phase II)。 现在我们需要添加 资金层,允许资产进入和离开系统。
1.1 “Mock Chain” 策略
在 Phase 0x11 中,我们实现一个 模拟器,而不是直接同步 500GB 的比特币数据。
- 目标: 验证内部逻辑 (余额入账、风控检查、幂等性)。
- 方法:
MockBtcChain和MockEvmChaintrait,模拟 RPC 调用。
graph LR
User[用户] -->|API 请求| Gateway
Gateway -->|风控检查| FundingService
FundingService -->|指令| ME[撮合引擎]
FundingService -.->|模拟 RPC| MockChain[Mock Chain 适配器]
MockChain -.->|回调| FundingService
1.2 阶段规划
| 章节 | 主题 | 状态 |
|---|---|---|
| 0x11 | 充值与提现 (Mock) | ✅ 已完成 |
| 0x11-a | 真实链集成 | 🚧 建设中 |
2. 核心实现
2.1 资金服务 (src/funding/service.rs)
资金操作的核心协调器。
- 充值 (Deposit): 接收 “模拟事件”,检查幂等性,通过撮合引擎增加用户余额。
- 提现 (Withdraw): 验证用户,锁定引擎中的资金,模拟广播,更新数据库。
2.2 链适配器接口 (src/funding/chain_adapter.rs)
我们将区块链细节抽象在 Trait 之后:
#![allow(unused)]
fn main() {
#[async_trait]
pub trait ChainClient: Send + Sync {
async fn generate_address(&self, user_id: i64) -> Result<String, ChainError>;
async fn broadcast_withdraw(&self, to: &str, amount: &str) -> Result<String, ChainError>;
// ... 验证方法
}
}
2.3 数据库 Schema (Migration)
migrations/010_deposit_withdraw.sql 新增的关键表:
deposit_history: 追踪入金 (Key:tx_hash)。withdraw_history: 追踪出金 (Key:request_id)。user_addresses: 映射User <-> Asset <-> Address。
3. 数据流
3.1 充值流程 (Mock)
- 触发:
POST /internal/mock/deposit { user_id, asset, amount } - 幂等性: 检查
deposit_history中是否存在tx_hash。 - 引擎执行: 发送
OrderAction::Deposit给撮合引擎。 - 结果: 用户余额增加。
#![allow(unused)]
fn main() {
// src/funding/deposit.rs
pub async fn process_deposit(...) {
if db.exists(tx_hash).await? { return Ok(()); }
// Command Engine
engine.execute(Deposit(user_id, asset, amount)).await?;
// Persist
db.insert_deposit(..., "SUCCESS").await?;
}
}
3.2 提现流程
- 请求:
POST /api/v1/private/withdraw/apply - 风控: 2FA (规划中), 白名单, 余额检查。
- 引擎锁定: 发送
OrderAction::WithdrawLock(瞬间扣除)。 - 广播: 调用
mock_chain.broadcast()。 - 终结: 更新
withdraw_history填充tx_hash。
4. 验证与测试
我们使用全链路 E2E 脚本验证了本阶段功能。
4.1 验证脚本
运行主脚本以验证完整生命周期:
./scripts/verify_funding_trading_flow.sh
覆盖场景:
- 注册 用户 A & B。
- 充值 BTC 给用户 A (模拟)。
- 划转 资金 (Internal Transfer)。
- 交易 (买/卖) 改变余额。
- 提现 USDT (用户 B)。
- 审计: 检查数据库一致性。
4.2 安全性验证
- 地址验证: 针对
0x...(ETH) 和1/3/bc1...(BTC) 的严格正则校验。 - 内部鉴权: Mock 端点受
X-Internal-Secret保护。
Caution
安全警告:
/internal/mock/deposit接口存在重大安全隐患,因为它允许直接修改用户余额。虽然目前增加了 Secret 校验,但在 Phase 0x11-a Sentinel(区块链扫描器)完全集成并稳定后,必须彻底移除此接口。
总结
Phase 0x11 建立了交易所的 “资金高速公路”。 通过使用 Mock Chain,我们将复杂的内部逻辑(会计、风控、幂等性)与外部区块链的混乱隔离开来。
关键成就:
一套完整的、幂等的资产流入/流出系统,且做到 “Blockchain Agnostic” (与具体链解耦)。
下一步:
Phase 0x11-a: 将 “Mock Adapter” 替换为 “Real Node Sentinel” (Bitcoin Core / Anvil)。