An xOne validator key is a geth keystore v3 file plus a password file, both mode 0600 or narrower, and the key runs in one process on the whole fleet. To rotate a seat, stop the old signer, confirm that no process holds the key, wait one block, then start the next. Abort on the first missed leader turn.

This post goes deeper on custody and rotation than the net2040 validator guide. Read that guide first for the follower, import and start commands. The xOneTS, xOnePy and xOneC repositories are private.

Where do the keystore and the password file live?

The keystore is a file such as <datadir>/keystore/UTC--.... The password is a plain text file that you choose, for example <datadir>/miner.password. The node key is <datadir>/nodekey. (keys.md)

REFERENCE TABLEScroll to explore all columns →
File Format Mode
Keystore encrypted JSON (scrypt or pbkdf2) 0600 or narrower
Password file first line is the password 0600 or narrower
nodekey 64 hex characters 0600 or narrower
Data directory directory 0700
  • xOneRS refuses a file with any group, other or execute bit. The Permissions error names the file and the mode. Fix it with chmod 600 <file>.
  • AllowInsecurePermissions is an override in the calling code. It is not a flag or an environment variable. Do not use it in production.
  • xOneRS does not check the file owner or the mode of the directory above. Keep the keystore directory 0700 yourself.
  • Passwords come from files only. There is no prompt.

To change a password, update decrypts with the old password and writes the same key under the new one. The path does not change:

xone account update 0xADDR --datadir D --password old.txt --new-password new.txt

What does the node never do with a key?

xOneRS never writes a key, a password or a decrypted key to a log, an error, a panic message, an RPC response or a metric. It never takes a key or password on the command line or in an environment variable. It never writes a validator key. It only reads the keystore you made. (keys.md)

  • Key and password bytes are zeroized when dropped. Disable swap and core dumps on a validator host. The program cannot prevent them.
  • A nodekey that exists but is unreadable or malformed stops the node. The node never replaces it silently. geth creates a new one after any read error.
  • Not covered yet: the remote-signer network transport, HSM support and a seat move between hosts as a feature. A seat move is the manual sequence below.

What is the one-signer rule?

A validator key runs in exactly one process on the whole fleet. Two signers on one key is a safety fault. The mint gate of each client states this as rule 2, and the xOneTS, xOnePy and xOneC copies say it in the same words. (xOneTS mint-gate.md)

Other rules that apply to a rotation:

  • One cutover at a time across all clients and hosts.
  • The candidate is at the tip with 8 or more peers before the switch.
  • No plaintext key in a unit, a flag or a log. Remove staged key copies after the test.

What are the exact steps of a rotation?

Stop, confirm 0 processes, wait, start. Abort on the first miss. These steps come from the mint gate. (xOneTS, xOnePy, xOneC)

  1. Record the head number and the time of the flip.
  2. Stop the current signer. Confirm 0 processes with the key. Wait for one block.
  3. Start the next signer (see the next section).
  4. Compute the leader turns from round % 900 % N on the masternode list in force. Watch each turn.
  5. Verify each seal three ways: the block is stamped after the flip, the next block names it as parent and it is canonical on an independent node, and the candidate's own log shows the same number and hash.
  6. On a missed turn, a wrong-root error, a rejected own block or a vote on two blocks of one round, stop the candidate at once and start the rollback signer. Stop within 45 to 60 seconds. Never wait out a 300 s dead slot.
  7. After the hand-off, confirm that the other signer is back as a follower with no key and that no staged key copy remains.

Do not leave a seat idle across an epoch boundary. A masternode that seals no block in a whole epoch is penalised at the next epoch switch and leaves the list. One epoch is 900 rounds on net2040.

Does a hot switch differ from a restart?

Yes. xOneTS switches without a restart. xOneRS needs a restart with --mine. In xOneRS, miner_start answers "method not found" (rpc.rs).

