pub struct WanningState { /* private fields */ }Expand description
闸 + 审计日志 + 时钟的运行时状态。
Implementations§
Source§impl WanningState
impl WanningState
Sourcepub fn new(clock: SharedClock) -> Self
pub fn new(clock: SharedClock) -> Self
纯内存状态(无审计落盘)。回放与测试用。
Sourcepub fn with_wal(
clock: SharedClock,
wal_path: impl AsRef<Path>,
) -> Result<Self, CoreError>
pub fn with_wal( clock: SharedClock, wal_path: impl AsRef<Path>, ) -> Result<Self, CoreError>
带审计落盘的状态。WAL 打开为追加模式,绝不截断。
Sourcepub fn live(wal_path: impl AsRef<Path>) -> Result<Self, CoreError>
pub fn live(wal_path: impl AsRef<Path>) -> Result<Self, CoreError>
生产状态:系统时钟 + 审计落盘。
注意:不回放已有 WAL——闸从空开始,只往后追加。适合「一次进程一次新账」
的 demo 场景;长期服务重启要接续旧账,用 WanningState::live_resuming。
Sourcepub fn live_resuming(wal_path: impl AsRef<Path>) -> Result<Self, CoreError>
pub fn live_resuming(wal_path: impl AsRef<Path>) -> Result<Self, CoreError>
断点续跑:先整体回放已有 WAL 对账(损坏/篡改/不一致 → fail-closed 拒启), 再换回系统时钟、继续往同一份 WAL 追加。
长期服务(MCP server)重启时用它:账本、撤销、nonce 登记全部从审计接续, 绝不带着一张空账本接着判——否则重启会把 nonce 洗白、把撤销掉的授权复活。
同一份 WAL 同时至多一个活着的写进程(Wal::open 自动持单写者锁):
第二个进程 fail-closed 拒启(CoreError::WalLocked)。两个平台并挂同一份
WAL(.mcp.json + .trae/mcp.json)就是真实场景——并发双闸的内存账本
互不知情,预算硬上限会被合力突破(实测见 tests/single_writer.rs)。
与 WanningState::replay 的区别:replay 冻结在「过去的世界」(注入时钟停在
最后一条记录的 ts、不挂 WAL);本方法校验过后回到「现在的世界」(系统时钟,
继续写审计)。
pub fn gate(&self) -> &Gate
pub fn wal_path(&self) -> Option<&Path>
Sourcepub fn wal_line_count(&self) -> Option<u64>
pub fn wal_line_count(&self) -> Option<u64>
WAL 当前行数;无 WAL 时为 None。审计证据的「WAL 偏移」即行号。
Sourcepub fn last_wal_line(&self) -> Option<u64>
pub fn last_wal_line(&self) -> Option<u64>
最近一次追加的 WAL 行号(1-based);无 WAL 时为 None。
Sourcepub fn audit_chain_tail(&self) -> Option<u64>
pub fn audit_chain_tail(&self) -> Option<u64>
审计完整性链的链尾值(最后一条记录的链值;无 WAL 时为 None)。
对账证据之一:实时侧这个值,与读侧 read_verified
独立重算的链尾必须相等——逐行成链,改历史行而不重算后续整条链,当场现形。
Sourcepub fn register_delegation(
&mut self,
delegation: Delegation,
) -> Result<(), CoreError>
pub fn register_delegation( &mut self, delegation: Delegation, ) -> Result<(), CoreError>
注册委托:先确认必成,再写审计,再入闸(write-ahead)。
Sourcepub fn revoke(&mut self, delegation_id: &str) -> Result<(), CoreError>
pub fn revoke(&mut self, delegation_id: &str) -> Result<(), CoreError>
撤销委托(kill switch):先确认必成,再写审计,再撤销。
Sourcepub fn decide(
&mut self,
intent: &SpendIntent,
) -> Result<GateDecision, CoreError>
pub fn decide( &mut self, intent: &SpendIntent, ) -> Result<GateDecision, CoreError>
判定一笔消费意图:evaluate → 写审计 → commit(write-ahead)。
返回闸的判定。注意失败语义:
- 审计写失败 →
Err,状态零变更(这笔消费没有发生,也不能发生); - 审计写成功但 commit 失败(理论不可达)→
Err,WAL 领先于账本, 回放侧只会更严格,不会放水。
Sourcepub fn state_hash(&self) -> u64
pub fn state_hash(&self) -> u64
闸状态指纹(FNV-1a 64,非密码学,仅用于确定性对账)。
覆盖:委托集、账本、撤销集、nonce 登记集、策略运行时状态(W-27 速率 窗口时刻与类目台账——随 commit 演化的状态必须进指纹,否则「速率窗口跨 重启被洗掉」这类回放缺失对账不出来);全部按有序迭代序列化, 因此「同一份 WAL 回放两遍 hash 必相同」由构造保证。