Task
dig_sex::reward -- RewardLedger, record, claimed_for, reconcile_from_chain, RecordOutcome -- is implemented, tested and unused.
Wire the ledger half now: persist it on disk per store, record claims idempotently, and make claimed_for answerable.
What is deliberately NOT in scope
The claim mechanism -- how the node actually claims rewards from an on-chain distributor. The user has said those details are coming later. Do not invent them, and do not build a speculative claim path that will have to be torn out.
This is done when the ledger is real, persistent and correct, so the claim path has somewhere to record into once it is specified.
Why the constraints matter
- Chain is authoritative.
reconcile_from_chain exists so on-chain truth overwrites local belief, never the reverse.
- Recording is idempotent. Replaying a chain event must not inflate the total. The crate already carries a revert-proof for this (
replaying_a_chain_event_cannot_inflate_the_total); the persistence layer must not undo the property by, for example, keying rows on insertion order rather than the claim id.
- It fails toward UNDER-counting. If the ledger is unsure it reports less claimed, never more. Over-reporting claimed rewards is a surface that lies about money.
Context
- Persistence belongs with node state under the per-user AppData location, sealed at rest to the user key alongside the rest of node state (NC-2 / NC-3).
- dig-sex
SPEC.md section 2A.
Evidence
A test that fails without the fix: record a claim, restart, assert claimed_for still returns it; then replay the same claim and assert the total is unchanged.
Parent
Orchestrator epic: https://github.com/DIG-Network/dig_ecosystem/issues/3138
Task
dig_sex::reward--RewardLedger,record,claimed_for,reconcile_from_chain,RecordOutcome-- is implemented, tested and unused.Wire the ledger half now: persist it on disk per store, record claims idempotently, and make
claimed_foranswerable.What is deliberately NOT in scope
The claim mechanism -- how the node actually claims rewards from an on-chain distributor. The user has said those details are coming later. Do not invent them, and do not build a speculative claim path that will have to be torn out.
This is done when the ledger is real, persistent and correct, so the claim path has somewhere to record into once it is specified.
Why the constraints matter
reconcile_from_chainexists so on-chain truth overwrites local belief, never the reverse.replaying_a_chain_event_cannot_inflate_the_total); the persistence layer must not undo the property by, for example, keying rows on insertion order rather than the claim id.Context
SPEC.mdsection 2A.Evidence
A test that fails without the fix: record a claim, restart, assert
claimed_forstill returns it; then replay the same claim and assert the total is unchanged.Parent
Orchestrator epic: https://github.com/DIG-Network/dig_ecosystem/issues/3138