Run an L1 node
Evidence level: Production reference. The genesis files, peer IPs, and ports below were taken from the live CoNET L1 (chainId 224422) on 2026-08-17. Fetch live ENRs at join time. Do not reuse a stale checkout of genesis.json from an engineering script tree.
Public site: https://gitbook.conet.network/developers/l1-node.html
Anyone may run a geth + Prysm beacon full node and, after depositing 32 CNET per validator into the Beacon deposit contract, run a Prysm validator. That path is permissionless.
It is not Guardian addNode, not LayerMinus mining gossip, and not the ValidatorDepositRedeem application ledger. Those sets are documented on Participate in mining.
Vision: wallet-addressed consensus transport
CoNET L1 keeps Ethereum-compatible proof-of-stake consensus (Beacon) and an EVM execution environment. The architectural destination is not “a PoS fork with different genesis parameters.” It is:
A wallet-addressed, privacy-routed EVM proof-of-stake network — geth and Prysm still speak TCP/UDP to neighbors, but the long-lived application peer identity is a wallet / OpenPGP route on Layer Minus, not a stable public IP:port.
| Role | Traditional Ethereum | CoNET destination (L1-over-L0) |
|---|---|---|
| Validator identity | BLS public key | BLS public key (unchanged) |
| Application route identity | ENR / libp2p peer ID tied to IP | Routing EOA + OpenPGP keys |
| Network location | Public IP:port |
Dynamic L0 entry / mailbox / occupied pipe |
| Gossip transport | TCP/UDP on the Internet | Encrypted L0 duplex (AES session) over ordinary HTTP(S)+TCP/IP substrate |
| Client code | Native P2P stacks | Unmodified geth / Prysm behind TUN + conet-l0d |
The critical change is separating long-lived node identity from network location. A node can keep the same wallet route while changing ISP, data center, NAT, or Guardian entry — without publishing a stable reachable IP as its consensus neighbor identity.
Accurate wording: CoNET still uses TCP/IP underneath. Guardians and entries still need physical connectivity. Overlay VIPs such as 100.64.0.0/10 are compatibility addresses for unmodified clients. CoNET does not claim “no IP.” It claims that a fixed public IP is not required as the application-layer P2P identity.
Why this matters
- Consensus-plane location privacy — neighbors and external observers see wallet routes and L0 paths, not a permanent validator
IP:portmap. - Higher cost for targeted DDoS — attacks must discover and suppress dynamic entries and multiple Guardians, not only hammer one static host.
- NAT-friendly full nodes — inbound public ports are not the only way to keep a static peer; L0 occupy / reverse paths can carry geth and beacon TCP.
- Upstream-compatible engineering — L0 and L1 can be tested separately; public P2P remains a migration and emergency substrate.
Production honesty (do not collapse vision into “already shipped”)
| Plane | Status in this book |
|---|---|
| Permissionless join docs | Public hubs, live ENRs, and inbound 8400 / 4200 / 4300 — see below |
| conet-l0d overlay | Under development / lab-proven (geth + beacon TCP, lab discv5 via L0) — not a claim that every production proposer has abandoned public listen |
| Beacon index ≥ 2000 | Consensus-registry allocation evidence (decentralization) — not a census of “validators already on L0-only gossip” |
Until an explicit production cutover note is published with operator evidence (hubs, proposers, miss-slot / propagation metrics), treat wallet-addressed L1 gossip as the destination architecture, and treat public P2P as the documented permissionless join path and migration / fallback substrate.
Open engineering bar for full L0 consensus gossip
A six-second slot does not forgive optimistic routing. Before calling L0 the sole critical path, publish comparable metrics: L0 hop latency (P50/P95/P99), block propagation to 50%/90% of validators, attestation inclusion delay, missed slots and reorgs vs public-P2P baselines, duplex reconnect time, Guardian failure impact, and discv5 loss rates. Avoid collapsing many routing EOAs into one public wallet. Prefer occupied duplex for steady TCP; keep P1 for setup / wake / control / rare degrade — not the high-volume data plane. Use several entries, mailboxes, and ASN-diverse Guardians so privacy does not become Guardian centralization.
What you are joining
| Role | Permission | What it does |
|---|---|---|
| Execution + consensus node | Open | Sync and serve the canonical L1 tip; peer on geth and Prysm P2P |
| Beacon validator | Open after a 32 CNET deposit | Propose and attest once the deposit is processed |
| Guardian / DePIN miner | Permissioned (adminList on GuardianNodesInfoV6) |
L0 service plane — Participate in mining |
| VDR stake record | Application contract | ValidatorDepositRedeem 32 CNET ledger — not the Beacon deposit contract |
Do not treat totalStakedValidatorCount() as the Prysm active set. See Validators.
Downloads
Host these three files next to your datadir. They are the production execution genesis, consensus genesis, and Prysm chain config.
| File | URL | SHA-256 |
|---|---|---|
genesis.json |
https://gitbook.conet.network/l1/network/genesis.json | bc8e77990a5b76d75b6a2041a2ae4d69c9cda03d120b1434b8ce3e11296fde60 |
genesis.ssz |
https://gitbook.conet.network/l1/network/genesis.ssz | ae0a63e7bf175bb4312d5b728ff1eced7ceb4286ff5d7074cecbfa21dfd7fb46 |
config.yml |
https://gitbook.conet.network/l1/network/config.yml | 4bda580c4cfec801ecaed6fa04ad38bb9f1e941833fa7237ed5c6327f3cfbe24 |
Checksum list: SHA256SUMS
BASE=https://gitbook.conet.network/l1/network
mkdir -p conet-l1 && cd conet-l1
curl -fsSL -O "$BASE/genesis.json" -O "$BASE/genesis.ssz" -O "$BASE/config.yml" -O "$BASE/SHA256SUMS"
shasum -a 256 -c SHA256SUMS
A checksum mismatch means you must not geth init or start a beacon. Re-download; do not “fix” the files by hand.
Chain parameters
Confirm genesis against a live beacon before you treat a local copy as authoritative:
curl -s http://38.102.126.50:4100/eth/v1/beacon/genesis
| Field | Value |
|---|---|
chainId / deposit network |
224422 (0x36ca6) |
genesis_time |
1781376367 |
genesis_fork_version |
0x20000089 |
genesis_validators_root |
0xacac7566fdf384a1ada45c01dcf9030d7eb0e1e5f5302659101d0b2a5bb59092 |
| Beacon deposit contract | 0x4242424242424242424242424242424242424242 |
| Deposit per validator | 32 CNET |
| Slot / epoch | SECONDS_PER_SLOT=6, SLOTS_PER_EPOCH=32 |
| Eth1 follow | ETH1_FOLLOW_DISTANCE=64, EPOCHS_PER_ETH1_VOTING_PERIOD=4 |
| Electra | Disabled (ELECTRA_FORK_EPOCH = 18446744073709551615) |
| Recommended clients | geth 1.17.x, Prysm v7.1.4+ |
config.yml uses PRESET_BASE: interop and the fork versions above. Keep Electra disabled so the legacy deposit-contract path stays active.
The Beacon deposit contract is 0x4242…4242. It is not ValidatorDepositRedeem (0xc71e…).
Active L1 hosts
These six public IPs are the current execution / consensus / DHT hubs. Do not bootstrap from deprecated hosts (216.225.192.76, 207.90.192.71, 38.102.85.33, or other retired seeds).
| Public IP | Role |
|---|---|
38.102.126.30 |
Archive RPC, DHT hub, production beacon |
38.102.126.50 |
Public RPC, DHT hub, production beacon |
216.225.202.23 |
Full node, validators, DHT hub |
216.225.202.22 |
Full node, validators, DHT hub |
216.225.197.3 |
Full node, validators, DHT hub |
216.225.202.82 |
Full node, validators, DHT hub |
Ports
| Plane | Port | Protocol | Expose on your host? |
|---|---|---|---|
| Geth P2P | 8400 | TCP + UDP | Yes, if you want inbound peers |
| Production beacon REST | 4100 | TCP | Read-only on hubs; bind yours to loopback unless you intend a public API |
| Production beacon P2P | 4200 / 4300 | TCP / UDP | Yes, if you want inbound consensus peers |
| DHT ENR API | 4110 | TCP | Optional; you do not need to run a DHT hub to join |
| DHT P2P | 4210 / 4310 | TCP / UDP | DHT hub only |
Do not expose Engine API (authrpc), JWT, geth HTTP/WS, beacon gRPC, or validator RPC to the public Internet. Bind those to 127.0.0.1. Opening P2P is not the same as opening JSON-RPC.
DHT servers (consensus bootstrap)
Prefer live ENRs. Peer IDs change if a DHT process is rebuilt.
for ep in \
38.102.126.30:4110 \
38.102.126.50:4110 \
216.225.202.23:4110 \
216.225.202.22:4110 \
216.225.197.3:4110 \
216.225.202.82:4110
do
echo "== $ep"
curl -s --connect-timeout 5 "http://${ep}/eth/v1/node/identity" \
| python3 -c "import sys,json; d=json.load(sys.stdin)['data']; print(d['peer_id']); print(d['enr'])"
done
Pass each enr: string to Prysm as --bootstrap-node. That is the supported join path.
Snapshot DHT peer_id values (2026-08-17, port 4110 — not the production beacon):
| Host | DHT peer_id (:4110) |
|---|---|
38.102.126.30 |
16Uiu2HAmQoVe9DeBo4gW1WEmXohZLk3ACUkEeRGmBM7B5NAjU4YD |
38.102.126.50 |
16Uiu2HAm3a8Ak19rig7uwDKbWivRnjiwpfZNqZv6SsUeaTcBUPw8 |
216.225.202.23 |
16Uiu2HAmN51gXoyK9kyr5HkSWuRYizeA2m1ipW4fn3V3tGo1fCKs |
216.225.202.22 |
16Uiu2HAmBcwKE21Y2WV2guKpwBDkDXvxqQ9hRn1agC1S2Aneg3Nq |
216.225.197.3 |
16Uiu2HAkxR4cZAKjehmczq3teuYCAWqrkDmhsZLabJBa7QPyDj6q |
216.225.202.82 |
16Uiu2HAmGnXxJijMnNHQfrngvNNMvTdESCuJyuzbEQfxPdKMFx3T |
Optional static multiaddrs use TCP 4210 (DHT) or TCP 4200 (production beacon) plus the matching live peer_id. Production beacon peer_id on :4100 is different from the DHT sidecar on the same IP. If you pin --peer, curl :4100 / :4110 first.
Execution-layer bootnodes
Live geth enode records (P2P 8400, 2026-08-17):
enode://e5fe89d9ad924db6e4699480242a12fccba2c00e35772db706e46190c0ded9bb2b7e0d996826f5e46d369e01336213ef263c5038f94552e5f5e6e8ec76573a3f@38.102.126.30:8400
enode://d9243095bca94720f88d38c93ae4ccefc8b67651c66b4c93c915f845f6abfd39a091465db02db32b1a5b8061566c1558d2e6842f75620bf533480bab8a180168@38.102.126.50:8400
enode://5cf9a159e641318cda27e6bc1b4185667c0cdb1b54c3df5b8626eacbacea93af64c243dbdd09b40c62ba24792d0afc571cf17cbc47a5ed5a6207f27054c01d65@216.225.202.23:8400
enode://8e09d44bb4c29543a172e53dd8a74677a2a63d3d98a3d530f9d8b6f6bd6802a542f5b79d509ff737a9a764a66ab44a81403597cb50e350178ddd91f487e28f2d@216.225.202.22:8400
enode://dc0624c81896cdec036af7096886b1629a288b4824a467038df645c5c6b0f7fe75e13758ea80c0c37ba6245b221680db1fb553d564e54b55410eb6063bb64ca0@216.225.197.3:8400
enode://f1e249c97ce861441b3bd4832213cc634dd5c23d1a8722cd9c1aea28492779f6b64e012e8d97d56006d69be5224903ea5a787d8af68e9542db82ac1f76491dd5@216.225.202.82:8400
Pass them to geth as --bootnodes (comma-separated) and/or --nat=extip:<your-public-ip>. Your advertised IP must match the address peers will dial.
Older bootnode lists that still name 216.225.192.76 or the historic .50 id 206bf64b… are stale. Use the list above.
Start a full node
This is a shape, not a host rebuild script. Use your own datadir, JWT, and fee recipient. Do not copy another operator’s systemd units or secrets.
- Init execution (once):
geth init --datadir ./execution ./genesis.json
- Run geth with P2P on 8400, Engine API on loopback, and the bootnodes above. Example flags:
geth \
--datadir ./execution \
--networkid 224422 \
--port 8400 \
--discovery.port 8400 \
--nat extip:<YOUR_PUBLIC_IP> \
--bootnodes "<enode1>,<enode2>,..." \
--http --http.addr 127.0.0.1 --http.port 8545 --http.api eth,net,web3 \
--authrpc.addr 127.0.0.1 --authrpc.port 8551 \
--authrpc.jwtsecret ./jwtsecret \
--authrpc.vhosts localhost
Use gcmode=full for a validator-only machine. Archive mode is optional and heavier.
- Run Prysm beacon with the downloaded
genesis.sszandconfig.yml, Engine JWT, and live DHT ENRs:
beacon-chain \
--accept-terms-of-use \
--chain-id=224422 \
--genesis-state=./genesis.ssz \
--chain-config-file=./config.yml \
--execution-endpoint=http://127.0.0.1:8551 \
--jwt-secret=./jwtsecret \
--deposit-contract=0x4242424242424242424242424242424242424242 \
--p2p-host-ip=<YOUR_PUBLIC_IP> \
--p2p-tcp-port=4200 \
--p2p-udp-port=4300 \
--rpc-host=127.0.0.1 \
--grpc-gateway-host=127.0.0.1 \
--bootstrap-node=<ENR from :4110> \
--bootstrap-node=<ENR from another :4110>
Do not default to --peer against a single historic seed. Prefer several --bootstrap-node ENRs from the DHT list.
Firewall / security group: allow inbound 8400/tcp+udp and 4200/tcp + 4300/udp on your host. Opening only loopback RPC does not make you a peer.
Sync check: geth
admin.peersshould include at least one of the bootnodes; beacon should show peers and a rising head. Compareeth_blockNumberand beacon genesis root withhttps://rpc1.conet.networkand a hub:4100.
https://rpc.conet.network is deprecated and must not be used to judge sync.
Optional: overlay P2P (conet-l0d)
Destination: wallet-addressed L0 as the consensus gossip transport (Vision). Today: permissionless join still documents public hubs and inbound 8400 / 4200 / 4300. The Linux daemon (conet-l0d) adds a static overlay (100.64.0.0/10) so unmodified geth / Prysm can peer over Layer Minus. Maturity: Under development / lab-proven (2026-08-18/19). It does not yet claim that every production proposer has left public listen.
Operator how-to: Applications — L1 overlay daemon
CLI / config / TUN ownership: Developers — conet-l0d
Deploy a spoke that peers over overlay
Use this when the host is NAT’d or you want a fixed overlay peer to a hub that already runs conet-l0d. Evidence level: lab-proven (2026-08-18/19); maturity remains Under development.
- Hub and spoke both run
conet-l0dwith matching[[peers]]/[[l0.channels]](ports 8400 geth, 4200 beacon TCP; optional 4300 UDP). Enable[l0]only on authorized host configs. Each overlay port should use its own routing EOA + listen SSE when you use channels. - Start overlay before relying on peers
sudo conet-l0d start --config /etc/conet-l0d.toml # lab helpers (crate scripts): map VIP listen ↔ public bind; steer hub public dials onto overlay ./overlay-beacon-listen-dnat.sh apply ./overlay-dht-steer.sh apply # spoke only, when dialing a public hub ENR/IP then DNAT onto L0 Advertise overlay on the L0_ONLY spoke; keep RPC on loopback
# Spoke (example VIP 100.64.0.5) — advertise only; do not bind Engine/HTTP to the VIP geth --nat extip:100.64.0.5 --port 8400 --discovery.port 8400 \ --bootnodes "enode://<hub-key>@100.64.0.6:8400" \ --nodiscover --netrestrict 100.64.0.0/10 \ --http.addr 127.0.0.1 --authrpc.addr 127.0.0.1 beacon-chain --p2p-host-ip=100.64.0.5 --p2p-static-id \ --p2p-tcp-port=4200 --p2p-udp-port=4300 \ --p2p-allowlist=100.64.0.0/10 --no-discovery \ --peer=/ip4/100.64.0.6/tcp/4200/p2p/<hub-live-peer-id> \ --rpc-host=127.0.0.1 --grpc-gateway-host=127.0.0.1Fetch live hub
peer_idfrom the hub’s beacon REST (:4100/ gateway), not a stale doc row:curl -s http://127.0.0.1:4100/eth/v1/node/identity # on the hub- Hub may keep
--p2p-host-ip=<public-ip>and public peers. Overlay VIP listen still needsoverlay-beacon-listen-dnat.shso packets to100.64.0.6:4200reach the socket bound on the public IP. - Do not bind
--http.addr,--authrpc.addr,--p2p-local-ip, or--rpc-hostto the overlay VIP. Do not point SilentPass /SaaS_Sock5at these P2P ports.
Sync check (overlay)
| Check | Healthy |
|---|---|
| TUN | ip -4 addr show conet-l0 shows the spoke/hub VIP |
| Geth | net_peerCount ≥ 1 and ss shows 100.64.x.x ↔ 100.64.y.y:8400 ESTAB |
| Beacon | GET /eth/v1/node/peer_count → connected ≥ 1 and ss shows overlay :4200 ESTAB |
| Daemon | duplex_offer accepted and/or stable duplex AES frame on :8400 / :4200 (P1 alone is lossy for TCP handshake) |
geth overlay ESTAB does not prove beacon is peered. Always check :4200 separately. A large sync_distance with is_syncing=true means the node is catching up — that is not a peer failure.
Beacon connected=0 over overlay (recovery)
Lab incidents (2026-08-18/19) separated overlay failure from Prysm dial backoff:
| Symptom | Typical cause | Fix order |
|---|---|---|
dial backoff / failed to dial …/tcp/4200 while SYN-SENT never becomes ESTAB |
Occupied L0 pipe (HTTP 409) or broken DNAT/steer; TCP falls back to lossy P1 | Clear mailbox B SI occupy → bounce conet-l0d hub then spoke → flush tcp 4200 conntrack → re-apply DNAT/steer |
Overlay geth ESTAB but beacon still connected=0 |
Same as above on the 4200 channel only; or Prysm backoff after failed dials | Fix :4200 pipe first; then authorized restart-beacon on that host only |
After SI fleet rollout, lab floods l0_connect / P1 409 |
Mailbox B still holds exclusive l0_listen / l0_connect |
pkill SI on B (systemd restarts); wait until active; then ordered l0d bounce |
Ghost hub :4200 conntrack |
Steer/DNAT left stale NAT | overlay-dht-steer.sh apply / DNAT apply without restarting geth/beacon |
Authorized recovery sequence (light → heavy):
- Confirm hub
peer_idmatches the spoke--peermultiaddr. - Re-apply
overlay-beacon-listen-dnat.sh(both ends) and spokeoverlay-dht-steer.shif used; flushconntrackfor tcp sport/dport 4200. - If logs show 409: soft-restart CoNET-SI on mailbox B only (
pkilldist/start.js; do not wipe; do not restart geth/beacon for this step). - Bounce
conet-l0don the hub first, then the spoke; re-apply DNAT/steer after each start. - If Prysm still only logs dial backoff: restart beacon only on the spoke (example lab script:
./start-geth-beacon-only.sh restart-beacon). Do not wipe datadir; do not restart geth/validator; do not re-apply steer immediately after that restart. - Accept:
connected ≥ 1and overlay:4200ESTAB.
Joining overlay does not authorize restarting anyone else’s chain clients. See also the operator page troubleshooting section.
Stake a validator (optional)
After the node is synced:
- Generate validator keystores with a current Ethereum staking-deposit tool or Prysm’s key tools. Keep the mnemonic offline.
- Submit 32 CNET per validator to
0x4242424242424242424242424242424242424242onchainId224422, using the deposit calldata for those keys. - Wait for the eth1 follow distance (64 blocks) and the voting period (4 epochs) before expecting the validator to appear.
- Start
validatoragainst your local beacon, with your suggested fee recipient.
This page does not publish deposit private keys, operator wallets, or a hosted launchpad. A deposit to ValidatorDepositRedeem (0xc71e…) is a different application flow and does not by itself activate a Prysm validator.
Safety boundary
- Joining does not require, and this book does not authorize, restarting anyone else’s geth, beacon, or validator.
- Do not wipe
chaindata/ beacon data on a machine that is already producing. - Do not expose Engine API or validator keys.
- Do not invent a new download hostname; the files live under
https://gitbook.conet.network/l1/network/.
Related
- Validators — consensus role vs Guardian vs VDR
- Network identity —
chainIdand RPC policy - RPC and Explorer — application JSON-RPC (not P2P)
- Participate in mining — permissioned DePIN gossip
- L1 decentralization — three counts that are not interchangeable
- conet-l0d — optional overlay catch (Under development)
- Applications — L1 overlay daemon