From f08dfbd61118ad2c2d6903c22de4951af72fba60 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Sat, 18 Apr 2026 22:59:32 +0200 Subject: [PATCH] 0.5.5 --- Cargo.toml | 2 +- khbb_lib/src/enriched_classifier.rs | 215 ++++++++++++++++++++++++++++ khbb_lib/src/lib.rs | 9 ++ khbb_lib/src/listener.rs | 92 +++++++++++- 4 files changed, 316 insertions(+), 2 deletions(-) create mode 100644 khbb_lib/src/enriched_classifier.rs diff --git a/Cargo.toml b/Cargo.toml index fd550a2..09f5ed9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ ] [workspace.package] -version = "0.5.4" +version = "0.5.5" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-bobot" diff --git a/khbb_lib/src/enriched_classifier.rs b/khbb_lib/src/enriched_classifier.rs new file mode 100644 index 0000000..8ae9151 --- /dev/null +++ b/khbb_lib/src/enriched_classifier.rs @@ -0,0 +1,215 @@ +// file: khbb_lib/src/enriched_classifier.rs + +//! Classification of enriched account snapshots into stronger domain signals. + +/// Confirmed or refined event derived from an enriched account snapshot. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub enum KhbbEnrichedConfirmedEvent { + /// Confirmed token account activity. + ConfirmedTokenAccountActivity(KhbbConfirmedTokenAccountActivityEvent), + /// Confirmed mint account activity. + ConfirmedMintAccountActivity(KhbbConfirmedMintAccountActivityEvent), + /// Unknown token-program-owned account activity. + UnknownTokenProgramAccountActivity(KhbbUnknownTokenProgramAccountActivityEvent), +} + +/// Confirmed token account activity. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct KhbbConfirmedTokenAccountActivityEvent { + /// Account pubkey. + pub pubkey: std::string::String, + /// Context slot from the enrichment response. + pub context_slot: u64, + /// Owner program if available. + pub owner: std::option::Option, + /// Lamports if available. + pub lamports: std::option::Option, +} + +/// Confirmed mint account activity. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct KhbbConfirmedMintAccountActivityEvent { + /// Account pubkey. + pub pubkey: std::string::String, + /// Context slot from the enrichment response. + pub context_slot: u64, + /// Owner program if available. + pub owner: std::option::Option, + /// Lamports if available. + pub lamports: std::option::Option, +} + +/// Unknown token-program-owned account activity. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct KhbbUnknownTokenProgramAccountActivityEvent { + /// Account pubkey. + pub pubkey: std::string::String, + /// Context slot from the enrichment response. + pub context_slot: u64, + /// Owner program if available. + pub owner: std::option::Option, + /// Lamports if available. + pub lamports: std::option::Option, +} + +/// Classifies an enriched account snapshot into a stronger confirmed event. +pub(crate) fn classify_enriched_account_snapshot( + snapshot: &crate::KhbbEnrichedAccountSnapshot, +) -> core::result::Result, crate::KhbbError> { + if !snapshot.exists { + return Ok(None); + } + let kind = match &snapshot.kind { + Some(value) => value, + None => { + return Ok(None); + } + }; + match kind { + crate::KhbbEnrichedAccountKind::PotentialTokenAccount => { + Ok(Some( + KhbbEnrichedConfirmedEvent::ConfirmedTokenAccountActivity( + KhbbConfirmedTokenAccountActivityEvent { + pubkey: snapshot.pubkey.clone(), + context_slot: snapshot.context_slot, + owner: snapshot.owner.clone(), + lamports: snapshot.lamports, + }, + ), + )) + } + crate::KhbbEnrichedAccountKind::PotentialMintAccount => { + Ok(Some( + KhbbEnrichedConfirmedEvent::ConfirmedMintAccountActivity( + KhbbConfirmedMintAccountActivityEvent { + pubkey: snapshot.pubkey.clone(), + context_slot: snapshot.context_slot, + owner: snapshot.owner.clone(), + lamports: snapshot.lamports, + }, + ), + )) + } + crate::KhbbEnrichedAccountKind::UnknownAccount => { + let owner = match snapshot.owner.as_deref() { + Some(value) => value, + None => { + return Ok(None); + } + }; + let known_program = + crate::program_registry::classify_known_program_id(owner); + match known_program { + Some(crate::KhbbKnownProgram::SplToken) + | Some(crate::KhbbKnownProgram::SplToken2022) => { + Ok(Some( + KhbbEnrichedConfirmedEvent::UnknownTokenProgramAccountActivity( + KhbbUnknownTokenProgramAccountActivityEvent { + pubkey: snapshot.pubkey.clone(), + context_slot: snapshot.context_slot, + owner: snapshot.owner.clone(), + lamports: snapshot.lamports, + }, + ), + )) + } + _ => Ok(None), + } + } + } +} + +#[cfg(test)] +mod tests { + #[test] + fn classify_enriched_snapshot_returns_confirmed_token_account() { + let snapshot = crate::KhbbEnrichedAccountSnapshot { + pubkey: std::string::String::from("SomePubkey"), + context_slot: 100, + exists: true, + owner: Some(crate::ids::SPL_TOKEN_PROGRAM_ID.to_string()), + lamports: Some(123), + kind: Some(crate::KhbbEnrichedAccountKind::PotentialTokenAccount), + }; + let result = super::classify_enriched_account_snapshot(&snapshot); + assert!(result.is_ok()); + let event_option = result.expect("classify token snapshot"); + assert!(event_option.is_some()); + match event_option.expect("confirmed token event") { + super::KhbbEnrichedConfirmedEvent::ConfirmedTokenAccountActivity(inner) => { + assert_eq!(inner.pubkey, "SomePubkey"); + assert_eq!(inner.context_slot, 100); + assert_eq!(inner.lamports, Some(123)); + } + _ => { + panic!("expected confirmed token account activity"); + } + } + } + + #[test] + fn classify_enriched_snapshot_returns_confirmed_mint_account() { + let snapshot = crate::KhbbEnrichedAccountSnapshot { + pubkey: std::string::String::from("MintPubkey"), + context_slot: 200, + exists: true, + owner: Some(crate::ids::SPL_TOKEN_PROGRAM_ID.to_string()), + lamports: Some(456), + kind: Some(crate::KhbbEnrichedAccountKind::PotentialMintAccount), + }; + let result = super::classify_enriched_account_snapshot(&snapshot); + assert!(result.is_ok()); + let event_option = result.expect("classify mint snapshot"); + assert!(event_option.is_some()); + match event_option.expect("confirmed mint event") { + super::KhbbEnrichedConfirmedEvent::ConfirmedMintAccountActivity(inner) => { + assert_eq!(inner.pubkey, "MintPubkey"); + assert_eq!(inner.context_slot, 200); + assert_eq!(inner.lamports, Some(456)); + } + _ => { + panic!("expected confirmed mint account activity"); + } + } + } + + #[test] + fn classify_enriched_snapshot_returns_unknown_token_program_activity() { + let snapshot = crate::KhbbEnrichedAccountSnapshot { + pubkey: std::string::String::from("UnknownTokenOwnedPubkey"), + context_slot: 300, + exists: true, + owner: Some(crate::ids::SPL_TOKEN_PROGRAM_ID.to_string()), + lamports: Some(789), + kind: Some(crate::KhbbEnrichedAccountKind::UnknownAccount), + }; + let result = super::classify_enriched_account_snapshot(&snapshot); + assert!(result.is_ok()); + let event_option = result.expect("classify unknown token owned snapshot"); + assert!(event_option.is_some()); + match event_option.expect("unknown token owned event") { + super::KhbbEnrichedConfirmedEvent::UnknownTokenProgramAccountActivity(inner) => { + assert_eq!(inner.pubkey, "UnknownTokenOwnedPubkey"); + assert_eq!(inner.context_slot, 300); + } + _ => { + panic!("expected unknown token program account activity"); + } + } + } + + #[test] + fn classify_enriched_snapshot_returns_none_when_account_missing() { + let snapshot = crate::KhbbEnrichedAccountSnapshot { + pubkey: std::string::String::from("MissingPubkey"), + context_slot: 400, + exists: false, + owner: None, + lamports: None, + kind: None, + }; + let result = super::classify_enriched_account_snapshot(&snapshot); + assert!(result.is_ok()); + assert!(result.expect("classify missing snapshot").is_none()); + } +} diff --git a/khbb_lib/src/lib.rs b/khbb_lib/src/lib.rs index 537113c..febb150 100644 --- a/khbb_lib/src/lib.rs +++ b/khbb_lib/src/lib.rs @@ -25,6 +25,7 @@ mod domain_classifier; mod ids; mod heuristics; mod account_enrichment; +mod enriched_classifier; /// Runs the listener application bootstrap workflow. pub use crate::app::run_listener_app; @@ -118,3 +119,11 @@ pub use crate::heuristics::KhbbPotentialTokenBootstrapActivitySignal; pub use crate::account_enrichment::KhbbEnrichedAccountKind; /// Minimal enriched account snapshot. pub use crate::account_enrichment::KhbbEnrichedAccountSnapshot; +/// Confirmed or refined event derived from an enriched account snapshot. +pub use crate::enriched_classifier::KhbbEnrichedConfirmedEvent; +/// Confirmed token account activity. +pub use crate::enriched_classifier::KhbbConfirmedTokenAccountActivityEvent; +/// Confirmed mint account activity. +pub use crate::enriched_classifier::KhbbConfirmedMintAccountActivityEvent; +/// Unknown token-program-owned account activity. +pub use crate::enriched_classifier::KhbbUnknownTokenProgramAccountActivityEvent; diff --git a/khbb_lib/src/listener.rs b/khbb_lib/src/listener.rs index d97b092..c0042ff 100644 --- a/khbb_lib/src/listener.rs +++ b/khbb_lib/src/listener.rs @@ -645,7 +645,7 @@ pub async fn run_listener_runtime( &classified.pubkey, &response_value, ); - match enrichment_result { + match enrichment_result { Ok(snapshot) => { tracing::trace!( listener_session_id = session.id, @@ -657,6 +657,51 @@ pub async fn run_listener_runtime( kind = ?snapshot.kind, "enriched token program account snapshot" ); + let confirmed_result = + crate::enriched_classifier::classify_enriched_account_snapshot( + &snapshot, + ); + match confirmed_result { + Ok(Some(crate::KhbbEnrichedConfirmedEvent::ConfirmedTokenAccountActivity(inner))) => { + tracing::trace!( + listener_session_id = session.id, + pubkey = %inner.pubkey, + context_slot = inner.context_slot, + owner = ?inner.owner, + lamports = ?inner.lamports, + "confirmed token account activity event" + ); + } + Ok(Some(crate::KhbbEnrichedConfirmedEvent::ConfirmedMintAccountActivity(inner))) => { + tracing::trace!( + listener_session_id = session.id, + pubkey = %inner.pubkey, + context_slot = inner.context_slot, + owner = ?inner.owner, + lamports = ?inner.lamports, + "confirmed mint account activity event" + ); + } + Ok(Some(crate::KhbbEnrichedConfirmedEvent::UnknownTokenProgramAccountActivity(inner))) => { + tracing::trace!( + listener_session_id = session.id, + pubkey = %inner.pubkey, + context_slot = inner.context_slot, + owner = ?inner.owner, + lamports = ?inner.lamports, + "unknown token-program-owned account activity event" + ); + } + Ok(None) => {} + Err(error) => { + tracing::error!( + listener_session_id = session.id, + error = %error, + pubkey = %classified.pubkey, + "failed to classify enriched account snapshot" + ); + } + } } Err(error) => { tracing::error!( @@ -798,6 +843,51 @@ pub async fn run_listener_runtime( kind = ?snapshot.kind, "enriched token program account snapshot" ); + let confirmed_result = + crate::enriched_classifier::classify_enriched_account_snapshot( + &snapshot, + ); + match confirmed_result { + Ok(Some(crate::KhbbEnrichedConfirmedEvent::ConfirmedTokenAccountActivity(inner))) => { + tracing::trace!( + listener_session_id = session.id, + pubkey = %inner.pubkey, + context_slot = inner.context_slot, + owner = ?inner.owner, + lamports = ?inner.lamports, + "confirmed token account activity event" + ); + } + Ok(Some(crate::KhbbEnrichedConfirmedEvent::ConfirmedMintAccountActivity(inner))) => { + tracing::trace!( + listener_session_id = session.id, + pubkey = %inner.pubkey, + context_slot = inner.context_slot, + owner = ?inner.owner, + lamports = ?inner.lamports, + "confirmed mint account activity event" + ); + } + Ok(Some(crate::KhbbEnrichedConfirmedEvent::UnknownTokenProgramAccountActivity(inner))) => { + tracing::trace!( + listener_session_id = session.id, + pubkey = %inner.pubkey, + context_slot = inner.context_slot, + owner = ?inner.owner, + lamports = ?inner.lamports, + "unknown token-program-owned account activity event" + ); + } + Ok(None) => {} + Err(error) => { + tracing::error!( + listener_session_id = session.id, + error = %error, + pubkey = %classified.pubkey, + "failed to classify enriched account snapshot" + ); + } + } } Err(error) => { tracing::error!(