ch03-05 State:账户、历史、治理、费用、参数
先抓住结构
读“State:账户、历史、治理、费用、参数”时先画边界。一个真实协议最容易读乱的地方,不是函数太多,而是不知道 Pool、Book、State、Vault 和 BalanceManager 各自负责哪一段。
架构坐标
先把架构坐标钉在这些文件上。读这一节时不需要展开所有实现,只要看清对象分工、入口函数和后续会反复回来的状态边界。
- packages/deepbook/sources/state/state.move
- packages/deepbook/sources/state/account.move
- packages/deepbook/sources/state/history.move
- packages/deepbook/sources/state/governance.move
- packages/deepbook/sources/state/trade_params.move
这些入口是架构地图上的锚点。先标注每个模块负责的状态,再顺着一次下单或结算回到具体函数。
读架构
state.move 的 State 包含 accounts: Table<ID, Account>、history: History、governance: Governance。State::process_create 是撮合之后的账务中枢:
- 更新治理和历史:
governance.update(ctx)、history.update(...)。 - 处理每个 maker fill:
process_fills会更新 maker 账户、成交量和应结算余额。 - 更新 taker 账户:确保账户存在,读取交易量和 stake。
- 根据
trade_params、账户 stake、历史交易量和 EWMA 惩罚计算 taker fee。 - 如果新订单剩余数量被插入订单簿,则加入 account open orders。
- 调用
order_info.calculate_partial_fill_balances得到本次 taker 的settled和owed。
这说明订单状态和资金状态是分阶段写入的:Book 先改变撮合状态,State 再把成交解释为账户余额变化,Vault 最后才移动真实资产。
阅读补充
State 是撮合之后的会计和参数层。Book 告诉协议成交了什么,State 决定这些成交如何影响 maker/taker 账户、交易量、stake、费率、rebate 和历史统计。
阅读 State 时建议按函数职责拆表:账户 open orders、已结算余额、历史 epoch 数据、治理参数、费率计算。把这些混成一个“状态更新”会让费用来源和最终 owed/settled 难以解释。
工程判断
- 费用问题优先查 trade params、stake、历史交易量和 governance 配置。
- 账户 open orders 与 Vault 资产余额不是同一类状态。
- State 输出的 owed/settled 需要继续交给 Vault 结算。
读完以后问自己
- State 为什么不负责订单簿排序?
- maker/taker fee 计算依赖哪些状态?
owed和settled为什么还不是最终钱包余额?