open-standards/smart-byte/smart-byte-rs/crates/smart-byte-tendermint/tests/voting_power_math.rs
Transaction Science 5ae7e4ef86 ingest wave E: 3 crates · op-bin + smart-byte-tendermint + eoc-safety
OpenPay (1 crate, 1801 LOC, 57 tests)
  op-bin              BIN/IIN database + range matching + card-network
                      classification. 8-digit normalized prefix Bin +
                      BinRange. Sorted-vec interval tree with O(log N) point
                      lookup + overlap rejection. CardNetwork classify()
                      with structural rules (Visa 4, MC 51-55/2221-2720,
                      Amex 34/37, Discover, JCB, Diners, UnionPay, RuPay,
                      Mir, Troy, Maestro, Elo). Static prefix tables +
                      build_default_tree(). ISO/IEC 7812-1 Annex B Luhn
                      (validate / is_valid / check_digit). Card-type +
                      issuer-country + Durbin regulated-debit. PCI-safe:
                      8-digit cap, no full-PAN APIs.

Smart Byte (1 crate, ~1500 LOC, 20 tests)
  smart-byte-tendermint  BFT consensus. Step enum + Round + propose/prevote/
                         precommit/commit FSM with voting-power tallies.
                         ValidatorSet with 2/3+1 quorum, 1/3+1 trust
                         threshold, round-robin proposer. Block / Header /
                         Commit / CommitSig with Blake3 hashing. Light client
                         (sequential + skipping). ABCI Application trait +
                         EchoApp. DuplicateVoteEvidence + LightClientAttackEvidence.
                         IBC ClientState + ConsensusState + light-client
                         update.

EOC (1 crate, 2084 LOC, 23 tests)
  eoc-safety          AI safety primitives. RegexSet over 16 prompt-injection
                      signatures. 13-family jailbreak detector (DAN/DUDE/
                      Grandma/STAN/AIM/dev-mode/etc.). Presidio-style PII
                      redactor with Luhn-validated CC. Toxicity / bias /
                      NSFW classifier traits + heuristic baselines (5-axis
                      bias, 4-category NSFW with hard-reject for minors).
                      Constitutional AI critique→revise loop. Composable
                      InputGuard / OutputGuard pipelines. JSON-Schema-subset
                      output validator. Token-bucket rate limiter +
                      abuse-window detection. Red-team replay harness.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-24 16:52:07 -04:00

70 lines
2.1 KiB
Rust

use smart_byte_tendermint::validator::{Validator, ValidatorId, ValidatorSet};
fn vid(b: u8) -> ValidatorId {
ValidatorId::from_bytes([b; 32])
}
#[test]
fn quorum_is_two_thirds_plus_one_for_equal_power() {
// 4 validators with power 1 each, total = 4
let vs = ValidatorSet::new((0..4).map(|i| Validator::new(vid(i as u8), 1))).unwrap();
assert_eq!(vs.total_voting_power(), 4);
// floor(2*4/3)+1 = floor(2.66)+1 = 2+1 = 3
assert_eq!(vs.quorum(), 3);
}
#[test]
fn quorum_handles_weighted_validators() {
// total = 100 → quorum = 66+1 = 67
let vs = ValidatorSet::new(vec![
Validator::new(vid(1), 40),
Validator::new(vid(2), 30),
Validator::new(vid(3), 20),
Validator::new(vid(4), 10),
])
.unwrap();
assert_eq!(vs.total_voting_power(), 100);
assert_eq!(vs.quorum(), 67);
assert_eq!(vs.trust_threshold(), 34);
}
#[test]
fn has_quorum_aggregates_signers_by_power() {
let vs = ValidatorSet::new(vec![
Validator::new(vid(1), 40),
Validator::new(vid(2), 30),
Validator::new(vid(3), 20),
Validator::new(vid(4), 10),
])
.unwrap();
// 40 + 30 = 70 ≥ 67 → quorum
assert!(vs.has_quorum([&vid(1), &vid(2)].into_iter()));
// 40 + 20 = 60 < 67 → no quorum
assert!(!vs.has_quorum([&vid(1), &vid(3)].into_iter()));
// unknown validator → no quorum
assert!(!vs.has_quorum([&vid(99)].into_iter()));
}
#[test]
fn overflow_returns_error() {
let err = ValidatorSet::new(vec![
Validator::new(vid(1), u64::MAX),
Validator::new(vid(2), 1),
]);
assert!(err.is_err());
}
#[test]
fn proposer_rotates_by_round() {
let vs = ValidatorSet::new((0..4).map(|i| Validator::new(vid(i as u8), 1))).unwrap();
let p0 = vs.proposer(1, 0).unwrap().id;
let p1 = vs.proposer(1, 1).unwrap().id;
let p2 = vs.proposer(1, 2).unwrap().id;
let p3 = vs.proposer(1, 3).unwrap().id;
let p4 = vs.proposer(1, 4).unwrap().id;
// round-robin: 1,2,3,0,1
assert_ne!(p0, p1);
assert_ne!(p1, p2);
assert_ne!(p2, p3);
assert_eq!(p0, p4);
}