secret_rotation/
secret_rotation.rs1use anyhow::Result;
2use iroh::{Endpoint, SecretKey};
3use iroh_gossip::{api::Event, net::Gossip};
4use sha2::Digest;
5
6use distributed_topic_tracker::{
8 AutoDiscoveryBuilder, AutoDiscoveryGossip, SecretRotation, TopicId,
9};
10
11
12#[derive(Debug, Clone, Copy)]
13struct MySecretRotation;
14
15impl SecretRotation for MySecretRotation {
16 fn get_unix_minute_secret(
17 &self,
18 topic_hash: [u8; 32],
19 unix_minute: u64,
20 initial_secret_hash: [u8; 32],
21 ) -> [u8; 32] {
22 let mut hash = sha2::Sha512::new();
23 hash.update(topic_hash);
24 hash.update(unix_minute.to_be_bytes());
25 hash.update(initial_secret_hash);
26 hash.update(b"as long as you return 32 bytes this is a valid secret rotation function");
27 hash.finalize()[..32].try_into().expect("hashing failed")
28 }
29}
30
31impl Default for MySecretRotation {
32 fn default() -> Self {
33 Self {}
34 }
35}
36
37
38#[tokio::main]
39async fn main() -> Result<()> {
40 let secret_key = SecretKey::generate(rand::rngs::OsRng);
42
43 let endpoint = Endpoint::builder()
45 .secret_key(secret_key)
46 .discovery_n0()
47 .bind()
48 .await?;
49
50 let gossip = Gossip::builder()
52 .spawn_with_auto_discovery::<MySecretRotation>(endpoint.clone(), None)
53 .await?;
54
55 let _router = iroh::protocol::Router::builder(endpoint.clone())
57 .accept(iroh_gossip::ALPN, gossip.gossip.clone())
58 .spawn();
59
60 let topic_id = TopicId::new("my-iroh-gossip-topic".to_string());
61 let initial_secret = b"my-initial-secret".to_vec();
62
63 let (sink, mut stream) = gossip
65 .subscribe_and_join_with_auto_discovery(topic_id, &initial_secret)
66 .await?
67 .split();
68
69 println!("Joined topic");
70
71 tokio::spawn(async move {
73 while let Ok(event) = stream.recv().await {
74 if let Event::Received(msg) = event {
75 println!(
76 "\nMessage from {}: {}",
77 &msg.delivered_from.to_string()[0..8],
78 String::from_utf8(msg.content.to_vec()).unwrap()
79 );
80 } else if let Event::NeighborUp(peer) = event {
81 println!("\nJoined by {}", &peer.to_string()[0..8]);
82 }
83 }
84 });
85
86 let mut buffer = String::new();
88 let stdin = std::io::stdin();
89 loop {
90 print!("\n> ");
91 stdin.read_line(&mut buffer).unwrap();
92 sink.broadcast(buffer.clone().replace("\n", "").into())
93 .await
94 .unwrap();
95 print!(" - (sent)\n");
96 buffer.clear();
97 }
98}