MANTIS is a Bittensor subnet (netuid 123) that rewards miners for embeddings which improve forecasting targets specified in config.py. Each challenge specifies a ticker, embedding dimension (dim), horizon (blocks_ahead), and a loss/scoring type (loss_func). Validators collect encrypted miner payloads, align embeddings with prices, compute per-hotkey salience, and set on-chain weights.
graph TD
subgraph "validator.py (orchestrator)"
direction LR
A[On sampled block] --> B[cycle.py];
B -->|payloads| C["datalog.append_step()"];
A --> D[Periodic checks];
D --> E["datalog.process_pending_payloads()"];
D --> F["datalog.get_training_data_sync()"];
F --> G["model.multi_salience()"];
G --> H["subtensor.set_weights()"];
end
subgraph "ledger.py (state)"
I[DataLog]
end
subgraph "External"
J[Miners]
K[Drand beacon]
L[Subtensor]
end
C --> I;
E --> I;
F -- reads --> I;
B -- downloads --> J;
E -- fetches --> K;
H -- writes --> L;
B -- reads commits --> L;
config.py– Defines network constants and theCHALLENGESlist.ledger.py– Contains theDataLogand per‑challengeChallengeDatastructures. It stores prices, decrypted embeddings and raw payloads and handles decryption & validation.validator.py– Orchestrates block sampling, payload collection, decryption, model training and weight setting.model.py– Computes per‑hotkey salience across challenges and produces a final hotkey→score distribution used for weights.cycle.py– Downloads miner payloads and validates commit URLs.comms.py– Performs asynchronous HTTP downloads (payload retrieval).bucket_forecast.py/hitfirst.py/utils.py– Implements LBFGS p/Q salience and HITFIRST salience (shared math lives inutils.py).
@dataclass
class ChallengeData:
dim: int
blocks_ahead: int
sidx: Dict[int, Dict[str, Any]]
class DataLog:
blocks: List[int]
challenges: Dict[str, ChallengeData]
raw_payloads: Dict[int, Dict[str, bytes]]Each challenge maps sample indices to prices and hotkey embeddings. The DataLog holds the per‑block payload queue and the challenge data.
-
Initialise –
validator.pyloads or creates aDataLogand syncs the metagraph. -
Collect – Every
SAMPLE_EVERYblocks the validator downloads encrypted payloads and current prices and appends them viadatalog.append_step. -
Decrypt –
datalog.process_pending_payloadsobtains Drand signatures once the 300‑block delay has elapsed, decrypts payloads, validates structure and stores embeddings. -
Prune – Periodically, inactive hotkeys are removed from challenge data via
datalog.prune_hotkeys. -
Evaluate – Periodically the validator builds a training snapshot from the
DataLog, runsmodel.multi_salience(), and converts the resulting hotkey salience into UID weights. A small fixed weight is reserved for young UIDs; the remainder is allocated by salience. For LBFGS challenges, p-only and Q-only saliences are combined 50/50 within the challenge. -
Bootstrap – On first run the validator attempts to download an initial datalog snapshot from
config.DATALOG_ARCHIVE_URLintoconfig.STORAGE_DIR.
- Time‑lock encryption prevents miners from seeing future prices before submitting.
- Embedded hotkey checks ensure decrypted payloads belong to the committing miner.
- Payload validation replaces malformed data with zero vectors.
- Download size limits mitigate denial‑of‑service attacks.
- Commit host: Cloudflare R2 only (
*.r2.devor*.r2.cloudflarestorage.com). - Object key: Path must be exactly your hotkey (no directories or extra segments).
- Size limit: Payloads must be ≤ 25 MB.
- Format: Only V2 JSON payloads are accepted. They include fields like
v,round,hk,owner_pk,C,W_owner,W_time,binding, andalg.
- Swap out the salience algorithm by editing
model.py. - Adjust challenges or hyperparameters in
config.py. - Modify storage or decryption logic in
ledger.py.
Released under the MIT License © 2024 MANTIS.
-
Decrypt –
datalog.process_pending_payloadsobtains Drand signatures once the 300‑block delay has elapsed, decrypts payloads, validates structure and stores embeddings. -
Prune – Periodically, inactive hotkeys are removed from challenge data via
datalog.prune_hotkeys. -
Evaluate – Every
TASK_INTERVALblocks the validator builds training data, computes salience scores and normalises weights on‑chain. A small fixed weight is reserved for young UIDs; the remainder is allocated by salience. For LBFGS challenges, classifier and Q saliences are combined 50/50 within the challenge, then challenge-level weights fromconfig.pyare applied for multi-challenge aggregation. -
Bootstrap – On first run the validator attempts to download an initial datalog snapshot from
config.DATALOG_ARCHIVE_URLintoconfig.STORAGE_DIR.
- Time‑lock encryption prevents miners from seeing future prices before submitting.
- Embedded hotkey checks ensure decrypted payloads belong to the committing miner.
- Payload validation replaces malformed data with zero vectors.
- Download size limits mitigate denial‑of‑service attacks.
- Commit host: Cloudflare R2 only (
*.r2.devor*.r2.cloudflarestorage.com). - Object key: Path must be exactly your hotkey (no directories or extra segments).
- Size limit: Payloads must be ≤ 25 MB.
- Format: Only V2 JSON payloads are accepted. They include fields like
v,round,hk,owner_pk,C,W_owner,W_time,binding, andalgas described in the payload guide.
Project dependencies are declared in pyproject.toml (PEP 621). Key libraries include bittensor, xgboost, requests, aiohttp, torch, and scikit-learn.
See MINER_GUIDE.md for setup and lbfgs_guide.md for 17-dim LBFGS embeddings.
- Swap out the salience algorithm by editing
model.py. - Adjust challenges or hyperparameters in
config.py. - Modify storage or decryption logic in
ledger.py.
Released under the MIT License © 2024 MANTIS.