Skip to content

Commit

Permalink
Change to explicit resolve
Browse files Browse the repository at this point in the history
  • Loading branch information
someone235 committed Aug 27, 2023
1 parent 3dba135 commit 9046b8d
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 49 deletions.
2 changes: 1 addition & 1 deletion rpc/core/src/api/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub trait RpcApi: Sync + Send + AnySync {
/// Adds a peer to the node's outgoing connection list.
///
/// This will, in most cases, result in the node connecting to said peer.
async fn add_peer(&self, peer_address: RpcContextualPeerAddress, is_permanent: bool) -> RpcResult<()> {
async fn add_peer(&self, peer_address: String, is_permanent: bool) -> RpcResult<()> {
self.add_peer_call(AddPeerRequest::new(peer_address, is_permanent)).await?;
Ok(())
}
Expand Down
5 changes: 4 additions & 1 deletion rpc/core/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use kaspa_consensus_core::tx::TransactionId;
use kaspa_utils::networking::IpAddress;
use kaspa_utils::networking::{IpAddress, ResolveError};
use std::{net::AddrParseError, num::TryFromIntError};
use thiserror::Error;

Expand All @@ -10,6 +10,9 @@ pub enum RpcError {
#[error("Not implemented")]
NotImplemented,

#[error("Couldn't resolve host: {0}")]
ResolveHostError(#[from] ResolveError),

#[error("Integer downsize conversion error {0}")]
IntConversionError(#[from] TryFromIntError),

Expand Down
4 changes: 2 additions & 2 deletions rpc/core/src/model/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,12 @@ impl GetConnectedPeerInfoResponse {
#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, BorshSchema)]
#[serde(rename_all = "camelCase")]
pub struct AddPeerRequest {
pub peer_address: RpcContextualPeerAddress,
pub peer_address: String,
pub is_permanent: bool,
}

impl AddPeerRequest {
pub fn new(peer_address: RpcContextualPeerAddress, is_permanent: bool) -> Self {
pub fn new(peer_address: String, is_permanent: bool) -> Self {
Self { peer_address, is_permanent }
}
}
Expand Down
6 changes: 2 additions & 4 deletions rpc/grpc/core/src/convert/message.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::protowire::{self, submit_block_response_message::RejectReason};
use kaspa_rpc_core::{
RpcContextualPeerAddress, RpcError, RpcExtraData, RpcHash, RpcIpAddress, RpcNetworkType, RpcPeerAddress, RpcResult,
};
use kaspa_rpc_core::{RpcError, RpcExtraData, RpcHash, RpcIpAddress, RpcNetworkType, RpcPeerAddress, RpcResult};
use std::str::FromStr;

macro_rules! from {
Expand Down Expand Up @@ -519,7 +517,7 @@ try_from!(item: &protowire::GetConnectedPeerInfoResponseMessage, RpcResult<kaspa
});

try_from!(item: &protowire::AddPeerRequestMessage, kaspa_rpc_core::AddPeerRequest, {
Self { peer_address: RpcContextualPeerAddress::from_str(&item.address)?, is_permanent: item.is_permanent }
Self { peer_address: item.address.clone().to_owned(), is_permanent: item.is_permanent }
});
try_from!(&protowire::AddPeerResponseMessage, RpcResult<kaspa_rpc_core::AddPeerResponse>);

Expand Down
5 changes: 3 additions & 2 deletions rpc/service/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use kaspa_rpc_core::{
Notification, RpcError, RpcResult,
};
use kaspa_txscript::{extract_script_pub_key_address, pay_to_address_script};
use kaspa_utils::{channel::Channel, triggers::SingleTrigger};
use kaspa_utils::{channel::Channel, networking::ContextualNetAddress, triggers::SingleTrigger};
use kaspa_utxoindex::api::UtxoIndexProxy;
use kaspa_wrpc_core::ServerCounters as WrpcServerCounters;
use std::{
Expand Down Expand Up @@ -560,7 +560,8 @@ impl RpcApi for RpcCoreService {
warn!("AddPeer RPC command called while node in safe RPC mode -- ignoring.");
return Err(RpcError::UnavailableInSafeMode);
}
let peer_address = request.peer_address.normalize(self.config.net.default_p2p_port());
let peer_address = tokio::task::spawn_blocking(move || ContextualNetAddress::resolve(&request.peer_address)).await.unwrap()?;
let peer_address = peer_address.normalize(self.config.net.default_p2p_port());
if let Some(connection_manager) = self.flow_context.connection_manager() {
connection_manager.add_connection_request(peer_address.into(), request.is_permanent).await;
} else {
Expand Down
8 changes: 4 additions & 4 deletions rpc/wrpc/server/src/address.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::service::WrpcEncoding;
use kaspa_consensus_core::networktype::NetworkType;
use kaspa_utils::networking::{ContextualNetAddress, FromStrError};
use kaspa_utils::networking::{ContextualNetAddress, ResolveError};
use std::str::FromStr;

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -33,7 +33,7 @@ impl WrpcNetAddress {
}

impl FromStr for WrpcNetAddress {
type Err = FromStrError;
type Err = ResolveError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"default" => Ok(WrpcNetAddress::Default),
Expand All @@ -47,15 +47,15 @@ impl FromStr for WrpcNetAddress {
}

impl TryFrom<&str> for WrpcNetAddress {
type Error = FromStrError;
type Error = ResolveError;

fn try_from(s: &str) -> Result<Self, Self::Error> {
WrpcNetAddress::from_str(s)
}
}

impl TryFrom<String> for WrpcNetAddress {
type Error = FromStrError;
type Error = ResolveError;

fn try_from(s: String) -> Result<Self, Self::Error> {
WrpcNetAddress::from_str(&s)
Expand Down
74 changes: 39 additions & 35 deletions utils/src/networking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::{
num::ParseIntError,
ops::Deref,
str::FromStr,
sync::Arc,
};
use uuid::Uuid;

Expand Down Expand Up @@ -282,6 +283,37 @@ impl ContextualNetAddress {
pub fn loopback() -> Self {
Self { ip: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).into(), port: None }
}

// resolve uses `to_socket_addrs` which is a blocking io operation, so when used in
// a tokio context it's best to be used inside a `tokio::task::spawn_blocking` block.
pub fn resolve(s: &str) -> Result<Self, ResolveError> {
match s.parse::<ContextualNetAddress>() {
Ok(addr) => Ok(addr),
Err(e) => {
if !hostname_validator::is_valid(s) {
return Err(ResolveError::AddrParseError(e));
} else {
let (host, port) = match s.split_once(":") {
Some((host, port_str)) => match port_str.parse::<u16>() {
Ok(port) => (host, Some(port)),
Err(e) => {
return Err(ResolveError::ParseIntError(e));
}
},
None => (s, None),
};
const STUB_PORT: u16 = 80;
match (host, STUB_PORT).to_socket_addrs() {
Ok(mut addrs) => match addrs.next() {
Some(addr) => Ok(Self::new(addr.ip().into(), port)),
None => Err(ResolveError::LookupFoundNoAddresses(s.to_owned())),
},
Err(e) => Err(ResolveError::IoError(Arc::new(e))),
}
}
}
}
}
}

impl From<NetAddress> for ContextualNetAddress {
Expand All @@ -290,8 +322,8 @@ impl From<NetAddress> for ContextualNetAddress {
}
}

#[derive(Debug, thiserror::Error)]
pub enum FromStrError {
#[derive(Debug, thiserror::Error, Clone)]
pub enum ResolveError {
#[error("Lookup found no addresses associated with: {0}")]
LookupFoundNoAddresses(String),

Expand All @@ -302,58 +334,30 @@ pub enum FromStrError {
ParseIntError(#[from] ParseIntError),

#[error(transparent)]
IoError(#[from] std::io::Error),
IoError(#[from] Arc<std::io::Error>),
}

impl FromStr for ContextualNetAddress {
type Err = FromStrError;
type Err = AddrParseError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match SocketAddr::from_str(s) {
Ok(socket) => Ok(Self::new(socket.ip().into(), Some(socket.port()))),
Err(_) => {
match IpAddress::from_str(s) {
Ok(ip_addr) => Ok(Self::new(ip_addr, None)),
Err(e) => {
if !hostname_validator::is_valid(s) {
Err(FromStrError::AddrParseError(e))
} else {
let (host, port) = match s.split_once(":") {
Some((host, port_str)) => match port_str.parse::<u16>() {
Ok(port) => (host, Some(port)),
Err(e) => {
return Err(FromStrError::ParseIntError(e));
}
},
None => (s, None),
};
const STUB_PORT: u16 = 80;
match (host, STUB_PORT).to_socket_addrs() {
Ok(mut addrs) => match addrs.next() {
Some(addr) => Ok(Self::new(addr.ip().into(), port)),
None => Err(FromStrError::LookupFoundNoAddresses(s.to_owned())),
},
Err(e) => Err(FromStrError::IoError(e)),
}
}
}
}
// Ok(Self::new(IpAddress::from_str(s)?, None))
}
Err(_) => Ok(Self::new(IpAddress::from_str(s)?, None)),
}
}
}

impl TryFrom<&str> for ContextualNetAddress {
type Error = FromStrError;
type Error = AddrParseError;

fn try_from(s: &str) -> Result<Self, Self::Error> {
ContextualNetAddress::from_str(s)
}
}

impl TryFrom<String> for ContextualNetAddress {
type Error = FromStrError;
type Error = AddrParseError;

fn try_from(s: String) -> Result<Self, Self::Error> {
ContextualNetAddress::from_str(&s)
Expand Down

0 comments on commit 9046b8d

Please sign in to comment.