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.
Yuma Consensus Flow
Median
Step 1: Read Weights and Stake
At epoch start, the algorithm reads current state from on-chain storage:
| Storage Item | What It Contains |
|---|---|
Weights | Validator → Miner weight matrix (W[i][j]) |
TotalStake | TAO staked per hotkey (S[i]) |
Bonds | Previous epoch's bond matrix |
ValidatorPermit | Which neurons can validate |
Validators submit weights via set_weights. Each validator assigns scores to miners they've evaluated, forming a weight matrix.
| Validator | Stake | Weight to M0 | Weight to M1 | Weight to M2 |
|---|---|---|---|---|
| V0 | 600 TAO (60%) | 0.5 | 0.3 | 0.2 |
| V1 | 400 TAO (40%) | 0.4 | 0.4 | 0.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:
- Collect all validator weights for miner j: [W[0][j], W[1][j], ...]
- Sort weights by value (ascending)
- Walk through, accumulating validator stake
- When cumulative stake exceeds 49% (1 - κ), that weight is the consensus
// 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:
Clipping serves two purposes:
- Prevents inflation: Validators can't give miners more credit than consensus allows
- Measures alignment: Clipped weights indicate disagreement with the network
| Validator | M0 (C=0.5) | M1 (C=0.3) | M2 (C=0.2) |
|---|---|---|---|
| V0 | min(0.5, 0.5) = 0.5 | min(0.3, 0.3) = 0.3 | min(0.2, 0.2) = 0.2 |
| V1 | min(0.4, 0.5) = 0.4 | min(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:
For our example:
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):
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:
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 Item | Updated With |
|---|---|
Consensus | C[j] per miner |
Incentive | I[j] normalized ranks |
Dividends | D[i] per validator |
Bonds | B'[i][j] EMA-updated |
ValidatorTrust | Sum of clipped weights per validator |
Emission | TAO 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.