ui + config: optimize ip list at config ui, api port modal, update, translations, better check ports availability, refactor settings initialization and arguments passing

This commit is contained in:
ardocrat 2023-06-29 03:42:03 +03:00
parent 8fdc2c1e39
commit 1a74678c67
11 changed files with 381 additions and 248 deletions

View file

@ -11,7 +11,7 @@ network:
restart: Restart
autorun: Autorun
disabled_server: 'Enable integrated node or add another connection method by pressing %{dots} in the top-left corner of the screen.'
no_ip_addresses: There are no available IP addresses on your system, server cannot be started, check your network connectivity.
no_ips: There are no available IP addresses on your system, server cannot be started, check your network connectivity.
sync_status:
node_restarting: Node is restarting
node_down: Node is down
@ -60,7 +60,6 @@ network_mining:
enable_server: Enable server
server_setting: 'Enable stratum server or change more settings by selecting %{settings} at the bottom of the screen. App restart is required to change settings of the running server.'
info: 'Mining server is enabled, you can change its settings by selecting %{settings} at the bottom of the screen. Data is updating when devices are connected.'
port_unavailable: Specified port is unavailable
rewards_wallet: Wallet for rewards
server: Stratum server
address: Address
@ -72,15 +71,17 @@ network_mining:
disconnected: Disconnected
network_settings:
port: Port
ip_address: IP Address
ip: IP Address
change_port: Change port
enter_value: 'Enter value:'
server:
title: Server
enter_value: Enter value
port_unavailable: Specified port is unavailable
restart_app_required: App restart is required to apply changes.
enable: Enable
disable: Disable
restart: Restart
api_ip_address: API IP Address
server: Server
api_ip: API IP Address
api_port: API Port
modal:
cancel: Cancel
save: Save

View file

@ -11,7 +11,7 @@ network:
restart: Перезапустить
autorun: Автозапуск
disabled_server: 'Включите встроенный узел или добавьте другой способ подключения, нажав %{dots} в левом-верхнем углу экрана.'
no_ip_addresses: В вашей системе отсутствуют доступные IP адреса, запуск сервера невозможен, проверьте ваше подключение к сети.
no_ips: В вашей системе отсутствуют доступные IP адреса, запуск сервера невозможен, проверьте ваше подключение к сети.
sync_status:
node_restarting: Узел перезапускается
node_down: Узел выключен
@ -60,7 +60,6 @@ network_mining:
enable_server: Включить сервер
server_setting: 'Включите stratum-сервер или измените больше настроек, выбрав %{settings} внизу экрана. Для изменения настроек запущенного сервера потребуется перезапуск приложения.'
info: 'Сервер майнинга запущен, вы можете изменить его настройки, выбрав %{settings} внизу экрана. Данные обновляются, когда устройства подключены.'
port_unavailable: Указанный порт недоступен
rewards_wallet: Кошелёк для наград
server: Stratum-сервер
address: Адрес
@ -71,16 +70,18 @@ network_mining:
connected: Подключен
disconnected: Отключен
network_settings:
ip_address: IP Адрес
ip: IP Адрес
port: Порт
change_port: Изменить порт
enter_value: 'Введите значение:'
server:
title: Сервер
enter_value: Введите значение
port_unavailable: Указанный порт недоступен
restart_app_required: Для применения изменений требуется перезапуск приложения.
enable: Включить
disable: Выключить
restart: Перезапустить
api_ip_address: API IP Адрес
server: Сервер
api_ip: API IP Адрес
api_port: API Порт
modal:
cancel: Отмена
save: Сохранить

View file

@ -45,7 +45,7 @@ impl Default for Root {
}
impl ModalContainer for Root {
fn allowed_modal_ids(&self) -> &Vec<&'static str> {
fn modal_ids(&self) -> &Vec<&'static str> {
self.allowed_modal_ids.as_ref()
}
}

View file

@ -23,11 +23,12 @@ use crate::gui::views::View;
/// Contains modal ids to draw at current container if possible.
pub trait ModalContainer {
fn allowed_modal_ids(&self) -> &Vec<&'static str>;
/// List of modal ids to show at current view container.
fn modal_ids(&self) -> &Vec<&'static str>;
/// Check if it's possible to show modal.
fn can_show_modal(&self, id: &'static str) -> bool {
self.allowed_modal_ids().contains(&id)
self.modal_ids().contains(&id)
}
}

