Skip to content

Fix get_client_filters livelock in protocol_filter_out_70015#1071

Open
echennells wants to merge 1 commit into
libbitcoin:masterfrom
echennells:fix-filter-out-70015-getdata-livelock
Open

Fix get_client_filters livelock in protocol_filter_out_70015#1071
echennells wants to merge 1 commit into
libbitcoin:masterfrom
echennells:fix-filter-out-70015-getdata-livelock

Conversation

@echennells

Copy link
Copy Markdown

Bug

handle_receive_get_filters returns false after dispatching a response, unsubscribing from get_client_filters. send_filter then re-subscribes via SUBSCRIBE_CHANNEL once the ancestry is exhausted. Because that resubscribe happens inside the notify cycle, the handler is re-entered for the same in-flight message — the same consume-one / produce-one loop as the protocol_transaction_out_106 get_data livelock.

This is the bip157 compact-filter sibling of that bug — the identical resubscribe-during-notify pattern, found by inspection after it. Unlike the tx_out case it is latent, not reproduced: protocol_filter_out_70015 only attaches when the node advertises node_client_filters and the peer negotiates bip157, and a default node advertises neither (protocol_maximum caps at bip130 and filters are off). It becomes reachable only when the node is configured as a compact-filter server ([peer] protocol_maximum = 70015 plus the node_client_filters service bit). Confirmed by source inspection and structural identity to the proven tx_out fix; not exercised live.

Fix

  • handle_receive_get_filters: return true (stay subscribed) instead of return false.
  • send_filter: drop the per-request SUBSCRIBE_CHANNEL resubscribe on completion.

Mirrors the protocol_transaction_out_106 fix (#1070). The other two handlers in this protocol (get_filter_checkpoint, get_filter_headers) already return true and are unaffected.

handle_receive_get_filters returned false (desubscribe) after dispatching a
response, and send_filter resubscribed via SUBSCRIBE_CHANNEL when the ancestry
was exhausted. The resubscribe runs inside the notify cycle, re-entering the
handler for the in-flight message and pegging a core (100% CPU livelock).

Stay subscribed (return true) and drop the per-request resubscribe. This is the
BIP157 compact-filter sibling of the protocol_transaction_out_106 get_data fix;
the other two handlers here (get_filter_checkpoint, get_filter_headers) already
return true and are unaffected.
@evoskuil

evoskuil commented Jul 3, 2026

Copy link
Copy Markdown
Member

The fix doesn’t seem to address why the subscription is being dropped while a notification is being handled. The channel must not accept another request on the protocol type while one is being handled. This opens the node up to DoS by way of memory exhaustion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants