Skip to content

Commit 84061e3

Browse files
authored
Merge pull request #135 from dusk-network/agent/operator-reliability-runbook
Document installer-backed node maintenance and recovery
2 parents b9c7f55 + 0d2257c commit 84061e3

13 files changed

Lines changed: 440 additions & 393 deletions

src/content/docs/developer/integrations/tx-lifecycle.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Do not use **included**, **removed**, **accepted**, or **confirmed** as a paymen
3838
| How are transactions prioritized? | Candidate selection iterates by descending `gasPrice`. Equal-price ordering is not a client contract. |
3939
| How does replacement work? | A transaction that conflicts on a spending ID replaces the existing transaction only when its gas price is strictly higher. Raising only the gas limit is insufficient. Moonlight uses account and nonce as its spending ID; Phoenix conflicts on spent nullifiers. |
4040
| What happens when the mempool is full? | A higher-priced transaction can evict the lowest-priced entry. Node operators configure the capacity; the default is 10,000 transactions. |
41-
| When do transactions expire? | Expiry is local node policy, not a field in the transaction. The default residence is three days, checked hourly, and both values are configurable. Clients must not treat three days as a network guarantee. |
41+
| When do transactions expire? | Expiry is local node policy, not a field in the transaction. Rusk's built-in defaults are three days with hourly checks, while node-installer `v0.5.22` configures mainnet and testnet nodes for 30 minutes with checks every five minutes. Clients must use the policy of their node instead of treating either value as a network guarantee. |
4242
| What happens to future Moonlight nonces? | A transaction with a nonce gap is briefly staged outside the real mempool while the node waits for intermediate nonces. It emits `deferred`, is invisible to `mempoolTxs`, and is admitted only if the gap is filled before retries end. |
4343
| Can every node publish transactions? | A full Rusk node can receive and rebroadcast transactions. Its operator can disable or restrict public HTTP access, apply ACLs, or rate-limit propagation. |
4444

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,103 @@
11
---
22
title: Run an archive node
3-
description: Learn about Dusk archive nodes that store and give access to Dusk’s historical data.
3+
description: Install and operate a Rusk node with finalized historical indexes.
44
---
55

6-
Archive nodes extend the functionality of [Provisioners](/operator/provisioner) by also preserving a complete historical record of the Dusk blockchain. While provisioners focus on the current state and consensus duties, archive mode adds long-term historical data access for applications, users, researchers, and auditors.
6+
An archive node runs the archive build of Rusk and retains finalized historical indexes in addition to normal chain state. Applications use it for queries such as `moonlightHistory`, `fullMoonlightHistory`, and `finalizedEvents`.
77

8-
Archive nodes are commonly run as data-serving infrastructure and do not need to stake DUSK. However, archive mode is built on top of the regular node stack, so an archive node can also be configured to participate in consensus if you choose to stake and run it that way.
8+
Archive mode does not require staking. An archive node can also participate in consensus, but production API infrastructure is usually kept separate from provisioner duties so query load and maintenance do not compete with consensus.
99

10-
In short, archive nodes:
11-
- Provide additional historical data (such as events emitted by contracts) that is not stored by a Provisioner node
12-
- Expose archive-only GraphQL queries such as `moonlightHistory`, `fullMoonlightHistory`, and `finalizedEvents`
13-
- Can also participate in consensus by staking DUSK, though that is optional
10+
## Requirements
1411

15-
:::tip[Run an Archive node]
16-
If you want to quickly launch & run an archive node, you can use the <a href="https://github.com/dusk-network/node-installer" target="_blank">node installer</a> by following [the archive guide](/operator/archive-node).
17-
:::
18-
19-
## Archive Node Specifications
12+
Use Ubuntu 24.04 LTS and begin with at least:
2013

21-
Archive nodes store and serve historical data and require large storage capacity, efficient processing for concurrent requests, and fast Internet connectivity. The following recommended specifications serve as a baseline for Archive Nodes. Over time, storage requirements will increase.
14+
| CPU | RAM | Storage | Network |
15+
|---|---|---|---|
16+
| 4 cores at 2 GHz | 8 GB | 500 GB | 100 Mbps |
2217

23-
| CPU | RAM | Storage | Network Connection |
24-
| :------------- | :--- | :------ | :----------------- |
25-
| 4 cores; 2 GHz | 8 GB | 500 GB | 100 Mbps |
18+
This is an initial planning baseline, not a capacity guarantee. Archive storage grows over time; monitor actual utilization and expansion lead time.
2619

