Distributed Topic Tracker?
The Distributed Topic Tracker addresses the challenge of enabling iroh-gossip peers to discover each other during initial and continuous bootstrap.
A key property of the system is that it operates from a cold start, requiring no prior knowledge, no custom servers, and no centralized control.
The Mainline approach was developed as a solution to this problem. Detailed specifications of the system are provided in the Protocol and Architecture documents.
Repository: https://github.com/rustonbsd/distributed-topic-tracker
distributed-topic-tracker
Decentralized auto Bootstraping for iroh-gossip topic’s via the mainline Bittorrent DHT.
Quick start
Add dependencies (names subject to final crate publish):
[dependencies]
anyhow = "1"
tokio = "1"
iroh = "*"
iroh-gossip = "*"
distributed-topic-tracker = "0.1.5"
Simple iroh-gossip integration example:
use anyhow::Result;
use iroh::{Endpoint, SecretKey};
use iroh_gossip::net::Gossip;
// Imports from distrubuted-topic-tracker
use distributed_topic_tracker::{AutoDiscoveryGossip, RecordPublisher, TopicId};
#[tokio::main]
async fn main() -> Result<()> {
// Generate a new random secret key
let secret_key = SecretKey::generate(rand::rngs::OsRng);
// Set up endpoint with discovery enabled
let endpoint = Endpoint::builder()
.secret_key(secret_key.clone())
.discovery_n0()
.bind()
.await?;
// Initialize gossip with auto-discovery
let gossip = Gossip::builder().spawn(endpoint.clone());
// Set up protocol router
let _router = iroh::protocol::Router::builder(endpoint.clone())
.accept(iroh_gossip::ALPN, gossip.clone())
.spawn();
// [Distributed Topic Tracker]
let topic_id = TopicId::new("my-iroh-gossip-topic".to_string());
let initial_secret = b"my-initial-secret".to_vec();
let record_publisher = RecordPublisher::new(
topic_id.clone(),
endpoint.node_id(),
secret_key.secret().clone(),
None,
initial_secret,
);
// A new field "subscribe_and_join_with_auto_discovery/_no_wait"
// is available on iroh_gossip::net::Gossip
let topic = gossip
.subscribe_and_join_with_auto_discovery(record_publisher)
.await?;
println!("[joined topic]");
// Do something with the gossip topic
// (bonus: GossipSender and GossipReceiver are safely clonable)
let (_gossip_sender, _gossip_receiver) = topic.split().await?;
Ok(())
}
Protocol Info
- Protocol details (spec): PROTOCOL.md
- Architecture (illustrative): ARCHITECTURE.md
- Feedback issue: https://github.com/rustonbsd/distributed-topic-tracker-exp/issues/5
Features
- Fully decentralized bootstrap for iroh-gossip
- Ed25519-based signing and hpke shared-secret-based encryption
- DHT rate limiting (caps per-minute records)
- Resilient bootstrap with retries and jitter
- Background publisher with bubble detection and peer merging
Testing
Unit Tests
Run unit tests for core components:
cargo test
End-to-End Tests
Test peer discovery across multiple Docker containers:
# Requires Docker and Docker Compose
./test-e2e.sh
The e2e test verifies that multiple nodes can discover each other through the DHT and successfully join the same gossip topic.
Roadmap
- Finalize crate name and publish to crates.io
- Tests and CI
- Add more examples
- Optimize configuration settings
- Major refactor
- Docs (api)
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
- Try it, then drop feedback: https://github.com/rustonbsd/distributed-topic-tracker-exp/issues/5
- PRs, issue and success reports welcome.
Unless explicitly stated, any contribution intentionally submitted for inclusion in this project shall be dual-licensed as above, without any additional terms or conditions.