2424//! That is effectively a measurement of how much better each order got executed
2525//! because solver S participated in the competition.
2626use {
27+ super :: { Arbitrator , PartitionedSolutions , Ranking } ,
2728 crate :: domain:: {
2829 self ,
2930 OrderUid ,
4748 } ,
4849} ;
4950
50- /// Implements auction arbitration in 3 phases:
51- /// 1. filter unfair solutions
52- /// 2. mark winners
53- /// 3. compute reference scores
54- ///
55- /// The functions assume the `Arbitrator` is the only one
56- /// changing the ordering or the `participants`.
57- impl Arbitrator {
58- /// Runs the entire auction mechanism on the passed in solutions.
59- pub fn arbitrate (
60- & self ,
61- participants : Vec < Participant < Unranked > > ,
62- auction : & domain:: Auction ,
63- ) -> Ranking {
64- let partitioned = self . partition_unfair_solutions ( participants, auction) ;
65- let filtered_out = partitioned
66- . discarded
67- . into_iter ( )
68- . map ( |participant| participant. rank ( Ranked :: FilteredOut ) )
69- . collect ( ) ;
70-
71- let mut ranked = self . mark_winners ( partitioned. kept ) ;
72- ranked. sort_by_key ( |participant| {
73- (
74- // winners before non-winners
75- std:: cmp:: Reverse ( participant. is_winner ( ) ) ,
76- // high score before low score
77- std:: cmp:: Reverse ( participant. solution ( ) . computed_score ( ) . cloned ( ) ) ,
78- )
79- } ) ;
80- Ranking {
81- filtered_out,
82- ranked,
83- }
84- }
85-
86- /// Removes unfair solutions from the set of all solutions.
51+ impl Arbitrator for Config {
8752 fn partition_unfair_solutions (
8853 & self ,
8954 mut participants : Vec < Participant < Unranked > > ,
@@ -134,8 +99,6 @@ impl Arbitrator {
13499 }
135100 }
136101
137- /// Picks winners and sorts all solutions where winners come before
138- /// non-winners and higher scores come before lower scores.
139102 fn mark_winners ( & self , participants : Vec < Participant < Unranked > > ) -> Vec < Participant > {
140103 let winner_indexes = self . pick_winners ( participants. iter ( ) . map ( |p| p. solution ( ) ) ) ;
141104 participants
@@ -151,9 +114,7 @@ impl Arbitrator {
151114 . collect ( )
152115 }
153116
154- /// Computes the reference scores which are used to compute
155- /// rewards for the winning solvers.
156- pub fn compute_reference_scores ( & self , ranking : & Ranking ) -> HashMap < eth:: Address , Score > {
117+ fn compute_reference_scores ( & self , ranking : & Ranking ) -> HashMap < eth:: Address , Score > {
157118 let mut reference_scores = HashMap :: default ( ) ;
158119
159120 for participant in & ranking. ranked {
@@ -189,7 +150,9 @@ impl Arbitrator {
189150
190151 reference_scores
191152 }
153+ }
192154
155+ impl Config {
193156 /// Returns indices of winning solutions.
194157 /// Assumes that `solutions` is sorted by score descendingly.
195158 /// This logic was moved into a helper function to avoid a ton of `.clone()`
@@ -349,7 +312,7 @@ fn score_by_token_pair(solution: &Solution, auction: &Auction) -> Result<ScoreBy
349312 Ok ( scores)
350313}
351314
352- pub struct Arbitrator {
315+ pub struct Config {
353316 pub max_winners : usize ,
354317 pub weth : WrappedNativeToken ,
355318}
@@ -415,48 +378,6 @@ type ScoreByDirection = HashMap<DirectedTokenPair, Score>;
415378/// of the auction.
416379type ScoresBySolution = HashMap < SolutionKey , ScoreByDirection > ;
417380
418- pub struct Ranking {
419- /// Solutions that were discarded because they were malformed
420- /// in some way or deemed unfair by the selection mechanism.
421- filtered_out : Vec < Participant < Ranked > > ,
422- /// Final ranking of the solutions that passed the fairness
423- /// check. Winners come before non-winners and higher total
424- /// scores come before lower scores.
425- ranked : Vec < Participant < Ranked > > ,
426- }
427-
428- impl Ranking {
429- /// All solutions including the ones that got filtered out.
430- pub fn all ( & self ) -> impl Iterator < Item = & Participant < Ranked > > {
431- self . ranked . iter ( ) . chain ( & self . filtered_out )
432- }
433-
434- /// Enumerates all solutions. The index is used as solution UID.
435- pub fn enumerated ( & self ) -> impl Iterator < Item = ( usize , & Participant < Ranked > ) > {
436- self . all ( ) . enumerate ( )
437- }
438-
439- /// All solutions that won the right to get executed.
440- pub fn winners ( & self ) -> impl Iterator < Item = & Participant < Ranked > > {
441- self . ranked . iter ( ) . filter ( |p| p. is_winner ( ) )
442- }
443-
444- /// All solutions that were not filtered out but also did not win.
445- pub fn non_winners ( & self ) -> impl Iterator < Item = & Participant < Ranked > > {
446- self . ranked . iter ( ) . filter ( |p| !p. is_winner ( ) )
447- }
448-
449- /// All solutions that passed the filtering step.
450- pub fn ranked ( & self ) -> impl Iterator < Item = & Participant < Ranked > > {
451- self . ranked . iter ( )
452- }
453- }
454-
455- struct PartitionedSolutions {
456- kept : Vec < Participant < Unranked > > ,
457- discarded : Vec < Participant < Unranked > > ,
458- }
459-
460381#[ cfg( test) ]
461382mod tests {
462383 use {
@@ -469,7 +390,14 @@ mod tests {
469390 Price ,
470391 order:: { self , AppDataHash } ,
471392 } ,
472- competition:: { Participant , Score , Solution , TradedOrder , Unranked } ,
393+ competition:: {
394+ Participant ,
395+ Score ,
396+ Solution ,
397+ TradedOrder ,
398+ Unranked ,
399+ winner_selection:: Arbitrator ,
400+ } ,
473401 eth:: { self , TokenAddress } ,
474402 } ,
475403 infra:: Driver ,
@@ -1268,8 +1196,8 @@ mod tests {
12681196 pub buy_amount : eth:: U256 ,
12691197 }
12701198
1271- fn create_test_arbitrator ( ) -> super :: Arbitrator {
1272- super :: Arbitrator {
1199+ fn create_test_arbitrator ( ) -> super :: Config {
1200+ super :: Config {
12731201 max_winners : 10 ,
12741202 weth : H160 :: from_slice ( & hex ! ( "C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" ) ) . into ( ) ,
12751203 }
0 commit comments