This chapter builds on: Ch 8 Weights & Scoring

Yuma Consensus

Yuma Consensus is Bittensor's algorithm for validators to collectively agree on miner rankings. It runs at each epoch as part of block execution, using a stake-weighted median that resists manipulation and Sybil attacks.

Step 1: Read Weights and Stake

At epoch start, the algorithm reads current state from on-chain storage:

Storage ItemWhat It Contains
WeightsValidator → Miner weight matrix (W[i][j])
TotalStakeTAO staked per hotkey (S[i])
BondsPrevious epoch's bond matrix
ValidatorPermitWhich neurons can validate

Validators submit weights via set_weights. Each validator assigns scores to miners they've evaluated, forming a weight matrix.

ValidatorStakeWeight to M0Weight to M1Weight to M2
V0600 TAO (60%)0.50.30.2
V1400 TAO (40%)0.40.40.2

Step 2: Compute Stake-Weighted Median (Consensus)

For each miner, we find the stake-weighted median of all validator weights. This is the core innovation that makes Yuma Sybil-resistant.

Why Weighted Median?

Unlike a simple average, the weighted median ignores minority outliers. An attacker with 10% stake giving a score of 0 has no effect on consensus – only participants with majority stake can shift the median.

The algorithm for each miner j:

  1. Collect all validator weights for miner j: [W[0][j], W[1][j], ...]
  2. Sort weights by value (ascending)
  3. Walk through, accumulating validator stake
  4. When cumulative stake exceeds 49% (1 - κ), that weight is the consensus
typescript
// Stake-weighted median for miner j
function consensus(j, weights, stake, kappa = 0.51) {
  // Get (weight, stake) pairs for miner j
  const pairs = validators.map(i => ({
    weight: weights[i][j],
    stake: stake[i]
  }));

  // Sort by weight ascending
  pairs.sort((a, b) => a.weight - b.weight);

  // Find median where cumulative stake > minority threshold
  let cumulative = 0;
  const minority = 1 - kappa; // 0.49

  for (const { weight, stake } of pairs) {
    cumulative += stake;
    if (cumulative > minority) {
      return weight; // This is the consensus!
    }
  }
}

Applying to our example:

  • M0: Weights [0.5, 0.4], stakes [0.6, 0.4]. Sorted: 0.4 (40%), 0.5 (100%). At 0.5, cumulative > 49%. C[0] = 0.5
  • M1: Weights [0.3, 0.4], stakes [0.6, 0.4]. Sorted: 0.3 (60%) > 49%. C[1] = 0.3
  • M2: Weights [0.2, 0.2]. Both same. C[2] = 0.2

Step 3: Clip Weights to Consensus

Each validator's weight is clipped to the consensus value:

W'[i][j] = min(W[i][j], C[j])

Clipping serves two purposes:

  1. Prevents inflation: Validators can't give miners more credit than consensus allows
  2. Measures alignment: Clipped weights indicate disagreement with the network
ValidatorM0 (C=0.5)M1 (C=0.3)M2 (C=0.2)
V0min(0.5, 0.5) = 0.5min(0.3, 0.3) = 0.3min(0.2, 0.2) = 0.2
V1min(0.4, 0.5) = 0.4min(0.4, 0.3) = 0.3 (clipped!)min(0.2, 0.2) = 0.2

V1's weight for M1 was clipped from 0.4 to 0.3. This affects V1's validator trust (sum of clipped weights vs. original weights).

Step 4: Calculate Ranks and Incentive

Rank is computed as the stake-weighted sum of clipped weights:

