From a78c4c52e2866e62563f73aba5828d82f8b130a2 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Sun, 19 Apr 2026 00:13:37 +0200 Subject: [PATCH] 0.5.9 --- Cargo.toml | 2 +- khbb_lib/src/listener.rs | 28 ++++++++++ khbb_lib/src/session_tracker.rs | 97 +++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 14b5bb2..16ae80a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ ] [workspace.package] -version = "0.5.8" +version = "0.5.9" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-bobot" diff --git a/khbb_lib/src/listener.rs b/khbb_lib/src/listener.rs index ae99f5c..b538e86 100644 --- a/khbb_lib/src/listener.rs +++ b/khbb_lib/src/listener.rs @@ -1286,6 +1286,34 @@ pub async fn run_listener_runtime( ); }, } + let session_candidates = + session_candidate_tracker.snapshot_sorted_by_score_desc(); + tracing::info!( + listener_session_id = session.id, + candidate_count = session_candidates.len(), + "session candidate summary ready" + ); + for candidate in &session_candidates { + tracing::info!( + listener_session_id = session.id, + key = %candidate.key, + category = %candidate.category, + pubkey = ?candidate.pubkey, + first_seen_slot = candidate.first_seen_slot, + last_seen_slot = candidate.last_seen_slot, + seen_count = candidate.seen_count, + score = candidate.score, + confidence = ?candidate.confidence, + "session candidate summary entry" + ); + } + let high_confidence_candidates = session_candidate_tracker + .snapshot_with_min_confidence(crate::KhbbCandidateConfidence::High); + tracing::info!( + listener_session_id = session.id, + high_confidence_candidate_count = high_confidence_candidates.len(), + "session high confidence candidate summary ready" + ); let status_update_result = crate::storage::update_listener_session_status(pool, session.id, &final_status).await; match status_update_result { diff --git a/khbb_lib/src/session_tracker.rs b/khbb_lib/src/session_tracker.rs index cabf547..a8523ab 100644 --- a/khbb_lib/src/session_tracker.rs +++ b/khbb_lib/src/session_tracker.rs @@ -53,6 +53,42 @@ impl KhbbSessionCandidateTracker { }, } } + + /// Returns all tracked candidates as a vector snapshot. + pub fn snapshot(&self) -> std::vec::Vec { + let mut values = std::vec::Vec::::new(); + for value in self.candidates.values() { + values.push(value.clone()); + } + values + } + + /// Returns tracked candidates sorted from highest to lowest score. + pub fn snapshot_sorted_by_score_desc(&self) -> std::vec::Vec { + let mut values = self.snapshot(); + values.sort_by(|left, right| { + right + .score + .cmp(&left.score) + .then_with(|| right.seen_count.cmp(&left.seen_count)) + .then_with(|| left.key.cmp(&right.key)) + }); + values + } + + /// Returns tracked candidates whose confidence is at least the requested minimum. + pub fn snapshot_with_min_confidence( + &self, + min_confidence: crate::KhbbCandidateConfidence, + ) -> std::vec::Vec { + let mut values = std::vec::Vec::::new(); + for candidate in self.snapshot_sorted_by_score_desc() { + if confidence_rank(candidate.confidence) >= confidence_rank(min_confidence) { + values.push(candidate); + } + } + values + } } fn build_session_candidate_from_correlated_signal( @@ -136,6 +172,14 @@ fn compute_candidate_confidence(score: u64) -> crate::KhbbCandidateConfidence { crate::KhbbCandidateConfidence::Low } +fn confidence_rank(confidence: crate::KhbbCandidateConfidence) -> u8 { + match confidence { + crate::KhbbCandidateConfidence::Low => 1, + crate::KhbbCandidateConfidence::Medium => 2, + crate::KhbbCandidateConfidence::High => 3, + } +} + #[cfg(test)] mod tests { #[test] @@ -208,4 +252,57 @@ mod tests { assert!(update.is_new); assert_eq!(update.candidate.confidence, crate::KhbbCandidateConfidence::Medium); } + + #[test] + fn snapshot_sorted_by_score_desc_orders_highest_score_first() { + let mut tracker = super::KhbbSessionCandidateTracker::new(); + let token_signal = crate::KhbbCorrelatedSignal::ConfirmedTokenAccountUpdate( + crate::KhbbConfirmedTokenAccountUpdateSignal { + pubkey: std::string::String::from("TokenPubkey"), + context_slot: 100, + owner: Some(crate::ids::SPL_TOKEN_PROGRAM_ID.to_string()), + lamports: Some(123), + }, + ); + let mint_signal = crate::KhbbCorrelatedSignal::PotentialNewTokenMint( + crate::KhbbPotentialNewTokenMintSignal { + pubkey: std::string::String::from("MintPubkey"), + context_slot: 200, + owner: Some(crate::ids::SPL_TOKEN_PROGRAM_ID.to_string()), + lamports: Some(456), + }, + ); + tracker.upsert_from_correlated_signal(&token_signal); + tracker.upsert_from_correlated_signal(&mint_signal); + let snapshot = tracker.snapshot_sorted_by_score_desc(); + assert_eq!(snapshot.len(), 2); + assert_eq!(snapshot[0].category, "mint"); + assert_eq!(snapshot[1].category, "token_account"); + } + + #[test] + fn snapshot_with_min_confidence_filters_candidates() { + let mut tracker = super::KhbbSessionCandidateTracker::new(); + let token_signal = crate::KhbbCorrelatedSignal::ConfirmedTokenAccountUpdate( + crate::KhbbConfirmedTokenAccountUpdateSignal { + pubkey: std::string::String::from("TokenPubkey"), + context_slot: 100, + owner: Some(crate::ids::SPL_TOKEN_PROGRAM_ID.to_string()), + lamports: Some(123), + }, + ); + let mint_signal = crate::KhbbCorrelatedSignal::PotentialNewTokenMint( + crate::KhbbPotentialNewTokenMintSignal { + pubkey: std::string::String::from("MintPubkey"), + context_slot: 200, + owner: Some(crate::ids::SPL_TOKEN_PROGRAM_ID.to_string()), + lamports: Some(456), + }, + ); + tracker.upsert_from_correlated_signal(&token_signal); + tracker.upsert_from_correlated_signal(&mint_signal); + let filtered = tracker.snapshot_with_min_confidence(crate::KhbbCandidateConfidence::High); + assert_eq!(filtered.len(), 1); + assert_eq!(filtered[0].category, "mint"); + } }