From 5e2f927e73a8d1317f45bf1925cb2aa8072eb36b Mon Sep 17 00:00:00 2001 From: Nicholas Rodrigues Lordello Date: Fri, 27 May 2022 09:36:21 +0200 Subject: [PATCH] Add `objective` Flag And use `SuplusFeesCosts` for Price Estimates (#229) This PR adds a new field to `SolverConfig` to allow configuring Quasimodo for different environments. Specifically, requests to Quasimodo from the solver should use a different objective then when requesting price estimates (when solving, Quasimodo defaults to optimizing with capped surplus, which we don't want for price estimates). ### Test Plan Run the orderbook locally and see the new parameter: ``` % cargo run -p orderbook -- --price-estimators Quasimodo --log-filter shared::http_solver=trace ... 2022-05-25T13:26:42.718Z TRACE shared::http_solver: request url=https://.../solve?instance_name=2022-05-25_13%3A26%3A42.718259_UTC_Ethereum___Mainnet_1_0&time_limit=2&max_nr_exec_orders=100&use_internal_buffers=false&objective=surplusfeescosts body=... ... ``` --- crates/orderbook/src/main.rs | 9 ++--- crates/shared/src/http_solver.rs | 40 +++++++++++++++++-- .../shared/src/price_estimation/quasimodo.rs | 6 +-- crates/solver/src/solver.rs | 25 ++++-------- crates/solver/src/solver/http_solver.rs | 7 +--- 5 files changed, 50 insertions(+), 37 deletions(-) diff --git a/crates/orderbook/src/main.rs b/crates/orderbook/src/main.rs index b8c31a3e82..303c440804 100644 --- a/crates/orderbook/src/main.rs +++ b/crates/orderbook/src/main.rs @@ -38,7 +38,7 @@ use shared::{ }, baseline_solver::BaseTokens, current_block::current_block_stream, - http_solver::{DefaultHttpSolverApi, SolverConfig}, + http_solver::{DefaultHttpSolverApi, Objective, SolverConfig}, maintenance::ServiceMaintenance, metrics::{serve_metrics, setup_metrics_registry, DEFAULT_METRICS_PORT}, network::network_name, @@ -556,10 +556,9 @@ async fn main() { ), client: client.clone(), config: SolverConfig { - api_key: None, - max_nr_exec_orders: 100, - has_ucp_policy_parameter: false, - use_internal_buffers: args.shared.quasimodo_uses_internal_buffers.into(), + use_internal_buffers: Some(args.shared.quasimodo_uses_internal_buffers), + objective: Some(Objective::SurplusFeesCosts), + ..Default::default() }, }), pool_fetcher.clone(), diff --git a/crates/shared/src/http_solver.rs b/crates/shared/src/http_solver.rs index 17690d0a1c..ea0a2e38c9 100644 --- a/crates/shared/src/http_solver.rs +++ b/crates/shared/src/http_solver.rs @@ -49,7 +49,7 @@ pub struct DefaultHttpSolverApi { } /// Configuration for solver requests. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct SolverConfig { /// Optional value for the `X-API-KEY` header. pub api_key: Option, @@ -62,6 +62,27 @@ pub struct SolverConfig { /// Controls if/how to set `use_internal_buffers`. pub use_internal_buffers: Option, + + /// Controls the objective function to optimize for. + pub objective: Option, +} + +impl Default for SolverConfig { + fn default() -> Self { + Self { + api_key: None, + max_nr_exec_orders: 100, + has_ucp_policy_parameter: false, + use_internal_buffers: None, + objective: None, + } + } +} + +#[derive(Debug)] +pub enum Objective { + CappedSurplusFeesCosts, + SurplusFeesCosts, } #[async_trait::async_trait] @@ -105,11 +126,24 @@ impl HttpSolverApi for DefaultHttpSolverApi { use_internal_buffers.to_string().as_str(), ); } + match self.config.objective { + Some(Objective::CappedSurplusFeesCosts) => { + url.query_pairs_mut() + .append_pair("objective", "cappedsurplusfeescosts"); + } + Some(Objective::SurplusFeesCosts) => { + url.query_pairs_mut() + .append_pair("objective", "surplusfeescosts"); + } + _ => {} + } if let Some(auction_id) = maybe_auction_id { url.query_pairs_mut() .append_pair("auction_id", auction_id.to_string().as_str()); } let query = url.query().map(ToString::to_string).unwrap_or_default(); + let body = serde_json::to_string(&model).context("failed to encode body")?; + tracing::trace!(%url, %body, "request"); let mut request = self .client .post(url) @@ -121,8 +155,6 @@ impl HttpSolverApi for DefaultHttpSolverApi { header.set_sensitive(true); request = request.header("X-API-KEY", header); } - let body = serde_json::to_string(&model).context("failed to encode body")?; - tracing::trace!("request {}", body); let request = request.body(body.clone()); let mut response = request.send().await.context("failed to send request")?; let status = response.status(); @@ -131,7 +163,7 @@ impl HttpSolverApi for DefaultHttpSolverApi { .await .context("response body")?; let text = std::str::from_utf8(&response_body).context("failed to decode response body")?; - tracing::trace!("response {}", text); + tracing::trace!(body = %text, "response"); let context = || { format!( "request query {}, request body {}, response body {}", diff --git a/crates/shared/src/price_estimation/quasimodo.rs b/crates/shared/src/price_estimation/quasimodo.rs index c9444b88f7..5b84d21181 100644 --- a/crates/shared/src/price_estimation/quasimodo.rs +++ b/crates/shared/src/price_estimation/quasimodo.rs @@ -433,10 +433,8 @@ mod tests { base: Url::parse(&quasimodo_url).expect("failed to parse quasimodo url"), client, config: SolverConfig { - api_key: None, - max_nr_exec_orders: 100, - has_ucp_policy_parameter: false, - use_internal_buffers: true.into(), + use_internal_buffers: Some(true), + ..Default::default() }, }), sharing: Default::default(), diff --git a/crates/solver/src/solver.rs b/crates/solver/src/solver.rs index cb651dea08..d6ce0d75a2 100644 --- a/crates/solver/src/solver.rs +++ b/crates/solver/src/solver.rs @@ -282,32 +282,23 @@ pub fn create( mip_solver_url.clone(), "Mip".to_string(), SolverConfig { - api_key: None, - max_nr_exec_orders: 100, - has_ucp_policy_parameter: false, - use_internal_buffers: mip_uses_internal_buffers.into(), + use_internal_buffers: Some(mip_uses_internal_buffers), + ..Default::default() }, ))), SolverType::CowDexAg => Ok(shared(create_http_solver( account, cow_dex_ag_solver_url.clone(), "CowDexAg".to_string(), - SolverConfig { - api_key: None, - max_nr_exec_orders: 100, - has_ucp_policy_parameter: false, - use_internal_buffers: None, - }, + SolverConfig::default(), ))), SolverType::Quasimodo => Ok(shared(create_http_solver( account, quasimodo_solver_url.clone(), "Quasimodo".to_string(), SolverConfig { - api_key: None, - max_nr_exec_orders: 100, - has_ucp_policy_parameter: true, - use_internal_buffers: quasimodo_uses_internal_buffers.into(), + use_internal_buffers: Some(quasimodo_uses_internal_buffers), + ..Default::default() }, ))), SolverType::OneInch => Ok(shared(SingleOrderSolver::new( @@ -389,10 +380,8 @@ pub fn create( solver.url, solver.name, SolverConfig { - api_key: None, - max_nr_exec_orders: 100, - has_ucp_policy_parameter: false, - use_internal_buffers: mip_uses_internal_buffers.into(), + use_internal_buffers: Some(mip_uses_internal_buffers), + ..Default::default() }, )) }); diff --git a/crates/solver/src/solver/http_solver.rs b/crates/solver/src/solver/http_solver.rs index 02151088d4..ad54535162 100644 --- a/crates/solver/src/solver/http_solver.rs +++ b/crates/solver/src/solver/http_solver.rs @@ -508,12 +508,7 @@ mod tests { chain_id: 0, base: url.parse().unwrap(), client: Client::new(), - config: SolverConfig { - api_key: None, - max_nr_exec_orders: 0, - has_ucp_policy_parameter: false, - use_internal_buffers: None, - }, + config: SolverConfig::default(), }, Account::Local(Address::default(), None), H160::zero(),