Peam is a minimal, performance-first Lean consensus client written in Rust.
The project is built around a small core, fast SSZ and hashing paths, lean storage, and practical multi-client interoperability. The goal is not to be feature-heavy; the goal is to keep the critical path cheap, observable, and easy to reason about.
- Alpha software
- Suitable for experimentation, devnets, and benchmarking
- Not intended for production mainnet use yet
- Small, auditable codebase
- Low-memory operation
- Fast serialization and merkleization paths
- Straightforward networking and sync behavior
- Clean operational surface for mixed-client devnets
- Rust toolchain (
cargo,rustc) - Git
- Docker (optional)
cargo build
cargo testTo build the binary only:
cargo build --release -p peam --bin peamPeam runs from a small key=value config file.
Example node.conf:
genesis_time=42
http_api=true
http_address=127.0.0.1
http_port=5052
metrics=true
metrics_address=127.0.0.1
metrics_port=8080
listen_addr=/ip4/0.0.0.0/udp/9000/quic-v1
Run the node:
cargo run --release -- --run --config node.conf --data-dir /tmp/peam_dataPrint the genesis root only:
cargo run --release -- --config node.confPeam supports direct CLI overrides for the main devnet and quickstart paths.
Example:
cargo run --release -- --run --config node.conf --data-dir /tmp/peam_data \
--listen /ip4/0.0.0.0/udp/9001/quic-v1 \
--bootnode /ip4/127.0.0.1/udp/9000/quic-v1/p2p/<peer-id> \
--metrics-port 8081 \
--http-port 5053 \
--node-id peam_0 \
--validator-keys /path/to/hash-sig-keys \
--is-aggregatorCheckpoint sync:
cargo run --release -- --run --config node.conf --data-dir /tmp/peam_data \
--checkpoint-sync-url http://localhost:5052leanSpec-style aliases supported by the CLI:
--genesis--custom_genesis--network--bootnodes--validators--validator-registry-path--node-key--metrics-port--api-port--http-port--aggregator
For the full CLI surface:
cargo run --release -- -- --helpMost operational settings can be supplied in the config file.
Common keys:
genesis_time=<u64>
http_api=true|false
http_address=127.0.0.1
http_port=5052
metrics=true|false
metrics_address=127.0.0.1
metrics_port=8080
listen_addr=/ip4/0.0.0.0/udp/9000/quic-v1
node_key_path=/path/to/node.key
bootnodes=/ip4/.../p2p/...
bootnodes_file=/path/to/nodes.yaml
trusted_peers=/ip4/.../p2p/...
validator_count=4
local_validator_index=0
attestation_committee_count=1
is_aggregator=true|false
validator_config_path=/path/to/validator-config.yaml
checkpoint_sync_url=http://host:port
storage_dir=store
A few notes:
bootnodes_fileaccepts anodes.yaml/ ENR file and is the cleanest path for quickstart-style deployments.- If
http_portis omitted, it falls back tometrics_port. - If
http_addressis omitted, it falls back tometrics_address. - Setting
--metrics-port 0disables metrics. - Setting
--api-port 0disables the HTTP API listener.
Peam exposes:
GET /v0/healthGET /lean/v0/healthGET /v0/states/finalizedGET /lean/v0/states/finalizedGET /v0/checkpoints/justifiedGET /lean/v0/checkpoints/justifiedGET /v0/fork_choiceGET /lean/v0/fork_choiceGET /metrics
By default:
- HTTP API is enabled
- Metrics are disabled unless
metrics=true
Example:
curl http://127.0.0.1:5052/v0/health
curl http://127.0.0.1:8080/metrics | headBuild locally:
docker build -t peam:local .Published images:
ghcr.io/malik672/peam:latestghcr.io/malik672/peam:sha-<commit>ghcr.io/malik672/peam:<tag>
Run with Docker:
docker run --rm \
-v "$PWD/node.conf:/config/node.conf:ro" \
-v /tmp/peam_data:/data \
ghcr.io/malik672/peam:latest \
--run --config /config/node.conf --data-dir /dataThe Docker publish workflow is:
.github/workflows/docker_publish.yml
Run the mixed-client devnet script from the Peam repo:
./scripts/run_devnet2_3clients.shLogs are written under:
.tmp/<run>/logs/
Clean old runs:
rm -rf .tmp/devnet*- Peam uses a disk-backed store for long-lived chain data.
- Fork choice is in memory and optimized for the live working set.
- Metrics and logging are intended to be useful in mixed-client debugging, not only local happy-path runs.
PRs are welcome.
Before opening one, please run:
cargo testIf you are changing sync, state transition, or fork choice behavior, it is worth running at least one mixed-client devnet before pushing.
Dual-licensed under:
- MIT
- Apache-2.0
See:
LICENSELICENSE-APACHE
- Some networking test structure and PQ verification flow were adapted from Ream.