open-standards/smart-byte/smart-byte-rs/crates/smart-byte-tendermint/src/light_client.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

126 lines
4.1 KiB
Rust

//! Tendermint light client.
//!
//! A light client maintains a "trusted" header at some height and
//! verifies later headers by one of two paths:
//!
//! * **Sequential** — verify that the next height's commit is signed
//! by 2/3+1 of the trusted validator set, and the new header's
//! `last_commit_hash` matches.
//! * **Skipping** — jump multiple heights forward if at least a
//! 1/3+1 *trust threshold* of the current trusted validator set
//! has also signed the target commit. This is the mechanism used
//! by IBC clients to bridge sparse update frequencies.
use crate::block::{Commit, Header};
use crate::error::{Error, Result};
use crate::validator::ValidatorSet;
/// Light-client trust state.
#[derive(Debug, Clone)]
pub struct TrustedState {
/// The most recently trusted header.
pub header: Header,
/// Validator set the trusted header was signed under.
pub validators: ValidatorSet,
}
impl TrustedState {
/// Construct a fresh trusted state (e.g. from a genesis header).
pub fn new(header: Header, validators: ValidatorSet) -> Self {
Self { header, validators }
}
}
/// Verify a sequential header update.
///
/// `commit` must commit `new_header.hash()` and the precommit signers
/// must hold 2/3+1 of `trusted.validators` voting power.
pub fn verify_sequential(
trusted: &TrustedState,
new_header: &Header,
commit: &Commit,
) -> Result<()> {
if new_header.height != trusted.header.height + 1 {
return Err(Error::LightClient("not sequential"));
}
if new_header.last_block_hash != trusted.header.hash() {
return Err(Error::LightClient("last_block_hash mismatch"));
}
if commit.height != new_header.height {
return Err(Error::LightClient("commit height mismatch"));
}
if commit.block_hash != new_header.hash() {
return Err(Error::LightClient("commit block_hash mismatch"));
}
let signers: Vec<_> = commit.signatures.iter().map(|s| &s.validator).collect();
if !trusted.validators.has_quorum(signers) {
return Err(Error::LightClient("no 2/3+1 quorum"));
}
Ok(())
}
/// Verify a skipping header update.
///
/// `commit` must commit `new_header.hash()`. The skip is permitted if
/// signers of `commit` hold at least 1/3+1 of `trusted.validators`
/// voting power *and* hold 2/3+1 of `new_validators` voting power.
pub fn verify_skipping(
trusted: &TrustedState,
new_header: &Header,
new_validators: &ValidatorSet,
commit: &Commit,
) -> Result<()> {
if new_header.height <= trusted.header.height {
return Err(Error::LightClient("not forward"));
}
if commit.height != new_header.height {
return Err(Error::LightClient("commit height mismatch"));
}
if commit.block_hash != new_header.hash() {
return Err(Error::LightClient("commit block_hash mismatch"));
}
let signers: Vec<_> = commit.signatures.iter().map(|s| &s.validator).collect();
// 1/3+1 of TRUSTED set
let trusted_power = trusted
.validators
.iter()
.filter(|v| signers.iter().any(|s| **s == v.id))
.map(|v| v.voting_power)
.sum::<u64>();
if trusted_power < trusted.validators.trust_threshold() {
return Err(Error::LightClient("trust threshold not met"));
}
// 2/3+1 of NEW set
if !new_validators.has_quorum(signers) {
return Err(Error::LightClient("new validator quorum not met"));
}
Ok(())
}
/// Update a `TrustedState` after a verified sequential step.
pub fn apply_sequential(
trusted: &mut TrustedState,
new_header: Header,
new_validators: ValidatorSet,
commit: &Commit,
) -> Result<()> {
verify_sequential(trusted, &new_header, commit)?;
trusted.header = new_header;
trusted.validators = new_validators;
Ok(())
}
/// Update a `TrustedState` after a verified skipping step.
pub fn apply_skipping(
trusted: &mut TrustedState,
new_header: Header,
new_validators: ValidatorSet,
commit: &Commit,
) -> Result<()> {
verify_skipping(trusted, &new_header, &new_validators, commit)?;
trusted.header = new_header;
trusted.validators = new_validators;
Ok(())
}