mina_node_testing/scenarios/solo_node/
sync_to_genesis.rs

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