Skip to main content

full_config/
full_config.rs

1use std::time::Duration;
2
3use anyhow::Result;
4use ed25519_dalek::SigningKey;
5use iroh::{Endpoint, SecretKey};
6use iroh_gossip::net::Gossip;
7
8// Imports from distributed-topic-tracker
9use distributed_topic_tracker::{
10    AutoDiscoveryGossip, BootstrapConfig, BubbleMergeConfig, Config, DefaultSecretRotation,
11    DhtConfig, MergeConfig, MessageOverlapMergeConfig, PublisherConfig, RecordPublisher,
12    RotationHandle, TimeoutConfig, TopicId,
13};
14
15// Default configuration, all in one spot as an overview
16// same as `Config::default()`
17fn config_builder() -> Config {
18    Config::builder()
19        .dht_config(
20            DhtConfig::builder()
21                .retries(3)
22                .base_retry_interval(Duration::from_secs(5))
23                .max_retry_jitter(Duration::from_secs(10))
24                .get_timeout(Duration::from_secs(10))
25                .put_timeout(Duration::from_secs(10))
26                .build(),
27        )
28        .bootstrap_config(
29            BootstrapConfig::builder()
30                .max_bootstrap_records(5)
31                .publish_record_on_startup(true)
32                .check_older_records_first_on_startup(false)
33                .discovery_poll_interval(Duration::from_millis(2000))
34                .no_peers_retry_interval(Duration::from_millis(1500))
35                .per_peer_join_settle_time(Duration::from_millis(100))
36                .join_confirmation_wait_time(Duration::from_millis(500))
37                .build(),
38        )
39        .max_join_peer_count(4)
40        .publisher_config(
41            PublisherConfig::builder()
42                .initial_delay(Duration::from_secs(10))
43                .base_interval(Duration::from_secs(10))
44                .max_jitter(Duration::from_secs(50))
45                .build(),
46        )
47        .merge_config(
48            MergeConfig::builder()
49                .bubble_merge(
50                    BubbleMergeConfig::builder()
51                        .min_neighbors(4)
52                        .initial_interval(Duration::from_secs(30))
53                        .base_interval(Duration::from_secs(60))
54                        .max_jitter(Duration::from_secs(120))
55                        .fail_topic_creation_on_merge_startup_failure(true)
56                        .max_join_peers(2)
57                        .build(),
58                )
59                .message_overlap_merge(
60                    MessageOverlapMergeConfig::builder()
61                        .initial_interval(Duration::from_secs(30))
62                        .base_interval(Duration::from_secs(60))
63                        .max_jitter(Duration::from_secs(120))
64                        .fail_topic_creation_on_merge_startup_failure(true)
65                        .max_join_peers(2)
66                        .build(),
67                )
68                .build(),
69        )
70        .timeouts(
71            TimeoutConfig::builder()
72                .join_peer_timeout(Duration::from_secs(5))
73                .broadcast_neighbors_timeout(Duration::from_secs(5))
74                .broadcast_timeout(Duration::from_secs(5))
75                .build(),
76        )
77        .build()
78}
79
80#[tokio::main]
81async fn main() -> Result<()> {
82    // Generate a new random secret key
83    let secret_key = SecretKey::generate();
84    let signing_key = SigningKey::from_bytes(&secret_key.to_bytes());
85
86    // Set up endpoint with discovery enabled
87    let endpoint = Endpoint::builder(iroh::endpoint::presets::N0)
88        .secret_key(secret_key.clone())
89        .bind()
90        .await?;
91
92    // Initialize gossip with auto-discovery
93    let gossip = Gossip::builder().spawn(endpoint.clone());
94
95    // Set up protocol router
96    let _router = iroh::protocol::Router::builder(endpoint.clone())
97        .accept(iroh_gossip::ALPN, gossip.clone())
98        .spawn();
99
100    let topic_id = TopicId::new("my-iroh-gossip-topic".to_string());
101    let initial_secret = b"my-initial-secret".to_vec();
102
103    let record_publisher =
104        RecordPublisher::builder(topic_id.clone(), signing_key.clone(), initial_secret)
105            .config(config_builder())
106            .secret_rotation(RotationHandle::new(DefaultSecretRotation))
107            .build();
108
109    let topic = gossip
110        .subscribe_and_join_with_auto_discovery(record_publisher)
111        .await?;
112
113    println!("[joined topic]");
114
115    // Do something with the gossip topic
116    // (bonus: GossipSender and GossipReceiver are safely clonable)
117    let (_gossip_sender, _gossip_receiver) = topic.split().await?;
118
119    Ok(())
120}