Skip to content

Commit 961e92f

Browse files
authored
feat: implement mdns and rendezvous peer discovery (#9)
* feat: implement mdns and rendezvous peer discovery * chore: bump version, cleanup logging * docs: update readme * feat: replace HashMap with BTreeMap for relays and rendezvous
1 parent b64b015 commit 961e92f

13 files changed

+461
-412
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/chat/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "chat-example"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
authors = ["Calimero Limited <info@calimero.network>"]
55
edition = "2021"
66
repository = "https://github.com/calimero-network/boot-node"
@@ -15,9 +15,11 @@ libp2p = { version = "0.53.2", features = [
1515
"gossipsub",
1616
"identify",
1717
"macros",
18+
"mdns",
1819
"noise",
1920
"ping",
2021
"quic",
22+
"rendezvous",
2123
"relay",
2224
"tokio",
2325
"tcp",

examples/chat/README.md

+9-29
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,24 @@
11
# Chat
2-
This examples show cases how to manually dial (connect to) either local peer or remote peer has a reservation on relay-server.
2+
This examples show cases how to build chat application with DCUtR, mDNS, Relay, Rendezvous and GossipSub protocols.
3+
- Local node gets reservation on the relay.
4+
- Local node advertises relayed address at the Rendezvous node.
5+
- Local nodes discovers other local nodes via mDNS discovery and attempts direct connection.
6+
- Local nodes discovers other remote nodes via Rendezvous discovery and attempts hole punched connectioned.
37

4-
## Run local only
5-
This examples shows how to run two sessions locally and connect sessions by manually dialing local peer.
6-
7-
Run first chat session in echo mode.
8-
```
9-
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
10-
```
11-
12-
Run second chat session in interactive mode with local peer dial.
13-
```
14-
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
15-
```
16-
17-
In the interactive session publish new message manually:
18-
```
19-
publish calimero-network/examples/chat/v0.0.1 ola
20-
```
21-
22-
## Run locally with remote peer dial in
23-
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).
24-
25-
Additional info:
26-
- Remote instance is running in a private subnet behind NAT.
27-
- Remote instance PeerId: `12D3KooWP285Hw3CSTdr9oU6Ezz4hDoi6XS5vfDjjNeTJ1uFMGvp`
28-
- Remote instance address at the relay server: `ip4/3.71.239.80/udp/4001/quic-v1/p2p/12D3KooWAgFah4EZtWnMMGMUddGdJpb5cq2NubNCAD2jA5AZgbXF/p2p-circuit/p2p/12D3KooWP285Hw3CSTdr9oU6Ezz4hDoi6XS5vfDjjNeTJ1uFMGvp`
8+
## Run
299
Run first chat session in interactive mode with remote peer dial.
3010
```
31-
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
11+
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
3212
```
3313

3414
Run second chat session in interactive mode with remote peer dial.
3515
```
36-
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
16+
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
3717
```
3818

3919
In any interactive session publish new message manually:
4020
```
41-
publish calimero-network/examples/chat/v0.0.1 ola
21+
publish calimero-network/examples/chat/v0.0.2 ola
4222
```
4323

4424
## Debugging and known issues

examples/chat/src/main.rs

+15-20
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ struct Opt {
3131

3232
/// The listening address of a relay server to connect to.
3333
#[clap(long)]
34-
relay_address: Multiaddr,
34+
boot_nodes: Vec<Multiaddr>,
35+
36+
/// The listening address of a relay server to connect to.
37+
#[clap(long, default_value = "/calimero/devnet/examples/chat")]
38+
rendezvous_namespace: String,
3539

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

6468
let keypair = generate_ed25519(opt.secret_key_seed);
6569

66-
let (network_client, mut network_events) =
67-
network::run(keypair.clone(), opt.port, opt.relay_address.clone()).await?;
70+
let (network_client, mut network_events) = network::run(
71+
keypair.clone(),
72+
opt.port,
73+
libp2p::rendezvous::Namespace::new(opt.rendezvous_namespace)?,
74+
opt.boot_nodes.clone(),
75+
opt.boot_nodes.clone(),
76+
)
77+
.await?;
6878

6979
if let Some(peer_addrs) = opt.dial_peer_addrs {
7080
for addr in peer_addrs {
@@ -128,18 +138,6 @@ async fn handle_network_event(
128138
is_echo: bool,
129139
) -> eyre::Result<()> {
130140
match event {
131-
network::types::NetworkEvent::IdentifySent { peer_id } => {
132-
debug!("Identify sent to {:?}", peer_id);
133-
}
134-
network::types::NetworkEvent::IdentifyReceived {
135-
peer_id,
136-
observed_addr,
137-
} => {
138-
debug!(
139-
"Identify received from {:?} at {:?}",
140-
peer_id, observed_addr
141-
);
142-
}
143141
network::types::NetworkEvent::Message { message, .. } => {
144142
let text = String::from_utf8_lossy(&message.data);
145143
println!("{LINE_START} Received message: {:?}", text);
@@ -166,9 +164,6 @@ async fn handle_network_event(
166164
network::types::NetworkEvent::ListeningOn { address, .. } => {
167165
info!("Listening on: {}", address);
168166
}
169-
event => {
170-
info!("Unhandled event: {:?}", event);
171-
}
172167
}
173168
Ok(())
174169
}

0 commit comments

Comments
 (0)