View file

@ -29,6 +29,7 @@ use crate::gui::views::network_metrics::NetworkMetrics;
use crate::gui::views::network_mining::NetworkMining;
use crate::gui::views::network_node::NetworkNode;
use crate::gui::views::network_settings::NetworkSettings;
use crate::gui::views::settings_node::NodeSetup;
use crate::gui::views::settings_stratum::StratumServerSetup;
use crate::node::Node;
use crate::Settings;
@ -60,23 +61,24 @@ impl NetworkTabType {
pub struct Network {
current_tab: Box<dyn NetworkTab>,
allowed_modal_ids: Vec<&'static str>,
modal_ids: Vec<&'static str>,
}
impl Default for Network {
fn default() -> Self {
Self {
current_tab: Box::new(NetworkNode::default()),
allowed_modal_ids: vec![
StratumServerSetup::STRATUM_PORT_MODAL
modal_ids: vec![
StratumServerSetup::STRATUM_PORT_MODAL,
NodeSetup::API_PORT_MODAL
]
}
}
}
impl ModalContainer for Network {
fn allowed_modal_ids(&self) -> &Vec<&'static str> {
self.allowed_modal_ids.as_ref()
fn modal_ids(&self) -> &Vec<&'static str> {
self.modal_ids.as_ref()
}
}
@ -278,10 +280,57 @@ impl Network {
addresses
}
/// Draw IP list radio buttons.
pub fn ip_list_ui(ui: &mut egui::Ui,
saved_ip: &String,
ips: &Vec<IpAddr>,
on_change: impl FnOnce(&String)) {
let saved_ip_addr = &IpAddr::from_str(saved_ip.as_str()).unwrap();
let mut selected_ip_addr = saved_ip_addr;
// Set first IP address as current if saved is not present at system.
if !ips.contains(selected_ip_addr) {
selected_ip_addr = ips.get(0).unwrap();
}
// Show available IP addresses on the system.
let _ = ips.chunks(2).map(|x| {
if x.len() == 2 {
ui.columns(2, |columns| {
let ip_addr_l = x.get(0).unwrap();
columns[0].vertical_centered(|ui| {
View::radio_value(ui,
&mut selected_ip_addr,
ip_addr_l,
ip_addr_l.to_string());
});
let ip_addr_r = x.get(1).unwrap();
columns[1].vertical_centered(|ui| {
View::radio_value(ui,
&mut selected_ip_addr,
ip_addr_r,
ip_addr_r.to_string());
})
});
} else {
let ip_addr = x.get(0).unwrap();
View::radio_value(ui,
&mut selected_ip_addr,
ip_addr,
ip_addr.to_string());
}
ui.add_space(12.0);
}).collect::<Vec<_>>();
if saved_ip_addr != selected_ip_addr {
(on_change)(&selected_ip_addr.to_string());
}
}
/// Show message when IP addresses are not available at system.
pub fn no_ip_address_ui(ui: &mut egui::Ui) {
ui.vertical_centered(|ui| {
ui.label(RichText::new(t!("network.no_ip_addresses"))
ui.label(RichText::new(t!("network.no_ips"))
.size(16.0)
.color(Colors::INACTIVE_TEXT)
);
@ -290,10 +339,13 @@ impl Network {
}
/// Check whether a port is available on the provided host.
pub fn is_port_available(host: &str, port: u16) -> bool {
let ip_addr = Ipv4Addr::from_str(host).unwrap();
let ipv4 = SocketAddrV4::new(ip_addr, port);
TcpListener::bind(ipv4).is_ok()
pub fn is_port_available(host: &String, port: &String) -> bool {
if let Ok(p) = port.parse::<u16>() {
let ip_addr = Ipv4Addr::from_str(host.as_str()).unwrap();
let ipv4 = SocketAddrV4::new(ip_addr, p);
return TcpListener::bind(ipv4).is_ok();
}
false
}
}

View file

@ -77,29 +77,21 @@ impl NetworkTab for NetworkMining {
ui.add_space(4.0);
// Show button to enable stratum server if port is available.
if self.stratum_server_setup.is_stratum_port_available {
if self.stratum_server_setup.is_port_available {
ui.add_space(6.0);
View::button(ui, t!("network_mining.enable_server"), Colors::GOLD, || {
Node::start_stratum_server();
});
ui.add_space(2.0);
}
let stratum_enabled = Settings::node_config_to_read()
.members.clone()
.server.stratum_mining_config.unwrap()
.enable_stratum_server.unwrap();
// Show stratum server autorun checkbox.
let stratum_enabled = NodeConfig::is_stratum_autorun_enabled();
View::checkbox(ui, stratum_enabled, t!("network.autorun"), || {
let mut w_node_config = Settings::node_config_to_update();
w_node_config.members
.server.stratum_mining_config.as_mut().unwrap()
.enable_stratum_server = Some(!stratum_enabled);
w_node_config.save();
});
NodeConfig::toggle_stratum_autorun();
});
ui.add_space(6.0);
}
});
});
return;
} else if Node::is_stratum_server_starting() {

View file

@ -37,6 +37,11 @@ impl NetworkTab for NetworkSettings {
}
fn on_modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
match modal.id {
NodeSetup::API_PORT_MODAL => {
self.node_setup.api_port_modal_ui(ui, modal, cb);
},
_ => {}
}
}
}

