clients using self-described gateway information
This commit is contained in:
Generated
+2
@@ -6072,6 +6072,7 @@ dependencies = [
|
||||
"opentelemetry",
|
||||
"opentelemetry-jaeger",
|
||||
"pretty_env_logger",
|
||||
"schemars",
|
||||
"semver 0.11.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -7338,6 +7339,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"bs58 0.4.0",
|
||||
"log",
|
||||
"nym-api-requests",
|
||||
"nym-bin-common",
|
||||
"nym-config",
|
||||
"nym-crypto",
|
||||
|
||||
@@ -180,7 +180,6 @@ pub(crate) async fn execute(args: Init) -> Result<(), ClientError> {
|
||||
let selection_spec = GatewaySelectionSpecification::new(
|
||||
user_chosen_gateway_id.map(|id| id.to_base58_string()),
|
||||
Some(args.latency_based_selection),
|
||||
false,
|
||||
);
|
||||
|
||||
// Load and potentially override config
|
||||
|
||||
@@ -185,7 +185,6 @@ pub(crate) async fn execute(args: Init) -> Result<(), Socks5ClientError> {
|
||||
let selection_spec = GatewaySelectionSpecification::new(
|
||||
user_chosen_gateway_id.map(|id| id.to_base58_string()),
|
||||
Some(args.latency_based_selection),
|
||||
false,
|
||||
);
|
||||
|
||||
// Load and potentially override config
|
||||
|
||||
@@ -15,6 +15,7 @@ clap_complete_fig = "4.0"
|
||||
log = { workspace = true }
|
||||
pretty_env_logger = "0.4.0"
|
||||
semver = "0.11"
|
||||
schemars = { workspace = true, features = ["preserve_order"], optional = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true, optional = true }
|
||||
|
||||
@@ -45,6 +46,7 @@ vergen = { version = "=7.4.3", default-features = false, features = [
|
||||
default = []
|
||||
openapi = ["utoipa"]
|
||||
output_format = ["serde_json"]
|
||||
bin_info_schema = ["schemars"]
|
||||
tracing = [
|
||||
"tracing-subscriber",
|
||||
"tracing-tree",
|
||||
|
||||
@@ -82,6 +82,7 @@ impl BinaryBuildInformation {
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
#[cfg_attr(feature = "bin_info_schema", derive(schemars::JsonSchema))]
|
||||
pub struct BinaryBuildInformationOwned {
|
||||
/// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable.
|
||||
pub binary_name: String,
|
||||
|
||||
@@ -69,7 +69,7 @@ impl NymApiTopologyProvider {
|
||||
Ok(mixes) => mixes,
|
||||
};
|
||||
|
||||
let gateways = match self.validator_client.get_cached_gateways().await {
|
||||
let gateways = match self.validator_client.get_cached_described_gateways().await {
|
||||
Err(err) => {
|
||||
error!("failed to get network gateways - {err}");
|
||||
return None;
|
||||
|
||||
@@ -280,30 +280,13 @@ impl GatewayEndpointConfig {
|
||||
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)
|
||||
}
|
||||
|
||||
pub fn from_node(node: nym_topology::gateway::Node, use_tls: bool) -> Self {
|
||||
// TODO: in the future this shall return a Result and explicit `use_tls` will be removed in favour of the tls info being available on the struct
|
||||
if use_tls {
|
||||
Self::from_topology_node_tls(node)
|
||||
} else {
|
||||
Self::from_topology_node_no_tls(node)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_topology_node_no_tls(node: nym_topology::gateway::Node) -> Self {
|
||||
pub fn from_node(node: nym_topology::gateway::Node) -> Self {
|
||||
GatewayEndpointConfig {
|
||||
gateway_id: node.identity_key.to_base58_string(),
|
||||
gateway_listener: node.clients_address(),
|
||||
gateway_owner: node.owner,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_topology_node_tls(node: nym_topology::gateway::Node) -> Self {
|
||||
GatewayEndpointConfig {
|
||||
gateway_id: node.identity_key.to_base58_string(),
|
||||
gateway_listener: node.clients_address_tls(),
|
||||
gateway_owner: node.owner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
||||
|
||||
@@ -107,20 +107,17 @@ where
|
||||
let mut new_keys = ManagedKeys::generate_new(&mut rng);
|
||||
|
||||
let gateway_details = match selection_specification {
|
||||
GatewaySelectionSpecification::UniformRemote { must_use_tls } => {
|
||||
GatewaySelectionSpecification::UniformRemote => {
|
||||
let gateway = uniformly_random_gateway(&mut rng, &available_gateways)?;
|
||||
GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway, must_use_tls))
|
||||
GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway))
|
||||
}
|
||||
GatewaySelectionSpecification::RemoteByLatency { must_use_tls } => {
|
||||
GatewaySelectionSpecification::RemoteByLatency => {
|
||||
let gateway = choose_gateway_by_latency(&mut rng, &available_gateways).await?;
|
||||
GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway, must_use_tls))
|
||||
GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway))
|
||||
}
|
||||
GatewaySelectionSpecification::Specified {
|
||||
must_use_tls,
|
||||
identity,
|
||||
} => {
|
||||
GatewaySelectionSpecification::Specified { identity } => {
|
||||
let gateway = get_specified_gateway(&identity, &available_gateways)?;
|
||||
GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway, must_use_tls))
|
||||
GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway))
|
||||
}
|
||||
GatewaySelectionSpecification::Custom {
|
||||
gateway_identity,
|
||||
|
||||
@@ -181,17 +181,14 @@ impl<T> From<PersistedGatewayDetails<T>> for GatewayDetails<T> {
|
||||
#[derive(Clone)]
|
||||
pub enum GatewaySelectionSpecification<T = EmptyCustomDetails> {
|
||||
/// Uniformly choose a random remote gateway.
|
||||
UniformRemote { must_use_tls: bool },
|
||||
UniformRemote,
|
||||
|
||||
/// Should the new, remote, gateway be selected based on latency.
|
||||
RemoteByLatency { must_use_tls: bool },
|
||||
RemoteByLatency,
|
||||
|
||||
/// Gateway with this specific identity should be chosen.
|
||||
// JS: I don't really like the name of this enum variant but couldn't think of anything better at the time
|
||||
Specified {
|
||||
must_use_tls: bool,
|
||||
identity: IdentityKey,
|
||||
},
|
||||
Specified { identity: IdentityKey },
|
||||
|
||||
// TODO: this doesn't really fit in here..., but where else to put it?
|
||||
/// This client has handled the selection by itself
|
||||
@@ -203,27 +200,18 @@ pub enum GatewaySelectionSpecification<T = EmptyCustomDetails> {
|
||||
|
||||
impl<T> Default for GatewaySelectionSpecification<T> {
|
||||
fn default() -> Self {
|
||||
GatewaySelectionSpecification::UniformRemote {
|
||||
must_use_tls: false,
|
||||
}
|
||||
GatewaySelectionSpecification::UniformRemote
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> GatewaySelectionSpecification<T> {
|
||||
pub fn new(
|
||||
gateway_identity: Option<String>,
|
||||
latency_based_selection: Option<bool>,
|
||||
must_use_tls: bool,
|
||||
) -> Self {
|
||||
pub fn new(gateway_identity: Option<String>, latency_based_selection: Option<bool>) -> Self {
|
||||
if let Some(identity) = gateway_identity {
|
||||
GatewaySelectionSpecification::Specified {
|
||||
identity,
|
||||
must_use_tls,
|
||||
}
|
||||
GatewaySelectionSpecification::Specified { identity }
|
||||
} else if let Some(true) = latency_based_selection {
|
||||
GatewaySelectionSpecification::RemoteByLatency { must_use_tls }
|
||||
GatewaySelectionSpecification::RemoteByLatency
|
||||
} else {
|
||||
GatewaySelectionSpecification::UniformRemote { must_use_tls }
|
||||
GatewaySelectionSpecification::UniformRemote
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
use nym_api_requests::coconut::{
|
||||
BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
|
||||
};
|
||||
use nym_api_requests::models::MixNodeBondAnnotated;
|
||||
use nym_api_requests::models::{DescribedGateway, MixNodeBondAnnotated};
|
||||
use nym_api_requests::models::{
|
||||
GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
|
||||
RewardEstimationResponse, StakeSaturationResponse,
|
||||
@@ -275,6 +275,12 @@ impl NymApiClient {
|
||||
Ok(self.nym_api.get_gateways().await?)
|
||||
}
|
||||
|
||||
pub async fn get_cached_described_gateways(
|
||||
&self,
|
||||
) -> Result<Vec<DescribedGateway>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_gateways_described().await?)
|
||||
}
|
||||
|
||||
pub async fn get_gateway_core_status_count(
|
||||
&self,
|
||||
identity: IdentityKeyRef<'_>,
|
||||
|
||||
@@ -8,13 +8,7 @@ use http_api_client::{ApiClient, NO_PARAMS};
|
||||
use nym_api_requests::coconut::{
|
||||
BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
|
||||
};
|
||||
use nym_api_requests::models::{
|
||||
ComputeRewardEstParam, GatewayBondAnnotated, GatewayCoreStatusResponse,
|
||||
GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse,
|
||||
MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse,
|
||||
MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse,
|
||||
StakeSaturationResponse, UptimeResponse,
|
||||
};
|
||||
use nym_api_requests::models::{ComputeRewardEstParam, DescribedGateway, GatewayBondAnnotated, GatewayCoreStatusResponse, GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse, MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse, MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse, StakeSaturationResponse, UptimeResponse};
|
||||
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
|
||||
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
|
||||
use nym_name_service_common::response::NamesListResponse;
|
||||
@@ -79,6 +73,14 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_gateways_described(&self) -> Result<Vec<DescribedGateway>, NymAPIError> {
|
||||
self.get_json(
|
||||
&[routes::API_VERSION, routes::GATEWAYS, routes::DESCRIBED],
|
||||
NO_PARAMS,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_active_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
|
||||
self.get_json(
|
||||
&[routes::API_VERSION, routes::MIXNODES, routes::ACTIVE],
|
||||
|
||||
@@ -6,6 +6,7 @@ use nym_network_defaults::NYM_API_VERSION;
|
||||
pub const API_VERSION: &str = NYM_API_VERSION;
|
||||
pub const MIXNODES: &str = "mixnodes";
|
||||
pub const GATEWAYS: &str = "gateways";
|
||||
pub const DESCRIBED: &str = "described";
|
||||
|
||||
pub const DETAILED: &str = "detailed";
|
||||
pub const DETAILED_UNFILTERED: &str = "detailed-unfiltered";
|
||||
|
||||
@@ -35,6 +35,10 @@ nym-sphinx-types = { path = "../nymsphinx/types", features = ["sphinx", "outfox"
|
||||
nym-sphinx-routing = { path = "../nymsphinx/routing" }
|
||||
nym-bin-common = { path = "../bin-common" }
|
||||
|
||||
# I'm not sure how to feel about pulling in this dependency here...
|
||||
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
|
||||
|
||||
|
||||
# 'serializable' feature
|
||||
nym-config = { path = "../config", optional = true }
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{filter, NetworkAddress, NodeVersion};
|
||||
use nym_api_requests::models::DescribedGateway;
|
||||
use nym_crypto::asymmetric::{encryption, identity};
|
||||
use nym_mixnet_contract_common::GatewayBond;
|
||||
use nym_sphinx_addressing::nodes::{NodeIdentity, NymNodeRoutingAddress};
|
||||
@@ -10,6 +11,7 @@ use std::convert::{TryFrom, TryInto};
|
||||
use std::fmt;
|
||||
use std::fmt::Formatter;
|
||||
use std::io;
|
||||
use std::net::AddrParseError;
|
||||
use std::net::SocketAddr;
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -27,6 +29,17 @@ pub enum GatewayConversionError {
|
||||
#[source]
|
||||
source: io::Error,
|
||||
},
|
||||
|
||||
#[error("'{gateway}' has not provided any valid ip addresses")]
|
||||
NoIpAddressesProvided { gateway: String },
|
||||
|
||||
#[error("'{gateway}' has provided a malformed ip address: {err}")]
|
||||
MalformedIpAddress {
|
||||
gateway: String,
|
||||
|
||||
#[source]
|
||||
err: AddrParseError,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -36,7 +49,13 @@ pub struct Node {
|
||||
// we're keeping this as separate resolved field since we do not want to be resolving the potential
|
||||
// hostname every time we want to construct a path via this node
|
||||
pub mix_host: SocketAddr,
|
||||
pub clients_port: u16,
|
||||
|
||||
// #[serde(alias = "clients_port")]
|
||||
pub clients_ws_port: u16,
|
||||
|
||||
// #[serde(default)]
|
||||
pub clients_wss_port: Option<u16>,
|
||||
|
||||
pub identity_key: identity::PublicKey,
|
||||
pub sphinx_key: encryption::PublicKey, // TODO: or nymsphinx::PublicKey? both are x25519
|
||||
pub version: NodeVersion,
|
||||
@@ -82,11 +101,17 @@ impl Node {
|
||||
}
|
||||
|
||||
pub fn clients_address(&self) -> String {
|
||||
format!("ws://{}:{}", self.host, self.clients_port)
|
||||
self.clients_address_tls()
|
||||
.unwrap_or_else(|| self.clients_address_no_tls())
|
||||
}
|
||||
|
||||
pub fn clients_address_tls(&self) -> String {
|
||||
format!("wss://{}:443", self.host)
|
||||
pub fn clients_address_no_tls(&self) -> String {
|
||||
format!("ws://{}:{}", self.host, self.clients_ws_port)
|
||||
}
|
||||
|
||||
pub fn clients_address_tls(&self) -> Option<String> {
|
||||
self.clients_wss_port
|
||||
.map(|p| format!("wss://{}:{p}", self.host))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +156,8 @@ impl<'a> TryFrom<&'a GatewayBond> for Node {
|
||||
owner: bond.owner.as_str().to_owned(),
|
||||
host,
|
||||
mix_host,
|
||||
clients_port: bond.gateway.clients_port,
|
||||
clients_ws_port: bond.gateway.clients_port,
|
||||
clients_wss_port: None,
|
||||
identity_key: identity::PublicKey::from_base58_string(&bond.gateway.identity_key)?,
|
||||
sphinx_key: encryption::PublicKey::from_base58_string(&bond.gateway.sphinx_key)?,
|
||||
version: bond.gateway.version.as_str().into(),
|
||||
@@ -146,3 +172,65 @@ impl TryFrom<GatewayBond> for Node {
|
||||
Node::try_from(&bond)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a DescribedGateway> for Node {
|
||||
type Error = GatewayConversionError;
|
||||
|
||||
fn try_from(value: &'a DescribedGateway) -> Result<Self, Self::Error> {
|
||||
let Some(ref self_described) = value.self_described else {
|
||||
return (&value.bond).try_into();
|
||||
};
|
||||
|
||||
let ips = &self_described.host_information.ip_address;
|
||||
if ips.is_empty() {
|
||||
return Err(GatewayConversionError::NoIpAddressesProvided {
|
||||
gateway: value.bond.gateway.identity_key.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
let ips = ips
|
||||
.iter()
|
||||
.map(|ip| ip.parse())
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|err| GatewayConversionError::MalformedIpAddress {
|
||||
gateway: value.bond.gateway.identity_key.clone(),
|
||||
err,
|
||||
})?;
|
||||
|
||||
let host = match &self_described.host_information.hostname {
|
||||
None => NetworkAddress::IpAddr(ips[0]),
|
||||
Some(hostname) => NetworkAddress::Hostname(hostname.clone()),
|
||||
};
|
||||
|
||||
// get ip from the self-reported values so we wouldn't need to do any hostname resolution
|
||||
// (which doesn't really work in wasm)
|
||||
let mix_host = SocketAddr::new(ips[0], value.bond.gateway.mix_port);
|
||||
|
||||
Ok(Node {
|
||||
owner: value.bond.owner.as_str().to_owned(),
|
||||
host,
|
||||
mix_host,
|
||||
clients_ws_port: self_described.mixnet_websockets.ws_port,
|
||||
clients_wss_port: self_described.mixnet_websockets.wss_port,
|
||||
identity_key: identity::PublicKey::from_base58_string(
|
||||
&self_described.host_information.keys.ed25519,
|
||||
)?,
|
||||
sphinx_key: encryption::PublicKey::from_base58_string(
|
||||
&self_described.host_information.keys.x25519,
|
||||
)?,
|
||||
version: self_described
|
||||
.build_information
|
||||
.build_version
|
||||
.as_str()
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<DescribedGateway> for Node {
|
||||
type Error = GatewayConversionError;
|
||||
|
||||
fn try_from(value: DescribedGateway) -> Result<Self, Self::Error> {
|
||||
Node::try_from(&value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ use std::str::FromStr;
|
||||
|
||||
#[cfg(feature = "serializable")]
|
||||
use ::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use nym_api_requests::models::DescribedGateway;
|
||||
|
||||
pub mod error;
|
||||
pub mod filter;
|
||||
@@ -403,10 +404,33 @@ impl<'de> Deserialize<'de> for NymTopology {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nym_topology_from_detailed(
|
||||
pub trait IntoGatewayNode: TryInto<gateway::Node>
|
||||
where
|
||||
<Self as TryInto<gateway::Node>>::Error: Display,
|
||||
{
|
||||
fn identity(&self) -> IdentityKeyRef;
|
||||
}
|
||||
|
||||
impl IntoGatewayNode for GatewayBond {
|
||||
fn identity(&self) -> IdentityKeyRef {
|
||||
&self.gateway.identity_key
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoGatewayNode for DescribedGateway {
|
||||
fn identity(&self) -> IdentityKeyRef {
|
||||
&self.bond.gateway.identity_key
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nym_topology_from_detailed<G>(
|
||||
mix_details: Vec<MixNodeDetails>,
|
||||
gateway_bonds: Vec<GatewayBond>,
|
||||
) -> NymTopology {
|
||||
gateway_bonds: Vec<G>,
|
||||
) -> NymTopology
|
||||
where
|
||||
G: IntoGatewayNode,
|
||||
<G as TryInto<gateway::Node>>::Error: Display,
|
||||
{
|
||||
let mut mixes = BTreeMap::new();
|
||||
for bond in mix_details
|
||||
.into_iter()
|
||||
@@ -435,7 +459,7 @@ pub fn nym_topology_from_detailed(
|
||||
|
||||
let mut gateways = Vec::with_capacity(gateway_bonds.len());
|
||||
for bond in gateway_bonds.into_iter() {
|
||||
let gate_id = bond.gateway.identity_key.clone();
|
||||
let gate_id = bond.identity().to_owned();
|
||||
match bond.try_into() {
|
||||
Ok(gate) => gateways.push(gate),
|
||||
Err(err) => {
|
||||
|
||||
@@ -190,7 +190,12 @@ pub struct SerializableGateway {
|
||||
|
||||
#[cfg_attr(feature = "wasm-serde-types", tsify(optional))]
|
||||
#[serde(alias = "clients_port")]
|
||||
pub clients_port: Option<u16>,
|
||||
#[serde(alias = "clients_ws_port")]
|
||||
pub clients_ws_port: Option<u16>,
|
||||
|
||||
#[cfg_attr(feature = "wasm-serde-types", tsify(optional))]
|
||||
#[serde(alias = "clients_wss_port")]
|
||||
pub clients_wss_port: Option<u16>,
|
||||
|
||||
#[serde(alias = "identity_key")]
|
||||
pub identity_key: String,
|
||||
@@ -209,7 +214,9 @@ impl TryFrom<SerializableGateway> for gateway::Node {
|
||||
let host = gateway::Node::parse_host(&value.host)?;
|
||||
|
||||
let mix_port = value.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT);
|
||||
let clients_port = value.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT);
|
||||
let clients_ws_port = value
|
||||
.clients_ws_port
|
||||
.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT);
|
||||
let version = value.version.map(|v| v.as_str().into()).unwrap_or_default();
|
||||
|
||||
// try to completely resolve the host in the mix situation to avoid doing it every
|
||||
@@ -224,7 +231,8 @@ impl TryFrom<SerializableGateway> for gateway::Node {
|
||||
owner: value.owner,
|
||||
host,
|
||||
mix_host,
|
||||
clients_port,
|
||||
clients_ws_port,
|
||||
clients_wss_port: value.clients_wss_port,
|
||||
identity_key: identity::PublicKey::from_base58_string(&value.identity_key)
|
||||
.map_err(GatewayConversionError::from)?,
|
||||
sphinx_key: encryption::PublicKey::from_base58_string(&value.sphinx_key)
|
||||
@@ -241,7 +249,8 @@ impl<'a> From<&'a gateway::Node> for SerializableGateway {
|
||||
host: value.host.to_string(),
|
||||
explicit_ip: Some(value.mix_host.ip()),
|
||||
mix_port: Some(value.mix_host.port()),
|
||||
clients_port: Some(value.clients_port),
|
||||
clients_ws_port: Some(value.clients_ws_port),
|
||||
clients_wss_port: value.clients_wss_port,
|
||||
identity_key: value.identity_key.to_base58_string(),
|
||||
sphinx_key: value.sphinx_key.to_base58_string(),
|
||||
version: Some(value.version.to_string()),
|
||||
|
||||
@@ -86,15 +86,13 @@ pub fn current_network_topology(nym_api_url: String) -> Promise {
|
||||
|
||||
pub async fn setup_gateway_wasm(
|
||||
client_store: &ClientStorage,
|
||||
force_tls: bool,
|
||||
chosen_gateway: Option<IdentityKey>,
|
||||
gateways: &[gateway::Node],
|
||||
) -> Result<InitialisationResult, WasmCoreError> {
|
||||
let setup = if client_store.has_full_gateway_info().await? {
|
||||
GatewaySetup::MustLoad
|
||||
} else {
|
||||
let selection_spec =
|
||||
GatewaySelectionSpecification::new(chosen_gateway.clone(), None, force_tls);
|
||||
let selection_spec = GatewaySelectionSpecification::new(chosen_gateway.clone(), None);
|
||||
|
||||
GatewaySetup::New {
|
||||
specification: selection_spec,
|
||||
@@ -110,21 +108,19 @@ pub async fn setup_gateway_wasm(
|
||||
|
||||
pub async fn setup_gateway_from_api(
|
||||
client_store: &ClientStorage,
|
||||
force_tls: bool,
|
||||
chosen_gateway: Option<IdentityKey>,
|
||||
nym_apis: &[Url],
|
||||
) -> Result<InitialisationResult, WasmCoreError> {
|
||||
let mut rng = thread_rng();
|
||||
let gateways = current_gateways(&mut rng, nym_apis).await?;
|
||||
setup_gateway_wasm(client_store, force_tls, chosen_gateway, &gateways).await
|
||||
setup_gateway_wasm(client_store, chosen_gateway, &gateways).await
|
||||
}
|
||||
|
||||
pub async fn setup_from_topology(
|
||||
explicit_gateway: Option<IdentityKey>,
|
||||
force_tls: bool,
|
||||
topology: &NymTopology,
|
||||
client_store: &ClientStorage,
|
||||
) -> Result<InitialisationResult, WasmCoreError> {
|
||||
let gateways = topology.gateways();
|
||||
setup_gateway_wasm(client_store, force_tls, explicit_gateway, gateways).await
|
||||
setup_gateway_wasm(client_store, explicit_gateway, gateways).await
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use nym_mixnet_contract_common::{
|
||||
GatewayBond, IdentityKey, Interval, MixId, MixNode, Percent, RewardedSetNodeStatus,
|
||||
};
|
||||
use nym_node_requests::api::v1::gateway::models::WebSockets;
|
||||
use nym_node_requests::api::v1::node::models::HostInformation;
|
||||
use nym_node_requests::api::v1::node::models::{BinaryBuildInformationOwned, HostInformation};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::{Display, Formatter};
|
||||
@@ -360,6 +360,9 @@ pub struct CirculatingSupplyResponse {
|
||||
pub struct NymNodeDescription {
|
||||
pub host_information: HostInformation,
|
||||
|
||||
// TODO: do we really care about ALL build info or just the version?
|
||||
pub build_information: BinaryBuildInformationOwned,
|
||||
|
||||
// for now we only care about their ws/wss situation, nothing more
|
||||
pub mixnet_websockets: WebSockets,
|
||||
}
|
||||
|
||||
@@ -100,6 +100,15 @@ async fn get_gateway_description(
|
||||
});
|
||||
}
|
||||
|
||||
let build_info =
|
||||
client
|
||||
.get_build_information()
|
||||
.await
|
||||
.map_err(|err| NodeDescribeCacheError::ApiFailure {
|
||||
gateway: gateway.identity_key.clone(),
|
||||
source: err,
|
||||
})?;
|
||||
|
||||
let websockets =
|
||||
client
|
||||
.get_mixnet_websockets()
|
||||
@@ -111,6 +120,7 @@ async fn get_gateway_description(
|
||||
|
||||
let description = NymNodeDescription {
|
||||
host_information: host_info.data,
|
||||
build_information: build_info,
|
||||
mixnet_websockets: websockets,
|
||||
};
|
||||
|
||||
|
||||
Generated
+2
@@ -3918,6 +3918,7 @@ dependencies = [
|
||||
"clap_complete_fig",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
"schemars",
|
||||
"semver 0.11.0",
|
||||
"serde",
|
||||
"vergen",
|
||||
@@ -4628,6 +4629,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"bs58 0.4.0",
|
||||
"log",
|
||||
"nym-api-requests",
|
||||
"nym-bin-common",
|
||||
"nym-config",
|
||||
"nym-crypto",
|
||||
|
||||
@@ -204,8 +204,7 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
|
||||
}
|
||||
|
||||
let gateway_setup = if register_gateway {
|
||||
let selection_spec =
|
||||
GatewaySelectionSpecification::new(Some(chosen_gateway_id), None, false);
|
||||
let selection_spec = GatewaySelectionSpecification::new(Some(chosen_gateway_id), None);
|
||||
let mut rng = rand_07::thread_rng();
|
||||
let available_gateways =
|
||||
current_gateways(&mut rng, &config.core.base.client.nym_api_urls).await?;
|
||||
|
||||
@@ -25,7 +25,7 @@ http-api-client = { path = "../../common/http-api-client", optional = true }
|
||||
|
||||
## openapi:
|
||||
utoipa = { workspace = true, optional = true }
|
||||
nym-bin-common = { path = "../../common/bin-common" }
|
||||
nym-bin-common = { path = "../../common/bin-common", features = ["bin_info_schema"] }
|
||||
|
||||
[features]
|
||||
default = ["client"]
|
||||
|
||||
@@ -8,6 +8,7 @@ use async_trait::async_trait;
|
||||
use http_api_client::{ApiClient, HttpClientError};
|
||||
|
||||
pub use http_api_client::Client;
|
||||
use nym_bin_common::build_information::BinaryBuildInformationOwned;
|
||||
|
||||
pub type NymNodeApiClientError = HttpClientError;
|
||||
|
||||
@@ -18,6 +19,10 @@ pub trait NymNodeApiClientExt: ApiClient {
|
||||
self.get_json_from(routes::api::v1::host_info_absolute())
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_build_information(&self) -> Result<BinaryBuildInformationOwned, NymNodeApiClientError> {
|
||||
self.get_json_from(routes::api::v1::build_info_absolute()).await
|
||||
}
|
||||
|
||||
// TODO: implement calls for other endpoints; for now I only care about the wss
|
||||
async fn get_mixnet_websockets(&self) -> Result<WebSockets, NymNodeApiClientError> {
|
||||
|
||||
@@ -419,11 +419,8 @@ where
|
||||
let gateway_setup = if self.has_valid_gateway_info().await {
|
||||
GatewaySetup::MustLoad
|
||||
} else {
|
||||
let selection_spec = GatewaySelectionSpecification::new(
|
||||
self.config.user_chosen_gateway.clone(),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let selection_spec =
|
||||
GatewaySelectionSpecification::new(self.config.user_chosen_gateway.clone(), None);
|
||||
|
||||
let mut rng = OsRng;
|
||||
|
||||
@@ -487,7 +484,7 @@ where
|
||||
|
||||
if !known_gateway {
|
||||
let selection_spec =
|
||||
GatewaySelectionSpecification::new(self.config.user_chosen_gateway, None, false);
|
||||
GatewaySelectionSpecification::new(self.config.user_chosen_gateway, None);
|
||||
|
||||
let mut rng = OsRng;
|
||||
let setup = GatewaySetup::New {
|
||||
|
||||
@@ -171,7 +171,6 @@ pub(crate) async fn execute(args: &Init) -> Result<(), NetworkRequesterError> {
|
||||
let selection_spec = GatewaySelectionSpecification::new(
|
||||
user_chosen_gateway_id.map(|id| id.to_base58_string()),
|
||||
Some(args.latency_based_selection),
|
||||
false,
|
||||
);
|
||||
|
||||
// Load and potentially override config
|
||||
|
||||
Reference in New Issue
Block a user