diff --git a/crates/autopilot/src/arguments.rs b/crates/autopilot/src/arguments.rs index cf31431dcb..1a8420973e 100644 --- a/crates/autopilot/src/arguments.rs +++ b/crates/autopilot/src/arguments.rs @@ -230,6 +230,11 @@ pub struct Arguments { /// to settle their winning orders at the same time. pub max_winners_per_auction: usize, + #[clap(long, env, default_value = "3")] + /// The maximum allowed number of solutions to be proposed from a single + /// solver, per auction. + pub max_solutions_per_solver: usize, + /// Archive node URL used to index CoW AMM #[clap(long, env)] pub archive_node_url: Option, @@ -278,6 +283,7 @@ impl std::fmt::Display for Arguments { run_loop_native_price_timeout, max_winners_per_auction, archive_node_url, + max_solutions_per_solver, } = self; write!(f, "{}", shared)?; @@ -357,6 +363,11 @@ impl std::fmt::Display for Arguments { )?; writeln!(f, "max_winners_per_auction: {:?}", max_winners_per_auction)?; writeln!(f, "archive_node_url: {:?}", archive_node_url)?; + writeln!( + f, + "max_solutions_per_solver: {:?}", + max_solutions_per_solver + )?; Ok(()) } } diff --git a/crates/autopilot/src/run.rs b/crates/autopilot/src/run.rs index a3b2c39a0a..c6747413b7 100644 --- a/crates/autopilot/src/run.rs +++ b/crates/autopilot/src/run.rs @@ -528,6 +528,7 @@ pub async fn run(args: Arguments) { solve_deadline: args.solve_deadline, max_run_loop_delay: args.max_run_loop_delay, max_winners_per_auction: args.max_winners_per_auction, + max_solutions_per_solver: args.max_solutions_per_solver, }; let run = RunLoop::new( diff --git a/crates/autopilot/src/run_loop.rs b/crates/autopilot/src/run_loop.rs index e68f185ff3..c8057c1092 100644 --- a/crates/autopilot/src/run_loop.rs +++ b/crates/autopilot/src/run_loop.rs @@ -51,6 +51,7 @@ pub struct Config { /// by waiting for the next block to appear. pub max_run_loop_delay: Duration, pub max_winners_per_auction: usize, + pub max_solutions_per_solver: usize, } pub struct RunLoop { @@ -550,6 +551,16 @@ impl RunLoop { std::cmp::Reverse(participant.solution().score().get().0) }); + // Limit the number of accepted solutions per solver. Do not alter the ordering + // of solutions + let mut counter = HashMap::new(); + solutions.retain(|participant| { + let driver = participant.driver().name.clone(); + let count = counter.entry(driver).or_insert(0); + *count += 1; + *count <= self.config.max_solutions_per_solver + }); + // Filter out solutions that are not fair let solutions = solutions .iter()