This file provides guidance for AI agents working with this codebase.
Requirements: Go 1.25+, GCC 10+ or Clang, 32GB+ RAM, SSD/NVMe storage
make erigon # Build main binary (./build/bin/erigon)
make integration # Build integration test binary
make lint # Run golangci-lint + mod tidy check
make test-short # Quick unit tests (-short -failfast)
make test-all # Full test suite with coverage
make gen # Generate all auto-generated code (mocks, grpc, etc.)Before committing, always verify changes with: make lint && make erigon integration
- Erigon is an Ethereum execution client
- Data flow:
db -> snapshots snapshotsare immutableUnwindbeyond data in snapshots not allowed
| Directory | Purpose | Component Docs |
|---|---|---|
cmd/ |
Entry points: erigon, rpcdaemon, caplin, sentry, downloader | - |
execution/stagedsync/ |
Staged sync pipeline | agents.md |
db/ |
Storage: MDBX, snapshots, ETL | agents.md |
cl/ |
Consensus layer (Caplin) | agents.md |
p2p/ |
P2P networking (DevP2P) | agents.md |
rpc/jsonrpc/ |
JSON-RPC API | - |
./build/bin/erigon --datadir=./data --chain=mainnet
./build/bin/erigon --datadir=dev --chain=dev --beacon.api=beacon,validator,node,config # PoS dev modeCommit messages: prefix with package(s) modified, e.g., eth, rpc: make trace configs optional
Run make lint before every push. The linter is non-deterministic — run it repeatedly until clean.
Important: Always run make lint after making code changes and before committing. Fix any linter errors before proceeding. PRs must pass make lint before being opened or updated.
When manually dispatching a workflow that is not part of the PR's automatic check list, add a comment on the PR explaining which workflow was dispatched, why it was chosen, and include a direct link to the workflow run.
Before running git push, always run make lint first and fix all issues. Run lint multiple times if needed — it is non-deterministic.
The linter (make lint) is non-deterministic in which files it scans — new issues may appear on subsequent runs. Run lint repeatedly until clean.
Common lint categories and fixes:
- ruleguard (defer tx.Rollback/cursor.Close): The error check must come before
defer tx.Rollback(). Never remove an explicit.Close()or.Rollback()— adddeferas a safety net alongside it, since the timing of the explicit call may matter. - prealloc: Pre-allocate slices when the length is known from a range.
- unslice: Remove redundant
[:]on variables that are already slices. - newDeref: Replace
*new(T)withT{}. - appendCombine: Combine consecutive
appendcalls into one. - rangeExprCopy: Use
&xinrangeto avoid copying large arrays. - dupArg: For intentional
x.Equal(x)self-equality tests, suppress with//nolint:gocritic. - Loop ruleguard in benchmarks: For
BeginRw/BeginRoinside loops wheredeferdoesn't apply, suppress with//nolint:gocritic.
Make sure all scripts and shell code used from GitHub workflows is cross platform, for macOS, Windows and Linux.
Read CI-GUIDELINES.md for guidelines before making changes to workflows.
Go's test result cache keys on the mtime+size of every file read (via Go stdlib) during a test run. CI normalizes mtimes via git restore-mtime in .github/actions/setup-erigon/action.yml so that unchanged files get stable mtimes across runs.
When a test reads a data file at runtime (via os.Open, os.ReadFile, os.Stat, etc.) that lives outside a testdata/ directory, it must be added to the git restore-mtime pattern list in setup-erigon/action.yml. Otherwise that package's test results will never be cached in CI.
Covered patterns already include **/testdata/**, execution/tests/test-corners/**, cl/spectest/**/data_*/**, cl/transition/**/test_data/**, cl/utils/eth2shuffle/spec/**, and execution/state/genesiswrite/*.json.