preserve sp scan cache cancellation across widening rollback
What changed, and why it matters
This commit fixes a small logic bug in how Sparrow Wallet caches scans for silent payments (a privacy-preserving way to receive Bitcoin). During a specific multi-step process called 'widening rollback,' if the user or a server disconnect had already cancelled the scan, the code could accidentally un-cancel it and restore old cached data. The fix simply checks 'if already cancelled, stay cancelled' before restoring the snapshot. It is a correctness/reliability fix rather than a direct theft-of-funds vulnerability, but it could cause the wallet to miss or misreport silent-payment transactions after a cancellation.
Treat as a low-to-moderate reliability fix. Users relying on silent payments should upgrade to a release containing this commit to avoid scenarios where a cancelled scan is inadvertently resumed from stale cache state. No immediate emergency response is warranted absent evidence of active exploitation.
Security signals we found
State resurrection bug in concurrency/caching logic
Cancellation signal could be lost during rollback
Fix touches privacy-sensitive silent payment scanning
No input validation or cryptographic change
Evidence from the diff
SilentPaymentsScanCache.restoreFromSnapshot() now returns early if state == State.CANCELLED. Previously, after a snapshot was captured and before restoreFromSnapshot ran, cancelSilentPaymentScans() (e.g., triggered by server disconnect) could set state to CANCELLED and signal the condition. The subsequent restoreFromSnapshot would then overwrite state with snapshot.state, effectively resurrecting a pre-cancellation cache and losing the cancellation signal. The patch preserves the cancellation and avoids restoring stale snapshot state. No further condition signal is needed because cancellation already signalled both conditions.
Changed components
src/main/java/com/sparrowwallet/sparrow/net/SilentPaymentsScanCache.javaSilent Payments scanning cache state machineWallet transaction discovery / UTXO detection for silent paymentsInspect captured patch +7 / −0
diff --git a/src/main/java/com/sparrowwallet/sparrow/net/SilentPaymentsScanCache.java b/src/main/java/com/sparrowwallet/sparrow/net/SilentPaymentsScanCache.java
index 8ecdc68..05035cf 100644
--- a/src/main/java/com/sparrowwallet/sparrow/net/SilentPaymentsScanCache.java
+++ b/src/main/java/com/sparrowwallet/sparrow/net/SilentPaymentsScanCache.java
@@ -142,6 +142,13 @@ class SilentPaymentsScanCache {
*/
void restoreFromSnapshot(Snapshot snapshot) {
assert lock.isHeldByCurrentThread();
+ //If the cache was cancelled between captureSnapshot and now (e.g., a server disconnect ran
+ //cancelSilentPaymentScans during the widening RPC), preserve the cancellation rather than
+ //resurrecting a CANCELLED cache to its pre-widening state. Cancel already signalled both
+ //conditions, so no further signal is needed here.
+ if(state == State.CANCELLED) {
+ return;
+ }
state = snapshot.state;
serverStart = snapshot.serverStart;
entries.clear();
Why this scored 31/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.