The official validator implementation for Cartha subnet (SN35). Score miners based on their USDC liquidity positions, compute weights, and publish them to the Bittensor network—all with built-in on-chain event replay and robust scoring algorithms.
Cartha Validator provides a complete, production-ready solution for running a validator on the Cartha subnet:
- 📊 Intelligent Scoring - Score miners based on locked USDC amounts, lock duration, pool weights, and expired pool filtering
- 🔄 Weekly Epoch Management - Automatic weekly epoch detection (Friday 00:00 UTC) with daily expiry checks
- 🔒 Validator Whitelist - Only whitelisted validators can query verified miners (contact subnet owner to be added)
# Install dependencies
uv sync
# Run a dry-run to see computed weights
uv run python -m cartha_validator.main \
--wallet-name cold \
--wallet-hotkey hot \
--netuid 35 \
--dry-run
# Run in production mode (publishes weights)
uv run python -m cartha_validator.main \
--wallet-name cold \
--wallet-hotkey hot \
--netuid 35- Python 3.11
uvfor dependency management- Bittensor wallet (coldkey and hotkey)
- Access to Cartha verifier instance
- Validator Whitelist: Your validator hotkey must be whitelisted by the subnet owner
The validator operates on a weekly epoch cycle (Friday 00:00 UTC → Thursday 23:59 UTC):
- Weekly Epoch Detection - Detects the current weekly epoch (Friday 00:00 UTC boundary)
- Validator Whitelist Check - Verifies that the validator hotkey is whitelisted (required to query verified miners)
- Fetch Verified Miners - Retrieves the epoch-frozen miner list from the verifier for the current weekly epoch
- Fetch Deregistered Hotkeys - Retrieves list of deregistered hotkeys from the verifier (all positions scored as 0)
- Daily Expiry Checks - Performs daily checks during the week to filter out expired pools and deregistered hotkeys
- Score Liquidity - Calculates scores based on:
- Locked USDC amounts (6 decimals)
- Lock duration (with Model-1 boost)
- Pool weights (configurable per pool)
- Expired pool filtering (pools with
expires_atin the past are excluded)
- Cache & Publish - Normalizes scores to weights, caches them for the week, and publishes via
set_weightsto Bittensor every Bittensor epoch (tempo blocks) - Submit Rankings - Automatically submits ranking data to the leaderboard API after successfully publishing weights (if leaderboard API is configured)
Note: The verifier handles all on-chain validation and RPC queries. Validators do not need to configure RPC endpoints.
The validator uses a direct scoring system that preserves competitive differences:
-
Raw Score Calculation:
raw = poolWeight * amount * min(lockDays, maxLockDays) / maxLockDays -
Normalized Weights:
weight = raw / sum(all_raw_scores)
Scores are used directly without exponential normalization, ensuring that differences in liquidity positions translate proportionally to weight distribution.
- Command Reference - Complete documentation for all command-line arguments
- Architecture Guide - Deep dive into validator internals and design
- Testnet Setup - Step-by-step testnet deployment guide
- Version Control - Version management and CI/CD workflows
- Feedback & Support - Get help and provide feedback
Cartha Validator enforces strict security policies:
- Validator Whitelist - Only whitelisted validators can query verified miners. Non-whitelisted validators will be rejected with a clear error message directing them to contact the subnet owner.
- Epoch Freezing - Uses verifier's epoch-frozen snapshots to prevent manipulation
- Verifier-Based Validation - The verifier handles all on-chain validation and RPC queries, ensuring consistent and secure verification
- Registration Validation - Checks that the validator hotkey is registered before running
- Deregistered Hotkey Filtering - Automatically scores all positions for deregistered hotkeys as 0
- Expired Pool Filtering - Automatically filters out pools that have expired (
expires_atin the past) - Version Control - Validators must meet the minimum version requirement set on-chain
- Epoch Duration: Friday 00:00 UTC → Thursday 23:59 UTC (7 days)
- Weight Calculation: Computed once per week at epoch start
- Weight Publishing: Cached weights are republished every Bittensor epoch (tempo blocks) throughout the week
- Daily Expiry Checks: Validator checks for expired pools daily and updates weights accordingly
- Daemon Mode: Runs continuously, checking for new epochs every
--poll-intervalseconds (default: 300s = 5 minutes) - Metagraph Syncing: Automatically syncs metagraph every 100 blocks to stay current
- Bittensor Epoch Integration: Publishes cached weights every Bittensor epoch (tempo) during the weekly cycle
- Startup Behavior: On startup, always fetches and publishes weights (bypasses cooldown)
- If the requested epoch isn't frozen yet, the verifier returns the last frozen epoch
- Validator automatically uses the frozen epoch data for consistency
- Logs epoch fallback events for transparency
Cartha Validator includes automated version management and update capabilities:
- Semantic Versioning: Uses semantic versioning (major.minor.patch) in
pyproject.toml - CI/CD Enforcement: Version bumps are required when merging from
stagingtomain - Version Utilities: Helper scripts for version management:
# Get current version python scripts/get_version.py # Bump version (major, minor, or patch) python scripts/bump_version.py patch python scripts/bump_version.py minor python scripts/bump_version.py major
The validator includes an automated update system that:
- Checks GitHub Releases: Automatically checks for new releases on GitHub
- PM2 Process Management: Manages validator process via PM2 (survives SSH disconnect)
- Automatic Updates: Pulls latest code, installs dependencies, and restarts validator
- Environment Validation: Validates
.envfile before restarting - Failure Handling: Keeps validator running on current version if update fails
# One-time installation
cd cartha-validator
chmod +x scripts/install.sh
./scripts/install.shThis will:
- Install PM2 globally
- Install Python dependencies
- Create PM2 ecosystem configuration
- Set up PM2 to start on system boot
- Start both validator manager and validator processes
# Check status of both processes
pm2 status
# View validator logs locally
pm2 logs cartha-validator
# View manager logs
pm2 logs cartha-validator-manager
# Manual restart (if needed)
pm2 restart cartha-validator
# Stop both processes
pm2 stop all
# Start both processes
pm2 start ecosystem.config.jsNote: The validator manager automatically handles updates. You typically only need to interact with PM2 for manual restarts or troubleshooting.
Configure the auto-updater via scripts/update_config.yaml:
github_repo: "General-Tao-Ventures/cartha-validator"
check_interval: 3600 # Check every hour
pm2_app_name: "cartha-validator"See scripts/update_config.yaml for all configuration options.
Validators (local access):
pm2 logs cartha-validator
pm2 logs cartha-validator --err # Error logs only
pm2 logs cartha-validator-manager # Manager logs# Run tests
make test
# Format code
uv run ruff format
# Type check
uv run mypy cartha_validator- cartha-verifier - The API service that provides epoch-frozen miner lists
- cartha-cli - Miner tooling for registration and lock proof submission
Made with ❤ by GTV