Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/CODEBASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ See `docs/ARCHITECTURE.md` for the full architecture diagram and detailed compon
| `HTTP_HOST` | HTTP bind address (default: `0.0.0.0`) |
| `HTTP_PORT` | API port (default: `3000`) |
| `CONFIG_FILE` | Solver config file (default: `fynd.toml` if present) |
| `REMOTE_CONFIG_URL` | Remote config URL (default: chain-specific PropellerHeads S3 URL; `--no-remote-config` disables) |
| `WORKER_POOLS_CONFIG` | Deprecated legacy pools-only config file; its pools override the config file's |
| `BLOCKLIST_CONFIG` | Blocklist config file |
| `RUST_LOG` | Tracing filter (e.g. `info,fynd=debug`) |
Expand All @@ -120,7 +121,7 @@ See `docs/ARCHITECTURE.md` for the full architecture diagram and detailed compon

| File | Purpose |
|---|---|
| `fynd.toml` | Full solver config: any subset of tuning fields + `[pools]`. Resolved field-by-field: CLI > file > embedded default (`fynd-core/src/config/default_config.toml`) |
| `fynd.toml` | Full solver config: any subset of tuning fields + `[pools]`. Resolved field-by-field: CLI > file > remote config (S3, per chain) > embedded default (`fynd-core/src/config/default_config.toml`) |
| `worker_pools.toml` | Deprecated legacy pools-only file, still honored (its pools override the config file's) |
| `blocklist.toml` | Component IDs to exclude from the Tycho stream. Optional — falls back to tycho-simulation defaults if not found |

Expand Down
6 changes: 4 additions & 2 deletions docs/guides/server-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ Run `fynd serve --help` for the full list.
| `--worker-router-timeout-ms` | — | `100` | Default solve timeout (ms) |
| `--worker-router-min-responses` | — | `0` | Early return threshold (0 = wait for all pools) |
| `--config-file` | `CONFIG_FILE` | `fynd.toml` (if present) | TOML config file overriding the embedded defaults (see [Config file](#config-file-fyndtoml)). |
| `--remote-config-url` | `REMOTE_CONFIG_URL` | _(chain-specific S3 URL)_ | Remote config with the latest tuned values, pulled at startup. Fetch failures never block startup. |
| `--no-remote-config` | — | `false` | Disable the remote config fetch. |
| `-w, --worker-pools-config` | `WORKER_POOLS_CONFIG` | `worker_pools.toml` (if present) | **Deprecated** — legacy pools-only config file; move the `[pools]` section into `fynd.toml`. Still honored: its pools override the config file's. |
| `--blocklist-config` | `BLOCKLIST_CONFIG` | [tycho-simulation default](https://github.com/propeller-heads/tycho-simulation/blob/main/blocklist.toml) | Path to blocklist TOML config file. Components listed here are excluded from the Tycho stream. |
| `--disable-tls` | — | `false` | Disable TLS for Tycho connection |
Expand All @@ -104,8 +106,8 @@ Run `fynd serve --help` for the full list.

## Config file (`fynd.toml`)

Every solver-tuning flag above resolves field-by-field through three layers, highest priority
first: **CLI flags > config file > embedded defaults**. The config file may set any subset of
Every solver-tuning flag above resolves field-by-field through four layers, highest priority
first: **CLI flags > config file > remote config (S3) > embedded defaults**. The config file may set any subset of
the fields (same names as the flags) plus the worker pools; `./fynd.toml` is picked up
automatically, or pass `--config-file`.

Expand Down
2 changes: 1 addition & 1 deletion fynd-core/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ applications.
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `algorithm/` | `Algorithm` trait + built-in `MostLiquidAlgorithm`, `BellmanFordAlgorithm`, `PathFrankWolfeAlgorithm`. Pluggable via associated graph types. `AlgorithmConfig` shared by all |
| `solver.rs` | `FyndBuilder` assembles the full pipeline (feed + gas + computations + pools + encoder + router). `Solver` runs it |
| `config/` | Layered solver config: `embedded_default()` parses `default_config.toml` (single source of truth for all tuning defaults) into a complete `Config`; `PartialConfig` layers overlay via `Config::apply` (CLI/file > embedded); `Config::validate` range-checks the result |
| `config/` | Layered solver config: `embedded_default()` parses `default_config.toml` (single source of truth for all tuning defaults) into a complete `Config`; `PartialConfig` layers overlay via `Config::apply` (CLI > file > remote > embedded); `config::remote` fetches per-chain tuned values from S3 (fail-safe: retries, size cap, warn-and-fallback, never panics), `get_default(chain)` = embedded + remote in one call; `Config::validate` range-checks the result |
| `worker_pool/` | `WorkerPool` manages dedicated OS threads. `SolverWorker` runs a prioritized select loop (shutdown > market events > derived events > tasks). `TaskQueue` is `async_channel`-based |
| `worker_pool_router/` | `WorkerPoolRouter` fans out orders to all pools, ranks candidates by `amount_out_net_gas` descending; price guard (if enabled) validates in rank order; optionally encodes |
| `feed/` | `TychoFeed` (WebSocket → MarketState), `GasPriceFetcher`, `MarketEvent` broadcasting, `ProtocolRegistry` |
Expand Down
26 changes: 25 additions & 1 deletion fynd-core/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
//!
//! 1. **Explicit overrides** — lib builder setters or CLI flags
//! 2. **Local config file** — any subset of the fields, same schema as the embedded default
//! 3. **Embedded default** — `default_config.toml`, compiled into the binary
//! 3. **Remote config** — tuned values pulled from S3 per chain (see [`remote`])
//! 4. **Embedded default** — `default_config.toml`, compiled into the binary
//!
//! The embedded default deserializes directly into a complete [`Config`] — every field
//! (except the chain-specific `min_tvl`) is required, so a gap between the struct and
Expand All @@ -26,6 +27,8 @@
//! let overrides = PartialConfig { worker_router_timeout_ms: Some(50), ..Default::default() };
//! let config = embedded_default()
//! .clone()
//! .apply_remote(&remote::default_remote_config_url(chain), timeout)
//! .await
//! .apply(&PartialConfig::from_file("fynd.toml")?)
//! .apply(&overrides);
//! let builder = FyndBuilder::new(chain, tycho_url, rpc_url, config.protocols.clone(), min_tvl)
Expand All @@ -39,6 +42,8 @@ use tycho_simulation::tycho_common::models::{Chain, TvlThresholdTier};

use crate::solver::PoolConfig;

pub mod remote;

/// The embedded default configuration, compiled into the binary.
const EMBEDDED_DEFAULT_TOML: &str = include_str!("default_config.toml");

Expand Down Expand Up @@ -151,6 +156,25 @@ pub fn embedded_default() -> &'static Config {
&EMBEDDED_DEFAULT
}

/// Overall time budget (including retries) for the fetch inside [`get_default`].
/// Callers wanting a different budget use [`Config::apply_remote`] directly.
const GET_DEFAULT_FETCH_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(2);

/// Returns the embedded default configuration with the latest remotely tuned values for
/// `chain` applied on top, fetched from the default S3 URL (see
/// [`remote::default_remote_config_url`]).
///
/// The simple one-call form of `embedded_default().clone().apply_remote(...)`, with a
/// built-in 2 s fetch budget. Never fails or panics: on any fetch problem the embedded
/// defaults are returned unchanged (a warning is logged). Layer local overrides on top
/// with [`Config::apply`]; for a custom URL or timeout use [`Config::apply_remote`].
pub async fn get_default(chain: Chain) -> Config {
embedded_default()
.clone()
.apply_remote(&remote::default_remote_config_url(chain), GET_DEFAULT_FETCH_TIMEOUT)
.await
}

impl Config {
/// Returns `min_tvl`, falling back to `chain`'s default TVL threshold when unset.
pub fn min_tvl_or_chain_default(&self, chain: Chain) -> f64 {
Expand Down
Loading
Loading