Skip to main content

iroh_gossip_rendezvous/
lib.rs

1//! # iroh-gossip-rendezvous
2//!
3//! Passphrase-based peer rendezvous for [`iroh-gossip`] swarms, using the
4//! BitTorrent [Mainline DHT] as an out-of-band meeting place.
5//!
6//! Two nodes that share a passphrase and an application salt can find each
7//! other and join the same gossip topic with no central bootstrap server and
8//! no prior knowledge of each other's network address.
9//!
10//! ```no_run
11//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
12//! use iroh_gossip_rendezvous::Rendezvous;
13//!
14//! let rendezvous = Rendezvous::join("my-passphrase", "my-app/v1").await?;
15//! rendezvous.broadcast(bytes::Bytes::from_static(b"hello")).await?;
16//!
17//! let mut receiver = rendezvous.subscribe();
18//! while let Ok(event) = receiver.recv().await {
19//!     // handle event (iroh_gossip::api::Event)
20//!     drop(event);
21//! }
22//! # Ok(()) }
23//! ```
24//!
25//! The algorithm is a clock-free variant of a HyParView-healing protocol with
26//! K-sharded slots, logical aging, vouching, and a two-layer AEAD record
27//! format. See `dht-partition-healing.md` in the repository for the design
28//! specification and `examples/simulator.rs` for validation scaffolding.
29//!
30//! ## Lifetime
31//!
32//! The returned [`Rendezvous`] is the keep-alive anchor for the DHT
33//! maintenance loops. Dropping it cancels the loops and the swarm will
34//! slowly drift off the DHT as entries age out. Any [`iroh_gossip::api::GossipSender`]
35//! or [`iroh_gossip::api::GossipReceiver`] extracted from the handle via
36//! [`Rendezvous::sender`] or [`Rendezvous::subscribe`] must be dropped
37//! before — or kept alongside — the [`Rendezvous`].
38//!
39//! [`iroh-gossip`]: https://docs.rs/iroh-gossip
40//! [Mainline DHT]: https://en.wikipedia.org/wiki/Mainline_DHT
41
42#![cfg_attr(docsrs, feature(doc_cfg))]
43
44mod builder;
45mod crypto;
46mod dht;
47mod error;
48mod gossip_glue;
49mod keys;
50mod merge;
51mod protocol;
52mod rendezvous;
53mod state;
54mod wire;
55
56#[cfg(feature = "sim")]
57#[cfg_attr(docsrs, doc(cfg(feature = "sim")))]
58#[allow(clippy::module_name_repetitions)]
59mod sim_impl;
60
61// Kani bounded-model-checking harnesses. Gated on the `kani` cfg (set
62// automatically by `cargo kani`), so regular builds never see them.
63#[cfg(kani)]
64mod kani_proofs;
65
66pub use builder::Builder;
67pub use error::{Error, Result};
68pub use rendezvous::Rendezvous;
69pub use state::{DhtStatus, RendezvousState};
70
71/// Algorithm defaults, one per `§2` parameter of [`PROTOCOL.md`].
72///
73/// All defaults are overridable via [`Builder`]. The constants are re-exported
74/// here so callers (and the `tests/spec_drift.rs` consistency check) can
75/// reference them without poking at private modules.
76///
77/// [`PROTOCOL.md`]: https://github.com/swaits/iroh-gossip-rendezvous/blob/main/PROTOCOL.md
78pub mod defaults {
79    pub use crate::builder::{
80        DEFAULT_EPOCH_WRITES, DEFAULT_HEAL_PERIOD, DEFAULT_JITTER, DEFAULT_MAX_AGE,
81        DEFAULT_MAX_ENTRIES, DEFAULT_MAX_VOUCHES, DEFAULT_SHARDS, DEFAULT_WRITE_PERIOD,
82    };
83}
84
85/// Discrete-event simulator + DHT-backend surface.
86///
87/// Gated behind the `sim` feature flag. See [`sim::run`] and
88/// [`sim::Scenario`] for the simulator entry points used by
89/// `examples/simulator.rs`. [`sim::InMemoryDht`], [`sim::DhtSlots`],
90/// [`sim::SlotKey`], [`sim::SlotRecord`], and [`sim::DhtError`] are
91/// exposed here for third-party DHT backend implementations and for
92/// integration tests that inject a custom backend via
93/// [`Builder::dht_backend`] (under the `test-support` feature).
94///
95/// Not part of the stable public API; function signatures and item layout
96/// may shift between `0.x` releases as simulation results move the defaults.
97#[cfg(feature = "sim")]
98#[cfg_attr(docsrs, doc(cfg(feature = "sim")))]
99pub mod sim {
100    pub use crate::sim_impl::{
101        ENTRY_LEN, Entry, MAX_ENTRIES, Outcome, PubDhtError as DhtError, PubDhtSlots as DhtSlots,
102        PubInMemoryDht as InMemoryDht, PubSlotKey as SlotKey, Scenario, SimConfig, SlotRecord,
103        decode_entries, encode_entries, run,
104    };
105}