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]>
112 lines
3.7 KiB
Rust
112 lines
3.7 KiB
Rust
//! Tendermint evidence — proofs of validator misbehavior.
|
|
//!
|
|
//! Tendermint slashes two classes of misbehavior:
|
|
//!
|
|
//! * **DuplicateVote** — a validator signed two different votes at the
|
|
//! same `(height, round, kind)`. This is the prototypical
|
|
//! double-signing offense.
|
|
//! * **LightClientAttack** — a validator signed a commit on a
|
|
//! conflicting fork that a light client could be fooled into
|
|
//! trusting (lunatic / equivocation / amnesia variants).
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::block::Commit;
|
|
use crate::error::{Error, Result};
|
|
use crate::validator::ValidatorId;
|
|
use crate::vote::Vote;
|
|
|
|
/// Proof of a validator double-signing two distinct votes.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct DuplicateVoteEvidence {
|
|
/// First conflicting vote.
|
|
pub vote_a: Vote,
|
|
/// Second conflicting vote.
|
|
pub vote_b: Vote,
|
|
}
|
|
|
|
impl DuplicateVoteEvidence {
|
|
/// Validate that the two votes are in fact a double-sign.
|
|
///
|
|
/// They must:
|
|
/// * come from the same validator;
|
|
/// * share `(height, round, kind)`;
|
|
/// * vote for different `block_hash` values.
|
|
pub fn verify(&self) -> Result<()> {
|
|
if self.vote_a.validator != self.vote_b.validator {
|
|
return Err(Error::InvalidEvidence("validator mismatch"));
|
|
}
|
|
if self.vote_a.height != self.vote_b.height {
|
|
return Err(Error::InvalidEvidence("height mismatch"));
|
|
}
|
|
if self.vote_a.round != self.vote_b.round {
|
|
return Err(Error::InvalidEvidence("round mismatch"));
|
|
}
|
|
if self.vote_a.kind != self.vote_b.kind {
|
|
return Err(Error::InvalidEvidence("kind mismatch"));
|
|
}
|
|
if self.vote_a.block_hash == self.vote_b.block_hash {
|
|
return Err(Error::InvalidEvidence("votes agree"));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// The misbehaving validator.
|
|
pub fn offender(&self) -> ValidatorId {
|
|
self.vote_a.validator
|
|
}
|
|
}
|
|
|
|
/// Proof that a conflicting block commit exists at the same height.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct LightClientAttackEvidence {
|
|
/// The honest, canonical commit.
|
|
pub canonical: Commit,
|
|
/// The conflicting commit that fooled (or could fool) the light client.
|
|
pub conflicting: Commit,
|
|
}
|
|
|
|
impl LightClientAttackEvidence {
|
|
/// Validate the evidence: same height, distinct block hashes.
|
|
pub fn verify(&self) -> Result<()> {
|
|
if self.canonical.height != self.conflicting.height {
|
|
return Err(Error::InvalidEvidence("height mismatch"));
|
|
}
|
|
if self.canonical.block_hash == self.conflicting.block_hash {
|
|
return Err(Error::InvalidEvidence("commits agree"));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Compute the intersection of validators that signed both commits —
|
|
/// these are the offending validators.
|
|
pub fn offenders(&self) -> Vec<ValidatorId> {
|
|
let a: std::collections::HashSet<_> =
|
|
self.canonical.signatures.iter().map(|s| s.validator).collect();
|
|
self.conflicting
|
|
.signatures
|
|
.iter()
|
|
.map(|s| s.validator)
|
|
.filter(|id| a.contains(id))
|
|
.collect()
|
|
}
|
|
}
|
|
|
|
/// Discriminated evidence union submitted to the chain.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum Evidence {
|
|
/// A validator double-signed.
|
|
DuplicateVote(DuplicateVoteEvidence),
|
|
/// A light-client attack was detected.
|
|
LightClientAttack(LightClientAttackEvidence),
|
|
}
|
|
|
|
impl Evidence {
|
|
/// Validate the evidence.
|
|
pub fn verify(&self) -> Result<()> {
|
|
match self {
|
|
Self::DuplicateVote(e) => e.verify(),
|
|
Self::LightClientAttack(e) => e.verify(),
|
|
}
|
|
}
|
|
}
|