View file

@ -14,24 +14,22 @@
use std::net::IpAddr;
use std::str::FromStr;
use egui::RichText;
use crate::gui::Colors;
use crate::gui::icons::COMPUTER_TOWER;
use egui::{RichText, TextStyle, Widget};
use crate::gui::{Colors, Navigator};
use crate::gui::icons::{COMPUTER_TOWER, POWER};
use crate::gui::platform::PlatformCallbacks;
use crate::gui::views::{Network, View};
use crate::gui::views::{Modal, ModalPosition, Network, View};
use crate::node::{Node, NodeConfig};
/// Integrated node server setup ui section.
pub struct NodeSetup {
/// API IP address to be used inside edit modal.
api_address_edit: String,
/// API port to be used inside edit modal.
api_port_edit: String,
/// Flag to check if API port is available inside edit modal.
api_port_available_edit: bool,
/// Flag to check if API port is available from saved config value.
pub(crate) api_port_available: bool,
pub(crate) is_api_port_available: bool,
/// API secret to be used inside edit modal.
api_secret_edit: String,
@ -45,13 +43,12 @@ pub struct NodeSetup {
impl Default for NodeSetup {
fn default() -> Self {
let (api_address, api_port) = NodeConfig::get_api_address_port();
let is_api_port_available = Network::is_port_available(api_address.as_str(), api_port);
let (api_ip, api_port) = NodeConfig::get_api_address_port();
let is_api_port_available = is_api_port_available(&api_ip, &api_port);
Self {
api_address_edit: api_address,
api_port_edit: api_port.to_string(),
api_port_edit: api_port,
api_port_available_edit: is_api_port_available,
api_port_available: is_api_port_available,
is_api_port_available,
api_secret_edit: "".to_string(),
foreign_api_secret_edit: "".to_string(),
ftl_edit: "".to_string(),
@ -62,10 +59,10 @@ impl Default for NodeSetup {
const SECRET_SYMBOLS: &'static str = "••••••••••••";
impl NodeSetup {
pub const API_PORT_MODAL: &'static str = "stratum_port";
pub const API_PORT_MODAL: &'static str = "api_port";
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
View::sub_title(ui, format!("{} {}", COMPUTER_TOWER, t!("network_settings.server.title")));
View::sub_title(ui, format!("{} {}", COMPUTER_TOWER, t!("network_settings.server")));
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(4.0);
@ -79,17 +76,17 @@ impl NodeSetup {
if Node::is_running() {
ui.scope(|ui| {
// Setup spacing between buttons.
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
ui.add_space(6.0);
ui.columns(2, |columns| {
columns[0].vertical_centered_justified(|ui| {
View::button(ui, t!("network_settings.server.disable"), Colors::GOLD, || {
View::button(ui, t!("network_settings.disable"), Colors::GOLD, || {
Node::stop(false);
});
});
columns[1].vertical_centered_justified(|ui| {
View::button(ui, t!("network_settings.server.restart"), Colors::GOLD, || {
View::button(ui, t!("network_settings.restart"), Colors::GOLD, || {
Node::restart();
});
});
@ -98,7 +95,8 @@ impl NodeSetup {
} else {
ui.add_space(6.0);
ui.vertical_centered(|ui| {
View::button(ui, t!("network_settings.server.enable"), Colors::GOLD, || {
let enable_text = format!("{} {}", POWER, t!("network_settings.enable"));
View::button(ui, enable_text, Colors::GOLD, || {
Node::start();
});
});
@ -112,7 +110,7 @@ impl NodeSetup {
ui.add_space(4.0);
let addrs = Network::get_ip_list();
// Show error message when IP addresses are not available on the system.
// Show message when IP addresses are not available on the system.
if addrs.is_empty() {
Network::no_ip_address_ui(ui);
ui.add_space(4.0);
@ -121,63 +119,146 @@ impl NodeSetup {
ui.add_space(4.0);
ui.vertical_centered(|ui| {
ui.label(RichText::new(t!("network_settings.server.api_ip_address"))
ui.label(RichText::new(t!("network_settings.api_ip"))
.size(16.0)
.color(Colors::GRAY)
);
ui.add_space(6.0);
// Show API IP addresses to select.
let (api_ip, api_port) = NodeConfig::get_api_address_port();
Network::ip_list_ui(ui, &api_ip, &addrs, |selected_ip| {
self.is_api_port_available = is_api_port_available(selected_ip, &api_port);
NodeConfig::save_api_address_port(selected_ip, &api_port);
});
// Show API IP address setup.
self.api_ip_address_setup_ui(ui, addrs)
ui.label(RichText::new(t!("network_settings.api_port"))
.size(16.0)
.color(Colors::GRAY)
);
ui.add_space(6.0);
// Show API port setup.
self.api_port_setup_ui(ui, cb);
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(6.0);
});
}
}
/// Show API IP address setup.
fn api_ip_address_setup_ui(&mut self, ui: &mut egui::Ui, addrs: Vec<IpAddr>) {
let (addr, port) = NodeConfig::get_api_address_port();
let saved_ip_addr = &IpAddr::from_str(addr.as_str()).unwrap();
let mut selected_addr = saved_ip_addr;
/// Draw API port setup ui.
fn api_port_setup_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
let (_, port) = NodeConfig::get_api_address_port();
// Show button to choose API server port.
View::button(ui, port.clone(), Colors::BUTTON, || {
// Setup values for modal.
self.api_port_edit = port;
self.api_port_available_edit = self.is_api_port_available;
// Set first IP address as current if saved is not present at system.
if !addrs.contains(selected_addr) {
selected_addr = addrs.get(0).unwrap();
// Show API port modal.
let port_modal = Modal::new(Self::API_PORT_MODAL)
.position(ModalPosition::CenterTop)
.title(t!("network_settings.change_port"));
Navigator::show_modal(port_modal);
cb.show_keyboard();
});
ui.add_space(14.0);
// Show error when API server port is unavailable.
if !self.is_api_port_available {
ui.label(RichText::new(t!("network_settings.port_unavailable"))
.size(16.0)
.color(Colors::RED));
ui.add_space(12.0);
}
}
// Show available IP addresses on the system.
let _ = addrs.chunks(2).map(|x| {
if x.len() == 2 {
/// Draw API port [`Modal`] content ui.
pub fn api_port_modal_ui(&mut self,
ui: &mut egui::Ui,
modal: &Modal,
cb: &dyn PlatformCallbacks) {
ui.add_space(6.0);
ui.vertical_centered(|ui| {
ui.label(RichText::new(t!("network_settings.enter_value"))
.size(16.0)
.color(Colors::GRAY));
ui.add_space(8.0);
// Draw API port text edit.
let text_edit_resp = egui::TextEdit::singleline(&mut self.api_port_edit)
.font(TextStyle::Heading)
.desired_width(58.0)
.cursor_at_end(true)
.ui(ui);
text_edit_resp.request_focus();
if text_edit_resp.clicked() {
cb.show_keyboard();
}
// Show error when specified port is unavailable.
if !self.api_port_available_edit {
ui.add_space(12.0);
ui.label(RichText::new(t!("network_settings.port_unavailable"))
.size(16.0)
.color(Colors::RED));
}
ui.add_space(12.0);
// Show modal buttons.
ui.scope(|ui| {
// Setup spacing between buttons.
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
ui.columns(2, |columns| {
let addr0 = x.get(0).unwrap();
columns[0].vertical_centered(|ui| {
View::radio_value(ui,
&mut selected_addr,
addr0,
addr0.to_string());
columns[0].vertical_centered_justified(|ui| {
View::button(ui, t!("modal.cancel"), Colors::WHITE, || {
cb.hide_keyboard();
modal.close();
});
let addr1 = x.get(1).unwrap();
columns[1].vertical_centered(|ui| {
View::radio_value(ui,
&mut selected_addr,
addr1,
addr1.to_string());
})
});
} else {
let addr = x.get(0).unwrap();
View::radio_value(ui,
&mut selected_addr,
addr,
addr.to_string());
}
ui.add_space(10.0);
}).collect::<Vec<_>>();
columns[1].vertical_centered_justified(|ui| {
View::button(ui, t!("modal.save"), Colors::WHITE, || {
// Check if port is available.
let (ip, _) = NodeConfig::get_api_address_port();
let available = is_api_port_available(&ip, &self.api_port_edit);
self.api_port_available_edit = available;
// Save stratum server address at config if it was changed and check port availability.
if saved_ip_addr != selected_addr {
NodeConfig::save_api_server_address_port(selected_addr.to_string(), port.to_string());
let available = Network::is_port_available(selected_addr.to_string().as_str(), port);
self.api_port_available = available;
if self.api_port_available_edit {
// Save port at config if it's available.
NodeConfig::save_api_address_port(
&ip,
&self.api_port_edit
);
self.is_api_port_available = true;
cb.hide_keyboard();
modal.close();
}
});
});
});
ui.add_space(6.0);
});
});
}
}
fn is_api_port_available(ip: &String, port: &String) -> bool {
let same_address_as_running = {
let (current_ip, current_port) = NodeConfig::get_api_address_port();
Node::is_running() && &current_ip == ip && &current_port == port
};
if same_address_as_running || (!Node::is_running() && Network::is_port_available(&ip, &port)) {
if &NodeConfig::get_p2p_port().to_string() != port {
let (stratum_ip, stratum_port) = NodeConfig::get_stratum_address_port();
return if &stratum_ip == ip {
&stratum_port != port
} else {
true
}
}
}
false
}

View file

@ -22,29 +22,27 @@ use crate::gui::icons::WRENCH;
use crate::gui::platform::PlatformCallbacks;
use crate::gui::views::{Modal, ModalPosition, Network, View};
use crate::node::NodeConfig;
use crate::Settings;
/// Stratum server setup ui section.
pub struct StratumServerSetup {
/// Stratum IP address to be used inside edit modal.
stratum_address_edit: String,
/// Stratum port to be used inside edit modal.
stratum_port_edit: String,
/// Flag to check if stratum port is available inside edit modal.
stratum_port_available_edit: bool,
/// Flag to check if stratum port is available from saved config value.
pub(crate) is_stratum_port_available: bool
pub(crate) is_port_available: bool
}
impl Default for StratumServerSetup {
fn default() -> Self {
let (stratum_address, stratum_port) = NodeConfig::get_stratum_address_port();
let is_port_available = Network::is_port_available(stratum_address.as_str(), stratum_port);
let (ip, port) = NodeConfig::get_stratum_address_port();
let is_port_available = is_stratum_port_available(&ip, &port);
Self {
stratum_address_edit: stratum_address,
stratum_port_edit: stratum_port.to_string(),
stratum_port_edit: port,
stratum_port_available_edit: is_port_available,
is_stratum_port_available: is_port_available
is_port_available
}
}
}
@ -58,42 +56,50 @@ impl StratumServerSetup {
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(4.0);
// Show error message when IP addresses are not available on the system.
let addrs = Network::get_ip_list();
if addrs.is_empty() {
// Show message when IP addresses are not available on the system.
let all_ips = Network::get_ip_list();
if all_ips.is_empty() {
Network::no_ip_address_ui(ui);
return;
}
ui.vertical_centered(|ui| {
ui.label(RichText::new(t!("network_settings.ip_address"))
ui.label(RichText::new(t!("network_settings.ip"))
.size(16.0)
.color(Colors::GRAY)
);
ui.add_space(6.0);
// Show stratum IP address setup.
self.ip_address_setup_ui(ui, addrs);
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(6.0);
// Show stratum IP addresses to select.
let (ip, port) = NodeConfig::get_stratum_address_port();
Network::ip_list_ui(ui, &ip, &all_ips, |selected_ip| {
self.is_port_available = is_stratum_port_available(selected_ip, &port);
NodeConfig::save_stratum_address_port(selected_ip, &port);
if !self.is_port_available {
NodeConfig::disable_stratum_autorun();
}
});
ui.label(RichText::new(t!("network_settings.port"))
.size(16.0)
.color(Colors::GRAY)
);
// Show button to choose stratum server port.
ui.add_space(6.0);
let (stratum_address, stratum_port) = NodeConfig::get_stratum_address_port();
View::button(ui, stratum_port.to_string(), Colors::BUTTON, || {
// Show stratum port setup.
self.port_setup_ui(ui, cb);
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(6.0);
});
}
/// Draw stratum port setup ui.
fn port_setup_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
let (_, port) = NodeConfig::get_stratum_address_port();
// Show button to choose stratum server port.
View::button(ui, port.clone(), Colors::BUTTON, || {
// Setup values for modal.
self.stratum_address_edit = stratum_address.clone();
self.stratum_port_edit = stratum_port.to_string();
self.stratum_port_available_edit = Network::is_port_available(
stratum_address.as_str(),
stratum_port
);
self.stratum_port_edit = port;
self.stratum_port_available_edit = self.is_port_available;
// Show stratum port modal.
let port_modal = Modal::new(Self::STRATUM_PORT_MODAL)
@ -105,19 +111,15 @@ impl StratumServerSetup {
ui.add_space(14.0);
// Show error when stratum server port is unavailable.
if !self.is_stratum_port_available {
ui.label(RichText::new(t!("network_mining.port_unavailable"))
if !self.is_port_available {
ui.label(RichText::new(t!("network_settings.port_unavailable"))
.size(16.0)
.color(Colors::RED));
ui.add_space(12.0);
}
View::horizontal_line(ui, Colors::ITEM_STROKE);
ui.add_space(6.0);
});
}
/// Draw stratum port [`Modal`] content.
/// Draw stratum port [`Modal`] content ui.
pub fn stratum_port_modal_ui(&mut self,
ui: &mut egui::Ui,
modal: &Modal,
@ -143,7 +145,7 @@ impl StratumServerSetup {
// Show error when specified port is unavailable.
if !self.stratum_port_available_edit {
ui.add_space(12.0);
ui.label(RichText::new(t!("network_mining.port_unavailable"))
ui.label(RichText::new(t!("network_settings.port_unavailable"))
.size(16.0)
.color(Colors::RED));
}
@ -153,7 +155,7 @@ impl StratumServerSetup {
// Show modal buttons.
ui.scope(|ui| {
// Setup spacing between buttons.
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
ui.columns(2, |columns| {
columns[0].vertical_centered_justified(|ui| {
@ -166,21 +168,15 @@ impl StratumServerSetup {
columns[1].vertical_centered_justified(|ui| {
View::button(ui, t!("modal.save"), Colors::WHITE, || {
// Check if port is available.
let port_parse = self.stratum_port_edit.parse::<u16>();
let is_available = port_parse.is_ok() && Network::is_port_available(
self.stratum_address_edit.as_str(),
port_parse.unwrap()
);
self.stratum_port_available_edit = is_available;
let (ip, _) = NodeConfig::get_api_address_port();
let available = is_stratum_port_available(&ip, &self.stratum_port_edit);
self.stratum_port_available_edit = available;
// Save port at config if it's available.
if self.stratum_port_available_edit {
NodeConfig::save_stratum_address_port(
self.stratum_address_edit.clone(),
self.stratum_port_edit.clone()
);
NodeConfig::save_stratum_address_port(&ip, &self.stratum_port_edit);
self.is_stratum_port_available = true;
self.is_port_available = true;
cb.hide_keyboard();
modal.close();
}
@ -191,52 +187,18 @@ impl StratumServerSetup {
});
});
}
/// Show stratum IP address setup.
fn ip_address_setup_ui(&mut self, ui: &mut egui::Ui, addrs: Vec<IpAddr>) {
let (addr, port) = NodeConfig::get_stratum_address_port();
let saved_ip_addr = &IpAddr::from_str(addr.as_str()).unwrap();
let mut selected_addr = saved_ip_addr;
// Set first IP address as current if saved is not present at system.
if !addrs.contains(selected_addr) {
selected_addr = addrs.get(0).unwrap();
}
// Show available IP addresses on the system.
let _ = addrs.chunks(2).map(|x| {
if x.len() == 2 {
ui.columns(2, |columns| {
let addr0 = x.get(0).unwrap();
columns[0].vertical_centered(|ui| {
View::radio_value(ui,
&mut selected_addr,
addr0,
addr0.to_string());
});
let addr1 = x.get(1).unwrap();
columns[1].vertical_centered(|ui| {
View::radio_value(ui,
&mut selected_addr,
addr1,
addr1.to_string());
})
});
} else {
let addr = x.get(0).unwrap();
View::radio_value(ui,
&mut selected_addr,
addr,
addr.to_string());
}
ui.add_space(10.0);
}).collect::<Vec<_>>();
// Save stratum server address at config if it was changed and check port availability.
if saved_ip_addr != selected_addr {
NodeConfig::save_stratum_address_port(selected_addr.to_string(), port.to_string());
let available = Network::is_port_available(selected_addr.to_string().as_str(), port);
self.is_stratum_port_available = available;
}
}
}
fn is_stratum_port_available(ip: &String, port: &String) -> bool {
if Network::is_port_available(&ip, &port) {
if &NodeConfig::get_p2p_port().to_string() != port {
let (api_ip, api_port) = NodeConfig::get_api_address_port();
return if &api_ip == ip {
&api_port != port
} else {
true
}
}
}
false
}

View file

@ -35,7 +35,7 @@ pub struct NodeConfig {
impl NodeConfig {
/// Initialize integrated node config.
pub fn init(chain_type: ChainTypes) -> Self {
pub fn init(chain_type: &ChainTypes) -> Self {
let _ = Self::check_api_secret_files(chain_type, API_SECRET_FILE_NAME);
let _ = Self::check_api_secret_files(chain_type, FOREIGN_API_SECRET_FILE_NAME);
@ -46,11 +46,11 @@ impl NodeConfig {
}
/// Initialize config with provided [`ChainTypes`].
pub fn for_chain_type(chain_type: ChainTypes) -> ConfigMembers {
pub fn for_chain_type(chain_type: &ChainTypes) -> ConfigMembers {
let path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
let parsed = Settings::read_from_file::<ConfigMembers>(path.clone());
if !path.exists() || parsed.is_err() {
let mut default_config = GlobalConfig::for_chain(&chain_type);
let mut default_config = GlobalConfig::for_chain(chain_type);
default_config.update_paths(&Settings::get_working_path(Some(chain_type)));
let config = default_config.members.unwrap();
Settings::write_to_file(&config, path);
@ -62,14 +62,16 @@ impl NodeConfig {
/// Save node config to disk.
pub fn save(&mut self) {
let chain_type = self.members.server.chain_type;
let config_path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
let config_path = Settings::get_config_path(
SERVER_CONFIG_FILE_NAME,
Some(&self.members.server.chain_type)
);
Settings::write_to_file(&self.members, config_path);
}
/// Check that the api secret files exist and are valid.
fn check_api_secret_files(
chain_type: ChainTypes,
chain_type: &ChainTypes,
secret_file_name: &str,
) -> Result<(), ConfigError> {
let grin_path = Settings::get_working_path(Some(chain_type));
@ -83,7 +85,7 @@ impl NodeConfig {
}
/// Get stratum server IP address and port.
pub fn get_stratum_address_port() -> (String, u16) {
pub fn get_stratum_address_port() -> (String, String) {
let r_config = Settings::node_config_to_read();
let saved_stratum_addr = r_config
.members
@ -95,11 +97,11 @@ impl NodeConfig {
.as_ref()
.unwrap();
let (addr, port) = saved_stratum_addr.split_once(":").unwrap();
(addr.to_string(), port.parse().unwrap())
(addr.into(), port.into())
}
/// Save stratum server IP address and port.
pub fn save_stratum_address_port(addr: String, port: String) {
pub fn save_stratum_address_port(addr: &String, port: &String) {
let addr_to_save = format!("{}:{}", addr, port);
let mut w_node_config = Settings::node_config_to_update();
w_node_config
@ -112,8 +114,47 @@ impl NodeConfig {
w_node_config.save();
}
/// Check if stratum mining server autorun is enabled.
pub fn is_stratum_autorun_enabled() -> bool {
let stratum_config = Settings::node_config_to_read()
.members
.clone()
.server
.stratum_mining_config
.unwrap();
if let Some(enable) = stratum_config.enable_stratum_server {
return enable;
}
false
}
/// Toggle stratum mining server autorun.
pub fn toggle_stratum_autorun() {
let autorun = Self::is_stratum_autorun_enabled();
let mut w_node_config = Settings::node_config_to_update();
w_node_config.members
.server
.stratum_mining_config
.as_mut()
.unwrap()
.enable_stratum_server = Some(!autorun);
w_node_config.save();
}
/// Disable stratum mining server autorun.
pub fn disable_stratum_autorun() {
let mut w_node_config = Settings::node_config_to_update();
w_node_config.members
.server
.stratum_mining_config
.as_mut()
.unwrap()
.enable_stratum_server = Some(false);
w_node_config.save();
}
/// Get API server IP address and port.
pub fn get_api_address_port() -> (String, u16) {
pub fn get_api_address_port() -> (String, String) {
let r_config = Settings::node_config_to_read();
let saved_api_addr = r_config
.members
@ -121,11 +162,11 @@ impl NodeConfig {
.api_http_addr
.as_str();
let (addr, port) = saved_api_addr.split_once(":").unwrap();
(addr.to_string(), port.parse().unwrap())
(addr.into(), port.into())
}
/// Save API server IP address and port.
pub fn save_api_server_address_port(addr: String, port: String) {
pub fn save_api_address_port(addr: &String, port: &String) {
let addr_to_save = format!("{}:{}", addr, port);
let mut w_node_config = Settings::node_config_to_update();
w_node_config.members.server.api_http_addr = addr_to_save;
@ -149,7 +190,7 @@ impl NodeConfig {
}
/// Save API secret text.
pub fn save_api_secret(api_secret: String) {
pub fn save_api_secret(api_secret: &String) {
if api_secret.is_empty() {
return;
}
@ -181,7 +222,7 @@ impl NodeConfig {
}
/// Save Foreign API secret text.
pub fn save_foreign_api_secret(api_secret: String) {
pub fn save_foreign_api_secret(api_secret: &String) {
if api_secret.is_empty() {
return;
}

View file

@ -65,11 +65,9 @@ impl AppConfig {
}
/// Change chain type and load new [`NodeConfig`] accordingly.
pub fn change_chain_type(&mut self, chain_type: ChainTypes) {
if self.chain_type == chain_type {
return;
} else {
self.chain_type = chain_type;
pub fn change_chain_type(&mut self, chain_type: &ChainTypes) {
if self.chain_type != *chain_type {
self.chain_type = *chain_type;
self.save();
// Load config for selected chain type.
@ -95,10 +93,9 @@ impl Settings {
/// Initialize settings with app and node configs.
fn init() -> Self {
let app_config = AppConfig::init();
let chain_type = app_config.chain_type;
Self {
app_config: Arc::new(RwLock::new(app_config)),
node_config: Arc::new(RwLock::new(NodeConfig::init(chain_type)))
node_config: Arc::new(RwLock::new(NodeConfig::init(&app_config.chain_type))),
app_config: Arc::new(RwLock::new(app_config))
}
}
@ -123,7 +120,7 @@ impl Settings {
}
/// Get working directory path for the application.
pub fn get_working_path(chain_type: Option<ChainTypes>) -> PathBuf {
pub fn get_working_path(chain_type: Option<&ChainTypes>) -> PathBuf {
// Check if dir exists.
let mut path = match dirs::home_dir() {
Some(p) => p,
@ -141,7 +138,7 @@ impl Settings {
}
/// Get config file path from provided name and [`ChainTypes`] if needed.
pub fn get_config_path(config_name: &str, chain_type: Option<ChainTypes>) -> PathBuf {
pub fn get_config_path(config_name: &str, chain_type: Option<&ChainTypes>) -> PathBuf {
let main_path = Self::get_working_path(chain_type);
let mut settings_path = main_path.clone();
settings_path.push(config_name);