REFERENCE TABLEScroll to explore all columns →
Client Start the key Stop the key
xOneRS restart with --mine --keystore <file> --password <file> --miner.etherbase 0x<address> stop the process
xOneTS follower with --keystore, --password and --miner.etherbase, no --mine: miner_start on loopback RPC, or SIGUSR1 miner_stop or SIGUSR2 drops the key

xOneTS standby details, from the mint gate:

  • At start the follower checks that the files exist, that the keystore mode is 0600 or narrower and that the address matches. It opens the safety unit. It does not decrypt the key. The log has key not decrypted and the metrics show xone_mining 0.
  • miner_start decrypts the key, opens the signer and turns mining on. Only loopback callers can use it. Check mining on by=miner_start ... key=loaded and xone_mining 1. A wrong password returns an error and leaves mining off.
  • Run miner_start in the epoch in which the old signer stopped. A candidate with mining off across an epoch boundary can lose the seat.

The validator guide lists xOnePy and xOneC. Their copies of the mint gate do not mention the hot switch.

Where is the signer safety record, and what is the quiet window?

xOneRS opens the record at <datadir>/xone/safety (producer.rs). The record is written and synced before each signature exists, and it only rises. ADR-010 is still "proposed".

  • The runbook and ADR-010 name datadir/safety. Issue #820 tracks that mismatch. Use the path the code uses. xOneTS opens <datadir>/safety (main.ts).
  • One directory holds one key. A new key needs a new directory.
  • Do not restore or copy the record from a backup. A signature that reached no peer leaves no trace. A restore from before it can sign another block for that round (ADR-010, residual risk R1). The upgrade and rollback how-to covers the rollback case.
  • At every start the signer is quiet for a window: 120 s on net2040. Only seconds with valid gossip from a peer count. During the window, a signature of our key from another process raises the record and restarts the wait. --miner.quietwindow accepts only a larger value (flags.md).
  • Log lines: fence open: the quiet window passed, signing starts and fence closed: our key signed ...; the quiet window restarts.

What does this not cover?

It does not cover two hosts. The file lock on the safety directory stops a second process on one host only. The quiet window is a wait with observation, not a lock. If two hosts open at the same moment, or one starts while the other is cut off from it, both can sign until a sighting arrives (ADR-010, residual risk R2).

The xOneTS mint test accepted this limit: its fence is a count of client processes naming the seat on each host, not a cross-host lock (net2040-ts-mint.md). The mint gate lists a fence that works across hosts as a pre-flight item. Live seats are in the hourly tracker: on 2026-11-14T18:30Z it showed Rust on seat 0xa0ea since 2026-11-12 03:28Z and xOneTS on its own seat 0xfC71 since 2026-11-13T12:24Z.

How do other clients describe key custody?

Other clients describe key custody in their own terms. The rows are descriptions, not test results.

REFERENCE TABLEScroll to explore all columns →
Source What it states xOne
Besu QBFT docs (no date shown) --security-module selects an HSM. The key is a keystore v3 file on disk. HSM support is a later item.
erigon-xdc (private repository) Producer flags --xdc.v2.produce --xdc.v1.signerkey. xOneRS reads a keystore file named by --keystore and a password file named by --password.

See also the node operations guide.

Frequently asked questions

Where does xOne keep the validator key?

In a geth keystore v3 file, for example <datadir>/keystore/UTC--.... A password file unlocks it. Both need mode 0600 or narrower, and the data directory needs 0700.

Can the node print or log my key?

No. xOneRS never writes a key, a password or a decrypted key to a log, an error, a panic message, an RPC response or a metric. It never accepts them on the command line or in an environment variable.

How do I move a seat to another client?

Stop the old signer, confirm that no process holds the key, wait one block, then start the new one. xOneTS can switch with miner_start or SIGUSR1. xOneRS restarts with --mine. Abort on the first missed leader turn.

Does xOne stop two hosts from signing with one key?

Not on its own. The file lock covers one host. The quiet window is a wait with observation, not a lock. Keep to the one-signer rule.

Sources