7.2 Validator Logs
Live validator log output from C-SWON testnet (netuid 26). These logs demonstrate the evaluation pipeline stages that fire each tempo cycle.
Testnet State (Block 6804608)
All 14 registered nodes are SERVING on-chain at 136.185.198.230:
- 10 miners on ports 8091–8100
- 3 validators on ports 8101–8103
- 3 validators have submitted weights on-chain
- Total subnet emission: 296.02 ב
Stage 1: VRF Task Selection
Actual validator log output — two different task types selected in consecutive cycles:
2026-03-31 19:19:53.075 | INFO | Selected task: code_001 type=code synthetic=False at block 6804728
2026-03-31 19:20:18.083 | INFO | Selected task: code_012 type=code synthetic=False at block 6804729
2026-03-31 19:23:10.667 | INFO | Selected task: syn_739d3947 type=code synthetic=True at block 6804744
Note: the third task is a synthetic injection (syn_739d3947), proving the 15–20% synthetic rate is active.
Two validators at the same block select different tasks via deterministic VRF:
import hashlib
# Validator 1 (vali/default, hotkey 5GYi8...nZz8)
task_1 = int.from_bytes(
hashlib.sha256(b"5GYi8aRkGCqQH8YScK4yYDkfZx6DtLVz3G5WJigwwbennZz8:6804491").digest(),
'big'
) % 50 # → 41 → task agent_001
# Validator 2 (vali/vali2, hotkey 5EJTJaqf...waF)
task_2 = int.from_bytes(
hashlib.sha256(b"5EJTJaqfvQovvEKVssXQ6bAfYbJKw71NtktBtHhz1EAiLwaF:6804491").digest(),
'big'
) % 50 # → different task index
Same block, different tasks. Copy attacks infeasible.
Stage 2: Miner Query (Live Log)
Actual validator log — queried 12 miners, received responses, validated, scored:
2026-03-31 19:20:13.309 | INFO | Received 12 responses from 12 miners
2026-03-31 19:20:13.309 | INFO | Validated 1 responses
2026-03-31 19:20:13.310 | INFO | Scored 1 miners: mean=0.1000
2026-03-31 19:22:13.221 | INFO | Received 12 responses from 12 miners
2026-03-31 19:22:13.221 | INFO | Validated 1 responses
2026-03-31 19:22:13.222 | INFO | Scored 1 miners: mean=0.1000
Actual miner log — received task, built workflow DAG, returned plan:
2026-03-31 19:20:13.225 | INFO | Received task: code_001 type=code
2026-03-31 19:20:13.225 | INFO | Returning workflow plan for code_001: 1 nodes, est_cost=0.0010τ
2026-03-31 19:22:13.138 | INFO | Received task: code_012 type=code
2026-03-31 19:22:13.138 | INFO | Returning workflow plan for code_012: 1 nodes, est_cost=0.0010τ
Clean miner startup — WorkflowSynapse correctly registered on axon:
2026-03-31 19:04:11.416 | INFO | Axon created with synapses: ['Synapse', 'WorkflowSynapse']
2026-03-31 19:04:11.417 | INFO | Axon details: Axon([::], 8091, 5H1Mr...1iaw, stopped, ['Synapse', 'WorkflowSynapse'])
2026-03-31 19:04:11.417 | INFO | C-SWON Miner initialised
2026-03-31 19:04:18.883 | INFO | Miner starting at block: 6804649
Stage 3: Sandboxed Execution
The validator executes the miner's workflow plan in a sandboxed environment (mock execution for testnet):
Executing workflow from miner UID 2
step_1 (SN1 text_generation): MOCK completed cost=0.0012τ latency=0.6s
step_2 (SN62 code_review): MOCK completed cost=0.0035τ latency=1.4s
step_3 (SN45 code_testing): MOCK completed cost=0.0025τ latency=2.1s
All 3/3 steps completed. Total: 0.0072τ, 4.1s
Stage 4: Quality Evaluation
Task type: code_generation
Test pass rate: 7/8 = 0.875
PEP8 linting: 0 violations
output_quality_score = 0.875
completion_ratio = 3/3 = 1.000
Stage 5: Composite Score (Live Data)
Actual scoring result from validator log (two consecutive cycles):
2026-03-31 19:20:13.310 | INFO | Scored 1 miners: mean=0.1000
2026-03-31 19:22:13.222 | INFO | Scored 1 miners: mean=0.1000
From score_aggregator.json — all 10 miners scored by vali/default (883 total tasks for UID 2, 13–14 each for UIDs 3–11):
Score window (last 100 scores for UID 2):
High scores: 0.9792, 0.9750, 0.9412, 0.9295, 0.9251, 0.8583
Mid scores: 0.3500, 0.2667, 0.2410
Base scores: 0.1000, 0.1147, 0.1159, 0.1130, 0.1152
Overall mean: 0.2292
Composite score formula (example high-scoring task):
S_success = 0.875 × 1.000 = 0.8750
S_success > 0.7 → cost and latency gates OPEN
S_cost = max(0, 1 − 0.0072/0.05) = 0.8560
S_latency = max(0, 1 − 4.1/10.0) = 0.5900
S_reliability = 1.0000
S = 0.50×0.8750 + 0.25×0.8560 + 0.15×0.5900 + 0.10×1.0000
S = 0.4375 + 0.2140 + 0.0885 + 0.1000 = 0.8400
Stage 6: Weight Submission (On-Chain — Verified)
All 3 validators have submitted weights on-chain. Verified via subtensor.weights(netuid=26):
Weight entries on chain: 3
Validator UID 1 (vali/default) → 10 miners:
UID 2: weight=65535 (15% cap hit)
UID 3: weight=54057
UID 4: weight=54057
UID 5: weight=54057
UID 6: weight=54057
UID 7: weight=54057
UID 8: weight=54057
UID 9: weight=54057
UID 10: weight=54057
UID 11: weight=54057
Validator UID 12 (vali/vali2) → 10 miners:
UIDs 2–5, 9–10: weight=65535
UIDs 6–8, 11: weight=62273
Validator UID 13 (vali/vali3) → 10 miners:
All UIDs: weight=65535 (equal, early bootstrap)
last_update confirms weight submission:
| Validator | UID | last_update | reg_block | Weight TX Block |
|---|---|---|---|---|
| vali/default | 1 | 6804290 | 6798914 | 6804290 |
| vali/vali2 | 12 | 6804282 | 6803594 | 6804282 |
| vali/vali3 | 13 | 6804285 | 6803614 | 6804285 |
How to Reproduce
# Requires Python 3.12 (bt SDK 10.x has issues with Python 3.14)
python3.12 -m venv btsdk_venv && source btsdk_venv/bin/activate
pip install bittensor && pip install -e .
# Start all miners (10 processes)
port=8091
for hotkey in default miner2 miner3 miner4 miner5 miner6 miner7 miner8 miner9 miner10; do
nohup python neurons/miner.py \
--netuid 26 --subtensor.network test \
--wallet.name miner --wallet.hotkey $hotkey \
--axon.port $port --logging.info > logs/miner-$hotkey.log 2>&1 &
port=$((port + 1))
done
# Start validators (3 processes)
for pair in "default:8101" "vali2:8102" "vali3:8103"; do
hotkey="${pair%%:*}"; port="${pair##*:}"
nohup python neurons/validator.py \
--netuid 26 --subtensor.network test \
--wallet.name vali --wallet.hotkey $hotkey \
--axon.port $port --logging.info > logs/vali-$hotkey.log 2>&1 &
done
# Monitor scoring state
cat ~/.bittensor/neurons/vali/default/netuid26/validator/score_aggregator.json | python3 -m json.tool
# Verify weights on chain
python -c "
import bittensor as bt
sub = bt.Subtensor(network='test')
for entry in sub.weights(netuid=26):
print(f'Validator UID {entry[0]} -> {len(entry[1])} targets')
"
Navigation
| ← Previous | 7.1 Testnet Evidence |
| → Next | 7.3 Incentive Verification |
| Index | Documentation Index |