27-
## Run an archive node
28-
> A step-by-step guide to setting up a Dusk archive node.
20+
## Install
2921

30-
The following guide will explain you how to install and setup an archive node on Ubuntu 24.04 through the [node installer](https://github.com/dusk-network/node-installer). This installer will set up Rusk as a service on your server, preconfigure parts of the node, and provide a couple of helper scripts.
22+
Run the released node installer with the archive feature:
3123

32-
Install Rusk with the archive feature enabled by pasting the following command in your server terminal:
3324
```sh
34-
curl --proto '=https' --tlsv1.2 -sSfL https://github.com/dusk-network/node-installer/releases/latest/download/node-installer.sh | sudo bash -s -- --feature archive
25+
curl --proto '=https' --tlsv1.2 -sSfL \
26+
https://github.com/dusk-network/node-installer/releases/latest/download/node-installer.sh \
27+
| sudo bash -s -- --feature archive
3528
```
3629

37-
This will install an archive node with the network being set to mainnet.
38-
39-
## Configure Rusk
30+
Add `--network testnet` before `--feature archive` for a testnet archive node.
4031

41-
You now should have successfully installed Rusk.
42-
43-
A quick check with:
44-
45-
```sh
46-
ruskquery version
47-
```
48-
49-
Should tell you, that you are running the latest installer version.
50-
51-
## Start your node
52-
53-
If you've configured everything correctly, you can now start rusk:
54-
```sh
55-
service rusk start
56-
```
32+
Start Rusk and monitor synchronization:
5733

58-
Your node will now start syncing. You can check if it indeed is by running:
5934
```sh
35+
sudo systemctl start rusk
36+
systemctl is-active rusk
37+
ruskquery peers
6038
ruskquery block-height
6139
```
6240

63-
It is best to wait until your node is synced up. You can find the latest block height on [the block explorer](https://explorer.dusk.network/). Alternatively, consider [fast-syncing](/operator/guides/fast-sync) for a quicker method.
41+
Compare the height with the matching [network](/operator/networks/).
42+
43+
An archive expected to answer complete history must synchronize from genesis or restore a trusted backup that includes the archive databases. The installer's `download_state` snapshot restores execution state, but it does not backfill archive indexes for blocks before that snapshot.
6444

65-
## Enable http
45+
## Enable the HTTP API
6646

67-
If you want to serve archive data to the outside world, your node needs to enable the http capabilities. This can be done by adding
47+
The installed API is not intended to be public by default. For local access or a reverse proxy on the same host, add this to `/opt/dusk/conf/rusk.toml`:
6848

6949
```toml
70-
# rusk.toml
7150
[http]
7251
listen = true
73-
listen_address = '0.0.0.0:8080'
52+
listen_address = '127.0.0.1:8080'
7453
```
7554

76-
To your rusk.toml file in your system's `/opt/dusk/conf` folder. That's it.
55+
Then restart Rusk:
7756

78-
Now you can query the archive for data with an external client application.
57+
```sh
58+
sudo systemctl restart rusk
59+
```
7960

80-
## Test archive endpoint
61+
Use `0.0.0.0:8080` only when the API must accept traffic on an external interface. Restrict it with a firewall, access policy, rate limits, or a controlled reverse proxy. Public `8080/tcp` access is not required for synchronization or consensus.
8162

82-
You can check which GraphQL queries are available by retrieving the schema (SDL). On RUES, an empty body returns the schema:
83-
```bash
84-
curl -s -X POST "http://<your-node-host>:8080/on/graphql/query"
85-
```
63+
:::caution[Updates regenerate rusk.toml]
64+
Rerun the installer with `--feature archive` during every update. The installer regenerates `/opt/dusk/conf/rusk.toml`, so review the new file and reapply the intended `[http]` settings before returning the API to service.
65+
:::
8666

87-
This should now return a different schema than a normal node returns. Archive-enabled nodes expose additional historical queries such as `moonlightHistory`, `fullMoonlightHistory`, and `finalizedEvents`.
67+
## Verify archive queries
8868

89-
A regular node also exposes `checkBlock`, but the `onlyFinalized: true` behavior below is archive-only.
69+
List the archive fields exposed by canonical GraphQL:
9070

91-
In order to test this endpoint, you can run the following command.
71+
```sh
72+
curl -fsS -X POST "http://127.0.0.1:8080/graphql" \
73+
-H "Content-Type: application/json" \
74+
--data-raw '{"query":"{ __schema { queryType { fields { name } } } }"}' \
75+
| jq -r '.data.__schema.queryType.fields[].name' \
76+
| grep -E '^(moonlightHistory|fullMoonlightHistory|finalizedEvents|checkBlock)$'
77+
```
78+
79+
Query a known block:
9280

93-
```bash
94-
curl -s -X POST "http://<your-node-host>:8080/on/graphql/query" \
95-
--data-raw '{ block(height: 1) { header { hash } } }' | jq .
81+
```sh
82+
curl -fsS -X POST "http://127.0.0.1:8080/graphql" \
83+
-H "Content-Type: application/json" \
84+
--data-raw '{"query":"{ block(height: 1) { header { height hash } } }"}' \
85+
| jq .
9686
```
9787

98-
Then use the returned block hash with `checkBlock`:
88+
To verify finalized-block lookup, replace `<BLOCK_HASH>` with the returned hash:
9989

100-
```bash
101-
curl -s -X POST "http://<your-node-host>:8080/on/graphql/query" \
102-
--data-raw 'query { checkBlock(height: 1, hash: "<block_hash>", onlyFinalized: true) }' | jq .
90+
```sh
91+
curl -fsS -X POST "http://127.0.0.1:8080/graphql" \
92+
-H "Content-Type: application/json" \
93+
--data-raw '{"query":"{ checkBlock(height: 1, hash: \"<BLOCK_HASH>\", onlyFinalized: true) }"}' \
94+
| jq .
10395
```
10496

105-
On a non-archive node, `onlyFinalized: true` returns an error.
97+
Archive history is populated as blocks finalize. Verify the earliest range your application requires before declaring the service ready.
10698

107-
## Stake with archive node
99+
See [Scan Moonlight deposits](/developer/integrations/historical_events/) for a bounded history consumer and [HTTP API](/developer/integrations/http-api/) for query and access-policy details.
108100

109-
It is possible to stake and participate in consensus while the archive node is running. This is usually not recommended, but is possible since the archive is built on top of a normal provisioner node and therefore has all the capabilities to do so.
101+
## Stake from an archive node
110102

111-
You can read the [node wallet guide](/operator/guides/node-wallet-setup) for a step-by-step instruction on setting up the wallet, depending on if you want the archive node to participate in consensus too or not.
103+
Staking is optional. If this host will also be a provisioner, follow [Set up the node wallet](/operator/guides/node-wallet-setup/) and apply the same monitoring, key-isolation, and update procedures as any other provisioner.

src/content/docs/operator/faq.md

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ Yes. The node only needs the consensus key file (`consensus.keys`). Export it fr
6363
Example (adjust user/IP):
6464

6565
```bash
66-
scp consensus.keys duskadmin@<node-ip>:/opt/dusk/conf/
66+
scp consensus.keys duskadmin@<node-ip>:~/consensus.keys
67+
ssh duskadmin@<node-ip> \
68+
'sudo install -o root -g dusk -m 640 ~/consensus.keys /opt/dusk/conf/consensus.keys && rm -f ~/consensus.keys'
6769
```
6870

6971
#### What if I lose access to my server or keys?
@@ -80,13 +82,15 @@ rusk-wallet stake --amt 3000
8082

8183
#### How can I recover my node if the state is corrupted?
8284

83-
Reload from a snapshot and restart:
85+
For a default mainnet or testnet node, reload from a snapshot and restart:
8486

8587
```bash
86-
download_state
87-
service rusk start
88+
sudo download_state
89+
sudo systemctl start rusk
8890
```
8991

92+
For an archive node that requires complete history, follow the archive-specific [re-sync guidance](/operator/guides/manual-resync/#restore-a-published-state).
93+
9094
#### How can I run a Dusk node on Docker?
9195

9296
We don't support a production-ready Docker image. For ephemeral (non-persistent) usage:
@@ -111,37 +115,31 @@ Without the node installer, configure `rusk.toml`:
111115
[kadcast]
112116
public_address = "<MY_WAN_IPV4>:<NEW_PORT>"
113117
listen_address = "<MY_LAN_IPV4>:<NEW_PORT>" # Optional
114-
bootstrapping_nodes = ["165.22.193.63:9000", "167.172.175.19:9000"]
115118
```
116119

120+
Retain the bootstrapping nodes supplied for the selected network.
121+
117122
#### How do I change the HTTP API port?
118123

119124
In `rusk.toml`:
120125

121126
```toml
122127
[http]
123128
listen = true
124-
listen_address = "0.0.0.0:8080"
129+
listen_address = "127.0.0.1:8081"
125130
```
126131

127-
Or via CLI:
128-
129-
```bash
130-
--http-listen-addr 0.0.0.0:8081
131-
```
132+
The installer regenerates `rusk.toml` during upgrades, so review and reapply this setting afterward. Bind an external interface only when required, and restrict public API traffic.
132133

133134
#### How can I get data from testnet or mainnet nodes?
134135

135136
See [/developer/integrations/http-api](/developer/integrations/http-api) and [/developer/integrations/historical_events](/developer/integrations/historical_events).
136137

137-
#### How can I relay my internal port 8080 when using RUES?
138-
139-
```bash
140-
socat tcp-listen:8081,reuseaddr,fork tcp:localhost:8080
141-
```
142-
143138
#### How can I perform a liveness check on my node?
144139

145140
- `ruskquery block-height` (should increase over time)
146141
- `ruskquery peers`
147-
- `systemctl status rusk`
142+
- `systemctl is-active rusk`
143+
- `ruskquery info`
144+
145+
See [Maintain and monitor a node](/operator/maintenance-monitoring/) for network-tip comparison, resources, logs, and alerts.
Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,55 @@
11
---
2-
title: Fast-sync your node
3-
description: Speed up your Dusk node synchronization by leveraging pre-available snapshot.
2+
title: Fast-sync a node
3+
description: Replace local chain state with a published mainnet or testnet snapshot.
44
---
55

6-
The node installer comes with an easy to use fast syncing tool. To significantly reduce the time required to sync your node to the latest published state, you can use the `download_state` command. This command stops your node and replaces its current state with the latest published state from one of Dusk's archive nodes.
6+
The node installer provides `download_state` for mainnet and testnet. It downloads a published state, stops Rusk, replaces the local state and chain database, and leaves the service stopped for operator verification.
77

8-
## Available states
8+
:::caution
9+
Fast sync replaces current chain state under `/opt/dusk/rusk`. It does not replace consensus keys or node configuration, but you should still verify you selected the intended network before confirming.
10+
:::
11+
12+
Fast sync does not backfill archive indexes for blocks before the snapshot. Do not use a state snapshot alone to bootstrap an archive node that promises complete historical data.
13+
14+
## List snapshots
15+
16+
The command detects the network from `/opt/dusk/conf/rusk.toml`:
917

10-
To see the available published states, run:
1118
```sh
1219
download_state --list
1320
```
1421

15-
## Download state
22+
Override detection only when necessary:
23+
24+
```sh
25+
download_state --network testnet --list
26+
```
27+
28+
## Replace state
29+
30+
Download the latest snapshot:
1631

17-
To install the latest state, simply run:
1832
```sh
19-
download_state
33+
sudo download_state
2034
```
2135

22-
Once it tells you the operation is complete, run the following command to start your node again:
36+
Or select one of the listed block heights:
37+
2338
```sh
24-
service rusk start
39+
sudo download_state <BLOCK_HEIGHT>
2540
```
2641

27-
This process bootstraps your node with the latest available state snapshot, allowing it to sync the remaining blocks much faster than starting from genesis.
42+
The tool downloads to a unique temporary file and removes it afterward. A successful command still leaves Rusk stopped.
43+
44+
## Restart and verify
2845

29-
:::note
30-
If you are experiencing errors in downloading the state, it might be due to some remnants of previous state syncing. Try to clean up with:
3146
```sh
32-
sudo rm /tmp/state.tar.gz
47+
sudo systemctl start rusk
48+
systemctl is-active rusk
49+
ruskquery peers
50+
ruskquery block-height
3351
```
34-
:::
52+
53+
Check the height again after roughly 30 seconds. The node should continue syncing from the snapshot toward the current [network tip](/operator/networks/).
54+
55+
If the service fails, inspect `systemctl status rusk`, `/var/log/rusk.log`, and `/var/log/rusk_recovery.log` before retrying. See [Re-sync a node](/operator/guides/manual-resync/) for the decision process.

0 commit comments

Comments
 (0)