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