mina_node_testing/scenarios/solo_node/
basic_connectivity_initial_joining.rs1#![allow(warnings)]
2
3use std::{collections::HashMap, time::Duration};
4
5use libp2p::Multiaddr;
6
7use node::{
8 core::log::{debug, system_time},
9 p2p::connection::outgoing::P2pConnectionOutgoingInitOpts,
10};
11
12use crate::{
13 hosts,
14 node::RustNodeTestingConfig,
15 scenario::{ListenerNode, ScenarioStep},
16 scenarios::ClusterRunner,
17};
18
19#[derive(documented::Documented, Default, Clone, Copy)]
26pub struct SoloNodeBasicConnectivityInitialJoining;
27
28impl SoloNodeBasicConnectivityInitialJoining {
29 pub async fn run(self, mut runner: ClusterRunner<'_>) {
30 std::env::set_var("MINA_DISCOVERY_FILTER_ADDR", "true");
31 const MAX_PEERS_PER_NODE: usize = 100;
32 const KNOWN_PEERS: usize = 5; const STEPS: usize = 3_000;
34 const STEP_DELAY: Duration = Duration::from_millis(200);
35
36 let initial_peers = hosts::devnet();
37 eprintln!("set max peers per node: {MAX_PEERS_PER_NODE}");
38 for seed in &initial_peers {
39 eprintln!("add initial peer: {seed:?}");
40 }
41 let config = RustNodeTestingConfig::devnet_default()
42 .max_peers(MAX_PEERS_PER_NODE)
43 .initial_peers(initial_peers);
44
45 let node_id = runner.add_rust_node(config);
46 let peer_id = libp2p::PeerId::try_from(
47 runner
48 .node(node_id)
49 .expect("must exist")
50 .state()
51 .p2p
52 .my_id(),
53 )
54 .unwrap();
55 eprintln!("launch Mina Rust node, id: {node_id}, peer_id: {peer_id}");
56
57 for step in 0..STEPS {
58 tokio::time::sleep(STEP_DELAY).await;
59
60 let steps = runner
61 .pending_events(true)
62 .map(|(node_id, _, events)| {
63 events.map(move |(_, event)| ScenarioStep::Event {
64 node_id,
65 event: event.to_string(),
66 })
67 })
68 .flatten()
69 .collect::<Vec<_>>();
70
71 for step in steps {
72 runner.exec_step(step).await.unwrap();
73 }
74
75 runner
76 .exec_step(ScenarioStep::AdvanceNodeTime {
77 node_id,
78 by_nanos: STEP_DELAY.as_nanos() as _,
79 })
80 .await
81 .unwrap();
82
83 runner
84 .exec_step(ScenarioStep::CheckTimeouts { node_id })
85 .await
86 .unwrap();
87
88 let node = runner.node(node_id).expect("must exist");
89 let ready_peers = node.state().p2p.ready_peers_iter().count();
90 let my_id = node.state().p2p.my_id();
91 let known_peers: usize = node
92 .state()
93 .p2p
94 .ready()
95 .and_then(|p2p| p2p.network.scheduler.discovery_state())
96 .map_or(0, |discovery_state| {
97 discovery_state
98 .routing_table
99 .closest_peers(&my_id.try_into().unwrap())
100 .count()
101 });
102
103 println!("step: {step}");
104 println!("known peers: {known_peers}");
105 println!("connected peers: {ready_peers}");
106
107 if ready_peers >= KNOWN_PEERS && known_peers >= KNOWN_PEERS {
109 debug!(system_time(); "Step: {}, known peers: {}, connected peers: {}, success", step, known_peers, ready_peers);
110
111 if let Some(debugger) = runner.debugger() {
112 tokio::time::sleep(Duration::from_secs(10)).await;
113 let connections = debugger
114 .connections_raw(0)
115 .map(|(id, c)| (id, (c.info.addr, c.info.fd, c.info.pid, c.incoming)))
116 .collect::<HashMap<_, _>>();
117
118 for (id, cn) in &connections {
120 eprintln!("{id}: {}", serde_json::to_string(cn).unwrap());
121 }
122 for (id, msg) in debugger.messages(0, "") {
124 eprintln!("{id}: {}", serde_json::to_string(&msg).unwrap());
125 }
126 let connections = debugger
128 .connections()
129 .filter_map(|id| Some((id, connections.get(&id)?.clone())))
130 .collect::<HashMap<_, _>>();
131 let incoming = connections.iter().filter(|(_, (_, _, _, i))| *i).count();
132 let outgoing = connections.len() - incoming;
133 eprintln!(
134 "debugger seen {incoming} incoming connections and {outgoing} outgoing connections",
135 );
136 let state_machine_peers = if cfg!(feature = "p2p-webrtc") {
137 ready_peers
138 } else {
139 ready_peers.max(known_peers)
140 };
141 assert_eq!(
142 incoming + outgoing,
143 state_machine_peers,
144 "debugger must see the same number of connections as the state machine"
145 );
146 } else {
147 eprintln!("no debugger, run test with --use-debugger for additional check");
148 }
149
150 return;
151 }
152 }
153
154 panic!("timeout");
155 }
156}