Repository navigation
Conversation
1aa326e to
9e6fbb5
Compare
8c879a6 to
867bbec
Compare
9e6fbb5 to
959ff76
Compare
959ff76 to
9eeb645
Compare
867bbec to
4caa4eb
Compare
9eeb645 to
fae1e7b
Compare
454b09c to
d9c9caa
Compare
fae1e7b to
37d135e
Compare
d9c9caa to
c493e0a
Compare
37d135e to
869c34f
Compare
c493e0a to
61dfd9c
Compare
869c34f to
3563acf
Compare
61dfd9c to
a29b6d6
Compare
3563acf to
0b8d60f
Compare
7aa0307 to
96f3a85
Compare
a90dc8e to
4fb93a7
Compare
4fb93a7 to
0598569
Compare
54242b8 to
0f33135
Compare
0598569 to
0ecfd08
Compare
0f33135 to
2b07fdc
Compare
0e2daec to
9bf378b
Compare
2b07fdc to
551dd28
Compare
9bf378b to
fa35088
Compare
551dd28 to
1f2a15c
Compare
fa35088 to
694558a
Compare
1f2a15c to
37e33e6
Compare
694558a to
3c63ab0
Compare
37e33e6 to
2fc2f90
Compare
|
@rain-marvin review |
|
🔎 Reviewing |
There was a problem hiding this comment.
This PR splits the receipt backfill pass into two steps. It still reads the receipt balances in parallel, at most 4 at a time and pinned to the read block. Then it writes the discoveries to the vault's single inventory aggregate one at a time, in the order the logs were collected. Before, up to 4 writers loaded and persisted the same aggregate at once. A big pass, such as the restart after a rollback, could use up the 3-attempt conflict retry budget and stop startup. The PR also adds a 65-receipt regression test and a SPEC note.
Overall read: the fix is correct and the right size. During run_startup_recovery the backfill is the only writer to the aggregate, because the live monitors, periodic backfills and redemption workers start after it returns. So serial writes remove the conflict at its source. buffered keeps the collection order, so unique_by and the ITN duplicate-deposit check now treat the earliest deposit as canonical every time. The reconciliation loop was already serial. The open thread about try_collect dropping finished reads is not a defect: no durable progress is lost, the checkpoint does not move, and the next pass redoes the same idempotent range. No new findings.
claude-opus-5-5 · high · 12 min
3c63ab0 to
8f8799d
Compare
a481944 to
ed56f2f
Compare
|
@rain-marvin review |
|
🔎 Reviewing |
There was a problem hiding this comment.
This PR splits receipt backfill discovery into two steps: the pinned balanceOf reads still run concurrently (now buffered so they keep log order, with try_collect), and the writes to the vault's single inventory aggregate (ITN duplicate check, DiscoverReceipt, ReconcileBalance, mint-recovery callback) now run one at a time. Before this, four concurrent writers on one aggregate could use up the three-attempt optimistic-concurrency retry budget, and a large pass (the restart after a rollback) would fail and stop startup.
Overall read: the change does what it says and is about as small as it can be while keeping reads concurrent. The new 65-receipt test was run against the base code and fails there with AggregateConflict after the retries run out; on this head it passes repeatedly. At startup the backfill is the only writer to the aggregate, because the redemption and mint workers start after run_startup_recovery, so the startup failure cannot recur from inside the pass. Sequential writes also make the ITN duplicate-deposit check deterministic when two deposits for the same request land in one pass. Checkpoint behavior is unchanged: a failed read or write still leaves the checkpoint where it was. The two earlier try_collect threads were already settled and nothing in the code changes that. No findings.
claude-opus-5-5 · high · 24 min
|
@CodeRabbit review |
✅ Action performedReview finished.
|
Merge activity
|
…n one pass finds many receipts

Backfill passes now serialize writes to the vault's inventory aggregate, eliminating optimistic-concurrency races that could stop the service at startup. Restarts after rollbacks find every returned receipt in one pass, and concurrent writes to the same aggregate were losing the race on every retry. Reads still run concurrently; only the aggregate writes run sequentially. Fixes RAI-2835. This is the top of a 10-PR stack.
Closes RAI-2835
Contributes to RAI-2601
Contributes to RAI-1215
Live effect: Service restarts after rollbacks succeed instead of failing on optimistic-concurrency conflicts. · Risk: Low (changes backfill write order, no money or keys). · Ships: On merge. · Blocks: None.
Decisions
Risks
Proof
Rollout
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.