Compact Block Filter Header
A commitment to a chain of compact block filters enabling light clients to verify filter correctness without downloading full blocks.
Key Takeaways
- Compact block filter headers form a hash chain that commits to every compact block filter in a blockchain's history, allowing light clients to verify that peers are serving correct filters without downloading full blocks.
- Each filter header is computed as the double-SHA256 of the filter hash concatenated with the previous filter header, creating an authenticated chain that makes it impossible to tamper with a single filter without invalidating every subsequent header.
- Defined in BIP 157 alongside the client-side block filtering protocol, filter headers replace the privacy-leaking Bloom filter approach of BIP 37 by shifting all transaction matching to the client side.
What Is a Compact Block Filter Header?
A compact block filter header is a 32-byte hash that serves as a commitment to a specific block's compact block filter and to the entire chain of filters before it. Light clients use filter headers to detect whether a peer is serving fake or incomplete filters, providing a verification layer that does not require downloading full blocks or trusting a single server.
The concept was introduced in BIP 157 (Client Side Block Filtering), authored by Olaoluwa Osuntokun, Alex Akselrod, and Jim Posen. While its companion specification BIP 158 defines how to construct the filters themselves using Golomb-coded sets, BIP 157 defines the peer-to-peer protocol for requesting and verifying those filters: this is where filter headers play their central role. Together, these two BIPs replaced the older BIP 37 Bloom filter model, which required clients to reveal their addresses to serving nodes.
The term "compact block filter header" is sometimes shortened to "cfheader" in developer documentation and protocol messages. It should not be confused with the block header, which commits to a block's transactions via a Merkle root. Filter headers live in a separate, parallel chain that commits to filter data rather than transaction data.
How It Works
Understanding filter headers requires knowing the two-layer structure of the compact block filter protocol. BIP 158 defines the filter: a compact, deterministic representation of a block's relevant data (primarily scriptPubKeys) encoded as a Golomb-coded set. BIP 157 defines how clients request and verify those filters using the filter header chain.
Filter Header Construction
Each filter header is derived from two inputs: the hash of the current block's filter and the previous block's filter header. The computation is:
filter_header = double-SHA256(filter_hash || previous_filter_header)
// For the genesis block (height 0):
previous_filter_header = 0x0000...0000 (32 zero bytes)
// For all subsequent blocks:
previous_filter_header = filter_header of block at (height - 1)This recursive structure creates a hash chain analogous to how block headers link to their predecessors. Changing a single filter at any height invalidates its filter header and every filter header that follows, making retroactive tampering immediately detectable.
The P2P Protocol Messages
BIP 157 defines three pairs of request/response messages for filter header exchange:
getcfheaders/cfheaders: the client requests filter headers for a range of blocks. The response includes the previous filter header (as the starting point) plus a list of filter hashes for each block in the range. The client then recomputes the headers locally and verifies the chain links.getcfilters/cfilter: once filter headers are verified, the client requests the actual filters and checks each filter's hash against the corresponding header.getcfcheckpt/cfcheckpt: the client requests filter headers at every 1,000-block interval. These checkpoints allow parallel verification: the client can download filter headers for different ranges from different peers and verify each range against the checkpoints.
Multi-Peer Verification
Filter headers are not committed to by consensus: they do not appear inside block headers and are not validated by the Bitcoin network's consensus rules. This means a malicious peer could, in theory, serve a self-consistent but entirely fabricated filter header chain.
The defense is multi-peer cross-checking. BIP 157 recommends that clients connect to multiple outbound peers and compare their filter headers. If peers disagree on a filter header for a given block height, the client can download the full block from either peer, reconstruct the filter locally using the deterministic BIP 158 algorithm, and determine which peer lied. The dishonest peer is then banned.
With at least one honest peer in the set, the client is guaranteed to detect and reject fraudulent filters. This is a weaker security model than full block validation but significantly stronger than the BIP 37 approach, where a malicious peer could omit transactions without detection.
Comparison with Bloom Filters (BIP 37)
Before compact block filters, SPV clients used BIP 37 Bloom filters to request relevant transactions from full nodes. That approach had two major problems:
| Property | BIP 37 (Bloom Filters) | BIP 157/158 (Compact Block Filters) |
|---|---|---|
| Privacy | Client sends filter to server, revealing which addresses it watches | Server sends filter to client; server learns nothing about client interests |
| Filter generation | Per-client: server builds a unique filter for each client request | Per-block: server builds one deterministic filter reused by all clients |
| Verification | None: server can omit transactions and client cannot detect it | Filter header chain enables cross-peer verification |
| DoS resistance | Low: each client request costs server CPU and disk I/O | High: filters are precomputed and cached |
| Bandwidth | Lower per query (only matching transactions returned) | Higher per query (entire filter downloaded, matching blocks fetched) |
Bitcoin Core disabled BIP 37 Bloom filter serving by default in version 0.19.0 (released in 2019), effectively deprecating the approach for new wallet implementations. The compact block filter model defined by BIP 157/158 is now the standard for privacy-conscious light clients.
Use Cases
Mobile Lightning Wallets
Mobile lightweight clients benefit most from compact block filter headers. Lightning Labs' Neutrino implementation, built on BIP 157/158, powers LND's light client mode and enables wallets like Blixt to run a near-full Lightning node directly on a mobile device. The filter header chain allows these wallets to sync the blockchain privately, downloading only the blocks that contain relevant transactions.
Privacy-Preserving Chain Scanning
Wallets recovering from a seed phrase need to scan the entire blockchain for transactions matching their derived addresses. With compact block filters, this scan happens locally: the wallet downloads filters, matches them against its own addresses, and only fetches the few blocks that produce matches. The filter header chain ensures the wallet can trust the filters it downloads by cross-checking with multiple peers.
Efficient Initial Sync
The checkpoint mechanism (getcfcheckpt) allows new clients to parallelize their initial sync. By fetching filter header checkpoints at 1,000-block intervals from one peer, the client can request detailed filter headers for each interval from different peers simultaneously. Each range is independently verifiable against its bounding checkpoints, reducing sync time significantly compared to sequential downloading.
Adoption and Implementation Status
BIP 157 and BIP 158 are both listed as "Deployed" in the Bitcoin Improvement Proposal repository. However, adoption across implementations varies:
- Bitcoin Core supports building the compact block filter index via the
-blockfilterindexoption and serving filters to peers via-peerblockfilters, but both remain disabled by default. Node operators must explicitly enable them. - Neutrino (Lightning Labs) is the most mature client-side implementation, written in Go and integrated into LND. It performs full BIP 157/158 filter header verification with multi-peer cross-checking.
- btcd, the Go-based full node, natively serves compact block filters and is commonly used as a backend for Neutrino clients.
- Wallet implementations including Wasabi Wallet and various Lightning mobile wallets use compact block filter headers for chain synchronization.
The fact that Bitcoin Core does not enable filter serving by default means the set of peers offering compact block filters is smaller than the overall Bitcoin network. This can make peer discovery harder for light clients relying on the protocol, though dedicated filter-serving nodes partially compensate.
Risks and Considerations
No Consensus-Level Commitment
The most significant limitation of compact block filter headers is that they exist outside of Bitcoin's consensus rules. Block headers do not commit to filter data, so there is no way to prove a filter is wrong using only block headers. Security relies entirely on the honest majority assumption among connected peers: if all of a client's peers collude, they can serve a fabricated filter header chain without detection.
Proposals to embed a filter commitment in the coinbase transaction or in a future soft fork have been discussed but not adopted. Adding such a commitment would make filter verification as strong as Merkle proof verification, but it would also require a consensus change.
Bandwidth Overhead
Compact block filters are significantly more bandwidth-efficient than downloading full blocks, but they still require downloading the filter for every block, regardless of whether it contains relevant transactions. For the basic filter type, each filter is typically a few kilobytes. Over hundreds of thousands of blocks, this accumulates to several gigabytes of filter data for a full initial sync from the genesis block.
False Positive Rate
Golomb-coded set filters have a tunable false positive rate. The basic filter type uses parameters that produce a match probability of roughly 1 in 784,931 per item. While this is very low, false positives still occur: the client occasionally downloads a full block only to find no relevant transactions. This is a privacy-bandwidth tradeoff: lower false positive rates would require larger filters.
Eclipse Attack Vulnerability
If an attacker controls all of a light client's peer connections (an eclipse attack), they can serve arbitrary filter headers and filters. The multi-peer verification defense only works when at least one peer is honest. Light clients should use diverse peer discovery methods and, where possible, connect to at least one trusted node to mitigate this risk.
Further Reading
- Compact Block Filters: How Neutrino Light Clients Query Bitcoin Privately
- Bitcoin Light Clients: SPV, Neutrino, and Compact Block Filters
- BIP 157: Client Side Block Filtering
- BIP 158: Compact Block Filters for Light Clients
This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.