1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
//! Multi-node network example (equivalent to example2.cpp).
//!
//! Creates N nodes on localhost, joins them recursively
//! via the first node, then prints state periodically.
//!
//! Usage:
//! cargo run --example network
//! RUST_LOG=debug cargo run --example network
use std::time::{Duration, Instant};
use tesseras_dht::Node;
use tesseras_dht::nat::NatState;
const NUM_NODES: usize = 20;
const POLL_ROUNDS: usize = 30;
fn main() {
env_logger::Builder::from_env(
env_logger::Env::default().default_filter_or("info"),
)
.format(|buf, record| {
use std::io::Write;
writeln!(
buf,
"{} [{}] {}",
record.level(),
record.target(),
record.args()
)
})
.init();
println!("Creating {NUM_NODES} nodes...");
let start = Instant::now();
// Create bootstrap node
let mut nodes: Vec<Node> = Vec::new();
let bootstrap = Node::bind(0).expect("bind bootstrap");
let bootstrap_port = bootstrap.local_addr().unwrap().port();
println!("Bootstrap: {} @ port {bootstrap_port}", bootstrap.id_hex());
nodes.push(bootstrap);
// Create and join remaining nodes
for i in 1..NUM_NODES {
let mut node = Node::bind(0).expect("bind node");
node.set_nat_state(NatState::Global);
node.join("127.0.0.1", bootstrap_port).expect("join");
println!("Node {i}: {} joined", &node.id_hex()[..8]);
nodes.push(node);
}
nodes[0].set_nat_state(NatState::Global);
println!("\nAll {NUM_NODES} nodes created in {:?}", start.elapsed());
// Poll all nodes to exchange messages
println!("\nPolling {POLL_ROUNDS} rounds...");
for round in 0..POLL_ROUNDS {
for node in nodes.iter_mut() {
node.poll().ok();
}
std::thread::sleep(Duration::from_millis(50));
if (round + 1) % 10 == 0 {
let sizes: Vec<usize> =
nodes.iter().map(|n| n.routing_table_size()).collect();
let avg = sizes.iter().sum::<usize>() / sizes.len();
let max = sizes.iter().max().unwrap();
println!(
" Round {}: avg routing table = {avg}, max = {max}",
round + 1
);
}
}
// Print final state
println!("\n--- Final state ---");
for (i, node) in nodes.iter().enumerate() {
println!(
"Node {i}: {} | rt={} peers={} storage={}",
&node.id_hex()[..8],
node.routing_table_size(),
node.peer_count(),
node.storage_count(),
);
}
}
|