Skip to content

dash-spv: compact-filter sync stalls silently when the only connected peer lacks NODE_COMPACT_FILTERS #815

@QuantumExplorer

Description

@QuantumExplorer

Summary

dash-spv compact-filter sync (BIP157/158) stalls indefinitely and silently when the only connected peer does not advertise the NODE_COMPACT_FILTERS service bit. Block-header sync (which doesn't need the capability) reaches the chain tip, but Filter Header / Filter sync freezes ~2,000 blocks short of tip, so the wallet never sees transactions/UTXOs in recent blocks. The request processor logs No peers support required capability and the download coordinator retries the same item 20+ times forever, never connecting to additional peers to find a capable one and never surfacing a terminal error.

Environment

  • dash-spv pinned rev 5c0113e7901551450f6063023eec4be95beeb6b9
  • Network: testnet
  • Consumer: SwiftDashSDK / SwiftExampleApp (dashpay/platform) on an iOS Simulator, but the stall is entirely in dash-spv's peer-selection + filter download.

Symptom

  • Headers: 1,499,648/1,499,644 (100.0%) — reaches tip ✅
  • Filter Headers: 1,497,593/1,499,648 (99.9%) processed: 0, last_activity: 210sfrozen ~2,055 blocks behind tip, never advances (persists across client Pause/Start and Clear).
  • Consequence: a freshly-funded address (faucet tx in a recent block) never appears as spendable, so anything needing recent UTXOs (asset-lock funding, receiving) is blocked, and the client looks hung with no error surfaced to the consumer.

Root cause (from logs)

Only one peer is connected, and it lacks compact-filter support:

INFO  dash_spv::network::peer: Updated peer info for 91.92.199.202:15333: height=1499644, version=70240, services=ServiceFlags(7173)
INFO  dash_spv::network::manager: Successfully connected to 91.92.199.202:15333
INFO  dash_spv::sync::sync_coordinator: Spawning FilterHeader task, receiving message types: [CFHeaders]
ERROR dash_spv::network::manager: Request processor: failed to send message: Protocol error: No peers support required capability
ERROR dash_spv::network::manager: Request processor: failed to send message: Protocol error: No peers support required capability   (x128)
WARN  dash_spv::sync::download_coordinator: Retrying item (attempt 1) ... (attempt 20+)

ServiceFlags(7173) = 0x1C05 = bits 0,2,10,11,12 → NODE_NETWORK (1) | NODE_BLOOM (4) | NODE_NETWORK_LIMITED (1024) | 2048 | 4096. Bit 6 (NODE_COMPACT_FILTERS, value 64) is NOT set. So GetCFHeaders/GetCFilters can't be sent to this peer, every attempt fails with No peers support required capability, and the coordinator just keeps retrying the same item.

Why it's a bug (two parts)

  1. Peer selection. When compact-filter sync is enabled, dash-spv connects to (and stays on) a single peer that doesn't advertise NODE_COMPACT_FILTERS, and never opens additional connections / rotates peers to find a filter-capable one. On testnet (where filter-serving nodes are sparse) this reliably wedges filter sync.
  2. Failure handling / surfacing. The download coordinator retries the same item indefinitely (20+ attempts observed) with no backoff escalation to a terminal, surfaced error and no trigger to re-select peers. To the consumer the client is indistinguishable from a hang — the progress bar simply freezes with no event/error.

Suggested fixes

  • When NODE_COMPACT_FILTERS is required for the active sync mode, require/prefer peers advertising it during peer selection, and proactively open additional connections / rotate peers until a capable one is found (instead of getting stuck on a single incapable peer).
  • Bound the retry loop: after N failures with No peers support required capability, either re-trigger peer discovery for a capable peer or emit a terminal error/event the consumer can react to.
  • Surface a distinct NoCompactFilterPeers (or similar) status/event so UIs can show "searching for a compact-filter peer…" / an actionable error rather than a frozen progress bar.

Repro

  1. testnet, compact-filter sync enabled.
  2. Connect such that the only reachable/selected peer advertises services without bit 6 (NODE_COMPACT_FILTERS) — e.g. ServiceFlags(7173).
  3. Header sync reaches tip; Filter Header sync stalls ~2k blocks short; logs spam No peers support required capability + Retrying item. No recovery across client restart/clear.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions