The five onboarding phases
Onboarding is an ordered pipeline — each phase depends on the previous.- Pre-flight — clock sync, iroh key generation, Ethereum key funding, region selection
- On-chain setup — TOKEN approval, staking, atomic
registerNode - Node startup — rate-bounds fetch, blacklist sync, peer table bootstrap from registry
- Gossip subscription — join
cdn/global/v1and regional topic, publish firstNodeAnnounce - Accepting paid delivery — seven acceptance criteria below
Phase 1: Pre-flight
- NTP sync. Gossip validation requires ±60 s agreement for
NodeAnnouncefreshness. A skewed clock will cause your announcements to be rejected silently. - iroh keypair.
decdn node init-keys. Store securely — loss means recovery viareclaimNodeId(requires proving Ethereum address ownership). - Ethereum key funding. Enough TOKEN for
minStake+ buffer for challenge bonds. Enough native gas for ~20 transactions (registration, stake top-up, occasional updates). - Region. Two-letter country code. Pick where your node is physically located; misrepresenting region creates reputation + compliance exposure.
Phase 2: On-chain setup
registerNode call is atomic:
- Pulls
stakeAmountTOKEN from your address (must be ≥minStake). - Verifies the EIP-712 signature (your Ethereum address committing to your NodeId).
- Verifies the ed25519 ownership proof (your NodeId committing to your Ethereum address, preventing squatting).
- Writes the
NodeInforecord.
Phase 3: Node startup
Ondecdn node run:
- Load keys and verify the registered
NodeInfomatches your local identity. - Fetch
(MIN_RATE, MAX_RATE)for your payment token from the governance contract. - Sync the
ContentBlacklist— read from genesis to current block. Subsequent polls happen on the configured interval. - Bootstrap the peer table by querying
StakingRegistry.getNodes()for known nodes. Fallback to a bundledpeers.jsonif the registry is unreachable.
Phase 4: Gossip subscription
- Join
cdn/global/v1. - Join
cdn/region/{cc}/v1for your region. - Publish your first
NodeAnnounce(rate, multiaddrs, region,popular_hashes = []). - Join
cdn/reputation/v1to receive gossip-propagated reputation reports.
Phase 5: Accepting paid delivery — seven acceptance criteria
Your node is operationally ready only when all of these hold:- Registered in
StakingRegistrywith stake ≥minStake. - Gossip subscribed — both global and regional topics.
- First
NodeAnnouncepublished within the last 60 seconds. - Blacklist sync lag < 5 minutes (
decdn_blacklist_sync_lag_seconds). - Rate within bounds — no
decdn_rate_bounds_clamp_events_totalincrements. - Watchtowers registered — 2–3 independent watchtowers (watchtower setup).
- Peer table populated — ≥ N peers (configurable threshold).
/health returns "ready" only when all seven hold.
NAT and multiaddr updates
iroh hole-punching handles most NAT scenarios automatically. When your public-facing address changes (cloud region, new home ISP lease), callStakingRegistry.updateMultiaddrs(newMultiaddrs) — gossip propagation carries the update to the rest of the mesh.
Re-onboarding after deregistration
If you deregister (voluntary) or are auto-ejected (prolonged offline + governance policy), re-registering requires:- Nonce increment.
NodeInfo.nonceis incremented to invalidate old slash signatures. firstRegisteredAtpreserved. Your tenure anchor does not reset — reputation cold-start bonuses do not apply twice to the same operator address.
Key rotation
bindNodeId() lets you rotate keys post-registration. Workflow:
- Generate a new keypair.
- Sign
(Ethereum address, new NodeId, nonce+1)with both the new NodeId and the Ethereum address. - Submit to
bindNodeId. - Contract updates the
NodeInfo.nodeIdfield atomically.
Deregistration
claimUnbondedStake. During unbonding:
- Node cannot accept new deliveries (automatically excluded from selection).
- Node is still slashable for evidence that predates deregistration.
MAX_EVIDENCE_AGE_USis strictly less than the unbonding period — evidence that could slash you must be submitted before you can withdraw.