Skip to content

Latest commit

 

History

History
1061 lines (830 loc) · 21.1 KB

File metadata and controls

1061 lines (830 loc) · 21.1 KB

Validator

Table Of Contents

1. Requirements

Back to top ^

2. Setup

Step 1: Clone the repository

git clone https://github.com/mode-network/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.10 pkg-config

Step 6: Install PM2

sudo npm install pm2 -g

Step 7: Install the Python environment

sudo apt install python3.10-venv

Step 8: Create a new Python environment

python3.10 -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

  • Create a postgres database with the name "synth"
  • Rename the ".env.example" in the root of the repo to ".env"
  • Update the .env file with your database credentials.

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 ^

--ewma.cutoff_days INTEGER

The number of days against which to run the moving average, (e.g. 1).

Default: 2

Example:

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

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

pm2 start validator.config.js -- --ewma.cutoff_days 1

for testnet it's:

pm2 start validator.test.config.js -- --ewma.cutoff_days 1

Back to top ^

--ewma.half_life_days FLOAT

The half-life in days for the exponential decay, (e.g. 2.0).

Default: 1.0

Example:

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

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

pm2 start validator.config.js -- --ewma.half_life_days 2.0

Back to top ^

--softmax.beta FLOAT

Negative beta to give higher weight to lower scores.

Default: -0.002

Example:

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

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

pm2 start validator.config.js -- --softmax.beta -0.003

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. 8).

Default: 8

Example:

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

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

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

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 ^

--neuron.use_multiprocess INTEGER

Wether to use multiple processes for the validator dendrite.

Default: 1

Example to disable multiprocess:

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

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

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

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

  • Enter into the postgres container: docker exec -it postgres bash
  • Enter into psql: psql -U postgres
  • List databases: \l. You should see "synth" database
  • Connect to database: \c synth

Useful SQL queries

  • Check the validator requests: select * from validator_requests order by start_time desc limit 500;
  • Check the miner predictions:
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;
  • Check the miner scores:
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;
  • Check the predictions table size: SELECT pg_size_pretty(pg_total_relation_size('miner_predictions')) as size;
  • /!\ Delete old predictions
delete from miner_predictions
using validator_requests 
where miner_predictions.validator_requests_id = validator_requests.id
and validator_requests.start_time < now()::DATE - 20;