zeekayandHanzo Dev e06cea0db2 engine/chain: LIVE stale-alias view-change lock rebase (F1 / mainnet 1085761 freeze)
The v1.35.36 cert-receive canonical fix let luxd-4 past the 1085755 storm wall,
but it then froze at round-height 1085761: a pre-fix durable v3 view-change lock
stored by an OUTER proposervm wrapper id (committedSlot written when canonical=
outer) is re-seeded by viewForLocked as lockBlock, and prevoteTarget compares that
stale alias against the inner-canonical winner by RAW id. The equality fails, the
node prevotes its stale lock forever, no POL for the winner forms → SAFE but
FROZEN (lockIsStaleAlias=true, lockRound=0, prevoteTarget=stale, winner=inner).

The boot-time operator migration (lock_migration.go) already repairs this durably,
but it is one-shot and env-gated. This adds the LIVE, per-step, in-memory analogue
so a running fleet self-heals without operator action:

  - round_view.go rebaseLockAlias: a PURE, mechanical alias swap. Re-names an
    existing lock onto `canonical`, preserving the locked VALUE (same inner block)
    and the lock ROUND. Touches no tally/round/precommit record, so every other
    round-machine invariant is trivially preserved. It RESTORES the machine's
    contract that lockBlock is always an inner canonical.

  - integration.go maybeRebaseStaleLock: at the top of each view-change step, if
    the height's view is locked on a NON-winner id, resolve that lock's inner
    canonical (vmCanonicalResolver — tracked canonicalRep, then the durable VM
    store) with NO engine lock held (preserving runViewChangePass's mu->slotMu
    order), and rebase onto the winner IFF the resolved inner EQUALS winnerCanon.

SAFETY (no liveness bought with a fork): we only ever move a lock to the value the
whole fleet is already converging on. A lock resolving to a DIFFERENT inner (real
fork) or unresolvable is left untouched — the node stays fail-closed frozen. A
fresh in-session lock is already canonical, resolves to itself, and only rebases
when it equals the winner (a no-op) — an honest same-session precommit is never
re-pointed. lockRound is preserved, so the unlock bar for a genuinely conflicting
value is not lowered. The rebase target is the deterministic winner canonical
(unique per (height,parent-group) via convergedWinnerAtHeightLocked), and
recordOwnPrecommit still refuses a conflicting precommit at a round, so no node can
be made to POL two distinct inner ids at one height; 2α−n>f (n=5,α=4: 3>1) is
unchanged. Scope is exactly the v3 soft-lock case (lockRounds); legacy hard locks
(recoveredLocks, no round) are never round-seeded into a view, so they stay the
operator migration's domain — the live gate and reserveSlotForSign agree on which
locks are re-pointable.

Tests (fail-on-old / pass-on-new):
  - round_view: TestRoundView_RebaseLockAlias (pure alias swap, round preserved,
    prevoteTarget flips suppression->winner, guards never fabricate a lock).
  - RED TestRedLiveRebase_SafetyGate: same-inner rebased live (no migration);
    divergent-inner REFUSED (no fork); unresolvable left untouched.
  - Multinode TestMultiNode_LiveStaleLockRebase_ConvergesNoFork: the n=5 α=4
    3/2 stale-outer split-lock freezes without a resolver (control) and CONVERGES
    to a single head via the live rebase with no boot migration (fix).

Full engine/chain suite green (356s); lock/view-change/fork/committee/incident
subset green under -race (139s).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-09 12:01:09 -07:00
2026-06-28 20:35:52 -07:00
2026-06-28 20:35:53 -07:00

consensus

Lux Consensus

Lux is not merely adding post-quantum signatures to a chain; it defines a hybrid finality architecture for DAG-native consensus, with protocol-agnostic threshold lifecycle, post-quantum threshold sealing, and cross-chain propagation of Horizon finality.

