Skip to content

Commit

Permalink
Retry oneinch solver init (#36)
Browse files Browse the repository at this point in the history
Recently the oneinch solver pod crashes during initialization more
frequently. This is due to rate limits during `OneInch::new()`.

This PR makes it so that we retry the initialization 10s because this is
usually just a temporary error.

While I was at it I unified the semantics of all `Solver::new()`
implementations to panic if a non recoverable error happens which makes
the code slightly nicer to read. (Only paraswap needed this change)
  • Loading branch information
MartinquaXD authored Jun 7, 2024
1 parent 7d5b158 commit 48d5202
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
33 changes: 31 additions & 2 deletions src/infra/dex/oneinch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use {
},
ethereum_types::H160,
ethrpc::current_block::CurrentBlockStream,
std::sync::atomic::{self, AtomicU64},
std::{
sync::atomic::{self, AtomicU64},
time::{Duration, Instant},
},
tracing::Instrument,
};

Expand All @@ -19,6 +22,7 @@ pub struct OneInch {
spender: eth::ContractAddress,
}

#[derive(Debug, Clone)]
pub struct Config {
/// The base URL for the 1Inch swap API.
pub endpoint: Option<reqwest::Url>,
Expand All @@ -45,6 +49,7 @@ pub struct Config {
pub block_stream: Option<CurrentBlockStream>,
}

#[derive(Debug, Clone)]
pub enum Liquidity {
Any,
Only(Vec<String>),
Expand All @@ -54,7 +59,31 @@ pub enum Liquidity {
pub const DEFAULT_URL: &str = "https://api.1inch.io/v5.0/1/";

impl OneInch {
pub async fn new(config: Config) -> Result<Self, Error> {
/// Initializes a new solver instance. Panics if it doesn't succeed after a
/// short period of time.
pub async fn new(config: Config) -> Self {
/// How long we try to initialize the solver before panicking.
const INIT_TIMEOUT: Duration = Duration::from_secs(10);
/// How long to wait before trying to initialize the solver again.
const RETRY_DELAY: Duration = Duration::from_secs(1);

let start = Instant::now();
loop {
let error = match Self::try_new(config.clone()).await {
Ok(solver) => return solver,
Err(err) => err,
};

if start.elapsed() > INIT_TIMEOUT {
panic!("could not initialize oneinch solver in time");
} else {
tracing::warn!(?error, "failed to initialize oneinch solver; trying again");
tokio::time::sleep(RETRY_DELAY).await;
}
}
}

async fn try_new(config: Config) -> Result<Self, Error> {
let client = super::Client::new(Default::default(), config.block_stream);
let endpoint = config
.endpoint
Expand Down
12 changes: 7 additions & 5 deletions src/infra/dex/paraswap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,23 @@ pub struct Config {
}

impl ParaSwap {
pub fn new(config: Config) -> anyhow::Result<Self> {
let mut key = reqwest::header::HeaderValue::from_str(&config.api_key)?;
/// Tries to initialize a new solver instance. Panics if it fails.
pub fn new(config: Config) -> Self {
let mut key = reqwest::header::HeaderValue::from_str(&config.api_key).unwrap();
key.set_sensitive(true);

let mut headers = reqwest::header::HeaderMap::new();
headers.insert("x-api-key", key);

let client = reqwest::Client::builder()
.default_headers(headers)
.build()?;
.build()
.unwrap();

Ok(Self {
Self {
client: super::Client::new(client, config.block_stream.clone()),
config,
})
}
}

pub async fn swap(
Expand Down
4 changes: 2 additions & 2 deletions src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ async fn run_with(args: cli::Args, bind: Option<oneshot::Sender<SocketAddr>>) {
cli::Command::OneInch { config } => {
let config = config::dex::oneinch::file::load(&config).await;
Solver::Dex(solver::Dex::new(
dex::Dex::OneInch(dex::oneinch::OneInch::new(config.oneinch).await.unwrap()),
dex::Dex::OneInch(dex::oneinch::OneInch::new(config.oneinch).await),
config.base.clone(),
))
}
cli::Command::ParaSwap { config } => {
let config = config::dex::paraswap::file::load(&config).await;
Solver::Dex(solver::Dex::new(
dex::Dex::ParaSwap(dex::paraswap::ParaSwap::new(config.paraswap).unwrap()),
dex::Dex::ParaSwap(dex::paraswap::ParaSwap::new(config.paraswap)),
config.base.clone(),
))
}
Expand Down

0 comments on commit 48d5202

Please sign in to comment.