Contractless/src/rpc/server/tests.rs

58 lines
2.0 KiB
Rust
Raw Normal View History

2026-05-24 17:56:57 +00:00
use crate::common::network_startup::is_public_network_address;
use crate::Arc;
use crate::Mutex;
use crate::SocketAddr;
use crate::TcpStream;
pub fn endpoint_port(ip_port: &str) -> Option<u16> {
ip_port
.rsplit_once(':')
.and_then(|(_, port)| port.parse::<u16>().ok())
}
// Verify the announced endpoint is public and matches the connected peer.
pub async fn ip_test(ip_port: &str, stream: &Arc<Mutex<TcpStream>>) -> bool {
// Private, loopback, malformed, and otherwise non-public addresses
// are rejected before comparing them with the connected socket.
if !is_public_network_address(ip_port) {
return false;
}
let stream_guard = stream.lock().await;
let remote_addr = stream_guard.peer_addr();
// Strip the port from either IPv4 host:port or bracketed IPv6
// [host]:port forms before comparing against the socket address.
let submitted_ip = ip_port
.strip_prefix('[')
.and_then(|value| value.split_once(']').map(|(ip, _)| ip))
.or_else(|| ip_port.rsplit_once(':').map(|(ip, _)| ip))
.unwrap_or(ip_port);
remote_addr.is_ok_and(|addr| addr.ip().to_string() == submitted_ip)
}
// check if port is open
pub async fn is_port_open(ip_port: &str) -> Result<bool, Box<dyn std::error::Error>> {
// Port 0 is the explicit client marker; it is never a miner endpoint.
if endpoint_port(ip_port) == Some(0) {
return Ok(false);
}
// A successful outbound connect confirms the peer can accept inbound
// node traffic on the port it advertised.
let Ok(addr) = ip_port.parse::<SocketAddr>() else {
return Ok(false);
};
match tokio::net::TcpStream::connect(addr).await {
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
// verify connecting client time is within 1 second of our own.
pub fn is_within_one_second(timestamp1: u32, timestamp2: u32) -> bool {
let duration = timestamp1.wrapping_sub(timestamp2);
duration <= 1 || timestamp2.wrapping_sub(timestamp1) <= 1
}