open-standards/smart-byte/smart-byte-rs/crates/smart-byte-ilp/src/btp.rs
Transaction Science 8180ee8c71 ingest wave D: 3 crates · op-fraud-graph + smart-byte-ilp + eoc-quantize
OpenPay (1 crate, 2487 LOC, 33 tests)
  op-fraud-graph    Graph-based fraud detection. EntityKind (card/email/
                    device/IP/address/phone/BIN+last4/account) with
                    canonicalization + hashed EntityKey + billing↔shipping
                    mismatch detection. Adjacency-list FraudGraph with
                    idempotent upsert + edge-merge. Double-hashing Bloom
                    filter (capacity+FPR-sized). Union-find connected
                    components. PageRank with dangling-sink handling.
                    Louvain community detection. Shared-instrument hub
                    rings. Sliding ring-buffer velocity counters. Synthetic
                    identity heuristics (freshness + heavy-use + mail-drop).
                    Structuring / smurfing / mule-chain DFS. EntityRisk +
                    TransactionRisk + RiskBand combiner.

Smart Byte (1 crate, ~1844 LOC, 44 tests)
  smart-byte-ilp    Interledger Protocol v4. OER codec (length-determinant,
                    var-octet-string, BE u32/u64). Prepare/Fulfill/Reject
                    packet roundtrip with all 19 IL-RFC-27 reject codes.
                    SHA-256 Condition + Fulfillment with constant-time
                    verify. ILP address validator (7 schemes, 1-128 char
                    segments, 1023-byte cap, segment-aligned prefix match).
                    STREAM (15 frame types). BTP. SPSP payment-pointer
                    resolver. Open Payments API. Longest-prefix routing
                    Connector with fixed-point quote conversion + balance +
                    rate-limit checks.

EOC (1 crate, 1921 LOC, 36 tests)
  eoc-quantize      Quantization primitives. int8 (symmetric/asymmetric
                    with zero-inclusion fix), int4 (GPTQ + AWQ group quant),
                    int2 (BitNet), fp8 (E4M3/E5M2), nf4 (QLoRA). GGUF v3
                    header parse. safetensors read sketch. Calibration
                    datasets + per-channel scales. KV-cache quant. Energy
                    tradeoff curves (joules-per-token across schemes).

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

182 lines
5.8 KiB
Rust

//! BTP — Bilateral Transfer Protocol — message types.
//!
//! BTP is the framing two ILP connectors speak to each other over a
//! single persistent WebSocket (or other reliable bidirectional stream).
//! Each BTP message is a `(type, request_id, sub_protocols[])` triple
//! plus a type-specific body.
//!
//! See IL-RFC-23.
use crate::error::{IlpError, Result};
use crate::oer::{
decode_length, decode_u32, decode_var_octet_string, encode_length, encode_u32,
encode_var_octet_string,
};
/// BTP packet-type discriminators.
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BtpPacketType {
/// `1` — Response (success).
Response = 1,
/// `2` — Error response.
ErrorResponse = 2,
/// `6` — Message (request).
Message = 6,
/// `7` — Transfer (request carrying an ILP `Prepare`).
Transfer = 7,
}
impl BtpPacketType {
/// Map a wire byte to a BTP packet type.
pub fn from_u8(b: u8) -> Result<Self> {
Ok(match b {
1 => BtpPacketType::Response,
2 => BtpPacketType::ErrorResponse,
6 => BtpPacketType::Message,
7 => BtpPacketType::Transfer,
other => return Err(IlpError::UnknownBtpPacketType(other)),
})
}
}
/// Content-type marker for a BTP sub-protocol payload.
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ContentType {
/// `0` — application/octet-stream.
OctetStream = 0,
/// `1` — text/plain-utf8.
TextPlain = 1,
/// `2` — application/json.
Json = 2,
}
impl ContentType {
/// Lift a byte into a `ContentType`. Unknown values fall back to
/// `OctetStream`.
pub fn from_u8(b: u8) -> Self {
match b {
1 => ContentType::TextPlain,
2 => ContentType::Json,
_ => ContentType::OctetStream,
}
}
}
/// A single BTP sub-protocol entry. The reference sub-protocol is
/// `"ilp"`, which carries an ILP packet in `data`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BtpSubProtocol {
/// Protocol name (e.g. `"ilp"`).
pub name: String,
/// Content-type of the payload.
pub content_type: ContentType,
/// Payload bytes.
pub data: Vec<u8>,
}
/// A complete BTP message envelope.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BtpMessage {
/// Packet type discriminator.
pub packet_type: BtpPacketType,
/// Request id matching responses to requests.
pub request_id: u32,
/// Ordered list of sub-protocol entries.
pub sub_protocols: Vec<BtpSubProtocol>,
}
impl BtpMessage {
/// Encode the message to its on-wire byte representation.
pub fn encode(&self) -> Vec<u8> {
let mut out = Vec::new();
out.push(self.packet_type as u8);
encode_u32(&mut out, self.request_id);
let mut body = Vec::new();
encode_length(&mut body, self.sub_protocols.len());
for sp in &self.sub_protocols {
encode_var_octet_string(&mut body, sp.name.as_bytes());
body.push(sp.content_type as u8);
encode_var_octet_string(&mut body, &sp.data);
}
// BTP wraps the sub-protocol list in a length-prefixed body.
crate::oer::encode_length(&mut out, body.len());
out.extend_from_slice(&body);
out
}
/// Decode the message from its on-wire bytes.
pub fn decode(input: &[u8]) -> Result<Self> {
if input.is_empty() {
return Err(IlpError::InvalidPacket("btp empty".into()));
}
let packet_type = BtpPacketType::from_u8(input[0])?;
let (request_id, used) = decode_u32(&input[1..])?;
let mut cursor = 1 + used;
let (body_len, used) = decode_length(&input[cursor..])?;
cursor += used;
let body_end = cursor
.checked_add(body_len)
.ok_or_else(|| IlpError::InvalidPacket("btp body overflow".into()))?;
if input.len() < body_end {
return Err(IlpError::InvalidPacket("btp body truncated".into()));
}
let body = &input[cursor..body_end];
let (n_sp, used) = decode_length(body)?;
let mut bcur = used;
let mut sub_protocols = Vec::with_capacity(n_sp);
for _ in 0..n_sp {
let (name_bytes, used) = decode_var_octet_string(&body[bcur..])?;
bcur += used;
let name = core::str::from_utf8(name_bytes)
.map_err(|e| IlpError::InvalidPacket(format!("btp sp name utf-8: {e}")))?
.to_string();
if bcur >= body.len() {
return Err(IlpError::InvalidPacket("btp sp content_type missing".into()));
}
let content_type = ContentType::from_u8(body[bcur]);
bcur += 1;
let (data_bytes, used) = decode_var_octet_string(&body[bcur..])?;
bcur += used;
sub_protocols.push(BtpSubProtocol {
name,
content_type,
data: data_bytes.to_vec(),
});
}
Ok(BtpMessage {
packet_type,
request_id,
sub_protocols,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn btp_roundtrip() {
let msg = BtpMessage {
packet_type: BtpPacketType::Message,
request_id: 42,
sub_protocols: vec![
BtpSubProtocol {
name: "ilp".into(),
content_type: ContentType::OctetStream,
data: vec![1, 2, 3, 4],
},
BtpSubProtocol {
name: "auth".into(),
content_type: ContentType::TextPlain,
data: b"token".to_vec(),
},
],
};
let wire = msg.encode();
let back = BtpMessage::decode(&wire).unwrap();
assert_eq!(msg, back);
}
}