Skip to content

Latest commit

 

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

batch-export

batch-export is a tool to retrieve Ethereum event logs for specific contracts, particularly designed for Swarm's Postage Stamp contract on the Gnosis Chain. It fetches logs within a specified block range using the export command and saves them to a file.

Features

  • Retrieve event logs for a specified contract address and block range.
  • Handles large block ranges by querying in smaller chunks.
  • Supports rate limiting for RPC requests.
  • Retries requests that fail with a transient network error (timeouts, dropped connections, rate limiting) using an exponential backoff.
  • Saves retrieved logs to a specified output file (default: export.ndjson) in NDJSON format.
  • Exports up to the latest finalized block by default (--end=0), so a snapshot never contains logs from blocks that can still be reorged.
  • Graceful shutdown on interrupt signals (Ctrl+C).
  • Continue a previous export from where it stopped (incremental snapshots).
  • By default emits a slim log shape — only the types.Log fields Bee consumes (address, topics, data, blockNumber, transactionHash), plus logIndex so exports stay resumable. Pass --slim=false to emit the full geth types.Log JSON shape for other consumers. The slim shape is decoder-compatible with geth's types.Log (so Bee reads both interchangeably).

Requirements

  • Go 1.25 or later

Installation

git clone https://github.com/ethersphere/batch-export.git
cd batch-export
make binary
# The binary will be located in the dist/ folder

Usage

The primary command is export.

./dist/batch-export export --help
./dist/batch-export export \
    --block-range-limit=10000 \
    --compress=true \
    --end=0 \
    --endpoint <YOUR_GNOSIS_RPC_ENDPOINT>

Flags

  -b, --block-range-limit uint32   Max blocks per log query (default 5)
  -c, --compress                   Compress to GZIP
      --end uint                   End block (optional, uses latest finalized block if 0)
  -e, --endpoint string            Ethereum based RPC endpoint URL (default "https://rpc.gnosis.gateway.fm")
  -h, --help                       help for export
  -m, --max-request int            Max RPC requests/sec (default 15)
  -o, --output string              Output file path (NDJSON) (default "export.ndjson")
  -r, --resume string              Continue a previous export file (.ndjson, .gz or .gzip); combine with --output to write a new snapshot instead of appending in place
      --retry-delay duration       Delay before the first retry, doubling per retry up to 30s (default 1s)
      --retry-max int              Max retries per RPC request on transient network errors (0 disables retrying) (default 5)
      --slim                       Emit only the types.Log fields Bee consumes, plus logIndex (default true)
      --start uint                 Start block (optional, uses contract start block if 0) (default 31306381)
  -v, --verbosity string           Log verbosity (silent, error, warn, info, debug) (default "info")

Continuing a previous snapshot

Instead of re-exporting every block, point --resume at the previous snapshot and name the new one with --output. The previous file is read, never modified; the new file holds everything the previous one did plus the blocks exported since:

./dist/batch-export export --resume snapshots/2026-07.ndjson.gzip --output snapshots/2026-08.ndjson.gzip

If --output names a different existing file, it is overwritten — the same os.Create semantics as a fresh export — so pick a new name for each snapshot. (Naming the input itself under another spelling — absolute vs relative, a symlink, a case difference — is detected and appends in place instead.)

Formats are detected by content, not extension: .ndjson, .gz and .gzip all work, and the output's format always matches the input's. Gzip stores no filename inside, so decompressing names the result after the archive minus its extension — name snapshots with the double extension, as above, and extraction yields a .ndjson file. Omitting --output (or naming the input) appends to the previous file in place — the space-saving variant:

./dist/batch-export export --resume export.ndjson.gzip

--start is ignored (with a warning) when --resume is set: the cursor in the previous file decides where the fetch resumes. The last exported block is re-queried and entries already present are skipped, so continuing neither duplicates nor drops a log. Each continuation of a compressed snapshot adds a gzip member — standard tools (gzcat, gunzip, Go, Python) read multi-member files as one stream, a year of monthly continuations costs about 0.02% in size, and gzcat old.gzip | gzip > fresh.gzip consolidates the members any time.

Keep one canonical snapshot file. --compress is ignored when resuming: regenerating a .gzip from a plain twin is how an independently continued archive gets overwritten. Resume a compressed file to get a compressed result.

Resume only files this tool produced. The file's tail is validated before anything is written: content the tool never writes — a non-log line, foreign data, an alien gzip member — is refused rather than repaired. The one exception is the tool's own interrupted final write (a run killed mid-export): in copy mode it is simply not copied, in place it is truncated away with a warning, and its entries are re-fetched. Note that resuming does not detect a file from a different chain; pairing the snapshot with the right --endpoint is the operator's contract.

If a copy-mode run itself is interrupted or fails, the input was never touched — delete the incomplete --output file and rerun.

The produced NDJSON is consumed by batch-archive, which embeds it for use inside Bee.

Verifying a snapshot

verify proves a refreshed snapshot still holds everything the original did — byte for byte, in order — followed only by newer entries, and prints the new snapshot's last block number in decimal:

./dist/batch-export verify --old export.ndjson.gzip --new snapshot.ndjson.gzip

A non-zero exit means the new snapshot must not replace the old one.

Maintainers

About

CLI to export Ethereum event logs (e.g. Swarm Postage Stamp contract on Gnosis Chain) into NDJSON.

Resources

Stars

1 star

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages