This commit is contained in:
Jędrzej Stuczyński
2026-06-05 16:00:10 +01:00
parent 7a7a14f585
commit c24814179f
5 changed files with 20 additions and 15 deletions
+2
View File
@@ -30,6 +30,8 @@ fn has_sufficient_tokens(
};
let chain_balance = &capabilities.on_chain_balance;
// this should never happen because we have queried for this specific balance,
// but some defensive coding never hurt
if chain_balance.denom != minimum_balance.denom {
return false;
}
+9 -7
View File
@@ -39,7 +39,7 @@ use tracing::{error, info, trace, warn};
pub(crate) struct NodeStatusCacheConfig {
pub(crate) minimum_on_chain_balance: Coin,
pub(crate) balance_retrieval_concurrency: usize,
pub(crate) chain_capabilities_retrieval_concurrency: usize,
/// Indicates how often should the chain balances (and feegrants) of known nodes be refreshed.
/// (it is an overkill to do it every single iteration)
@@ -66,8 +66,8 @@ pub(crate) struct NodeStatusCacheConfig {
pub struct NodeStatusCacheRefresher {
config: NodeStatusCacheConfig,
/// Indicates the last time chain balances of known nodes were refreshed.
last_refreshed_chain_balances: Option<Instant>,
/// Indicates the last time chain capabilities of known nodes were refreshed.
last_refreshed_chain_capabilities: Option<Instant>,
// Main stored data
cache: NodeStatusCache,
@@ -117,7 +117,7 @@ impl NodeStatusCacheRefresher {
Self {
cache,
config,
last_refreshed_chain_balances: None,
last_refreshed_chain_capabilities: None,
mixnet_contract_cache: contract_cache,
described_cache,
mixnet_contract_cache_listener: contract_cache_listener,
@@ -261,7 +261,7 @@ impl NodeStatusCacheRefresher {
// note: we use `for_each_concurrent` rather than `stream::iter(..).buffer_unordered(..)`.
// The latter yields a `Stream` whose `Send` bound gets over-generalised once chained into
// `collect()`, tripping "implementation of `Send` is not general enough" (rust-lang/rust#102211)
let concurrency = self.config.balance_retrieval_concurrency.max(1);
let concurrency = self.config.chain_capabilities_retrieval_concurrency.max(1);
// std Mutex is fine because we don't hold it across await points
let capabilities = std::sync::Mutex::new(HashMap::<
@@ -373,7 +373,7 @@ impl NodeStatusCacheRefresher {
}
fn should_refresh_chain_interaction(&self) -> bool {
let Some(last_refresh) = self.last_refreshed_chain_balances else {
let Some(last_refresh) = self.last_refreshed_chain_capabilities else {
return true;
};
last_refresh.elapsed() > self.config.chain_capabilities_refresh_interval
@@ -417,7 +417,7 @@ impl NodeStatusCacheRefresher {
let chain_info = if self.should_refresh_chain_interaction() {
let info = self.retrieve_chain_info(&described).await?;
self.last_refreshed_chain_balances = Some(Instant::now());
self.last_refreshed_chain_capabilities = Some(Instant::now());
info
} else {
// use the currently cached values instead
@@ -470,6 +470,8 @@ async fn retrieve_chain_capabilities(
};
let is_feegrant_grantee = match query_client.allowances(account_id, None).await {
// currently this is a very coarse check. the grant might be expired, it might not allow for
// cosmwasm executemsg, but that's a good enough first iteration
Ok(allowances) => !allowances.allowances.is_empty(),
Err(err) => {
warn!(node_id, %err, "failed to retrieve node feegrant allowances");
+2 -2
View File
@@ -56,10 +56,10 @@ pub(crate) async fn start_cache_refresh(
let config = NodeStatusCacheConfig {
minimum_on_chain_balance,
balance_retrieval_concurrency: config
chain_capabilities_retrieval_concurrency: config
.node_status_api
.debug
.node_balance_retrieval_concurrency,
.chain_capabilities_retrieval_concurrency,
chain_capabilities_refresh_interval: config
.node_status_api
.debug
+1 -1
View File
@@ -388,7 +388,7 @@ impl<T> DeserialisedCache<T> {
};
serialiser.deserialize_from(file).map_err(|err| {
error!("failed to deserialised persistent cache file at {path:?}: {err}");
error!("failed to deserialise persistent cache file at {path:?}: {err}");
std::io::Error::other(err)
})
}
+6 -5
View File
@@ -725,7 +725,7 @@ pub struct NodeStatusAPIDebug {
// base amount (in unym)
pub minimum_on_chain_balance_amount: u128,
pub node_balance_retrieval_concurrency: usize,
pub chain_capabilities_retrieval_concurrency: usize,
#[serde(with = "humantime_serde")]
pub chain_capabilities_refresh_interval: Duration,
@@ -733,17 +733,18 @@ pub struct NodeStatusAPIDebug {
impl NodeStatusAPIDebug {
const DEFAULT_NODE_STATUS_CACHE_REFRESH_INTERVAL: Duration = Duration::from_secs(305);
const DEFAULT_NODE_BALANCE_RETRIEVAL_CONCURRENCY: usize = 8;
const DEFAULT_CHAIN_CAPABILITIES_RETRIEVAL_CONCURRENCY: usize = 8;
const DEFAULT_CHAIN_CAPABILITIES_REFRESH_INTERVAL: Duration = Duration::from_secs(24 * 60 * 60); // once a day is more than enough
const DEFAULT_CHAIN_BALANCE_REFRESH_THRESHOLD: u128 = 1_000000; // 1 nym is enough for all tx fees for quite some time
const DEFAULT_MINIMUM_ON_CHAIN_BALANCE: u128 = 1_000000; // 1 nym is enough for all tx fees for quite some time
}
impl Default for NodeStatusAPIDebug {
fn default() -> Self {
NodeStatusAPIDebug {
caching_interval: Self::DEFAULT_NODE_STATUS_CACHE_REFRESH_INTERVAL,
minimum_on_chain_balance_amount: Self::DEFAULT_CHAIN_BALANCE_REFRESH_THRESHOLD,
node_balance_retrieval_concurrency: Self::DEFAULT_NODE_BALANCE_RETRIEVAL_CONCURRENCY,
minimum_on_chain_balance_amount: Self::DEFAULT_MINIMUM_ON_CHAIN_BALANCE,
chain_capabilities_retrieval_concurrency:
Self::DEFAULT_CHAIN_CAPABILITIES_RETRIEVAL_CONCURRENCY,
chain_capabilities_refresh_interval: Self::DEFAULT_CHAIN_CAPABILITIES_REFRESH_INTERVAL,
}
}