use cid::Cid;
use ipfrs_network::{NetworkConfig, NetworkNode};
use std::str::FromStr;
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("=== DHT Operations Example ===\n");
let config = NetworkConfig::default();
println!("Creating and starting network node...");
let mut node = NetworkNode::new(config)?;
node.start().await?;
println!("Node peer ID: {}", node.peer_id());
println!("Listening addresses:");
for addr in node.listeners() {
println!(" {}", addr);
}
println!("\nWaiting for node to initialize and bootstrap...");
sleep(Duration::from_secs(3)).await;
println!("\nBootstrapping DHT...");
node.bootstrap_dht().await?;
sleep(Duration::from_secs(2)).await;
println!("\n--- Scenario 1: Announce Content to DHT ---");
let test_cid_str = "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi";
let cid = Cid::from_str(test_cid_str)?;
println!("Announcing content with CID: {}", cid);
node.provide(&cid).await?;
println!("Content announced! This node is now a provider for this CID.");
println!("Other nodes can find this content by querying the DHT.");
sleep(Duration::from_secs(2)).await;
println!("\n--- Scenario 2: Find Providers for Content ---");
println!("Searching for providers of CID: {}", cid);
println!("(Note: Results will come through events)");
node.find_providers(&cid).await?;
sleep(Duration::from_secs(2)).await;
println!("\n--- Scenario 3: DHT Node Lookup ---");
let target_peer = node.peer_id();
println!("Looking up peer: {}", target_peer);
println!("(Note: Results will come through events)");
node.find_node(target_peer).await?;
sleep(Duration::from_secs(2)).await;
println!("\n--- Scenario 4: Routing Table Information ---");
let rt_info = node.get_routing_table_info()?;
println!("Routing table:");
println!(" Total peers: {}", rt_info.total_peers);
println!(" Number of buckets: {}", rt_info.num_buckets);
if !rt_info.buckets.is_empty() {
println!("\n Bucket details (first 5):");
for bucket in rt_info.buckets.iter().take(5) {
println!(" Bucket {}: {} peers", bucket.index, bucket.num_entries);
}
}
println!("\n--- Scenario 5: Get Closest Local Peers ---");
println!("Querying for closest peers to our local peer ID...");
match node.get_closest_local_peers().await {
Ok(peers) => {
println!("Found {} closest peers:", peers.len());
for (i, peer) in peers.iter().take(5).enumerate() {
println!(" {}. {}", i + 1, peer);
}
}
Err(e) => {
println!("Error getting closest peers: {}", e);
}
}
println!("\n--- Scenario 6: Announce Multiple Content Items ---");
let cids = [
"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"bafybeihkoviema7g3gxyt6la7vd5ho32ictqbilu3wnlo3rs7ewhnp7lly",
"bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku",
];
println!("Announcing {} content items...", cids.len());
for (i, cid_str) in cids.iter().enumerate() {
if let Ok(cid) = Cid::from_str(cid_str) {
println!(" {}: {}", i + 1, cid);
if let Err(e) = node.provide(&cid).await {
println!(" Error: {}", e);
} else {
println!(" Announced successfully");
}
sleep(Duration::from_millis(500)).await;
}
}
println!("\n--- Final Statistics ---");
let stats = node.stats();
println!("Connected peers: {}", stats.connected_peers);
println!("Bytes sent: {}", stats.bytes_sent);
println!("Bytes received: {}", stats.bytes_received);
let rt_info = node.get_routing_table_info()?;
println!("Routing table peers: {}", rt_info.total_peers);
println!("\nDHT operations complete!");
node.stop().await?;
Ok(())
}