Files
consensus/pkg/rust/Cargo.toml
T
zeekayandHanzo Dev c22f13f63e cert: the weight clause Go runs last, the set admitted whole, and one workspace
THE TOTAL. `Register` in `validator/registration.go` runs seven clauses, and
this port had six. The seventh is `math.Add64` on the running weight: a set
whose weights sum past what a `uint64` holds is refused entire, before any of
it is admitted. Without it `total_stake` folded with `saturating_add` and
`voted_stake` summed with `saturating_add`, so a set of four validators at
2^63 reported `u64::MAX` staked AND `u64::MAX` voted — and
`u64::MAX > floor(2·u64::MAX/3)`. A certificate carrying HALF the stake
cleared the two-thirds export floor, which is the rung a bridge reads.

Clamping is what makes the two sides agree on a number neither can represent,
so neither clamps any more. The set carries its total as a fact established at
admission with `checked_add` — one source of truth, decided at the one place
that still has a registration to refuse — and `voted_stake` is checked too:
the voters are a subset of the members, so against a set this crate admitted
the overflow is unreachable, and reaching it is evidence about the stake
source rather than about the votes. `weighted_quasar` takes the same
treatment: a vector with no representable total leaves by the same door as a
zero total, since a plain sum WRAPS to a small total and sizes the count gate
below the stake quorum it exists to anticipate.

THE SET. `insert` admits one validator and reports on that one, which is a
property no set can be built out of: a caller that inserts in a loop and logs
what failed is left holding a set missing a member, with `n` short by one and
the total short by that member's stake — the two numbers every threshold is
read against, wrong, with nothing to say so. `ValidatorSet::register` is the
port of Go's whole-set door: sorted by node id so which duplicate a set is
refused on cannot depend on the order a caller built its input, and
all-or-nothing because the set under construction is a local. `insert` stays
for a membership change to a set already live, and now says so.

THE BINDING. `pkg/typescript` path-depends on `pkg/rust` and could not
compile: narrowing the node id from 32 bytes to 20 left two `NodeID::from([u8;
32])` calls with no impl. It is a 20-byte API now, and the 20 bytes come from
20-byte input — `arr[..20]` would reintroduce exactly the collision the
narrowing exists to prevent, so a hex string of the wrong length is refused,
never trimmed. The width is `size_of::<cert::NodeId>()`, taken from the core
rather than restated, so it cannot drift again. `addValidator` also stopped
discarding the core's answer, which reported a validator as added when the
set had refused it.

And the two crates are one workspace, because that is what they already were.
Built separately they can disagree and did — nothing built both, so nothing
noticed. `cargo test` at the root now builds both, which turns this class of
break from a review finding into a compile error. It also surfaced two tests
in the binding that had been failing unnoticed: they voted with unregistered
ids, from before only members were counted.

No signed byte moves. `canonical_vote_message` is untouched, the node id
enters no signed message, and the Go corpus and the frozen `pop` vectors pass
unchanged.

Verified: 97 tests green (92 rust, 5 napi), clippy clean at the workspace
root, the binding's 29 JS tests green against a linux build of it. Red's PoC
— four validators of 2^63, two voting, read at QUASAR — returned `Ok(())`
before and now dies at registration with `WeightOverflow`.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-01 11:53:54 -07:00

65 lines
1.8 KiB
TOML

[package]
name = "lux-consensus"
version = "1.22.4"
edition = "2021"
description = "Lux Consensus SDK — pure-Rust Quasar post-quantum probabilistic consensus (Wave / FPC / Photon / Focus / Quasar PQ finality via hybrid BLS12-381 + Pulsar = P3Q)"
license-file = "LICENSE"
repository = "https://github.com/luxfi/consensus"
homepage = "https://lux.network"
readme = "README.md"
keywords = ["consensus", "post-quantum", "quasar", "probabilistic", "lux"]
categories = ["cryptography", "algorithms", "network-programming"]
authors = ["Lux Industries Inc."]
exclude = ["target/"]
[package.metadata.docs.rs]
no-default-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
hex = "0.4"
libc = "0.2"
# BLS12-381 signatures for Quasar consensus
blst = "0.3"
# Optional GPU acceleration dependencies
# MLX (Apple Silicon) - via C++ bindings
mlx-sys = { version = "0.1", optional = true }
# BLAKE3 for fast hashing (SIMD optimized)
blake3 = { version = "1.5", optional = true }
# Parallel processing
rayon = { version = "1.10", optional = true }
[lib]
name = "lux_consensus"
path = "src/lib.rs"
crate-type = ["rlib"]
[features]
default = []
# CPU-optimized with SIMD (no GPU)
simd = ["blake3", "rayon"]
# Apple Silicon GPU acceleration via MLX
mlx = ["mlx-sys", "simd"]
# NVIDIA GPU acceleration via CUDA (future)
cuda = ["simd"]
# Full GPU acceleration (MLX on macOS, CUDA on Linux/Windows)
gpu = ["mlx", "cuda"]
# [[example]]
# name = "basic_usage"
# path = "examples/basic_usage.rs"
[dev-dependencies]
criterion = { version = "0.7.0", features = ["html_reports"] }
# Reads conformance/corpus.json — the Go-generated finality standard this crate
# is checked against. Tests only; it is not in the shipped crate.
serde_json = "1.0"
[[bench]]
name = "consensus_bench"
harness = false