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 std::sync::Arc;
25
26pub async fn restart_node_service(
27    node_registry: NodeRegistryManager,
28    peer_id: PeerId,
29    retain_peer_id: bool,
30) -> Result<()> {
31    let nodes_len = node_registry.nodes.read().await.len();
32    let mut current_node = None;
33
34    for node in node_registry.nodes.read().await.iter() {
35        if node.read().await.peer_id.is_some_and(|id| id == peer_id) {
36            current_node = Some(Arc::clone(node));
37            break;
38        }
39    }
40
41    let current_node = current_node.ok_or_else(|| {
42        error!("Could not find the provided PeerId: {peer_id:?}");
43        eyre!("Could not find the provided PeerId: {peer_id:?}")
44    })?;
45
46    let rpc_client = RpcClient::from_socket_addr(current_node.read().await.rpc_socket_addr);
47    let service = NodeService::new(Arc::clone(&current_node), Box::new(rpc_client));
48    let mut service_manager = ServiceManager::new(
49        service,
50        Box::new(ServiceController {}),
51        VerbosityLevel::Normal,
52    );
53    service_manager.stop().await?;
54    let service_name = current_node.read().await.service_name.clone();
55
56    let service_control = ServiceController {};
57    if retain_peer_id {
58        debug!("Retaining the peer id: {peer_id:?} for the node: {service_name:?}");
59        // reuse the same port and root dir to retain peer id.
60        service_control
61            .uninstall(&service_name, false)
62            .map_err(
63                |err| eyre!("Error while uninstalling node {service_name:?} with: {err:?}",),
64            )?;
65        let current_node_clone = current_node.read().await.clone();
66        let install_ctx = InstallNodeServiceCtxBuilder {
67            alpha: current_node_clone.alpha,
68            antnode_path: current_node_clone.antnode_path.clone(),
69            autostart: current_node_clone.auto_restart,
70            data_dir_path: current_node_clone.data_dir_path.clone(),
71            env_variables: node_registry.environment_variables.read().await.clone(),
72            evm_network: current_node_clone.evm_network.clone(),
73            relay: current_node_clone.relay,
74            init_peers_config: current_node_clone.initial_peers_config.clone(),
75            log_dir_path: current_node_clone.log_dir_path.clone(),
76            log_format: current_node_clone.log_format,
77            max_archived_log_files: current_node_clone.max_archived_log_files,
78            max_log_files: current_node_clone.max_log_files,
79            metrics_port: None,
80            name: current_node_clone.service_name.clone(),
81            network_id: current_node_clone.network_id,
82            node_ip: current_node_clone.node_ip,
83            node_port: current_node_clone.get_antnode_port(),
84            no_upnp: current_node_clone.no_upnp,
85            rewards_address: current_node_clone.rewards_address,
86            rpc_socket_addr: current_node_clone.rpc_socket_addr,
87            service_user: current_node_clone.user.clone(),
88            write_older_cache_files: current_node_clone.write_older_cache_files,
89        }
90        .build()?;
91
92        service_control
93            .install(install_ctx, false)
94            .map_err(|err| eyre!("Error while installing node {service_name:?} with: {err:?}",))?;
95        service_manager.start().await?;
96    } else {
97        let current_node_clone = current_node.read().await.clone();
98        debug!("Starting a new node since retain peer id is false.");
99        let new_node_number = nodes_len + 1;
100        let new_service_name = format!("antnode{new_node_number}");
101
102        // example path "log_dir_path":"/var/log/antnode/antnode18"
103        let log_dir_path = {
104            let mut log_dir_path = current_node_clone.log_dir_path.clone();
105            log_dir_path.pop();
106            log_dir_path.join(&new_service_name)
107        };
108        // example path "data_dir_path":"/var/antctl/services/antnode18"
109        let data_dir_path = {
110            let mut data_dir_path = current_node_clone.data_dir_path.clone();
111            data_dir_path.pop();
112            data_dir_path.join(&new_service_name)
113        };
114
115        create_owned_dir(
116            log_dir_path.clone(),
117            current_node_clone.user.as_ref().ok_or_else(|| {
118                error!("The user must be set in the RPC context");
119                eyre!("The user must be set in the RPC context")
120            })?,
121        )
122        .map_err(|err| {
123            error!(
124                "Error while creating owned dir for {:?}: {err:?}",
125                current_node_clone.user
126            );
127            eyre!(
128                "Error while creating owned dir for {:?}: {err:?}",
129                current_node_clone.user
130            )
131        })?;
132        debug!("Created data dir: {data_dir_path:?} for the new node");
133        create_owned_dir(
134            data_dir_path.clone(),
135            current_node_clone
136                .user
137                .as_ref()
138                .ok_or_else(|| eyre!("The user must be set in the RPC context"))?,
139        )
140        .map_err(|err| {
141            eyre!(
142                "Error while creating owned dir for {:?}: {err:?}",
143                current_node_clone.user
144            )
145        })?;
146        // example path "antnode_path":"/var/antctl/services/antnode18/antnode"
147        let antnode_path = {
148            debug!("Copying antnode binary");
149            let mut antnode_path = current_node_clone.antnode_path.clone();
150            let antnode_file_name = antnode_path
151                .file_name()
152                .ok_or_eyre("Could not get filename from the current node's antnode path")?
153                .to_string_lossy()
154                .to_string();
155            antnode_path.pop();
156            antnode_path.pop();
157
158            let antnode_path = antnode_path.join(&new_service_name);
159            create_owned_dir(
160                data_dir_path.clone(),
161                current_node_clone
162                    .user
163                    .as_ref()
164                    .ok_or_else(|| eyre!("The user must be set in the RPC context"))?,
165            )
166            .map_err(|err| {
167                eyre!(
168                    "Error while creating owned dir for {:?}: {err:?}",
169                    current_node_clone.user
170                )
171            })?;
172            let antnode_path = antnode_path.join(antnode_file_name);
173
174            std::fs::copy(&current_node_clone.antnode_path, &antnode_path).map_err(|err| {
175                eyre!(
176                    "Failed to copy antnode bin from {:?} to {antnode_path:?} with err: {err}",
177                    current_node_clone.antnode_path
178                )
179            })?;
180            antnode_path
181        };
182
183        let install_ctx = InstallNodeServiceCtxBuilder {
184            alpha: current_node_clone.alpha,
185            autostart: current_node_clone.auto_restart,
186            data_dir_path: data_dir_path.clone(),
187            env_variables: node_registry.environment_variables.read().await.clone(),
188            evm_network: current_node_clone.evm_network.clone(),
189            relay: current_node_clone.relay,
190            init_peers_config: current_node_clone.initial_peers_config.clone(),
191            log_dir_path: log_dir_path.clone(),
192            log_format: current_node_clone.log_format,
193            name: new_service_name.clone(),
194            max_archived_log_files: current_node_clone.max_archived_log_files,
195            max_log_files: current_node_clone.max_log_files,
196            metrics_port: None,
197            network_id: current_node_clone.network_id,
198            node_ip: current_node_clone.node_ip,
199            node_port: None,
200            no_upnp: current_node_clone.no_upnp,
201            rewards_address: current_node_clone.rewards_address,
202            rpc_socket_addr: current_node_clone.rpc_socket_addr,
203            antnode_path: antnode_path.clone(),
204            service_user: current_node_clone.user.clone(),
205            write_older_cache_files: current_node_clone.write_older_cache_files,
206        }
207        .build()?;
208        service_control.install(install_ctx, false).map_err(|err| {
209            eyre!("Error while installing node {new_service_name:?} with: {err:?}",)
210        })?;
211
212        let node = NodeServiceData {
213            alpha: current_node_clone.alpha,
214            antnode_path,
215            auto_restart: current_node_clone.auto_restart,
216            connected_peers: None,
217            data_dir_path,
218            evm_network: current_node_clone.evm_network,
219            relay: current_node_clone.relay,
220            initial_peers_config: current_node_clone.initial_peers_config.clone(),
221            listen_addr: None,
222            log_dir_path,
223            log_format: current_node_clone.log_format,
224            max_archived_log_files: current_node_clone.max_archived_log_files,
225            max_log_files: current_node_clone.max_log_files,
226            metrics_port: None,
227            network_id: current_node_clone.network_id,
228            node_ip: current_node_clone.node_ip,
229            node_port: None,
230            no_upnp: current_node_clone.no_upnp,
231            number: new_node_number as u16,
232            peer_id: None,
233            pid: None,
234            rewards_address: current_node_clone.rewards_address,
235            reward_balance: current_node_clone.reward_balance,
236            rpc_socket_addr: current_node_clone.rpc_socket_addr,
237            schema_version: NODE_SERVICE_DATA_SCHEMA_LATEST,
238            service_name: new_service_name.clone(),
239            status: ServiceStatus::Added,
240            user: current_node_clone.user.clone(),
241            user_mode: false,
242            version: current_node_clone.version.clone(),
243            write_older_cache_files: current_node_clone.write_older_cache_files,
244        };
245
246        let rpc_client = RpcClient::from_socket_addr(node.rpc_socket_addr);
247        let service = NodeService::new(Arc::clone(&current_node), Box::new(rpc_client));
248        let mut service_manager = ServiceManager::new(
249            service,
250            Box::new(ServiceController {}),
251            VerbosityLevel::Normal,
252        );
253        service_manager.start().await?;
254        node_registry
255            .push_node(service_manager.service.service_data.read().await.clone())
256            .await;
257    };
258
259    Ok(())
260}