diff --git a/packages/rs-dapi-client/src/address_list.rs b/packages/rs-dapi-client/src/address_list.rs index 5a92df63fe..2f59b22c3b 100644 --- a/packages/rs-dapi-client/src/address_list.rs +++ b/packages/rs-dapi-client/src/address_list.rs @@ -1,7 +1,6 @@ //! Subsystem to manage DAPI nodes. use chrono::Utc; -use dapi_grpc::tonic::codegen::http; use dapi_grpc::tonic::transport::Uri; use rand::{rngs::SmallRng, seq::IteratorRandom, SeedableRng}; use std::collections::hash_map::Entry; @@ -24,8 +23,8 @@ impl FromStr for Address { fn from_str(s: &str) -> Result { Uri::from_str(s) - .map(Address::from) - .map_err(AddressListError::from) + .map_err(|e| AddressListError::InvalidAddressUri(e.to_string())) + .map(Address::try_from)? } } @@ -47,9 +46,17 @@ impl Hash for Address { } } -impl From for Address { - fn from(uri: Uri) -> Self { - Address(uri) +impl TryFrom for Address { + type Error = AddressListError; + + fn try_from(value: Uri) -> Result { + if value.host().is_none() { + return Err(AddressListError::InvalidAddressUri( + "uri must contain host".to_string(), + )); + } + + Ok(Address(value)) } } @@ -97,7 +104,7 @@ pub enum AddressListError { /// A valid uri is required to create an Address #[error("unable parse address: {0}")] #[cfg_attr(feature = "mocks", serde(skip))] - InvalidAddressUri(#[from] http::uri::InvalidUri), + InvalidAddressUri(String), } /// A structure to manage DAPI addresses to select from @@ -195,13 +202,12 @@ impl AddressList { guard.remove(address) } - // TODO: this is the most simple way to add an address - // however we need to support bulk loading (e.g. providing a network name) - // and also fetch updated from SML. + #[deprecated] + // TODO: Remove in favor of add /// Add a node [Address] to [AddressList] by [Uri]. /// Returns false if the address is already in the list. pub fn add_uri(&mut self, uri: Uri) -> bool { - self.add(Address::from(uri)) + self.add(Address::try_from(uri).expect("valid uri")) } /// Randomly select a not banned address. @@ -251,23 +257,24 @@ impl IntoIterator for AddressList { } } -// TODO: Must be changed to FromStr -impl From<&str> for AddressList { - fn from(value: &str) -> Self { - let uri_list: Vec = value +impl FromStr for AddressList { + type Err = AddressListError; + + fn from_str(s: &str) -> Result { + let uri_list: Vec
= s .split(',') - .map(|uri| Uri::from_str(uri).expect("invalid uri")) - .collect(); + .map(Address::from_str) + .collect::>()?; - Self::from_iter(uri_list) + Ok(Self::from_iter(uri_list)) } } -impl FromIterator for AddressList { - fn from_iter>(iter: T) -> Self { +impl FromIterator
for AddressList { + fn from_iter>(iter: T) -> Self { let mut address_list = Self::new(); for uri in iter { - address_list.add_uri(uri); + address_list.add(uri); } address_list diff --git a/packages/rs-dapi-client/src/transport/grpc.rs b/packages/rs-dapi-client/src/transport/grpc.rs index 853639ca77..62a7590406 100644 --- a/packages/rs-dapi-client/src/transport/grpc.rs +++ b/packages/rs-dapi-client/src/transport/grpc.rs @@ -44,8 +44,8 @@ impl TransportClient for PlatformGrpcClient { .get_or_create(PoolPrefix::Platform, &uri, None, || { match create_channel(uri.clone(), None) { Ok(channel) => Ok(Self::new(channel).into()), - Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!( - "Channel creation failed: {}", + Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!( + "channel creation failed: {}", e ))), } @@ -65,7 +65,7 @@ impl TransportClient for PlatformGrpcClient { Some(settings), || match create_channel(uri.clone(), Some(settings)) { Ok(channel) => Ok(Self::new(channel).into()), - Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!( + Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!( "Channel creation failed: {}", e ))), @@ -81,7 +81,7 @@ impl TransportClient for CoreGrpcClient { .get_or_create(PoolPrefix::Core, &uri, None, || { match create_channel(uri.clone(), None) { Ok(channel) => Ok(Self::new(channel).into()), - Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!( + Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!( "Channel creation failed: {}", e ))), @@ -102,7 +102,7 @@ impl TransportClient for CoreGrpcClient { Some(settings), || match create_channel(uri.clone(), Some(settings)) { Ok(channel) => Ok(Self::new(channel).into()), - Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!( + Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!( "Channel creation failed: {}", e ))), diff --git a/packages/rs-sdk/examples/read_contract.rs b/packages/rs-sdk/examples/read_contract.rs index 7ac2cc333d..75e1e1214d 100644 --- a/packages/rs-sdk/examples/read_contract.rs +++ b/packages/rs-sdk/examples/read_contract.rs @@ -3,7 +3,7 @@ use std::{num::NonZeroUsize, str::FromStr}; use clap::Parser; use dash_sdk::{mock::provider::GrpcContextProvider, platform::Fetch, Sdk, SdkBuilder}; use dpp::prelude::{DataContract, Identifier}; -use rs_dapi_client::AddressList; +use rs_dapi_client::{Address, AddressList}; use zeroize::Zeroizing; #[derive(clap::Parser, Debug)] @@ -80,14 +80,14 @@ fn setup_sdk(config: &Config) -> Sdk { // Let's build the Sdk. // First, we need an URI of some Dash Platform DAPI host to connect to and use as seed. - let uri = http::Uri::from_str(&format!( - "http://{}:{}", + let address = Address::from_str(&format!( + "https://{}:{}", config.server_address, config.platform_port )) .expect("parse uri"); // Now, we create the Sdk with the wallet and context provider. - let sdk = SdkBuilder::new(AddressList::from_iter([uri])) + let sdk = SdkBuilder::new(AddressList::from_iter([address])) .build() .expect("cannot build sdk"); diff --git a/packages/rs-sdk/src/platform/types/evonode.rs b/packages/rs-sdk/src/platform/types/evonode.rs index 70bbabee61..2f91e17106 100644 --- a/packages/rs-sdk/src/platform/types/evonode.rs +++ b/packages/rs-sdk/src/platform/types/evonode.rs @@ -25,8 +25,8 @@ use std::fmt::Debug; /// use futures::executor::block_on; /// /// let sdk = Sdk::new_mock(); -/// let uri: http::Uri = "http://127.0.0.1:1".parse().unwrap(); -/// let node = EvoNode::new(uri.into()); +/// let address = "http://127.0.0.1:1".parse().expect("valid address"); +/// let node = EvoNode::new(address); /// let status = block_on(EvoNodeStatus::fetch_unproved(&sdk, node)).unwrap(); /// ``` diff --git a/packages/rs-sdk/src/sync.rs b/packages/rs-sdk/src/sync.rs index be7cf9d265..5f5d266669 100644 --- a/packages/rs-sdk/src/sync.rs +++ b/packages/rs-sdk/src/sync.rs @@ -355,7 +355,7 @@ mod test { Err(ExecutionError { inner: MockError::Generic, retries, - address: Some(Uri::from_static("http://localhost").into()), + address: Some("http://localhost".parse().expect("valid address")), }) } diff --git a/packages/rs-sdk/tests/fetch/config.rs b/packages/rs-sdk/tests/fetch/config.rs index c2f8edbc4e..f55484f5ce 100644 --- a/packages/rs-sdk/tests/fetch/config.rs +++ b/packages/rs-sdk/tests/fetch/config.rs @@ -8,7 +8,7 @@ use dpp::{ dashcore::{hashes::Hash, ProTxHash}, prelude::Identifier, }; -use rs_dapi_client::AddressList; +use rs_dapi_client::{Address, AddressList}; use serde::Deserialize; use std::{path::PathBuf, str::FromStr}; use zeroize::Zeroizing; @@ -131,9 +131,12 @@ impl Config { false => "http", }; - let address: String = format!("{}://{}:{}", scheme, self.platform_host, self.platform_port); + let address: Address = + format!("{}://{}:{}", scheme, self.platform_host, self.platform_port) + .parse() + .expect("valid address"); - AddressList::from_iter(vec![http::Uri::from_str(&address).expect("valid uri")]) + AddressList::from_iter([address]) } /// Create new SDK instance diff --git a/packages/rs-sdk/tests/fetch/evonode.rs b/packages/rs-sdk/tests/fetch/evonode.rs index 6a6ce4a1f8..b2521ba864 100644 --- a/packages/rs-sdk/tests/fetch/evonode.rs +++ b/packages/rs-sdk/tests/fetch/evonode.rs @@ -5,6 +5,7 @@ use dash_sdk::platform::{types::evonode::EvoNode, FetchUnproved}; use dpp::dashcore::{hashes::Hash, ProTxHash}; use drive_proof_verifier::types::EvoNodeStatus; use http::Uri; +use rs_dapi_client::Address; use std::time::Duration; /// Given some existing evonode URIs, WHEN we connect to them, THEN we get status. use tokio::time::timeout; @@ -60,11 +61,11 @@ async fn test_evonode_status_refused() { let cfg = Config::new(); let sdk = cfg.setup_api("test_evonode_status_refused").await; - let uri: Uri = "http://127.0.0.1:1".parse().unwrap(); + let address: Address = "http://127.0.0.1:1".parse().expect("valid address"); - let node = EvoNode::new(uri.clone().into()); + let node = EvoNode::new(address.clone()); let result = EvoNodeStatus::fetch_unproved(&sdk, node).await; - tracing::debug!(?result, ?uri, "evonode status"); + tracing::debug!(?result, ?address, "evonode status"); assert!(result.is_err()); }