Files
consensus/engine
zeekay 395eab9874 consensus(engine/chain): real alpha-of-K quorum-cert finality (no proposer self-finality)
THE BUG (CFT, not BFT): a proposer self-finalized its own block on its lone
self-vote (ForceAccept) and a peer's REJECT was counted as ACCEPT for the
proposer's own block (effectiveAccept = ... || IsOwnProposal). Followers
fast-followed unverified gossip and courtesy-voted only back to the proposer
(broken vote topology), so they could never reach threshold themselves. An
equivocating proposer could finalize two valid roots at one height -> fork.

THE FIX:
- QuorumCert (engine/chain/quorum_cert.go): the alpha-of-K finality witness.
  Assembles from alpha distinct correctly-signed ACCEPT votes over the
  canonical position; Verify enforces threshold + strictly-increasing-distinct
  voters + per-vote signature via a pluggable VoteVerifier. Wire codec for
  gossip (quorum_cert_codec.go). Quasar bridge (quorum_cert_quasar.go): upgrades
  to protocol/quasar.WeightedQuorumCert with real ML-DSA records + weighted
  Merkle inclusion when the node supplies the PQ validator set; fails closed
  otherwise. PROVEN: quasar's own Verify accepts the bridged cert.
- ForceAccept demoted to single-validator (K==1) only; refuses K>1 (fail-closed).
- effectiveAccept REJECT->ACCEPT flip deleted. Vote signatures verified at
  ingestion (multi-validator): forged/unsigned/wrong-position votes dropped, so
  the count, the cert, and IsAccepted stay consistent and forgery-proof.
- Topology rebuilt: followers broadcast SIGNED votes to ALL validators; whoever
  collects alpha assembles + gossips the cert; followers finalize on the
  verified cert (HandleIncomingCert) instead of fast-following. Liveness held:
  late/dropped Chits no longer freeze (cert gossip + re-request), no self-finality.
- Fail-closed DEX guard (quorum_guard.go): RequireQuorumFinalityForValueDEX
  refuses value DEX unless Mode()==QuorumFinality (K>1 + verifier).
- Start refuses K>1 without a verifier (forces the node bump to wire it).

Gates (all pass, race-clean): TestConsensus_NoProposerSelfFinality,
_AcceptRequiresQuorum, _EquivocatingProposerCannotFinalizeBothForks,
_PartitionMinorityCannotFinalize, TestDEX_BFTQuorumFinalizesFill,
_ByzantineProposerFakeFillRejected, TestLiveness_NoFreezeUnderLateChits,
_DroppedProposerChitsStillFinalizeViaPeerCert, TestQuasarBridge_RealCertVerifies.
194 engine/chain tests pass.
2026-06-22 16:32:28 -07:00
..
2025-12-19 08:49:11 -08:00