Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/file_event_publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct FileEventPublisher {

impl FileEventPublisher {
pub async fn connect(relay_config: &RelayConfig) -> Result<Self, HasheusError> {
let client = Client::default();
let client = relay_connector::build_client();
let relay_urls = relay_connector::connect_all(&client, &relay_config.file_relay_urls).await;

if relay_urls.is_empty() {
Expand Down
14 changes: 12 additions & 2 deletions src/profile_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const PROFILE_TIMEOUT: Duration = Duration::from_secs(3);
// the newest profile of the user that the relays return in time. each relay is
// asked on its own, so one that's slow to connect doesn't hide another's answer.
pub async fn fetch(public_key: PublicKey, relay_urls: &[RelayUrl]) -> Option<Event> {
let client = Client::default();
let client = relay_connector::build_client();
let filter = Filter::new()
.kind(Kind::Metadata)
.author(public_key)
Expand Down Expand Up @@ -56,7 +56,7 @@ pub async fn fetch(public_key: PublicKey, relay_urls: &[RelayUrl]) -> Option<Eve
mod tests {
use super::*;
use crate::test_event_builders::build_profile;
use crate::test_relays::{DEAD_RELAY_URL, relay_url, run_relay};
use crate::test_relays::{DEAD_RELAY_URL, relay_url, run_mismatching_relay, run_relay};

#[tokio::test]
async fn fetches_the_newest_profile() {
Expand All @@ -69,6 +69,16 @@ mod tests {
assert_eq!(profile, Some(newer));
}

#[tokio::test]
async fn ignores_events_a_relay_sends_that_werent_asked_for() {
let (_relay, url) = run_mismatching_relay().await;

assert_eq!(
fetch(Keys::generate().public_key(), &[relay_url(&url)]).await,
None
);
}

#[tokio::test]
async fn has_none_without_a_profile() {
let (_relay, url) = run_relay(&[build_profile(&Keys::generate(), 1, "someone")]).await;
Expand Down
6 changes: 6 additions & 0 deletions src/relay_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use tokio::task::JoinSet;

const CONNECT_TIMEOUT: Duration = Duration::from_secs(10);

// like the web page, an event that doesn't match what was asked for is dropped,
// so a relay can't pass off another file's verification as this file's.
pub fn build_client() -> Client {
Client::builder().verify_subscriptions(true).build()
}

// a relay that fails to connect isn't retried, so callers only use the ones
// that connect.
pub async fn connect(client: &Client, url: &RelayUrl) -> Option<Relay> {
Expand Down
18 changes: 16 additions & 2 deletions src/test_relays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use crate::relay_config::RelayConfig;
use nostr_sdk::prelude::*;
use std::time::Duration;

// relays for tests: one running in the test process, seeded with events, and
// one that can't be reached.
// relays for tests: one running in the test process, seeded with events, one
// that answers with events that weren't asked for, and one that can't be
// reached.

// nothing listens on port 1, so connecting fails right away.
pub const DEAD_RELAY_URL: &str = "ws://127.0.0.1:1";
Expand All @@ -27,6 +28,19 @@ pub async fn run_relay(events: &[Event]) -> (MockRelay, String) {
(relay, url.to_string())
}

// a relay that answers every request with events that don't match it.
pub async fn run_mismatching_relay() -> (MockRelay, String) {
let relay = MockRelay::run_with_opts(LocalRelayTestOptions {
unresponsive_connection: None,
send_random_events: true,
})
.await
.unwrap();
let url = relay.url().await;

(relay, url.to_string())
}

pub fn relay_url(url: &str) -> RelayUrl {
RelayUrl::parse(url).unwrap()
}
Expand Down
17 changes: 15 additions & 2 deletions src/verification_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ async fn coordinate(
sender: mpsc::Sender<Result<Update, HasheusError>>,
) {
// the client shuts its relays down when dropped, so it's held until the end.
let client = Client::default();
let client = relay_connector::build_client();
let mut progress = Progress::new(&stages_by_url, user_requirement);
let mut has_loaded = false;
let mut has_found_user_profile = false;
Expand Down Expand Up @@ -395,7 +395,9 @@ mod tests {
use crate::test_event_builders::{
HASH, build_event, build_file_event, build_follow_list, build_profile,
};
use crate::test_relays::{DEAD_RELAY_URL, build_relay_config, relay_url, run_relay};
use crate::test_relays::{
DEAD_RELAY_URL, build_relay_config, relay_url, run_mismatching_relay, run_relay,
};

mod group_stages_by_url {
use super::*;
Expand Down Expand Up @@ -634,6 +636,17 @@ mod tests {
assert_eq!(received, [Received::Loaded]);
}

#[tokio::test]
async fn ignores_events_a_relay_sends_that_werent_asked_for() {
let (_relay, url) = run_mismatching_relay().await;

let received = fetch_all(None, build_relay_config(&[&url], &[&url]))
.await
.unwrap();

assert_eq!(received, [Received::Loaded]);
}

#[tokio::test]
async fn finishes_with_a_repeated_relay_url() {
let alice = Keys::generate();
Expand Down
Loading