167 lines
6.3 KiB
Rust
167 lines
6.3 KiB
Rust
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use futures::channel::mpsc;
|
|
use nym_bandwidth_controller::{BandwidthController, BandwidthTicketProvider};
|
|
use nym_credential_storage::ephemeral_storage::EphemeralCredentialStorage;
|
|
use nym_sdk::{
|
|
NymNetworkDetails,
|
|
mixnet::{EventSender, MixnetClient, MixnetClientBuilder},
|
|
};
|
|
use nym_validator_client::{
|
|
QueryHttpRpcNyxdClient,
|
|
nyxd::{Config as NyxdClientConfig, NyxdClient},
|
|
};
|
|
|
|
use crate::{
|
|
RegistrationClient, clients::MixnetBasedRegistrationClient, config::RegistrationMode,
|
|
error::RegistrationClientError,
|
|
};
|
|
use config::BuilderConfig;
|
|
|
|
pub(crate) mod config;
|
|
|
|
pub struct RegistrationClientBuilder {
|
|
pub config: BuilderConfig,
|
|
}
|
|
|
|
impl RegistrationClientBuilder {
|
|
pub fn new(config: BuilderConfig) -> Self {
|
|
Self { config }
|
|
}
|
|
|
|
pub fn use_lp(&self) -> bool {
|
|
let lp_enabled = self.config.enable_lp_regitration;
|
|
let lp_info_available = self.config.entry_node.node.lp_data.is_some()
|
|
&& self.config.exit_node.node.lp_data.is_some();
|
|
// To remove when LP supports Mixnet registration
|
|
let wireguard_mode = self.config.mode == RegistrationMode::Wireguard;
|
|
let use_lp = lp_enabled && lp_info_available && wireguard_mode;
|
|
if !use_lp && lp_enabled {
|
|
tracing::warn!(
|
|
"LP is enabled but can't be used: Missing LP information: {lp_info_available}, wireguard mode: {wireguard_mode}"
|
|
);
|
|
}
|
|
use_lp
|
|
}
|
|
|
|
pub async fn build(self) -> Result<RegistrationClient, RegistrationClientError> {
|
|
if self.use_lp() {
|
|
tracing::debug!("Using LP for registration");
|
|
Err(RegistrationClientError::LpRegistrationNotPossible {
|
|
node_id: "any".to_string(),
|
|
})
|
|
// Ok(RegistrationClient::Lp(Box::new(self.build_lp().await?)))
|
|
} else {
|
|
tracing::debug!("Using Mixnet for registration");
|
|
Ok(RegistrationClient::Mixnet(Box::new(
|
|
self.build_mixnet().await?,
|
|
)))
|
|
}
|
|
}
|
|
|
|
pub(crate) async fn build_mixnet(
|
|
self,
|
|
) -> Result<MixnetBasedRegistrationClient, RegistrationClientError> {
|
|
let storage = self.config.setup_mixnet_client_storage().await?;
|
|
let config = self.config.registration_client_config();
|
|
let cancel_token = self.config.cancel_token.clone();
|
|
let (event_tx, event_rx) = mpsc::unbounded();
|
|
|
|
let nyxd_client = get_nyxd_client(&self.config.network_env)?;
|
|
let mixnet_client_startup_timeout = self.config.mixnet_client_startup_timeout;
|
|
|
|
let (mixnet_client, bandwidth_controller): (
|
|
MixnetClient,
|
|
Box<dyn BandwidthTicketProvider>,
|
|
) = if let Some((mixnet_client_storage, credential_storage)) = storage {
|
|
let builder = MixnetClientBuilder::new_with_storage(mixnet_client_storage)
|
|
.event_tx(EventSender(event_tx));
|
|
let mixnet_client = tokio::time::timeout(
|
|
mixnet_client_startup_timeout,
|
|
self.config.build_and_connect_mixnet_client(builder),
|
|
)
|
|
.await
|
|
.inspect_err(|_| {
|
|
tracing::warn!(
|
|
"mixnet client connection timed out after {:?}",
|
|
mixnet_client_startup_timeout
|
|
)
|
|
})?
|
|
.inspect_err(|e| tracing::warn!("mixnet build/connect error: {e}"))?;
|
|
let bandwidth_controller =
|
|
Box::new(BandwidthController::new(credential_storage, nyxd_client));
|
|
(mixnet_client, bandwidth_controller)
|
|
} else {
|
|
let builder = MixnetClientBuilder::new_ephemeral().event_tx(EventSender(event_tx));
|
|
let mixnet_client = tokio::time::timeout(
|
|
mixnet_client_startup_timeout,
|
|
self.config.build_and_connect_mixnet_client(builder),
|
|
)
|
|
.await
|
|
.inspect_err(|_| {
|
|
tracing::warn!(
|
|
"mixnet client connection timed out after {:?}",
|
|
mixnet_client_startup_timeout
|
|
)
|
|
})?
|
|
.inspect_err(|e| tracing::warn!("mixnet build/connect error: {e}"))?;
|
|
let bandwidth_controller = Box::new(BandwidthController::new(
|
|
EphemeralCredentialStorage::default(),
|
|
nyxd_client,
|
|
));
|
|
(mixnet_client, bandwidth_controller)
|
|
};
|
|
let mixnet_client_address = *mixnet_client.nym_address();
|
|
|
|
Ok(MixnetBasedRegistrationClient {
|
|
mixnet_client,
|
|
config,
|
|
cancel_token,
|
|
mixnet_client_address,
|
|
bandwidth_controller,
|
|
event_rx,
|
|
})
|
|
}
|
|
|
|
// async fn build_lp(self) -> Result<LpBasedRegistrationClient, RegistrationClientError> {
|
|
// let storage = self.config.setup_credential_storage().await?;
|
|
// let config = self.config.registration_client_config();
|
|
//
|
|
// let nyxd_client = get_nyxd_client(&self.config.network_env)?;
|
|
//
|
|
// let bandwidth_controller: Box<dyn BandwidthTicketProvider> =
|
|
// if let Some(credential_storage) = storage {
|
|
// Box::new(BandwidthController::new(credential_storage, nyxd_client))
|
|
// } else {
|
|
// Box::new(BandwidthController::new(
|
|
// EphemeralCredentialStorage::default(),
|
|
// nyxd_client,
|
|
// ))
|
|
// };
|
|
//
|
|
// Ok(LpBasedRegistrationClient {
|
|
// config,
|
|
// bandwidth_controller,
|
|
// cancel_token: self.config.cancel_token.clone(),
|
|
// fallback_client_builder: Some(self),
|
|
// })
|
|
// }
|
|
}
|
|
|
|
// temporary while we use the legacy bandwidth-controller
|
|
fn get_nyxd_client(
|
|
network: &NymNetworkDetails,
|
|
) -> Result<QueryHttpRpcNyxdClient, RegistrationClientError> {
|
|
let config = NyxdClientConfig::try_from_nym_network_details(network)
|
|
.map_err(RegistrationClientError::FailedToCreateNyxdClientConfig)?;
|
|
let nyxd_url = network
|
|
.endpoints
|
|
.first()
|
|
.map(|ep| ep.nyxd_url())
|
|
.ok_or(RegistrationClientError::InvalidNyxdUrl)?;
|
|
|
|
NyxdClient::connect(config, nyxd_url.as_str())
|
|
.map_err(RegistrationClientError::FailedToConnectUsingNyxdClient)
|
|
}
|