Skip to content

Settle fast-path orders from the autopilot - #4729

Open
AryanGodara wants to merge 4 commits into
actually-store-quote-competition-datafrom
aryan/be-62-autopilot-settle-fastpath
Open

Settle fast-path orders from the autopilot#4729
AryanGodara wants to merge 4 commits into
actually-store-quote-competition-datafrom
aryan/be-62-autopilot-settle-fastpath

Conversation

@AryanGodara

@AryanGodara AryanGodara commented Aug 11, 2026

Copy link
Copy Markdown
Member

Description

When a fast-path order arrives, the autopilot recovers its quote's winning solution and settles it out of competition via the driver's /settle.
Solves BE-62.

Stacked on #4737.

Changes

  • on every new order, look up its quote's auction_id, then recover the winning solution + fill from proposed_solutions / proposed_trade_executions
  • send the order, its fill (limit) prices, and native prices to the driver that produced the quote, matched by solver address
  • add the fastPath payload to the autopilot's /settle DTO

How to test

No automated tests yet: the competition data this reads isn't persisted until BE-56, so the listener is no-op on real orders for now. I verified locally by seeding a competition in local DB (with all migrations) and asserting fast_path_order returns it. The end-to-end test should land once BE-56 and orderbook fast-path support are in.
For those reasons keeping this PR in draft for now

@AryanGodara AryanGodara self-assigned this Aug 11, 2026
@linear-code

linear-code Bot commented Aug 11, 2026

Copy link
Copy Markdown

BE-62

Comment thread crates/autopilot/src/infra/order_notify/fast_path.rs
Comment thread crates/autopilot/src/infra/order_notify/fast_path.rs Outdated
Comment thread crates/autopilot/src/infra/order_notify/fast_path.rs
Comment thread crates/autopilot/src/infra/persistence/mod.rs Outdated
Comment thread crates/autopilot/src/infra/persistence/mod.rs Outdated
Comment thread crates/autopilot/src/infra/solvers/dto/settle.rs
Base automatically changed from aryan/be-58-settle-fastpath-quote to main August 13, 2026 07:09
@AryanGodara
AryanGodara force-pushed the aryan/be-62-autopilot-settle-fastpath branch from b6c9e30 to 9ceb810 Compare August 13, 2026 07:22
@AryanGodara
AryanGodara changed the base branch from main to actually-store-quote-competition-data August 14, 2026 14:51
@AryanGodara
AryanGodara force-pushed the aryan/be-62-autopilot-settle-fastpath branch from 9ceb810 to a2eb919 Compare August 14, 2026 14:54
@AryanGodara
AryanGodara force-pushed the aryan/be-62-autopilot-settle-fastpath branch from d318fbe to 26528a1 Compare August 14, 2026 16:38
@AryanGodara
AryanGodara marked this pull request as ready for review August 14, 2026 16:56
@AryanGodara
AryanGodara requested a review from a team as a code owner August 14, 2026 16:56
@claude

claude Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Claude finished @AryanGodara's task in 4m 29s —— View job


PR Review: Settle fast-path orders from the autopilot

Reviewed against origin/actually-store-quote-competition-data. The earlier review points look addressed — the settle now runs in a spawned task (fast_path.rs:127), initiation is logged with solver/uid/auction_id (fast_path.rs:68), the native-price lookup uses Duration::ZERO, the DB read is a single joined query (single_fast_path_order), and the fill amount is now passed through to the driver (executed/limit_prices). Nice, focused stack.

One substantive finding, posted inline:

  • native_prices isn't actually cache-only on a miss (fast_path.rs:79) — estimate_native_price(_, Duration::ZERO) short-circuits only on a cache hit; a miss falls through to a live, un-time-bounded fetch (fetch_prices guards timeout.is_zero(), the singular method does not). Can blow the fast-path window and the doc comment overstates the behavior.

Nothing else blocking from my side. The executed == limit_prices.sell/buy fill relies on the recorded amount exactly matching the signed order for non-partial fills (Static-fee market orders) — worth keeping an eye on once real competition data flows, but consistent with compare_orders already gating the match.

Comment thread crates/autopilot/src/infra/order_notify/fast_path.rs Outdated
Comment thread crates/autopilot/src/infra/order_notify/fast_path.rs Outdated
Comment thread crates/autopilot/src/infra/order_notify/fast_path.rs Outdated
Comment thread crates/autopilot/src/infra/order_notify/fast_path.rs Outdated
Comment on lines +1021 to +1023
// The cached solution carries the fees and quote; so the recovered
// order needs neither.
let order = boundary::order::to_domain(&model_order, vec![], None);

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.

I don't think this is true. When we send /quote requests we don't send any fee data with the order.
This might actually become quite painful. When the orderbook updates the competition data the executed_sell and executed_buy would already have to account for those fees. 🤕
We definitely need a test asserting that the price at which the order ultimately gets filled makes sense given the original quote, gas usage, and fees (protocol and partner).

Comment thread crates/autopilot/src/run.rs Outdated
Comment thread crates/e2e/tests/e2e/fast_path_settle.rs Outdated
Comment thread crates/e2e/tests/e2e/fast_path_settle.rs Outdated
Comment thread crates/e2e/tests/e2e/fast_path_settle.rs
Comment thread crates/configs/src/orderbook/order_validation.rs Outdated
Comment on lines +261 to +265
// Held out: not settled early by the fast path.
assert_eq!(
services.get_order(&uid).await.unwrap().metadata.status,
OrderStatus::Open
);

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.

I think this assertion doesn't give us anything. The order could be unsettled immediately after placing it just because the autopilot is a bit slow to kick things off.

Comment on lines +300 to +302
sqlx::query_scalar(
"SELECT id FROM competition_auctions WHERE order_uids @> ARRAY[$1::bytea]",
)

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.

Not sure what this is supposed to prove. The other test has the additional condition that the auction_id must not be the one associated with the quote but here we don't have that. So if we only settle after valid_from due to a bug but still in the original quote auction we wouldn't realize that.

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.

2 participants