Test Execution & Writing Skill
Test Execution & Writing — run pytest, write new tests, check coverage
P2P Networking Debug — RLPx, devp2p, sync issue diagnosis
Full skill instructions
Specialized skill for diagnosing and resolving RLPx connections, devp2p handshakes, and synchronization issues.
| File | Role |
|---|---|
ethclient/networking/rlpx/transport.py | RLPx connection, ECIES handshake |
ethclient/networking/rlpx/ecies.py | ECIES encryption/decryption |
ethclient/networking/rlpx/protocol.py | devp2p protocol messages |
ethclient/networking/eth/protocol.py | eth/68 message encoding/decoding |
ethclient/networking/snap/protocol.py | snap/1 messages |
ethclient/networking/discv4/ | Discovery v4 (Kademlia) |
ethclient/networking/sync/full_sync.py | Full sync strategy |
ethclient/networking/sync/snap_sync.py | Snap sync strategy |
conn.use_snappy = True for Geth v1.17.0+["eth/68", "snap/1"] matchingMost common connection refusal reason:
from ethclient.networking.rlpx.protocol import DisconnectReason
# DisconnectReason.TOO_MANY_PEERS == 0x04
Mitigation strategies:
# Sepolia bootnodes (EF DevOps, high connection success rate)
SEPOLIA_BOOTNODES = [
("138.197.51.181", 30303),
("146.190.1.103", 30303),
]
ECIES Handshake Flow:
Initiator Responder
| |
|--- auth-msg (ECIES) ------>| (pubkey + nonce + signature)
| |
|<--- auth-ack (ECIES) ------| (pubkey + nonce)
| |
|--- [frame cipher init] --->| (AES-CTR + MAC secrets derived)
| |
|--- Hello (p2p) ----------->| (version, client, caps, port, id)
|<--- Hello (p2p) ----------|
| |
|--- Status (eth/68) ------->| (network, genesis, head, forkid)
|<--- Status (eth/68) ------|
Common failure causes:
MAC mismatch: ECIES key derivation error. Check local keyUnexpected message: Non-Hello message received before Hello. Check frame parsingProtocol version mismatch: devp2p v5 requiredNetwork ID mismatch: Mainnet=1, Sepolia=11155111Genesis hash mismatch: Use correct genesis for the network# Required for Geth v1.17.0+
conn.use_snappy = True
# Symptoms: message decoding failure, RLP parsing errors
# Cause: missing snappy compress/decompress
# Fix: verify python-snappy package is installed
# pip install python-snappy
from ethclient.networking.rlpx.ecies import ecies_encrypt, ecies_decrypt
# auth-msg creation
# 1. Generate ephemeral keypair
# 2. Sign with static key
# 3. Encrypt with ECIES (using remote public key)
# 4. Send
# auth-ack processing
# 1. Decrypt with ECIES (using local private key)
# 2. Derive shared secret (ECDH)
# 3. Generate frame cipher keys (KDF)
[header (16B, AES-CTR encrypted)]
[header-mac (16B)]
[frame (variable, AES-CTR encrypted, padded to 16B)]
[frame-mac (16B)]
header: [frame-size (3B big-endian)] [header-data (13B)]
# p2p message codes
HELLO = 0x00
DISCONNECT = 0x01
PING = 0x02
PONG = 0x03
# Hello fields:
# version: 5
# client_id: "py-ethclient/1.0"
# caps: [["eth", 68], ["snap", 1]]
# listen_port: 30303
# node_id: 64-byte public key
class DisconnectReason(IntEnum):
REQUESTED = 0x00 # Normal shutdown
TCP_ERROR = 0x01 # TCP error
BREACH_OF_PROTOCOL = 0x02 # Protocol violation
USELESS_PEER = 0x03 # Useless peer
TOO_MANY_PEERS = 0x04 # Peer limit exceeded ★
ALREADY_CONNECTED = 0x05 # Already connected
INCOMPATIBLE_VERSION = 0x06 # Incompatible version
INVALID_IDENTITY = 0x07 # Invalid identity
CLIENT_QUITTING = 0x08 # Client quitting
UNEXPECTED_IDENTITY = 0x09 # Unexpected identity
CONNECTED_TO_SELF = 0x0a # Connected to self
TIMEOUT = 0x0b # Timeout
SUBPROTOCOL_ERROR = 0x10 # Subprotocol error
# Post-Status exchange validation items:
# 1. networkId match (1=mainnet, 11155111=sepolia)
# 2. genesisHash match
# 3. forkID compatibility (fork_hash + fork_next)
# ForkID calculation:
# fork_hash = CRC32(genesis_hash + fork_block_numbers)
# fork_next = next scheduled hard fork block
# On mismatch: DISCONNECT(SUBPROTOCOL_ERROR)
[hash (32B)] [signature (65B)] [type (1B)] [data (RLP)]
hash = keccak256(signature || type || data)
from ethclient.networking.discv4.routing import Node, RoutingTable
# Add bootnode to table
boot = Node(id=boot_pubkey, ip="138.197.51.181", udp_port=30303, tcp_port=30303)
table.add_node(boot)
# Discover nearby nodes via FindNode
closest = table.closest_nodes(target_id=my_node_id, count=16)
| Symptom | Cause | Resolution |
|---|---|---|
| Header download stalls | No peer response | Try different peer, adjust timeout |
| Missing bodies | Peer lacks data | Distribute requests across peers |
| EVM execution failure | State mismatch | Re-execute from earlier block |
| Slow synchronization | Sequential block processing | Use snap sync |
| Symptom | Cause | Resolution |
|---|---|---|
| Empty AccountRange response | Pivot block too old | Restart with fresh pivot |
| Proof verification failure | State changed | Update pivot block |
| Missing bytecodes | Hash mismatch | Re-request from different peer |
| Timeouts | Slow peer | Use adaptive timeout |
# Snap sync timeout constants
SNAP_TIMEOUT = 15 # seconds (default)
PEER_WAIT_TIMEOUT = 30 # peer wait
# adaptive_timeout: automatically increases for slow peers
import logging
# P2P debug logging
logging.getLogger("ethclient.networking.rlpx").setLevel(logging.DEBUG)
logging.getLogger("ethclient.networking.eth").setLevel(logging.DEBUG)
logging.getLogger("ethclient.networking.discv4").setLevel(logging.DEBUG)
logging.getLogger("ethclient.networking.sync").setLevel(logging.DEBUG)
| Item | Mainnet | Sepolia |
|---|---|---|
| Network ID | 1 | 11155111 |
| Chain ID | 1 | 11155111 |
| Bootnode success rate | Low (TOO_MANY_PEERS) | High |
| eth protocol | eth/68, eth/69 | eth/68, eth/69 |
| snap protocol | snap/1 | snap/1 |
| Snappy | Required | Required |
Test Execution & Writing — run pytest, write new tests, check coverage
ZK Circuit Build & Groth16 Proofs — from circuit design to EVM verification
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience