# Run a node, step by step

This page walks through running a relayer node, from the server to the first reward claim, and then through leaving when you decide to stop. It follows the operator guide that is published with the node package, which lists every setting in full. The rules a node follows are in [What you commit to](https://redacted.gg/docs/node-network/running-a-node.md#what-you-commit-to), and how the network fits together is in [How the node network works](https://redacted.gg/docs/node-network/node-network.md).

> **Note:** **Coming soon.** The official release package arrives with the node network, so you can follow these steps as soon as it is out.

## 1. What you need

A node needs a server, access to THORChain, a screening source you trust and some RUNE.

- A Linux x86_64 server with systemd 250 or later, the `acl` package, outbound HTTPS and nginx with a TLS certificate, which gives the node a public HTTPS endpoint. This page calls it the relay host. Give it to the node alone, with no shared logins and no other services under accounts you would not trust with the node's decisions.
- A machine of your own, apart from the relay host. It holds the operator key and runs the tool for registering, updating and claiming.
- A THORChain RPC for the node to read from and broadcast to, and at least one more from another provider, which the node uses to confirm what the first one reports. To trace where money came from, the node also needs a THORNode of your own with a full transaction index and an index of block events, and a Midgard of your own that is in sync. Both belong on servers you control, because whoever runs them sees which accounts the node traces.
- An Ozone instance to trust. Ozone is the reference screener, built by Redacted's core contributors. The node asks the instance about addresses, checks that every answer is signed with the instance's keys and keeps a signed copy of the lists as a backup. You can use the public instance at [ozone.redacted.gg](https://ozone.redacted.gg), which publishes its keys, or run your own, because Ozone is published as open source with the launch.
- RUNE. The bond is 100 RUNE at launch. Each relayer account also needs a small amount of RUNE once, so that it exists on chain, and the main one keeps a working balance because it pays the registration fee for the private accounts the node sponsors. The node sends its transactions at a gas price of zero, and it pauses relaying if the chain's minimum ever rises above that.

## 2. Get the release and check its checksum

Every release is published with its checksum and confirmed through governance, as the [Roadmap](https://redacted.gg/docs/project/roadmap.md) describes. Before you stage a release, compare its checksum and its source commit with the ones that were published and confirmed.

Staging builds the release directory on the relay host, where `<id>` names the release. The first argument is the node package, the second is the new release directory and the third is your settings file. The package ships a template for that file as `packaging/runtime.json`, and step 4 lists what goes into it, so you can read ahead to have it ready. Stage as root, or hand the release to root before you install it, because the installer refuses a release that another account owns or can write.

```sh
node packaging/release.cjs /path/to/relayer-node /opt/redacted-node/releases/<id> ./runtime.json
```

The staged release holds only the files the node needs. Its `release.json` lists the SHA-256 checksum of every file and the source commit, and the node refuses to start if any file has changed since. Then run the installer, also as root.

```sh
/opt/redacted-node/releases/<id>/install-linux.sh
```

The installer downloads the pinned Node.js version and checks its checksum, installs the dependencies, verifies the release against its checksums, reproduces the contract's published test vector for deposit approvals, and runs the policy tests and the type check. Never install as the service account, because root runs parts of what the installer creates and no other account may be able to write them.

## 3. Create the keys

A node uses three kinds of key, and they live in different places.

- The operator key belongs to the account that holds the bond and that you register with. It stays on your own machine, in a file that only you can read, and off the relay host.
- The signing key signs deposit approvals and own-funds confirmations. It is registered on chain separately from any account, and it lives on the relay host.
- The relayer keys belong to the accounts that submit the node's actions, its heartbeats and its votes on waiting deposits. They are hot keys on the relay host. The standard setup uses four, and a node can list up to 16.

Generate the signing key and the relayer keys with the release's own tool, `redacted-node`, which sits in the release directory and also runs with `npm run node-cli --` from a checkout. Key files hold 64 hex characters and can be read only by their owner, and the tool never prints a private key.

```sh
redacted-node keygen --out attestation.key
redacted-node keygen --out relayer.key
redacted-node keygen --out relayer-2.key
redacted-node keygen --out relayer-3.key
redacted-node keygen --out relayer-4.key
redacted-node address --key-file relayer.key --key-file relayer-2.key --key-file relayer-3.key --key-file relayer-4.key
```

`keygen` prints the public key of the key it makes, and `address` prints the chain address of each relayer account. You put those addresses in your settings file and send each one a small amount of RUNE.

## 4. Configure

Your settings file starts from the template in `packaging/runtime.json`, which already switches the node features on through `REDACTED_NODE_MODE`, and the node refuses to start until the template's placeholders are filled in. Only public settings belong in this file, and the node refuses a file with a setting whose name suggests a secret. Your keys reach the node through systemd instead. The settings you fill in include these.

- The operator address, which holds the bond.
- The node's public HTTPS endpoint, `publicPrefix`, which is registered on chain.
- The addresses of your relayer accounts, in the order of their key files.
- Your chain RPC and at least one read failover from another provider.
- Your own THORNode and Midgard for tracing.
- The Ozone instance you trust, with the keys you pin for it.
- The contract build the node expects, with the address of the upgrade timelock from the deployment record. The node refuses to start against any other build.

The settings become part of the staged release and its checksums, so after you change the file, stage the release again as in step 2. The operator guide describes every setting and its default.

Next, install the keys as systemd credentials, as root. The service loads them from there, and an optional key for the Ozone API goes into the same directory the same way.

```sh
install -d -m 0700 /etc/redacted-node
install -m 0400 relayer.key relayer-2.key relayer-3.key relayer-4.key attestation.key /etc/redacted-node/
```

The node's API has no TCP port. It listens on a Unix socket that systemd holds, and nginx passes requests to it. As root, create a group for the socket and make nginx's worker user its only member, which is `www-data` on Debian and Ubuntu.

```sh
groupadd --system redacted-node-api
usermod -aG redacted-node-api www-data
```

Copy the release's `redacted-node@.service` and `redacted-node@.socket` to `/etc/systemd/system/`, add the release's `nginx-private-api.conf` inside your node's HTTPS server block, restart nginx so that its workers join the new group, and start the units.

```sh
systemctl daemon-reload && systemctl enable --now redacted-node@<id>.socket redacted-node@<id>.service
```

The service starts closed while your node is not yet registered. It reads the node's state every 15 seconds, so it opens by itself once the chain shows the node active.

Then read the configuration that nginx actually uses, with `nginx -T`, and check three things. The `/private-api/` locations must sit only in a server block that listens on port 443 with TLS. Those locations must carry the forwarded-protocol and strict transport security headers as the release ships them. No other server block, including a port 80 or catch-all block, may reach the socket. The service also refuses requests that did not arrive over HTTPS, but that is a second line of defense and does not replace this check. Repeat it after every nginx change or release that touches the include.

## 5. Register on chain

*Diagram: Registering a node. Governance invites the operator, the operator registers with the bond, each relayer account agrees, heartbeats follow and the node takes an active place or waits on standby, with every step recorded on THORChain (drawn on https://redacted.gg/docs/node-network/run-a-node-guide/)*

Registration is a short sequence of messages, and each one is public on chain.

Governance admits the first operators, and governance is the DAO until the token relaunch. To become one of them, reach out through the official channels at [redacted.money](https://www.redacted.money), and governance sends the invitation that lets your operator account register. Once governance opens admission, which is one-way, anyone who posts the bond can register without an invitation. From your own machine, check where things stand.

```sh
redacted-node status --runtime runtime.json
```

It shows the minimum bond, the admission mode and whether the emergency exit is open.

Then register with the operator key. The tool attaches the bond, which is 100 RUNE at launch and can be more with `--bond`, and it registers your endpoint and your signing key together with the relayer accounts from `runtime.json`.

```sh
redacted-node register --runtime runtime.json --key-file operator.key --attestation-key-file attestation.key
```

Every command that sends a message first prints the exact message, together with the equivalent `thornode tx wasm execute` line. With `--dry-run` it stops there and reads no key for signing. Otherwise it asks you to confirm, or takes `--yes`. Before it signs, it applies the contract's rules itself. The endpoint must be empty or an `https` address of at most 256 bytes, and a relayer address can serve only one node. Until admission opens, the tool also checks that your operator account has its invitation.

Next, each relayer account agrees to submit for you. On the relay host, as root, run `link`, which sends a `set_operator` message from every relayer account. Both sides have to consent, so nobody can attach an address to someone else's bond.

```sh
redacted-node link --runtime runtime.json --operator <operator> --key-file /etc/redacted-node/relayer.key --key-file /etc/redacted-node/relayer-2.key --key-file /etc/redacted-node/relayer-3.key --key-file /etc/redacted-node/relayer-4.key
```

Then check the result.

```sh
redacted-node status --runtime runtime.json --operator <operator> --attestation-key-file attestation.key
```

It must show your node as active, every relayer account as linked and the signing key as matching.

Registering puts your node in line for one of the active places, and there are 21 of them at launch. While one is free, a ready node takes it at once. When all of them are taken, your node waits on standby, where it keeps sending heartbeats and does not relay or approve deposits, and a daily rotation gives places to the ready standby nodes with the most stake first (see [Node rotation](https://redacted.gg/docs/node-network/node-rotation.md)). `status` shows whether your node holds a place or waits on standby, when the next rotation is due and why the node last moved.

From then on the service keeps the node live. It sends heartbeats by itself, by default at least every eight hours and only while the node can actually serve, and `redacted-node heartbeat` sends one by hand if you ever need it. Heartbeats are also what keep a node ready for an active place.

Each release of the official app lists the nodes it connects to, so app users reach your node once a release includes it, and other clients can use it from the start.

## 6. Check the status and monitor

Run the status command whenever you want to see where the node stands. It shows the registry, your node's record, whether each relayer account is linked, the node's recent activity and the height from which it could be evicted if it stayed idle.

The service also answers a discovery route, `GET /node`. It reports the software and release, the operator, the endpoint and status on chain, the relayer accounts, whether the node holds an active place or waits on standby, the screening mode and the age of its snapshot, and whether the emergency exit is open.

The node writes three things you can follow, and none of them holds a user's network address.

- Metrics go to standard output, which means journald, as one line a minute with counts, latencies and gauges only.
- Node events, such as heartbeats, gate changes and alerts, are logged in fixed text.
- Every screening decision is added to the screening record, a file that is never rewritten. It is the evidence the node rules ask you to keep, and a removal or a slash can cite it.

The screening record has a size limit, so archive old days from time to time. When it is full, the node stops screening and stops sending heartbeats until there is room again.

The node logs an alert, at most once an hour, when no node at all or your own node has been inactive for about two days. A node sends no heartbeat while it cannot serve, for example when it cannot reach its screening sources, so that it never looks live while serving nobody. A node that neither relays nor sends a heartbeat for 14 days can be evicted by anyone, and it moves into unbonding without a penalty. A standby node that keeps sending heartbeats is not evicted.

The service screens waiting deposits again and votes by itself to send one back when the Ozone instance you trust lists where the money came from. It casts that vote from a relayer account, so your operator key stays off the relay host. Votes on the safety switches are yours to cast, from your own machine with the operator key, and the operator guide has the command.

## 7. Update through governance-confirmed releases

A node pins the contract build it was checked against and refuses to start against any other, so a contract upgrade and a new node release go together. Governance schedules an upgrade in public, with the checksum of the new code, and it waits about 3 days before it runs, or less if all three emergency signers use the emergency lane (see [Upgrades, in the open](https://redacted.gg/docs/protocol/security.md#upgrades-in-the-open)). Node releases are published with their checksums and confirmed through governance, so watch for scheduled upgrades and stage the new release before one runs.

Stage the new release next to the old one, install it as root, and run the bootstrap with `--preflight` under the same credentials as the service before you switch (the operator guide gives the full command). This dry start checks the release, the keys against their addresses, the chain ID, the deployment pins and your node's state on chain. It refuses unless your node is active, every relayer account is linked and the registered signing key is the one on the relay host. Then switch over in one command.

```sh
systemctl stop redacted-node@<old>.service redacted-node@<old>.socket && systemctl start redacted-node@<new>.service
systemctl disable redacted-node@<old>.service redacted-node@<old>.socket && systemctl enable redacted-node@<new>.socket redacted-node@<new>.service
```

The new service starts its socket first, and requests that arrive meanwhile wait on the socket. Never run two services with the same relayer keys, and stop the old socket too, or a request can start the old service again.

Smaller changes do not need a new release. `redacted-node update` changes your endpoint or your relayer accounts, `redacted-node rotate-attestation-key` replaces the signing key, and `redacted-node bond` adds to the bond. Rotating the signing key makes every outstanding approval invalid at once, so install the new key as `/etc/redacted-node/attestation.key` and restart the service. Adding to the bond matters after a slash that leaves it below the minimum, because the node then pauses until it tops up (see [What happens in a slash](https://redacted.gg/docs/node-network/node-network.md#what-happens-in-a-slash)).

## 8. Claim rewards

Your node earns rewards as set out in [Rewards](https://redacted.gg/docs/node-network/running-a-node.md#rewards). The contract holds them for your operator account until you claim. Run `redacted-node claim-rewards` from your own machine with the operator key. If the tool reports that more remains, run it again. You can claim at any time, and also after you have left.

## 9. Leave

You can leave at any time, from an active place or from standby. Run `redacted-node unbond` from your own machine with the operator key. The node stops relaying at once, and your bond becomes claimable after the unbonding period of about 14 days. Then run `redacted-node claim` to take it back. The bond can still be slashed until you claim it, as [What happens in a slash](https://redacted.gg/docs/node-network/node-network.md#what-happens-in-a-slash) explains. Claim your rewards as well, which works after you have left. You can register again later in the same way.

The operator guide that comes with the node package lists every setting and every command in full.

---

Page: https://redacted.gg/docs/node-network/run-a-node-guide/
