Files
consensus/engine/chain/b1_cert_no_viewchange_test.go
zeekayandHanzo Dev 4f09496454 engine/chain: finality ladder in the Lux ontology (Photon→Wave→Nova→Quasar→Horizon)
The four finality concepts as DISTINCT authorization tiers that never collapse, named
in our astrophysics ontology (no generic BFT / Cosmos vocabulary):

  Photon  in flight, being sampled          authorizes nothing
  Wave    the forming Nova preference        authorizes nothing
  Nova    beta-ignition, sampler accepts     authorizes LOCAL execution (reorgable)
  Quasar  2/3-stake certificate              authorizes bridges / DEX / cross-chain
  Horizon PQ-sealed, irreversible            authorizes irreversible settlement

finality.go: the Finality enum + AuthorizesLocalExecution/Export/IrreversibleSettlement
boundary methods (the anti-collapse invariant as code: a block below Quasar can never be
exported as deterministically final).

quorum.go: reconciled to the Nova tier ONLY — NovaQuorum(n)=floor(n/2)+1 (majority,
crash-tolerant, drives Nova ignition / local exec), CrashTolerance, NovaBeta. Deleted the
node-count CertQuorum/ByzantineTolerance I had added: the Quasar tier has exactly ONE
definition and it is config.TwoThirdsStakeFloor / EqualStakeSupermajorityThreshold (strict
>2/3 stake, distinct signers via QuorumCert.VerifyWeighted) — never re-expressed as a count.
TestNova_Below_Quasar proves the two tiers stay distinct (Nova majority < Quasar 2/3; n=5:
3 vs 4).

Removed the dead config.Parameters.ViewChange field (Phase A deleted everything that read
it) and its stale test assignments — no Tendermint vocabulary left in runtime config.

Whole-repo build + ladder/quorum tests green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-10 01:17:22 -07:00

69 lines
2.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (C) 2019-2026, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// b1_cert_no_viewchange_test.go — the B1 premise, made explicit.
//
// B1 (owner decision 2026-07-09): keep the ⅔-stake α-of-K quorum cert as the SOLE finality
// decider (it is the real, working BFT finality) and DELETE the Tendermint view-change/lock/POL
// liveness layer bolted on top. The view-change exists ONLY to converge COMPETING siblings under
// the anyone-can-propose storm; with ONE proposer per height (the node-side windower fix, the B1
// gate) there are no competing siblings, so α canonical signatures align on the single block and
// the cert finalizes with NO view-change.
//
// This pins that premise directly: n=5, ViewChange EXPLICITLY DISABLED, one block per height, the
// fleet finalizes every height via the α-of-K cert with a single head. It is the standing proof
// that deleting the view-change removes only the storm-convergence layer, never the decider — the
// cert path is complete on its own. (The mainstream multinode suite already runs at this default;
// this makes the B1 contract an explicit, named regression rather than incidental coverage.)
package chain
import (
"testing"
"github.com/luxfi/ids"
)
func TestB1_CertFinalizesWithoutViewChange_OneProposerPerHeight(t *testing.T) {
p := prodParams5()
net := newSimNet(t, 5, p)
// One proposer per height (rotated) — the post-storm-fix regime: no competing siblings, so
// every honest node signs the SAME canonical block and α=4 signatures assemble one cert.
const heights = 6
parentID := ids.Empty
parentRoot := simGenesisRoot()
for h := uint64(1); h <= heights; h++ {
blk := newHonestBlock(parentID, parentRoot, h, "b1-one-proposer")
net.build(int(h%5), blk) // a single deterministic proposer builds this height
if !waitFor(emergeTO, func() bool {
all, fork := net.finalizedEverywhere(blk)
return all && !fork
}) {
t.Fatalf("B1: height %d must finalize via the α-of-K cert with ViewChange OFF; heads=%v",
h, net.headsAtHeight(h))
}
if seen := net.headsAtHeight(h); len(seen) != 1 {
t.Fatalf("B1: single head required at height %d (the cert is the decider), got %v", h, seen)
}
parentID, parentRoot = blk.ID(), blk.stateRoot
}
// Every node finalized the identical chain — the cert alone gave BFT agreement, no view-change.
for h := uint64(1); h <= heights; h++ {
var first ids.ID
for i, n := range net.nodes {
got, ok := n.rt.FinalizedBlockAtHeight(h)
if !ok {
t.Fatalf("B1: node %d missing finalized height %d", i, h)
}
if i == 0 {
first = got
} else if got != first {
t.Fatalf("B1: divergence at height %d — node %d has %s, node 0 has %s", h, i, got, first)
}
}
}
}