Tutorial

Verify pins

A verifier checks that pinners really serve the albums they offered. When a draw puts you on a check, your verifier dials the pinner’s node, fetches one drawn piece, commits to what it saw, and reveals the answer about 15 minutes later. Every one of the three verifiers who reveals is paid 1 TTT once the check has a majority answer.

The verifier is a Docker container. It runs on any always-on machine with Docker. The desktop app is not involved. Being in the majority is not required to be paid.

What you need

A machine that stays onLinux, macOS, or Windows with Docker and Docker Compose 2.24 or newer. Outbound internet only. No port forwarding
A new walletUsed only for this. Step 2 creates it
50 TTTThe stake. For your first 50 TTT, ask @xphorm:matrix.org, Torrentech’s admin, in #torrentech:matrix.org
A little ETH on Arbitrum OneGas for the join, and for every commit, reveal, and settlement
An Arbitrum One RPC (optional)The default is the public https://arb1.arbitrum.io/rpc. Your own RPC is more reliable

The deposit can be taken

All 50 TTT

The stake is lost for any of these:

  • Two different commits on one check. This happens when two copies of the verifier run with the same key. Run one copy per key.
  • A reveal that does not match the commit.
  • A commit that is never revealed. The reveal needs a salt the verifier keeps in its data volume. Losing that volume between commit and reveal, or stopping the verifier for longer than the reveal window, leaves the commit unrevealed. Anyone can then claim the fault.

An honest answer that loses the vote is not punished. After a slash you can stake again.

1. Get the compose file

mkdir torrentech-verifier && cd torrentech-verifier
curl -fsSLO https://www.torrentech.org/verifier/docker-compose.yml

It runs the public image registry.gitlab.com/torrentech/torrentech-verifier:latest with the Arbitrum One contract addresses already set. No login is needed to pull it.

2. Create the wallet

This writes a new key straight into verifier.env and never prints it:

(umask 077; docker run --rm registry.gitlab.com/torrentech/torrentech-verifier:latest \
  node -e "console.log('VERIFIER_CYCLE_PRIVATE_KEY=' + require('ethers').Wallet.createRandom().privateKey)" \
  > verifier.env)

verifier.env is the only place the key lives. It is readable by you alone (-rw-------). Back it up somewhere safe; without it the stake cannot be withdrawn. Do not paste it into chat, and do not share docker compose config output, which prints it.

To use an existing wallet instead, write one line into verifier.env yourself: VERIFIER_CYCLE_PRIVATE_KEY=0x<64 hex>, then chmod 600 verifier.env.

3. Turn on checking

Create .env next to the compose file:

printf 'VERIFIER_DIAL=1\nVERIFIER_INTERVAL_SECONDS=300\n' > .env
SettingWhy
VERIFIER_DIAL=1Dials the pinner. Without it every answer would be “could not reach”
VERIFIER_INTERVAL_SECONDS=300One pass every 5 minutes. The commit window is 15 minutes, so keep this well under 900
VERIFIER_RPC_URL=… (optional)Your own Arbitrum One RPC

These go in .env, not in verifier.env. Compose reads .env to fill in the settings; verifier.env holds only the key.

4. Fund and join

See the wallet address and balances:

docker compose run --rm verifier node scripts/verifier-stake.js status
Wallet: 0x…
Stake: none
Enrolled: no
TTT balance: 0.0 (stake is 50.0)
ETH for gas: 0.0

Send the address to @xphorm:matrix.org in #torrentech:matrix.org for the 50 TTT, and put a little ETH on Arbitrum One on it. When status shows both, join:

docker compose run --rm verifier node scripts/verifier-stake.js join

join approves 50 TTT to VerifierRegistry, stakes, and enrolls on VerifierAssigner. It skips a step that is already done and prints each transaction hash. It stops with a plain message when the wallet is short of TTT or has no ETH for gas. Run status again: Stake: active, Enrolled: yes.

You enter draws from the first round (30 minutes) that starts after you enroll.

5. Run it

docker compose up -d
docker compose logs -f

The container restarts after a crash and keeps its data in the torrentech-verifier_verifier-data volume. Each pass looks at the recent checks, including the many you are not on, and prints a line for each one it acted on or skipped:

LineMeaning
commit sent 0x…You are on a check and committed your answer
reveal sent 0x…The answer is revealed. Pay follows once the check has a majority
settle-verifier sent …Your verifier settled 1 TTT for a committee member, you or another
settle-pin sent …Your verifier settled a pinner’s 5 TTT for a passed check
settle-moderation sent …Your verifier settled a moderator’s review credit
slash sent …Another member committed and never revealed; your verifier reported it
skip not-committee …A check you are not on. Normal
shadow …Your verifier’s own reading of a recent check, compared with the committee’s answer. Information only
skip reward-budget …Today’s verifier pool is spent. It refills at 00:00 UTC
skip no-dial …VERIFIER_DIAL=1 is missing from .env

6. Pay

RuleLive behavior
Per check1 TTT to each member who revealed and was not slashed, once the three have a majority answer
DrawsUp to 24 checks every 30 minutes, three verifiers each, picked at random from the active pool. A verifier is never put on its own pins
Daily pool5,000 TTT for all verifiers together. One wallet can receive at most 5,000 TTT a day across all pay
PayoutThe verifier sends the settlement itself. There is no claim button

Updating

docker compose pull
docker compose up -d

The data volume carries pending reveals across the restart. Keep the downtime short: a commit must still be revealed inside its window.

Leaving

  1. Check that nothing is waiting to be revealed. The last commit sent in docker compose logs should have its reveal sent after it. If not, wait up to 30 minutes.
  2. Start unbonding. You leave the pool at once:
    docker compose run --rm verifier node scripts/verifier-stake.js leave
  3. Stop the verifier with docker compose down. Leave out -v; the volume is harmless to keep.
  4. One day later, take the stake back. withdraw says when it opens if you are early:
    docker compose run --rm verifier node scripts/verifier-stake.js withdraw

To come back later, run join again.

Troubleshooting

Help: #torrentech:matrix.org.