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]>
Lux Consensus Source Code Organization
This directory contains implementations of the Lux consensus framework in multiple programming languages. Each language implementation provides the same consensus algorithms with language-specific optimizations and idioms.
Directory Structure
src/
├── c/ # C implementation (high-performance, minimal overhead)
├── cpp/ # C++ implementation with MLX extensions (GPU acceleration)
├── go/ # Go implementation (production blockchain integration)
├── python/ # Python implementation (research and prototyping)
└── rust/ # Rust implementation (memory-safe systems programming)
Language Implementations
Go (/src/go/)
- Status: Production-ready
- Use Case: Core blockchain node integration
- Import Path:
github.com/luxfi/consensus(via go.work at root) - Features: Full integration with Lux node, concurrent processing
C (/src/c/)
- Status: Data structures only — not real consensus (per SDK audit)
- Use Case: Embedded systems, performance-critical applications
- Features: Minimal dependencies, ZeroMQ networking, SIMD optimizations
Rust (/src/rust/)
- Status: FFI wrapper around the C library — inherits C limitations, not native consensus (per SDK audit)
- Use Case: Memory-safe systems, async applications
- Features: Zero-cost abstractions, async/await, compile-time guarantees
Python (/src/python/)
- Status: Research/Development
- Use Case: Prototyping, research, data analysis
- Features: NumPy integration, ML frameworks, visualization
C++ (/src/cpp/)
- Status: Development
- Use Case: High-performance with GPU acceleration
- Features: MLX extensions, template metaprogramming, SIMD/GPU support
Building
From the repository root:
# Build all implementations
make build
# Build specific language
make build-go
make build-c
make build-rust
make build-python
make build-cpp
Testing
From the repository root:
# Test all implementations
make test
# Test specific language
make test-go
make test-c
make test-rust
make test-python
make test-cpp
Consensus Engines
All implementations support these consensus engines (Quasar family):
- Wave - Threshold voting with fast probabilistic consensus (production)
- Nova - Linear chain consensus (wraps Ray sub-protocol)
- Nebula - DAG consensus with safe-prefix commit (wraps Field sub-protocol)
- PostQuantum - Quantum-resistant consensus with BLS + Pulsar + ML-DSA
- Chain - Linear chain consensus for ordered blocks
- DAG - Full directed acyclic graph consensus
Performance Benchmarks
| Implementation | Votes/Second | Memory Usage | Latency |
|---|---|---|---|
| C | 14,000+ | < 10 MB | < 1ms |
| Rust | 13,500+ | < 15 MB | < 1ms |
| Go | 12,000+ | < 20 MB | < 2ms |
| C++ (w/ MLX) | 15,000+ | < 25 MB | < 1ms |
| Python | 5,000+ | < 50 MB | < 5ms |
Note. These per-implementation votes/sec figures are unverified and, per the SDK audit, several measure data-structure insertion on stub/wrapper SDKs (C = data structures only, Rust = FFI wrapper over C, C++ = Wave-only stub); only the Python SDK implements real consensus. Treat as illustrative, not measured consensus throughput. See
.github/workflows/README.mdand the "Honest Assessment" block inLLM.md.
Protocol Compatibility
All implementations use the same binary protocol for network communication:
┌─────────────┬────────────┬──────────┬───────────┬──────────┐
│ Engine Type │ Node ID │ Block ID │ Vote Type │ Reserved │
│ (1 byte) │ (2 bytes) │ (2 bytes)│ (1 byte) │ (2 bytes)│
└─────────────┴────────────┴──────────┴───────────┴──────────┘
This ensures interoperability between different language implementations.
Development Guidelines
- Consistency: All implementations should provide the same consensus guarantees
- Testing: Each implementation must have comprehensive test coverage
- Documentation: Language-specific documentation in
docs/{language}/ - Performance: Optimize for language strengths while maintaining correctness
- Compatibility: Maintain protocol compatibility across all implementations
Contributing
When adding features or fixes:
- Implement in the reference implementation (Go)
- Port to other languages maintaining consistency
- Add tests for all implementations
- Update documentation
See CONTRIBUTING.md for detailed guidelines.
License
Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.