Discover peers
Activate signed presence beacons or local-link mDNS with a bounded peer book and automatic dialing.
Choose the source that matches where peers meet:
- Use mDNS for peers on the same local network.
- Use signed discovery when peers already share a pubsub mesh.
- Enable both when the application needs both sources.
Both sources feed one bounded peer book and one automatic-dial policy.
Enable signed discovery
cargo add minip2p-rs --features discovery
Signed discovery publishes application-scoped presence beacons over pubsub:
let mut node = minip2p::Endpoint::builder()
.discovery()
.bind_quic_dual_stack()?;
node.listen_all()?;
.discovery_config(...) selects a custom topic, publication cadence, and
announcement limit. Tune the shared address book and dial policy with
.peer_discovery_config(...).
Discovery can dial direct addresses announced by other peers without a relay. A configured relay is still required for relay circuits, reservations, and relay-assisted hole punching:
let node = minip2p::Endpoint::builder()
.relay(relay)
.discovery()
.bind_quic_dual_stack()?;
Enable local mDNS
cargo add minip2p-rs --features mdns
Then enable it on the endpoint:
let node = minip2p::Endpoint::builder()
.mdns()
.bind_quic_dual_stack()?;
mDNS needs no pubsub or relay. Its observations are unauthenticated until the
transport verifies the remote peer, and its automatic dials remain direct-only.
KnownPeer::beacon_addrs and KnownPeer::mdns_addrs show where each address
came from.
Enable both methods on the same builder when the application needs LAN and pubsub-based discovery.
How peers appear
Each endpoint periodically publishes a signed beacon containing its current dialable address snapshot. Discovery:
- verifies the beacon identity and signature;
- normalizes and bounds the advertised addresses;
- updates the TTL-based known-peer book;
- starts or cancels NAT-aware dials according to discovery policy.
Address-less beacons can refresh peer presence without starting a dial. Wildcard listen addresses are filtered because another peer cannot dial them.
Observe the address book
for peer in node.known_peers() {
println!(
"peer={} connected={} addresses={:?}",
peer.peer,
peer.connected,
peer.addrs,
);
}
for event in node.take_discovery_events() {
println!("{event:?}");
}
DiscoveryEvent reports peers being discovered, updated, or expired, plus
automatic dial failures and rejected beacons. Use
next_discovery_event(deadline) when a synchronous loop wants one focused
event.
Customize policy
use minip2p::{BeaconConfig, Endpoint, PeerDiscoveryConfig};
let beacon = BeaconConfig {
topic: "my-app/discovery/v1".into(),
..BeaconConfig::default()
};
let policy = PeerDiscoveryConfig {
max_known_peers: 256,
..PeerDiscoveryConfig::default()
};
let node = Endpoint::builder()
.discovery_config(beacon)?
.peer_discovery_config(policy)?
.bind_quic_dual_stack()?;
BeaconConfig controls the pubsub topic, cadence, and local announcement cap.
PeerDiscoveryConfig is shared by signed discovery and mDNS; it controls peer
and address bounds, source TTLs, automatic dialing, tie breaking, retry
backoff, and mDNS dial-rate limits. Invalid bounds are rejected before a socket
is allocated.
For a complete mesh demonstration, use the existing
minip2p-chat example.
It combines discovery, gossipsub, relay circuits, and direct upgrades.