When a peer's getheaders locator yields no headers, zakurad maps the empty result to Response::Nil, which sends nothing on the wire:
|
zs::Response::BlockHeaders(headers) if headers.is_empty() => zn::Response::Nil, |
The getheaders protocol expects a headers reply even when empty (zcashd and Bitcoin Core always send one). With no reply, the requesting zcashd's headers-sync times out ("Peer=1 did not answer getheaders"), and a hard-locked single-peer sidecar enters disconnect/reconnect churn. On a fresh regtest chain (both nodes at genesis) the sidecar never leaves IBD, so its wallet RPCs stay disabled.
On mainnet the impact is bounded: the stall only occurs when the sidecar reaches tip-parity and issues a getheaders that returns empty, and it recovers on the next block inv (~75 s), so it shows up as reconnect churn and log noise rather than a hard failure. On regtest it is fatal.
Reproduce: start zakurad on regtest with a zcashd sidecar (valargroup v1.0.0, sha b861ea94…) pinned via -connect; the sidecar logs the getheaders timeout and never syncs.
Fix reference: fixed upstream in Zebra (ZcashFoundation/zebra#10952, commit de4d3c0e5): always reply with a (possibly empty) headers message. Note that Nil remains correct for getblocks, where sending nothing matches zcashd behavior.
When a peer's
getheaderslocator yields no headers,zakuradmaps the empty result toResponse::Nil, which sends nothing on the wire:zakura/zakurad/src/components/inbound.rs
Line 533 in 7880676
The
getheadersprotocol expects aheadersreply even when empty (zcashd and Bitcoin Core always send one). With no reply, the requesting zcashd's headers-sync times out ("Peer=1 did not answer getheaders"), and a hard-locked single-peer sidecar enters disconnect/reconnect churn. On a fresh regtest chain (both nodes at genesis) the sidecar never leaves IBD, so its wallet RPCs stay disabled.On mainnet the impact is bounded: the stall only occurs when the sidecar reaches tip-parity and issues a
getheadersthat returns empty, and it recovers on the next block inv (~75 s), so it shows up as reconnect churn and log noise rather than a hard failure. On regtest it is fatal.Reproduce: start zakurad on regtest with a zcashd sidecar (valargroup v1.0.0, sha
b861ea94…) pinned via-connect; the sidecar logs the getheaders timeout and never syncs.Fix reference: fixed upstream in Zebra (ZcashFoundation/zebra#10952, commit de4d3c0e5): always reply with a (possibly empty)
headersmessage. Note thatNilremains correct forgetblocks, where sending nothing matches zcashd behavior.