Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions ansible/roles/decdn_node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,25 +428,43 @@ See `roles/decdn_node/defaults/main.yml` for the full knob list, defaults and un

The role stops at ADR 019 Phase 1 (host prep) and Phase 3 (startup). Phase 2 — fund,
bond, register — is the operator's, but it is **no longer a set of raw contract
calls**: upstream ships a guided CLI. Every one of these takes `--dry-run`.
calls**: upstream ships a guided CLI. Every one of these takes `--dry-run`. They need
`--rpc-url` (see "The RPC URL is the exception" below), so on the node run them
through the `decdn_chain` helper from
[`docs/lifecycle.md` § Running on-chain commands](../../../docs/lifecycle.md#running-on-chain-commands),
which runs as `decdn` with `/etc/decdn/decdn.env` and adds `--config`, `--rpc-url` and
`--keystore-password-file`.

```bash
# Guided path: pre-flight checks (clock skew, gas, balances), key generation,
# bond and registration, ending in a readiness summary. Thin orchestration over
# `key-gen` / `node bond` / `node register` — it submits no transaction they do
# not. (The exit path below is NOT part of setup.)
decdn setup --mbps 100 --region US \
decdn_chain setup --mbps 100 --region US \
--multiaddr /ip4/<public-ip>/udp/4433/quic-v1 --yes --accept-terms

# Or drive the primitives directly:
decdn node bond --mbps 100 # CapacityBond.bond + declareMbps (idempotent:
# tops up only the shortfall, so a re-run after a
# partial failure converges rather than over-bonding)
decdn node register --region US \
decdn_chain node bond --mbps 100 # CapacityBond.bond + declareMbps (idempotent:
# tops up only the shortfall, so a re-run after a
# partial failure converges rather than over-bonding)
decdn_chain node register --region US \
--multiaddr /ip4/<public-ip>/udp/4433/quic-v1 \
--accept-terms # CapacityBond.registerNode — builds the EIP-712
# binding + ed25519 ownership signatures locally.
# --region is REQUIRED (no default).
--accept-terms # CapacityBond.registerNode — builds the EIP-712
# binding + ed25519 ownership signatures locally.
# --region is REQUIRED (no default).
```

On a dual-stack host, add `--multiaddr /ip6/<public-ipv6>/udp/4433/quic-v1` as well.
Builds since decdn/decdn#2144 (`869141e9`) bind QUIC on both `0.0.0.0:4433` and
`[::]:4433`; check `ss -ulpn` shows `[::]:4433` first. Older builds are IPv4-only on
that port, so register `/ip4/` only there.
To get the address to fund, run `whoami` as `decdn` (also in that section of
`docs/lifecycle.md`). `keystore.json` has no plaintext address field.

```bash
sudo systemd-run --pty --wait --collect -p User=decdn \
/usr/local/bin/decdn --config /etc/decdn/node.toml whoami \
--keystore-password-file /etc/decdn/keystore.password
```

Exiting is the reverse, in order: `decdn node deregister` (leaves the active set
Expand All @@ -469,7 +487,10 @@ renders (`--config /etc/decdn/node.toml`), so those only have to be right once.
environment (only the daemon does), and this role keeps `rpc_url` out of `node.toml`
because it may embed an API key. Pass it with `--rpc-url`. The `decdn_chain` helper in
[`docs/lifecycle.md` § Running on-chain commands](../../../docs/lifecycle.md#running-on-chain-commands)
does that from `/etc/decdn/decdn.env`, as the `decdn` user.
does that from `/etc/decdn/decdn.env`, as the `decdn` user. The tradeoff: the URL sits
in the `decdn` process's argv while the command runs, where other local users can see
it with `ps`. The section there covers the shared-host workaround and the upstream fix
(`env = "DECDN_RPC_URL"` on the CLI's `--rpc-url`).

## Network

Expand Down
24 changes: 23 additions & 1 deletion docs/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,29 @@ decdn_chain setup --mbps 100 --region DE \

The URL is in the `decdn` process's arguments while the command runs, so other local
users could read it with `ps`. On a shared host, write a `0600` copy of `node.toml`
with `rpc_url` set under `[blockchain]` and pass that as `--config` instead.
with `rpc_url` set under `[blockchain]` and pass that as `--config` instead. The clean
fix is upstream: give `CommonChainArgs.rpc_url` (`crates/common/src/cli/common.rs`)
`env = "DECDN_RPC_URL"`, as the daemon has. Then `EnvironmentFile=` alone would be
enough and the helper could drop `--rpc-url`.

Register the node's public `/ip4/` multiaddr, and on a dual-stack host its `/ip6/` one
too (repeat `--multiaddr`). Since decdn/decdn#2144 (`869141e9`) the daemon binds QUIC
on both `0.0.0.0:4433` and `[::]:4433`; on a host without IPv6 it starts IPv4-only and
logs a `warn`. Check `ss -ulpn` shows `[::]:4433` before registering an `/ip6/` address.
An older build binds IPv6 on a random port, so an `/ip6/` address on-chain would point
at a port nothing listens on: register `/ip4/` only there. To add the `/ip6/` address
after an upgrade, run `decdn_chain node update-multiaddrs` with **both** addresses; it
replaces the whole on-chain set.

To fund the wallet you need its address, and `keystore.json` has no plaintext address
field. `whoami` decrypts it. It takes no `--rpc-url`, so run it directly rather than
through `decdn_chain`:

```bash
sudo systemd-run --pty --wait --collect -p User=decdn \
/usr/local/bin/decdn --config /etc/decdn/node.toml whoami \
--keystore-password-file /etc/decdn/keystore.password
```

## Compose and Kubernetes

Expand Down
9 changes: 6 additions & 3 deletions docs/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ On Ubuntu 25.10 and later, `sudo` is sudo-rs; see the `ansible_become_exe` note
at a latency cost. A node that serves paid traffic should be directly reachable, and
the multiaddr it registers on-chain must be its public address
(`/ip4/<public-ip>/udp/4433/quic-v1`).
- **IPv6:** supported. On Ansible, `baseline_preserve_ipv6_autoconf` (default `true`)
keeps SLAAC addresses alive under DevSec hardening; set it `false` on static-IPv6
hosts. Multi-homed hosts may need `baseline_rp_filter_loose: true`.
- **IPv6:** supported alongside IPv4. Since decdn/decdn#2144 (`869141e9`) the node's
QUIC listener binds both `0.0.0.0:4433` and `[::]:4433`, and a dual-stack node
registers both its `/ip4/` and `/ip6/` multiaddrs; older builds are IPv4-only on
4433. On Ansible, `baseline_preserve_ipv6_autoconf` (default `true`) keeps SLAAC
addresses alive under DevSec hardening; set it `false` on static-IPv6 hosts.
Multi-homed hosts may need `baseline_rp_filter_loose: true`.
- **Loopback only, never exposed:** metrics `127.0.0.1:9090`, admin RPC
`127.0.0.1:9191`. Reach them over SSH, or ship metrics with the monitoring options.
- **Clock:** keep NTP running (`baseline` installs chrony). `decdn setup`'s pre-flight
Expand Down
Loading