1use std::collections::HashMap;
2use vrf_pbft::{Config, ConsensusEngine, Node};
3
4fn main() {
5 let config = Config::new(3); let mut engine = ConsensusEngine::new(config);
7
8 let weights = [500, 300, 200, 150, 100, 100, 80, 60, 40, 20];
10 for (i, &w) in weights.iter().enumerate() {
11 let node = Node::new((i + 1) as u64, w).expect("failed to create node");
12 engine.add_node(node);
13 }
14
15 let total_rounds = 100;
16 println!(
17 "Simulating {} rounds with {} nodes (f=3)\n",
18 total_rounds,
19 weights.len()
20 );
21 println!(
22 "Node weights: {:?}",
23 weights
24 );
25 println!("Total weight: {}\n", weights.iter().sum::<u64>());
26
27 let blocks = engine.run(total_rounds).expect("simulation failed");
28
29 let mut proposer_count: HashMap<u64, u32> = HashMap::new();
31 for block in &blocks {
32 *proposer_count.entry(block.proposer).or_default() += 1;
33 }
34
35 println!("Results:");
36 println!(" Rounds attempted: {}", engine.round());
37 println!(" Blocks committed: {}", blocks.len());
38 println!(
39 " Success rate: {:.1}%",
40 blocks.len() as f64 / engine.round() as f64 * 100.0
41 );
42
43 println!("\nProposer distribution:");
44 let mut sorted: Vec<_> = proposer_count.iter().collect();
45 sorted.sort_by_key(|(id, _)| *id);
46 for (id, count) in sorted {
47 let w = weights[(*id - 1) as usize];
48 println!(" Node {} (weight {:>3}): {} blocks", id, w, count);
49 }
50
51 let ledger_lens: Vec<usize> = engine.nodes().iter().map(|n| n.ledger().len()).collect();
53 let all_same = ledger_lens.windows(2).all(|w| w[0] == w[1]);
54 println!(
55 "\nLedger consistency: {} (all nodes have {} blocks)",
56 if all_same { "PASS" } else { "FAIL" },
57 ledger_lens[0]
58 );
59}