mina_node_testing/scenarios/p2p/
kademlia.rs1use node::ActionKind;
2
3use crate::{
4 cluster::ClusterNodeId,
5 node::RustNodeTestingConfig,
6 scenario::ListenerNode,
7 scenarios::{
8 multi_node::connection_discovery::{
9 check_kademlia_entries, wait_for_identify, wait_for_node_ready,
10 },
11 ClusterRunner, RunCfg,
12 },
13};
14
15#[derive(documented::Documented, Default, Clone, Copy)]
23pub struct KademliaBootstrap;
24
25impl KademliaBootstrap {
26 pub async fn run(self, mut runner: ClusterRunner<'_>) {
27 std::env::set_var("MINA_DISCOVERY_FILTER_ADDR", "false");
28 const NUM: u8 = 16;
29
30 let seed_node = runner.add_rust_node(RustNodeTestingConfig::devnet_default());
31 wait_for_node_ready(&mut runner, seed_node).await;
32 let mut nodes = vec![];
33
34 let config = RustNodeTestingConfig {
35 initial_peers: vec![ListenerNode::Rust(seed_node)],
36 ..RustNodeTestingConfig::devnet_default()
37 };
38 std::env::set_var("MINA_DISCOVERY_FILTER_ADDR", "true");
39 for _ in 0..NUM {
40 let node_id = runner.add_rust_node(config.clone());
41 let peer_id = runner.node(node_id).expect("Node not found").peer_id();
42
43 nodes.push((node_id, peer_id));
44
45 wait_for_bootstrap(&mut runner, node_id).await;
46 wait_for_identify(&mut runner, seed_node, peer_id, "mina").await;
47 }
48
49 let peer_ids = nodes.iter().map(|node| node.1);
50 let seed_has_peers =
51 check_kademlia_entries(&mut runner, seed_node, peer_ids.clone()).unwrap_or_default();
52 assert!(
53 seed_has_peers,
54 "Seed doesn't have all peers in it's routing table"
55 );
56
57 std::env::set_var("MINA_DISCOVERY_FILTER_ADDR", "true");
58 let new_node = runner.add_rust_node(config);
59 let new_node_peer_id = runner.node(new_node).expect("Not note found").peer_id();
60
61 wait_for_bootstrap(&mut runner, new_node).await;
62 wait_for_identify(&mut runner, seed_node, new_node_peer_id, "mina").await;
63 let new_has_peers =
64 check_kademlia_entries(&mut runner, seed_node, peer_ids).unwrap_or_default();
65 assert!(
66 new_has_peers,
67 "Node doesn't have all peers in it's routing table"
68 );
69 }
70}
71
72async fn wait_for_bootstrap(runner: &mut ClusterRunner<'_>, node_id: ClusterNodeId) {
73 runner
74 .run(RunCfg::default().action_handler(move |node, _, _, action| {
75 node == node_id
76 && matches!(
77 action.action().kind(),
78 ActionKind::P2pNetworkKademliaBootstrapFinished
79 )
80 }))
81 .await
82 .expect("Node failed to bootstrap")
83}