# Validator network topology

Run a production validator in an isolated network segment. Allow consensus traffic between validators, but route execution P2P and all transaction ingress through redundant trusted follower RPC nodes.

:::info
These trusted RPC nodes can also provide internal access to chain state as an alternative to `https://rpc.tempo.xyz`.
:::

## Why validators need an isolation layer

Do not submit transactions directly to a validator. Submit them to a trusted RPC node, which checks transaction signatures before forwarding valid transactions to the validator. This prevents invalid transactions from consuming the validator's compute resources.

Do not establish execution devp2p connections between validators. A malicious or compromised validator or public peer could otherwise send spurious transactions directly to another validator and attempt to exhaust its resources. With the recommended topology, transactions are gossiped only through the trusted RPC layer, while validators communicate directly with one another only over consensus P2P.

:::info[Run trusted RPC nodes on separate instances]
Run trusted RPC nodes on machines or instances separate from the validator so they do not share CPU, memory, disk, or network resources with it. The isolation boundary is ineffective if abusive traffic against an RPC node can still exhaust the validator host.
:::

## Recommended validator topology

The validator has two types of network relationships:

* **Consensus P2P:** The validator communicates directly with other Tempo validators.
* **Execution P2P:** The validator peers only with its operator's trusted RPC nodes over TCP and UDP. It does not establish execution P2P connections with other validators or public peers.

The execution P2P layer is open, so place trusted RPC nodes between the validator and that network. Configure each trusted RPC node with `--follow ws://<VALIDATOR_PRIVATE_IP>:8546` so it syncs in lockstep with the validator over a private WebSocket connection.

Run at least two trusted RPC nodes for each validator to avoid a single point of failure for execution P2P and transaction ingress:

Two separate Validator units each contain a trusted RPC group and its validator: R1 with V1, and R2 with V2. A client outside both units submits a transaction to R1 over JSON-RPC. R1 and R2 each connect to Public Nodes and to each other over bidirectional execution P2P. R1 follows V1 and R2 follows V2 using --follow over WebSocket; each pair also has a bidirectional execution P2P connection. V1 and V2 communicate over bidirectional consensus P2P, with no execution P2P connection between them.

No validator P2P or RPC port should be directly accessible from the internet. Do not allow execution P2P between `V1` and `V2`; transactions cross the validator isolation boundary only through `R1` or `R2`.

## Validator firewall policy

Enforce the topology at the network firewall even when the node's peer configuration restricts discovery or has a fixed peer list.

Firewall for the validator (default ports):

| Traffic | Source or destination | Port | Policy |
| --- | --- | --- | --- |
| Consensus P2P | Other Tempo validators | `8000/TCP` | Allow |
| Execution P2P | Trusted RPC hosts | `30303/TCP` and `30303/UDP` | Allow |
| WebSocket JSON-RPC | Trusted RPC hosts | `8546/TCP` | Allow |
| HTTP JSON-RPC management | Validator host only (loopback) | `8545/TCP` | Deny remote access |
| All other inbound traffic | Any source | Any port | Deny |

Restrict the validator's execution peer configuration to the trusted follower RPC nodes. Do not include other validators in this allowlist, and do not rely on peer discovery alone to provide isolation.

## Configure validator execution peers

Each follower needs a stable and unique execution P2P identity. On each follower, print its `enode://` URL from the discovery secret that the node uses:

```bash
tempo p2p enode <FOLLOWER_DISCOVERY_SECRET>
```

Run the command once for each trusted RPC node. Each node must have a unique discovery secret that it uses to identify itself. Use the RPC node's private IP that the validator uses to reach it.

Concatenate these `enode://` URLs, passed to the validator command:

```bash
tempo node <EXISTING_ARGUMENTS> \
  --disable-discovery \
  --trusted-only \
  --trusted-peers "enode://<FOLLOWER_A_PUBLIC_KEY>@<FOLLOWER_A_PRIVATE_IP>:30303,enode://<FOLLOWER_B_PUBLIC_KEY>@<FOLLOWER_B_PRIVATE_IP>:30303" \
  --ws \
  --ws.addr <VALIDATOR_PRIVATE_IP> \
  --ws.port 8546 \
  --ws.api eth,consensus
```

Each flag serves a specific purpose:

| Flag | Effect on the validator |
| --- | --- |
| `--trusted-peers` | Static list of trusted peers that the node accepts connections from or tries to connect to. |
| `--trusted-only` | Connects to and accepts execution P2P connections from trusted peers only. |
| `--disable-discovery` | Disables DNS, discv4, and discv5 peer discovery. |

Keep the firewall allowlist in place. The enode allowlist authenticates the followers' execution P2P identities, while the firewall restricts which private IPs can reach the validator's P2P port.

The `--ws` flags enable the validator's WebSocket endpoint for followers. Follow mode uses `consensus` RPC subscriptions and finalization data, plus `eth` RPC calls to fetch blocks. `--http` alone does not enable WebSocket subscriptions. Bind WebSocket RPC to the validator's private interface and allow port `8546/TCP` only from trusted RPC hosts.

### Add or remove trusted RPC nodes without restarting

Enable the `admin` RPC namespace on a localhost-only HTTP management endpoint at validator startup to change the in-memory trusted peer set while the validator is running. Add these flags to the validator command above, keeping its private WebSocket endpoint enabled:

```bash
tempo node <EXISTING_ARGUMENTS> \
  --http \
  --http.addr 127.0.0.1 \
  --http.port 8545 \
  --http.api eth,net,web3,admin
```

Here, "trusted" means the RPC node is allowed to exchange execution P2P traffic with the validator. It does not grant permission to administer the validator. `--trusted-peers` and `--trusted-only` control execution P2P connections; they do not authenticate or restrict JSON-RPC callers. A compromised follower must not be able to change the validator's peer allowlist.

Keep `admin` on `http://127.0.0.1:8545`, accessible only from the validator host. Never include it in `--ws.api` on the follower-facing endpoint or expose the management endpoint through a proxy to followers, clients, or the public internet. The two endpoints belong to the same validator process but use separate bind addresses, ports, and RPC namespace lists.

If the validator already enables other HTTP namespaces on this localhost-only endpoint, preserve them when adding `admin`. Enabling the namespace after startup requires a validator restart. Run the following management commands on the validator host.

Add a trusted RPC node immediately:

```bash
cast rpc admin_addTrustedPeer \
  '"enode://<FOLLOWER_PUBLIC_KEY>@<FOLLOWER_PRIVATE_IP>:30303"' \
  --rpc-url http://127.0.0.1:8545
```

To remove a trusted RPC node, first remove it from the trusted set, then disconnect its active peer session:

```bash
cast rpc admin_removeTrustedPeer \
  '"enode://<FOLLOWER_PUBLIC_KEY>@<FOLLOWER_PRIVATE_IP>:30303"' \
  --rpc-url http://127.0.0.1:8545

cast rpc admin_removePeer \
  '"enode://<FOLLOWER_PUBLIC_KEY>@<FOLLOWER_PRIVATE_IP>:30303"' \
  --rpc-url http://127.0.0.1:8545
```

These methods update only the validator's in-memory peer set. Update the durable `--trusted-peers` configuration separately so the intended peers remain after a restart. Update the firewall allowlist at the same time.

## Configure trusted RPC nodes

Place each trusted RPC node on a separate machine or instance from the validator, preferably in a separate network segment. Configure each node to:

* Run in follow mode with `--follow` pointed at the validator's private WebSocket RPC endpoint.
* Participate in the public Tempo execution P2P network.
* Accept transaction submissions from clients or an internal load balancer instead of exposing the validator's JSON-RPC endpoint.

On startup, RPC nodes discover a starting set of peers from bootnodes and connect to new peers through P2P discovery. Their P2P ports must be reachable by the public execution network, subject to the operator's host-hardening and traffic-control policy.

### Follow the validator over WebSocket

On each trusted RPC host, add an explicit validator URL to the node's existing chain, data directory, and discovery-secret configuration:

```bash
tempo node <EXISTING_ARGUMENTS> \
  --follow ws://<VALIDATOR_PRIVATE_IP>:8546 \
  --http \
  --http.addr <FOLLOWER_PRIVATE_IP> \
  --http.port 8545 \
  --http.api eth,net,web3
```

Use the same chain as the validator and the discovery secret used to derive that follower's allowlisted enode. Replace an existing bare `--follow` with this explicit URL so the node follows your validator instead of the chain's default upstream. Keep peer discovery enabled on the followers; the `--disable-discovery` and `--trusted-only` flags above apply to the validator.

The follower opens an outbound WebSocket connection to the validator. It does not need its own `--ws` server enabled to follow. Its `--http` flags expose a separate endpoint for clients or an internal load balancer; restrict access to that endpoint to the intended callers. For setup and snapshot instructions, see [running RPC and standby nodes](https://tempo.xyz/developers/docs/guide/node/rpc).

## Failure and maintenance considerations

Both follower RPC nodes are on the validator's transaction-ingress path. Monitor their execution peer counts, block heights, resource utilization, transaction-submission health, and private links to the validator.

Run the followers independently so either node can continue accepting and relaying transactions when the other is unavailable. Configure clients or an internal load balancer to remove an unhealthy follower from rotation. Verify that failure of either follower does not interrupt transaction submission through the remaining node.

## Validate the isolation boundary

After deployment or a firewall change, confirm that:

* Other validators can reach the validator's consensus port.
* The validator's execution peer count exactly matches the number of trusted RPC nodes.
* Internet hosts cannot reach the validator on any ports.
* The validator cannot establish execution P2P connections to internet peers or other validators.
* Each follower is configured with `--follow` against the validator and remains synced.
* Each follower can reach the validator's private WebSocket endpoint on port `8546`, but cannot reach its localhost HTTP management endpoint on port `8545` or call `admin` methods over WebSocket.
* Transactions submitted through either follower reach the validator.
* Clients cannot submit transactions directly to the validator.
* Transaction submission continues after either follower is removed from service.
* Monitoring reaches both hosts only through the private monitoring network.

See [system requirements and ports](https://tempo.xyz/developers/docs/guide/node/system-requirements#ports), [validator monitoring](https://tempo.xyz/developers/docs/guide/node/validator-monitoring), and [node security](https://tempo.xyz/developers/docs/guide/node/security) for the related operational controls.
