seed-nodes: igneum-seed-1 live and synced; relay path from the Mac; prices in the account's currency (USD)

igneum-seed-1 (Hetzner cx23, fsn1, 188.245.5.161:26611): built on the VM in 1,530 s, synced to the live devnet
(12,204 blocks, same sink as the live node) through a non-mining relay igneumd on the Mac (the live node's addPeer
RPC is refused in safe mode); the live node and the Windows PC learned the seed's address by peer exchange and dialled
it. seeds.txt written. Hetzner prices corrected to USD (pricing API currency) in the plans, READMEs and scripts;
current-generation types per location (cx23 EU, cpx22 sin, cpx21 US) in the cloud-devnet config.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-03 22:27:52 +00:00
parent 3baf399615
commit 74e7c2bdf5
10 changed files with 87 additions and 43 deletions

View file

@ -22,9 +22,9 @@ What it proves:
What it does not prove: nothing about GPU hash rates (CPU miners), nothing at 1,000 miners, one evening of data.
Cost (Hetzner API prices of 3 Oct 2026, net): EUR 0.76 per hour for the 20 nodes at 4 per location (EUR 476 per
month if left running), or EUR 0.47 per hour EU-heavy; the builder VM about EUR 0.03 per hour for one hour. An evening
of six hours: about EUR 5. DigitalOcean variant: USD 0.71 per hour. Time to first block after "yes": about 25 minutes
Cost (Hetzner API prices of 3 Oct 2026, net): USD 0.76 per hour for the 20 nodes at 4 per location (USD 476 per
month if left running), or USD 0.47 per hour EU-heavy; the builder VM USD 0.0296 per hour for one hour. An evening
of six hours: about USD 5. DigitalOcean variant: USD 0.71 per hour. Time to first block after "yes": about 25 minutes
(VM creation, a 10 to 25 minute build, install).
Command sequence: `infra/cloud-devnet/README.md`, section "The command sequence". In short: `create.sh`,
@ -62,9 +62,9 @@ template.
## The go/no-go question for the project lead
Spend about EUR 5 and USD 2 to 4 tonight-to-tomorrow for (a) the first reorg-depth, propagation and partition numbers
Spend about USD 5 (Hetzner, billed in USD) and USD 2 to 4 (RunPod) tonight-to-tomorrow for (a) the first reorg-depth, propagation and partition numbers
from a real multi-region network, which gate 3 needs and the simulator cannot give, and (b) the per-card hash rates
and the three ASIC-resistance measurements (L2 cliff, inline ratio, recompile time) on 3060, 3090 and 4090, closing
the measurement half of ledger items M1, M11 and M16 for those cards? If yes: `cd infra/cloud-devnet && ./create.sh`
and `cd infra/gpu-bench && ./make-bundle.sh` are the two starting commands. If no: the scripts keep, nothing bills,
and the seed node stays at EUR 6.49 per month.
and the seed node stays at USD 6.49 per month.

View file

