Skip to content

Commit

Permalink
feat: Add peer discovery example
Browse files Browse the repository at this point in the history
  • Loading branch information
aidan46 committed Jan 23, 2025
1 parent c40a8b3 commit 5ea1677
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 1 deletion.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ members = [
"pallets/market",
"pallets/proofs",
"pallets/randomness",
"pallets/storage-provider",
"pallets/storage-provider", "peer-resolver",
"primitives",
"runtime",
"storage-provider/client",
Expand Down
19 changes: 19 additions & 0 deletions peer-resolver/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
authors.workspace = true
edition.workspace = true
homepage.workspace = true
license-file.workspace = true
name = "peer-resolver"
repository.workspace = true
version = "0.1.0"

[dependencies]
anyhow.workspace = true
clap = { workspace = true, features = ["derive"] }
libp2p = { workspace = true, features = ["identify", "macros", "noise", "rendezvous", "tcp", "tokio", "yamux"] }
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
tracing.workspace = true
tracing-subscriber = { workspace = true, features = ["env-filter"] }

[lints]
workspace = true
121 changes: 121 additions & 0 deletions peer-resolver/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use std::time::Duration;

use anyhow::{bail, Result};
use clap::Parser;
use libp2p::{
futures::StreamExt,
noise,
rendezvous::client::{Behaviour, Event},
swarm::SwarmEvent,
tcp, yamux, Multiaddr, PeerId, Swarm, SwarmBuilder,
};
use tracing_subscriber::EnvFilter;

#[derive(Debug)]
struct PeerInfo {
peer_id: PeerId,
multiaddresses: Vec<Multiaddr>,
}

#[derive(Parser)]
struct Cli {
/// Peer ID to resolve
#[arg(long)]
peer_id: PeerId,

/// Rendezvous point address of the bootstrap node
#[arg(long)]
rendezvous_point_address: Multiaddr,

/// PeerID of the bootstrap node
#[arg(long)]
rendezvous_point: PeerId,
}

fn create_swarm() -> Result<Swarm<Behaviour>> {
Ok(SwarmBuilder::with_new_identity()
.with_tokio()
.with_tcp(
tcp::Config::default(),
noise::Config::new,
yamux::Config::default,
)?
.with_behaviour(|key| Behaviour::new(key.clone()))?
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(10)))
.build())
}

async fn discover(
swarm: &mut Swarm<Behaviour>,
peer_id_to_find: PeerId,
rendezvous_point_address: Multiaddr,
rendezvous_point: PeerId,
) -> Result<PeerInfo> {
// Dial in to the rendezvous point.
swarm.dial(rendezvous_point_address)?;

loop {
match swarm.select_next_some().await {
SwarmEvent::ConnectionEstablished { peer_id, .. } => {
if peer_id == rendezvous_point {
tracing::info!("Connection established with rendezvous point {}", peer_id);
tracing::info!("Connected to rendezvous point, discovering nodes...");

// Requesting rendezvous point for peer discovery
swarm
.behaviour_mut()
.discover(None, None, None, rendezvous_point);
}
}
// Received discovered event from the rendezvous point
SwarmEvent::Behaviour(Event::Discovered { registrations, .. }) => {
// Check registrations
for registration in &registrations {
// Get peer ID from the registration record
let peer_id = registration.record.peer_id();
// skip self
if &peer_id == swarm.local_peer_id() {
continue;
}
if peer_id == peer_id_to_find {
return Ok(PeerInfo {
peer_id,
multiaddresses: registration.record.addresses().to_vec(),
});
}
}
bail!("No registered multi-addresses found for Peer ID {peer_id_to_find}");
}

other => tracing::debug!("Other event: {other:?}"),
}
}
}

#[tokio::main]
async fn main() -> Result<()> {
let _ = tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.try_init();
let args = Cli::parse();

let mut swarm = create_swarm()?;
match discover(
&mut swarm,
args.peer_id,
args.rendezvous_point_address,
args.rendezvous_point,
)
.await
{
Ok(peer_info) => {
println!("Found peer with Peer ID {}", args.peer_id);
println!("Peer Info:");
println!("Peer ID: {}", peer_info.peer_id);
println!("Multiaddresses: {:?}", peer_info.multiaddresses);
}
Err(e) => eprintln!("{e}"),
}

Ok(())
}

0 comments on commit 5ea1677

Please sign in to comment.