From eb97b93588e422da8bff9e849cffcf43074b0e59 Mon Sep 17 00:00:00 2001 From: monty-sei Date: Mon, 10 Aug 2026 10:54:58 +1000 Subject: [PATCH] docs(node): document the Sei Labs seeds, retire the random peer list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the hardcoded list of community peer IPs with the Sei Labs seed nodes, and corrects the P2P config schema, which documented keys that do not exist in sei-tendermint. The old snippets/random-peers.jsx shipped 17 hardcoded addresses — mostly bare IPs of nodes we do not operate — and handed each reader a random five. Those rot silently as operators re-key or renumber, and a wrong NodeID is rejected at the handshake rather than degraded, so the failure is opaque. The seeds are stable identities behind stable DNS, three per network across three regions. Schema corrections (verified against sei-tendermint/config/toml.go): - seeds -> bootstrap-peers (the documented key does not exist) - persistent_peers -> persistent-peers, and the other underscore spellings - max_num_inbound_peers / max_num_outbound_peers / allowed_pools removed; the real keys are max-connections and max-incoming-connection-attempts - addr_book_strict removed from the validator sentry example — no such key exists, so that config would not have applied as written --- node/index.mdx | 46 ++++++--- node/technical-reference.mdx | 20 ++-- node/troubleshooting.mdx | 12 ++- node/validators.mdx | 12 +-- snippets/random-peers.jsx | 175 ----------------------------------- snippets/seeds.jsx | 120 ++++++++++++++++++++++++ 6 files changed, 177 insertions(+), 208 deletions(-) delete mode 100644 snippets/random-peers.jsx create mode 100644 snippets/seeds.jsx diff --git a/node/index.mdx b/node/index.mdx index 3b7977a..a996383 100644 --- a/node/index.mdx +++ b/node/index.mdx @@ -6,7 +6,7 @@ keywords: ["sei node", "node operations", "validator", "RPC node", "sei blockcha --- import { VersionTable } from '/snippets/version-table.jsx'; -import { RandomPeers } from '/snippets/random-peers.jsx'; +import { Seeds } from '/snippets/seeds.jsx'; **Power the Sei Network Infrastructure** @@ -133,28 +133,44 @@ See Network Versions table above for current recommended version. Default init mode is **full** (RPC/P2P bind to all interfaces). For **validator** or **seed** nodes, use `--mode validator` or `--mode seed` so RPC and P2P bind to localhost only. See the [Validator Operations Guide](/node/validators) for the full validator init example. -Peers can be found here - - -- mainnet (pacific-1): - - - -- testnet (atlantic-2): - - - ```bash # Initialize node (default mode is full: RPC/P2P bind to all interfaces) # For validator nodes, use: seid init --chain-id --mode validator seid init --chain-id # Genesis is written automatically for known networks (mainnet and testnets); no download needed. +# bootstrap-peers is also populated automatically with the Sei Labs seeds — no +# manual peer list needed. See "Peer discovery" below. +``` + +##### Peer discovery + +`seid init` writes the Sei Labs seed nodes into `bootstrap-peers` for you, so a +fresh node finds peers with no further configuration. The seeds run in three +regions per network, and they gossip the rest of the network to you over PEX — +you do not need to maintain a peer list. -# Configure peers in config.toml. -PEERS="" + + Seeds belong in `bootstrap-peers`, not `persistent-peers`. Bootstrap peers seed + your address book and may then be dropped once you have real peers; + `persistent-peers` holds connections open indefinitely, which is only + appropriate for nodes you operate yourself. + + +If you need to set them by hand — an existing node initialised before seeds +shipped, or a home you did not create with `seid init` — the values are: + +- mainnet (pacific-1): -#Set persistent peers in config.toml -sed -i 's/persistent-peers = .*/persistent-peers = "'$PEERS'"/' ~/.sei/config/config.toml + + +- testnet (atlantic-2): + + + +```bash +# Only needed if bootstrap-peers is empty (e.g. a node initialised before seeds shipped) +sed -i 's/bootstrap-peers = .*/bootstrap-peers = ""/' ~/.sei/config/config.toml ``` ##### Configure App Settings diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx index 186396a..cb6b4cd 100644 --- a/node/technical-reference.mdx +++ b/node/technical-reference.mdx @@ -132,15 +132,19 @@ The config.toml file controls the core consensus engine and networking: [p2p] laddr = "tcp://0.0.0.0:26656" external-address = "" -seeds = "" -persistent_peers = "" +# Populated automatically by `seid init` on known networks with the Sei Labs seeds. +bootstrap-peers = "" +persistent-peers = "" +blocksync-peers = "" upnp = false -max_num_inbound_peers = 40 -max_num_outbound_peers = 10 -allowed_pools = "" -max_packet_msg_payload_size = 10240 -handshake_timeout = "20s" -dial_timeout = "3s" +max-connections = 64 +max-incoming-connection-attempts = 100 +pex = true +private-peer-ids = "" +allow-duplicate-ip = false +max-packet-msg-payload-size = 1400 +handshake-timeout = "20s" +dial-timeout = "3s" # RPC Configuration [rpc] diff --git a/node/troubleshooting.mdx b/node/troubleshooting.mdx index 2d129dd..6e73f5c 100644 --- a/node/troubleshooting.mdx +++ b/node/troubleshooting.mdx @@ -4,7 +4,7 @@ description: 'Detailed guide for troubleshooting node problems.' keywords: ['sei node', 'blockchain node', 'node configuration', 'bug', 'troubleshooting'] --- -import { RandomPeers } from '/snippets/random-peers.jsx'; +import { Seeds } from '/snippets/seeds.jsx'; Understanding common errors and their solutions helps maintain a healthy node operation. @@ -189,9 +189,15 @@ ERR peer handshake failed endpoint={} err=EOF module=p2p **Resolution Steps:** -1. **Update peer configurations** with current node IDs: +1. **Point the node at the Sei Labs seeds.** They hold stable identities behind + stable DNS, so unlike a hand-maintained peer list they do not go stale: - + + + The first error above — `expected to connect with peer X, got Y` — means the + node ID paired with that address is wrong. The handshake pins the ID, so a + mismatched pair is rejected outright rather than degraded. Replace the entry + rather than retrying it. 2. **Verify network connectivity:** diff --git a/node/validators.mdx b/node/validators.mdx index 003d7dd..28ffa9b 100644 --- a/node/validators.mdx +++ b/node/validators.mdx @@ -112,18 +112,16 @@ Validators may choose to implement a sentry node architecture to protect the blo # Validator node config.toml [p2p] pex = false -persistent_peers = "sentry_node_id@sentry_node_ip:26656" -private_peer_ids = "" -addr_book_strict = false +persistent-peers = "sentry_node_id@sentry_node_ip:26656" +private-peer-ids = "" # Sentry node config.toml [p2p] pex = true -persistent_peers = "validator_node_id@ip:port" -private_peer_ids = "validator_node_id" -addr_book_strict = true +persistent-peers = "validator_node_id@ip:port" +private-peer-ids = "validator_node_id" #optional -unconditional_peer_ids = "validator_node_id" +unconditional-peer-ids = "validator_node_id" ``` ### Key Management Practices diff --git a/snippets/random-peers.jsx b/snippets/random-peers.jsx deleted file mode 100644 index 3daa06a..0000000 --- a/snippets/random-peers.jsx +++ /dev/null @@ -1,175 +0,0 @@ -export const RandomPeers = ({ format = 'bash', network = 'mainnet', count = 5 }) => { - const PEERS = { - mainnet: [ - 'd53ab7681ed0df3d3249fc0132df7c3a131c9c1a@45.250.253.40:51656', - '4ee8aea5bb58e9038d72e74322e3bba755287398@202.8.8.183:11956', - '81409623ae4da3ec7b400cf640dea0b0999a964b@57.128.230.96:51556', - '61a5be64b5215786fe5da712584678d0626636b5@87.249.137.71:51556', - 'f83c536f43df9a5d900cd3c2f702c04d7dddc7b5@136.243.67.45:11956', - 'b8d600a2f568576b5a2df5ee649cf9b809389064@162.19.62.176:26756', - '57860b18ed3e1bbe8901ba73f2e63c7e6fe8b3d3@57.129.54.81:26656', - '04fc6bba6c5c33034811612dca31c7adda24b299@91.134.60.37:16856', - 'de64b779c7f4091e6f1765f5ca4c46f9d3011732@65.108.70.106:46656', - '3be6b24cf86a5938cce7d48f44fb6598465a9924@p2p.state-sync.pacific-1.seinetwork.io:26656', - '70e0c91b83b5ed1beaca798267f2debdf97dac10@18.156.6.83:26656', - 'dd6b1ae002a15c1c8a38e05660f49a93c75d4159@148.251.181.225:26656' - ], - testnet: [ - '71beea83970431f55816eee5f066a611a1dc80f7@p2p.state-sync.atlantic-2.seinetwork.io:26656', - '65c257f9275beb1b99ca169ef89743c034b15db0@3.76.192.224:26656', - '33588592e477c5238ff2a5d8dc765f85790ef853@23.109.47.225:26656', - 'babc3f3f7804933265ec9c40ad94f4da8e9e0017@testnet-seed.rhinostake.com:11956', - '8542cd7e6bf9d260fef543bc49e59be5a3fa9074@seed.publicnode.com:56656' - ] - }; - - const pickRandom = (arr, n) => { - const shuffled = [...arr]; - for (let i = shuffled.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; - } - return shuffled.slice(0, Math.min(n, arr.length)); - }; - - const CopyIcon = ({ className }) => ( - - - - - ); - - const CheckIcon = ({ className }) => ( - - - - ); - - const ShuffleIcon = ({ className }) => ( - - - - - - - - ); - - const pool = PEERS[network] ?? []; - - // Peers are inlined, not fetched. Seed with a deterministic slice so the - // first paint already shows peers (no misleading "loading" text, no - // SSR/hydration mismatch), then randomize on the client in useEffect. - const [peers, setPeers] = useState(() => pool.slice(0, count)); - const [copied, setCopied] = useState(false); - - const shuffle = () => { - setPeers(pickRandom(pool, count)); - }; - - useEffect(() => { - shuffle(); - }, [network, count]); - - if (pool.length === 0) { - return ( -
-
-          No peers configured for network “{network}”.
-        
-
- ); - } - - const peerString = peers.join(','); - const displayText = format === 'toml' ? `persistent_peers = "${peerString}"` : `PEERS="${peerString}"`; - - const handleCopy = async () => { - try { - await navigator.clipboard.writeText(displayText); - setCopied(true); - setTimeout(() => setCopied(false), 2000); - } catch { - // noop - } - }; - - return ( -
-
-
-          {displayText}
-        
-
- - -
-
-
- ); -}; diff --git a/snippets/seeds.jsx b/snippets/seeds.jsx new file mode 100644 index 0000000..1b82ce3 --- /dev/null +++ b/snippets/seeds.jsx @@ -0,0 +1,120 @@ +export const Seeds = ({ format = 'bash', network = 'mainnet' }) => { + // Sei Labs operated seed nodes. Three per network, one per region, so losing + // a region does not cost bootstrap capability. + // + // These are stable, published addresses: the NodeID is pinned by the + // secret-connection handshake, so a mismatched pair is rejected rather than + // silently degraded. Do not edit without updating the platform repo — the + // source of truth is the SeiNode's externalAddress and NodeID in + // clusters///seeds/seed-N/. + const SEEDS = { + mainnet: [ + '0cd5f57c249b5aca815710338e1fe7a14797585d@seed-0-p2p.pacific-1.prod.platform.sei.io:26656', + 'f0f057f1593d28bec11591cf146bd223e0be1866@seed-1-p2p.pacific-1.prod-euw1.platform.sei.io:26656', + '8e28f62368a1ceae0102645db8584b218650930d@seed-2-p2p.pacific-1.prod-use2.platform.sei.io:26656' + ], + testnet: [ + '362f934ead3654fca9cafdac63b52b47b2f9a95e@seed-0-p2p.atlantic-2.prod.platform.sei.io:26656', + '1f55cd51183d3a6cad8a3667b91d08d0338bd52e@seed-1-p2p.atlantic-2.prod-euw1.platform.sei.io:26656', + '7152be2e4c1a057d2b2467723058c5f0ec790472@seed-2-p2p.atlantic-2.prod-use2.platform.sei.io:26656' + ] + }; + + const CopyIcon = ({ className }) => ( + + + + + ); + + const CheckIcon = ({ className }) => ( + + + + ); + + const [copied, setCopied] = useState(false); + + const seeds = SEEDS[network] ?? []; + + if (seeds.length === 0) { + return ( +
+
+          No seeds configured for network “{network}”.
+        
+
+ ); + } + + const seedString = seeds.join(','); + const displayText = format === 'toml' ? `bootstrap-peers = "${seedString}"` : `SEEDS="${seedString}"`; + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(displayText); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch { + // noop + } + }; + + return ( +
+
+
+          {displayText}
+        
+
+ +
+
+
+ ); +};