← 文档索引
pangolin-pay 地址池收款模型
2026-07-09 · 阅读版 · 执行真相源 docs/superpowers/plans/2026-07-09-pay-address-pool.md · #34/34A 收款模型修订(折中方案)
从"每单唯一 HD 地址"改为地址池复用:池大小 = 峰值并行度(初始 10,不够动态派生),地址复用摊薄激活/归集成本;仍多地址,避免并发订单金额撞、对账精确。归集成本从 O(订单数) 降到 O(池大小),激活一次/地址即长期复用。是"单地址(省钱撞单)"与"每单唯一(精确但贵)"的折中。
核心风险 · 地址复用的迟到付款错配:地址回收后绑给新订单,若前一个用户超时后才付款,钱打到已绑新订单的地址上 → 可能误配。解法(必须):① 匹配按"到账 tx + 金额 + 时间戳(晚于建单)",不按余额、不只按地址;② 每单唯一金额(基准+唯一尾数);③ 匹配不到活跃订单的到账 → 记 orphan_payments 人工对账;④(可选)超时后地址冷却再重绑。
设计(规则 + 安全点)
- 地址池:HD 派生地址(
m/44'/195'/0'/0/i),状态 idle|busy,初始 10。
- 建单:绑最小编号 idle 地址→busy;无 idle → 派生新地址入池。原子(事务/行锁,防并发抢同址)。
- 每单唯一金额 ⭐:基准 + 唯一尾数,当前活跃订单间不撞;复用地址上旧单迟到付款不误配新单。
- 15min 超时 → expired → 地址回 idle(可选冷却)→ 提示重建订单。
- 付款完成 → paid → 地址回 idle(注意:地址里仍有 USDT 待归集,idle 只表示可重绑)。
- 匹配:找"到该地址 + 金额命中 + 区块时间晚于建单"的转入 tx。
- 同用户单订单:同时只能一个活跃订单。
- 归集:定期扫池内有余额地址→冷钱包(能量租赁 ~$0.1–1/笔);池 ~10,笔数有界;与 busy 解耦。
Phase A — 数据模型
- A.1
addresses(id, addr_index唯一, address, state, activated, created_at),按需派生入池。
- A.2
pay_orders 加 user_ref / address_id / expect_amount(唯一金额) / matched_tx_id。
- A.3
orphan_payments(tx_id唯一, address, value, block_ts, handled)。
- A.4 复用 addr_cursor 派生新址;迁移 + 索引(status/address/user_ref)。
Phase B — 建单
- B.1 CreateOrder(user, sku):校验同用户无活跃单 → 原子选最小 idle 置 busy(无则派生)→ 分配唯一金额 → 写 pending(TTL 15min)。
- B.2 唯一金额分配(基准+唯一尾数,当前活跃单间不撞)。
- B.3 GetOrder + releaseAddress 公共方法(paid/expired 复用)。
Phase C — watcher(匹配/释放/孤儿)
- C.1 匹配:pending 单查其地址转入,value 命中唯一金额 且
block_ts>created → paid + 记 tx + 释放地址。
- C.2 超时:pending 过期 → expired + 释放地址(可选冷却)。
- C.3 孤儿:匹配不到活跃订单的到账 → 记 orphan_payments(去重)。
- C.4 幂等(tx_id 去重)+ 崩溃恢复;TronGrid 取 block_timestamp 供时间过滤。
Phase D — 归集
- D.1 扫池内有余额地址 → 冷钱包(能量租赁,先手动 runbook);与订单状态解耦。
Phase E — 测试 + 真链
- E.1 单测:并发不抢同址、复用后迟到付款不误配、唯一金额、超时释放、孤儿、幂等、崩溃恢复、同用户单订单。
- E.2 真链:两并发订单各绑地址付款;一单超时释放后新单复用同址,旧地址补"旧金额"付款应成孤儿不误配;归集。
不在本轮 / 取舍
- GasFree(#35,免 TRX 但每笔固定 1 USDT,更适合少地址批量,另议)。
- 能量租赁自动化(先手动);池增长上限(先宽松);发货侧(独角数卡 + /internal/codes/mint)另排。
相关:加密货币交易引擎(已实现钱包/tron/sweep) · #34 收款闭环全景