R[j] = Σi (W'[i][j] × S[i])

For our example:

R[M0] = 0.5 × 0.6 + 0.4 × 0.4 = 0.46
R[M1] = 0.3 × 0.6 + 0.3 × 0.4 = 0.30
R[M2] = 0.2 × 0.6 + 0.2 × 0.4 = 0.20

Normalizing these ranks gives incentive scores, which determine miner emission share (stored in Incentive):

  • M0: 0.46 / 0.96 = 47.9%
  • M1: 0.30 / 0.96 = 31.3%
  • M2: 0.20 / 0.96 = 20.8%

Step 5: Update Bonds (EMA)

Bonds represent a validator's accumulated "investment" in miners. They're updated using an Exponential Moving Average (EMA):

B'[i][j] = α × (W[i][j] × S[i]) + (1 - α) × B[i][j]

Where α is derived from the BondsMovingAverage parameter.

Yuma3: Liquid Alpha

In subnets with Yuma3 enabled, the α value is dynamic based on how close a validator's weight is to consensus. Consensus-aligned weights get faster bond accumulation.

The EMA smooths bond changes over time. Validators who consistently weight a miner accumulate more bonds than those who frequently change weights.

Step 6: Calculate Dividends

Dividends are how validators earn rewards. They're computed from bonds and incentive:

D[i] = Σj (B'[i][j] / ΣkB'[k][j]) × I[j]

A validator's dividend share in each miner equals their bond share, weighted by that miner's incentive.

Dividends are stored in Dividends and determine validator emission share.

Step 7: Write Results to Storage

Finally, all computed values are written back to on-chain storage:

Storage ItemUpdated With
ConsensusC[j] per miner
IncentiveI[j] normalized ranks
DividendsD[i] per validator
BondsB'[i][j] EMA-updated
ValidatorTrustSum of clipped weights per validator
EmissionTAO distributed per neuron

These storage updates happen atomically within the epoch – see Emission Mechanics for how incentive and dividends translate to actual TAO/Alpha distribution.

Interactive Calculator

Experiment with the algorithm. Set validator stakes and weights, then see how consensus, ranks, and emission are computed step by step.

Consensus Calculator

Experiment with validator weights and see how consensus is computed

Validators: 2
Miners: 3

Input: Validator Stakes & Weights

ValidatorStake (TAO)→ M0→ M1→ M2Actions
V0
V1

Step 1: Consensus (Weighted Median)

M0
0.500
M1
0.300
M2
0.200

Step 2: Clipped Weights

Validator→ M0→ M1→ M2Trust
V00.500 0.300 0.200 1.000
V10.400 0.300 (was 0.40)0.200 0.900

Step 3: Miner Incentive (Server Emission)

M0
47.92% 0.4792 τ
M1
31.25% 0.3125 τ
M2
20.83% 0.2083 τ

Step 4: Validator Dividends

V0
60.29% 0.6029 τ
V1
39.71% 0.3971 τ

Try this: Give one validator an extreme weight (e.g., 0.9 to M0) and see how it gets clipped to consensus. Notice that the validator's trust score decreases when their weights differ from consensus.

Collusion test: Create a minority validator coalition (combined stake <50%) all giving the same outlier weight. Watch how the weighted median ignores them entirely.

Full Worked Example

Let's trace through a complete epoch with the 2 validators and 3 miners from above.

Initial State

  • V0: 600 TAO stake, weights [0.5, 0.3, 0.2]
  • V1: 400 TAO stake, weights [0.4, 0.4, 0.2]

Step-by-Step Trace

StepM0M1M2
Consensus C[j]0.50.30.2
Rank R[j]0.460.300.20
Incentive I[j]47.9%31.3%20.8%
ValidatorTrustNotes
V01.0Perfect alignment (no clipping)
V10.9Clipped on M1 (0.4 → 0.3)

Key Properties

Sybil Resistant

Creating many fake validators with small stake doesn't help. Only majority stake can shift the weighted median.

Collusion Resistant

A minority coalition cannot manipulate consensus. They need >50% stake to shift results.

Incentive Aligned

Validators earn more by aligning with consensus. Outlier weights get clipped, reducing trust and dividends.

Temporally Stable

EMA bonds smooth changes over time. Validators can't rapidly shift rewards by changing weights.

Related Pages

Source Code

The Yuma Consensus algorithm is implemented in:

  • pallets/subtensor/src/epoch/math.rs: weighted_median() at line 975
  • pallets/subtensor/src/epoch/run_epoch.rs: epoch_mechanism() at line 559