synth-subnet

Validator

Table Of Contents

1. Requirements

Back to top ^

2. Setup

Step 1: Clone the repository

git clone https://github.com/synthdataco/synth-subnet.git

Step 2: Change directory to the project root

cd ./synth-subnet

Step 3: Add the required repositories

sudo add-apt-repository ppa:deadsnakes/ppa

⚠️ NOTE: The deadsnakes repository, while unofficial, it is hugely popular and used by many Python projects.

Step 4: Install Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Step 5: Install the dependencies

sudo apt update && \
  sudo apt install nodejs npm python3.11 pkg-config

Step 6: Install PM2

sudo npm install pm2 -g

Step 7: Install the Python environment

sudo apt install python3.11-venv

Step 8: Create a new Python environment

python3.11 -m venv bt_venv

Step 9: Activate and switch to the newly created Python virtual environment

source bt_venv/bin/activate

This should activate the bt_venv environment and you should see the command line prefixed with (bt_venv).

Step 10: Install local Python dependencies

With the Python virtual environment active, install the Python dependencies:

pip install -r requirements.txt

3. Create a Wallet

💡 TIP: For a more extensive list of the Bittensor CLI commands see here.

Step 1: Activate the Python virtual environment

If you haven’t already, ensure you are running from the Python virtual environment:

source bt_venv/bin/activate

Step 2: Create the cold/hot wallets

btcli wallet create \
  --wallet.name validator \
  --wallet.hotkey default

🚨 WARNING: You must ensure your wallets have enough TAO (0.1 should be sufficient) to be start mining. For testnet, you can use the btcli wallet faucet.

Step 3: Register wallet

Acquire a slot on the Bittensor subnet by registering the wallet:

btcli subnet register \
  --wallet.name validator \
  --wallet.hotkey default \
  --netuid 50

if you want to try it on testnet first, run the following command:

btcli subnet register \
  --wallet.name validator \
  --wallet.hotkey default \
  --network test \
  --netuid 247
btcli root register --wallet.name validator --wallet.hotkey default
  1. Stake:
btcli stake add \
  --wallet.name validator \
  --wallet.hotkey default \
  --netuid 50

for testnet:

btcli stake add \
  --wallet.name validator \
  --wallet.hotkey default \
  --network test \
  --netuid 247

Step 4: Verify wallet registration (optional)

Check the wallet has been registered:

btcli wallet overview \
  --wallet.name validator \
  --wallet.hotkey default

You can also check the network metagraph:

btcli subnet metagraph \
  --netuid 50

for testnet it’s:

btcli subnet metagraph \
  --network test \
  --netuid 247

Back to top ^

4. Run the Validator

Step 1: Database setup

Step 2: Activate the Python virtual environment

source bt_venv/bin/activate

Step 3: Run database migrations

alembic upgrade head

Step 4: Start PM2 with the validator config

pm2 start validator.config.js

for testnet use:

pm2 start validator.test.config.js

Step 5: Check the validator is running (optional)

pm2 list

Back to top ^

5. Options

5.1. Common Options

--axon.port INTEGER

The external port for the Axon component. This port is used to communicate to other neurons.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--axon.port 8091",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --axon.port 8091

for testnet it’s:

pm2 start validator.test.config.js -- --axon.port 8091

Back to top ^

--sma.low.days INTEGER

The window for the simple moving average (SMA) of the validator scores for the 24h prompt.

Default: 10

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--sma.low.days 10",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --sma.low.days 10

Back to top ^

--sma.high.days INTEGER

The window for the simple moving average (SMA) of the validator scores for the 1h prompt.

Default: 3

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--sma.high.days 3",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --sma.high.days 3

Back to top ^

--softmax.low.beta FLOAT

Negative beta to give higher weight to lower scores for the 24h prompt

Default: -0.1

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--softmax.low.beta -0.1",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --softmax.low.beta -0.1

Back to top ^

--softmax.high.beta FLOAT

Negative beta to give higher weight to lower scores for the 1h prompt

Default: -0.2

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--softmax.high.beta -0.2",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --softmax.high.beta -0.2

Back to top ^

--logging.debug

Turn on bittensor debugging information.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--logging.debug",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --logging.debug

Back to top ^

--logging.info

Turn on bittensor info level information.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--logging.info",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --logging.info

Back to top ^

--logging.trace

Turn on bittensor trace level information.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--logging.trace",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --logging.trace

Back to top ^

--netuid INTEGER

The netuid (network unique identifier) of the subnet within the root network, (e.g. 247).

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--netuid 247",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --netuid 247

Back to top ^

--neuron.axon_off BOOLEAN

This will switch off the Axon component.

Default: false

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.axon_off true",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.axon_off true

Back to top ^

--neuron.device TEXT

The name of the device to run on.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.device cuda",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.device cuda

