Normalized frame archive
Status: implemented interchange format v1.
The archive history source lets the node backfill from local, checksummed
objects without retaining raw chain history. It is deliberately source-neutral:
an Amazon Parquet, Xatu, EraE, BigQuery, or custom adapter can project its input
to normalized BlockFrame JSON Lines and then use the same runtime and
processors.
Example history configuration:
[[sources.history]]id = "offline-frames"kind = "archive"priority = 5trust = "trusted_dataset"manifest = "./archives/mainnet/manifest.json"A relative manifest path is relative to the directory of the configuration
file, not the working directory the node starts in.
Manifest:
{ "format_version": 1, "id": "mainnet-public-data-2026-08-01", "chain_id": 1, "schema_version": "normalized-frame-jsonl.v1", "capabilities": ["Header", "Transactions", "Receipts", "Logs"], "complete_capabilities": ["Header", "Transactions", "Receipts", "Logs"], "finality": "Finalized", "objects": [ { "from_block": 19426589, "to_block": 19427588, "path": "19426589-19427588.jsonl", "blake3": "lowercase-64-hex-digits", "bytes": 1234567 } ]}Each non-empty object line is one JSON-encoded BlockFrame. Objects must:
- use simple relative paths (no absolute paths or
..); - have the exact declared byte length and BLAKE3 digest;
- contain exactly one frame per block in their declared range;
- be ordered, contiguous, and parent-linked;
- match the manifest chain, finality, and declared material capabilities;
- be reached without crossing a symbolic link below the manifest’s directory.
Reads enforce the normal source byte, frame, and frame-count budgets, and hold one line at a time. The adapter verifies the complete object’s length and BLAKE3 digest before it yields any frame; a length or checksum mismatch fails the read then. It then streams the frames from the same open file, hashing it again as it goes, and adds immutable object identity to their provenance. A structural failure, such as a truncated frame, a block out of order, missing, or repeated, a parent mismatch, a schema mismatch, or a chain or finality mismatch, fails the read as corrupt where it is found, after the frames before it may already have been applied; a later source or a rerun resumes after them. An object edited in place between the two passes fails with the checksum error only after its frames.
Frames report only the checks the archive made: the object’s BLAKE3 digest,
and the parent link to the previous frame of the same object. A frame’s own
verification claims and consensus anchor are dropped, and the trust of its
earlier provenance is capped at trusted_dataset.
The archive is a trusted-dataset source, not automatically a cryptographic raw
history source. An EraE adapter must additionally decode raw bodies/receipts,
verify their commitment roots, and anchor canonicality before advertising
verified_material.
Backfill any configured processor:
leani backfill \ --processor erc20-balances \ --from-block 12345678 \ --to-block 12346677The runtime records coverage and discards input frames after reduction. Only
processor output, undo/change journals, and job metadata remain in SQLite.
An ordered processor such as erc20-balances applies its history
contiguously from start_block upward, so --from must be the block after
the last one it applied, or its start_block when it has applied none; the
command refuses any other start and names the block to use.
When rpc.historical_mode = "on_demand", the same source can answer bounded
historical RPC without importing frames into SQLite. Exact block and receipt
responses additionally require complete canonical header RLP, EIP-2718
transaction bytes, typed receipt bytes, senders, receipt gas fields, and
withdrawals whenever the header commits to a withdrawals root. The manifest
must declare those capabilities complete. A blobs-only Xatu projection is
correctly rejected for generic RPC because its predicate-filtered transaction
material is not a complete block body.
Built by Smart-Byte · Legal notice (Impressum) · Privacy