Supersede the stale Quasar-wrapper notes with the actual consensus/quasar verify
gate: dormant-by-default safety contract, files/tests, and the owner-gated
remaining-work map (producer+encoder export, gossip ingest, per-epoch validator
provider, config wiring, grace-window runbook) + mainnet activation order.
Red adversarial review of the PQ-finality gate. Dormant default verified a true
no-op; these harden the ACTIVATED path before any forward-dated activation:
H1 (HIGH) — bindCheck now binds cert.Epoch == cp.Epoch (and cert.Round). The
gate resolves verification keys from the cert's epoch; an unbound epoch let a
cert signed under a DIFFERENT validator-set era (e.g. a compromised RETIRED
committee key) certify the current block, nullifying KeyEra rotation as a
blast-radius bound. Honest certs match (producer signs Subject.Epoch==cp.Epoch).
+ wrong-epoch / wrong-round anti-replay test cases.
M2 (MED) — activation is now HEIGHT-ONLY, deterministic. Removed time.Now() (and
the ActivationConfig.Time field) from the accept path: wall-clock gating split
finalization across validators with skewed clocks (some halting on a missing
cert, others finalizing without one). A height is consensus-agreed; timestamp
forward-dating is expressed by choosing the activation height.
L5 (LOW) — an activated gate with a nil store/validator provider now fails
closed with ErrGateMisconfigured instead of panicking in the accept hook (a
panic would halt the chain uncontrollably). Off the dormant path. + test.
M3 (doc) — made the StateRoot=0 transitive-through-BlockHash contract explicit in
bindCheck (non-zero cert StateRoot already rejected + tested) so the producer
follow-on cannot silently ship state-committing certs that self-halt.
proposervm: verifyQuasarFinality short-circuits on nil gate BEFORE building the
Checkpoint, so the default path makes zero block-accessor calls.
13 gate tests green under -race; full proposervm suite green; go build ./... exit 0.
Deferred to follow-ons (gate is dormant + unwired in production): M4 cert-
unavailability halt runbook + grace window, L6 MemCertStore eviction (no ingest
caller yet), proposervm Accept-path integration test, positive valid-cert test
(needs consensus to export cert encoders).
Node-side integration of luxfi/consensus v1.29.0 Quasar compact-cert finality.
luxd finalizes on classical Snow every block; at CHECKPOINTS a sampled committee
QuasarCert over the finalized digest is VERIFIED. This wires the verify half as
an OPTIONAL, FORWARD-DATED, DORMANT-BY-DEFAULT check in the block-accept path.
consensus/quasar (new package):
- Gate.VerifyAccepted: the accept-path safety boundary. nil gate / zero
activation / below-activation-height / non-checkpoint => no-op (classical
Snow unchanged). Post-activation at a checkpoint => REQUIRE a valid cert
bound to the finalized block; fail closed (missing/mismatch/invalid -> error).
- ActivationConfig: forward-dated dormant switch (Height==0 => never; optional
wall-clock Time gate). The safety contract: this branch changes NOTHING about
live finality until the owner sets a real activation height.
- bindCheck: anti-replay binding (cert chain/height/block/state == finalized).
- policyStore: default posture HYBRID_PQ = Beam(BLS) ^ Pulsar (Pulsar verify
~140us < BLS, cert ~27KB); STRICT_DUAL_PQ / POLARIS configurable. The cert
can never select its own (weaker) policy (I1/I2 enforced by consensus).
- ValidatorSet/MemCertStore: the per-leg key + cert-lookup seams (HYBRID_PQ
BLS+Pulsar keys now; Corona/Magnetar/weighted-set + per-epoch resolution are
the activation-wiring follow-on).
- Producer (scaffolding): the committee-sign service contract + MaybeProduce
request site, sharing ONE checkpoint cadence with verify. nil producer =
verify-only (the default). Concrete pulsard signer is the follow-on; it needs
consensus to export the (currently package-private) cert/payload ENCODERS.
proposervm: post_fork_block.Accept calls vm.verifyQuasarFinality(b) BEFORE the
accept commits, so an un-PQ-certified checkpoint halts without persisting. nil
gate (default) => unchanged classical accept. SetQuasarGate installs it.
Tests: 12 gate tests green (dormant no-op, nil-safe, below-activation, time-gate,
non-checkpoint, missing-fails-closed, 4x mismatch/anti-replay, real-verifier
delegation, validator-set-unavailable, producer nil-safety/dormant/active). Full
proposervm suite green; go build ./... exit 0.
node/consensus/quasar + node/consensus/zap + node/node/quasar.go were a
superseded duplicate of the live post-quantum finality path
(consensus/protocol/quasar WeightedQuorumCert, driven by the chain engine).
The node-side hub wrapped that live core but added only dormant scaffolding:
- an undriven P-Chain finality loop (finCh never fed; run() sat idle)
- a fail-closed CoronaCoordinator stub (Sign/Verify errored in prod,
InitializeCorona was test-only, so q.corona stayed nil)
- a QuantumFinality store nothing read (only n.Quasar.Stop() was ever called)
Dependency trace: zero cross-repo importers; the Q-Chain VM
(luxfi/chains/quantumvm) is external, independent, and finalized by the live
chain-engine QuorumCert path, not this hub; consensus/zap (ZAP/DID agentic
bridge) was a collateral dormant island on the same stub with no external
importers. Wiring was impossible without driving the live accept path or
adding a redundant second finality authority, both out of scope, so the hub
is removed rather than wired.
Live consensus/protocol/quasar and consensus/engine/chain are untouched.
Q-Chain VM registration, genesis, and critical-by-default status are
unchanged. Genuine PQ tests (TLS hybrid KEX, ML-DSA UTXO, hostname
addressing) are preserved; only the dormant-hub tests were removed.
cpuBLSVerify / cpuMLDSAVerify previously did length checks and returned true for
any well-formed input — a no-GPU node would ACCEPT FORGED signatures once LP-210
wires the GPU pipeline into block-accept. Now they perform REAL verification via
luxfi/crypto pure-Go primitives:
- BLS: bls.Verify after PublicKeyFromCompressedBytes/SignatureFromBytes
(enforces exact length, on-curve, subgroup membership; malformed => false).
- ML-DSA: pub.VerifySignature (FIPS-204 nil-context), pk 1952, sig 3309.
- Corona + ZK: FAIL CLOSED (return false) — luxfi/crypto has no pure-Go verifier
and the Corona GPU kernel is the known-wrong-prime BLOCKED kernel; never
rubber-stamp an unverified signature.
ML-DSA signature size corrected 3293 (stale round-3 Dilithium3) -> 3309 (FIPS-204
ML-DSA-65) in MLDSAWork doc + gpuMLDSAVerify flatten width, so the CPU oracle and
GPU path size the signature identically; pinned by TestMLDSA_WorkStructSizeIsCanonical.
Tests rebuilt to carry REAL valid BLS/ML-DSA signatures (was random bytes the old
format-only check accepted). TestCPUVerify_RealOracle proves: valid accepted,
forged rejected, Corona+ZK fail closed. All green.
go.sum: 7 luxfi modules (chains, keys, kms, sdk, staking, zap) had their content
hashes refreshed to the canonical registry values after an upstream re-tag (same
versions, same go.mod — source re-tag only). 'go mod verify' = all modules
verified. Surgical patch (7 lines), minimal go.sum preserved.
(cherry picked from commit e40f04b112f8b5d15223325199db4b981f05878c)
vms.go drops the dexvm import+entry, calls appendDChainVM; vms_dchain.go (//go:build dchain)
links it, vms_nodchain.go (//go:build !dchain) no-ops; vms/dexvm alias gated //go:build
dchain + doc_nodchain.go placeholder. Genesis-gate (constants.DexVMID, no pkg dep) retained.
VERIFIED: public 'go list -deps ./node/' has ZERO chains/dexvm|luxfi/dex|gpu-kernels|luxcpp;
-tags dchain brings them in. Both builds green.
Consensus change -- held for human review before merge/push (bundles with merkle-activation).
Remove unused bloom filter, test helpers, metrics scaffolding, and
linearizable VM wrapper. Trim stale go.sum entries. Add genesis builder
helpers and xvm FX/genesis initialization.