Skip to content

Commit

Permalink
Merge pull request #73 from pubky/fix/relay-resolve
Browse files Browse the repository at this point in the history
Fix/relay resolve
  • Loading branch information
Nuhvi authored Jul 27, 2024
2 parents 0e9caad + 465e25a commit 0e9a68b
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 41 deletions.
1 change: 1 addition & 0 deletions pkarr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub const DEFAULT_RESOLVERS: [&str; 1] = ["resolver.pkarr.org:6881"];
pub use bytes;
pub use simple_dns as dns;

#[cfg(not(target_arch = "wasm32"))]
macro_rules! if_async {
($($item:item)*) => {$(
#[cfg(all(not(target_arch = "wasm32"), feature = "async"))]
Expand Down
55 changes: 38 additions & 17 deletions pkarr/src/relay_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,27 +112,21 @@ impl PkarrRelayClient {
///
/// # Errors
///
/// - Returns [Error::RelayError] if the relay responded with a status >= 400 or something
/// wring with the transport, transparent from [ureq::Error].
/// - Returns [Error::RelayError] if the relay responded with a status >= 400
/// (except 404 in which case you should receive Ok(None)) or something wrong
/// with the transport, transparent from [ureq::Error].
/// - Returns [Error::IO] if something went wrong while reading the payload.
pub fn resolve(&self, public_key: &PublicKey) -> Result<Option<SignedPacket>> {
let mut last_result = Ok(None);
if let Some(signed_packet) = self.resolve_inner(public_key).recv()?? {
self.cache
.lock()
.unwrap()
.put(public_key.clone(), signed_packet.clone());

while let Ok(response) = self.resolve_inner(public_key).recv() {
match response {
Ok(Some(signed_packet)) => {
self.cache
.lock()
.unwrap()
.put(public_key.clone(), signed_packet.clone());

return Ok(Some(signed_packet));
}
result => last_result = result,
}
}
return Ok(Some(signed_packet));
};

last_result
Ok(None)
}

// === Private Methods ===
Expand Down Expand Up @@ -246,6 +240,10 @@ impl PkarrRelayClient {
};
}
}
Err(ureq::Error::Status(404, _)) => {
debug!(?url, "SignedPacket not found");
let _ = sender.send(Ok(None));
}
Err(error) => {
debug!(?url, ?error, "Error response");
let _ = sender.send(Err(Error::RelayError(Box::new(error))));
Expand Down Expand Up @@ -308,4 +306,27 @@ mod tests {

assert_eq!(resolved.as_bytes(), signed_packet.as_bytes());
}

#[test]
fn not_found() {
let keypair = Keypair::random();

let mut server = mockito::Server::new();

let path = format!("/{}", keypair.public_key());

server.mock("GET", path.as_str()).with_status(404).create();

let relays: Vec<String> = vec![server.url()];
let settings = RelaySettings {
relays,
..RelaySettings::default()
};

let client = PkarrRelayClient::new(settings.clone()).unwrap();

let resolved = client.resolve(&keypair.public_key()).unwrap();

assert!(resolved.is_none());
}
}
55 changes: 38 additions & 17 deletions pkarr/src/relay_client_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,21 @@ impl PkarrRelayClientAsync {
///
/// # Errors
///
/// - Returns [Error::RelayError] if the relay responded with a status >= 400 or something
/// wring with the transport, transparent from [ureq::Error].
/// - Returns [Error::RelayError] if the relay responded with a status >= 400
/// (except 404 in which case you should receive Ok(None)) or something wrong
/// with the transport, transparent from [ureq::Error].
/// - Returns [Error::IO] if something went wrong while reading the payload.
pub async fn resolve(&self, public_key: &PublicKey) -> Result<Option<SignedPacket>> {
let mut last_result = Ok(None);
if let Some(signed_packet) = self.0.resolve_inner(public_key).recv_async().await?? {
self.cache()
.lock()
.unwrap()
.put(public_key.clone(), signed_packet.clone());

while let Ok(response) = self.0.resolve_inner(public_key).recv_async().await {
match response {
Ok(Some(signed_packet)) => {
self.cache()
.lock()
.unwrap()
.put(public_key.clone(), signed_packet.clone());
return Ok(Some(signed_packet));
};

return Ok(Some(signed_packet));
}
result => last_result = result,
}
}

last_result
Ok(None)
}
}

Expand Down Expand Up @@ -127,4 +121,31 @@ mod tests {

futures::executor::block_on(test());
}

#[test]
fn not_found() {
async fn test() {
let keypair = Keypair::random();

let mut server = mockito::Server::new();

let path = format!("/{}", keypair.public_key());

server.mock("GET", path.as_str()).with_status(404).create();

let relays: Vec<String> = vec![server.url()];
let settings = RelaySettings {
relays,
..RelaySettings::default()
};

let client = PkarrRelayClient::new(settings.clone()).unwrap().as_async();

let resolved = client.resolve(&keypair.public_key()).await.unwrap();

assert!(resolved.is_none());
}

futures::executor::block_on(test());
}
}
32 changes: 26 additions & 6 deletions pkarr/src/relay_client_web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl PkarrRelayClient {
/// # Errors
///
/// - Returns [Error::WasmRelayError] For Error responses
/// (except 404, these get converted to Ok(None).
/// - Returns [Error::JsError] If an error happened on JS side.
pub async fn resolve(&self, public_key: &PublicKey) -> Result<Option<SignedPacket>> {
let futures = self.relays.iter().map(|relay| {
Expand Down Expand Up @@ -85,7 +86,13 @@ impl PkarrRelayClient {

match select_ok(futures).await {
Ok((response, _)) => Ok(response),
Err(e) => Err(e),
Err(e) => {
if let Error::WasmRelayError(404, _) = e {
return Ok(None);
}

Err(e)
}
}
}
}
Expand Down Expand Up @@ -176,6 +183,8 @@ mod tests {
};
}

const TEST_RELAY: &str = "http://localhost:6881";

#[wasm_bindgen_test]
async fn basic() {
let keypair = Keypair::random();
Expand All @@ -190,11 +199,9 @@ mod tests {

let signed_packet = SignedPacket::from_packet(&keypair, &packet).unwrap();

let client = PkarrRelayClient::new(vec![
"http://fail.non".to_string(),
"https://relay.pkarr.org".to_string(),
])
.unwrap();
let client =
PkarrRelayClient::new(vec!["http://fail.non".to_string(), TEST_RELAY.to_string()])
.unwrap();

client.publish(&signed_packet).await.unwrap();

Expand All @@ -208,4 +215,17 @@ mod tests {

assert_eq!(resolved.as_bytes(), signed_packet.as_bytes());
}

#[wasm_bindgen_test]
async fn not_found() {
let keypair = Keypair::random();

let client = PkarrRelayClient::new(vec![TEST_RELAY.to_string()]).unwrap();

let resolved = client.resolve(&keypair.public_key()).await.unwrap();

log!("{:?}", resolved);

assert!(resolved.is_none());
}
}
4 changes: 3 additions & 1 deletion pkarr/src/signed_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ use std::{
char,
fmt::{self, Display, Formatter},
net::{Ipv4Addr, Ipv6Addr},
time::SystemTime,
};

#[cfg(not(target_arch = "wasm32"))]
use std::time::SystemTime;

const DOT: char = '.';

self_cell!(
Expand Down

0 comments on commit 0e9a68b

Please sign in to comment.