Skip to content

Vss#17

Merged
gofman8 merged 12 commits into
UTEXO-Protocol:devfrom
dcorral:vss
May 21, 2026
Merged

Vss#17
gofman8 merged 12 commits into
UTEXO-Protocol:devfrom
dcorral:vss

Conversation

@dcorral
Copy link
Copy Markdown
Collaborator

@dcorral dcorral commented Apr 14, 2026

VSS Cloud Backup

Overview

VSS (Versioned Storage Service) cloud backup lets a node replicate its state to a remote server so it can be recovered later on a different device. It is fully optional and opt-in: it must be compiled into the build and turned on at startup by pointing the node at a VSS server URL. With it off, the node behaves exactly as a node without the feature.

The goal is disaster recovery: if the machine running the node is lost, a new node initialized with the same wallet mnemonic can pull its state back from the VSS server and resume operation.

What gets backed up

Two independent streams are replicated to the VSS server:

  • Node key-value state — the Lightning data the node must never lose: channel manager, channel monitors, payment records, swap data, and RGB channel info.
  • RGB wallet data — the wallet files (assets, allocations, transfers) managed by the underlying RGB library.

Both streams share one VSS server but use separate, isolated namespaces so they never collide.

When backups are triggered

  • Node key-value state is backed up continuously and automatically: every time the node persists a piece of Lightning state locally, the same update is also sent to the VSS server. There is no schedule and no batching — a backup happens as part of each state change, so the remote copy tracks the node in near real time.
  • RGB wallet data is backed up after every state-changing wallet operation (sending or receiving assets, issuances, channel funding, etc.). It can also be triggered on demand via the HTTP API (see below).
  • Restore is triggered once, automatically, at unlock on a fresh node: if the local database has no Lightning state but the VSS server does, the node restores from VSS before it finishes starting up.

Configuring the node

VSS is controlled entirely by command-line flags on the standalone node.

Flag Purpose
--vss-url <URL> VSS server URL. Setting it enables VSS backup.
--vss-allow-http Permit an http:// URL for non-loopback hosts (otherwise only https:// and loopback HTTP are allowed).
--vss-allow-empty-restore On a fresh device, start with empty state if a restore fails instead of aborting. Use with care.

By default, only https:// URLs (or loopback http://, e.g. a local dev server) are accepted, so channel state is never sent in plaintext over an untrusted network by mistake.

Examples

Enable backup against a remote server:

rgb-lightning-node /path/to/datadir \
  --daemon-listening-port 3001 \
  --ldk-peer-listening-port 9735 \
  --network mainnet \
  --vss-url https://vss.example.com/vss

Local development against the bundled regtest VSS server:

# start regtest services together with a local VSS server
VSS=1 ./regtest.sh start

# run the node pointing at the local server (loopback http is allowed)
cargo run --features vss -- /tmp/rlndata \
  --network regtest \
  --vss-url http://localhost:8081/vss

Recover on a new machine: initialize/unlock the node with the same mnemonic and the same --vss-url. On unlock, the node detects the empty local state and restores from VSS automatically before coming online.

HTTP API

When VSS is enabled, two endpoints are available:

# trigger an immediate RGB wallet backup
curl -X POST http://localhost:3001/vssbackup

# check backup health, including how many writes are still pending replication
curl http://localhost:3001/vssbackupinfo

A non-zero pending-writes count in /vssbackupinfo means some updates have not yet reached the server; monitoring can alert on this to detect a persistently unreachable VSS server.

How concurrency and atomicity are handled

Local store is the source of truth

Every write goes to the local store first and must succeed there; only then is it replicated to VSS. If the local write fails, the operation fails. This means the node never depends on the network being up to make progress, and the local copy is always authoritative.

Backups are eventually consistent, not transactional

Replication to VSS is best-effort. If a write cannot reach the server, it is placed on an in-memory retry queue and re-sent opportunistically on the next successful write. The queue is bounded; if it overflows, the oldest entry is dropped (the authoritative local copy still holds it). The result is an eventually-consistent remote copy whose staleness is observable via /vssbackupinfo.

Single-writer ownership (preventing concurrent corruption)

Each VSS store is meant to be owned by exactly one running node at a time. Two nodes writing to the same store would interleave and corrupt each other's state. To prevent this:

  • At startup the node claims an ownership marker in the store using a conditional create that only succeeds if no one already holds it. If another instance owns the marker, the second node refuses to start.
  • While running, the node periodically re-checks that it still owns the marker. If the marker was taken over by someone else, the node stops rather than risk corrupting the other instance's state.

To migrate a store to a new node after the previous owner is definitively gone, the ownership marker is cleared out-of-band (by hand) before starting the new node.

Atomicity of individual values

Each value is written and encrypted as a single self-contained unit, so a value on the server is either the old version or the new one — never a partial mix. Restores read each value independently (and in parallel for speed), so an interrupted restore can simply be retried.

Encryption

The key-value stream is always encrypted at rest on the server; there is no option to disable it. The encryption key is derived from the wallet mnemonic, so only a node initialized with the same mnemonic can read or restore the backup. This is also why recovery requires the original mnemonic, not just access to the server.

SDK support

VSS configuration is currently available only on the standalone node (via the command-line flags and HTTP endpoints above). The embedded SDK (UniFFI bindings) does not yet expose VSS configuration, so SDK-driven nodes run without cloud backup for now. Exposing VSS through the SDK is a possible future addition.

Operational summary

  • Turn it on with --vss-url; everything else is automatic.
  • The node keeps working even if the server is down; catch-up happens automatically once it is reachable again.
  • Watch the pending-writes count in /vssbackupinfo to confirm backups are current.
  • Never point two running nodes at the same VSS store.
  • Keep the wallet mnemonic safe — it is required to decrypt and restore.

@gofman8 gofman8 merged commit 8cf817a into UTEXO-Protocol:dev May 21, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants