Defensive block storage for Bitcoin Core. Validates blocks in RAM, strips hazeable content (witness data, scriptSig, OP_RETURN payloads, coinbase arbitrary data), and writes only the structural skeleton to disk. Your node never persistently stores potentially harmful embedded data.
Two modes of operation:
- Exorcism — live hazing: incoming blocks are stripped in real-time after validation, before disk write. The full block data exists only in volatile memory during processing.
- Exorcist — retroactive conversion: converts an existing full archive node (
blk*.dat) into a hazed node (gsb*.dat). Reads blocks, strips them, writes structural archive, securely zeros originals, deletesblk*.datandrev*.datfiles. Irreversible.
Bitcoin blocks can contain arbitrary data embedded in witness fields, scriptSig, OP_RETURN outputs, and coinbase transactions. Some of this data may be illegal to possess in certain jurisdictions (e.g. CSAM, copyrighted material, classified information).
A standard Bitcoin Core node stores every byte of every block to disk permanently. Exorcism provides a defensive alternative: your node validates the full block data (maintaining consensus correctness) but never writes the hazeable content to persistent storage. The on-disk representation contains only the structural data needed for UTXO tracking, block verification, and chain state.
This is not legal advice. Exorcism provides the strongest technical defensive posture available to a node operator — you never "possessed" the hazeable bytes in a storage sense. Whether this constitutes legal protection depends on your jurisdiction. Consult a lawyer.
Incoming block (P2P / RPC)
│
▼
Full validation in RAM (AcceptBlock)
│ ← block is fully validated against consensus rules
▼
Block Stripper (field_classifier → block_stripper)
│ ← strips witness, scriptSig, OP_RETURN, coinbase data
│ ← preserves: block header, tx hashes, output scripts, amounts
▼
Stripped Block → gsb*.dat (on disk)
│
▼
SecureZero (volatile memset)
│ ← zeros the full block data in RAM
▼
Done — hazeable content never touched disk
| File | Purpose |
|---|---|
exorcism.h/cpp |
Live hazing — hooks into validation pipeline, strips after AcceptBlock |
exorcist.h/cpp |
Retroactive conversion — walks blk*.dat, converts to gsb*.dat, zeros originals |
block_stripper.h/cpp |
Stripping engine — removes hazeable fields from blocks |
field_classifier.h/cpp |
Field classifier — decides which transaction fields are hazeable |
stripped_block.h/cpp |
GSB format — the stripped block data structure (Ghost Stripped Block) |
bloom_filter.h/cpp |
Bloom filter — tracks which data was stripped for reconstruction queries |
block_reconstruct.h/cpp |
Reconstruction — fetches original block from network peers on demand |
legal_packet.h/cpp |
Legal Compliance Packet — generates documentation of what was stripped |
mode_selector.h/cpp |
Mode selection — hazed vs full archive operating mode |
rpc/haze.h/cpp |
RPC interface — gethazestatus, exorcise commands |
| Field | Stripped? | Preserved? | Why |
|---|---|---|---|
| Block header | Yes | Needed for chain validation | |
| Transaction hashes | Yes | Needed for merkle tree / tx lookup | |
| Output scriptPubKey | Yes | Needed for UTXO set | |
| Output amounts | Yes | Needed for UTXO set | |
| Witness data | Yes | Can contain arbitrary embedded data | |
| scriptSig | Yes | Can contain arbitrary data (legacy) | |
| OP_RETURN payload | Yes | Arbitrary data by design | |
| Coinbase scriptSig | Yes | Miner-controlled arbitrary data |
The stripped node retains ~99% of operational capability: UTXO lookups, address indexing, balance queries, mempool validation, mining template construction, and block header serving all work normally. The only operations that fail are serving full raw block data to peers (the node can request the original from the network on demand via block_reconstruct).
Phase 1: Strip blk*.dat → read, strip, write gsb*.dat, update block index
Phase 2: Zero blk*.dat → overwrite every byte with 0x00
Phase 3: Cleanup delete blk*.dat and rev*.dat
Features:
- Resumable: writes a checkpoint marker after each block. If interrupted,
Resume()continues from the last successful block. - Progress reporting: callback-based progress updates (blocks processed, percentage, current phase).
- Irreversible by design: after Phase 2, the original data is unrecoverable. This is the point.
The test/ directory contains unit tests and integration tests from the Bitcoin Ghost test suite.
See docs/specification.md for the full Ghost Haze Exorcism specification (v2).
- bitcoin-reaper — dead code detection engine (identifies what Exorcism strips)
- bitcoin-buds — transaction classification and policy filtering
- bitcoin-shroud — transaction relay timing privacy
Extracted from Bitcoin Ghost where Exorcism has been running in production on Bitcoin mainnet nodes since early 2026. The hazing system processes every block during IBD and ongoing operation, ensuring the on-disk block store never contains raw hazeable content.
MIT