ant_node_manager/
rpc.rs

1// Copyright (C) 2024 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
4// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
5// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
6// KIND, either express or implied. Please review the Licences for the specific language governing
7// permissions and limitations relating to use of the SAFE Network Software.
8
9use crate::{
10    ServiceManager, VerbosityLevel, add_services::config::InstallNodeServiceCtxBuilder,
11    config::create_owned_dir,
12};
13use ant_service_management::{
14    NodeRegistryManager, NodeService, NodeServiceData, ServiceStatus,
15    control::{ServiceControl, ServiceController},
16    node::NODE_SERVICE_DATA_SCHEMA_LATEST,
17    rpc::RpcClient,
18};
19use color_eyre::{
20    Result,
21    eyre::{OptionExt, eyre},
22};
23use libp2p::PeerId;
24use service_manager::RestartPolicy;
25use std::sync::Arc;
26
27pub async fn restart_node_service(
28    node_registry: NodeRegistryManager,
29    peer_id: PeerId,
30    retain_peer_id: bool,
31) -> Result<()> {
32    let nodes_len = node_registry.nodes.read().await.len();
33    let mut current_node = None;
34
35    for node in node_registry.nodes.read().await.iter() {
36        if node.read().await.peer_id.is_some_and(|id| id == peer_id) {
37            current_node = Some(Arc::clone(node));
38            break;
39        }
40    }
41
42    let current_node = current_node.ok_or_else(|| {
43        error!("Could not find the provided PeerId: {peer_id:?}");
44        eyre!("Could not find the provided PeerId: {peer_id:?}")
45    })?;
46
47    let rpc_client = RpcClient::from_socket_addr(current_node.read().await.rpc_socket_addr);
48    let service = NodeService::new(Arc::clone(&current_node), Box::new(rpc_client));
49    let mut service_manager = ServiceManager::new(
50        service,
51        Box::new(ServiceController {}),
52        VerbosityLevel::Normal,
53    );
54    service_manager.stop().await?;
55    let service_name = current_node.read().await.service_name.clone();
56
57    let service_control = ServiceController {};
58    if retain_peer_id {
59        debug!("Retaining the peer id: {peer_id:?} for the node: {service_name:?}");
60        // reuse the same port and root dir to retain peer id.
61        service_control
62            .uninstall(&service_name, false)
63            .map_err(
64                |err| eyre!("Error while uninstalling node {service_name:?} with: {err:?}",),
65            )?;
66        let current_node_clone = current_node.read().await.clone();
67        let install_ctx = InstallNodeServiceCtxBuilder {
68            alpha: current_node_clone.alpha,
69            antnode_path: current_node_clone.antnode_path.clone(),
70            autostart: current_node_clone.auto_restart,
71            data_dir_path: current_node_clone.data_dir_path.clone(),
72            env_variables: node_registry.environment_variables.read().await.clone(),
73            evm_network: current_node_clone.evm_network.clone(),
74            relay: current_node_clone.relay,
75            init_peers_config: current_node_clone.initial_peers_config.clone(),
76            log_dir_path: current_node_clone.log_dir_path.clone(),
77            log_format: current_node_clone.log_format,
78            max_archived_log_files: current_node_clone.max_archived_log_files,
79            max_log_files: current_node_clone.max_log_files,
80            metrics_port: None,
81            name: current_node_clone.service_name.clone(),
82            network_id: current_node_clone.network_id,
83            node_ip: current_node_clone.node_ip,
84            node_port: current_node_clone.get_antnode_port(),
85            no_upnp: current_node_clone.no_upnp,
86            // This setting doesn't really matter because RPC will soon be taken out of use.
87            restart_policy: RestartPolicy::Never,
88            rewards_address: current_node_clone.rewards_address,
89            rpc_socket_addr: current_node_clone.rpc_socket_addr,
90            service_user: current_node_clone.user.clone(),
91            // This setting doesn't really matter because RPC will soon be taken out of use.
92            stop_on_upgrade: true,
93            write_older_cache_files: current_node_clone.write_older_cache_files,
94        }
95        .build()?;
96
97        service_control
98            .install(install_ctx, false)
99            .map_err(|err| eyre!("Error while installing node {service_name:?} with: {err:?}",))?;
100        service_manager.start().await?;
101    } else {
102        let current_node_clone = current_node.read().await.clone();
103        debug!("Starting a new node since retain peer id is false.");
104        let new_node_number = nodes_len + 1;
105        let new_service_name = format!("antnode{new_node_number}");
106
107        // example path "log_dir_path":"/var/log/antnode/antnode18"
108        let log_dir_path = {
109            let mut log_dir_path = current_node_clone.log_dir_path.clone();
110            log_dir_path.pop();
111            log_dir_path.join(&new_service_name)
112        };
113        // example path "data_dir_path":"/var/antctl/services/antnode18"
114        let data_dir_path = {
115            let mut data_dir_path = current_node_clone.data_dir_path.clone();
116            data_dir_path.pop();
117            data_dir_path.join(&new_service_name)
118        };
119
120        create_owned_dir(
121            log_dir_path.clone(),
122            current_node_clone.user.as_ref().ok_or_else(|| {
123                error!("The user must be set in the RPC context");
124                eyre!("The user must be set in the RPC context")
125            })?,
126        )
127        .map_err(|err| {
128            error!(
129                "Error while creating owned dir for {:?}: {err:?}",
130                current_node_clone.user
131            );
132            eyre!(
133                "Error while creating owned dir for {:?}: {err:?}",
134                current_node_clone.user
135            )
136        })?;
137        debug!("Created data dir: {data_dir_path:?} for the new node");
138        create_owned_dir(
139            data_dir_path.clone(),
140            current_node_clone
141                .user
142                .as_ref()
143                .ok_or_else(|| eyre!("The user must be set in the RPC context"))?,
144        )
145        .map_err(|err| {
146            eyre!(
147                "Error while creating owned dir for {:?}: {err:?}",
148                current_node_clone.user
149            )
150        })?;
151        // example path "antnode_path":"/var/antctl/services/antnode18/antnode"
152        let antnode_path = {
153            debug!("Copying antnode binary");
154            let mut antnode_path = current_node_clone.antnode_path.clone();
155            let antnode_file_name = antnode_path
156                .file_name()
157                .ok_or_eyre("Could not get filename from the current node's antnode path")?
158                .to_string_lossy()
159                .to_string();
160            antnode_path.pop();
161            antnode_path.pop();
162
163            let antnode_path = antnode_path.join(&new_service_name);
164            create_owned_dir(
165                data_dir_path.clone(),
166                current_node_clone
167                    .user
168                    .as_ref()
169                    .ok_or_else(|| eyre!("The user must be set in the RPC context"))?,
170            )
171            .map_err(|err| {
172                eyre!(
173                    "Error while creating owned dir for {:?}: {err:?}",
174                    current_node_clone.user
175                )
176            })?;
177            let antnode_path = antnode_path.join(antnode_file_name);
178
179            std::fs::copy(&current_node_clone.antnode_path, &antnode_path).map_err(|err| {
180                eyre!(
181                    "Failed to copy antnode bin from {:?} to {antnode_path:?} with err: {err}",
182                    current_node_clone.antnode_path
183                )
184            })?;
185            antnode_path
186        };
187
188        let install_ctx = InstallNodeServiceCtxBuilder {
189            alpha: current_node_clone.alpha,
190            autostart: current_node_clone.auto_restart,
191            data_dir_path: data_dir_path.clone(),
192            env_variables: node_registry.environment_variables.read().await.clone(),
193            evm_network: current_node_clone.evm_network.clone(),
194            relay: current_node_clone.relay,
195            init_peers_config: current_node_clone.initial_peers_config.clone(),
196            log_dir_path: log_dir_path.clone(),
197            log_format: current_node_clone.log_format,
198            name: new_service_name.clone(),
199            max_archived_log_files: current_node_clone.max_archived_log_files,
200            max_log_files: current_node_clone.max_log_files,
201            metrics_port: None,
202            network_id: current_node_clone.network_id,
203            node_ip: current_node_clone.node_ip,
204            node_port: None,
205            no_upnp: current_node_clone.no_upnp,
206            // This setting doesn't really matter because RPC will soon be taken out of use.
207            restart_policy: RestartPolicy::Never,
208            rewards_address: current_node_clone.rewards_address,
209            rpc_socket_addr: current_node_clone.rpc_socket_addr,
210            antnode_path: antnode_path.clone(),
211            service_user: current_node_clone.user.clone(),
212            // This setting doesn't really matter because RPC will soon be taken out of use.
213            stop_on_upgrade: true,
214            write_older_cache_files: current_node_clone.write_older_cache_files,
215        }
216        .build()?;
217        service_control.install(install_ctx, false).map_err(|err| {
218            eyre!("Error while installing node {new_service_name:?} with: {err:?}",)
219        })?;
220
221        let node = NodeServiceData {
222            alpha: current_node_clone.alpha,
223            antnode_path,
224            auto_restart: current_node_clone.auto_restart,
225            connected_peers: None,
226            data_dir_path,
227            evm_network: current_node_clone.evm_network,
228            relay: current_node_clone.relay,
229            initial_peers_config: current_node_clone.initial_peers_config.clone(),
230            listen_addr: None,
231            log_dir_path,
232            log_format: current_node_clone.log_format,
233            max_archived_log_files: current_node_clone.max_archived_log_files,
234            max_log_files: current_node_clone.max_log_files,
235            metrics_port: None,
236            network_id: current_node_clone.network_id,
237            node_ip: current_node_clone.node_ip,
238            node_port: None,
239            no_upnp: current_node_clone.no_upnp,
240            number: new_node_number as u16,
241            peer_id: None,
242            pid: None,
243            rewards_address: current_node_clone.rewards_address,
244            reward_balance: current_node_clone.reward_balance,
245            rpc_socket_addr: current_node_clone.rpc_socket_addr,
246            schema_version: NODE_SERVICE_DATA_SCHEMA_LATEST,
247            service_name: new_service_name.clone(),
248            status: ServiceStatus::Added,
249            user: current_node_clone.user.clone(),
250            user_mode: false,
251            version: current_node_clone.version.clone(),
252            write_older_cache_files: current_node_clone.write_older_cache_files,
253        };
254
255        let rpc_client = RpcClient::from_socket_addr(node.rpc_socket_addr);
256        let service = NodeService::new(Arc::clone(&current_node), Box::new(rpc_client));
257        let mut service_manager = ServiceManager::new(
258            service,
259            Box::new(ServiceController {}),
260            VerbosityLevel::Normal,
261        );
262        service_manager.start().await?;
263        node_registry
264            .push_node(service_manager.service.service_data.read().await.clone())
265            .await;
266    };
267
268    Ok(())
269}