Skip to content

refactor: parallelize unsupported-order detection and defer filtering#4309

Closed
metalurgical wants to merge 3 commits intocowprotocol:mainfrom
metalurgical:issue_3516
Closed

refactor: parallelize unsupported-order detection and defer filtering#4309
metalurgical wants to merge 3 commits intocowprotocol:mainfrom
metalurgical:issue_3516

Conversation

@metalurgical
Copy link
Copy Markdown

@metalurgical metalurgical commented Apr 5, 2026

Description

Parallelize unsupported-order detection and defer filtering

Changes

  • Switch risk detection to return UIDs,
  • run it concurrently with preprocessing,
  • apply filtering after updating orders.
    - Replace in-place sorting with permutation-based ordering to avoid cloning orders.

How to test

As normal.

Related Issues

Fixes #3516

Note

Built on top of #4308 Split from PR

@metalurgical metalurgical requested a review from a team as a code owner April 5, 2026 20:23
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@metalurgical
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@metalurgical
Copy link
Copy Markdown
Author

recheck

github-actions bot added a commit that referenced this pull request Apr 5, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances cross-platform support and optimizes the auction preprocessing pipeline. Significant changes include making memory allocators and system signals platform-specific, updating database configuration for Windows compatibility, and refactoring order sorting and filtering to minimize cloning and improve parallelism. No critical issues found.

@jmg-duarte
Copy link
Copy Markdown
Contributor

I believe this change is built on top of your other PR, please separate them for easier review

Copy link
Copy Markdown
Contributor

@jmg-duarte jmg-duarte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The typo fixes and import shortening changes are appreciated overall but in this PR they bring in noise to a review that must be done carefully

The parallelism change is also semi-buried in the sorting order refactor

The sorting order refactor is non-trivial and it lacks safety justifications as to why it works. It could also be abstracted/simplified since it doesn't matter if a vector contains T, Z, or A if we're ignoring the type and using another slice as "sorting reference"

Finally, I don't understand why there's so much documentation being removed

Comment thread crates/driver/src/domain/competition/risk_detector/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/risk_detector/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/sorting.rs
Comment thread crates/driver/src/domain/competition/sorting.rs
Comment thread crates/driver/src/domain/competition/sorting.rs Outdated
Comment thread crates/driver/src/domain/competition/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/mod.rs Outdated
@metalurgical
Copy link
Copy Markdown
Author

@jmg-duarte You raised valid points. Have simplified it to minimal correction for the issue, restored the documentation comments and removed the permutation based sorting.

@metalurgical metalurgical changed the title refactor: parallelize unsupported-order detection and refactor sorting to avoid order cloning refactor: parallelize unsupported-order detection and defer filtering Apr 6, 2026
Move unsupported-order detection to a parallel, read-only stage in the auction preprocessing pipeline. Detection now operates on a snapshot of orders and returns UIDs to discard, rather than mutating the auction early.
@jmg-duarte
Copy link
Copy Markdown
Contributor

Hey @metalurgical thanks for the changes! It looks much better now, I haven't had a chance of giving them a through review yet; if you don't mind resolving the conflicts, that would be great.

Full disclosure: The PR will need to go through internal testing to ensure there's no performance regressions, I'll take care of that and either bring comments or iterate directly on it myself (depends on outcomes); however, it might take a bit to do so due to this not being a top priority now.

Once more, thanks for your contribution

Copy link
Copy Markdown
Contributor

@jmg-duarte jmg-duarte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review is mostly for myself as I've already addressed these issues in a local branch, I just can't forget to actually push the fixes.
I'll push the changes, I'll also revert the import pathing changes as it distracts from the important parts of the PR

Comment on lines +88 to +100
/// Filters unsupported orders out of the auction.
pub async fn filter_unsupported_orders_in_auction(
&self,
mut auction: crate::domain::competition::Auction,
) -> crate::domain::competition::Auction {
let removed_uids = self.unsupported_order_uids(&auction.orders).await;
if !removed_uids.is_empty() {
auction
.orders
.retain(|order| !removed_uids.contains(&order.uid));
}
auction
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused

Comment on lines +148 to 151
let orders_for_unsupported_filter: Vec<competition::Order> = auction.orders.clone();
let unsupported_uids = risk_detector
.unsupported_order_uids(&orders_for_unsupported_filter)
.await;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let orders_for_unsupported_filter: Vec<competition::Order> = auction.orders.clone();
let unsupported_uids = risk_detector
.unsupported_order_uids(&orders_for_unsupported_filter)
.await;
let unsupported_uids = risk_detector
.unsupported_order_uids(&auction.orders)
.await;

Comment on lines +153 to 158
let mut auction = auction;
if !unsupported_uids.is_empty() {
auction
.orders
.retain(|order| !unsupported_uids.contains(&order.uid));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit to restrict mutability's "lifetime"

Suggested change
let mut auction = auction;
if !unsupported_uids.is_empty() {
auction
.orders
.retain(|order| !unsupported_uids.contains(&order.uid));
}
let auction = {
let mut auction = auction;
if !unsupported_uids.is_empty() {
auction
.orders
.retain(|order| !unsupported_uids.contains(&order.uid));
};
auction
};

Comment on lines +1 to 2
use std::sync::Arc;
use {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't pass CI, be sure to test stuff locally, we have the just scripts etc

}

auction
removed_uids
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
removed_uids
unsupported_uids

Comment on lines +136 to +140
let order = order.clone();
let check_tokens_fut = async move {
let quality = detector.determine_sell_token_quality(&order, now).await;
(order.uid, quality)
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let order = order.clone();
let check_tokens_fut = async move {
let quality = detector.determine_sell_token_quality(&order, now).await;
(order.uid, quality)
};
let check_tokens_fut = async move {
let quality = detector.determine_sell_token_quality(&order, now).await;
(order.uid, quality)
};

/// which is significantly faster than the
/// [num::BigRational] we used before.
pub struct OrdFloat(f64);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once you format the file correctly this disappears so lets just remove this line (even though I'm also a fan of this separation) to minimize the diff

let cow_amm_orders = tasks.cow_amm_orders.await;
auction.orders.extend(cow_amm_orders.iter().cloned());

// Start unsupported-order detection immediately
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong, creating the future doesn't drive it

Comment on lines +307 to +308
let unsupported_orders_future =
async move { self.unsupported_order_uids(&orders_for_unsupported).await };
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This filters flashloans before orders were loaded with app_data, meaning that the flashloan check ends up being wrong

Comment on lines +316 to +323
// We can sort the orders, determine UIDS to filter and fetch auction data in
// parallel.
let (auction, balances, app_data, unsupported_uids) = tokio::join!(
sort_orders_future,
tasks.balances,
tasks.app_data,
unsupported_orders_future,
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way flashloan filtering is handled here, it will break the actual flashloan filtering
It must be done strictly after the update_orders is done

@metalurgical metalurgical deleted the issue_3516 branch April 13, 2026 18:57
@github-actions github-actions bot locked and limited conversation to collaborators Apr 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(driver): parallelize without_unsupported_orders execution

2 participants