| name | interfold-ciphernode |
|---|---|
| description | Set up, register, and operate an Interfold ciphernode (FOLD staking). Use when the user wants to run a ciphernode, stake FOLD, bond/buy tickets, debug an interfold node, or help someone else set one up. Contains hard-won gotchas the official docs lack. |
Official docs: https://docs.theinterfold.com/ciphernode-operators (running, registration, tickets) Dashboard (bond/register/tickets from a browser wallet): https://dashboard.theinterfold.com/#operator
- Linux box (8+ cores, 16G+ RAM), Ethereum RPC with both WebSocket and HTTP. The best RPC is your own local full node — the easy path is the BuidlGuidl client (https://client.buidlguidl.com — one command, runs reth + lighthouse). A remote RPC works too if the user prefers; that's the human's call. (Note the split-port gotcha in #2 below applies to local reth.)
- UDP 9091 reachable from the internet (port forward through every NAT layer)
- Operator hot wallet (generate fresh ON the box) + small gas ETH
- Bond owner wallet (cold/Safe): 32,000 FOLD + 1,000 sUSDS per ticket + gas
- Mainnet tokens (verify on-chain, don't trust UI copy): FOLD bond token
0xe172e9b6cfbeeb5593bdce3f077356fdb33af904; ticket token underlying is sUSDS0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD; fee token is USDS0xdC035D45d973E3EC169d2276DDab16f1e407384F. Ignore the dashboard's "testnet deployment" faucet banner on mainnet — real FOLD is what the bonding registry pulls.
curl -fsSL https://raw.githubusercontent.com/theinterfold/interfold/main/install | bash
interfoldup install # installs to ~/.local/bin/interfoldinterfold ciphernode setupandpassword deletedemand a real TTY even with-p/-kflags ("IO error: not a terminal"). Headless: skip the wizard — write~/.config/interfold/interfold.config.yamlby hand (docs have the full YAML with contract addresses), theninterfold password set -p ...andinterfold wallet set --private-key ...work fine non-interactively.- One
rpc_url, two protocols: interfold opens a WebSocket torpc_urlAND makes plain HTTP POSTs to the same URL. Nodes that split WS/HTTP across ports (reth: 8546 ws-only, 8545 http-only) 403 one of them → node dies withHTTP error 403 with empty body. Fix: tiny localhost mux that routes Upgrade requests to the ws port and POSTs to the http port; pointrpc_urlat the mux. (Node.js ~40 lines: http server +upgradehandler piping to net.connect.) - Startup timeout crash loop: every start re-scans ALL chain history from the
earliest deploy_block (no checkpoint, ~500+ chunks, 30-45 min) and the default
startup_timeout_secs: 1800kills it at minute 30 → infinite restart loop that looks alive (peers connect early!). Setstartup_timeout_secs: 7200undernode:. Healthy startup ends with "Sync finished." + "LAUNCHING CIPHERNODE". Checksystemctl show <unit> -p NRestarts— a climbing count means the loop. interfold nodes up --detachsilently starts nothing with a singlenode:config. Useinterfold start(foreground) under systemd/nohup instead.- CLI vs running node: on-chain commands (
ciphernode set-bond-owner, etc.) need exclusive DB access — stop the service, run the command, restart. autopassword: truegenerates its own keyfile at~/.config/interfold/.interfold/config/_default/key— THAT file is the real secret; back it up (not whatever password you thought you set).interfold config checkmay say "mainnet: not in the published manifest, skipping" — manifest lags; docs' addresses are authoritative. (Fixed in ≥0.11.0: manifest now covers mainnet and reports "up to date".)
Releases ship fast (https://github.com/theinterfold/interfold/releases) — check often;
version-skewed nodes can't peer (see below). Official path is interfoldup update, but
the real flow has landmines; use a script like update-interfold.sh (in this gist) that
does: version check → back up old binary → update → interfold config check → restart.
interfoldupcan't overwrite a running binary ("Text file busy").rmthe binary first — the running process keeps its inode — then update, then restart.- No sudo needed with a
Restart=alwayssystemd unit: swap the binary, thenpkill -x interfold; systemd relaunches on the new binary. - Every restart = full rescan (~40 min outage) — plan the window (gotcha 3).
- Run
interfold node validate(new in ≥0.10) BEFORE upgrading — it's the official pre-upgrade health check. It needs the DB lock: with a crash-looping/running unit, park the binary (mvit aside so systemd's restart can't exec) to free the lock. - 0.9.0 → 0.11.0 migration landmine: pre-0.10 event logs contain legacy events
written to the wrong aggregate store (tagged chain 11155111 = Sepolia). 0.11.0
quarantines them, then dies with
EventStore replay sequence gap→ crash loop (node validateshows FAIL on aggregate 0). Fix (safe ifdata/has nojobs/key shares yet, i.e. the node has never served an E3): tar-backup the data dir,mv data/_default data/_default.pre-0.11, restart → node rebuilds from full rescan. - The wallet key lives in the data DB, not the config dir. After wiping data the
node dies with
No private key found in repository— re-runinterfold wallet set --private-key ...from your key backup (needs exclusive DB access: park the binary again while you run it). - Startup buffer crash — the #1 post-update landmine (0.11.0+). During the ~40 min
rescan the node buffers all live p2p gossip (fail-closed: it exits rather than drop a
message). Default
max_buffered_net_events: 1024dies in ~1 min on current mainnet — gossip runs ~20 events/sec with ~20 peers (~1 heartbeat/peer/sec). Symptom:network startup buffer limit exceeded ... events=N/N→ exit 1 → systemd crash loop where every attempt restarts the scan from chunk 1 and dies at the same wall-clock point. Size it as (observed events/sec) × (full-sync seconds) × 2; we run:Memory is a non-issue (events ~220 B; the separate 256 MB byte cap is the backstop). Thenode: max_buffered_net_events: 131072
Event broadcast channel backpressure: 1024/1000WARN during sync is a different internal queue — noisy, not fatal. - v0.11.0 isolated p2p networks per deployment: mismatched peers are dropped with "Rejected an incompatible Interfold peer". From an OLD node this looks like one peer connect/disconnect-flapping several times per second — that's your cue to upgrade, not a network problem.
- Fund operator wallet with gas ETH.
- From the node box:
interfold ciphernode set-bond-owner --owner 0xCOLD_WALLET(sent BY the operator key — the dashboard cannot do this step). - From the bond owner wallet on the dashboard: bond 32,000 FOLD → register → buy ticket(s) (1,000 sUSDS each; sUSDS keeps earning Sky yield while staked).
- Verify:
interfold ciphernode status→ Registered: true, Active: true.
QUIC version-negotiation probe — any live QUIC endpoint must reply (~31 bytes); run it from an EXTERNAL host against the public IP:9091/udp:
import socket, os
pkt = bytearray(1200); pkt[0] = 0xc0; pkt[1:5] = bytes.fromhex("fafafafa")
pkt[5] = 8; pkt[6:14] = os.urandom(8); pkt[14] = 8; pkt[15:23] = os.urandom(8)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM); s.settimeout(6)
s.sendto(bytes(pkt), ("PUBLIC_IP", 9091))
print(s.recvfrom(2048)) # reply = reachable; timeout = a hop is brokenValidate the probe against a known-good QUIC server (any Google IP :443) first.
If the Interfold bootstrap itself seems down, probe _dnsaddr.bootstrap.interfold.network's
resolved IP:port the same way from multiple networks before blaming local config.
- systemd unit:
ExecStart=<home>/.local/bin/interfold start -v,Restart=always,TimeoutStopSec=300, User=. Watch:journalctl -u interfold -f -o cat. - Backups (slashing risk if lost):
~/.config/interfold/(config + keyfile) and~/.config/interfold/.interfold/data/(db +jobs/encrypted key shares). - Don't publish the libp2p Peer ID alongside your identity — peers can map it to the node's IP for targeted DoS during committee rounds.
- Every restart = full re-scan (~40 min outage). Restart rarely; batch config changes.
One node + stacked tickets beats many nodes: the 32k FOLD bond is per-node dead weight, sortition weight comes from tickets, and one node serves multiple committees concurrently (CPU-bound at high ticket counts — that's when a second node makes sense).