See LP-105 §Claims and evidence for the canonical claims/evidence table and the ten architectural commitments — single source of truth.

CI Status Go Version

Quasar Family of Consensus

Quasar is the consensus engine for the Lux network. It provides unified consensus for linear chains (P-Chain, C-Chain) and DAG chains (X-Chain) with post-quantum finality via three independent cryptographic signing paths.

Sub-Protocols

Protocol Role Package
Photon K-of-N committee selection via Fisher-Yates sampling with luminance-weighted reputation protocol/photon
Wave Per-round threshold voting with FPC (Fast Probabilistic Consensus) protocol/wave
Focus Confidence accumulation: beta consecutive successes = local finality protocol/focus
Nova Linear chain consensus mode (P-Chain, C-Chain) -- wraps Ray protocol/nova
Nebula DAG consensus mode (X-Chain) -- wraps Field protocol/nebula
Prism DAG geometry: frontiers, cuts, uniform peer sampling protocol/prism
Horizon DAG order-theory: reachability, LCA, transitive closure, skip lists protocol/horizon
Flare DAG certificate/skip detection via 2f+1 quorum protocol/flare
Ray Linear chain finality driver: Wave + Focus + Sink protocol/ray
Field DAG finality driver: Wave + safe-prefix commit protocol/field
Quasar BLS + Pulsar + ML-DSA threshold signing, epoch management protocol/quasar

Signing Modes

Each cryptographic layer is independently toggleable:

Mode Layers Use Case
BLS-only BLS12-381 threshold Fastest classical consensus
BLS + ML-DSA BLS + FIPS 204 ML-DSA-65 Dual with PQ identity proof
BLS + Pulsar BLS + Ring-LWE 2-round threshold Dual with PQ threshold proof
BLS + Pulsar + ML-DSA All three in parallel Full Quasar (triple mode)

IsTripleMode() returns true when all three paths are configured. TripleSignRound1 runs BLS + Pulsar + ML-DSA signing in parallel goroutines.

PQ Mode Selection (Configurable)

The active mode is selectable at runtime via config.PQMode or the CONSENSUS_PQ_MODE env var. Defined in config/pq_mode.go:

Mode Env value Maps to wire policy
BLSOnly bls PolicyQuorum
BLSPlusMLDSA bls-mldsa PolicyPQ
BLSPlusCorona bls-rt PolicyPZ
BLSPlusGroth16 bls-z PolicyQuantum (placeholder)
TripleQuantum triple PolicyQuantum

Run bench/pq_modes_bench_test.go for measured per-mode signing / aggregation / verify costs and cert sizes. Storage and cert size trade-offs:

Mode Sign Agg Verify Cert Storage 10K
bls 312 µs 8.6 ms 714 µs 123 B 1.17 MB
bls-mldsa 369 µs 8.5 ms 3.4 ms 69 KB 665 MB
bls-rt 39 ms 3.3 s 1.6 ms 33 KB 318 MB
triple 40 ms 3.3 s 4.3 ms 102 KB 981 MB

