@@ -32,9 +32,41 @@ pub struct TimestampedSpikeEvent {
3232}
3333
3434/// Classifies fee spikes in a time series.
35- pub struct SpikeClassifier ;
35+ pub struct SpikeClassifier {
36+ baseline : u64 ,
37+ }
38+
39+ impl Default for SpikeClassifier {
40+ fn default ( ) -> Self {
41+ Self { baseline : 200 }
42+ }
43+ }
3644
3745impl SpikeClassifier {
46+ /// Create a classifier with the given baseline.
47+ pub fn new ( baseline : u64 ) -> Self {
48+ Self { baseline }
49+ }
50+
51+ /// Classify a single fee using the configured baseline.
52+ ///
53+ /// Returns [`SpikeSeverity::Low`] for fees below the 2× spike threshold.
54+ pub fn classify ( & self , fee : u64 ) -> SpikeSeverity {
55+ if self . baseline == 0 {
56+ return SpikeSeverity :: Low ;
57+ }
58+ let ratio = fee as f64 / self . baseline as f64 ;
59+ if ratio > 50.0 {
60+ SpikeSeverity :: Critical
61+ } else if ratio >= 10.0 {
62+ SpikeSeverity :: High
63+ } else if ratio >= 5.0 {
64+ SpikeSeverity :: Medium
65+ } else {
66+ SpikeSeverity :: Low
67+ }
68+ }
69+
3870 /// Returns indices of fees that fall outside 1.5 × IQR from Q1/Q3.
3971 /// `fees` need not be sorted; indices refer to the original slice.
4072 pub fn iqr_outliers ( fees : & [ u64 ] ) -> Vec < usize > {
@@ -57,7 +89,7 @@ impl SpikeClassifier {
5789
5890 /// Classify a single fee against a baseline.
5991 /// Returns `None` if the fee is below the 2× spike threshold.
60- pub fn classify ( fee : u64 , baseline : u64 ) -> Option < SpikeSeverity > {
92+ pub fn classify_with_baseline ( fee : u64 , baseline : u64 ) -> Option < SpikeSeverity > {
6193 if baseline == 0 {
6294 return None ;
6395 }
@@ -77,14 +109,14 @@ impl SpikeClassifier {
77109 let mut events = Vec :: new ( ) ;
78110 let mut i = 0 ;
79111 while i < fees. len ( ) {
80- if let Some ( severity) = Self :: classify ( fees[ i] , baseline) {
112+ if let Some ( severity) = Self :: classify_with_baseline ( fees[ i] , baseline) {
81113 let start = i;
82- while i < fees. len ( ) && Self :: classify ( fees[ i] , baseline) . is_some ( ) {
114+ while i < fees. len ( ) && Self :: classify_with_baseline ( fees[ i] , baseline) . is_some ( ) {
83115 i += 1 ;
84116 }
85117 let severity = fees[ start..i]
86118 . iter ( )
87- . filter_map ( |& f| Self :: classify ( f, baseline) )
119+ . filter_map ( |& f| Self :: classify_with_baseline ( f, baseline) )
88120 . max_by_key ( |s| match s {
89121 SpikeSeverity :: Low => 1 ,
90122 SpikeSeverity :: Medium => 2 ,
0 commit comments