Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
acb72d9
docs(node): add ValidatorConfig V2 operator guide
decofe Mar 19, 2026
7f7e305
docs(node): remove fee recipient section, not yet active
decofe Mar 19, 2026
4b91cdd
docs(node): differentiate pre-T2 and post-T2 validator operations
decofe Mar 19, 2026
80c7d41
docs(node): restructure operate-validator around V1/V2 split
decofe Mar 19, 2026
d66644b
docs(node): add validator lifecycle flowchart to V2 page
decofe Mar 19, 2026
55158a7
docs(node): simplify V2 flowchart to match operate-validator style
decofe Mar 19, 2026
95bc89a
docs(node): remove migration section from V2 operator docs
decofe Mar 19, 2026
32972b7
docs(node): fix description, remove migration mention
decofe Mar 19, 2026
363679f
docs(node): extract V1 content into validator-config-v1.mdx
decofe Mar 19, 2026
6cb74cd
docs(node): remove deleting signing shares section
decofe Mar 19, 2026
edd8239
docs(node): add isInitialized/getInitializedAtHeight to check V2 status
decofe Mar 19, 2026
d1c6adc
docs(node): link 'check if V2 is active' from intro
decofe Mar 19, 2026
4ca0ef7
docs(node): remove V2 mention from validator.mdx intro
decofe Mar 19, 2026
33f5cac
docs(node): fix lifecycle link to point to V2 validator states
decofe Mar 19, 2026
12ea777
docs(node): replace signature spec with CLI commands, remove consensu…
decofe Mar 19, 2026
fa6baba
docs(node): add rotation best practice — keep old validator until out…
decofe Mar 19, 2026
b77015e
docs(node): mention asymmetric ingress/egress and partial IP updates
decofe Mar 19, 2026
606b81b
docs(node): fix stale link to V1 validator states
decofe Mar 19, 2026
4c03dc5
docs(node): rephrase V2 availability intro
decofe Mar 19, 2026
bfc2cb8
docs(node): nest validator config pages under 'Operating your validat…
decofe Mar 19, 2026
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
84 changes: 10 additions & 74 deletions src/pages/guide/node/operate-validator.mdx
Original file line number Diff line number Diff line change
@@ -1,51 +1,20 @@
---
title: Operate your validator node
description: Day-to-day operations for Tempo validators. Node lifecycle, upgrades, key rotation, monitoring, and troubleshooting.
description: Day-to-day operations for Tempo validators. Node lifecycle, monitoring, metrics, log management, and Grafana dashboards.
---

# Operate your validator

This guide covers day-to-day operations for running a Tempo validator in production.

## Validator states
Validator management differs depending on which ValidatorConfig version is active:

Your validator moves through different states during operation. The transitions will happen only once on your validator's creation. Every state transition will happen on epoch boundaries in the happy case.
- **[ValidatorConfig V2](/guide/node/validator-config-v2)** (post-T2) — self-service key rotation, IP updates, and ownership transfers
- **[ValidatorConfig V1](/guide/node/validator-config-v1)** (pre-T2, legacy) — all management operations require coordinating with the Tempo team

```mermaid
flowchart TD
A[Inactive] -->|epoch ends| B["Syncer<br/>The validator starts syncing"]
B -->|+1 epoch| C["Syncer and Player"]
C -->|"+1 epoch, receives share"| D["Syncer<br/>Player<br/>Dealer"]
D -->|"once fully synced"| E["Voter ↔ Proposer"]
For validator states and lifecycle transitions, see the respective V1 and V2 pages.

click A "#not-a-participant-e"
click B "#syncer-epoch-e1"
click C "#player-epoch-e2"
click D "#dealer-epoch-e3"
click E "#dealer-epoch-e3"
```

Currently, on mainnet and testnet, the epoch length is around 3 hours, which means that your validator will transition through these states approximately every 3 hours. If the epoch length ever changes, the transition times will also change.

#### Not a participant (E)

Epoch E marks the addition of your validator to the on-chain validator configuration smart contract. Your validator isn't considered a peer by validators yet. This is because the validator hasn't been refreshed in the current epoch yet. It is normal that no height metrics progress during this period, your node has to be considered
a syncer to receive blocks.

#### Syncer (epoch E+1)

Your validator is now considered a peer by validators. It's syncing with the network and will be considered a player in the next epoch.

#### Player (epoch E+2)

Your validator is receiving consensus signing shares from dealers during the ceremony.

#### Dealer (epoch E+3)

Your validator is distributing consensus signing shares to other validators during the ceremony. Once your node is fully synced up, it will also
be able to propose blocks and vote for other validators' proposed blocks.

