Repository navigation
fix(scanner): decrement Staked by the full balance before zeroing it - #2140
Conversation
|
🔍 OpenCodeReview found 3 issue(s) in this PR.
📄
|
Stake-pool spends zeroed the stored pool record before reading the pledge for the statistic decrement, so the Staked statistic was never decremented when a pool was closed. Capture the pool's full stake balance (pledge plus accumulated staker rewards) before decommissioning and decrement with that, matching what creation and block rewards add. Both spend paths are covered: pool outputs spent as regular transaction inputs and pool outputs spent as block-reward outputs. The same fix is mirrored in the sync simulation's statistics model. Regression test covers decommissioning all three spend shapes with the statistic checked after every block, including a delegation that outlives its pool.
1b2eb92 to
2b6d134
Compare
Root cause
Both stake-pool spend handlers in
api-server/scanner-lib/src/blockchain_state/mod.rszeroed the stored pool record before reading the pledge for the statistic decrement, so the decrement always subtracted zero:PoolData::decommission_pool()zeroespledge_amountandstaker_rewards, sopledge_amount()read after the call is alwaysAmount::ZERO.Impact
Every pool closure leaves its full stake-at-death in the public
stakedstatistic forever. On mainnet the statistic currently exceeds the real staked supply by ~33M ML (~17%), consistent with ~170 dead pools × ~179k ML.Fix
A shared helper
decommission_pool_and_decrement_stakednow captures the pool'sstaker_balance()(pledge plus accumulated staker rewards — matching what creation and block rewards add to the statistic) before decommissioning, then decrementsStakedwith it:OutPointSourceId::Transactionbranch: pool outputs spent as regular transaction inputs.OutPointSourceId::BlockRewardbranch: pool outputs spent as block-reward outputs (keeps the existing address-transactions bookkeeping via the returned record's decommission destination).The stored record is still zeroed exactly as before (
decommission_poolsemantics unchanged); only the decrement source is corrected. The sync simulation's statistics model was updated to mirror the same behavior (it previously never decremented on pool spends at all).Test evidence
decommission_and_delegation_spends_update_staked_statistic(api-server/scanner-lib/src/sync/tests/mod.rs): 9-block scenario covering pool-creation pledges, pool spends of both shapes (Transaction-sourced andBlockReward-sourced), the stake-spend maturity lock, a delegation that outlives its pool, and a delegation spend after the pool is gone — with theStakedstatistic asserted after every block and decommissioned records checked for zeroed pledge/balance.simulation.rsmodel updated to decrement on pool spends; the whole sync simulation suite passes against the scanner.cargo test -p pos-accounting -p api-blockchain-scanner-lib -p api-server-backend-test-suite: 46 passed, 0 failed.cargo clippy --all-targetsclean;./do_checks.shclean.Known follow-up (out of scope)
Databases that already synced with the previous code keep the permanently overstated statistic — no storage-version bump in this PR, so existing deployments are not forced into a full reindex. Repairing the historical mainnet value needs a reindex/migration decision (or a targeted statistic rebuild) and should be tracked separately.
Delegation accounting is unaffected: the delegation-spend decrement is separate and already correct.