Consensus

The ceiling that kept the wrong people out

Entry #50 · 2026-08-20 · Devlog

The ceiling that kept the wrong people out

We shipped a limit to survive an emergency. Then we sat down, did the arithmetic we should have done the first time, and realised the limit was pointed at exactly the wrong thing. This is the story of a one-line cap, why it was quietly capping the people we most wanted, and how we tore it out without stopping the chain.

Where the cap came from

A few weeks ago the network hit a failure mode where too many validators were being treated as finality voters at once, and a wave of them going quiet at the same time could stall the whole thing. The fix that night was blunt and correct for that night: cap the committee at nine. Nine signing seats, no more. It stopped the bleeding, the chain came back, and we moved on.

Blunt fixes have a way of outstaying their welcome. Four of those nine seats are our always-on baked validators. That leaves five for everyone else — every stranger who ran the one-line installer, bonded 500 ASE, and did exactly what we asked them to. The committee is sorted by stake, and a minimum-bond newcomer sorts near the bottom. So the sixth external to show up sorted to seat ten, and seat ten does not exist. Synced, bonded, doing everything right, and earning nothing — because a band-aid from an unrelated incident had drawn a line just above their head.

Someone on Reddit noticed the earning had a ceiling and decided it was proof of something sinister. It wasn't sinister. It was a leftover. But they were right that it was real, and that stung enough to make us go and actually understand the thing we'd been carrying.

The arithmetic we skipped

Here is the number that changes everything, and that we should have looked at the first night: our finality quorum is weighted by stake, not by headcount. The threshold to finalize is two-thirds of total staked ASE, plus one. Not two-thirds of validators — two-thirds of the money behind them.

Our four baked validators hold about twenty-five million ASE each. A faucet-funded external holds five hundred. So the baked four carry something like 99.98% of all staked weight on the network. They clear the finality threshold by themselves, every block, without a single external vote.

Run that forward. You can add a hundred tiny-stake externals to the committee. They can sign, they can earn a proportional share of rewards, and they can also all fall over at the same instant — and finality does not so much as flinch, because collectively they were never carrying enough weight to matter to the quorum math. The exact catastrophe the cap was built to prevent cannot happen with these validators, because the thing that makes them safe to admit is the same thing that makes them individually small: their stake.

The cap was protecting the network from a danger that only exists when dead nodes carry quorum weight. Stake-weighted, they carry almost none. We had been rationing the one thing we most wanted more of — participants — to guard against a threat that our own consensus rules had already neutralised.

Proving it before believing it

We have a rule here, paid for in outages: no consensus change reaches production until a purpose-built devnet has watched it both fail and succeed. So we built the meanest version of the scenario. Twenty nodes — four heavy "core" validators standing in for the baked, sixteen minimum-bond externals — cap switched off entirely. Then we sent a kill signal to all sixteen externals at the same moment.

The core kept finalizing. Zero forks. No freeze. Throughput sagged while the dead nodes' block slots timed out and got skipped, then recovered — a graceful slowdown, not a safety failure, which is exactly the line you want to land on. The math held up in the harness the way it held up on paper.

Lifting it live, without a reset

The last thing we wanted was to reset the chain again just to change a number. So the raise is written as a switch the whole network throws in lockstep: a new maximum and a future block height to apply it at. Below that height, the code is byte-for-byte identical to the capped version — every node computes the same committee, so deploying it changes nothing until the moment it changes everything, everywhere, at once.

We rolled it to all four baked validators one at a time, hash-checking that the fleet stayed in exact agreement after each restart, then out to the externals and the installer bundle. No pause in block production. No reset. When the trigger height lands, the ceiling goes from nine to a hundred across the network in the same block, and the strangers who were sorted into seats that didn't exist will simply start signing.

The honest caveat

This is safe because externals are faucet-capped to tiny stake. A validator that somehow bonded a genuinely large stake and then died would carry real quorum weight, and dead weight in the quorum is the one thing finality can't tolerate. The real answer there is fast eviction of dormant validators, which is the next thing on this workbench. On the testnet, the faucet enforces the assumption for us; for mainnet, the eviction has to be real code, not an assumption.

The lesson is one we keep relearning in new costumes: an emergency fix is a snapshot of one bad night's understanding, and it deserves to be re-derived the moment the fire is out. We carried a ceiling for weeks because it worked and nobody re-checked why. The number was nine. The reason was gone. Now hundreds of people can earn what they sign — which was the entire point of building a chain anybody can validate in the first place.

Don't miss the next entry.

Join the launch list and we'll send you a note whenever there's a new devlog entry, a research drop, or a real milestone.