Mining and Validating on Localnet
This page walks through mining and validating on a local Bittensor network. It covers how to register a neuron on a subnet, then run the miner and validator scripts to begin earning emissions.
For mining and validating on the Bittensor mainnet, see Mining in Bittensor and Validating in Bittensor.
Prerequisites
Before continuing with the rest of this tutorial, make sure you've completed the following:
- Deploy a Subtensor chain locally
- Provision wallets for the subnet creator, miner, and validator users for this tutorial.
- Created and started a subnet to enable emissions.
This guide uses Opentensor's subnet template repo. The repo provides a minimal implementation for building a custom subnet on the Bittensor network and includes the core logic for the miner and validator.
1. Register the neuron hotkeys
To participate in a subnet, you must first register a hotkey on it. This registration assigns the wallet a unique identifier (UID), which is required to interact with and receive emissions from the subnet.
To register the hotkey, run the following command in your terminal, replacing NETUID, WALLET_NAME, and WALLET_HOTKEY with the target subnet ID, the name of the wallet, and the associated hotkey, respectively, as shown:
btcli subnets register --netuid NETUID \
--wallet-name WALLET_NAME \
--hotkey WALLET_HOTKEY \
--network ws://127.0.0.1:9945
You will be prompted to confirm the registration fee and enter your wallet password to authorize the transaction.
Show Sample Output
Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:88
Using the specified network local from config
Register to netuid: 2
Network: local
Netuid ┃ Symbol ┃ Cost (Τ) ┃ Hotkey ┃ Coldkey
━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2 │ β │ τ 0.0985 │ 5FErfAJc3Wf32TVLQTtM....TRTrgMF4sjYWfq49oMCxXxqS │ 5Gxhv5iZGBvvR6YJeEdLmvZ7hS....dHc43fLqMVkhki7j4
────────┼────────┼──────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────
│ │ │ │
Your balance is: 99,999.9000 τ
The cost to register by recycle is 0.0985 τ
Do you want to continue? [y/n] (n): y
Enter your password:
Decrypting...
Balance:
99,999.9000 τ ➡ 99,999.8015 τ
✅ Registered on netuid 3 with UID 2
Repeat the registration process for both the miner and validator hotkeys.
To confirm the registration of your hotkeys in the subnet, run the following command in your terminal:
btcli subnet show --netuid NETUID --network ws://127.0.0.1:9945
The command returns detailed information about a subnet including its registered neurons and their state.
Show Sample Output
Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:89
Subnet 2: New subnet
Network: local
UID ┃ Stake (β) ┃ Alpha (β) ┃ Tao (τ) ┃ Dividends ┃ Incentive ┃ Emissions (β) ┃ Hotkey ┃ Coldkey ┃ Identity
━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━
0 │ 5.04 β │ 5.04 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 9.017303 β │ 5DFZTw │ 5Dc1Qu │ (*Owner controlled)
1 │ 0.00 β │ 1.00 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5FErfA │ 5GxHV5 │ ~
2 │ 0.00 β │ 1.00 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5GRLEv │ 5EnNgi │ ~
─────┼───────────┼───────────┼─────────┼───────────┼───────────┼───────────────┼────────┼─────────┼─────────────────────
│ 5.04 β │ 5.04 β │ 0.00 β │ 0.000 │ │ 9.017303 β │ │ │
Subnet 2: New subnet
Owner: 5Dc1Qu2pDfWuDzt3c5wJV2LxRXAmVqZYsAib72e59H3vnRVn
Rate: 1.0056 τ/β
Emission: τ 0.0000
TAO Pool: τ 1.10k
Alpha Pool: 1.10 β
Tempo: 8/360
Registration cost (recycled): τ 0.0845
2. Acquire validator permit
To qualify as a validator on a subnet, a registered node must have a validator permit. This permit allows nodes to submit miner evaluations and set weights on a subnet. For more information, see validator permits.
To get validator permits on the demo subnet, you need to stake sufficient TAO to the validator hotkey. To do this, run the following command in the terminal:
btcli stake add --netuid NETUID \
--wallet-name WALLET_NAME \
--hotkey WALLET_HOTKEY \
--partial \
--network ws://127.0.0.1:9945
When running a local chain in fast-blocks mode, we recommend using the --no-mev-protection flag when executing this command.
Replace NETUID, WALLET_NAME, and WALLET_HOTKEY with the target subnet ID, the name of the wallet, and the associated hotkey, respectively.
Once you've staked enough TAO to the validator hotkey, the validator becomes eligible to submit evaluations and set weights on the subnet. You can verify that the validator has been granted a permit using any of the following methods:
- Using BTCLI
- Using Bittensor SDK
Run the following command in the terminal:
btcli wallet overview --wallet.name WALLET_NAME --network ws://127.0.0.1:9945
Replace the WALLET_NAME with the name of the validator wallet.
Show Sample Output
Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:88
Using the specified network local from config
Wallet
test-validator : 5Gxhv5iZGBvvR6YJeEd...bE6FdHc43fLqMVkhki7j4
Network: local
Subnet: 2: New subnet β
COLDKEY HOTKEY UID ACTIVE STAKE(β) RANK TRUST CONSENSUS INCENTIVE DIVIDENDS EMISSION(… VTRUST VPE… UPDAT… AXON HOTKEY_SS58
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
test-validator test-validator 1 False 287.57 0.00 0.00 0.00 0.00 0.00 38841066.… 0.00 * 5908 none 5FErfAJc3W
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 287.57 β 0.0000 0.0000 0.0000 0.0000 0.0000 ρ38841066 0.0000
Wallet free balance: 99,994.3638 τ
If the validator wallet has a validator permit, an asterisk (*) is shown under the VPERMIT column for the corresponding subnet in the response table.
This documentation is built against Bittensor Python SDK v10. For documentation built against SDK 9.12, see SDK 9.12 Archive.
Input the following lines in your Python environment, replacing NETUID, WALLET_NAME, and WALLET_HOTKEY with the target subnet ID, the name of the validator wallet, and its associated hotkey, respectively.
import bittensor as bt
network=bt.Subtensor(network="local")
subnet = network.metagraph(NETUID)
wallet = bt.Wallet( name = 'WALLET_NAME', hotkey = 'HOTKEY' )
my_uid = subnet.hotkeys.index( wallet.hotkey.ss58_address )
print(f'Validator permit: {subnet.validator_permit[my_uid]}')
The command outputs True or False depending on whether the validator hotkey has a permit.
On localnet subnets, competition for permits is typically minimal. After staking TAO to the validator hotkey, the neuron should become eligible for a validator permit. If it does not yet have one, wait until the end of the subnet’s tempo.