@ -9,14 +9,26 @@
| Name | igneum-seed-1 |
| Address | `188.245.5.161:26611` (Hetzner primary IPv4, auto-delete off, so a rebuilt server keeps it) |
| Provider, location, type | Hetzner Cloud, Falkenstein (fsn1), cx23 (2 Intel vCPU, 4 GB, 40 GB), Debian 12 |
| Cost | EUR 6.49 per month net, EUR 7.79 gross, EUR 0.0104 per hour, 20 TB traffic included (Hetzner API, 3 Oct 2026); plus the primary IPv4, about EUR 0.50 per month (approximate) |
| Cost | USD 6.49 per month net, USD 7.79 gross, USD 0.0104 per hour, 20 TB traffic included (Hetzner API, 3 Oct 2026); plus the primary IPv4, USD 0.60 per month net, 0.72 gross (pricing API). Total about USD 7.09 net, USD 8.51 gross per month. The account bills in USD: the pricing API reports `currency: USD`, VAT 20% |
| Firewall | inbound tcp 26611 from anywhere, tcp 22 from anywhere (the project lead's instruction; `SSH_SOURCE=me` narrows it to this Mac's IP), icmp; RPC bound to 127.0.0.1 only |
| Network | the shared devnet (`--devnet`, no suffix), built from `vendor/igneum-node` HEAD d62708a8 plus the uncommitted finality v2 work and `igneum-pow` HEAD, with `--features igneum-pow` |
| Role | p2p open, no mining, address manager on (serves `RequestAddresses`), `--nodnsseed`, UPnP off, `--externalip` set |
| How the Mac reaches it | the Mac's live node sits behind NAT (192.168.68.64), so the seed cannot dial in; the Mac dials out: `infra/seed-nodes/addpeer-from-mac.sh 188.245.5.161` (the `addPeer` RPC through grpcurl, permanent, no restart). If the live node is ever restarted by hand: `--addpeer=188.245.5.161:26611` |
| How the Mac reaches it | the Mac's live node sits behind NAT (192.168.68.64), so the seed cannot dial in; the Mac dials out. The `addPeer` RPC on the live node is refused ("Method unavailable in safe mode. Run the node with --unsaferpc"), so the working path is a relay: `infra/seed-nodes/addpeer-from-mac.sh relay start`, a second non-mining `igneumd` on the Mac (appdir /tmp/igneum-seed-relay, RPC 127.0.0.1:26680, wRPC 28680, p2p 127.0.0.1:26681) with `--addpeer=192.168.68.64:26611 --addpeer=188.245.5.161:26611`; it syncs from the live node and the seed syncs from it. The live node is untouched. When the live node is next restarted by hand, add `--addpeer=188.245.5.161:26611` to its flags and the relay is no longer needed |
`infra/seed-nodes/seeds.txt` holds exactly `188.245.5.161:26611`.
Verified 3 Oct 2026, 22:19 to 22:26 UTC: build on the VM 1,530 s (25.5 min, 2 vCPU, 2 jobs, 6 GB swap unused);
`igneumd/2.1.0` started with the finality v2 parameters, "External address is publicly routable 188.245.5.161:26611";
the relay on the Mac connected to it at once (protocol 12) and to the live node (protocol 11); the seed completed IBD
from the relay and reported `isSynced: true` at 22:25:39 UTC with 12,204 blocks and sink `a0a776bb129c...`, the same
block count and sink the live node reported in the same second. Peer exchange: without any configuration on their
side, the live node (`/kaspad:2.1.0/`, protocol 11) and the Windows PC's node (192.168.68.67, `/igneumd:2.1.0/`,
protocol 11) learned the seed's address from the relay and dialled it themselves; the live node's `getConnectedPeerInfo`
lists `188.245.5.161:26611` as an outbound peer, and the seed shows three inbound peers from the Mac's public IP.
`health.sh`: `OK igneum-seed-1 188.245.5.161 p2p=open unit=active rpc=yes synced=True blocks=12204 headers=12204 peers=3`.
The seed's own known-address table is empty because all three peers are behind NAT with no routable advertised address;
the first public node that connects will populate it.
## How the seed list reaches clients
1. Baked into the node. `vendor/igneum-node/consensus/core/src/config/params.rs` holds the per-network seed list as
@ -47,13 +59,13 @@ Three to five seeds across two providers and three regions. Proposed:
| Seed | Provider | Location | Type | Per month net |
|---|---|---|---|---|
| igneum-seed-1 | Hetzner | Falkenstein (EU) | cx23 | EUR 6.49 (live) |
| igneum-seed-2 | Hetzner | Ashburn (US east) | cpx11 (2 GB) or cpx21 (4 GB) | EUR 20.49 or 37.49 |
| igneum-seed-1 | Hetzner | Falkenstein (EU) | cx23 | USD 6.49 (live) |
| igneum-seed-2 | Hetzner | Ashburn (US east) | cpx11 (2 GB) or cpx21 (4 GB) | USD 20.49 or 37.49 |
| igneum-seed-3 | DigitalOcean | Singapore (sgp1) | s-2vcpu-4gb | USD 24 (DO pricing page) |
| igneum-seed-4 (optional) | DigitalOcean | New York or Frankfurt | s-2vcpu-4gb | USD 24 |
| igneum-seed-5 (optional) | Hetzner | Helsinki | cx23 | EUR 6.49 |
| igneum-seed-5 (optional) | Hetzner | Helsinki | cx23 | USD 6.49 |
Three seeds: about EUR 50 per month; five: about EUR 80 (approximate, mixed currencies). The US seed is the expensive
Three seeds: about USD 50 per month; five: about USD 80 (approximate, mixed currencies). The US seed is the expensive
one because Hetzner's current cx line is EU-only. Every seed is created with `create-seed.sh` (the DigitalOcean
variant reserves an IP in the same way) and provisioned with `provision-seed.sh`, which adds the seeds already in
`seeds.txt` as `--addpeer` entries so the seeds form a full mesh among themselves. `health.sh` checks them all.
@ -63,7 +75,7 @@ variant reserves an IP in the same way) and provisioned with `provision-seed.sh`
1. Add before removing: create and provision the replacement, run `health.sh` until it is synced and has peers.
2. Bake the new list (`params.rs`) and release packages with it; keep the old address in the list for one release so
clients on the previous build still bootstrap.
3. Keep the old IP alive until the release after that (a Hetzner primary IP or a DO reserved IP costs under EUR 1 per
3. Keep the old IP alive until the release after that (a Hetzner primary IP or a DO reserved IP costs under USD 1 per
month unattached, approximate), then delete the server and the IP, and remove the entry from `seeds.txt` and
`seeds.tsv`.
4. A compromised seed is the one case to remove first: delete the server, release the IP, bake and release the same

View file

@ -38,25 +38,25 @@ over `/live` on the site (stop the Mac's observer first). `site/api/live.mjs` re
## Cost
Hetzner API prices for this project on 3 Oct 2026, net EUR per month, hourly billing (the API's `price_hourly`):
Hetzner API prices for this project on 3 Oct 2026, net USD per month, hourly billing (the API's `price_hourly`):
| Location | Type | vCPU | RAM | Per month | Per hour | Note |
|---|---|---|---|---|---|---|
| fsn1, nbg1, hel1 | cx23 | 2 Intel | 4 GB | 6.49 | 0.0104 | the cheapest x86 type the project can create |
| sin | cpx22 | 2 AMD | 4 GB | 30.99 | 0.0497 | cx not sold outside the EU |
| ash, hil | cpx21 | 3 AMD | 4 GB | 37.49 | 0.0601 | the old cpx line, only still sold in the US; cpx11 (2 GB) is 20.49 |
| builder, any EU | cx43 | 8 Intel | 16 GB | about 20 | about 0.03 | deleted after the build (approximate: cx33 is 9.99, cx43 not priced in the check) |
| builder, any EU | cx43 | 8 Intel | 16 GB | 18.49 | 0.0296 | deleted after the build |
Plus about EUR 0.50 per month per primary IPv4 (approximate, Hetzner list price). VAT is added for a private
Plus USD 0.60 per month net per primary IPv4 (pricing API). The account bills in USD (the pricing API reports currency USD, VAT 20%); VAT is added for a private
customer; the API's gross column is net x 1.2.
| Mix | Nodes | Per month net | Per hour | An evening (6 h) |
|---|---|---|---|---|
| 4 per location (default `REGIONS`) | 8 EU, 4 sin, 4 ash, 4 hil | EUR 476 | EUR 0.76 | about EUR 5 |
| EU-heavy (`REGIONS=hel1,fsn1,nbg1,hel1,fsn1,nbg1,hel1,ash,hil,sin`) | 14 EU, 2 sin, 2 ash, 2 hil | EUR 303 | EUR 0.47 | about EUR 3 |
| 4 per location (default `REGIONS`) | 8 EU, 4 sin, 4 ash, 4 hil | USD 476 | USD 0.76 | about USD 5 |
| EU-heavy (`REGIONS=hel1,fsn1,nbg1,hel1,fsn1,nbg1,hel1,ash,hil,sin`) | 14 EU, 2 sin, 2 ash, 2 hil | USD 303 | USD 0.47 | about USD 3 |
| DigitalOcean `s-2vcpu-4gb` in any region (DO pricing page, USD 24/mo, 0.036/h) | 20 | USD 480 | USD 0.71 | about USD 4.50 |
The run is meant to last one evening, so the hourly column is the one that matters: well under EUR 10 all in, with
The run is meant to last one evening, so the hourly column is the one that matters: well under USD 10 all in, with
the builder. Leaving the network up costs the monthly column.
## What each script does

View file

@ -13,13 +13,13 @@ DO_REGIONS="${DO_REGIONS:-lon1,fra1,nyc3,sfo3,sgp1}"
# Instance size per location. The node holds up to four 256 MiB lottery caches (M15 cap), rocksdb and the CPU
# miner's own 256 MiB cache, so 2 GB plans are too small. What this Hetzner project can create (API, 3 Oct 2026, net
# EUR per month): cx23 (2 Intel vCPU, 4 GB) 6.49 in fsn1/nbg1/hel1 only; cpx22 (2 AMD vCPU, 4 GB) 22.99 EU, 30.99 sin;
# USD per month): cx23 (2 Intel vCPU, 4 GB) 6.49 in fsn1/nbg1/hel1 only; cpx22 (2 AMD vCPU, 4 GB) 22.99 EU, 30.99 sin;
# cpx21 (3 vCPU, 4 GB) 37.49 in ash/hil only (the old cpx line is deprecated in the EU and Singapore since Dec 2025);
# cpx11 (2 GB) 20.49 in ash/hil. So: cx23 in Europe, cpx22 in Singapore, cpx21 in the US. SERVER_TYPE overrides all.
TYPE_BY_LOCATION="${TYPE_BY_LOCATION:-fsn1=cx23,nbg1=cx23,hel1=cx23,sin=cpx22,ash=cpx21,hil=cpx21}"
SERVER_TYPE="${SERVER_TYPE:-}" # empty = pick from TYPE_BY_LOCATION
DO_SIZE="${DO_SIZE:-s-2vcpu-4gb}"
BUILDER_TYPE="${BUILDER_TYPE:-cx43}" # 8 Intel vCPU, 16 GB, EUR 0.03/h approximate, for the one-off node build (deleted afterwards)
BUILDER_TYPE="${BUILDER_TYPE:-cx43}" # 8 Intel vCPU, 16 GB, USD 0.0296/h, for the one-off node build (deleted afterwards)
DO_BUILDER_SIZE="${DO_BUILDER_SIZE:-c-8}"
IMAGE="${IMAGE:-debian-12}"
DO_IMAGE="${DO_IMAGE:-debian-12-x64}"

View file

@ -40,7 +40,7 @@ hetzner_prepare() {
}
hetzner_price() {
log "live price list for $1 (per location, EUR, excl. VAT):"
log "live price list for $1 (per location, USD, excl. VAT):"
hcloud server-type describe "$1" 2>/dev/null | sed -n '/Pricings/,$p' | head -40 || true
}
@ -111,9 +111,9 @@ done
if [ "$PROVIDER" = digitalocean ]; then do_price "$TYPE"; else
for t in $(for i in $(seq 1 "$N"); do type_for_location "$(region_of "$i")"; done | sort -u); do hetzner_price "$t"; done
fi
log "cost at the Hetzner API prices of 3 Oct 2026 (net EUR per month: cx23 6.49 EU, cpx22 30.99 sin, cpx21 37.49 ash/hil):"
log " 20 nodes as 4 per location = 8 x 6.49 + 4 x 30.99 + 8 x 37.49 = EUR 476/mo, EUR 0.76/h; an evening of 6 h about EUR 5 plus the builder (about EUR 0.03/h)"
log " EU-heavy alternative REGIONS=hel1,fsn1,nbg1,hel1,fsn1,nbg1,hel1,ash,hil,sin (14 EU, 2 each elsewhere): about EUR 303/mo, EUR 0.47/h"
log "cost at the Hetzner API prices of 3 Oct 2026 (net USD per month: cx23 6.49 EU, cpx22 30.99 sin, cpx21 37.49 ash/hil):"
log " 20 nodes as 4 per location = 8 x 6.49 + 4 x 30.99 + 8 x 37.49 = USD 476/mo, USD 0.76/h; an evening of 6 h about USD 5 plus the builder (about USD 0.03/h)"
log " EU-heavy alternative REGIONS=hel1,fsn1,nbg1,hel1,fsn1,nbg1,hel1,ash,hil,sin (14 EU, 2 each elsewhere): about USD 303/mo, USD 0.47/h"
log " DigitalOcean s-2vcpu-4gb: USD 24 per node per month (USD 0.036/h, DO pricing page): 20 nodes USD 480/mo, USD 0.71/h"
confirm "create $N servers now (hourly billing starts)?"

View file

@ -277,7 +277,7 @@ def bench_entry(d, nodes_file):
ver = " ".join(open(os.path.join(d, "version.txt")).read().split()) if os.path.exists(os.path.join(d, "version.txt")) else "<igneumd version>"
regions = ", ".join("%s x %d" % (r, sum(1 for n in nodes if n["region"] == r)) for r in sorted({n["region"] for n in nodes}))
lines = [f"## {date_txt}, cloud devnet: {len(nodes)} igneumd nodes across regions, CPU trickle miners, latency, partition and hash-rate steps (consensus-engineer)", "",
f"Machines: {len(nodes)} Hetzner Cloud VMs ({regions}; type cpx21 unless noted), Debian 12, chrony. Node: {ver}, built on a builder VM from the source tarball in results/{day}/src.stamp. Network: igneum-devnet-<suffix>, genesis bits <bits>, {len(nodes)} one-thread CPU miners (igneum-miner --engine igneum-pow), one BLS vote key per node, sparse --addpeer mesh (about 4 peers each).", "",
f"Machines: {len(nodes)} Hetzner Cloud VMs ({regions}; cx23 in the EU, cpx22 in Singapore, cpx21 in the US unless noted), Debian 12, chrony. Node: {ver}, built on a builder VM from the source tarball in results/{day}/src.stamp. Network: igneum-devnet-<suffix>, genesis bits <bits>, {len(nodes)} one-thread CPU miners (igneum-miner --engine igneum-pow), one BLS vote key per node, sparse --addpeer mesh (about 4 peers each).", "",
"Inter-region RTT (ms, median of pair averages): <paste results/" + day + "/latency/rtt-by-region.md>", "",
"Block propagation (arrival minus first arrival anywhere): p50 <n> ms, p90 <n> ms, p99 <n> ms, max <n> ms; per region <paste the region table from propagation.md>.", "",
"Partition <region>, <minutes> min: minority reorg depth max <n> (getVirtualChainFromBlock from the minority sink at heal), majority <n>; converged <n> s after heal; conflicting locks: <none | list>.", "",

View file

@ -5,7 +5,7 @@ serves peer exchange (the address manager stays on; `--connect` is never used).
per seed and is the file the consensus engineer bakes into the network parameters and every package reads as
`SEED_PEERS`. The plan, the client path and the rotation procedure are in `docs/plans/seed-nodes.md`.
The first seed, `igneum-seed-1`, was created on 3 Oct 2026 (Hetzner cx23, Falkenstein, EUR 6.49 per month net plus
The first seed, `igneum-seed-1`, was created on 3 Oct 2026 (Hetzner cx23, Falkenstein, USD 6.49 per month net plus
the IPv4). It runs the shared devnet (`--devnet`, no suffix).
```
@ -13,7 +13,8 @@ cd infra/seed-nodes
./create-seed.sh # one VM, persistent IPv4, firewall 22 + 26611 + icmp, appends seeds.tsv, rewrites seeds.txt
./provision-seed.sh igneum-seed-1 # source tarball -> build on the VM (about an hour on 2 vCPU) -> unit igneumd, started
./health.sh # one line per seed: p2p port, unit, RPC, synced, blocks, peers, known addresses
./addpeer-from-mac.sh 188.245.5.161 # the Mac's live node (NAT, gRPC only) dials the seed: addPeer over grpcurl, no restart
./addpeer-from-mac.sh relay start # a non-mining relay igneumd on the Mac peers with the live node (LAN) and the seed; the
# live node runs in safe RPC mode, so addPeer over grpcurl is refused (see the script)
SEED_NAME=igneum-seed-2 SEED_LOCATION=ash SEED_TYPE=cpx11 ./create-seed.sh # the next seed; provision adds the first as --addpeer
```

View file

@ -1,22 +1,53 @@
#!/usr/bin/env bash
# Make the Mac's live devnet node dial a seed (the Mac sits behind NAT on 192.168.68.64, so the seed cannot dial in).
# The live node (./target/release/kaspad --devnet ... --rpclisten=0.0.0.0:26610) serves gRPC only, no wRPC JSON, so
# this goes through grpcurl against the fork's own proto files. addPeer is an RPC call: the node is not restarted and
# nothing on the chain changes. isPermanent=true makes the node retry the seed after a disconnect (backoff up to 8 min).
# ./addpeer-from-mac.sh <ip[:port]> add (port defaults to 26611)
# ./addpeer-from-mac.sh --peers list the live node's connected peers
# ./addpeer-from-mac.sh --dag the live node's getBlockDagInfo (to compare block counts with the seed)
# If the live node is ever restarted by hand, the permanent alternative is the flag: --addpeer=<ip>:26611
# Connect the Mac's live devnet to a seed. The Mac sits behind NAT (192.168.68.64), so the seed cannot dial in; the
# Mac side has to dial out. Two ways:
#
# ./addpeer-from-mac.sh relay start [ip] RELAY (the way that works, 3 Oct 2026): a second, non-mining igneumd on
# this Mac (appdir /tmp/igneum-seed-relay, RPC 127.0.0.1:26680, wRPC JSON
# 28680, p2p 127.0.0.1:26681) with --addpeer to the live node's LAN address
# 192.168.68.64:26611 and to the seed. It syncs from the live node and the
# seed syncs from it; from then on every block reaches the seed through the
# relay. The live node is not touched.
# ./addpeer-from-mac.sh relay stop|status
# ./addpeer-from-mac.sh <ip[:port]> ADDPEER RPC on the live node over grpcurl (gRPC only, no wRPC JSON on it).
# The live node runs in safe mode and answers "Method unavailable in safe
# mode. Run the node with --unsaferpc"; so this only works after the live
# node is restarted with --unsaferpc, and then the simpler restart flag is
# --addpeer=<ip>:26611 anyway. Kept for a node started with --unsaferpc.
# ./addpeer-from-mac.sh --peers | --dag the live node's connected peers / getBlockDagInfo (read-only)
#
# Why not --addpeer=127.0.0.1:26611 for the relay: the live node's p2p identity is then seen twice (loopback and LAN)
# and the second handshake fails with PeerAlreadyExists; use the LAN address.
. "$(dirname "$0")/lib.sh"
need grpcurl "brew install grpcurl"
RPC="${MAC_RPC:-127.0.0.1:26610}"
LIVE_P2P="${LIVE_P2P:-192.168.68.64:26611}"
PROTO="$REPO/vendor/igneum-node/rpc/grpc/core/proto"
call() { grpcurl -plaintext -max-time 15 -import-path "$PROTO" -proto messages.proto -d "$1" "$RPC" protowire.RPC/MessageStream; }
RELAY_BIN="${RELAY_BIN:-$REPO/vendor/igneum-node/target-finality/release/igneumd}"
RELAY_DIR=/tmp/igneum-seed-relay
call() { need grpcurl "brew install grpcurl"; grpcurl -plaintext -max-time 15 -import-path "$PROTO" -proto messages.proto -d "$1" "$RPC" protowire.RPC/MessageStream; }
case "${1:-}" in
"") die "usage: addpeer-from-mac.sh <ip[:port]> | --peers | --dag" ;;
"") die "usage: addpeer-from-mac.sh relay start|stop|status [ip] | <ip[:port]> | --peers | --dag" ;;
--peers) call '{"getConnectedPeerInfoRequest":{}}' ;;
--dag) call '{"getBlockDagInfoRequest":{}}' ;;
relay)
case "${2:-}" in
start)
ip="${3:-$(head -1 "$SEEDS_TXT" | cut -d: -f1)}"; [ -n "$ip" ] || die "no seed ip (seeds.txt empty)"
[ -x "$RELAY_BIN" ] || die "no $RELAY_BIN (RELAY_BIN=... a finality v2 igneumd built on this Mac)"
pgrep -f "appdir=$RELAY_DIR" >/dev/null && die "relay already running (relay status)"
mkdir -p "$RELAY_DIR"
nohup "$RELAY_BIN" --devnet --appdir="$RELAY_DIR" --rpclisten=127.0.0.1:26680 --rpclisten-json=127.0.0.1:28680 \
--listen=127.0.0.1:26681 --addpeer="$LIVE_P2P" --addpeer="$ip:$P2P_PORT" --nodnsseed --disable-upnp --nologfiles --yes \
--loglevel=info > "$RELAY_DIR/relay.log" 2>&1 &
log "relay started (pid $!), log $RELAY_DIR/relay.log; peers: live node $LIVE_P2P and seed $ip:$P2P_PORT" ;;
stop) pkill -f "appdir=$RELAY_DIR" && log "relay stopped" || log "no relay running" ;;
status)
pgrep -fl "appdir=$RELAY_DIR" >/dev/null && log "relay running" || log "relay not running"
IGNEUM_RPC=ws://127.0.0.1:28680 python3 "$REPO/infra/cloud-devnet/node/wrpc.py" sample 2>/dev/null || true
IGNEUM_RPC=ws://127.0.0.1:28680 python3 "$REPO/infra/cloud-devnet/node/wrpc.py" call getConnectedPeerInfo 2>/dev/null | cut -c1-300 || true ;;
*) die "usage: addpeer-from-mac.sh relay start|stop|status [ip]" ;;
esac ;;
*) addr="$1"; case "$addr" in *:*) ;; *) addr="$addr:$P2P_PORT" ;; esac
log "addPeer $addr on the live node at $RPC"
log "addPeer $addr on the live node at $RPC (needs --unsaferpc on that node)"
call "{\"addPeerRequest\":{\"address\":\"$addr\",\"isPermanent\":true}}" ;;
esac

