Skip to content

Commit a13b5bc

Browse files
committed
chore: update CLAUDE.md and add skills
1 parent 91aff42 commit a13b5bc

File tree

5 files changed

+623
-4
lines changed

5 files changed

+623
-4
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
---
2+
name: test-pr-devnet
3+
description: Test ethlambda PR changes in multi-client devnet. Use when users want to (1) Test a branch/PR with other Lean clients, (2) Validate BlocksByRoot or P2P protocol changes, (3) Test sync recovery with pause/unpause, (4) Verify cross-client interoperability, (5) Run integration tests before merging.
4+
disable-model-invocation: true
5+
---
6+
7+
# Test PR in Devnet
8+
9+
Test ethlambda branch changes in a multi-client local devnet with zeam (Zig), ream (Rust), qlean (C++), and ethlambda.
10+
11+
## Quick Start
12+
13+
```bash
14+
# Test current branch (basic interoperability, ~60-90s)
15+
.claude/skills/test-pr-devnet/scripts/test-branch.sh
16+
17+
# Test with sync recovery (BlocksByRoot validation, ~90-120s)
18+
.claude/skills/test-pr-devnet/scripts/test-branch.sh --with-sync-test
19+
20+
# Test specific branch
21+
.claude/skills/test-pr-devnet/scripts/test-branch.sh my-feature-branch
22+
23+
# Check status while running
24+
.claude/skills/test-pr-devnet/scripts/check-status.sh
25+
26+
# Cleanup when done
27+
.claude/skills/test-pr-devnet/scripts/cleanup.sh
28+
```
29+
30+
## What It Does
31+
32+
1. **Builds branch-specific Docker image** tagged as `ghcr.io/lambdaclass/ethlambda:<branch-name>`
33+
2. **Updates lean-quickstart config** to use new image (backs up original)
34+
3. **Starts 4-node devnet** with fresh genesis (zeam, ream, qlean, ethlambda)
35+
4. **Optionally tests sync recovery** by pausing/unpausing nodes
36+
5. **Analyzes results** and provides summary
37+
6. **Leaves devnet running** for manual inspection
38+
39+
## Prerequisites
40+
41+
| Requirement | Location | Check |
42+
|-------------|----------|-------|
43+
| lean-quickstart | `/Users/mega/lean_consensus/lean-quickstart` | `ls $LEAN_QUICKSTART` |
44+
| Docker running | - | `docker ps` |
45+
| Git repository | ethlambda root | `git branch` |
46+
47+
## Test Scenarios
48+
49+
### Basic Interoperability (~60-90s)
50+
51+
**Goal:** Verify ethlambda produces blocks and reaches consensus with other clients
52+
53+
**Success criteria:**
54+
- ✅ No errors in ethlambda logs
55+
- ✅ All 4 nodes at same head slot
56+
- ✅ Finalization advancing (every 6-12 slots)
57+
- ✅ Each validator produces blocks for their slots
58+
59+
### Sync Recovery (~90-120s)
60+
61+
**Goal:** Test BlocksByRoot request/response when nodes fall behind
62+
63+
**Usage:** Add `--with-sync-test` flag
64+
65+
**What happens:**
66+
1. Devnet runs for 10s (~2-3 slots)
67+
2. Pauses `zeam_0` and `qlean_0`
68+
3. Network progresses 20s (~5 slots)
69+
4. Unpauses nodes → nodes sync
70+
71+
**Success criteria:**
72+
- ✅ Inbound BlocksByRoot requests logged
73+
- ✅ Successful responses sent
74+
- ✅ Paused nodes sync to current head
75+
76+
## Configuration Changes
77+
78+
The skill modifies `lean-quickstart/client-cmds/ethlambda-cmd.sh` to use your branch's Docker image.
79+
80+
**Automatic backup:** Creates `ethlambda-cmd.sh.backup`
81+
82+
**Restore methods:**
83+
```bash
84+
# 1. Cleanup script (recommended)
85+
.claude/skills/test-pr-devnet/scripts/cleanup.sh
86+
87+
# 2. Manual restore
88+
mv $LEAN_QUICKSTART/client-cmds/ethlambda-cmd.sh.backup \
89+
$LEAN_QUICKSTART/client-cmds/ethlambda-cmd.sh
90+
91+
# 3. Git restore (if no uncommitted changes)
92+
cd $LEAN_QUICKSTART && git checkout client-cmds/ethlambda-cmd.sh
93+
```
94+
95+
## Manual Workflow (Alternative to Script)
96+
97+
If you need fine-grained control:
98+
99+
### 1. Build Image
100+
101+
```bash
102+
cd /Users/mega/lean_consensus/ethlambda
103+
BRANCH=$(git rev-parse --abbrev-ref HEAD)
104+
docker build \
105+
--build-arg GIT_COMMIT=$(git rev-parse HEAD) \
106+
--build-arg GIT_BRANCH=$BRANCH \
107+
-t ghcr.io/lambdaclass/ethlambda:$BRANCH .
108+
```
109+
110+
### 2. Update Configuration
111+
112+
Edit `$LEAN_QUICKSTART/client-cmds/ethlambda-cmd.sh` line 17:
113+
```bash
114+
node_docker="ghcr.io/lambdaclass/ethlambda:<your-branch> \
115+
```
116+
117+
### 3. Start Devnet
118+
119+
```bash
120+
cd $LEAN_QUICKSTART
121+
NETWORK_DIR=local-devnet ./spin-node.sh --node all --generateGenesis --metrics
122+
```
123+
124+
### 4. Test Sync (Optional)
125+
126+
```bash
127+
# Create sync gap
128+
docker pause zeam_0 qlean_0
129+
sleep 20 # Network progresses
130+
131+
# Test recovery
132+
docker unpause zeam_0 qlean_0
133+
sleep 10 # Wait for sync
134+
```
135+
136+
### 5. Check Results
137+
138+
```bash
139+
# Quick status
140+
.claude/skills/test-pr-devnet/scripts/check-status.sh
141+
142+
# Detailed analysis (use devnet-log-review skill in lean-quickstart)
143+
cd $LEAN_QUICKSTART
144+
.claude/skills/devnet-log-review/scripts/analyze-logs.sh
145+
```
146+
147+
## Protocol Compatibility
148+
149+
| Client | Status | Gossipsub | BlocksByRoot |
150+
|--------|--------|-----------|--------------|
151+
| ream | ✅ Full | ✅ Full | ✅ Full |
152+
| zeam | ✅ Full | ✅ Full | ⚠️ Limited |
153+
| qlean | ✅ Full | ✅ Full | ⚠️ Limited |
154+
| ethlambda | ✅ Full | ✅ Full | ✅ Full |
155+
156+
**Notes:**
157+
- zeam/qlean BlocksByRoot errors are expected (not a blocker)
158+
- ream ↔ ethlambda BlocksByRoot should work perfectly
159+
- All clients use Gossipsub for block propagation
160+
161+
## Verification Checklist
162+
163+
| Check | Command | Expected |
164+
|-------|---------|----------|
165+
| All nodes running | `docker ps --filter "name=_0"` | 4 containers |
166+
| Peers connected | `docker logs ethlambda_0 \| grep "Received status request" \| wc -l` | > 10 |
167+
| Blocks produced | `docker logs ethlambda_0 \| grep "Published block" \| wc -l` | > 0 |
168+
| No errors | `docker logs ethlambda_0 \| grep ERROR \| wc -l` | 0 |
169+
170+
## Troubleshooting
171+
172+
### Build Fails
173+
```bash
174+
docker ps # Check Docker running
175+
docker system prune -a # Clean cache if needed
176+
```
177+
178+
### Nodes Won't Start
179+
```bash
180+
# Clean and retry
181+
docker stop zeam_0 ream_0 qlean_0 ethlambda_0 2>/dev/null
182+
docker rm zeam_0 ream_0 qlean_0 ethlambda_0 2>/dev/null
183+
cd $LEAN_QUICKSTART
184+
NETWORK_DIR=local-devnet ./spin-node.sh --node all --generateGenesis
185+
```
186+
187+
### Genesis Mismatch
188+
```bash
189+
cd $LEAN_QUICKSTART
190+
NETWORK_DIR=local-devnet ./spin-node.sh --node all --cleanData --generateGenesis
191+
```
192+
193+
### Image Tag Not Updated
194+
```bash
195+
# Verify the change
196+
grep "node_docker=" $LEAN_QUICKSTART/client-cmds/ethlambda-cmd.sh
197+
# Should show your branch name, not :local
198+
```
199+
200+
### Port Already in Use
201+
```bash
202+
docker stop $(docker ps -q --filter "name=_0") 2>/dev/null || true
203+
```
204+
205+
## Debugging
206+
207+
### P2P Request/Response Debugging
208+
209+
```bash
210+
# Check inbound BlocksByRoot handling
211+
docker logs ethlambda_0 2>&1 | grep "Received BlocksByRoot request"
212+
docker logs ethlambda_0 2>&1 | grep "Responding to BlocksByRoot"
213+
214+
# Check outbound BlocksByRoot requests
215+
docker logs ethlambda_0 2>&1 | grep "Sending BlocksByRoot request"
216+
docker logs ethlambda_0 2>&1 | grep "Received BlocksByRoot response"
217+
218+
# Check for protocol errors
219+
docker logs ethlambda_0 2>&1 | grep -E "Outbound request failed|protocol.*not.*support"
220+
221+
# Count requests/responses
222+
docker logs ethlambda_0 2>&1 | grep "Received BlocksByRoot request" | wc -l
223+
```
224+
225+
### Devnet Status Checks
226+
227+
```bash
228+
# Check all nodes are running
229+
docker ps --format "{{.Names}}: {{.Status}}" --filter "name=_0"
230+
231+
# Get current chain status (zeam)
232+
docker logs zeam_0 2>&1 | tail -100 | grep "CHAIN STATUS" | tail -1
233+
234+
# Get fork choice updates (ethlambda)
235+
docker logs ethlambda_0 2>&1 | grep "Fork choice head updated" | tail -5
236+
237+
# Check peer connectivity
238+
docker logs ethlambda_0 2>&1 | grep "Received status request" | wc -l
239+
```
240+
241+
### Common Investigation Patterns
242+
243+
```bash
244+
# Verify ethlambda is proposing blocks
245+
docker logs ethlambda_0 2>&1 | grep "We are the proposer"
246+
247+
# Compare finalized slots across clients
248+
for node in zeam_0 ream_0 ethlambda_0; do
249+
echo "$node:"
250+
docker logs "$node" 2>&1 | grep -i "finalized" | tail -1
251+
done
252+
253+
# Check peer discovery
254+
docker logs ethlambda_0 2>&1 | grep -i "peer\|connection" | head -20
255+
```
256+
257+
## References
258+
259+
- **[ethlambda CLAUDE.md](../../CLAUDE.md)** - Development workflow, detailed debugging commands
260+
- **[lean-quickstart devnet-log-review](../../../lean-quickstart/.claude/skills/devnet-log-review/SKILL.md)** - Comprehensive log analysis
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/bash
2+
3+
# Quick devnet status check
4+
5+
# Colors
6+
GREEN='\033[0;32m'
7+
RED='\033[0;31m'
8+
BLUE='\033[0;34m'
9+
NC='\033[0m'
10+
11+
echo -e "${BLUE}=== Devnet Status ===${NC}"
12+
echo ""
13+
14+
# Check running nodes
15+
echo "Running nodes:"
16+
docker ps --format " {{.Names}}: {{.Status}}" --filter "name=_0"
17+
echo ""
18+
19+
# Check each node's latest status
20+
for node in zeam_0 ream_0 qlean_0 ethlambda_0; do
21+
if docker ps --format "{{.Names}}" | grep -q "^$node$"; then
22+
echo -e "${GREEN}$node${NC}:"
23+
24+
case $node in
25+
zeam_0)
26+
docker logs zeam_0 2>&1 | tail -100 | grep "CHAIN STATUS" | tail -1 | sed 's/^/ /'
27+
;;
28+
ethlambda_0)
29+
docker logs ethlambda_0 2>&1 | grep "Fork choice head updated" | tail -1 | sed 's/^/ /'
30+
;;
31+
*)
32+
echo " (check logs manually)"
33+
;;
34+
esac
35+
echo ""
36+
fi
37+
done
38+
39+
# Check peer connectivity
40+
if docker ps --format "{{.Names}}" | grep -q "^ethlambda_0$"; then
41+
PEERS=$(docker logs ethlambda_0 2>&1 | grep "Received status request" | wc -l | tr -d ' ')
42+
echo "ethlambda peer interactions: $PEERS"
43+
echo ""
44+
fi
45+
46+
# Quick error check
47+
echo "Error counts:"
48+
for node in zeam_0 ream_0 qlean_0 ethlambda_0; do
49+
if docker ps --format "{{.Names}}" | grep -q "^$node$"; then
50+
COUNT=$(docker logs "$node" 2>&1 | grep -c "ERROR" || echo "0")
51+
if [[ "$COUNT" -eq 0 ]]; then
52+
echo -e " $node: ${GREEN}$COUNT${NC}"
53+
else
54+
echo -e " $node: ${RED}$COUNT${NC}"
55+
fi
56+
fi
57+
done
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
# Cleanup devnet and restore configurations
4+
5+
LEAN_QUICKSTART="${LEAN_QUICKSTART:-/Users/mega/lean_consensus/lean-quickstart}"
6+
ETHLAMBDA_CMD="$LEAN_QUICKSTART/client-cmds/ethlambda-cmd.sh"
7+
8+
# Colors
9+
GREEN='\033[0;32m'
10+
BLUE='\033[0;34m'
11+
NC='\033[0m'
12+
13+
echo -e "${BLUE}=== Devnet Cleanup ===${NC}"
14+
echo ""
15+
16+
# Stop devnet
17+
echo "Stopping devnet..."
18+
cd "$LEAN_QUICKSTART"
19+
NETWORK_DIR=local-devnet ./spin-node.sh --node all --stop 2>/dev/null || true
20+
21+
# Force remove containers
22+
echo "Removing containers..."
23+
docker rm -f zeam_0 ream_0 qlean_0 ethlambda_0 2>/dev/null || true
24+
25+
echo -e "${GREEN}✓ Devnet stopped${NC}"
26+
echo ""
27+
28+
# Restore config if backup exists
29+
if [[ -f "$ETHLAMBDA_CMD.backup" ]]; then
30+
echo "Restoring ethlambda-cmd.sh..."
31+
mv "$ETHLAMBDA_CMD.backup" "$ETHLAMBDA_CMD"
32+
echo -e "${GREEN}✓ Config restored${NC}"
33+
else
34+
echo "No backup found, skipping config restore"
35+
fi
36+
37+
echo ""
38+
echo "Cleanup complete!"

0 commit comments

Comments
 (0)