Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rendezvous): directly return error from register #4073

Merged
merged 8 commits into from
Jun 17, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 5 additions & 2 deletions examples/rendezvous/src/bin/rzv-identify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,14 @@ async fn main() {
SwarmEvent::Behaviour(MyBehaviourEvent::Identify(identify::Event::Received {
..
})) => {
swarm.behaviour_mut().rendezvous.register(
if let Err(error) = swarm.behaviour_mut().rendezvous.register(
rendezvous::Namespace::from_static("rendezvous"),
rendezvous_point,
None,
);
) {
log::error!("Failed to register {}", error);
dgarus marked this conversation as resolved.
Show resolved Hide resolved
return;
}
}
SwarmEvent::Behaviour(MyBehaviourEvent::Rendezvous(
rendezvous::client::Event::Registered {
Expand Down
7 changes: 5 additions & 2 deletions examples/rendezvous/src/bin/rzv-register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,14 @@ async fn main() {
log::error!("Lost connection to rendezvous point {}", error);
}
SwarmEvent::ConnectionEstablished { peer_id, .. } if peer_id == rendezvous_point => {
swarm.behaviour_mut().rendezvous.register(
if let Err(error) = swarm.behaviour_mut().rendezvous.register(
rendezvous::Namespace::from_static("rendezvous"),
rendezvous_point,
None,
);
) {
log::error!("Failed to register {}", error);
dgarus marked this conversation as resolved.
Show resolved Hide resolved
return;
}
log::info!("Connection established with rendezvous point {}", peer_id);
}
// once `/identify` did its job, we know our external address and can register
Expand Down
31 changes: 12 additions & 19 deletions protocols/rendezvous/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use libp2p_swarm::{
ConnectionDenied, ConnectionId, ExternalAddresses, FromSwarm, NetworkBehaviour, PollParameters,
THandler, THandlerInEvent, THandlerOutEvent, ToSwarm,
};
use std::collections::{HashMap, VecDeque};
use std::collections::HashMap;
use std::iter;
use std::task::{Context, Poll};
use std::time::Duration;
Expand All @@ -41,8 +41,6 @@ pub struct Behaviour {

keypair: Keypair,

error_events: VecDeque<Event>,
thomaseizinger marked this conversation as resolved.
Show resolved Hide resolved

waiting_for_register: HashMap<RequestId, (PeerId, Namespace)>,
waiting_for_discovery: HashMap<RequestId, (PeerId, Option<Namespace>)>,

Expand All @@ -66,7 +64,6 @@ impl Behaviour {
iter::once((crate::PROTOCOL_IDENT, ProtocolSupport::Outbound)),
libp2p_request_response::Config::default(),
),
error_events: Default::default(),
keypair,
waiting_for_register: Default::default(),
waiting_for_discovery: Default::default(),
Expand All @@ -82,13 +79,15 @@ impl Behaviour {
///
/// External addresses are either manually added via [`libp2p_swarm::Swarm::add_external_address`] or reported
/// by other [`NetworkBehaviour`]s via [`ToSwarm::ExternalAddrConfirmed`].
pub fn register(&mut self, namespace: Namespace, rendezvous_node: PeerId, ttl: Option<Ttl>) {
pub fn register(
&mut self,
namespace: Namespace,
rendezvous_node: PeerId,
ttl: Option<Ttl>,
) -> Result<(), RegisterError> {
dgarus marked this conversation as resolved.
Show resolved Hide resolved
let external_addresses = self.external_addresses.iter().cloned().collect::<Vec<_>>();
if external_addresses.is_empty() {
self.error_events
.push_back(Event::RegisterFailed(RegisterError::NoExternalAddresses));

return;
return Err(RegisterError::NoExternalAddresses);
}

match PeerRecord::new(&self.keypair, external_addresses) {
Expand All @@ -99,13 +98,11 @@ impl Behaviour {
);
self.waiting_for_register
.insert(req_id, (rendezvous_node, namespace));

Ok(())
}
Err(signing_error) => {
self.error_events.push_back(Event::RegisterFailed(
RegisterError::FailedToMakeRecord(signing_error),
));
}
};
Err(signing_error) => Err(RegisterError::FailedToMakeRecord(signing_error)),
dgarus marked this conversation as resolved.
Show resolved Hide resolved
}
}

/// Unregister ourselves from the given namespace with the given rendezvous peer.
Expand Down Expand Up @@ -239,10 +236,6 @@ impl NetworkBehaviour for Behaviour {
) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
use libp2p_request_response as req_res;

if let Some(event) = self.error_events.pop_front() {
return Poll::Ready(ToSwarm::GenerateEvent(event));
}

loop {
match self.inner.poll(cx, params) {
Poll::Ready(ToSwarm::GenerateEvent(req_res::Event::Message {
Expand Down
55 changes: 42 additions & 13 deletions protocols/rendezvous/tests/rendezvous.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use futures::stream::FuturesUnordered;
use futures::StreamExt;
use libp2p_identity as identity;
use libp2p_rendezvous as rendezvous;
use libp2p_rendezvous::client::RegisterError;
use libp2p_swarm::{DialError, Swarm, SwarmEvent};
use libp2p_swarm_test::SwarmExt;
use std::convert::TryInto;
Expand All @@ -36,7 +37,8 @@ async fn given_successful_registration_then_successful_discovery() {

alice
.behaviour_mut()
.register(namespace.clone(), *robert.local_peer_id(), None);
.register(namespace.clone(), *robert.local_peer_id(), None)
.expect("Should send register request");

match libp2p_swarm_test::drive(&mut alice, &mut robert).await {
(
Expand Down Expand Up @@ -79,6 +81,23 @@ async fn given_successful_registration_then_successful_discovery() {
}
}

#[tokio::test]
async fn should_return_error_when_no_external_addresses() {
let _ = env_logger::try_init();
let namespace = rendezvous::Namespace::from_static("some-namespace");
let server = new_server(rendezvous::server::Config::default()).await;
let mut client = Swarm::new_ephemeral(rendezvous::client::Behaviour::new);

let res = client
.behaviour_mut()
.register(namespace.clone(), *server.local_peer_id(), None);

match res {
Err(RegisterError::NoExternalAddresses) => {}
_ => panic!("Should get the RegisterError::NoExternalAddresses"),
}
dgarus marked this conversation as resolved.
Show resolved Hide resolved
}

#[tokio::test]
async fn given_successful_registration_then_refresh_ttl() {
let _ = env_logger::try_init();
Expand All @@ -91,7 +110,8 @@ async fn given_successful_registration_then_refresh_ttl() {

alice
.behaviour_mut()
.register(namespace.clone(), roberts_peer_id, None);
.register(namespace.clone(), roberts_peer_id, None)
.expect("Should send register request");
dgarus marked this conversation as resolved.
Show resolved Hide resolved

match libp2p_swarm_test::drive(&mut alice, &mut robert).await {
(
Expand All @@ -114,7 +134,8 @@ async fn given_successful_registration_then_refresh_ttl() {

alice
.behaviour_mut()
.register(namespace.clone(), roberts_peer_id, Some(refresh_ttl));
.register(namespace.clone(), roberts_peer_id, Some(refresh_ttl))
.expect("Should send register request");

match libp2p_swarm_test::drive(&mut alice, &mut robert).await {
(
Expand Down Expand Up @@ -150,11 +171,14 @@ async fn given_invalid_ttl_then_unsuccessful_registration() {
let ([mut alice], mut robert) =
new_server_with_connected_clients(rendezvous::server::Config::default()).await;

alice.behaviour_mut().register(
namespace.clone(),
*robert.local_peer_id(),
Some(100_000_000),
);
alice
.behaviour_mut()
.register(
namespace.clone(),
*robert.local_peer_id(),
Some(100_000_000),
)
.expect("Should send register request");

match libp2p_swarm_test::drive(&mut alice, &mut robert).await {
(
Expand Down Expand Up @@ -182,7 +206,8 @@ async fn discover_allows_for_dial_by_peer_id() {

alice
.behaviour_mut()
.register(namespace.clone(), roberts_peer_id, None);
.register(namespace.clone(), roberts_peer_id, None)
.expect("Should send register request");
match alice.next_behaviour_event().await {
rendezvous::client::Event::Registered { .. } => {}
event => panic!("Unexpected event: {event:?}"),
Expand Down Expand Up @@ -233,7 +258,8 @@ async fn eve_cannot_register() {
eve.connect(&mut robert).await;

eve.behaviour_mut()
.register(namespace.clone(), *robert.local_peer_id(), None);
.register(namespace.clone(), *robert.local_peer_id(), None)
.expect("Should send register request");

match libp2p_swarm_test::drive(&mut eve, &mut robert).await {
(
Expand Down Expand Up @@ -263,7 +289,8 @@ async fn can_combine_client_and_server() {
charlie
.behaviour_mut()
.client
.register(namespace.clone(), *robert.local_peer_id(), None);
.register(namespace.clone(), *robert.local_peer_id(), None)
.expect("Should send register request");
match libp2p_swarm_test::drive(&mut charlie, &mut robert).await {
(
[CombinedEvent::Client(rendezvous::client::Event::Registered { .. })],
Expand All @@ -274,7 +301,8 @@ async fn can_combine_client_and_server() {

alice
.behaviour_mut()
.register(namespace, *charlie.local_peer_id(), None);
.register(namespace, *charlie.local_peer_id(), None)
.expect("Should send register request");
match libp2p_swarm_test::drive(&mut charlie, &mut alice).await {
(
[CombinedEvent::Server(rendezvous::server::Event::PeerRegistered { .. })],
Expand All @@ -299,7 +327,8 @@ async fn registration_on_clients_expire() {

alice
.behaviour_mut()
.register(namespace.clone(), roberts_peer_id, Some(registration_ttl));
.register(namespace.clone(), roberts_peer_id, Some(registration_ttl))
.expect("Should send register request");
match alice.next_behaviour_event().await {
rendezvous::client::Event::Registered { .. } => {}
event => panic!("Unexpected event: {event:?}"),
Expand Down