May 19, 11-12 PM (48)
May 19, 12-1 PM (81)
May 19, 1-2 PM (71)
May 19, 2-3 PM (41)
May 19, 3-4 PM (51)
May 19, 4-5 PM (15)
May 19, 5-6 PM (20)
May 19, 6-7 PM (18)
May 19, 7-8 PM (9)
May 19, 8-9 PM (21)
May 19, 9-10 PM (10)
May 19, 10-11 PM (28)
May 19, 11-12 AM (13)
May 20, 12-1 AM (21)
May 20, 1-2 AM (9)
May 20, 2-3 AM (4)
May 20, 3-4 AM (5)
May 20, 4-5 AM (9)
May 20, 5-6 AM (37)
May 20, 6-7 AM (47)
May 20, 7-8 AM (53)
May 20, 8-9 AM (50)
May 20, 9-10 AM (16)
May 20, 10-11 AM (41)
May 20, 11-12 PM (28)
May 20, 12-1 PM (50)
May 20, 1-2 PM (92)
May 20, 2-3 PM (21)
May 20, 3-4 PM (326)
May 20, 4-5 PM (23)
May 20, 5-6 PM (23)
May 20, 6-7 PM (17)
May 20, 7-8 PM (23)
May 20, 8-9 PM (15)
May 20, 9-10 PM (5)
May 20, 10-11 PM (34)
May 20, 11-12 AM (16)
May 21, 12-1 AM (16)
May 21, 1-2 AM (9)
May 21, 2-3 AM (11)
May 21, 3-4 AM (7)
May 21, 4-5 AM (4)
May 21, 5-6 AM (27)
May 21, 6-7 AM (14)
May 21, 7-8 AM (22)
May 21, 8-9 AM (34)
May 21, 9-10 AM (45)
May 21, 10-11 AM (37)
May 21, 11-12 PM (27)
May 21, 12-1 PM (63)
May 21, 1-2 PM (68)
May 21, 2-3 PM (60)
May 21, 3-4 PM (53)
May 21, 4-5 PM (20)
May 21, 5-6 PM (27)
May 21, 6-7 PM (27)
May 21, 7-8 PM (25)
May 21, 8-9 PM (23)
May 21, 9-10 PM (3)
May 21, 10-11 PM (29)
May 21, 11-12 AM (10)
May 22, 12-1 AM (16)
May 22, 1-2 AM (6)
May 22, 2-3 AM (8)
May 22, 3-4 AM (4)
May 22, 4-5 AM (11)
May 22, 5-6 AM (10)
May 22, 6-7 AM (21)
May 22, 7-8 AM (13)
May 22, 8-9 AM (38)
May 22, 9-10 AM (12)
May 22, 10-11 AM (18)
May 22, 11-12 PM (25)
May 22, 12-1 PM (24)
May 22, 1-2 PM (34)
May 22, 2-3 PM (56)
May 22, 3-4 PM (13)
May 22, 4-5 PM (29)
May 22, 5-6 PM (13)
May 22, 6-7 PM (19)
May 22, 7-8 PM (20)
May 22, 8-9 PM (12)
May 22, 9-10 PM (12)
May 22, 10-11 PM (41)
May 22, 11-12 AM (12)
May 23, 12-1 AM (9)
May 23, 1-2 AM (0)
May 23, 2-3 AM (3)
May 23, 3-4 AM (1)
May 23, 4-5 AM (1)
May 23, 5-6 AM (4)
May 23, 6-7 AM (12)
May 23, 7-8 AM (1)
May 23, 8-9 AM (3)
May 23, 9-10 AM (1)
May 23, 10-11 AM (1)
May 23, 11-12 PM (5)
May 23, 12-1 PM (1)
May 23, 1-2 PM (6)
May 23, 2-3 PM (5)
May 23, 3-4 PM (5)
May 23, 4-5 PM (4)
May 23, 5-6 PM (0)
May 23, 6-7 PM (3)
May 23, 7-8 PM (23)
May 23, 8-9 PM (1)
May 23, 9-10 PM (9)
May 23, 10-11 PM (21)
May 23, 11-12 AM (27)
May 24, 12-1 AM (9)
May 24, 1-2 AM (0)
May 24, 2-3 AM (1)
May 24, 3-4 AM (1)
May 24, 4-5 AM (0)
May 24, 5-6 AM (3)
May 24, 6-7 AM (1)
May 24, 7-8 AM (2)
May 24, 8-9 AM (2)
May 24, 9-10 AM (4)
May 24, 10-11 AM (4)
May 24, 11-12 PM (1)
May 24, 12-1 PM (7)
May 24, 1-2 PM (46)
May 24, 2-3 PM (5)
May 24, 3-4 PM (3)
May 24, 4-5 PM (18)
May 24, 5-6 PM (2)
May 24, 6-7 PM (4)
May 24, 7-8 PM (13)
May 24, 8-9 PM (10)
May 24, 9-10 PM (15)
May 24, 10-11 PM (33)
May 24, 11-12 AM (42)
May 25, 12-1 AM (9)
May 25, 1-2 AM (4)
May 25, 2-3 AM (6)
May 25, 3-4 AM (1)
May 25, 4-5 AM (6)
May 25, 5-6 AM (14)
May 25, 6-7 AM (17)
May 25, 7-8 AM (17)
May 25, 8-9 AM (32)
May 25, 9-10 AM (43)
May 25, 10-11 AM (64)
May 25, 11-12 PM (33)
May 25, 12-1 PM (43)
May 25, 1-2 PM (40)
May 25, 2-3 PM (20)
May 25, 3-4 PM (27)
May 25, 4-5 PM (16)
May 25, 5-6 PM (6)
May 25, 6-7 PM (7)
May 25, 7-8 PM (11)
May 25, 8-9 PM (12)
May 25, 9-10 PM (13)
May 25, 10-11 PM (39)
May 25, 11-12 AM (25)
May 26, 12-1 AM (11)
May 26, 1-2 AM (11)
May 26, 2-3 AM (8)
May 26, 3-4 AM (11)
May 26, 4-5 AM (6)
May 26, 5-6 AM (9)
May 26, 6-7 AM (24)
May 26, 7-8 AM (39)
May 26, 8-9 AM (38)
May 26, 9-10 AM (41)
May 26, 10-11 AM (36)
May 26, 11-12 PM (4)
3,609 commits this week May 19, 2026 - May 26, 2026
sim-rs: replace vote-threshold with quorum-weight-fraction (CIP-164 PR #1196)
The YAML knob `vote-threshold: u64` (absolute count, mode-dependent
in meaning) is replaced by `quorum-weight-fraction: f64` (always a
fraction). The absolute threshold is derived at config build from
`quorum_weight_fraction × expected_total_weight`, with the
denominator per mode: PV+NPV seats (WfaLs), node count (Everyone),
total active stake (TopStakeFraction).

Default kept at 0.6 (legacy 300/500) in config.default.yaml to
preserve existing-experiment numerics; code default 0.75 (CIP-0164).

For TopStakeFraction, `try_vote_for_endorser_block` emits the
voter's own stake as the per-EB weight (rather than 1). The quorum
check is unchanged in form — `Σ weight ≥ vote_threshold()` — because
the threshold method now returns stake-denominated values.

`SimConfiguration::build` enforces σ_c > τ for TopStakeFraction and
bails with a clear error referencing the PR. Two new tests:
`top_stake_fraction_uses_stake_weighted_quorum` (per-voter weight =
stake, low-stake majority does NOT certify) and
`sim_config_rejects_top_stake_fraction_when_sigma_c_le_tau`.

`shared_consensus.rs` adapter: `derive_quorum_fraction` collapses to
a passthrough; expected_total_weight uses the new helper.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
shared-consensus: stake-weighted quorum for StakeCentile (CIP-164 PR #1196)
Quorum is now `Σ voter_stake ≥ τ × total_active_stake` under
StakeCentile committee selection. WfaLs and EveryoneVotes keep their
head-count semantics. The aggregator's per-voter weight unit is now
mode-polymorphic — seats for WfaLs, 1 for Everyone, voter stake for
StakeCentile — and the denominator returned by
`committee::expected_total_weight` matches.

`wfa.rs` is renamed to `committee.rs` since wFA^LS is one of three
schemes now, not the only one. `voter_weights` and the `weight`
parameter widen from u32 to u64 so stake values fit; quorum
comparisons follow.

`ElectionsConfig::validate()` enforces σ_c > τ at startup for
StakeCentile (PR #1196 §"Quorum as a stake threshold"); both the
sim-rs adapter and net-rs net-node panic on a misconfigured set.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
feat: move updatable transient fields into a dedicate overlay type and module
  This allows to properly encapsulate those fields which MUST NOT be accessed directly inadvertently. Given that it is very easy to so (and effectively hard to keep track of), moving them in a separate module encapsulated as private field in a struct gives us the strong compiler guarantees needed. Defining Deref and DerefMut also makes it transparent to use from the parent module; yet preserves the encapsulation we need.

  Note that this made apparent an inconsistency in terms of protocol parameters and governance activity between validation and block application. This is now properly handled.

Signed-off-by: KtorZ <[email protected]>
fix: defer epoch transition application, storing intermediate results.
  This is large because it touches quite many parts and I had to
  untangle store side-effects in the middle of various places. The
  general idea is rather simple, though:

  - The epoch transition no longer mutates the store directly;

  - Instead, the transition is entirely read-only; and produces three
    distinct 'pending' updates:
    - rewards payouts
    - pools updates (i.e. de-registration & parameters changes)
    - governance results (ratified & expired proposals, withdrawals, ...)

  - These updates are not immediately applied since they cannot be
    considered stable until later in the epoch. Instead, they're stashed
    in the ledger state object;

  - Later, once the results from the previous can be considered stable
    (cf stability window); we can flush the updates and begin the
    rewards calculations for the next epoch.

  What's left TODO from there:

  - We must ensure that access to various moving parts of the ledger
    state (e.g. protocol parameters, governance activity, etc...) are
    not done directly on the struct fields; but rather go through
    helpers that take care of applying the transient state if there's
    any. So for example a `.protocol_parameters()` will first look at
    any available governance update, and if any, use that in priority.

    Similarly, when consulting the balance of an account, we would first
    have to look for any unapplied rewards.

  - Refunds and withdrawals from governance are not checking that
    accounts still exists. They simply stash the update. But in
    practice, like for pools; we would also need to send uncollected
    money flow to the treasury. Same for pool refunds.

  - More importantly, updates are not currently flushed to disk. That
    crucial part is missing and will happen in a future commit. The plan
    for now is to do it "naively" and flush all updates at once as soon
    as we enter the stable part of the epoch. Later, we can split the
    update over multiple slots to avoid keeping the ledger busy for too
    long.

Signed-off-by: KtorZ <[email protected]>