#### Checking your validator's state
## Checking your validator's state

Monitor these metrics to track your validator's state:

Expand Down Expand Up @@ -140,47 +109,14 @@ The node will finish processing the current block before shutting down. Avoid us
**You cannot reset a validator's data and continue with the same identity.** Doing so risks inconsistent voting, which can cause irrecoverable network safety failures.
:::

If you need to reset your validator's data, you must rotate to a new validator identity. This requires coordinating with the Tempo team to deactivate your old identity and register a new one.
If you need to reset your validator's data, you must rotate to a new validator identity. See key rotation under [ValidatorConfig V2](/guide/node/validator-config-v2#rotate-validator-identity) or [ValidatorConfig V1](/guide/node/validator-config-v1#signing-key-rotation).

## Key Management

### Signing Key Rotation

To rotate your validator's signing key:

1. Generate a new keypair:

```bash
tempo consensus generate-private-key --output <new-key-path>
tempo consensus calculate-public-key --private-key <new-key-path>
```

2. Contact the Tempo team to update your validator's public key on-chain

3. Once confirmed, update your node configuration to use the new key and restart. Once the node is running, your validator will go through the [validator lifecycle](/guide/node/operate-validator#validator-states).

:::warning
The old validator identity must be deactivated before the new one is activated
:::

### Signing Share Recovery
For signing key rotation, IP address updates, signing share recovery, and ownership transfers, see:

:::danger
**You cannot reset a validator's data and continue with the same identity.** Doing so risks inconsistent voting, which can cause irrecoverable network safety failures.
:::

If you lose your signing share (stored on the database in `<datadir>/consensus/`), you will need to rotate to a new validator identity. This requires coordinating with the Tempo team to deactivate your old identity and register a new one.
We're planning to release a high-availability feature that allows storing consensus data in an external database, which will enable signing share recovery without the need for key rotation.

### Deleting Signing Shares

:::warning[Breaking Change in v1.1.0]
`--delete-signing-share` now requires the `--force` flag to prevent accidental deletion of validator signing keys. **Update any automation scripts that manage validator key lifecycle.**
:::

```bash
tempo consensus --delete-signing-share --force
```
- **[ValidatorConfig V2](/guide/node/validator-config-v2)** (post-T2) — self-service operations
- **[ValidatorConfig V1](/guide/node/validator-config-v1#key-management)** (pre-T2) — coordinated through the Tempo team

## Log Management

Expand Down
75 changes: 75 additions & 0 deletions src/pages/guide/node/validator-config-v1.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: ValidatorConfig V1 (Legacy)
description: Legacy validator management via ValidatorConfig V1. Key rotation, IP updates, and signing share recovery pre-T2.
---

# ValidatorConfig V1 (Legacy)

:::warning
This page documents ValidatorConfig V1 behavior, which applies **before the T2 hardfork**. Once T2 is active and migration from V1 to V2 is complete, use [ValidatorConfig V2](/guide/node/validator-config-v2) instead. You can [check if V2 is initialized](/guide/node/validator-config-v2#check-if-v2-is-active) to confirm the migration is complete.
:::

ValidatorConfig V1 is the original precompile for managing consensus participants. All management operations are permissioned and require coordinating with the Tempo team.

## Validator states

Under V1, your validator goes through the following states after being added on-chain. Each transition happens on epoch boundaries.

```mermaid
flowchart TD
A[Inactive] -->|epoch ends| B["Syncer<br/>The validator starts syncing"]
B -->|+1 epoch| C["Syncer and Player"]
C -->|"+1 epoch, receives share"| D["Syncer<br/>Player<br/>Dealer"]
D -->|"once fully synced"| E["Voter ↔ Proposer"]

click A "#not-a-participant-e"
click B "#syncer-epoch-e1"
click C "#player-epoch-e2"
click D "#dealer-epoch-e3"
click E "#dealer-epoch-e3"
```

Currently, on mainnet and testnet, the epoch length is around 3 hours, which means that your validator will transition through these states approximately every 3 hours.

#### Not a participant (E)

Epoch E marks the addition of your validator to the on-chain validator configuration smart contract. Your validator isn't considered a peer by validators yet. This is because the validator hasn't been refreshed in the current epoch yet. It is normal that no height metrics progress during this period, your node has to be considered a syncer to receive blocks.

#### Syncer (epoch E+1)

Your validator is now considered a peer by validators. It's syncing with the network and will be considered a player in the next epoch.

#### Player (epoch E+2)

Your validator is receiving consensus signing shares from dealers during the ceremony.

#### Dealer (epoch E+3)

Your validator is distributing consensus signing shares to other validators during the ceremony. Once your node is fully synced up, it will also be able to propose blocks and vote for other validators' proposed blocks.

## Key Management

### Signing Key Rotation

1. Generate a new keypair:

```bash
tempo consensus generate-private-key --output <new-key-path>
tempo consensus calculate-public-key --private-key <new-key-path>
```

2. Contact the Tempo team to update your validator's public key on-chain

3. Once confirmed, update your node configuration to use the new key and restart. Once the node is running, your validator will go through the [validator states](#validator-states) again.

:::warning
The old validator identity must be deactivated before the new one is activated.
:::

### Signing Share Recovery

If you lose your signing share, coordinate with the Tempo team to deactivate your old identity and register a new one.

### Update IP Addresses

Contact the Tempo team to update your validator's ingress and egress addresses on-chain.
208 changes: 208 additions & 0 deletions src/pages/guide/node/validator-config-v2.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
---
title: ValidatorConfig V2
description: Manage your validator with ValidatorConfig V2. Self-service key rotation, IP updates, and ownership transfer.
---

# ValidatorConfig V2

ValidatorConfig V2 ([TIP-1017](/protocol/tips/tip-1017)) is a new precompile for managing consensus participants. It replaces the original ValidatorConfig with stronger safety guarantees: ed25519 signature verification at registration, append-only history, and self-service operations for validators.

V2 becomes available after the T2 hardfork is activated and after an admin has finished the migration of entries from V1 to V2. Migration completion will be communicated to operators — you can also [check if V2 is active](#check-if-v2-is-active) yourself.

## Validator states

With V2, the syncer warmup phase from V1 is removed. Once added, a validator immediately becomes a player in the next epoch.

```mermaid
flowchart TD
A[Inactive] -->|epoch ends| B["Player<br/>Receives signing shares"]
B -->|"+1 epoch, receives share"| C["Player<br/>Dealer"]
C -->|"once fully synced"| D["Voter ↔ Proposer"]
```

Compare this to the [V1 validator states](/guide/node/validator-config-v1#validator-states), which required an additional syncer epoch before becoming a player.

## What changes for operators

With V2, validators can perform several operations themselves without coordinating with the Tempo team:

- **Rotate your validator identity** — swap to a new ed25519 key without losing your committee slot
- **Update IP addresses** — change ingress and egress endpoints independently (V2 supports asymmetric ingress/egress IPs)
- **Transfer ownership** — rebind your validator entry to a new address
- **Fee recipient separation** — will be enabled in a future hardfork. For now, continue using `--consensus.fee-recipient` when starting your node.

All write operations require either the contract owner or the validator's own address.

## Precompile address

```solidity
address constant VALIDATOR_CONFIG_V2 = 0xCCCCCCCC00000000000000000000000000000001;
```

## Check if V2 is active

After the T2 hardfork, the contract owner migrates validators from V1 to V2. Use these calls to check if migration is complete and V2 is active:

```bash
# Returns true once migration is complete and V2 is the active config
cast call 0xCCCCCCCC00000000000000000000000000000001 \
"isInitialized()(bool)" \
--rpc-url https://rpc.tempo.xyz

# Returns the block height at which V2 was initialized (0 if not yet initialized)
cast call 0xCCCCCCCC00000000000000000000000000000001 \
"getInitializedAtHeight()(uint64)" \
--rpc-url https://rpc.tempo.xyz
```

If `isInitialized()` returns `true`, V2 is active and all operations on this page are available. If it returns `false`, the network is still on [ValidatorConfig V1](/guide/node/validator-config-v1).

## Reading validator state

### Query active validators

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth noting here that active validators do not map to the active set of participants in the latest epoch

Fine leaving it out if it's an implementation detail


```bash
cast call 0xCCCCCCCC00000000000000000000000000000001 \
"getActiveValidators()" \
--rpc-url https://rpc.tempo.xyz
```

### Look up your validator

You can query your validator by address, public key, or index:

```bash
# By address
cast call 0xCCCCCCCC00000000000000000000000000000001 \
"validatorByAddress(address)(bytes32,address,string,string,uint64,uint64,uint64,address)" \
<YOUR_VALIDATOR_ADDRESS> \
--rpc-url https://rpc.tempo.xyz

# By public key
cast call 0xCCCCCCCC00000000000000000000000000000001 \
"validatorByPublicKey(bytes32)(bytes32,address,string,string,uint64,uint64,uint64,address)" \
<YOUR_PUBLIC_KEY> \
--rpc-url https://rpc.tempo.xyz

# By index
cast call 0xCCCCCCCC00000000000000000000000000000001 \
"validatorByIndex(uint64)(bytes32,address,string,string,uint64,uint64,uint64,address)" \
<INDEX> \
--rpc-url https://rpc.tempo.xyz
```

The returned `Validator` struct fields are:

| Field | Type | Description |
|-------|------|-------------|
| `publicKey` | `bytes32` | Ed25519 communication public key |
| `validatorAddress` | `address` | Validator control address |
| `ingress` | `string` | Inbound address (`IP:port`) |
| `egress` | `string` | Outbound address (`IP`) |
| `index` | `uint64` | Immutable array position |
| `addedAtHeight` | `uint64` | Block height when added |
| `deactivatedAtHeight` | `uint64` | Block height when deactivated (`0` = active) |
| `feeRecipient` | `address` | Address that receives block proposal fees |

## Operator guide

### Update IP addresses

If your node's network endpoints change, update them on-chain. The change takes effect at the next finalized block.

Unlike V1, V2 supports asymmetric ingress and egress IPs — they no longer need to share the same address. If you only want to update one, pass the current value for the other.

```bash
cast send 0xCCCCCCCC00000000000000000000000000000001 \
"setIpAddresses(uint64,string,string)" \
<YOUR_VALIDATOR_INDEX> \
"<NEW_IP>:<NEW_PORT>" \
"<NEW_EGRESS_IP>" \
--rpc-url https://rpc.tempo.xyz \
--private-key <YOUR_VALIDATOR_PRIVATE_KEY>
```

`<NEW_IP>:<NEW_PORT>` and `<NEW_EGRESS_IP>` may remain unchanged if you only need to update one of the two.

:::warning
Ingress addresses must be unique across all active validators. The transaction will revert if another active validator already uses the same `IP:port`.
:::

### Rotate validator identity

V2 lets you rotate to a new ed25519 key while keeping your validator index stable. This is useful for key rotation or recovery without leaving and re-joining the committee.

The simplest way to rotate is using the `tempo` CLI, which handles signature creation and the on-chain transaction in one step:

```bash

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prepend with the signature creation creation command as well?

tempo consensus rotate-validator \
--signing-key <NEW_PRIVATE_KEY_PATH> \
--rpc-url https://rpc.tempo.xyz
```

:::info
Rotation preserves your validator index and active validator count. The old entry is appended to history as deactivated, and the entry at your index is updated in place. You must use a different ingress address (changing the port is sufficient).
:::

After rotation, your validator goes through the [standard lifecycle](#validator-states) with the new identity.

:::danger[Do not shut down the old validator immediately]
After rotation, the rotated-out validator is still a member of the current committee until the next successful DKG ceremony completes. Shutting it down early will degrade network liveness.

Keep the old validator running and use `validators-info` to monitor its status:

```bash
tempo consensus validators-info --rpc-url https://rpc.tempo.xyz
```

Once the old validator shows `in_committee = false`, it is safe to shut down.
:::

#### Using raw contract calls

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this section if we prepend the rotate-validator command with signature creation.

Should probably never encourage or show how to use the contract directly since the cli does sanity checks


If you prefer to call the precompile directly, first generate the required ed25519 signature proving ownership of the new key:

```bash
tempo consensus create-rotate-validator-signature \
--signing-key <NEW_PRIVATE_KEY_PATH> \
--rpc-url https://rpc.tempo.xyz
```

Then use the output signature in a `rotateValidator` call via `cast send`.

#### Initial registration

When registering a new validator, generate the add-validator signature and provide it to the Tempo team:

```bash
tempo consensus create-add-validator-signature \
--signing-key <PRIVATE_KEY_PATH> \
--rpc-url https://rpc.tempo.xyz
```

### Transfer validator ownership

Rebind your validator entry to a new control address:

```bash
cast send 0xCCCCCCCC00000000000000000000000000000001 \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should create a cli command for this

"transferValidatorOwnership(uint64,address)" \
<YOUR_VALIDATOR_INDEX> \
<NEW_ADDRESS> \
--rpc-url https://rpc.tempo.xyz \
--private-key <YOUR_VALIDATOR_PRIVATE_KEY>
```

The new address must not already be used by another active validator.

## Differences from V1

| | V1 | V2 |
|---|---|---|
| **Key ownership** | No verification | Ed25519 signature required |
| **History** | Mutable, toggle active/inactive | Append-only, deactivate-once |
| **Validator index** | Could change | Stable for lifetime |
| **Self-service ops** | None (owner only) | IP updates, rotation, transfer |
| **Historical queries** | Required warmup state, bloated snapshots | `addedAtHeight` / `deactivatedAtHeight` fields |


Loading
Loading