fix(xmr): S08c - resume scanning after churn rollback
Resume XMR scanning after a node moves from Ready to Active, including when recovery is interrupted by a restart.
Series context
This is S08c part of the S series tracked in the XMR v3.21.0 launch plan. It addresses Issue 7 from Least Authority’s XMR review.
- Scope: Bifrost’s XMR scanner recovery after churn.
- Follow-up: S08d — extended automatic XMR scanner recovery - remains LATER.
- Launch plan: https://gitlab.com/thorchain/thornode/-/snippets/6058894
The broader S06(!5052) and S08(!5054) checks remain separate.
Problem
When a node becomes Active, Bifrost rolls its scanner back to re-observe recent blocks. The signer keeps its saved position.
For example, Bifrost asks for block 1001 while the signer expects 1003. The signer rejects the older request. Registering the same vault birthday again does not move it back, so scanning stalls until another recovery action moves it forward.
An interrupted recovery can also get stuck if a restart moves Bifrost’s requested height beyond the saved recovery target.
Changes
- Rewind the signer through its existing authenticated endpoint, then replay the required blocks.
- Allow churn rewinds of up to 730 blocks, matching the reviewed signer contract. Replay batches remain 72 blocks by default.
- Check limits before creating or lowering a recovery marker.
- Let unfinished churn recovery follow a later Bifrost request without skipping pending history or losing observations.
- Preserve recovery across lost responses, restarts and delayed acknowledgements.
- Use the configured signer network label for automatic rewinds. This matters when a chainnet signer uses a mainnet Monero daemon.
- Reorg checks start from the highest journal block, replacing the older marker-based check and covering unfinished catch-up.
- Identical observations from fresh scans and saved receipts count once; genuine transaction outputs still add together.
THORNode consensus and ordinary reorg limits are unchanged.
Limits
Rewinds above 730 blocks are rejected without changing the recovery marker. Broader historical recovery and manual cursor relocation remain S08d work.
The release signer must support the reviewed rewind contract. Image selection remains part of the launch deployment work.
Verification
- Full Monero, sidecar, blockscanner and observer mocknet suites passed.
- Tests cover rewind limits, interrupted recovery, durable restarts, retained observations, stale acknowledgements, registration-to-churn recovery, exact amounts, restart after journal commit, rejected handoffs, and receipt cleanup.
- The startup-clamp test replays every pending block from 1001 through 1110.
- The original stall reproduces on
develop. The network-label regression fails before its correction and passes afterwards.