TOTAL-STAKE-INFERENCE

FieldValue
NameTotal Stake Inference
Slug94
Statusraw
CategoryStandards Track
EditorDavid Rusu [email protected]
ContributorsAlexander Mozeika [email protected], Daniel Kashepava [email protected], Filip Dimitrijevic [email protected]

Timeline

  • 2026-05-28d45eed2 — Chore: mirror blochain specs into github/mdbook (#347)
  • 2026-05-1858b5698 — chore(blockchain): migrate contributor emails to @logos.co (#338)
  • 2026-01-19f24e567 — Chore/updates mdbook (#262)
  • 2026-01-1689f2ea8 — Chore/mdbook updates (#258)

Revision History

VersionChangesDate
1.0.0Initial revision.2026-01-20

Introduction

As with any Proof of Stake (PoS) consensus protocol, the probability that an eligible Cryptarchia participant wins the right to propose a block depends on that participant’s stake relative to the total active stake. Because leader selection in Cryptarchia is private, the total active stake is not directly observable. Instead, nodes must infer it from observable chain growth.

Overview

The total active stake can be inferred by observing the slot occupancy rate: a higher fraction of occupied slots implies more stake participating in consensus. By observing the rate of occupied slots from the previous epoch and knowing the total stake estimate used during that period, we can infer a correction to the total stake estimate to compensate for any changes in consensus participation. This inference process is done by each node following the chain. Leaders will use this total stake estimate to calculate their relative stake as part of the leadership lottery without revealing their stake to others.

The stake inference algorithm adjusts the previous total stake estimate based on the difference between the empirical slot activation rate (measured as the growth rate of the honest chain) and the expected slot activation rate. A large difference serves as an indicator that the total stake estimate is not accurate and must be adjusted.

This algorithm has been analyzed and shown to have good accuracy, precision and convergence speed. A caveat to note is that accuracy decreases with increased network delays. The analysis can be found in [1.0.0][Analysis] Total Stake Inference.

Construction

Definitions

Parameters and variables

SymbolValueNameDescription
beta1.0learning rateControls how quickly we adjust to new participation levels. Lower values for beta give a more stable / gradual adjustment, while higher values give faster convergence but at the cost of less stability.
PERIODobservation periodThe length of the observation period in slots.
finherited from Constantsslot activation coefficientThe target rate of occupied slots. Not all slots contain blocks, many are empty.
kinherited from Constantssecurity parameterBlock depth finality. Blocks deeper than k on any given chain are considered immutable.

Functions

  • Returns the number of blocks produced in the slots following slot in the honest chain.

Algorithm

For a current epoch’s estimate total_stake_estimate and the epoch’s first slot epoch_slot, the next epoch’s estimate is calculated as shown below:

#![allow(unused)]
fn main() {
const PRECISION: u64 = 1e3
fn total_stake_inference(total_stake_estimate: u64, epoch_slot: u64) -> u64 {
    // f: f64
    // PERIOD: u64
    // density_over_slots(u64, u64) -> u64

    let beta_p: u64 = truncate(beta * PRECISION)
    let f_p: u64 = truncate(f * PRECISION)
    let tse_p: u64 = total_stake_estimate * PRECISION

    let measured_density_p: u64 = density_over_slots(epoch_slot, PERIOD) * PRECISION
    let expected_density_p: u64 = PERIOD * f_p
    let density_diff_p: i128 = (expected_density_p as i128) - (measured_density_p as i128)
        let slot_activation_error_p: i128 = (tse_p * density_diff_p) / (expected_density_p as i128)
        let correction_p: i128 = (beta_p * slot_activation_error_p) / PRECISION;
        let new_total_stake_estimate = (tse_p - correction_p) / PRECISION;

        max(new_total_stake_estimate, 1) as u64
}
}

Annex

[1.0.0][Analysis] Total Stake Inference