Light clients & filters
Mobile and browser wallets, asset holders and devices shouldn't have to run a full node. Arrekta uses BIP 157/158-style compact block filters, with one improvement over Bitcoin: every filter is committed in the block, so a light client checks it against proof of work instead of trusting the peer that served it (§9.5).
What a filter contains
- every non-burn output lock in the block (coinbase included);
- every spent output's lock;
- every non-ARRK asset id among the outputs, as
"A" ‖ asset_id, so "watch asset X" works.
Items are hashed into a Golomb-coded set (P = 19, M = 784,931) keyed by the parent block hash.
Filters chain into filter headers:
filter_header(b) = TH("filter/header", TH("filter", filter_b) ‖ filter_header(parent)).
The commitment
From height 1, the coinbase's last burn output with a 36-byte payload starting "ARKF" must
carry the block's filter header (bad-cb-filter otherwise). The
coinbase is covered by the block's merkle root and therefore by its proof of work.
How a light client syncs
- Sync headers (headers-first, each with its AuxPoW).
- Fetch filter headers from several peers and compare them.
- Download filters and check each against its header; check the header against the coinbase commitment using the coinbase and its merkle branch.
- Fetch only the full blocks whose filters match its locks or assets.
The server never learns which addresses the client watches (unlike BIP 37 bloom filters).
Where to get filters
| Transport | Route |
|---|---|
| REST | GET /v1/blocks/{id}/filter (filter, header, coinbase, merkle branch) and GET /v1/filters/headers?start=&count= (Light clients API) |
| P2P | GETCFILTERS / CFILTER / GETCFHEADERS / CFHEADERS, nodes with services bit NODE_FILTERS (4) |
The SDKs provide verifyFilter, matchFilter, verifyMerkleBranch and verifyCheckpoint; see
the Light client guide.