QNet - what's been done this round
Three weeks on reworking consensus.
The cause of the stalls was a class of bug, not a single one. Some consensus decisions depended on what a node happened to hold on its own disk rather than on the block height, so two honest nodes could derive different participant lists and diverge - finality stopped with no attacker involved. Every such place is gone: elections are now a pure function of confirmed data, identical on every node. Alongside that, the specific epoch-boundary mechanisms: the participant set was sampled at the boundary while activity proofs stay admissible for another 90 blocks, the "is emission due" check returned a false yes at the very first boundary and the chain stopped ~4 hours in, and nothing actually required the emission at its height - a producer that couldn't build it shipped a valid empty block and the epoch lost both the issuance and its reward root.
A stall is no longer a dead end. Before, when finality stopped, production died three minutes later and there was no way out: recovery needs fresh activity proofs on chain, and those can't get there while production is stopped. Now the network keeps producing for ~48 more minutes on a frozen participant set that is identical everywhere, with no risk of splitting into two chains, and the set shrinks to drop the silent ones so the quorum threshold becomes reachable again. To be straight: making stalls impossible isn't achievable in any network of this type - if more than a third go quiet, finality stops, that's mathematics. What's removed are the reasons we stalled.
One nasty find. An honest producer that re-issued a block after a rollback could be banned on chain permanently, with no attacker present. And the reverse: a small detail in signature parsing let anyone fabricate a valid ban against any producer, and two of those were enough to stop finality for good. Rewritten.
Entry had a hole. Activation codes are tied to a wallet, but that check lived in the application, not the chain - a hand-built registration transaction sent straight to the network bypassed it. And the attestation step signed a binding to whatever beneficiary the caller named, with nothing proving they owned the wallet that actually burned, so anyone who saw a public burn on Solana could collect a legitimate quorum naming themselves. Ownership is now proven cryptographically on chain, and one burn activates exactly one node - previously a single entry could bring up both a super and a light node.
Rewards split 25/75 between operators and users.
Scale and hardening. Consensus messages went from ~3 MB to under 2 KB, registration attestations are collected in parallel (without it, onboarding at scale physically couldn't finish in time), the reward computation fits in memory for millions of recipients, and the state tree moved to disk. Around 250 places closed where a single request could take a node's process down; key substitution over the network removed; transport bound to its session against replays. Claiming rewards now requires the recipient's signature - an unsigned request could previously strip a wallet of all past earnings irreversibly. Storage rewritten: competing blocks at the same height are kept rather than discarded, and every check that quietly returned a partial result on a read error now stops instead of computing a wrong root.
Post #162
529
- ⚡ 8
- 🔥 4
- ❤ 3
- 👏 1