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