calimero-network 0.8.0

Core Calimero infrastructure and tools
Documentation
use libp2p::rendezvous::client::Event;
use owo_colors::OwoColorize;
use tracing::{debug, error, info, warn};

use super::{EventHandler, NetworkManager};
use crate::discovery::state::{PeerDiscoveryMechanism, RendezvousRegistrationStatus};

impl EventHandler<Event> for NetworkManager {
    fn handle(&mut self, event: Event) {
        debug!("{}: {:?}", "rendezvous".yellow(), event);

        match event {
            Event::Discovered {
                rendezvous_node,
                registrations,
                cookie,
            } => {
                self.discovery
                    .state
                    .update_rendezvous_cookie(&rendezvous_node, &cookie);

                for registration in registrations {
                    let peer_id = registration.record.peer_id();

                    if peer_id == *self.swarm.local_peer_id() {
                        continue;
                    }

                    self.discovery
                        .state
                        .add_peer_discovery_mechanism(&peer_id, PeerDiscoveryMechanism::Rendezvous);

                    if self.swarm.is_connected(&peer_id)
                        || self
                            .discovery
                            .state
                            .is_peer_discovered_via(&peer_id, PeerDiscoveryMechanism::Mdns)
                    {
                        continue;
                    }

                    debug!(
                        %peer_id,
                        addrs=?(registration.record.addresses()),
                        "Discovered new unconnected peer via rendezvous, attempting to dial it"
                    );

                    for address in registration.record.addresses() {
                        debug!(%peer_id, %address, "Dialing peer discovered via rendezvous");
                        if let Err(err) = self.swarm.dial(address.clone()) {
                            error!("Failed to dial peer: {:?}", err);
                        }
                    }
                }
            }
            Event::Registered {
                rendezvous_node, ..
            } => {
                self.discovery.state.update_rendezvous_registration_status(
                    &rendezvous_node,
                    RendezvousRegistrationStatus::Registered,
                );

                if let Some(peer_info) = self.discovery.state.get_peer_info(&rendezvous_node) {
                    if peer_info
                        .rendezvous()
                        .and_then(|info| info.cookie())
                        .is_none()
                    {
                        debug!(%rendezvous_node, "Discovering peers via rendezvous after registration");
                        if let Err(err) = self.rendezvous_discover(&rendezvous_node) {
                            error!(%err, "Failed to run rendezvous discovery after registration");
                        }
                    }
                }
            }
            Event::DiscoverFailed {
                rendezvous_node,
                namespace,
                error,
            } => {
                warn!(?rendezvous_node, ?namespace, error_code=?error, "Rendezvous discovery failed");
            }
            Event::RegisterFailed {
                rendezvous_node,
                namespace,
                error,
            } => {
                error!(?rendezvous_node, ?namespace, error_code=?error, "Rendezvous registration failed");
            }
            Event::Expired { peer } => {
                self.discovery.state.update_rendezvous_registration_status(
                    &peer,
                    RendezvousRegistrationStatus::Expired,
                );

                if let Some(nominated_peer) = self.find_new_rendezvous_peer() {
                    if self.swarm.is_connected(&nominated_peer) {
                        if let Err(err) = self.rendezvous_register(&nominated_peer) {
                            error!(%err, "Failed to register with nominated rendezvous peer");
                        }
                    } else {
                        debug!(%nominated_peer, "Dialing nominated rendezvous peer");
                        if let Err(err) = self.swarm.dial(nominated_peer) {
                            error!(%err, "Failed to dial nominated rendezvous peer");
                        }
                    }
                } else {
                    info!("Couldn't find new peer to nominate for rendezvous registration.");
                }
            }
        }
    }
}