Skip to content

Commit

Permalink
feat: implement mdns and rendezvous peer discovery (#9)
Browse files Browse the repository at this point in the history
* feat: implement mdns and rendezvous peer discovery

* chore: bump version, cleanup logging

* docs: update readme

* feat: replace HashMap with BTreeMap for relays and rendezvous
  • Loading branch information
fbozic authored May 27, 2024
1 parent b64b015 commit 961e92f
Show file tree
Hide file tree
Showing 13 changed files with 461 additions and 412 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

4 changes: 3 additions & 1 deletion examples/chat/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "chat-example"
version = "0.1.0"
version = "0.2.0"
authors = ["Calimero Limited <info@calimero.network>"]
edition = "2021"
repository = "https://github.com/calimero-network/boot-node"
Expand All @@ -15,9 +15,11 @@ libp2p = { version = "0.53.2", features = [
"gossipsub",
"identify",
"macros",
"mdns",
"noise",
"ping",
"quic",
"rendezvous",
"relay",
"tokio",
"tcp",
Expand Down
38 changes: 9 additions & 29 deletions examples/chat/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,24 @@
# Chat
This examples show cases how to manually dial (connect to) either local peer or remote peer has a reservation on relay-server.
This examples show cases how to build chat application with DCUtR, mDNS, Relay, Rendezvous and GossipSub protocols.
- Local node gets reservation on the relay.
- Local node advertises relayed address at the Rendezvous node.
- Local nodes discovers other local nodes via mDNS discovery and attempts direct connection.
- Local nodes discovers other remote nodes via Rendezvous discovery and attempts hole punched connectioned.

## Run local only
This examples shows how to run two sessions locally and connect sessions by manually dialing local peer.

Run first chat session in echo mode.
```
cargo run -p chat-example -- --mode echo --port 4002 --secret-key-seed 102 --gossip-topic-names calimero-network/examples/chat/v0.0.1 --relay-address /ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF
```

Run second chat session in interactive mode with local peer dial.
```
cargo run -p chat-example -- --mode interactive --port 4003 --secret-key-seed 103 --gossip-topic-names calimero-network/examples/chat/v0.0.1 --dial-peer-addrs /ip4/127.0.0.1/udp/4002/quic-v1/p2p/12D3KooWMpeKAbMK4BTPsQY3rG7XwtdstseHGcq7kffY8LToYYKK --relay-address /ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF
```

In the interactive session publish new message manually:
```
publish calimero-network/examples/chat/v0.0.1 ola
```

## Run locally with remote peer dial in
This examples shows how to run two sessions locally and connect sessions manually by dialing private remote peer from each session. For the gossip message to pass from one local session to second local session it needs to go "the long way" around (local -> remote -> local).

Additional info:
- Remote instance is running in a private subnet behind NAT.
- Remote instance PeerId: `12D3KooWP285Hw3CSTdr9oU6Ezz4hDoi6XS5vfDjjNeTJ1uFMGvp`
- Remote instance address at the relay server: `ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF/p2p-circuit/p2p/12D3KooWP285Hw3CSTdr9oU6Ezz4hDoi6XS5vfDjjNeTJ1uFMGvp`
## Run
Run first chat session in interactive mode with remote peer dial.
```
cargo run -p chat-example -- --mode interactive --port 4002 --secret-key-seed 102 --gossip-topic-names calimero-network/examples/chat/v0.0.1 --dial-peer-addrs /ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF/p2p-circuit/p2p/12D3KooWP285Hw3CSTdr9oU6Ezz4hDoi6XS5vfDjjNeTJ1uFMGvp --relay-address /ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF
cargo run -p chat-example -- --mode interactive --port 4002 --secret-key-seed 102 --gossip-topic-names calimero-network/examples/chat/v0.0.2 --boot-nodes /ip4/35.156.78.13/udp/4001/quic-v1/p2p/12D3KooWRnt7EmBwrNALhAXAgM151MdH7Ka9tvYS91ZUqnqwpjVg
```

Run second chat session in interactive mode with remote peer dial.
```
cargo run -p chat-example -- --mode interactive --port 4003 --secret-key-seed 103 --gossip-topic-names calimero-network/examples/chat/v0.0.1 --dial-peer-addrs /ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF/p2p-circuit/p2p/12D3KooWP285Hw3CSTdr9oU6Ezz4hDoi6XS5vfDjjNeTJ1uFMGvp --relay-address /ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF
cargo run -p chat-example -- --mode interactive --port 4003 --secret-key-seed 103 --gossip-topic-names calimero-network/examples/chat/v0.0.2 --boot-nodes /ip4/35.156.78.13/udp/4001/quic-v1/p2p/12D3KooWRnt7EmBwrNALhAXAgM151MdH7Ka9tvYS91ZUqnqwpjVg
```

In any interactive session publish new message manually:
```
publish calimero-network/examples/chat/v0.0.1 ola
publish calimero-network/examples/chat/v0.0.2 ola
```

## Debugging and known issues
Expand Down
35 changes: 15 additions & 20 deletions examples/chat/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ struct Opt {

/// The listening address of a relay server to connect to.
#[clap(long)]
relay_address: Multiaddr,
boot_nodes: Vec<Multiaddr>,

/// The listening address of a relay server to connect to.
#[clap(long, default_value = "/calimero/devnet/examples/chat")]
rendezvous_namespace: String,

/// Optional list of peer addresses to dial immediately after network bootstrap.
#[clap(long)]
Expand All @@ -51,9 +55,9 @@ enum Mode {
#[tokio::main]
async fn main() -> eyre::Result<()> {
tracing_subscriber::registry()
// "info,chat_example=debug,{}",
// "info,chat_example=debug,libp2p_mdns=warn,{}",
.with(EnvFilter::builder().parse(format!(
"info,chat_example=debug,{}",
"info,libp2p_mdns=warn,{}",
std::env::var("RUST_LOG").unwrap_or_default()
))?)
.with(tracing_subscriber::fmt::layer())
Expand All @@ -63,8 +67,14 @@ async fn main() -> eyre::Result<()> {

let keypair = generate_ed25519(opt.secret_key_seed);

let (network_client, mut network_events) =
network::run(keypair.clone(), opt.port, opt.relay_address.clone()).await?;
let (network_client, mut network_events) = network::run(
keypair.clone(),
opt.port,
libp2p::rendezvous::Namespace::new(opt.rendezvous_namespace)?,
opt.boot_nodes.clone(),
opt.boot_nodes.clone(),
)
.await?;

if let Some(peer_addrs) = opt.dial_peer_addrs {
for addr in peer_addrs {
Expand Down Expand Up @@ -128,18 +138,6 @@ async fn handle_network_event(
is_echo: bool,
) -> eyre::Result<()> {
match event {
network::types::NetworkEvent::IdentifySent { peer_id } => {
debug!("Identify sent to {:?}", peer_id);
}
network::types::NetworkEvent::IdentifyReceived {
peer_id,
observed_addr,
} => {
debug!(
"Identify received from {:?} at {:?}",
peer_id, observed_addr
);
}
network::types::NetworkEvent::Message { message, .. } => {
let text = String::from_utf8_lossy(&message.data);
println!("{LINE_START} Received message: {:?}", text);
Expand All @@ -166,9 +164,6 @@ async fn handle_network_event(
network::types::NetworkEvent::ListeningOn { address, .. } => {
info!("Listening on: {}", address);
}
event => {
info!("Unhandled event: {:?}", event);
}
}
Ok(())
}
Expand Down
Loading

0 comments on commit 961e92f

Please sign in to comment.