use new topology provider and appease wasm

This commit is contained in:
jmwample
2025-03-04 15:23:21 -07:00
parent b326993da6
commit 0c97b51a4c
5 changed files with 117 additions and 15 deletions
Generated
+4
View File
@@ -6238,6 +6238,7 @@ dependencies = [
"nym-bin-common",
"nym-client-core-config-types",
"nym-config",
"nym-contracts-common",
"nym-crypto",
"nym-gateway",
"nym-gateway-stats-storage",
@@ -6932,6 +6933,7 @@ version = "0.1.0"
dependencies = [
"async-trait",
"nym-api-requests",
"nym-client-core-config-types",
"nym-config",
"nym-crypto",
"nym-mixnet-contract-common",
@@ -6943,6 +6945,8 @@ dependencies = [
"serde",
"serde_json",
"thiserror 2.0.12",
"time",
"tokio",
"tracing",
"tsify",
"wasm-bindgen",
@@ -22,7 +22,7 @@ use crate::client::replies::reply_controller::{ReplyControllerReceiver, ReplyCon
use crate::client::replies::reply_storage::{
CombinedReplyStorage, PersistentReplyStorage, ReplyStorageBackend, SentReplyKeys,
};
use crate::client::topology_control::nym_api_provider::NymApiTopologyProvider;
use crate::client::topology_control::smart_api_provider::NymApiTopologyProvider;
use crate::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
};
@@ -556,6 +556,7 @@ where
config_topology,
nym_api_urls,
user_agent,
None,
)),
config::TopologyStructure::GeoAware(group_by) => {
warn!("using deprecated 'GeoAware' topology provider - this option will be removed very soon");
@@ -23,8 +23,8 @@ pub mod smart_api_provider;
#[allow(deprecated)]
pub use geo_aware_provider::GeoAwareTopologyProvider;
pub use nym_api_provider::{Config as NymApiTopologyProviderConfig, NymApiTopologyProvider};
pub use nym_topology::providers::TopologyProvider;
pub use smart_api_provider::{Config as NymApiTopologyProviderConfig, NymApiTopologyProvider};
// TODO: move it to config later
const MAX_FAILURE_COUNT: usize = 10;
@@ -8,9 +8,10 @@
use async_trait::async_trait;
use log::{debug, error, warn};
pub use nym_topology::providers::piecewise::Config;
use nym_topology::{
providers::piecewise::{Config, NymTopologyProvider, PiecewiseTopologyProvider},
EpochRewardedSet, NymTopology, RoutingNode,
providers::piecewise::{NymTopologyProvider, PiecewiseTopologyProvider},
EpochRewardedSet, NymTopology, RoutingNode, TopologyProvider,
};
use nym_validator_client::UserAgent;
use rand::{prelude::SliceRandom, thread_rng};
@@ -26,13 +27,13 @@ pub struct NymApiTopologyProvider {
impl NymApiTopologyProvider {
/// Construct a new thread safe Cached topology provider using the Nym API
pub fn new(
user_agent: UserAgent,
config: impl Into<Config>,
nym_api_urls: Vec<Url>,
config: Config,
user_agent: Option<UserAgent>,
initial_topology: Option<NymTopology>,
) -> Self {
let manager = NymApiPiecewiseProvider::new(nym_api_urls, Some(user_agent));
let inner = NymTopologyProvider::new(manager, config, initial_topology);
let manager = NymApiPiecewiseProvider::new(nym_api_urls, user_agent);
let inner = NymTopologyProvider::new(manager, config.into(), initial_topology);
Self { inner }
}
@@ -44,6 +45,28 @@ impl AsRef<NymTopologyProvider<NymApiPiecewiseProvider>> for NymApiTopologyProvi
}
}
impl AsMut<NymTopologyProvider<NymApiPiecewiseProvider>> for NymApiTopologyProvider {
fn as_mut(&mut self) -> &mut NymTopologyProvider<NymApiPiecewiseProvider> {
&mut self.inner
}
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
impl TopologyProvider for NymApiTopologyProvider {
async fn get_new_topology(&mut self) -> Option<NymTopology> {
self.as_mut().get_new_topology().await
}
}
#[cfg(target_arch = "wasm32")]
#[async_trait(?Send)]
impl TopologyProvider for NymApiTopologyProvider {
async fn get_new_topology(&mut self) -> Option<NymTopology> {
self.as_mut().get_new_topology().await
}
}
#[derive(Clone)]
struct NymApiPiecewiseProvider {
validator_client: nym_validator_client::client::NymApiClient,
@@ -81,11 +104,8 @@ impl NymApiPiecewiseProvider {
self.validator_client
.change_nym_api(self.nym_api_urls[self.currently_used_api].clone())
}
}
#[async_trait]
impl PiecewiseTopologyProvider for NymApiPiecewiseProvider {
async fn get_full_topology(&mut self) -> Option<NymTopology> {
async fn get_full_topology_inner(&mut self) -> Option<NymTopology> {
let layer_assignments = self.get_layer_assignments().await?;
let mut topology = NymTopology::new_empty(layer_assignments);
@@ -111,7 +131,7 @@ impl PiecewiseTopologyProvider for NymApiPiecewiseProvider {
Some(topology)
}
async fn get_descriptor_batch(&mut self, ids: &[u32]) -> Option<Vec<RoutingNode>> {
async fn get_descriptor_batch_inner(&mut self, ids: &[u32]) -> Option<Vec<RoutingNode>> {
// Does this need to return a hashmap of RoutingNodes? that is moderately inconvenient
// especially when the nodes themselves contain their node_id unless we expect to directly
// use the result of this fn for lookups where we would otherwise for example, have to
@@ -129,13 +149,13 @@ impl PiecewiseTopologyProvider for NymApiPiecewiseProvider {
let mut out = Vec::new();
for node in descriptor_vec {
if let Ok(routing_node) = RoutingNode::try_from(&node) {
let _ = out.push(routing_node);
out.push(routing_node);
}
}
Some(out)
}
async fn get_layer_assignments(&mut self) -> Option<EpochRewardedSet> {
async fn get_layer_assignments_inner(&mut self) -> Option<EpochRewardedSet> {
self.validator_client
.get_current_rewarded_set()
.await
@@ -146,3 +166,35 @@ impl PiecewiseTopologyProvider for NymApiPiecewiseProvider {
.ok()
}
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
impl PiecewiseTopologyProvider for NymApiPiecewiseProvider {
async fn get_full_topology(&mut self) -> Option<NymTopology> {
self.get_full_topology_inner().await
}
async fn get_descriptor_batch(&mut self, ids: &[u32]) -> Option<Vec<RoutingNode>> {
self.get_descriptor_batch_inner(ids).await
}
async fn get_layer_assignments(&mut self) -> Option<EpochRewardedSet> {
self.get_layer_assignments_inner().await
}
}
#[cfg(target_arch = "wasm32")]
#[async_trait(?Send)]
impl PiecewiseTopologyProvider for NymApiPiecewiseProvider {
async fn get_full_topology(&mut self) -> Option<NymTopology> {
self.get_full_topology_inner().await
}
async fn get_descriptor_batch(&mut self, ids: &[u32]) -> Option<Vec<RoutingNode>> {
self.get_descriptor_batch_inner(ids).await
}
async fn get_layer_assignments(&mut self) -> Option<EpochRewardedSet> {
self.get_layer_assignments_inner().await
}
}
@@ -112,6 +112,7 @@ impl<M: PiecewiseTopologyProvider> NymTopologyProvider<M> {
}
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
impl<M: PiecewiseTopologyProvider> TopologyProvider for NymTopologyProvider<M> {
async fn get_new_topology(&mut self) -> Option<NymTopology> {
@@ -127,6 +128,22 @@ impl<M: PiecewiseTopologyProvider> TopologyProvider for NymTopologyProvider<M> {
}
}
#[cfg(target_arch = "wasm32")]
#[async_trait(?Send)]
impl<M: PiecewiseTopologyProvider> TopologyProvider for NymTopologyProvider<M> {
async fn get_new_topology(&mut self) -> Option<NymTopology> {
let mut guard = self.inner.lock().await;
// check the cache
if let Some(cached) = guard.get_current_compatible_topology().await {
return Some(cached);
}
// not cached, or cache expired. try update.
guard.update_cache().await;
guard.get_current_compatible_topology().await
}
}
struct NymTopologyProviderInner<M: PiecewiseTopologyProvider> {
config: Config,
@@ -242,6 +259,7 @@ impl<M: PiecewiseTopologyProvider> NymTopologyProviderInner<M> {
}
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
impl<P: PiecewiseTopologyProvider> TopologyProvider for NymTopologyProviderInner<P> {
async fn get_new_topology(&mut self) -> Option<NymTopology> {
@@ -249,6 +267,15 @@ impl<P: PiecewiseTopologyProvider> TopologyProvider for NymTopologyProviderInner
}
}
#[cfg(target_arch = "wasm32")]
#[async_trait(?Send)]
impl<P: PiecewiseTopologyProvider> TopologyProvider for NymTopologyProviderInner<P> {
async fn get_new_topology(&mut self) -> Option<NymTopology> {
self.get_current_compatible_topology().await
}
}
#[cfg(not(target_arch = "wasm32"))]
/// Trait allowing construction and upkeep of a
#[async_trait]
pub trait PiecewiseTopologyProvider: Send {
@@ -265,7 +292,25 @@ pub trait PiecewiseTopologyProvider: Send {
async fn get_layer_assignments(&mut self) -> Option<EpochRewardedSet>;
}
#[cfg(target_arch = "wasm32")]
/// Trait allowing construction and upkeep of a
#[async_trait(?Send)]
pub trait PiecewiseTopologyProvider: Send {
/// Pull a copy of the full topology.
///
/// This is intended to be used sparingly as repeated usage could result in fetching duplicate
/// information more often than necessary.
async fn get_full_topology(&mut self) -> Option<NymTopology>;
/// Fetch a node descriptors for the set of provided IDs if available.
async fn get_descriptor_batch(&mut self, ids: &[u32]) -> Option<Vec<RoutingNode>>;
/// Fetch the latest mapping of node IDs to Nym Network layer.
async fn get_layer_assignments(&mut self) -> Option<EpochRewardedSet>;
}
#[cfg(test)]
#[cfg(not(target_arch = "wasm32"))]
mod test {
use super::*;
use crate::SupportedRoles;