Skip to content

Commit 2228501

Browse files
committed
docs: add CLAUDE.md
1 parent ec9c041 commit 2228501

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

CLAUDE.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# ethlambda Development Guide
2+
3+
Development reference for ethlambda - minimalist Lean Ethereum consensus client.
4+
Not to be confused with Ethereum consensus clients AKA Beacon Chain clients AKA Eth2 clients.
5+
6+
## Quick Reference
7+
8+
**Main branch:** `main`
9+
**Rust version:** 1.92.0 (edition 2024)
10+
**Test fixtures commit:** Check `LEAN_SPEC_COMMIT_HASH` in Makefile
11+
12+
## Codebase Structure (10 crates)
13+
14+
```
15+
bin/ethlambda/ # Entry point, CLI, orchestration
16+
crates/
17+
blockchain/ # State machine actor (GenServer pattern)
18+
├─ src/lib.rs # BlockChain actor, tick events, validator duties
19+
├─ src/store.rs # Fork choice store, block/attestation processing
20+
├─ fork_choice/ # LMD GHOST implementation (3SF-mini)
21+
└─ state_transition/ # STF: process_slots, process_block, attestations
22+
common/
23+
├─ types/ # Core types (State, Block, Attestation, Checkpoint)
24+
├─ crypto/ # XMSS aggregation (leansig wrapper)
25+
└─ metrics/ # Prometheus metrics
26+
net/
27+
├─ p2p/ # libp2p: gossipsub + req-resp (Status, BlocksByRoot)
28+
└─ rpc/ # Axum HTTP endpoints (/lean/v0/* and /metrics)
29+
storage/ # RocksDB backend, in-memory for tests
30+
```
31+
32+
## Key Architecture Patterns
33+
34+
### Actor Concurrency (spawned-concurrency)
35+
- **BlockChain**: Main state machine (GenServer pattern)
36+
- **P2P**: Network event loop with libp2p swarm
37+
- Communication via `mpsc::unbounded_channel`
38+
- Shared storage via `Arc<dyn StorageBackend>` (clone Store, share backend)
39+
40+
### Tick-Based Validator Duties (4-second slots, 4 intervals per slot)
41+
```
42+
Interval 0: Proposer check → accept attestations → build/publish block
43+
Interval 1: Non-proposers produce attestations
44+
Interval 2: Safe target update (fork choice with 2/3 threshold)
45+
Interval 3: Accept accumulated attestations
46+
```
47+
48+
### Attestation Pipeline
49+
```
50+
Gossip → Signature verification → new_attestations (pending)
51+
↓ (intervals 0/3)
52+
promote → known_attestations (fork choice active)
53+
54+
Fork choice head update
55+
```
56+
57+
### State Transition Phases
58+
1. **process_slots()**: Advance through empty slots, update historical roots
59+
2. **process_block()**: Validate header → process attestations → update justifications/finality
60+
3. **Justification**: 3SF-mini rules (delta ≤ 5 OR n² OR n(n+1))
61+
4. **Finalization**: Source with no unjustifiable gaps to target
62+
63+
## Development Workflow
64+
65+
### Before Committing
66+
```bash
67+
cargo fmt # Format code
68+
make lint # Clippy with -D warnings
69+
make test # All tests + forkchoice (with skip-signature-verification)
70+
```
71+
72+
### Common Operations
73+
```bash
74+
make run-devnet # Docker build → lean-quickstart local devnet
75+
rm -rf leanSpec && make leanSpec/fixtures # Regenerate test fixtures (requires uv)
76+
```
77+
78+
### Debugging
79+
80+
<!-- TODO: fill this part after a debug session -->
81+
82+
## Important Patterns & Idioms
83+
84+
### Metrics (RAII Pattern)
85+
```rust
86+
// Timing guard automatically observes duration on drop
87+
let _timing = metrics::time_state_transition();
88+
```
89+
90+
### Relative Indexing (justified_slots)
91+
```rust
92+
// Bounded storage: index relative to finalized_slot
93+
actual_slot = finalized_slot + 1 + relative_index
94+
// Helper ops in justified_slots_ops.rs
95+
```
96+
97+
## Cryptography & Signatures
98+
99+
**XMSS (eXtended Merkle Signature Scheme):**
100+
- Post-quantum signature scheme
101+
- 52-byte public keys, 3112-byte signatures
102+
- Epoch-based to prevent reuse
103+
- Aggregation via leanVM for efficiency
104+
105+
**Signature Aggregation (Two-Phase):**
106+
1. **Gossip signatures**: Fresh XMSS from network → aggregate via leanVM
107+
2. **Fallback to proofs**: Reuse previous block proofs for missing validators
108+
109+
## Networking (libp2p)
110+
111+
### Protocols
112+
- **Transport**: QUIC over UDP (TLS 1.3)
113+
- **Gossipsub**: Blocks + Attestations (snappy raw compression)
114+
- Topic: `/leanconsensus/{network}/{block|attestation}/ssz_snappy`
115+
- Mesh size: 8 (6-12 bounds), heartbeat: 700ms
116+
- **Req/Resp**: Status, BlocksByRoot (snappy frame compression + varint length)
117+
118+
### Retry Strategy on Block Requests
119+
- Exponential backoff: 10ms, 40ms, 160ms, 640ms, 2560ms
120+
- Max 5 attempts, random peer selection on retry
121+
122+
### Message IDs
123+
- 20-byte truncated SHA256 of: domain (valid/invalid snappy) + topic + data
124+
125+
## Configuration Files
126+
127+
**Genesis:** `genesis.json` (JSON format, cross-client compatible)
128+
- `GENESIS_TIME`: Unix timestamp for slot 0
129+
- `GENESIS_VALIDATORS`: Array of 52-byte XMSS pubkeys (hex)
130+
131+
**Validators:** JSON array of `{"pubkey": "...", "index": 0}`
132+
**Bootnodes:** ENR records (Base64-encoded, RLP decoded for QUIC port + secp256k1 pubkey)
133+
134+
## Testing
135+
136+
### Test Categories
137+
1. **Unit tests**: Embedded in source files
138+
2. **Spec tests**: From `leanSpec/fixtures/consensus/`
139+
- `forkchoice_spectests.rs` (requires `skip-signature-verification`)
140+
- `signature_spectests.rs`
141+
- `stf_spectests.rs` (state transition)
142+
143+
### Running Tests
144+
```bash
145+
cargo test --workspace --release # All workspace tests
146+
cargo test -p ethlambda-blockchain --features skip-signature-verification --test forkchoice_spectests
147+
```
148+
149+
## Common Gotchas
150+
151+
### Signature Verification
152+
- Tests require `skip-signature-verification` feature for performance
153+
- Crypto tests marked `#[ignore]` (slow leanVM operations)
154+
155+
### State Root Computation
156+
- Always computed via `tree_hash_root()` after full state transition
157+
- Must match proposer's pre-computed `block.state_root`
158+
159+
### Finalization Checks
160+
- Use `original_finalized_slot` for justifiability checks during attestation processing
161+
- Finalization updates can occur mid-processing
162+
163+
### `justified_slots` Window Shifting
164+
- Call `shift_window()` when finalization advances
165+
- Prunes justifications for now-finalized slots
166+
167+
## External Dependencies
168+
169+
**Critical:**
170+
- `leansig`: XMSS signatures (leanEthereum project)
171+
- `ethereum_ssz`: SSZ serialization
172+
- `tree_hash`: Merkle tree hashing
173+
- `spawned-concurrency`: Actor model
174+
- `libp2p`: P2P networking (custom LambdaClass fork)
175+
176+
**Storage:**
177+
- `rocksdb`: Persistent backend
178+
- In-memory backend for tests
179+
180+
## Resources
181+
182+
**Specs:** `leanSpec/src/lean_spec/` (Python reference implementation)
183+
**Devnet:** `lean-quickstart` (github.com/blockblaz/lean-quickstart)
184+
185+
## Other implementations
186+
187+
- zeam (Zig): <https://github.com/blockblaz/zeam>
188+
- ream (Rust): <https://github.com/ReamLabs/ream>
189+
- qlean (C++): <https://github.com/qdrvm/qlean-mini>

0 commit comments

Comments
 (0)