Skip to content
blockchain-compression cargo add →

crate · blockchain-compression · v0.1 · MIT

State bloat is a storage problem.
Compress it up to 60:1 on archival Solana data.

Every high-throughput chain grows faster than storage gets cheap. blockchain-compression pairs Zstandard with a custom dictionary of Solana byte patterns — program IDs, instruction discriminators, lamport amounts, Base58 — so archive nodes, indexers, and DePIN storage networks keep and move less data. The one measured headline is up to 60:1 on archival workloads with MaxCompression. Other preset ranges are illustrative and depend on how repetitive your input is: the README reports 20–60:1 with MaxCompression, 15–40:1 for account snapshots, and 10–30:1 for transactions.

// ratio range by preset (from README)

lower = better compressed size

FastCompression
5–15:1
Transactions
10–30:1
Instructions
10–25:1
Accounts
15–40:1
Mixed
12–35:1
MaxCompression
20–60:1

// the problem

State grows forever. Storage budgets don't.

A high-throughput chain adds state every slot and never gives it back. Full history becomes terabytes, then tens of terabytes, and the people who keep that history online — archive-node operators, indexers, explorers, and the DePIN storage networks paid to hold it — carry the bill. Generic compressors help, but they don't know what a chain looks like: a vanilla zstd encoder discovers some structure within a single block, never learns anything across blocks, and has no opinion about the same program IDs, signature shapes, and lamport amounts that repeat billions of times. Closing that gap is cheaper archival and cheaper data movement — which, as chains scale, is core infrastructure. That is the entire reason this library exists.

// archival

Cold storage scales with the chain

Account-state snapshots accumulate for the life of the network. Once you are holding terabytes of write-once history, a high archival ratio is the difference between a flat storage line and a cost curve that tracks block height.

// data movement

DePIN networks pay to move bytes

Decentralized storage and RPC networks are billed on what they hold and what they replicate across peers. Fewer bytes on the wire means cheaper replication and less bandwidth burned shipping the same repeated program IDs to every node.

// serving history

Explorers and indexers query the tail

Indexers warehouse the firehose of decoded transactions; explorers serve the long tail of history. Smaller stored size keeps more of the chain on warm disk, so fewer queries pay the cold-tier round-trip.

// what's in the dictionary

Hardcoded Solana patterns, not online training.

The dictionary is built once at SolanaCompressor::new() from a fixed list of byte patterns. That list lives in src/presets/solana.rs. No per-customer state, no online learner, no model file shipped beside the binary. The same dictionary on every install — deterministic round-trip by construction.

Zstandard receives that dictionary at encoder construction time and uses it as a reference pool. Byte sequences that match the dictionary become tiny back-references in the output stream.

// SOLANA_DICTIONARY_PATTERNS

Program IDs System, Token, Associated Token, Serum DEX, BPF Loader, Config, Vote, Stake
Instruction markers Transfer, Initialize, Close, Approve
Common amounts 0.01, 0.1, 1, 10 SOL (encoded in lamports)
Structure markers Signature-count headers (single, double, triple)
Character set Base58 alphabet used in Solana address encoding
// src/presets/solana.rs (excerpt)
const SOLANA_DICTIONARY_PATTERNS: &[&str] = &[
    "11111111111111111111111111111112",      // System Program
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token Program
    "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", // Associated Token
    "Vote111111111111111111111111111111111111111", // Vote Program
    "Stake11111111111111111111111111111111111111", // Stake Program
    "00e1f50500000000",                       // 1 SOL in lamports
    "00ca9a3b00000000",                       // 0.1 SOL in lamports
    // ... transfer / initialize / close / approve discriminators
];

// how it works

A chain-agnostic core, a Solana dictionary on top.

The crate layers a generic pattern engine under a Solana-specific preset. Bytes flow through a compression strategy that references the dictionary, then Zstandard emits the stream. Nothing in the pipeline knows about a running validator.

input bytes account / tx data SolanaCompressor presets/solana.rs CompressionStrategy core/ pattern engine Zstd + dictionary back-references compressed 10–60:1 SOLANA_DICTIONARY program IDs · Base58 ✓ decompress() returns the exact original bytes — round-trip verified on every operation

// core/

Chain-agnostic engine

The CompressionStrategy trait and a generic pattern engine. No chain knowledge lives here — it is reusable machinery.

// algorithms/

Aggressive passes

EnhancedCTW, MultiPassCompressor, and PracticalMaxCompression back the higher presets.

// presets/solana.rs

The production path

SolanaCompressor builds the Zstd dictionary at init and passes it to the encoder. This is what you use in practice.

Read the full architecture →

// presets

Six presets. Each one a Zstd level plus the same dictionary.

