Skip to main content

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:

ValidatorUIDlast_updatereg_blockWeight TX Block
vali/default1680429067989146804290
vali/vali212680428268035946804282
vali/vali313680428568036146804285

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')
"

← Previous7.1 Testnet Evidence
→ Next7.3 Incentive Verification
IndexDocumentation Index