mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
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]>
62 lines
1.4 KiB
JSON
62 lines
1.4 KiB
JSON
{
|
|
"name": "@luxfi/consensus",
|
|
"version": "1.22.1",
|
|
"description": "Lux Consensus SDK for TypeScript/Node.js - Native performance with type safety",
|
|
"main": "index.js",
|
|
"types": "index.d.ts",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "https://github.com/luxfi/consensus"
|
|
},
|
|
"license": "MIT",
|
|
"keywords": [
|
|
"lux",
|
|
"consensus",
|
|
"blockchain",
|
|
"bft",
|
|
"byzantine",
|
|
"napi-rs",
|
|
"native"
|
|
],
|
|
"files": [
|
|
"index.js",
|
|
"index.d.ts",
|
|
"*.node"
|
|
],
|
|
"napi": {
|
|
"name": "lux-consensus",
|
|
"triples": {
|
|
"defaults": true,
|
|
"additional": [
|
|
"aarch64-apple-darwin",
|
|
"x86_64-apple-darwin",
|
|
"aarch64-unknown-linux-gnu",
|
|
"x86_64-unknown-linux-gnu",
|
|
"x86_64-pc-windows-msvc"
|
|
]
|
|
}
|
|
},
|
|
"engines": {
|
|
"node": ">= 18"
|
|
},
|
|
"scripts": {
|
|
"artifacts": "napi artifacts",
|
|
"build": "napi build --platform --release",
|
|
"build:debug": "napi build --platform",
|
|
"prepublishOnly": "napi prepublish -t npm",
|
|
"test": "node --test test/*.test.js",
|
|
"universal": "napi universal",
|
|
"version": "napi version"
|
|
},
|
|
"devDependencies": {
|
|
"@napi-rs/cli": "^2.18.0"
|
|
},
|
|
"optionalDependencies": {
|
|
"@luxfi/consensus-darwin-arm64": "1.22.0",
|
|
"@luxfi/consensus-darwin-x64": "1.22.0",
|
|
"@luxfi/consensus-linux-arm64-gnu": "1.22.0",
|
|
"@luxfi/consensus-linux-x64-gnu": "1.22.0",
|
|
"@luxfi/consensus-win32-x64-msvc": "1.22.0"
|
|
}
|
|
}
|