Back to top ^

--neuron.dont_save_events BOOLEAN

Whether events are saved to a log file.

Default: false

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.dont_save_events true",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.dont_save_events true

Back to top ^

--neuron.disable_set_weights BOOLEAN

Disables setting weights.

Default: false

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.disable_set_weights true",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.disable_set_weights true

Back to top ^

--neuron.epoch_length INTEGER

The default epoch length (how often we set weights, measured in 12 second blocks), (e.g. 100).

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.epoch_length 100",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.epoch_length 100

Back to top ^

--neuron.events_retention_size TEXT

The events retention size.

Default: 2147483648 (2GB)

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.events_retention_size 2147483648",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.events_retention_size 2147483648

Back to top ^

--neuron.name TEXT

Trials for this neuron go in neuron.root / (wallet_cold - wallet_hot) / neuron.name.

Default: validator

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.name validator",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.name validator

Back to top ^

--neuron.sample_size INTEGER

The number of validators to query in a single step.

Default: 50

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.sample_size 50",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.sample_size 50

Back to top ^

--neuron.timeout INTEGER

The maximum timeout in seconds of the validator neuron response, (e.g. 120).

Default: -

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.timeout 120",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.timeout 120

Back to top ^

--neuron.nprocs INTEGER

The number of processes to run for the validator dendrite, (e.g. 2).

Default: 2

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.nprocs 2",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.nprocs 2

Back to top ^

--neuron.vpermit_tao_limit INTEGER

The maximum number of TAO allowed that is allowed for the validator to process validator response, (e.g. 1000).

Default: 4096

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--neuron.vpermit_tao_limit 1000",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --neuron.vpermit_tao_limit 1000

Back to top ^

--wallet.hotkey TEXT

The hotkey of the wallet.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--wallet.hotkey default",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --wallet.hotkey default

Back to top ^

--wallet.name TEXT

The name of the wallet to use.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--wallet.name validator",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --wallet.name validator

Back to top ^

5.2. Logging Options

--gcp.log_id_prefix TEXT

String to set the GCP log ID prefix.

Example:

// validator.config.js
module.exports = {
  apps: [
    {
      name: "validator",
      interpreter: "python3",
      script: "./neurons/validator.py",
      args: "--gcp.log_id_prefix my_validator_name",
      env: {
        PYTHONPATH: ".",
      },
    },
  ],
};

Alternatively, you can add the args directly to the command:

pm2 start validator.config.js -- --gcp.log_id_prefix my_validator_name

for testnet it’s:

pm2 start validator.test.config.js -- --gcp.log_id_prefix my_validator_name

Back to top ^

6. Appendix

6.1. Useful Commands

Command Description
pm2 stop validator Stops the validator.
pm2 logs validator --lines 100 View the logs of the validator.

Back to top ^

Run the validator with Docker

You can run the validator with Docker and docker compose.

  1. Run this command:
cp .env.validator .env.validator.local
  1. Optionally edit “POSTGRES_PASSWORD” in .env.validator.local file. Don’t change “POSTGRES_DB”
  2. Optionally edit entrypoint-validator.sh file, especially log_id_prefix if you want to forward the log to a GCP Log Bucket. For this you need the credential file and environment variable GOOGLE_APPLICATION_CREDENTIALS set to the path of this file
  3. Install docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
  1. Setup your bittensor wallet
  2. Start: docker compose up --build --remove-orphans --force-recreate -d
  3. Update with the same command
  4. Read the logs: docker compose logs -f

Useful commands

Useful SQL queries

select mp.format_validation, vr.start_time, miners.miner_uid, process_time
from miner_predictions mp
join validator_requests vr on mp.validator_requests_id = vr.id
join miners on miners.id = mp.miner_id
order by start_time desc
limit 500;
SELECT
	MS.ID,
	MP.VALIDATOR_REQUESTS_ID,
	MS.MINER_PREDICTIONS_ID,
	VR.START_TIME,
	VR.ASSET,
	MS.SCORED_TIME,
	MINERS.MINER_UID,
	(MS.SCORE_DETAILS_V3 -> 'total_crps')::FLOAT AS CSRP,
	MS.PROMPT_SCORE_V3
FROM
	MINER_SCORES MS
	JOIN MINER_PREDICTIONS MP ON MP.ID = MS.MINER_PREDICTIONS_ID
	JOIN MINERS ON MINERS.ID = MP.MINER_ID
	JOIN VALIDATOR_REQUESTS VR ON VR.ID = MP.VALIDATOR_REQUESTS_ID
WHERE
	MS.SCORED_TIME > NOW()::DATE - 10
ORDER BY
	MS.ID DESC;
delete from miner_predictions
using validator_requests
where miner_predictions.validator_requests_id = validator_requests.id
and validator_requests.start_time < now()::DATE - 20;