Agent index (llms.txt) — fetch this first, then the page it names.

Relay rewards

x/relay is the chain's registry of Tor relays and exits, and the rule for paying them from the relay share of emission (10% of each epoch's maximum).

State today: the registry, the epoch report and the payout are all wired. x/relay's end block settles each reported epoch, with no message needed. What is still missing is on the operator side: no orama command registers a relay, bandwidth measurement (sbws) is not installed, and nothing in the repository has run against a real Tor network yet. This page describes what the code does.

Messages

MessageSigned byWhat it does
RegisterRelayThe operatorRegisters a relay: node_id, the relay's RSA fingerprint (20 bytes), whether it is an exit, and an ed25519 cross-certificate from the node identity over the node id and fingerprint
ReportEpochA reporterSends one chunk of a per-epoch report: observations per relay (consensus weight, flags, uptime fraction) and an inputs_root. Up to 32 chunks of 4,096 entries
UpdateReportersNobody directlyAccepted only inside a passed governance proposal that changes the reporter set

Reporters are the directory authorities' measurement software. A report from anyone not in the reporter set fails with ErrNotReporter. At most 128 reporters exist. The operator of a registered relay cannot be a reporter: RegisterRelay refuses a reporter's address and a reporter-set change that names a relay operator is refused.

The report window. Epoch e is reported on while the chain is in epoch e+1. A report for the epoch in progress, a future epoch, an epoch whose window has passed, or an epoch with no relay ceiling is refused. The end block then settles the oldest reported epoch once the chain is in epoch e+2, one epoch per block. An epoch nobody reported is never settled and takes no later report. A relay is bucketed by the /16 of its operator's node, or into a shared "unidentified" bucket when the /16 is not known.

How a reward is computed

For each relay fingerprint, take the median of the reported weights, uptime and exit flag across at least a quorum of reporters. A relay is paid only if it is registered, not jailed, its ed25519 id matches, its median uptime is at least 0.9, and its node is still live: a node that retired, was tombstoned or is jailed earns nothing until it is back.

amount = min(median weight, per_relay_cap)       x 2 if the relay is an exit
         then capped per operator and per /16
         then scaled down to the epoch's relay ceiling

The weight is in norama: the reporter reports the authority's measured bandwidth times 1,000,000 norama, so a measured value of 1,000 is 1 ORAMA for the epoch and the per-relay cap of 100 ORAMA is reached at 100,000. A relay no authority measured weighs 0 and earns nothing, and the measurement software is not installed anywhere yet (see below).

ParameterValue
min_reporters_quorum3
min_uptime_fraction0.9
exit_multiplier2
per_relay_cap100 ORAMA
per_operator_cap200 ORAMA
per_prefix16_cap200 ORAMA

The first epoch that reaches quorum only activates rewards and mints nothing. Later epochs mint at most that epoch's relay ceiling through x/emission and credit the operator's earnings. A failed quorum mints nothing, and calling settlement twice for the same epoch has no extra effect.

These values are plan launch defaults, not tuned numbers, and nothing can change them after genesis. The quorum of 3 is one reporter per initial directory authority, so one lying reporter cannot move the median.

How a payout is split

Relay pay goes through the same 90/5/5 service split as storage pay (SplitServicePayment in x/storage). Each operator's total for the epoch, after the caps, is split once:

ShareWhere it goes
90%The operator's earnings account. The operator also gets the rounding remainder, so the three parts sum exactly to the total
5%Burned from the relay module account
5%The storage_archive module account, and x/storage's archive_fund counter rises by the same amount (see Storage deals and History archive)

The payout rows and the epoch's minted amount stay gross, before the split.

What is missing

  • +There is no orama command to register a relay (MsgRegisterRelay is in the SDK) or to send a report by hand.
  • +The reporter, orama-global reporter, runs on a directory-authority host: orama global install --services chain,dirauth,reporter --tor-reporter-operator <orama1...> sets up its home, its authority-id and its unit, and the authority exports its own vote of each period to a directory the reporter reads. It sends each closed epoch to x/relay in chunks and drops an epoch whose report window has passed or that is already settled (ErrWindowClosed, ErrEpochSettled) instead of retrying it. Its hot key must be in x/relay's reporter set, which is a chain decision, not part of the install.
  • +Bandwidth measurement (sbws) is not built. Without a bandwidth file the authorities weight relays by what they claim, which a relay can inflate, and that is the reason consensus weight is not yet a trustworthy reward basis.

See Tor for what exists on the network side.

Queries

Params, Reporters, Relay and EpochResult are public through the gateway. The TypeScript SDK has relayParams, relayReporters, relay and relayEpochResult.