View file

@ -4,10 +4,10 @@
PROVIDER="${PROVIDER:-hetzner}" # hetzner (hcloud) or digitalocean (doctl)
SEED_NAME="${SEED_NAME:-igneum-seed-1}"
SEED_TYPE="${SEED_TYPE:-cx23}" # 2 shared Intel vCPU, 4 GB, 40 GB: EUR 6.49/mo net, EUR 0.0104/h, in fsn1, nbg1, hel1
SEED_TYPE="${SEED_TYPE:-cx23}" # 2 shared Intel vCPU, 4 GB, 40 GB: USD 6.49/mo net, USD 0.0104/h, in fsn1, nbg1, hel1
# (Hetzner API, 3 Oct 2026). It is the cheapest x86 type this project can create in the
# EU: the old cpx11/cpx21 line is deprecated there since Dec 2025 (only ash and hil keep
# it, at EUR 20.49 and 37.49/mo), cpx12 (1 vCPU, 2 GB) costs 13.49. 4 GB is needed: the
# it, at USD 20.49 and 37.49/mo), cpx12 (1 vCPU, 2 GB) costs 13.49. 4 GB is needed: the
# node keeps up to four 256 MiB lottery caches (M15 cap) beside rocksdb, and the on-VM
# build wants 4 GB plus swap. US seeds: cpx11 (2 GB) or cpx21; Singapore: cpx22 (30.99).
SEED_LOCATION="${SEED_LOCATION:-fsn1}" # fsn1 Falkenstein, nbg1 Nuremberg, hel1, ash, hil, sin

