Skip to content

Commit 8ae2e9b

Browse files
committed
refactor: implement trait to cover simulation branch in test
1 parent c5cf81d commit 8ae2e9b

2 files changed

Lines changed: 87 additions & 5 deletions

File tree

  • crates/driver/src/domain/competition

crates/driver/src/domain/competition/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ impl Competition {
339339
Self::sort_orders(auction, solver_address, order_sorting_strategies)
340340
});
341341

342-
// We can sort the orders, fetch auction data in parallel.
342+
// We can sort the orders and fetch auction data in parallel.
343343
let (auction, balances, app_data) =
344344
tokio::join!(sort_orders_future, tasks.balances, tasks.app_data);
345345

crates/driver/src/domain/competition/risk_detector/mod.rs

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use {
2323
std::{
2424
collections::{HashMap, HashSet},
2525
fmt,
26+
ops::Deref,
2627
time::Instant,
2728
},
2829
};
@@ -49,13 +50,35 @@ pub enum Quality {
4950
Unknown,
5051
}
5152

53+
#[async_trait::async_trait]
54+
pub trait SellQualityDetector: Send + Sync {
55+
async fn determine_sell_token_quality(&self, order: &Order, now: Instant) -> Quality;
56+
fn get_quality(&self, token: &eth::TokenAddress, now: Instant) -> Quality;
57+
fn evict_outdated_entries(&self);
58+
}
59+
60+
#[async_trait::async_trait]
61+
impl SellQualityDetector for bad_tokens::simulation::Detector {
62+
async fn determine_sell_token_quality(&self, order: &Order, now: Instant) -> Quality {
63+
self.determine_sell_token_quality(order, now).await
64+
}
65+
66+
fn get_quality(&self, token: &eth::TokenAddress, now: Instant) -> Quality {
67+
Deref::deref(self).get_quality(token, now)
68+
}
69+
70+
fn evict_outdated_entries(&self) {
71+
Deref::deref(self).evict_outdated_entries()
72+
}
73+
}
74+
5275
#[derive(Default)]
5376
pub struct Detector {
5477
/// manually configured list of supported and unsupported tokens. Only
5578
/// tokens that get detected incorrectly by the automatic detectors get
5679
/// listed here and therefore have a higher precedence.
5780
hardcoded: HashMap<eth::TokenAddress, Quality>,
58-
simulation_detector: Option<bad_tokens::simulation::Detector>,
81+
simulation_detector: Option<Box<dyn SellQualityDetector>>,
5982
metrics: Option<bad_orders::metrics::Detector>,
6083
}
6184

@@ -73,9 +96,9 @@ impl Detector {
7396
/// methods.
7497
pub fn with_simulation_detector(
7598
&mut self,
76-
detector: bad_tokens::simulation::Detector,
99+
detector: impl SellQualityDetector + 'static,
77100
) -> &mut Self {
78-
self.simulation_detector = Some(detector);
101+
self.simulation_detector = Some(Box::new(detector));
79102
self
80103
}
81104

@@ -280,6 +303,38 @@ mod tests {
280303
Uid::from_parts(order_hash, signer, valid_to)
281304
}
282305

306+
struct TestSellQualityDetector {
307+
sell_detector_unsupported_uid: Uid,
308+
sell_detector_supported_uid: Uid,
309+
}
310+
311+
#[async_trait::async_trait]
312+
impl SellQualityDetector for TestSellQualityDetector {
313+
async fn determine_sell_token_quality(&self, order: &Order, _: Instant) -> Quality {
314+
if order.uid == self.sell_detector_unsupported_uid {
315+
Quality::Unsupported
316+
} else if order.uid == self.sell_detector_supported_uid {
317+
Quality::Supported
318+
} else {
319+
Quality::Supported
320+
}
321+
}
322+
323+
fn get_quality(&self, _: &eth::TokenAddress, _: Instant) -> Quality {
324+
Quality::Unknown
325+
}
326+
327+
fn evict_outdated_entries(&self) {}
328+
}
329+
330+
// Helper to create a mock sell quality detector purely for test
331+
fn sell_quality_detector(supported: Uid, unsupported: Uid) -> TestSellQualityDetector {
332+
TestSellQualityDetector {
333+
sell_detector_unsupported_uid: unsupported,
334+
sell_detector_supported_uid: supported,
335+
}
336+
}
337+
283338
#[tokio::test]
284339
async fn unsupported_order_uids_empty_returns_empty() {
285340
let detector = Detector::new(Default::default());
@@ -352,10 +407,26 @@ mod tests {
352407
addr(5).into(),
353408
valid_to,
354409
), // unknown buy
410+
order(
411+
uid(6, addr(11), valid_to),
412+
addr(11),
413+
addr(6).into(),
414+
addr(2).into(),
415+
valid_to,
416+
), // unknown sell unsupported
417+
order(
418+
uid(7, addr(12), valid_to),
419+
addr(12),
420+
addr(7).into(),
421+
addr(2).into(),
422+
valid_to,
423+
), // unknown sell supported
355424
];
356425

357426
let metrics_uid = orders[0].uid;
358427
let token_uid = orders[1].uid;
428+
let sell_detector_unsupported_uid = orders[5].uid;
429+
let sell_detector_supported_uid = orders[6].uid;
359430

360431
let metrics_detector = bad_orders::metrics::Detector::new(
361432
0.5,
@@ -378,8 +449,19 @@ mod tests {
378449
detector.encoding_failed(&[metrics_uid]);
379450
detector.encoding_failed(&[metrics_uid]);
380451

452+
detector.with_simulation_detector(sell_quality_detector(
453+
sell_detector_supported_uid,
454+
sell_detector_unsupported_uid,
455+
));
456+
381457
let removed = detector.unsupported_order_uids(&orders).await;
382458

383-
assert_eq!(removed, HashSet::from([metrics_uid, token_uid]));
459+
assert_eq!(
460+
removed,
461+
HashSet::from([metrics_uid, token_uid, sell_detector_unsupported_uid])
462+
); // all unsupported removed
463+
assert!(!removed.contains(&orders[2].uid)); // supported token kept
464+
assert!(!removed.contains(&orders[4].uid)); // unknown buy kept
465+
assert!(!removed.contains(&sell_detector_supported_uid)); // supported unknown sell kept
384466
}
385467
}

0 commit comments

Comments
 (0)