Skip to content

Conversation

@squadgazzz
Copy link
Contributor

@squadgazzz squadgazzz commented Dec 17, 2025

Description

From the original issue #3831:

The orderbook(s) and the autopilot run as separate processes but both need access to native prices. Unfortunately they don't share the same underlying native price cache which can lead to inconsistencies - especially for niche tokens.
For example the orderbook could be able to fetch a native price and allow an order to be placed. Then the autopilot will pick up the order from the DB and try to fetch the native price as well. If a token is very niche there might only be 1 solver supporting it and it's possible that it serves the orderbook request correctly but rate limits the autopilot request.

To fix this we need to have 1 native price cache that all services can use. Ideally we'd move all the quoting logic into a separate service and make it use a Redis cache (in case we need to scale the service horizontally).
However that is a lot of work and we can get a pretty reasonably approximation with a lot less effort.

For that we just need to make the orderbook forward the native price requests to the autopilot. This will then cause the autopilot cache to be the 1 shared cache for all the processes.

Changes

  • Added axum server to autopilot to handle /native_price requests
  • The orderbook forwards requests to a configurable URL
    • The new functionality is integrated into the current native price estimator config in the following way:
      • Driver native price estimator now has the Driver prefix to distinguish between legacy and new approach
      • The Forwarder prefix is added to use the Forwarder native price estimator.
    • The orderbook also forwards the native price timeout. This query param is optional, and autopilot fallbacks to the configured one if not provided in the request.
  • Adjusted e2e tests
    • Autopilot is now used as a native price estimator in all the tests.
    • The dual_autopilot_only_leader_produces_auctions requires running 2 autopilots at the same time for some period of time. Since it doesn't make much sense to specify more than 2 autopilot URLs in the orderbook config, a reverse proxy is introduced to make this test pass. This proxy simulates k8s behavior: when 2 instances of the same service are running, requests are automatically routed between them. An alternative approach is to run 2 autopilot APIs on different ports and specify them in the orderbook config, but the reverse proxy simulates the production behavior.
  • The API server is initialized before the metrics for a reason. Currently, the metrics port is used as a readiness probe in the k8s cluster. To avoid introducing an additional readiness probe endpoint, I decided to continue using the metrics port. But if the metrics readiness probe becomes available before the API server, the new service is added to the k8s proxy pool and starts serving orderbook requests, but since the server is not initialized fully, there is a chance that some of the requests fail. Initializing the metrics only after the API server resolves this issue.
  • An openapi.yml file with the hope that this component will be decentralized in the future.

How to test

Updated e2e tests. This also requires running tests on staging manually.

Related Issues

Partially fixes #3831

Further implementation

Once we are confident the new approach works well, the old config with native price estimators can be dropped from the orderbook crate.

@squadgazzz squadgazzz force-pushed the autopilot/native-price-api branch from f37f048 to 4699fb5 Compare December 17, 2025 11:17
@squadgazzz squadgazzz force-pushed the autopilot/native-price-api branch from 31968f3 to 5db5fc0 Compare December 17, 2025 19:42
@squadgazzz squadgazzz marked this pull request as ready for review December 17, 2025 20:09
@squadgazzz squadgazzz requested a review from a team as a code owner December 17, 2025 20:09
Copilot AI review requested due to automatic review settings December 17, 2025 20:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a native price API in the autopilot service and configures the orderbook to forward native price requests to it, addressing inconsistencies caused by separate caches in different processes. The implementation includes a fallback mechanism to the legacy price estimators if the autopilot is unavailable.

Key Changes:

  • Added an HTTP API server to autopilot exposing a /native_price/:token endpoint
  • Implemented a forwarding native price estimator in the orderbook that delegates to the autopilot API with fallback support
  • Updated e2e test infrastructure with a reverse proxy to support the dual-autopilot test scenario

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
crates/autopilot/src/infra/api.rs New HTTP API server for serving native price requests with error mapping
crates/autopilot/src/infra/mod.rs Module declaration for the new API module
crates/autopilot/src/run.rs Integration of the API server with graceful shutdown handling
crates/autopilot/src/arguments.rs Added CLI argument for configuring the native price API bind address
crates/autopilot/Cargo.toml Added axum, tower, and tower-http dependencies with tracing support
crates/orderbook/src/native_price_forwarder.rs New forwarding estimator that proxies requests to autopilot with fallback logic
crates/orderbook/src/lib.rs Module declaration for the native price forwarder
crates/orderbook/src/run.rs Wraps the native price estimator with the forwarder when autopilot URL is configured
crates/orderbook/src/arguments.rs Added CLI argument for the autopilot native price API URL
crates/e2e/src/setup/proxy.rs New reverse proxy implementation for load balancing between two autopilot instances in tests
crates/e2e/src/setup/mod.rs Module declaration for the proxy
crates/e2e/src/setup/services.rs Updated default test configuration to use autopilot for native prices
crates/e2e/tests/e2e/autopilot_leader.rs Updated dual-autopilot test to use the proxy for native price API failover
Cargo.lock Dependency updates reflecting new autopilot dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

Reminder: Please consider backward compatibility when modifying the API specification.
If breaking changes are unavoidable, ensure:

  • You explicitly pointed out breaking changes.
  • You communicate the changes to affected teams (at least Frontend team and SAFE team).
  • You provide proper versioning and migration mechanisms.

Caused by:

@squadgazzz squadgazzz marked this pull request as draft December 18, 2025 10:14
@squadgazzz squadgazzz marked this pull request as ready for review December 18, 2025 14:49
@squadgazzz squadgazzz requested a review from fafk December 18, 2025 14:52
Comment on lines +20 to +21
estimator: Arc<dyn NativePriceEstimating>,
timeout: Duration,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think having everything together in one file is okay for now but when we introduce more endpoints (e.g. for debugging stuff or so) we should have a better code structure.

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.

forward native price requests to autopilot

5 participants