refactor: parallelize unsupported-order detection and defer filtering#4309
refactor: parallelize unsupported-order detection and defer filtering#4309metalurgical wants to merge 3 commits intocowprotocol:mainfrom
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
There was a problem hiding this comment.
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.
|
I believe this change is built on top of your other PR, please separate them for easier review |
jmg-duarte
left a comment
There was a problem hiding this comment.
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
|
@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. |
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.
|
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 |
There was a problem hiding this comment.
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
| /// 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 | ||
| } |
| let orders_for_unsupported_filter: Vec<competition::Order> = auction.orders.clone(); | ||
| let unsupported_uids = risk_detector | ||
| .unsupported_order_uids(&orders_for_unsupported_filter) | ||
| .await; |
There was a problem hiding this comment.
| 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; |
| let mut auction = auction; | ||
| if !unsupported_uids.is_empty() { | ||
| auction | ||
| .orders | ||
| .retain(|order| !unsupported_uids.contains(&order.uid)); | ||
| } |
There was a problem hiding this comment.
nit to restrict mutability's "lifetime"
| 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 | |
| }; |
| use std::sync::Arc; | ||
| use { |
There was a problem hiding this comment.
This won't pass CI, be sure to test stuff locally, we have the just scripts etc
| } | ||
|
|
||
| auction | ||
| removed_uids |
There was a problem hiding this comment.
| removed_uids | |
| unsupported_uids |
| let order = order.clone(); | ||
| let check_tokens_fut = async move { | ||
| let quality = detector.determine_sell_token_quality(&order, now).await; | ||
| (order.uid, quality) | ||
| }; |
There was a problem hiding this comment.
| 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); | ||
|
|
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
This is wrong, creating the future doesn't drive it
| let unsupported_orders_future = | ||
| async move { self.unsupported_order_uids(&orders_for_unsupported).await }; |
There was a problem hiding this comment.
This filters flashloans before orders were loaded with app_data, meaning that the flashloan check ends up being wrong
| // 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, | ||
| ); |
There was a problem hiding this comment.
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
Description
Parallelize unsupported-order detection and defer filtering
Changes
- 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 #4308Split from PR