use std::collections::HashMap;
use vrf_pbft::{Config, ConsensusEngine, Node};
fn main() {
let config = Config::new(3); let mut engine = ConsensusEngine::new(config);
let weights = [500, 300, 200, 150, 100, 100, 80, 60, 40, 20];
for (i, &w) in weights.iter().enumerate() {
let node = Node::new((i + 1) as u64, w).expect("failed to create node");
engine.add_node(node);
}
let total_rounds = 100;
println!(
"Simulating {} rounds with {} nodes (f=3)\n",
total_rounds,
weights.len()
);
println!(
"Node weights: {:?}",
weights
);
println!("Total weight: {}\n", weights.iter().sum::<u64>());
let blocks = engine.run(total_rounds).expect("simulation failed");
let mut proposer_count: HashMap<u64, u32> = HashMap::new();
for block in &blocks {
*proposer_count.entry(block.proposer).or_default() += 1;
}
println!("Results:");
println!(" Rounds attempted: {}", engine.round());
println!(" Blocks committed: {}", blocks.len());
println!(
" Success rate: {:.1}%",
blocks.len() as f64 / engine.round() as f64 * 100.0
);
println!("\nProposer distribution:");
let mut sorted: Vec<_> = proposer_count.iter().collect();
sorted.sort_by_key(|(id, _)| *id);
for (id, count) in sorted {
let w = weights[(*id - 1) as usize];
println!(" Node {} (weight {:>3}): {} blocks", id, w, count);
}
let ledger_lens: Vec<usize> = engine.nodes().iter().map(|n| n.ledger().len()).collect();
let all_same = ledger_lens.windows(2).all(|w| w[0] == w[1]);
println!(
"\nLedger consistency: {} (all nodes have {} blocks)",
if all_same { "PASS" } else { "FAIL" },
ledger_lens[0]
);
}