mina_node_testing/scenarios/solo_node/
basic_connectivity_accept_incoming.rs

1#![allow(warnings)]
2
3use std::time::Duration;
4
5use libp2p::Multiaddr;
6use node::{
7    core::log::{debug, system_time},
8    p2p::{connection::outgoing::P2pConnectionOutgoingInitOpts, PeerId},
9};
10use rand::Rng;
11
12use crate::{
13    hosts,
14    node::{DaemonJson, OcamlNodeTestingConfig, RustNodeTestingConfig},
15    scenario::{ListenerNode, ScenarioStep},
16    scenarios::ClusterRunner,
17};
18
19/// Local test to ensure that the Rust node can accept a connection from an existing OCaml node.
20/// Launch an Rust node and connect it to seed nodes of the public (or private) OCaml testnet.
21/// Wait for the Rust node to complete peer discovery.
22/// Run a new OCaml node, specifying the Rust node under testing as the initial peer.
23/// Run the simulation until: OCaml node connects to Rust node and Rust node accepts the incoming
24/// connection.
25/// Fail the test if the specified number of steps occur but the condition is not met.
26#[derive(documented::Documented, Default, Clone, Copy)]
27pub struct SoloNodeBasicConnectivityAcceptIncoming;
28
29impl SoloNodeBasicConnectivityAcceptIncoming {
30    pub async fn run(self, mut runner: ClusterRunner<'_>) {
31        const MAX_PEERS_PER_NODE: usize = 100;
32        const KNOWN_PEERS: usize = 7; // current devnet network
33        const STEPS: usize = 6_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            .with_peer_id(rand::thread_rng().gen());
45
46        let node_id = runner.add_rust_node(config);
47        let node_addr = runner.node(node_id).unwrap().dial_addr();
48
49        eprintln!("launch Rust node, id: {node_id}, addr: {node_addr}");
50
51        let mut ocaml_node = None::<PeerId>;
52
53        for step in 0..STEPS {
54            tokio::time::sleep(STEP_DELAY).await;
55
56            let steps = runner
57                .pending_events(true)
58                .map(|(node_id, _, events)| {
59                    events.map(move |(_, event)| ScenarioStep::Event {
60                        node_id,
61                        event: event.to_string(),
62                    })
63                })
64                .flatten()
65                .collect::<Vec<_>>();
66
67            for step in steps {
68                runner.exec_step(step).await.unwrap();
69            }
70
71            runner
72                .exec_step(ScenarioStep::AdvanceNodeTime {
73                    node_id,
74                    by_nanos: STEP_DELAY.as_nanos() as _,
75                })
76                .await
77                .unwrap();
78
79            runner
80                .exec_step(ScenarioStep::CheckTimeouts { node_id })
81                .await
82                .unwrap();
83
84            let node = runner.node(node_id).expect("must exist");
85            let ready_peers = node.state().p2p.ready_peers_iter().count();
86            let my_id = node.state().p2p.my_id();
87            let known_peers: usize = node
88                .state()
89                .p2p
90                .ready()
91                .and_then(|p2p| p2p.network.scheduler.discovery_state())
92                .map_or(0, |discovery_state| {
93                    discovery_state
94                        .routing_table
95                        .closest_peers(&my_id.try_into().unwrap())
96                        .count()
97                });
98
99            println!("step: {step}");
100            println!("known peers: {known_peers}");
101            println!("connected peers: {ready_peers}");
102
103            // TODO: the threshold is too small, node cannot connect to many peer before the timeout
104            if ready_peers >= KNOWN_PEERS && known_peers >= KNOWN_PEERS || step >= 1000 {
105                debug!(system_time(); "Step: {}, known peers: {}, connected peers: {}", step, known_peers, ready_peers);
106
107                let ocaml_peer_id = if let Some(peer_id) = ocaml_node.as_ref() {
108                    *peer_id
109                } else {
110                    let node_id = runner.add_ocaml_node(OcamlNodeTestingConfig {
111                        initial_peers: vec![node_addr.clone()],
112                        daemon_json: DaemonJson::Custom(
113                            "/var/lib/coda/config_6929a7ec.json".to_owned(),
114                        ),
115                        block_producer: None,
116                    });
117                    let node = runner.ocaml_node(node_id).unwrap();
118                    eprintln!("launching OCaml node {}", node.dial_addr());
119
120                    ocaml_node = Some(node.peer_id());
121                    node.peer_id()
122                };
123                let node = runner.node(node_id).expect("must exist");
124                if let Some((peer_id, s)) = node
125                    .state()
126                    .p2p
127                    .ready_peers_iter()
128                    .find(|(peer_id, _)| *peer_id == &ocaml_peer_id)
129                {
130                    eprintln!("accept incoming connection from OCaml node: {peer_id}");
131                    assert!(s.is_incoming);
132                    return;
133                }
134            }
135        }
136
137        panic!("timeout");
138    }
139}