openmina_node_native/service/
builder.rs

1use ledger::proofs::provers::BlockProver;
2use node::{
3    account::AccountSecretKey, core::thread, p2p::identity::SecretKey as P2pSecretKey,
4    service::Recorder,
5};
6pub use openmina_node_common::NodeServiceCommonBuildError;
7use openmina_node_common::{
8    archive::config::ArchiveStorageOptions, p2p::TaskSpawner, rpc::RpcSender, EventSender,
9    NodeServiceCommonBuilder,
10};
11
12use crate::{http_server, NodeService, P2pTaskSpawner};
13
14pub struct NodeServiceBuilder {
15    common: NodeServiceCommonBuilder,
16    pub(super) recorder: Recorder,
17    http_server_port: Option<u16>,
18}
19
20#[derive(thiserror::Error, derive_more::From, Debug, Clone)]
21pub enum NodeServiceBuildError {
22    #[error("error when building common parts of the service: {0}")]
23    Common(NodeServiceCommonBuildError),
24}
25
26impl NodeServiceBuilder {
27    pub fn new(rng_seed: [u8; 32]) -> Self {
28        Self {
29            common: NodeServiceCommonBuilder::new(rng_seed),
30            recorder: Default::default(),
31            http_server_port: None,
32        }
33    }
34
35    pub fn event_sender(&self) -> &EventSender {
36        self.common.event_sender()
37    }
38
39    pub fn rpc_sender(&self) -> RpcSender {
40        self.common.rpc_sender()
41    }
42
43    pub fn ledger_init(&mut self) -> &mut Self {
44        self.common.ledger_init();
45        self
46    }
47
48    pub fn block_producer_init(
49        &mut self,
50        keypair: AccountSecretKey,
51        provers: Option<BlockProver>,
52    ) -> &mut Self {
53        self.common.block_producer_init(keypair, provers);
54        self
55    }
56
57    pub fn archive_init(&mut self, options: ArchiveStorageOptions, work_dir: String) -> &mut Self {
58        self.common.archive_init(options, work_dir);
59        self
60    }
61
62    pub fn p2p_init(&mut self, secret_key: P2pSecretKey) -> &mut Self {
63        self.common.p2p_init(secret_key, P2pTaskSpawner {});
64        self
65    }
66
67    pub fn p2p_init_with_custom_task_spawner(
68        &mut self,
69        secret_key: P2pSecretKey,
70        task_spawner: impl TaskSpawner,
71    ) -> &mut Self {
72        self.common.p2p_init(secret_key, task_spawner);
73        self
74    }
75
76    pub fn gather_stats(&mut self) -> &mut Self {
77        self.common.gather_stats();
78        self
79    }
80
81    pub fn record(&mut self, recorder: Recorder) -> &mut Self {
82        self.recorder = recorder;
83        self
84    }
85
86    pub fn http_server_init(&mut self, port: u16) -> &mut Self {
87        if let Some(cur_port) = self.http_server_port {
88            panic!("trying to start http server on port `{port}`, when it's already running on port `{cur_port}`");
89        }
90        self.http_server_port = Some(port);
91        let rpc_sender = self.rpc_sender();
92        let runtime = tokio::runtime::Builder::new_current_thread()
93            .enable_all()
94            .build()
95            .unwrap();
96        thread::Builder::new()
97            .name("openmina_http_server".to_owned())
98            .spawn(move || runtime.block_on(http_server::run(port, rpc_sender)))
99            .unwrap();
100        self
101    }
102
103    pub fn build(self) -> Result<NodeService, NodeServiceBuildError> {
104        let mut service = self.common.build()?;
105        service.recorder = self.recorder;
106        Ok(service)
107    }
108}