Ratios below are the README's published ranges. Real numbers depend on how repetitive your input is — a single random EVM payload won't compress like a batched Solana account dump.

Preset Zstd level Reported ratio Best for
FastCompression 3 5–15:1 Real-time processing
Transactions 3 10–30:1 Transaction data
Instructions 6 10–25:1 Program instructions
Accounts 6 15–40:1 Account state snapshots
Mixed 6 12–35:1 General-purpose
MaxCompression 19 20–60:1 Archival storage

// guarantees

Lossless or it's a failing test.

The README is explicit: "100% lossless — rigorous roundtrip validation on every operation." Every preset's test suite compresses sample data and asserts that decompress(compress(x)) == x. That guarantee is the contract of the CompressionStrategy trait, and it is the same contract whether you reach for FastCompression or MaxCompression.

  • Round-trip checked in unit tests for every preset.
  • Deterministic dictionary: same bytes in, same bytes out, anywhere.
  • Thread-safe — safe to share across concurrent encoders.
  • No network, no telemetry, no chain dependency at runtime.

// roundtrip.rs

use blockchain_compression::presets::solana::{
    SolanaCompressor, SolanaPreset,
};
use blockchain_compression::core::traits::CompressionStrategy;

let mut c = SolanaCompressor::new(SolanaPreset::Transactions);

let compressed   = c.compress(data)?;
let decompressed = c.decompress(&compressed)?;

assert_eq!(data, decompressed.as_slice());
// If this fails, the library is failing its own
// test suite — open an issue.

// install

Drop it into Cargo.toml.

// Cargo.toml — Zstd backend (recommended)

[dependencies]
blockchain-compression = { version = "0.1", features = ["zstd"] }

The Zstd backend is required for the Solana presets. DEFLATE and LZ4 are available as alternative backends behind features = ["deflate"] or features = ["lz4"].

// main.rs — basic usage

use blockchain_compression::presets::solana::{
    SolanaCompressor, SolanaPreset,
};
use blockchain_compression::core::traits::CompressionStrategy;

let mut compressor = SolanaCompressor::new(
    SolanaPreset::Accounts,
);

let compressed   = compressor.compress(data)?;
let decompressed = compressor.decompress(&compressed)?;

assert_eq!(data, decompressed.as_slice());

// honest comparisons

Where this library fits.

The reference points worth comparing against are general-purpose compressors that almost every node operator already has installed.

// explore

Everything, one link away.

Every page on this site, grouped by what you came for — start here, dig into a specific workload, or read the engineering notes.

// start here

// use cases by workload

// from the blog

All posts →

// faq

Questions teams ask before they adopt.

+ Where does the 60:1 number come from?

The one measured figure we cite is "up to 60:1 on archival workloads with the MaxCompression preset" (Zstd level 19). It is the top of the range, not the median, and it assumes the input has the repetitive byte structure typical of account snapshots or batched archival data. Every other ratio here is an illustrative preset range, not a guaranteed result on your data.

+ How does this help with blockchain state bloat?

State bloat is a storage-and-bandwidth problem: high-throughput chains add state every slot and never reclaim it, so full history grows without bound. Compression does not shrink live consensus state, but it shrinks the archival and historical copies that archive nodes, indexers, and DePIN storage networks are paid to keep. On repetitive archival Solana data the MaxCompression preset reaches up to 60:1, flattening a storage curve that otherwise tracks block height.

+ Which chains are supported today?

The shipping preset is SolanaCompressor, which builds its dictionary from common Solana program IDs, instruction discriminators, and lamport amounts. The core trait layer is chain-agnostic — you can build your own dictionary for other chains — but the README only ships Solana presets.

+ Is the output guaranteed lossless?

Yes. Round-trip equality is enforced by tests on every preset. The README states "100% lossless — rigorous roundtrip validation on every operation." If decompress(compress(data)) != data, the library is failing a unit test.

+ Which backend should I enable?

Use the zstd feature for the Solana presets. DEFLATE and LZ4 are available as alternative backends behind their own feature flags, but the dictionary-driven presets that achieve the headline ratios require zstd.

+ Is the dictionary trained on my data?

No. The dictionary is hardcoded from a fixed list of common Solana byte patterns and built at compressor construction. Decompression is deterministic and the binary is self-contained — there is no online training loop and no per-customer state.

+ Does it depend on a running Solana node?

No. It is a pure compression library. You hand it bytes, it returns smaller bytes. No RPC, no validator, no network dependency.

// ship it

Turn state bloat into a smaller bill.

Add the crate, pick a preset that matches your workload, and let the dictionary collapse the repetitive structure your chain generates every slot. Round-trip the output. Confirm the ratio on your own data before you plan capacity around it.