Skip to content

Commit

Permalink
Avoid building 2 auctions after restart (#2580)
Browse files Browse the repository at this point in the history
# Description
The autopilot periodically builds new auctions via a background task
that gets
[spawned](https://github.com/cowprotocol/services/blob/main/crates/autopilot/src/solvable_orders.rs#L126-L129)
immediately after starting the autopilot.
However, it also
["manually"](https://github.com/cowprotocol/services/blob/main/crates/autopilot/src/run.rs#L564-L567)
builds 1 auction right at the start. This leads to 2 auctions being
built in parallel whenever we restart the autopilot.

# Changes
Delete "manual" auction building process to do less work on restarts.

## How to test
e2e tests
  • Loading branch information
MartinquaXD authored Apr 2, 2024
1 parent 5430414 commit 31b7641
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 31 deletions.
5 changes: 0 additions & 5 deletions crates/autopilot/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,6 @@ pub async fn run(args: Arguments) {
let persistence =
infra::persistence::Persistence::new(args.s3.into().unwrap(), Arc::new(db.clone())).await;

let block = eth.current_block().borrow().number;
let solvable_orders_cache = SolvableOrdersCache::new(
args.min_order_validity_period,
persistence.clone(),
Expand All @@ -561,10 +560,6 @@ pub async fn run(args: Arguments) {
.expect("limit order price factor can't be converted to BigDecimal"),
domain::ProtocolFees::new(&args.fee_policies, args.fee_policy_max_partner_fee),
);
solvable_orders_cache
.update(block)
.await
.expect("failed to perform initial solvable orders update");

let liveness = Arc::new(Liveness::new(args.max_auction_age));
shared::metrics::serve_metrics(liveness.clone(), args.metrics_address);
Expand Down
2 changes: 1 addition & 1 deletion crates/autopilot/src/solvable_orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl SolvableOrdersCache {
/// Usually this method is called from update_task. If it isn't, which is
/// the case in unit tests, then concurrent calls might overwrite each
/// other's results.
pub async fn update(&self, block: u64) -> Result<()> {
async fn update(&self, block: u64) -> Result<()> {
let min_valid_to = now_in_epoch_seconds() + self.min_order_validity_period.as_secs() as u32;
let db_solvable_orders = self.persistence.solvable_orders(min_valid_to).await?;

Expand Down
26 changes: 22 additions & 4 deletions crates/e2e/src/setup/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use {
},
reqwest::{Client, StatusCode, Url},
sqlx::Connection,
std::time::Duration,
std::{ops::DerefMut, time::Duration},
};

pub const API_HOST: &str = "http://127.0.0.1:8080";
Expand Down Expand Up @@ -127,7 +127,7 @@ impl<'a> Services<'a> {
/// (note: specifying a larger solve deadline will impact test times as the
/// driver delays the submission of the solution until shortly before the
/// deadline in case the solution would start to revert at some point)
pub fn start_autopilot(&self, solve_deadline: Option<Duration>, extra_args: Vec<String>) {
pub async fn start_autopilot(&self, solve_deadline: Option<Duration>, extra_args: Vec<String>) {
let solve_deadline = solve_deadline.unwrap_or(Duration::from_secs(2));

let args = [
Expand All @@ -144,6 +144,7 @@ impl<'a> Services<'a> {

let args = autopilot::arguments::Arguments::try_parse_from(args).unwrap();
tokio::task::spawn(autopilot::run(args));
self.wait_until_autopilot_ready().await;
}

/// Start the api service in a background tasks.
Expand Down Expand Up @@ -195,7 +196,8 @@ impl<'a> Services<'a> {
args.autopilot,
]
.concat(),
);
)
.await;
self.start_api(
[
vec![
Expand Down Expand Up @@ -262,7 +264,8 @@ impl<'a> Services<'a> {

colocation::start_driver(self.contracts, solvers);

self.start_autopilot(Some(Duration::from_secs(11)), autopilot_args);
self.start_autopilot(Some(Duration::from_secs(11)), autopilot_args)
.await;
self.start_api(api_args).await;
}

Expand All @@ -279,6 +282,21 @@ impl<'a> Services<'a> {
.expect("waiting for API timed out");
}

async fn wait_until_autopilot_ready(&self) {
let is_up = || async {
let mut db = self.db.acquire().await.unwrap();
const QUERY: &str = "SELECT COUNT(*) FROM auctions";
let count: i64 = sqlx::query_scalar(QUERY)
.fetch_one(db.deref_mut())
.await
.unwrap();
count > 0
};
wait_for_condition(TIMEOUT, is_up)
.await
.expect("waiting for autopilot timed out");
}

pub async fn get_auction(&self) -> dto::AuctionWithId {
let response = self
.http
Expand Down
29 changes: 16 additions & 13 deletions crates/e2e/tests/e2e/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,22 @@ async fn onchain_settlement_without_liquidity(web3: Web3) {
}],
);
let services = Services::new(onchain.contracts()).await;
services.start_autopilot(
None,
vec![
format!(
"--trusted-tokens={weth:#x},{token_a:#x},{token_b:#x}",
weth = onchain.contracts().weth.address(),
token_a = token_a.address(),
token_b = token_b.address()
),
"--drivers=test_solver|http://localhost:11088/test_solver".to_string(),
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver".to_string(),
],
);
services
.start_autopilot(
None,
vec![
format!(
"--trusted-tokens={weth:#x},{token_a:#x},{token_b:#x}",
weth = onchain.contracts().weth.address(),
token_a = token_a.address(),
token_b = token_b.address()
),
"--drivers=test_solver|http://localhost:11088/test_solver".to_string(),
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver"
.to_string(),
],
)
.await;
services
.start_api(vec![
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver".to_string(),
Expand Down
15 changes: 9 additions & 6 deletions crates/e2e/tests/e2e/order_cancellation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,15 @@ async fn order_cancellation(web3: Web3) {
endpoint: solver_endpoint,
}],
);
services.start_autopilot(
None,
vec![
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver".to_string(),
],
);
services
.start_autopilot(
None,
vec![
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver"
.to_string(),
],
)
.await;
services
.start_api(vec![
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion crates/e2e/tests/e2e/protocol_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ async fn execute_test(
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver".to_string(),
];
config.extend(autopilot_config.iter().map(ToString::to_string));
services.start_autopilot(None, config);
services.start_autopilot(None, config).await;
services
.start_api(vec![
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion crates/e2e/tests/e2e/solver_competition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ async fn solver_competition(web3: Web3) {
.to_string(),
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver,solver2|http://localhost:11088/solver2".to_string(),
],
);
).await;
services.start_api(vec![
"--price-estimation-drivers=test_quoter|http://localhost:11088/test_solver,solver2|http://localhost:11088/solver2".to_string(),
]).await;
Expand Down

0 comments on commit 31b7641

Please sign in to comment.