Pulsar / triple include the full 2-round Pulsar threshold protocol (github.com/luxfi/pulsar/threshold — Pulsar is Lux's variant with DKG2 and Pulsar-SHA3 hash suite). Production parameters M=8, N=7, LogN=8 (ring degree 256), Q=2^48-ish: classical 2^142, quantum 2^130. Cert-size floor of ~33 KB is set by the (C, Z, Delta) ring polynomials; protocol/quasar/cert_size_compare_test.go measures and verifies this.

Architecture

consensus/
  protocol/
    photon/       Committee selection (Emitter + Luminance)
    wave/         Threshold voting + FPC
      fpc/        Fast Probabilistic Consensus selector
    focus/        Confidence counter (beta tracker)
    prism/        DAG cuts, frontiers, uniform sampling
    horizon/      DAG reachability, LCA, skip lists
    flare/        DAG cert/skip classification (2f+1)
    ray/          Linear chain driver (Nova uses this)
    field/        DAG finality driver (Nebula uses this)
    nova/         Linear chain consensus mode
    nebula/       DAG consensus mode
    chain/        Block interface primitives
    quasar/       BLS + Pulsar + ML-DSA threshold signing
  engine/         Consensus engine (Chain, DAG, PQ wrappers)
  core/           Core types, DAG structures
  types/          Block, Vote, Config, Bag
  config/         Parameter presets (single, local, testnet, mainnet)
  runtime/        VM wiring (chain IDs, validators, logging)
  pkg/wire/       Wire protocol credentials (ML-DSA-44/65/87 + BLS + Ed25519)
  bench/          Benchmarks
  version/        Re-exports github.com/luxfi/version

Consensus Flow

Linear Chains (Nova)

Photon (select committee) -> Wave (threshold vote) -> Focus (count beta) -> Ray (decide) -> Sink

DAG Chains (Nebula)

Photon (select committee) -> Wave (threshold vote per frontier vertex)
  -> Flare (cert/skip) -> Horizon (safe prefix) -> Field (commit ordered prefix) -> Committer

Quasar PQ Finality

After consensus decision, the Quasar signing layer produces threshold certificates:

  1. BLS: single-round threshold share via crypto/threshold
  2. Pulsar: 2-round Ring-LWE threshold via luxfi/corona/threshold
  3. ML-DSA-65: single-round FIPS 204 identity signature

All three run in parallel. A block is quantum-final when all configured certificate layers are valid.

Key Hierarchy

Layer Key Type Purpose
Node-ID Ed25519 P2P transport auth
Validator-BLS BLS12-381 Classical finality votes
Validator-PQ Pulsar (Ring-LWE) PQ finality shares
Validator-ID ML-DSA-65 (FIPS 204) PQ identity attestation
Wallet (EVM) secp256k1 User transaction signatures
Wallet (X-Chain) secp256k1 UTXO locking

Quick Start

import "github.com/luxfi/consensus"

chain := consensus.NewChain(consensus.DefaultConfig())

ctx := context.Background()
if err := chain.Start(ctx); err != nil {
    log.Fatal(err)
}
defer chain.Stop()

block := &consensus.Block{
    ID:       consensus.NewID(),
    ParentID: consensus.GenesisID,
    Height:   1,
    Payload:  []byte("Hello, Lux!"),
}
if err := chain.Add(ctx, block); err != nil {
    log.Fatal(err)
}

Configuration

// Auto-configure based on validator count
params := consensus.GetConfig(21) // mainnet defaults

// Or use presets
consensus.SingleValidatorParams() // 1 node, dev
consensus.LocalParams()           // 5 nodes, local
consensus.TestnetParams()         // 11 nodes, testnet
consensus.MainnetParams()         // 21 nodes, production

Benchmarks

Measured on Apple M1 Max:

Component Operation Time/Op
Wave Vote round 3.38 us
Photon K-of-N selection 3.03 us
Luminance Brightness update 72 ns

ZAP wire protocol (measured, bench/):

Configuration Throughput
Single connection 114K TPS
20 parallel connections 376K TPS
50 conns + batch 1000 20.26M TPS

Testing

GOWORK=off go test ./...
GOWORK=off go test -bench=. ./bench/

Security Model

  1. Pre-quantum: Attacker must corrupt >= 1/3 stake to fork
  2. Q-day (BLS broken): Lattice certificates prevent unsafe finalization
  3. Post-quantum: Security rests on Module-LWE (Pulsar) + Module-LWE/SIS (ML-DSA)

License

BSD 3-Clause. See LICENSE.

S
Description
Quasar consensus engine: Go implementations of consensus protocols for the Lux Network.
Readme
251 MiB
Languages
Go 85.5%
Rust 7.6%
Python 3.1%
TeX 1.2%
C 0.9%
Other 1.7%