Skip to content

driver: parallelize unsupported order detection#4347

Open
metalurgical wants to merge 36 commits into
cowprotocol:mainfrom
metalurgical:fix_chore_3516
Open

driver: parallelize unsupported order detection#4347
metalurgical wants to merge 36 commits into
cowprotocol:mainfrom
metalurgical:fix_chore_3516

Conversation

@metalurgical

@metalurgical metalurgical commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Description

Allow unsupported order detection be executed in parallel and optimize unsupported order detection.

Changes

  • Move without_unsupported_orders to risk detector.
  • Refactor without_unsupported_orders to do all unsupported order filtering (including flashloans) in one pass.
  • IntroduceDetectorApi trait to decouple the simulation detector for tests.
  • Schedule filtering and and liquidity fetching as separate tasks with tokio::spawn in solve(), allowing parallel execution.
  • Update quote.rs to use without_unsupported_orders.
  • Add test coverage.

How to test

cargo test -p driver

Related Issues

Fixes #3516, follow up PR to #4309 and taking into account #4329

@metalurgical metalurgical requested a review from a team as a code owner April 20, 2026 21:24

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

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.

Code Review

This pull request refactors the competition logic to parallelize unsupported order detection by updating the risk detector API to return a set of UIDs instead of modifying the auction in place. A critical logic error was identified in the new unsupported_order_uids method where orders flagged as unsupported by metrics are filtered out of the processing loop but never added to the removal set, effectively bypassing the intended filtering logic.

Comment thread crates/driver/src/domain/competition/risk_detector/mod.rs Outdated
@metalurgical

Copy link
Copy Markdown
Contributor Author

@jmg-duarte This is minimal, easily reviewable and I think in line with what is expected for resolving the linked issue. Just finishing off what I started.

@AryanGodara AryanGodara left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

left some minor comments

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/risk_detector/mod.rs
@metalurgical metalurgical marked this pull request as draft April 29, 2026 14:55
Make unsupported order detection read-only and execute it in parallel with sorting and data fetching. Apply filtering after update_orders to preserve existing ordering.
@metalurgical metalurgical marked this pull request as ready for review April 29, 2026 22:58
@metalurgical

Copy link
Copy Markdown
Contributor Author

@AryanGodara Thank you for the comments. It should be ready to be reviewed again. Excuse the force push, had to rebase a branch in to ensure it was working and then rebase it out again.

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

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.

Code Review

This pull request refactors the risk detection logic by introducing a SellQualityDetector trait to decouple the simulation detector and improve testability. It updates the Competition and Quote domains to use the refactored filter_unsupported_orders_in_auction and unsupported_order_uids methods, enabling in-place filtering of unsupported orders. Additionally, comprehensive unit tests were added for the Detector logic. I have no feedback to provide as the review comments provided did not meet the high severity threshold required by the style guide.

@AryanGodara AryanGodara left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Description nit: "Run unsupported detection in parallel in solve()" fit the original version, but not entirely accurate imo after the prev commits

The real wins here are the read-only unsupported_order_uids API, so quote.rs can reuse detection without faking an Auction, and the SellQualityDetector trait that enables the new tests. Worth surfacing those in the description instead.

otherwise lgtm

@metalurgical

metalurgical commented May 1, 2026

Copy link
Copy Markdown
Contributor Author

Description nit: "Run unsupported detection in parallel in solve()" fit the original version, but not entirely accurate imo after the prev commits

The real wins here are the read-only unsupported_order_uids API, so quote.rs can reuse detection without faking an Auction, and the SellQualityDetector trait that enables the new tests. Worth surfacing those in the description instead.

otherwise lgtm

Yes, this is true, with the latest commits it is effectively concurrent with liquidity fetching.

Edit: I have updated this to use tokio::spawn to schedule them as separate tasks and checked the PR description as well.

@metalurgical metalurgical changed the title driver: parallel unsupported order detection driver: parallelize unsupported order detection May 1, 2026
@metalurgical metalurgical requested a review from AryanGodara May 4, 2026 06:39
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/risk_detector/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/infra/api/error.rs Outdated
Comment thread crates/driver/src/domain/quote.rs Outdated
Comment thread crates/driver/src/domain/competition/risk_detector/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/risk_detector/mod.rs Outdated
@metalurgical metalurgical requested a review from jmg-duarte May 4, 2026 21:34
@metalurgical metalurgical requested a review from jmg-duarte May 5, 2026 21:50
Comment thread crates/driver/src/domain/competition/mod.rs
solver::Liquidity::Fetch => tasks.liquidity.await,
solver::Liquidity::Skip => Arc::new(Vec::new()),
let (auction, liquidity) = tokio::join!(
tokio::spawn(

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.

tokio::spawn returns detached JoinHandles. tokio::join! awaits them, but if the outer solve() future is dropped (e.g. client disconnect, overload shed), the spawned tasks keep running to completion. The previous inline tokio::join!(async { … }, future) would have been cancelled with the parent.

@metalurgical metalurgical May 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I see your point. Though this behavior is not new here, it already exists with run_blocking_with_timer.

I would like to suggest that you have a look at #4379. The same concept there can be used for this as well, just couple it with a scopeguard. This is also probably better implemented there as well, else it is duplicating efforts.

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.

Wouldn't this be solveable by simply using a cancellationtoken + dropguard?
The PR you're pointing to is huge and the scope/steps need to be discussed

@metalurgical metalurgical May 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes that is it.

The PR I am pointing to already has the cancellation token threaded through. It appears large but much of it is tests and plumbing. Did subsequently open an issue for it, #4380. So it just needs the drop guard added to it (and an patched in here) then the above behavior mentioned here will be handled as well.

Happy to discuss scope and steps further.

@metalurgical metalurgical requested a review from squadgazzz May 6, 2026 21:21

@squadgazzz squadgazzz left a comment

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.

Two notes on the c06963a refactor.

Comment thread crates/driver/src/domain/competition/risk_detector/mod.rs Outdated
Comment thread crates/driver/src/domain/competition/risk_detector/mod.rs Outdated
@metalurgical metalurgical requested a review from squadgazzz May 11, 2026 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(driver): parallelize without_unsupported_orders execution

4 participants