Problem
When every QRInfo attempt fails, MasternodesManager::tick logs a warning and calls complete_pipeline, so the manager reports its phase complete and the client proceeds to SYNCED with no masternode list. InstantSend and ChainLock verification are then silently unavailable for the life of the process, while every consumer sees a fully synced client.
The timeout path has behaved this way for a while. #947 extends the same give-up path to engine-rejected responses (QRInfo failed on every attempt, skipping masternode sync), which widens how often it can be reached, for example a validation divergence like #907 burns the whole budget deterministically on every peer until #934 lands.
The recovery machinery itself is correct, bounded retries against different peers are the right response to untrusted peer input. The gap is purely observability: giving up is indistinguishable from success at the API surface.
Proposal
- Emit a dedicated
SyncEvent (or a degraded flag on MasternodeStateUpdated) when masternode sync is skipped after retry exhaustion, so wallets can surface degraded mode instead of pretending full health.
- Consider a low-frequency background re-attempt after giving up (e.g. next cycle boundary or next peer connect), so a transient network-wide condition does not disable masternode features until restart.
Related: #947, #934, #907.
Problem
When every QRInfo attempt fails,
MasternodesManager::ticklogs a warning and callscomplete_pipeline, so the manager reports its phase complete and the client proceeds toSYNCEDwith no masternode list. InstantSend and ChainLock verification are then silently unavailable for the life of the process, while every consumer sees a fully synced client.The timeout path has behaved this way for a while. #947 extends the same give-up path to engine-rejected responses (
QRInfo failed on every attempt, skipping masternode sync), which widens how often it can be reached, for example a validation divergence like #907 burns the whole budget deterministically on every peer until #934 lands.The recovery machinery itself is correct, bounded retries against different peers are the right response to untrusted peer input. The gap is purely observability: giving up is indistinguishable from success at the API surface.
Proposal
SyncEvent(or a degraded flag onMasternodeStateUpdated) when masternode sync is skipped after retry exhaustion, so wallets can surface degraded mode instead of pretending full health.Related: #947, #934, #907.