Skip to content
Minotaur
+ 02 · Validator

Validator Configuration

Complete reference for all CLI arguments and environment variables used by the Minotaur validator.

Complete reference for all CLI arguments and environment variables used by the Minotaur validator (python -m minotaur_subnet.validator.main).

CLI Arguments

ArgumentDefaultDescription
--port9100HTTP listen port for the validator daemon
--epoch-seconds60Epoch duration in seconds for weight emission. Production uses 1200 (20 min) to match Bittensor’s weights_set_rate_limit.
--store-pathNonePath to the store.json persistence file. If omitted, uses in-memory store.
--tick-interval12.0BlockLoop tick interval in seconds (matches Ethereum block time)
--subtensor-urlNoneSubtensor WebSocket URL (e.g., wss://entrypoint-finney.opentensor.ai:443)
--netuid112Bittensor subnet UID
--wallet-nameNoneBittensor wallet name
--hotkey-nameNoneBittensor hotkey name
--validator-key""EVM private key (hex) for EIP-712 consensus signing
--validator-registry-addressNoneValidatorRegistry contract address. Falls back to VALIDATOR_REGISTRY_ADDRESS env. Source of canonical quorumBps and authorized validator EVM set.

Environment Variables

Bittensor identity

VariableDefaultDescription
NETUID112Subnet UID. Set to 1 for local testnet.
WALLET_NAMEBittensor wallet name (same as --wallet-name)
HOTKEY_NAMEBittensor hotkey name (same as --hotkey-name)
SUBTENSOR_URLSubtensor WebSocket endpoint (same as --subtensor-url)
VALIDATOR_HOTKEY_SS58Optional explicit hotkey override for solver-round metagraph leader election when the API service cannot load a local Bittensor wallet.

Simulation (Anvil forks)

The validator does not spawn Anvil. Operators run the three forks (Ethereum, Base, BT EVM) separately on ports 8545/8546/8547. The validator connects to them via the *_RPC_URL envs and uses the *_UPSTREAM_RPC_URL envs to advance each fork to the chain head between simulations.

VariableDefaultDescription
ANVIL_RPC_URLURL of the Ethereum Anvil fork the validator connects to. Usually http://localhost:8545 when Anvil runs on the same host.
BASE_RPC_URLURL of the Base Anvil fork (chain ID 8453). Usually http://localhost:8546.
BITTENSOR_EVM_RPC_URLURL of the BT EVM Anvil fork (chain ID 964). Usually http://localhost:8547.
BASE_SIM_RPC_URLfalls back to BASE_RPC_URLOptional override for the Base simulation fork if you split sim from quote.
ETH_UPSTREAM_RPC_URLUpstream Ethereum RPC (Alchemy / Infura) used to advance the local Anvil ETH fork to current head between simulations. Without it the fork stays frozen at startup.
BASE_UPSTREAM_RPC_URLUpstream Base RPC, same role as ETH_UPSTREAM_RPC_URL for the Base fork.
BITTENSOR_EVM_UPSTREAM_RPC_URLUpstream BT EVM RPC (typically https://lite.chain.opentensor.ai), same role for the BT EVM fork.

Consensus and signing

VariableDefaultDescription
VALIDATOR_PRIVATE_KEY""EVM private key (hex, with 0x prefix) for EIP-712 consensus signing (same as --validator-key).
VALIDATOR_AXON_URLPublic URL where this daemon serves the /identity endpoint, e.g. http://your-host:9100. The daemon signs this URL into its /identity attestation so other validators can verify the binding. If unset, /identity returns 503 and other validators can’t include you in their peer set.
VALIDATOR_REGISTRY_ADDRESSAddress of the on-chain ValidatorRegistry (same as --validator-registry-address). Holds the canonical quorumBps and the authorized validator EVM list; the daemon reads both at startup and refreshes once per epoch. See Quorum management.
VALIDATOR_REGISTRY_<chain_id>Per-chain form of the above (e.g. VALIDATOR_REGISTRY_8453 for Base, VALIDATOR_REGISTRY_964 for BT EVM). The daemon picks the right one based on CHAIN_ID. Preferred over the generic form in multi-chain deployments.
QUORUM_BPS_OVERRIDEEmergency / local-testnet escape hatch. Forces a local quorum value and skips the on-chain read. Production deployments should leave this unset so ValidatorRegistry.quorumBps() stays authoritative.
FOLLOWER_PROPOSAL_RESIMULATE1Set to 0 to skip independent re-simulation of leader proposals. UNSAFE in production — a compromised leader could fabricate simulation results. The daemon logs a startup warning when disabled.
CONSENSUS_REQUIRE_SIGNED_PROPOSALS1Set to 0 to accept unsigned proposals on /consensus/proposal. UNSAFE in production. The daemon logs a startup warning when disabled.

Leader election

VariableDefaultDescription
FORCE_LEADER""Set to "1" to force this validator to act as the leader, bypassing stake-based election. Useful for local testnet only.

Chain configuration

VariableDefaultDescription
CHAIN_ID31337Default EVM chain ID. Set to 8453 for Base, 964 for BT EVM, 31337 for local Anvil testnet.
SWAP_APP_ADDRESSOverride for the AppIntentBase-derived app contract address. Falls back to APP_INTENT_BASE_31337 for local testnet.
SUBNET_OWNER_HOTKEY / OWNER_HOTKEYSS58 of the subnet owner. Used for metagraph-driven role checks.

Logging

VariableDefaultDescription
LOG_LEVELINFOLog level: DEBUG, INFO, WARNING, ERROR. Read by api/server.py and the validator daemon at startup.

Docker Configuration (Local Testnet)

When running in the local testnet via Docker Compose, the validator is configured as follows:

docker-compose.yml YAML
validator:
command: >-
  python -m minotaur_subnet.validator.main
  --port 9100
  --store-path /data/store.json
environment:
  ANVIL_RPC_URL: http://anvil:8545
  BASE_RPC_URL: http://anvil-base:8546
  SUBTENSOR_URL: ws://subtensor:9944
  NETUID: "1"
  WALLET_NAME: validator
  HOTKEY_NAME: default
  VALIDATOR_PRIVATE_KEY: "${VALIDATOR_KEY_0}"  # see platform/local_testnet/.env.example
  QUORUM_BPS_OVERRIDE: "10000"
  CHAIN_ID: "31337"
  FORCE_LEADER: "1"
volumes:
  - testnet-config:/config:ro
  - store-data:/data
  - ~/.bittensor/wallets:/root/.bittensor/wallets:ro

Key points:

  • FORCE_LEADER=1 makes the validator act as leader immediately (no stake-based election on local testnet).
  • CHAIN_ID=31337 is the Anvil local chain ID.
  • NETUID=1 is the local subnet (not mainnet’s 112).
  • QUORUM_BPS_OVERRIDE is set on local testnet because there’s no real ValidatorRegistry contract on the Anvil fork. Do not set this in production.
  • The store volume (store-data) is shared between the API and validator containers.
  • Wallet directory is mounted read-only from the host.

Example: Production .env

.env SH
# Bittensor
NETUID=112
WALLET_NAME=my-validator
HOTKEY_NAME=my-hotkey
SUBTENSOR_URL=wss://entrypoint-finney.opentensor.ai:443

# Anvil forks (started separately — see Validator Quickstart Step 6)
ANVIL_RPC_URL=http://localhost:8545
BASE_RPC_URL=http://localhost:8546
BITTENSOR_EVM_RPC_URL=http://localhost:8547

# Upstreams that advance each Anvil fork to current head between sims
ETH_UPSTREAM_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_ALCHEMY_KEY
BASE_UPSTREAM_RPC_URL=https://base-mainnet.g.alchemy.com/v2/YOUR_ALCHEMY_KEY
BITTENSOR_EVM_UPSTREAM_RPC_URL=https://lite.chain.opentensor.ai

# Consensus — peer set comes from on-chain ValidatorRegistry + metagraph
# axon discovery. No VALIDATOR_PEERS env required.
VALIDATOR_PRIVATE_KEY=0xYOUR_EVM_PRIVATE_KEY
VALIDATOR_AXON_URL=http://your-public-host:9100
VALIDATOR_REGISTRY_8453=0x88a08d1105393EACE9B6f5ff678DbE508B8639aC
VALIDATOR_REGISTRY_964=0x0B5fE44e90515571761D86C28c4855F325EDE098

# Chain
CHAIN_ID=8453

# Logging
LOG_LEVEL=INFO

See the Network Reference for current mainnet contract addresses.

Precedence Rules

  1. CLI arguments win

    CLI arguments always take precedence over environment variables.

  2. --netuid default fallback

    For --netuid, the CLI value is used only if it differs from the default (112); otherwise the NETUID environment variable is checked.

  3. --validator-registry-address fallback chain

    Falls back to VALIDATOR_REGISTRY_ADDRESS, then VALIDATOR_REGISTRY_<CHAIN_ID> if neither is set on the CLI.

See also