Skip to content
galaddPublic

About

Standalone Rust toolkit for Ethereum ERA files — read, write, verify, and convert historical chain archives across clients.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

45 Commits

Folders and files

Repository files navigation

Brandon

The ffmpeg for Ethereum historical archives.

Brandon is a standalone Rust toolkit for reading, verifying, converting, and exploring Ethereum historical archives.

Instead of exposing archive internals, Brandon lets you work with Ethereum concepts—blocks, slots, epochs, headers, receipts, and states—through simple, UNIX-friendly commands.

It was built out of frustration with having to run an entire consensus client just to inspect a single historical block.


Install

From crates.io

cargo install brandon

From source:

git clone https://github.com/galadd/brandon.git
cd brandon
cargo install --path .

Prebuilt binaries are available on the releases page.


What Brandon can do today

  • ✓ Stream ERA/ERA1 archives without loading entire files into memory
  • ✓ Random-access blocks by slot
  • ✓ Build new ERA archives
  • ✓ Verify archive integrity and manifests
  • ✓ Rebuild indexes and transform archives
  • ✓ Zero-copy iteration over in-memory archives
  • ✓ Client-agnostic design
  • ✓ Structured JSON output
$ brandon info mainnet-00000-5ec1ffb8.era1

Format:          ERA1
File size:       3.71 MiB (3891337)
Starting slot:   0
Slot range:      0..8191
Block count:     8191
State present:   no
Total entries:   32770

Entry breakdown:
  BlockAccumulator 1
  BlockBody        8192
  BlockIndex       1
  CompressedHeader 8192
  Receipts         8192
  TotalDifficulty  8192

The Goal

A researcher should be able to go from zero to answering a question about Ethereum history in under a minute.

cargo install brandon

brandon block 12345678 --json \
    | jq '.proposer_index'

No node to synchronize.
No consensus client.
No heavyweight SSZ libraries.
Just install Brandon and ask questions about Ethereum history.

Note

The command above represents Brandon's target user experience. Today, Brandon provides the archive manipulation foundation that future high-level commands will build upon.


Vision

Brandon is designed in layers.

Each layer builds on the previous one while keeping the core library lightweight and client-independent.

Layer 1 — Archive Toolkit (Current)

The format-agnostic foundation.

Current capabilities include:

  • Reading ERA and ERA1 archives
  • Streaming readers
  • Random access by slot
  • Archive verification
  • Archive construction
  • Archive conversion
  • Zero-copy iteration
  • Client interoperability

The library intentionally avoids depending on any particular Ethereum client implementation.

For example, the era1_to_era converter lets callers provide their own SSZ implementation rather than forcing one on downstream users.


Layer 2 — Ethereum Concepts

Users shouldn't need to think about:

  • entry types
  • type codes
  • archive offsets
  • compression details

They should think about:

  • blocks
  • headers
  • epochs
  • slots
  • receipts
  • beacon states

The goal is to expose commands such as:

brandon block 12345678
brandon header 12345678
brandon receipts 12345678

along with structured JSON output using Ethereum consensus terminology.


Layer 3 — Remote Archives

Working with historical Ethereum data shouldn't require downloading an archive first.

Future versions will support commands such as:

brandon fetch block 12345678

Internally Brandon will:

  • locate the appropriate archive
  • download only the required byte ranges
  • decompress the requested data
  • decode it
  • print the result

The user shouldn't need to know where the archive lives or that HTTP range requests are involved.


Layer 4 — Search

Eventually Brandon aims to become a searchable interface over Ethereum history.

Examples include:

brandon search --proposer 1234 ./archives/

brandon search --graffiti "rocketpool"

brandon search --execution-block 19000000

Universal Inspection

One long-term goal is a single command capable of identifying almost anything.

$ curl https://example.com/archive.era \
    | brandon inspect

Format:     ERA
Epochs:     90–91
Blocks:     8192
Compressed: snappy
SHA256:     ...

Whether the input comes from:

  • a local file
  • a directory
  • stdin
  • a URL

Brandon should determine what it is automatically.


CLI

Inspect

brandon info archive.era1

brandon info archive.era --json

Verify

brandon verify archive.era1

brandon verify archive.era1 \
    --manifest checksums.txt

Read

# Read a single slot
brandon read archive.era1 --slot 42

# Stream every block
brandon read archive.era1 --all

# Read first 10 blocks
brandon read archive.era1 --count 10

# Extract blocks
brandon read archive.era1 \
    --all \
    --output-dir ./blocks

# Include beacon state
brandon read archive.era \
    --all \
    --state

Convert

# Rebuild indexes
brandon convert reindex archive.era1 \
    -o fixed.era1

# Remove receipts
brandon convert strip archive.era1 \
    --strip-receipts \
    -o slim.era1

# Headers only
brandon convert strip archive.era1 \
    --strip-receipts \
    --strip-bodies \
    --strip-td \
    -o headers.era1

# Split archive
brandon convert split archive.era1 \
    --output-dir ./blocks

Build

brandon build \
    --blocks-dir ./compressed \
    --output out.era

brandon build \
    --blocks-dir ./compressed \
    --state state.snappy \
    --state-slot 8192 \
    --output out.era

Library

[dependencies]
brandon = "0.1"

Streaming Reader

use brandon::{EraReader, TypedEntry};

let file = std::fs::File::open("archive.era1")?;
let mut reader = EraReader::new(file);

while let Some(entry) = reader.next_entry()? {
    match entry {
        TypedEntry::Header { data } => {
            println!("{}", data.len());
        }
        _ => {}
    }
}

Random Access

use brandon::EraRandomReader;

let file = std::fs::File::open("archive.era1")?;
let mut reader = EraRandomReader::new(file)?;

if let Some(block) = reader.read_block_at_slot(42)? {
    println!("{}", block.primary_data().len());
}

Zero-Copy Iteration

use brandon::read::iter_blocks;

let bytes = std::fs::read("archive.era")?;

for block in iter_blocks(&bytes)? {
    println!("{}", block.primary_data().len());
}

Format Support

Format Status Description
e2store ✅ Full Container format
ERA1 ✅ Full Pre-merge execution history
ERA ✅ Full Post-merge consensus history
E2SS 🟡 Structural Execution state snapshots
E2HS 🟡 Structural Execution history with proofs
ERE 🔜 Planned Full execution history

Full — Entry types recognized and verified against real archives.

Structural — Container supported; payload parsing not yet implemented.


Development

cargo test

cargo fmt --check

cargo clippy --all-targets --all-features

cargo build --release

License

Licensed under either

  • MIT
  • Apache-2.0

at your option.

About

Standalone Rust toolkit for Ethereum ERA files — read, write, verify, and convert historical chain archives across clients.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages