Conversation
25faaca to
39c2c27
Compare
There was a problem hiding this comment.
Code Review
This pull request effectively resolves a race condition where in-flight orders could be incorrectly marked as invalid. The change moves the filtering of in-flight orders to an earlier stage in solvable_orders.rs, ensuring they are removed from consideration before balance and validity checks occur. This correctly prevents orders that are being settled from being marked as invalid due to temporary balance changes. The implementation is sound and no critical issues were found.
Note: Security Review did not run due to the size of the PR.
| let surplus_capturing_jit_order_owners: Vec<_> = cow_amms | ||
| .iter() | ||
| .filter(|cow_amm| { | ||
| if in_flight_owners.contains(cow_amm.address()) { |
There was a problem hiding this comment.
Probably worth adding a short comment on why it is intentional to filter AMM orders by owners instead of UID.
There was a problem hiding this comment.
I have no idea why this is the case, I just kept the original logic from the deleted code. 😅
There was a problem hiding this comment.
Orders rebalancing cow amms revert when the cow amm does not have exactly the state the order was crafted for so having multiple orders in-flight for the same cow amm is an issue.
Additionally an amm can be rebalanced in many different ways which would all result in different order UIDs so filtering based on that is not sufficient. That's way we check if there is any order in-flight for that amm based on the owner of the order (i.e. the cow amm) and then discard that amm altogether for that auction.
There was a problem hiding this comment.
I added the above as a comment verbatim. 🌚
| } | ||
|
|
||
| #[instrument(skip_all)] | ||
| async fn fetch_in_flight_orders(&self, block: u64) -> HashSet<OrderUid> { |
There was a problem hiding this comment.
Do we need to keep this annotation?
| async fn fetch_in_flight_orders(&self, block: u64) -> HashSet<OrderUid> { | |
| #[instrument(skip_all)] | |
| async fn fetch_in_flight_orders(&self, block: u64) -> HashSet<OrderUid> { |
There was a problem hiding this comment.
We don't, the fn that runs the actual query is annotated. This fn that just does the remapping would just add noise.
MartinquaXD
left a comment
There was a problem hiding this comment.
Comments could be cleaned up a bit more but overall LGTM.
| let surplus_capturing_jit_order_owners: Vec<_> = cow_amms | ||
| .iter() | ||
| .filter(|cow_amm| { | ||
| if in_flight_owners.contains(cow_amm.address()) { |
There was a problem hiding this comment.
Orders rebalancing cow amms revert when the cow amm does not have exactly the state the order was crafted for so having multiple orders in-flight for the same cow amm is an issue.
Additionally an amm can be rebalanced in many different ways which would all result in different order UIDs so filtering based on that is not sufficient. That's way we check if there is any order in-flight for that amm based on the owner of the order (i.e. the cow amm) and then discard that amm altogether for that auction.
Co-authored-by: Martin Magnus <martin.beckmann@protonmail.com>
1ed78f0 to
033c046
Compare
Description
When I was working on another feature (the debug endpoint) I noticed that there is a race condition where we sometimes insert "invalid" order event to the DB.
From logs
Order is in
executingstate, then settles onchain. If the indexing runs now and we set the order totradedall is well. However if the in cache update runs first it's possible the wallet no longer has the necessary balance as it was traded away in the just executed swap and we consider it invalid and we insert the invalid event for an order that went through perfectly well.Changes
How to test
I had an e2e test to reproduce this which failed 6/10 times. After the fix it fails 0/10.