Skip to content

geanlabs/gean

Repository files navigation

gean

A Go consensus client for Lean Ethereum, built around the idea that protocol simplicity is a security property.

Philosophy

A consensus client should be something a developer can read, understand, and verify without needing to trust a small class of experts. If you can't inspect it end-to-end, it's not fully yours.

What is Lean Consensus

A complete redesign of Ethereum's consensus layer, hardened for security, decentralization, and finality in seconds.

Design approach

  • Readable over clever. Code is written so that someone unfamiliar with the codebase can follow it. Naming is explicit. Control flow is linear where possible.
  • Minimal dependencies. Fewer imports means fewer things that can break, fewer things to audit, and fewer things to understand.
  • No premature abstraction. Interfaces and generics are introduced when the duplication is real, not when it's hypothetical. Concrete types until proven otherwise.
  • Flat and direct. Avoid deep package hierarchies and layers of indirection. A function should do what its name says, and you should be able to find it quickly.
  • Concurrency only where necessary. Go makes concurrency easy to write and hard to reason about. We use it at the boundaries (networking, event loops) and keep the core logic sequential and deterministic.

Current status

gean currently targets Lean Consensus devnet-3 (single attestation committee).

Network Status Spec pin
devnet-3 Active development leanSpec@8b7636b

Prerequisites

  • Go 1.24.6+
  • Rust 1.87+ (for the leanSig FFI library under xmss/leansig-ffi/)
  • uv (astral.sh/uv) — needed to generate leanSpec test fixtures

Getting started

# Build (includes FFI library)
make build

# Run consensus spectests (builds FFI + fixtures)
make spec-test

# Run Go unit tests
make unit-test

# Lint
make lint

# Generate local devnet artifacts (overwrites):
# - config.yaml (genesis time = now, genesis validators)
# - nodes.yaml  (bootnodes derived from node*.key peer IDs)
# - keys/       (validator keypairs)
# - node*.key   (node identity keys)
make run-setup

# Run
make run

To run multiple local nodes:

# Terminal 1
make run

# Terminal 2
make run-node-1

# Terminal 3
make run-node-2

Notes:

  • config.yaml and nodes.yaml are local-only, generated by make run-setup, and are gitignored.
  • make run uses existing config.yaml/nodes.yaml if present (but always refreshes GENESIS_TIME to NOW + 30s); run make run-setup to force regeneration.

leanSpec fixtures and spectests (devnet-3)

make spec-test is the primary consensus-conformance entry point. It bootstraps leanSpec fixtures and runs spectests in a signature-skip lane.

# Generate/update fixtures from pinned leanSpec commit
make leanSpec/fixtures

# Verify leanSpec pin used for fixtures
git -C leanSpec rev-parse HEAD
cat leanSpec/.fixtures-commit

# Run only consensus spectests (fork-choice + state-transition)
make spec-test

# Run Go unit tests across packages
make unit-test

Notes:

  • Fixtures are generated under leanSpec/fixtures.
  • leanSpec/ is a local working directory and is gitignored.
  • Fixture generation uses uv run fill --fork=Devnet --layer=consensus --clean -o fixtures pinned by LEAN_SPEC_COMMIT_HASH in Makefile.

Metrics and Grafana

gean exposes Prometheus metrics at /metrics when --metrics-port is enabled.

./bin/gean \
  --genesis config.yaml \
  --bootnodes nodes.yaml \
  --validator-registry-path validators.yaml \
  --validator-keys keys \
  --node-id node0 \
  --metrics-port 8080

Grafana assets for gean are provided at:

  • observability/grafana/client-dashboard.json (dashboard import)
  • observability/grafana/prometheus-scrape.example.yml (scrape config example)

Dashboard notes:

  • Datasource UID is hardcoded to feyrb1q11ge0wa.
  • Panels filter targets using the Gean Job variable ($gean_job), populated from Prometheus job labels.

API

gean exposes a lightweight HTTP API (standard library only) for Lean endpoints.

Flags:

  • --api-host (default 0.0.0.0)
  • --api-port (default 5058, set to 0 to disable)
  • --api-enabled (default true)

Example:

curl http://localhost:5058/lean/v0/health
curl http://localhost:5058/lean/v0/fork_choice
curl -o finalized.ssz http://localhost:5058/lean/v0/states/finalized

Checkpoint sync example:

curl -I http://127.0.0.1:5058/lean/v0/states/finalized

./bin/gean \
  --genesis config.yaml \
  --bootnodes nodes.yaml \
  --validator-registry-path validators.yaml \
  --validator-keys keys \
  --node-id node1 \
  --listen-addr /ip4/0.0.0.0/tcp/9001 \
  --node-key node1.key \
  --data-dir data/node1 \
  --discovery-port 9001 \
  --api-port 5053 \
  --metrics-port 8081 \
  --checkpoint-sync-url http://127.0.0.1:5058/lean/v0/states/finalized

See api/README.md for full route details.

Running in a devnet

gean is part of the lean-quickstart multi-client devnet tooling.

Acknowledgements

License

MIT

About

A Go implementation of the Lean Ethereum consensus protocol

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors