From 9b72689dfab0ae3bbecb013aa8c98072d9c19720 Mon Sep 17 00:00:00 2001 From: metalurgical <97008724+metalurgical@users.noreply.github.com> Date: Sun, 21 Jun 2026 03:30:39 +0200 Subject: [PATCH 1/5] refactor: replace TimeSizedCache with Moka --- Cargo.lock | 2 +- crates/balance-overrides/src/balance/mod.rs | 2 +- crates/orderbook/Cargo.toml | 2 +- crates/orderbook/src/ipfs_app_data.rs | 27 +++++++-------------- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 933cb0ff3a..02cb8713bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6115,7 +6115,6 @@ dependencies = [ "bad-tokens", "balance-overrides", "bigdecimal", - "cached", "chain", "chrono", "clap", @@ -6134,6 +6133,7 @@ dependencies = [ "mimalloc", "mockall", "model", + "moka", "multibase", "num", "number", diff --git a/crates/balance-overrides/src/balance/mod.rs b/crates/balance-overrides/src/balance/mod.rs index e8a5f225bb..c1cbc39b65 100644 --- a/crates/balance-overrides/src/balance/mod.rs +++ b/crates/balance-overrides/src/balance/mod.rs @@ -891,7 +891,7 @@ mod tests { let strategy = detector.detect(NATIVE_ETH, user).await.unwrap(); - std::assert_matches!(strategy, Strategy::NativeEth); + std::assert_eq!(strategy, Strategy::NativeEth); // ETH is not an ERC20 token so we can't do an `eth_call` on `balanceOf()`. // Additionally `eth_getBalance` does not support state overrides. diff --git a/crates/orderbook/Cargo.toml b/crates/orderbook/Cargo.toml index 22737e4cb4..8ebd925ac1 100644 --- a/crates/orderbook/Cargo.toml +++ b/crates/orderbook/Cargo.toml @@ -25,7 +25,6 @@ axum = { workspace = true } bad-tokens = { workspace = true } balance-overrides = { workspace = true } bigdecimal = { workspace = true } -cached = { workspace = true } chain = { workspace = true } chrono = { workspace = true, features = ["clock"] } clap = { workspace = true } @@ -43,6 +42,7 @@ humantime = { workspace = true } humantime-serde = { workspace = true } mimalloc = { workspace = true, optional = true } model = { workspace = true } +moka = { workspace = true } multibase = { workspace = true } num = { workspace = true } number = { workspace = true } diff --git a/crates/orderbook/src/ipfs_app_data.rs b/crates/orderbook/src/ipfs_app_data.rs index 34493cb4e8..deb267d4e4 100644 --- a/crates/orderbook/src/ipfs_app_data.rs +++ b/crates/orderbook/src/ipfs_app_data.rs @@ -2,13 +2,12 @@ use { crate::ipfs::Ipfs, anyhow::Result, app_data::{AppDataHash, create_ipfs_cid}, - cached::{Cached, TimedSizedCache}, - std::sync::Mutex, + moka::sync::Cache, }; pub struct IpfsAppData { ipfs: Ipfs, - cache: Mutex>>, + cache: Cache>, metrics: &'static Metrics, } @@ -34,9 +33,10 @@ impl IpfsAppData { } Self { ipfs, - cache: Mutex::new(TimedSizedCache::with_size_and_lifespan_and_refresh( - 1000, 600, false, - )), + cache: Cache::builder() + .max_capacity(1000) + .time_to_live(std::time::Duration::from_secs(600)) + .build(), metrics, } } @@ -63,7 +63,7 @@ impl IpfsAppData { result } Ok(None) => { - tracing::debug!(?contract_app_data, %cid,"no full app data"); + tracing::debug!(?contract_app_data, %cid, "no full app data"); return Ok(None); } Err(err) => { @@ -88,13 +88,7 @@ impl IpfsAppData { let outcome = |data: &Option| if data.is_some() { "found" } else { "missing" }; let metric = &self.metrics.app_data; - if let Some(cached) = self - .cache - .lock() - .unwrap() - .cache_get(contract_app_data) - .cloned() - { + if let Some(cached) = self.cache.get(contract_app_data) { metric.with_label_values(&[outcome(&cached), "cache"]).inc(); return Ok(cached); } @@ -111,10 +105,7 @@ impl IpfsAppData { } }; - self.cache - .lock() - .unwrap() - .cache_set(*contract_app_data, result.clone()); + self.cache.insert(*contract_app_data, result.clone()); metric.with_label_values(&[outcome(&result), "node"]).inc(); Ok(result) } From d25ca1326faa34dffc23974156c4da9663c04fb1 Mon Sep 17 00:00:00 2001 From: metalurgical <97008724+metalurgical@users.noreply.github.com> Date: Sun, 21 Jun 2026 15:23:13 +0200 Subject: [PATCH 2/5] refactor: change sync cache to future --- crates/orderbook/src/ipfs_app_data.rs | 38 +++++++++++++++------------ 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/crates/orderbook/src/ipfs_app_data.rs b/crates/orderbook/src/ipfs_app_data.rs index deb267d4e4..d85d5705e2 100644 --- a/crates/orderbook/src/ipfs_app_data.rs +++ b/crates/orderbook/src/ipfs_app_data.rs @@ -2,7 +2,7 @@ use { crate::ipfs::Ipfs, anyhow::Result, app_data::{AppDataHash, create_ipfs_cid}, - moka::sync::Cache, + moka::future::Cache, }; pub struct IpfsAppData { @@ -79,33 +79,37 @@ impl IpfsAppData { } } }; - futures::future::select_ok([std::pin::pin!(fetch(old)), std::pin::pin!(fetch(new))]) - .await - .map(|(ok, _rest)| ok) + let result = + futures::future::select_ok([std::pin::pin!(fetch(old)), std::pin::pin!(fetch(new))]) + .await + .map(|(ok, _rest)| ok); + if result.is_err() { + self.metrics + .app_data + .with_label_values(&["error", "node"]) + .inc(); + } + result } pub async fn fetch(&self, contract_app_data: &AppDataHash) -> Result> { let outcome = |data: &Option| if data.is_some() { "found" } else { "missing" }; let metric = &self.metrics.app_data; - if let Some(cached) = self.cache.get(contract_app_data) { + if let Some(cached) = self.cache.get(contract_app_data).await { metric.with_label_values(&[outcome(&cached), "cache"]).inc(); return Ok(cached); } - let fetched = { - let _timer = self.metrics.fetches.start_timer(); - self.fetch_raw(contract_app_data).await - }; - let result = match fetched { - Ok(result) => result, - Err(err) => { - metric.with_label_values(&["error", "node"]).inc(); - return Err(err); - } - }; + let result = self + .cache + .try_get_with(*contract_app_data, async { + let _timer = self.metrics.fetches.start_timer(); + self.fetch_raw(contract_app_data).await + }) + .await + .map_err(|e| anyhow::anyhow!("{e}"))?; - self.cache.insert(*contract_app_data, result.clone()); metric.with_label_values(&[outcome(&result), "node"]).inc(); Ok(result) } From ce27f50146ba4a22a377be42e22c9f13a9e92533 Mon Sep 17 00:00:00 2001 From: metalurgical <97008724+metalurgical@users.noreply.github.com> Date: Mon, 22 Jun 2026 18:34:28 +0200 Subject: [PATCH 3/5] update --- crates/orderbook/src/ipfs_app_data.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/crates/orderbook/src/ipfs_app_data.rs b/crates/orderbook/src/ipfs_app_data.rs index d85d5705e2..6330d56e73 100644 --- a/crates/orderbook/src/ipfs_app_data.rs +++ b/crates/orderbook/src/ipfs_app_data.rs @@ -79,17 +79,9 @@ impl IpfsAppData { } } }; - let result = - futures::future::select_ok([std::pin::pin!(fetch(old)), std::pin::pin!(fetch(new))]) - .await - .map(|(ok, _rest)| ok); - if result.is_err() { - self.metrics - .app_data - .with_label_values(&["error", "node"]) - .inc(); - } - result + futures::future::select_ok([std::pin::pin!(fetch(old)), std::pin::pin!(fetch(new))]) + .await + .map(|(ok, _rest)| ok) } pub async fn fetch(&self, contract_app_data: &AppDataHash) -> Result> { @@ -108,10 +100,13 @@ impl IpfsAppData { self.fetch_raw(contract_app_data).await }) .await - .map_err(|e| anyhow::anyhow!("{e}"))?; + .map_err(|e| anyhow::anyhow!("{e}")); - metric.with_label_values(&[outcome(&result), "node"]).inc(); - Ok(result) + match &result { + Ok(result) => metric.with_label_values(&[outcome(result), "node"]).inc(), + Err(_) => metric.with_label_values(&["error", "node"]).inc(), + } + result } } From 92e9fda7c1c97631a2f53195592b04ee7a9955be Mon Sep 17 00:00:00 2001 From: metalurgical <97008724+metalurgical@users.noreply.github.com> Date: Mon, 22 Jun 2026 18:53:13 +0200 Subject: [PATCH 4/5] update --- crates/balance-overrides/src/balance/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/balance-overrides/src/balance/mod.rs b/crates/balance-overrides/src/balance/mod.rs index c1cbc39b65..e8a5f225bb 100644 --- a/crates/balance-overrides/src/balance/mod.rs +++ b/crates/balance-overrides/src/balance/mod.rs @@ -891,7 +891,7 @@ mod tests { let strategy = detector.detect(NATIVE_ETH, user).await.unwrap(); - std::assert_eq!(strategy, Strategy::NativeEth); + std::assert_matches!(strategy, Strategy::NativeEth); // ETH is not an ERC20 token so we can't do an `eth_call` on `balanceOf()`. // Additionally `eth_getBalance` does not support state overrides. From 6fa180da994435604dc73c7cb0bafc581ee199fa Mon Sep 17 00:00:00 2001 From: metalurgical <97008724+metalurgical@users.noreply.github.com> Date: Tue, 23 Jun 2026 18:37:19 +0200 Subject: [PATCH 5/5] update --- crates/orderbook/src/ipfs_app_data.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/crates/orderbook/src/ipfs_app_data.rs b/crates/orderbook/src/ipfs_app_data.rs index 6330d56e73..1f2850cd89 100644 --- a/crates/orderbook/src/ipfs_app_data.rs +++ b/crates/orderbook/src/ipfs_app_data.rs @@ -86,25 +86,21 @@ impl IpfsAppData { pub async fn fetch(&self, contract_app_data: &AppDataHash) -> Result> { let outcome = |data: &Option| if data.is_some() { "found" } else { "missing" }; - let metric = &self.metrics.app_data; if let Some(cached) = self.cache.get(contract_app_data).await { metric.with_label_values(&[outcome(&cached), "cache"]).inc(); return Ok(cached); } - - let result = self - .cache - .try_get_with(*contract_app_data, async { - let _timer = self.metrics.fetches.start_timer(); - self.fetch_raw(contract_app_data).await - }) - .await - .map_err(|e| anyhow::anyhow!("{e}")); - + let _timer = self.metrics.fetches.start_timer(); + let result = self.fetch_raw(contract_app_data).await; match &result { - Ok(result) => metric.with_label_values(&[outcome(result), "node"]).inc(), - Err(_) => metric.with_label_values(&["error", "node"]).inc(), + Ok(result) => { + self.cache.insert(*contract_app_data, result.clone()).await; + metric.with_label_values(&[outcome(result), "node"]).inc(); + } + Err(_) => { + metric.with_label_values(&["error", "node"]).inc(); + } } result }