mina_node_testing/scenarios/solo_node/
sync_to_genesis_custom.rs

1use std::time::Duration;
2
3use node::p2p::P2pTimeouts;
4use time::format_description;
5
6use crate::{
7    node::{OcamlNodeTestingConfig, OcamlStep, RustNodeTestingConfig},
8    scenario::{ListenerNode, ScenarioStep},
9    scenarios::{ClusterRunner, RunCfg},
10};
11
12/// Set up single Rust node and sync to custom genesis block/ledger.
13///
14/// Since we don't have a way to generate genesis block/ledger from
15/// daemon.json directly, we start up ocaml node with that daemon.json,
16/// connect to it and sync up from it for now.
17///
18/// 1. Start up ocaml node with custom genesis.
19/// 2. Wait for ocaml node ready.
20/// 3. Start rust node, connect to ocaml node and sync up from it.
21#[derive(documented::Documented, Default, Clone, Copy)]
22pub struct SoloNodeSyncToGenesisCustom;
23
24impl SoloNodeSyncToGenesisCustom {
25    pub async fn run(self, mut runner: ClusterRunner<'_>) {
26        let now = time::OffsetDateTime::now_utc()
27            .replace_second(0)
28            .unwrap()
29            .replace_nanosecond(0)
30            .unwrap();
31        eprintln!("Genesis timestamp: {now}");
32        let initial_time = redux::Timestamp::new(now.unix_timestamp_nanos().try_into().unwrap());
33
34        let format = format_description::well_known::Rfc3339;
35        let formated_initial_time = now.format(&format).unwrap();
36
37        let ocaml_node_config = OcamlNodeTestingConfig {
38            initial_peers: Vec::new(),
39            daemon_json: runner.daemon_json_load(
40                "./tests/files/vrf_genesis_epoch/daemon.json".into(),
41                &formated_initial_time,
42            ),
43            block_producer: None,
44        };
45
46        let ocaml_node = runner.add_ocaml_node(ocaml_node_config);
47
48        eprintln!("waiting for ocaml node readiness");
49        runner
50            .exec_step(ScenarioStep::Ocaml {
51                node_id: ocaml_node,
52                step: OcamlStep::WaitReady {
53                    timeout: Duration::from_secs(5 * 60),
54                },
55            })
56            .await
57            .unwrap();
58
59        // set here to be used in other child scenarios
60        runner.set_initial_time(initial_time);
61
62        let rust_node = runner.add_rust_node(RustNodeTestingConfig {
63            initial_time,
64            genesis: node::config::DEVNET_CONFIG.clone(),
65            max_peers: 100,
66            initial_peers: Vec::new(),
67            peer_id: Default::default(),
68            block_producer: None,
69            snark_worker: None,
70            timeouts: P2pTimeouts::default(),
71            libp2p_port: None,
72            recorder: Default::default(),
73            peer_discovery: true,
74        });
75
76        runner
77            .exec_step(ScenarioStep::ConnectNodes {
78                dialer: rust_node,
79                listener: ListenerNode::Ocaml(ocaml_node),
80            })
81            .await
82            .unwrap();
83
84        eprintln!("waiting for rust node to sync up from ocaml node");
85        runner
86            .run(
87                RunCfg::default().action_handler(move |node_id, state, _, _| {
88                    node_id == rust_node
89                        && state.transition_frontier.sync.is_synced()
90                        && state.transition_frontier.best_tip().is_some()
91                }),
92            )
93            .await
94            .expect("error while waiting to sync genesis block from ocaml");
95        eprintln!("rust node synced up from ocaml node");
96
97        runner
98            .exec_step(ScenarioStep::Ocaml {
99                node_id: ocaml_node,
100                step: OcamlStep::KillAndRemove,
101            })
102            .await
103            .unwrap();
104    }
105}