View file

@ -51,9 +51,9 @@ import json, sys
j = json.load(sys.stdin); loc = sys.argv[1]
for p in j["prices"]:
if p["location"] == loc:
print(" %s in %s: EUR %.2f per month net (%.2f gross), EUR %.4f per hour net, %d TB traffic included (Hetzner API)" % (
print(" %s in %s: USD %.2f per month net (%.2f gross), USD %.4f per hour net, %d TB traffic included (Hetzner API)" % (
j["name"], loc, float(p["price_monthly"]["net"]), float(p["price_monthly"]["gross"]), float(p["price_hourly"]["net"]), int(p.get("included_traffic", 0)) // (1 << 40)))' "$SEED_LOCATION"
log " plus the primary IPv4: about EUR 0.50 per month (approximate, Hetzner list price)"
log " plus the primary IPv4: USD 0.60 per month net, 0.72 gross (Hetzner pricing API)"
[ "${YES:-0}" = 1 ] || { printf 'create it now (billing starts) [type yes]: '; read -r a; [ "$a" = yes ] || die "not confirmed"; }
if hcloud server describe "$SEED_NAME" >/dev/null 2>&1; then log "$SEED_NAME exists, reusing it"; else
hcloud server create --name "$SEED_NAME" --type "$SEED_TYPE" --image "$IMAGE" --location "$SEED_LOCATION" \