fix(key-wallet): re-apply a spend whose coin was funded after it - #1015
fix(key-wallet): re-apply a spend whose coin was funded after it#1015ZocoLini wants to merge 1 commit into
Conversation
Two mainnet restores of the same wallet ended at the same balance with 7112 and 7111 wallet records. Replaying each run's logged block applications offline, against the blocks it stored, reproduced both results exactly, with no divergence from the logs. The missing record was e66553f3…8c9e at height 2 185 057: it pays change to the BIP44 account and spends a CoinJoin coin funded at 2 182 877. When the spend is applied before its funding, the CoinJoin account cannot recognise it. The funding then parks the coin in `spent_before_funded` (#1001), and that only attributes the spend if its block is delivered again. In one run it was (funding at step 1494, spend at 1516); in the other it was not (spend at 1608, funding at 1627, no redelivery), so the result depended on delivery order. `WalletInfoInterface::unrecorded_spend_heights` reports, for a transaction, the heights of the blocks that spent its outputs before it arrived and that the owning account has not recorded yet. `process_block_for_wallets` returns them per wallet in `BlockProcessingResult::reapply_heights`, only heights above the block being applied, so re-applying cannot loop. `BlocksManager` re-applies those blocks from block storage straight away; every downloaded block is stored on arrival. Re-applications emit no `SyncEvent::BlockProcessed` and so never touch a batch's pending-block accounting. Offline, both orderings now end with identical per-account records (7112), with about 105 blocks re-applied from disk per restore. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017DruChNTWXwJoWPartZwCf
|
Warning Review limit reachedNext included review available in 55 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #1015 +/- ##
==========================================
+ Coverage 72.56% 77.36% +4.80%
==========================================
Files 240 329 +89
Lines 63441 83949 +20508
==========================================
+ Hits 46033 64948 +18915
- Misses 17408 19001 +1593
|
Two mainnet restores of the same wallet ended at the same balance with 7112 and 7111 wallet records. Replaying each run's logged block applications offline, against the blocks it stored, reproduced both results exactly, with no divergence from the logs. The missing record was e66553f3…8c9e at height 2 185 057: it pays change to the BIP44 account and spends a CoinJoin coin funded at 2 182 877.
When the spend is applied before its funding, the CoinJoin account cannot recognise it. The funding then parks the coin in
spent_before_funded(#1001), and that only attributes the spend if its block is delivered again. In one run it was (funding at step 1494, spend at 1516); in the other it was not (spend at 1608, funding at 1627, no redelivery), so the result depended on delivery order.WalletInfoInterface::unrecorded_spend_heightsreports, for a transaction, the heights of the blocks that spent its outputs before it arrived and that the owning account has not recorded yet.process_block_for_walletsreturns them per wallet inBlockProcessingResult::reapply_heights, only heights above the block being applied, so re-applying cannot loop.BlocksManagerre-applies those blocks from block storage straight away; every downloaded block is stored on arrival. Re-applications emit noSyncEvent::BlockProcessedand so never touch a batch's pending-block accounting.Offline, both orderings now end with identical per-account records (7112), with about 105 blocks re-applied from disk per restore.