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 ) ]
5376pub 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