Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
0b3690a
fix: log payload attestations for gloas block bodies (#8942)
nflaig Feb 23, 2026
49f680d
feat: create standalone fork-choice dashboard (#8928)
nazarhussain Feb 23, 2026
aeb5a21
feat: model BeaconStateView (#8773)
twoeths Feb 23, 2026
f225223
refactor: unified pubkey cache (#8945)
wemeetagain Feb 23, 2026
95cf2ed
chore: properly await async monitoring requests during shutdown (#8896)
wemeetagain Feb 24, 2026
3b98c59
fix: bootstrap already-open libp2p connections at PeerManager startup…
lodekeeper Feb 24, 2026
ef31010
chore: track forkchoice update results via metrics (#8895)
wemeetagain Feb 24, 2026
96f78af
feat: libp2p v3 (#8890)
wemeetagain Feb 24, 2026
afd4462
ci: remove bun tests (#8959)
spiral-ladder Feb 25, 2026
6eb5502
fix: libp2p v3 unknown peers (#8960)
nflaig Feb 25, 2026
31b0dd0
chore: add .claude project configuration with skills and permissions …
lodekeeper Feb 25, 2026
4e115ed
feat: add gloas block import pipeline (#8940)
ensi321 Feb 25, 2026
167a02a
fix: use inclusive boundary for gossip clock disparity checks (#8968)
lodekeeper Mar 2, 2026
f2caa91
chore: bump libp2p deps and fix peer-collections type mismatch (#8970)
lodekeeper Mar 2, 2026
bb33751
chore: bump libp2p to 3.1.4 (#8973)
lodekeeper Mar 3, 2026
192806a
feat: integrate gossip validation spec tests (#8965)
nflaig Mar 3, 2026
09945f6
feat: implement epbs fork choice (#8739)
ensi321 Mar 4, 2026
45864cc
chore: bump libp2p deps to latest patch releases (#8984)
lodekeeper Mar 4, 2026
477bc36
chore(ci): pin ethspecify to 0.3.7 in check-specrefs (#8986)
lodekeeper Mar 4, 2026
20f622c
chore: bump fastify to v5.8.1 (#8989)
lodekeeper Mar 5, 2026
f36ec31
feat: set attestation data index based on payload status (#8982)
nflaig Mar 6, 2026
66fe43a
fix: cache previous epoch payload timeliness committees (#8991)
nflaig Mar 6, 2026
dce096d
refactor: separate writeBlockInputToDb into parallel block and column…
twoeths Mar 9, 2026
f9a3a81
fix(fork-choice): make payloadStatus explicit in ancestor traversal A…
twoeths Mar 9, 2026
bb27317
chore: pin pnpm with sha512 integrity in package.json (#9008)
nflaig Mar 9, 2026
0df1876
chore: pin github actions by commit hash (#9017)
nflaig Mar 10, 2026
e6c853d
chore(deps): bump the actions group with 13 updates (#9018)
dependabot[bot] Mar 10, 2026
b847afb
fix: prune serialized cache by block input keys (#9007)
nflaig Mar 10, 2026
165a02f
refactor: clone state in processExecutionPayloadEnvelope (#9015)
ensi321 Mar 11, 2026
be5acbb
chore: fix private imports (#8990)
nazarhussain Mar 11, 2026
0087e7a
chore: remove getComputeShuffledIndexFn() (#9011)
twoeths Mar 11, 2026
f7a5f4d
feat: use tsgo for build and type checks (#8992)
nazarhussain Mar 11, 2026
cfc5790
refactor: use BitArray for PTC votes instead of boolean[] (#9021)
GrapeBaBa Mar 12, 2026
8578102
feat: schedule Fulu fork for Chiado testnet (#9027)
dapplion Mar 12, 2026
85cdea6
chore: fix seen block input cache metrics (#9020)
nflaig Mar 12, 2026
8cdde18
refactor: simplify default variant lookup to avoid double hash lookup…
GrapeBaBa Mar 13, 2026
1ddf8e4
fix: correct pre-Deneb attestation propagation slot range boundary (#…
nflaig Mar 13, 2026
aeab9f9
fix(reqresp): clear composed response timeout signals (#9029)
lodekeeper Mar 13, 2026
8299317
feat(state-transition): add gloas fields/methods to IBeaconStateView …
twoeths Mar 13, 2026
b90dff6
docs(reqresp): add upstream issue reference to createRespSignal (#9033)
lodekeeper Mar 13, 2026
92c37f2
feat: add QUIC support (#8051)
wemeetagain Mar 14, 2026
5255481
chore: bump libp2p deps to latest published versions (#9035)
lodekeeper Mar 14, 2026
c11b797
chore: update lockfile for @libp2p/utils 7.0.13 (#9037)
lodekeeper Mar 14, 2026
6a85a50
perf(fork-choice): hoist proposerBoostRoot out of applyScoreChanges l…
GrapeBaBa Mar 16, 2026
241ad79
chore: bump @chainsafe/discv5 to v12.0.1 and @chainsafe/enr to v6.0.1…
lodekeeper Mar 16, 2026
21d4a81
chore(deps): bump the actions group with 7 updates (#9048)
dependabot[bot] Mar 16, 2026
8e34c75
chore: fix peerdas metrics (#8920)
rnfairchild Mar 16, 2026
26ed5ad
ci: add native module CPU portability check (#9044)
lodekeeper Mar 17, 2026
1ff95ea
chore: create GitHub releases as draft to support immutable releases …
lodekeeper Mar 17, 2026
e8653ab
chore: bump package versions to 1.41.0
nflaig Mar 14, 2026
9939b12
docs: update docs favicon to current Lodestar logo (#9058)
lodekeeper Mar 18, 2026
274a991
feat: state cache for ePBS (#8868)
ensi321 Mar 19, 2026
bb16850
feat: update voluntary exit for gloas (#9039)
nflaig Mar 19, 2026
13e882a
chore: v1.41.0 release (#9038)
matthewkeil Mar 19, 2026
5f2fffc
chore: merge stable 1.41.0 back to unstable (#9066)
matthewkeil Mar 19, 2026
4411584
chore: use permalinks for spec references (#9065)
markolazic01 Mar 19, 2026
70938e1
feat: add gloas execution payload envelope import pipeline (#8962)
ensi321 Mar 20, 2026
f6213da
feat: schedule Fulu fork for Gnosis mainnet (#9074)
dapplion Mar 20, 2026
7552832
fix: override MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS for Gnosis…
lodekeeper Mar 20, 2026
1d50253
docs: improve AGENTS.md with code quality rules and structural cleanu…
lodekeeper Mar 20, 2026
7b5ce39
chore: enable forceJsExtensions in biome lint config (#9079)
lodekeeper Mar 20, 2026
d73eccf
feat: add --http.requestTimeout flag to configure vc http request tim…
markolazic01 Mar 21, 2026
bfeb9e7
chore: clean up UnknownBlockSync (#9069)
twoeths Mar 23, 2026
5f9f015
fix: improve sync aggregate participation (#9070)
lodekeeper Mar 23, 2026
5007d8c
refactor: avoid falsy zero check in indexed attestation bounds valida…
nflaig Mar 23, 2026
e44b7c2
Merge remote-tracking branch 'origin/unstable' into epbs-devnet-0
lodekeeper Mar 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
44 changes: 44 additions & 0 deletions .claude/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Claude Code Configuration

This directory contains shared [Claude Code](https://code.claude.com/) configuration for the Lodestar project. See also [`AGENTS.md`](../AGENTS.md) at the repo root for project conventions and architecture guidance.

## Structure

```
.claude/
├── settings.json # Shared project settings (permissions allowlist)
├── settings.local.json # Personal settings (gitignored)
├── skills/ # Agent skills — Claude auto-discovers these
│ ├── kurtosis-devnet/ # Multi-client devnet testing
│ ├── release-notes/ # Release note drafting
│ └── local-mainnet-debug/ # Debug with real mainnet peers
└── README.md # This file
```

## Skills

Skills are automatically loaded by Claude Code based on task context. You can also invoke them manually:

| Skill | When to use |
| ----------------------- | -------------------------------------------------------------------------- |
| **kurtosis-devnet** | Spinning up local testnets, cross-client interop testing, fork transitions |
| **release-notes** | Drafting release notes for GitHub and Discord |
| **local-mainnet-debug** | Debugging networking/peer issues against real mainnet peers |

## Shared Plugins

For cross-project Ethereum development resources (consensus specs, client cross-reference), install from the shared marketplace:

```bash
claude plugin marketplace add ChainSafe/lodestar-claude-plugins
claude plugin install ethereum-rnd
claude plugin install consensus-clients
```

## Personal Configuration

Add personal settings to `.claude/settings.local.json` (gitignored). This is useful for:

- Personal API keys or tool preferences
- Local MCP server configurations
- Additional permission rules for your workflow
67 changes: 67 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(pnpm build)",
"Bash(pnpm --filter * build)",
"Bash(pnpm lint)",
"Bash(pnpm lint:fix)",
"Bash(pnpm check-types)",
"Bash(pnpm --filter * check-types)",
"Bash(pnpm test:unit)",
"Bash(pnpm vitest *)",
"Bash(pnpm download-spec-tests)",
"Bash(pnpm test:spec)",
"Bash(pnpm docs:lint)",
"Bash(pnpm docs:lint:fix)",
"Bash(git status *)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git branch *)",
"Bash(git show *)",
"Bash(git fetch *)",
"Bash(gh pr view *)",
"Bash(gh pr list *)",
"Bash(gh pr diff *)",
"Bash(gh pr checks *)",
"Bash(gh issue view *)",
"Bash(gh issue list *)",
"Bash(gh run view *)",
"Bash(gh run list *)",
"Bash(gh search *)",
"Bash(grep *)",
"Bash(cat *)",
"Bash(head *)",
"Bash(tail *)",
"Bash(wc *)",
"Bash(ls *)",
"Bash(curl -s http://localhost:*)"
],
"deny": [
"Bash(rm -rf / *)",
"Bash(sudo *)"
]
},
"enabledPlugins": {
"ethereum-rnd@lodestar-claude-plugins": true,
"consensus-clients@lodestar-claude-plugins": true,
"eth-rnd-archive@lodestar-claude-plugins": true,
"claude-md-management@claude-plugins-official": true,
"code-review@claude-plugins-official": true,
"code-simplifier@claude-plugins-official": true,
"commit-commands@claude-plugins-official": true,
"context7@claude-plugins-official": true,
"feature-dev@claude-plugins-official": true,
"pr-review-toolkit@claude-plugins-official": true,
"superpowers@claude-plugins-official": true,
"typescript-lsp@claude-plugins-official": true
},
"extraKnownMarketplaces": {
"lodestar-claude-plugins": {
"source": {
"source": "github",
"repo": "ChainSafe/lodestar-claude-plugins"
}
}
}
}
245 changes: 245 additions & 0 deletions .claude/skills/kurtosis-devnet/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
---
name: kurtosis-devnet
description: Run Ethereum multi-client devnets using Kurtosis and the ethpandaops/ethereum-package. Use for spinning up local testnets, validating cross-client interop, testing fork transitions, running assertoor checks, debugging CL/EL client interactions, or verifying new feature implementations across multiple consensus and execution clients.
---

# Kurtosis Devnet

Run Ethereum consensus/execution client devnets via [Kurtosis](https://github.com/kurtosis-tech/kurtosis) + [ethereum-package](https://github.com/ethpandaops/ethereum-package).

## Prerequisites

- [Kurtosis CLI](https://docs.kurtosis.com/install/) installed
- Docker running with sufficient resources (8GB+ RAM recommended for multi-client devnets)

## Quick Start

```bash
# Start devnet from config
# Always use --image-download always to ensure external images are up to date
kurtosis run github.com/ethpandaops/ethereum-package \
--enclave <name> \
--args-file network_params.yaml \
--image-download always

# List enclaves
kurtosis enclave ls

# Inspect services
kurtosis enclave inspect <name>

# View logs
kurtosis service logs <enclave> <service-name>
kurtosis service logs <enclave> <service-name> --follow

# Cleanup
kurtosis enclave rm -f <name>
# Or clean all enclaves
kurtosis clean -a
```

## Config File (`network_params.yaml`)

See `references/config-reference.md` for the full config structure.

Key sections:

- `participants`: list of CL+EL client pairs with images, flags, validator counts
- `network_params`: fork epochs, slot time, network-level settings
- `additional_services`: dora (explorer), assertoor (testing), prometheus, grafana
- `assertoor_params`: automated chain health checks
- `port_publisher`: expose CL/EL ports to host

## Building Custom Client Images

When testing local Lodestar branches, build a Docker image first:

```bash
# Fast build (recommended for iteration)
cd ~/lodestar && docker build -t lodestar:custom -f Dockerfile.dev .

# Production build (slower, for final validation only)
cd ~/lodestar && docker build -t lodestar:custom .

# Then reference in config:
# cl_image: lodestar:custom
```

**Always use `Dockerfile.dev` for iterative development.** It caches dependency layers and rebuilds in seconds vs minutes for the production Dockerfile. Only use the production `Dockerfile` for final validation or debugging build issues.

## Service Naming Convention

Kurtosis names services as: `{role}-{index}-{cl_type}-{el_type}`

Examples:

- `cl-1-lodestar-reth` — first CL node (Lodestar with Reth EL)
- `el-1-reth-lodestar` — corresponding EL node
- `vc-1-lodestar-reth` — validator client

## Accessing Services

After `kurtosis enclave inspect <name>`, find mapped ports:

```bash
# CL beacon API (find actual port from inspect output)
curl http://127.0.0.1:<mapped-port>/eth/v1/node/syncing

# Or use port_publisher for predictable ports:
# port_publisher:
# cl:
# enabled: true
# public_port_start: 33000 # cl-1=33000, cl-2=33005, etc.
# el:
# enabled: true
# public_port_start: 32000
```

Port publisher assigns sequential ports (step of 5 per service).

## Assertoor (Automated Testing)

Add to config:

```yaml
additional_services:
- assertoor

assertoor_params:
run_stability_check: true # chain stability, finality, no reorgs
run_block_proposal_check: true # every client pair proposes a block
```

Check results via the assertoor web UI (port shown in `kurtosis enclave inspect`).

## Common Devnet Patterns

### Fork Transition Testing

```yaml
network_params:
electra_fork_epoch: 0
fulu_fork_epoch: 1 # fork at epoch 1 (slot 32)
seconds_per_slot: 6 # faster for testing
```

### Mixed-Client Topology (Cross-Client Interop)

```yaml
participants:
- cl_type: lodestar
el_type: reth
count: 2
validator_count: 128
- cl_type: lighthouse
el_type: geth
count: 2
validator_count: 128
```

### Observer Nodes (No Validators)

```yaml
- cl_type: lodestar
cl_image: lodestar:custom
el_type: reth
count: 1
validator_count: 0 # observer-only
```

### Supernode Mode

Set `supernode: true` to run beacon+validator in a single process (faster startup, simpler topology):

```yaml
- cl_type: lodestar
el_type: reth
supernode: true
validator_count: 128
```

### Extra CL/VC Params

```yaml
cl_extra_params:
- --targetPeers=8
- --logLevel=debug
vc_extra_params:
- --suggestedFeeRecipient=0x...
```

## Monitoring & Debugging

```bash
# Stream logs from a specific service
kurtosis service logs <enclave> cl-1-lodestar-reth --follow

# Save all CL logs for analysis
for svc in $(kurtosis enclave inspect <enclave> 2>/dev/null | grep -oE 'cl-[0-9]+-[^[:space:]]+'); do
kurtosis service logs <enclave> $svc > "/tmp/${svc}.log" 2>&1
done

# Dora explorer (if enabled) — find port via inspect output

# Check chain finality
curl -s http://127.0.0.1:<port>/eth/v1/beacon/states/head/finality_checkpoints | jq

# Check peer count
curl -s http://127.0.0.1:<port>/eth/v1/node/peers | jq '.data | length'

# Check sync status
curl -s http://127.0.0.1:<port>/eth/v1/node/syncing | jq
```

### Wait for Finality

Finality typically takes 2-3 epochs after genesis. With `seconds_per_slot: 6` and 32 slots/epoch:

- 1 epoch ≈ 192s (3.2 min)
- First finalization ≈ epoch 3-4 boundary (≈10-13 min)

Monitor:

```bash
curl -s http://<port>/eth/v1/beacon/states/head/finality_checkpoints | jq '.data.finalized.epoch'
```

### Acceptance Criteria Pattern

For interop validation, define acceptance criteria **before** running the soak test:

```bash
# Example: check for zero errors across all CL nodes
for svc in cl-1-lodestar-reth cl-2-lodestar-reth; do
echo "=== $svc ==="
kurtosis service logs <enclave> $svc 2>&1 | grep -c "ERROR" || echo "0 errors"
done
```

## Troubleshooting

| Issue | Fix |
| ------------------------ | ------------------------------------------------------------------------- |
| Peers not connecting | Increase `--targetPeers`, check `directPeers` config |
| No finality | Need ≥2/3 validators attesting; check VC logs |
| "discv5 has no boot enr" | Harmless startup warning, ignore |
| Port conflicts | Change `public_port_start` or stop conflicting enclaves |
| Image not found | Ensure Docker image is built locally or available in registry |
| Slow startup | Use `Dockerfile.dev` for local builds; reduce validator count |
| Docker bind error | Use non-default port ranges; `kurtosis clean -a` between runs |
| Stale enclave state | Always `kurtosis clean -a` before relaunching (not `docker system prune`) |

## Tips

- **Start small:** 2+2 nodes for iteration, scale up for final validation
- **Test both roles:** Validator nodes show different bugs than observers — always check both
- **Multiple soak passes:** First clean run may miss edge cases. Run extended soaks (hours).
- **`kurtosis clean -a`** between runs — never use `docker system prune` (it can remove Kurtosis engine images)
- **Debug logs:** Set `global_log_level: "debug"` for verbose output from all nodes
- **Per-participant log levels:** Use `cl_log_level` / `el_log_level` on individual entries for targeted debugging

---

## Self-Maintenance

If any commands, file paths, URLs, or configurations in this skill are outdated or no longer work, update this SKILL.md with the correct information after completing your current task. Skills should stay accurate and self-healing — fix what you find broken.
Loading