config + ui: config refactoring, stratum server launch, mining ui (without worker list yet)
This commit is contained in:
parent
d34889a801
commit
94a598a923
12 changed files with 352 additions and 146 deletions
|
@ -1,15 +1,16 @@
|
||||||
screen_accounts:
|
screen_accounts:
|
||||||
title: Accounts
|
title: Accounts
|
||||||
network:
|
network:
|
||||||
|
self: Network
|
||||||
node: Integrated node
|
node: Integrated node
|
||||||
metrics: Metrics
|
metrics: Network metrics
|
||||||
mining: Mining
|
mining: Mining
|
||||||
settings: Server settings
|
settings: Node settings
|
||||||
enable: Enable
|
enable_node: Enable node
|
||||||
disable: Disable
|
disable: Disable
|
||||||
restart: Restart
|
restart: Restart
|
||||||
autorun: Autorun
|
autorun: Autorun
|
||||||
disabled_server: 'Enable server or choose another connection method by pressing %{dots} on top left corner of the screen.'
|
disabled_server: 'Enable integrated node or choose another connection method by pressing %{dots} in the top-left corner of the screen.'
|
||||||
sync_status:
|
sync_status:
|
||||||
server_restarting: Server is restarting
|
server_restarting: Server is restarting
|
||||||
server_down: Server is down
|
server_down: Server is down
|
||||||
|
@ -51,7 +52,20 @@ network_metrics:
|
||||||
supply: Supply
|
supply: Supply
|
||||||
block_time: Block time
|
block_time: Block time
|
||||||
reward: Reward
|
reward: Reward
|
||||||
difficulty_window: 'Difficulty at window %{size}'
|
difficulty_window: 'Difficulty window %{size}'
|
||||||
|
network_mining:
|
||||||
|
loading: Mining will be available after the synchronization
|
||||||
|
enable_server: Enable server
|
||||||
|
disabled_server: 'Enable stratum server at %{address} or change settings by selecting %{settings} at the bottom of the screen.'
|
||||||
|
starting: Stratum server is starting
|
||||||
|
info: 'Mining server is enabled, you can change settings by selecting %{settings} at the bottom of the screen. Data is updating when devices are connected.'
|
||||||
|
address: IP Address
|
||||||
|
wallet: Wallet Address
|
||||||
|
server: Stratum server
|
||||||
|
miners: Miners
|
||||||
|
devices: Devices
|
||||||
|
blocks_found: Blocks found
|
||||||
|
hashrate: Hashrate
|
||||||
modal:
|
modal:
|
||||||
cancel: Cancel
|
cancel: Cancel
|
||||||
modal_exit:
|
modal_exit:
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
screen_accounts:
|
screen_accounts:
|
||||||
title: Аккаунты
|
title: Аккаунты
|
||||||
network:
|
network:
|
||||||
|
self: Сеть
|
||||||
node: Встроенный узел
|
node: Встроенный узел
|
||||||
metrics: Метрики
|
metrics: Показатели сети
|
||||||
mining: Майнинг
|
mining: Майнинг
|
||||||
settings: Настройки сервера
|
settings: Настройки узла
|
||||||
enable: Включить
|
enable_node: Включить узел
|
||||||
disable: Выключить
|
disable: Выключить
|
||||||
restart: Перезапустить
|
restart: Перезапустить
|
||||||
autorun: Автозапуск
|
autorun: Автозапуск
|
||||||
disabled_server: 'Включите сервер или выберите другой способ подключения, нажав %{dots} в левом верхнем углу экрана.'
|
disabled_server: 'Включите встроенный узел или выберите другой способ подключения, нажав %{dots} в левом-верхнем углу экрана.'
|
||||||
sync_status:
|
sync_status:
|
||||||
server_restarting: Сервер перезапускается
|
server_restarting: Сервер перезапускается
|
||||||
server_down: Сервер выключен
|
server_down: Сервер выключен
|
||||||
|
@ -51,7 +52,20 @@ network_metrics:
|
||||||
supply: Предложение
|
supply: Предложение
|
||||||
block_time: Время блока
|
block_time: Время блока
|
||||||
reward: Награда
|
reward: Награда
|
||||||
difficulty_window: 'Сложность в окне %{size}'
|
difficulty_window: 'Окно сложности %{size}'
|
||||||
|
network_mining:
|
||||||
|
loading: Майнинг будет доступен после синхронизации
|
||||||
|
enable_server: Включить сервер
|
||||||
|
disabled_server: 'Включите stratum-сервер по адресу %{address} или измените настройки, выбрав %{settings} внизу экрана.'
|
||||||
|
starting: Stratum-сервер запускается
|
||||||
|
info: 'Сервер майнинга запущен, вы можете изменить настройки, выбрав %{settings} внизу экрана. Данные обновляются, когда устройства подключены.'
|
||||||
|
address: IP Адрес
|
||||||
|
wallet: Адрес кошелька
|
||||||
|
server: Stratum-сервер
|
||||||
|
miners: Майнеры
|
||||||
|
devices: Устройства
|
||||||
|
found: Найдено
|
||||||
|
hashrate: Хешрэйт
|
||||||
modal:
|
modal:
|
||||||
cancel: Отмена
|
cancel: Отмена
|
||||||
modal_exit:
|
modal_exit:
|
||||||
|
|
|
@ -74,7 +74,7 @@ fn start(mut options: NativeOptions, app_creator: AppCreator) {
|
||||||
|
|
||||||
setup_i18n();
|
setup_i18n();
|
||||||
|
|
||||||
if Settings::get_app_config().auto_start_node {
|
if Settings::app_config_to_read().auto_start_node {
|
||||||
Node::start();
|
Node::start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use egui_extras::{Size, StripBuilder};
|
||||||
use grin_chain::SyncStatus;
|
use grin_chain::SyncStatus;
|
||||||
|
|
||||||
use crate::gui::{Colors, Navigator};
|
use crate::gui::{Colors, Navigator};
|
||||||
use crate::gui::icons::{CARDHOLDER, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE, POWER};
|
use crate::gui::icons::{CARDHOLDER, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE};
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::views::network_metrics::NetworkMetrics;
|
use crate::gui::views::network_metrics::NetworkMetrics;
|
||||||
use crate::gui::views::network_mining::NetworkMining;
|
use crate::gui::views::network_mining::NetworkMining;
|
||||||
|
@ -32,7 +32,6 @@ use crate::Settings;
|
||||||
|
|
||||||
pub trait NetworkTab {
|
pub trait NetworkTab {
|
||||||
fn get_type(&self) -> NetworkTabType;
|
fn get_type(&self) -> NetworkTabType;
|
||||||
fn name(&self) -> String;
|
|
||||||
fn ui(&mut self, ui: &mut egui::Ui);
|
fn ui(&mut self, ui: &mut egui::Ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +43,17 @@ pub enum NetworkTabType {
|
||||||
Settings
|
Settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NetworkTabType {
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
match *self {
|
||||||
|
NetworkTabType::Node => { t!("network.node") }
|
||||||
|
NetworkTabType::Metrics => { t!("network.metrics") }
|
||||||
|
NetworkTabType::Mining => { t!("network.mining") }
|
||||||
|
NetworkTabType::Settings => { t!("network.settings") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Network {
|
pub struct Network {
|
||||||
current_tab: Box<dyn NetworkTab>,
|
current_tab: Box<dyn NetworkTab>,
|
||||||
}
|
}
|
||||||
|
@ -101,26 +111,22 @@ impl Network {
|
||||||
|
|
||||||
ui.columns(4, |columns| {
|
ui.columns(4, |columns| {
|
||||||
columns[0].vertical_centered_justified(|ui| {
|
columns[0].vertical_centered_justified(|ui| {
|
||||||
View::tab_button(ui, DATABASE,
|
View::tab_button(ui, DATABASE, self.is_current_tab(NetworkTabType::Node), || {
|
||||||
self.current_tab.get_type() == NetworkTabType::Node, || {
|
|
||||||
self.current_tab = Box::new(NetworkNode::default());
|
self.current_tab = Box::new(NetworkNode::default());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
columns[1].vertical_centered_justified(|ui| {
|
columns[1].vertical_centered_justified(|ui| {
|
||||||
View::tab_button(ui, GAUGE,
|
View::tab_button(ui, GAUGE, self.is_current_tab(NetworkTabType::Metrics), || {
|
||||||
self.current_tab.get_type() == NetworkTabType::Metrics, || {
|
|
||||||
self.current_tab = Box::new(NetworkMetrics::default());
|
self.current_tab = Box::new(NetworkMetrics::default());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
columns[2].vertical_centered_justified(|ui| {
|
columns[2].vertical_centered_justified(|ui| {
|
||||||
View::tab_button(ui, FACTORY,
|
View::tab_button(ui, FACTORY, self.is_current_tab(NetworkTabType::Mining), || {
|
||||||
self.current_tab.get_type() == NetworkTabType::Mining, || {
|
|
||||||
self.current_tab = Box::new(NetworkMining::default());
|
self.current_tab = Box::new(NetworkMining::default());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
columns[3].vertical_centered_justified(|ui| {
|
columns[3].vertical_centered_justified(|ui| {
|
||||||
View::tab_button(ui, FADERS,
|
View::tab_button(ui, FADERS, self.is_current_tab(NetworkTabType::Settings), || {
|
||||||
self.current_tab.get_type() == NetworkTabType::Settings, || {
|
|
||||||
self.current_tab = Box::new(NetworkSettings::default());
|
self.current_tab = Box::new(NetworkSettings::default());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -128,6 +134,10 @@ impl Network {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_current_tab(&self, tab_type: NetworkTabType) -> bool {
|
||||||
|
self.current_tab.get_type() == tab_type
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_title(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
|
fn draw_title(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
|
||||||
StripBuilder::new(ui)
|
StripBuilder::new(ui)
|
||||||
.size(Size::exact(52.0))
|
.size(Size::exact(52.0))
|
||||||
|
@ -170,7 +180,7 @@ impl Network {
|
||||||
strip.cell(|ui| {
|
strip.cell(|ui| {
|
||||||
ui.add_space(2.0);
|
ui.add_space(2.0);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
ui.label(RichText::new(self.current_tab.name().to_uppercase())
|
ui.label(RichText::new(self.current_tab.get_type().name().to_uppercase())
|
||||||
.size(18.0)
|
.size(18.0)
|
||||||
.color(Colors::TITLE));
|
.color(Colors::TITLE));
|
||||||
});
|
});
|
||||||
|
@ -217,15 +227,15 @@ impl Network {
|
||||||
|
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
|
|
||||||
View::button(ui, format!("{} {}", POWER, t!("network.enable")), Colors::GOLD, || {
|
View::button(ui, t!("network.enable_node"), Colors::GOLD, || {
|
||||||
Node::start();
|
Node::start();
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.add_space(4.0);
|
ui.add_space(2.0);
|
||||||
|
|
||||||
let autostart: bool = Settings::get_app_config().auto_start_node;
|
let autostart: bool = Settings::app_config_to_read().auto_start_node;
|
||||||
View::checkbox(ui, autostart, t!("network.autorun"), || {
|
View::checkbox(ui, autostart, t!("network.autorun"), || {
|
||||||
let mut w_app_config = Settings::get_app_config_to_update();
|
let mut w_app_config = Settings::app_config_to_update();
|
||||||
w_app_config.auto_start_node = !autostart;
|
w_app_config.auto_start_node = !autostart;
|
||||||
w_app_config.save();
|
w_app_config.save();
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,23 +34,19 @@ impl NetworkTab for NetworkMetrics {
|
||||||
NetworkTabType::Metrics
|
NetworkTabType::Metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
|
||||||
t!("network.metrics")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
let server_stats = Node::get_stats();
|
let server_stats = Node::get_stats();
|
||||||
// Show loading spinner when stats are not available or message when server is not enabled.
|
// Show message when node is not running or loading spinner when metrics are not available.
|
||||||
if server_stats.is_none() || server_stats.as_ref().unwrap().diff_stats.height == 0 {
|
if server_stats.is_none() || server_stats.as_ref().unwrap().diff_stats.height == 0 {
|
||||||
if !Node::is_running() {
|
if !Node::is_running() {
|
||||||
Network::disabled_server_content(ui);
|
Network::disabled_server_content(ui);
|
||||||
} else {
|
} else {
|
||||||
View::center_content(ui, 160.0, |ui| {
|
View::center_content(ui, 162.0, |ui| {
|
||||||
View::big_loading_spinner(ui);
|
View::big_loading_spinner(ui);
|
||||||
ui.add_space(18.0);
|
ui.add_space(18.0);
|
||||||
ui.label(RichText::new(t!("network_metrics.loading"))
|
ui.label(RichText::new(t!("network_metrics.loading"))
|
||||||
.size(16.0)
|
.size(16.0)
|
||||||
.color(Colors::TEXT)
|
.color(Colors::INACTIVE_TEXT)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -88,7 +84,7 @@ impl NetworkTab for NetworkMetrics {
|
||||||
[false, true, false, true]);
|
[false, true, false, true]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(4.0);
|
||||||
|
|
||||||
// Show difficulty adjustment window info
|
// Show difficulty adjustment window info
|
||||||
ui.vertical_centered_justified(|ui| {
|
ui.vertical_centered_justified(|ui| {
|
||||||
|
@ -119,7 +115,7 @@ impl NetworkTab for NetworkMetrics {
|
||||||
[false, true, false, true]);
|
[false, true, false, true]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(4.0);
|
||||||
|
|
||||||
// Show difficulty adjustment window blocks
|
// Show difficulty adjustment window blocks
|
||||||
let blocks_size = stats.diff_stats.last_blocks.len();
|
let blocks_size = stats.diff_stats.last_blocks.len();
|
||||||
|
|
|
@ -12,9 +12,14 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use egui::RichText;
|
||||||
|
use grin_chain::SyncStatus;
|
||||||
|
|
||||||
use crate::gui::Colors;
|
use crate::gui::Colors;
|
||||||
|
use crate::gui::icons::{COMPUTER_TOWER, CPU, FADERS, POLYGON};
|
||||||
use crate::gui::views::{Network, NetworkTab, NetworkTabType, View};
|
use crate::gui::views::{Network, NetworkTab, NetworkTabType, View};
|
||||||
use crate::node::Node;
|
use crate::node::Node;
|
||||||
|
use crate::Settings;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct NetworkMining;
|
pub struct NetworkMining;
|
||||||
|
@ -24,25 +29,184 @@ impl NetworkTab for NetworkMining {
|
||||||
NetworkTabType::Mining
|
NetworkTabType::Mining
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
|
||||||
t!("network.mining")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
let server_stats = Node::get_stats();
|
let server_stats = Node::get_stats();
|
||||||
// Show loading spinner when stats are not available or message when server is not enabled.
|
// Show message when node is not running or loading spinner when mining are not available.
|
||||||
if !server_stats.is_some() {
|
if !server_stats.is_some() || Node::get_sync_status().unwrap() != SyncStatus::NoSync {
|
||||||
if !Node::is_running() {
|
if !Node::is_running() {
|
||||||
Network::disabled_server_content(ui);
|
Network::disabled_server_content(ui);
|
||||||
} else {
|
} else {
|
||||||
ui.centered_and_justified(|ui| {
|
View::center_content(ui, 162.0, |ui| {
|
||||||
View::big_loading_spinner(ui);
|
View::big_loading_spinner(ui);
|
||||||
|
ui.add_space(18.0);
|
||||||
|
ui.label(RichText::new(t!("network_mining.loading"))
|
||||||
|
.size(16.0)
|
||||||
|
.color(Colors::INACTIVE_TEXT)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stats = server_stats.as_ref().unwrap();
|
// Stratum mining server address.
|
||||||
|
let stratum_address = Settings::node_config_to_read()
|
||||||
|
.members.clone()
|
||||||
|
.server.stratum_mining_config.unwrap()
|
||||||
|
.stratum_server_addr.unwrap();
|
||||||
|
|
||||||
|
let stratum_stats = &server_stats.as_ref().unwrap().stratum_stats;
|
||||||
|
if !stratum_stats.is_running && !Node::is_stratum_server_starting() {
|
||||||
|
// Show Stratum setup when mining server is not enabled.
|
||||||
|
View::center_content(ui, 162.0, |ui| {
|
||||||
|
let text = t!(
|
||||||
|
"network_mining.disabled_server",
|
||||||
|
"address" => stratum_address,
|
||||||
|
"settings" => FADERS
|
||||||
|
);
|
||||||
|
ui.label(RichText::new(text)
|
||||||
|
.size(16.0)
|
||||||
|
.color(Colors::INACTIVE_TEXT)
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
|
||||||
|
View::button(ui, t!("network_mining.enable_server"), Colors::GOLD, || {
|
||||||
|
Node::start_stratum_server();
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.add_space(2.0);
|
||||||
|
|
||||||
|
// Check if stratum server is enabled at config
|
||||||
|
let stratum_enabled = Settings::node_config_to_read()
|
||||||
|
.members.clone()
|
||||||
|
.server.stratum_mining_config.unwrap()
|
||||||
|
.enable_stratum_server.unwrap();
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} else if Node::is_stratum_server_starting() {
|
||||||
|
// Show loading spinner when mining server is starting.
|
||||||
|
View::center_content(ui, 162.0, |ui| {
|
||||||
|
View::big_loading_spinner(ui);
|
||||||
|
ui.add_space(18.0);
|
||||||
|
ui.label(RichText::new(t!("network_mining.starting"))
|
||||||
|
.size(16.0)
|
||||||
|
.color(Colors::INACTIVE_TEXT)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show stratum mining server info.
|
||||||
|
ui.vertical_centered_justified(|ui| {
|
||||||
|
View::sub_header(ui, format!("{} {}", COMPUTER_TOWER, t!("network_mining.server")));
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
|
|
||||||
|
ui.columns(2, |columns| {
|
||||||
|
columns[0].vertical_centered(|ui| {
|
||||||
|
View::rounded_box(ui,
|
||||||
|
stratum_address,
|
||||||
|
t!("network_mining.address"),
|
||||||
|
[true, false, true, false]);
|
||||||
|
});
|
||||||
|
columns[1].vertical_centered(|ui| {
|
||||||
|
// Stratum mining wallet address.
|
||||||
|
let wallet_address = Settings::node_config_to_read()
|
||||||
|
.members.clone()
|
||||||
|
.server.stratum_mining_config.unwrap()
|
||||||
|
.wallet_listener_url;
|
||||||
|
View::rounded_box(ui,
|
||||||
|
wallet_address,
|
||||||
|
t!("network_mining.wallet"),
|
||||||
|
[false, true, false, true]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
|
|
||||||
|
// Show network info.
|
||||||
|
ui.vertical_centered_justified(|ui| {
|
||||||
|
View::sub_header(ui, format!("{} {}", POLYGON, t!("network.self")));
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
|
|
||||||
|
ui.columns(3, |columns| {
|
||||||
|
columns[0].vertical_centered(|ui| {
|
||||||
|
let difficulty = if stratum_stats.network_difficulty > 0 {
|
||||||
|
stratum_stats.network_difficulty.to_string()
|
||||||
|
} else {
|
||||||
|
"-".into()
|
||||||
|
};
|
||||||
|
View::rounded_box(ui,
|
||||||
|
difficulty,
|
||||||
|
t!("network_node.difficulty"),
|
||||||
|
[true, false, true, false]);
|
||||||
|
});
|
||||||
|
columns[1].vertical_centered(|ui| {
|
||||||
|
let block_height = if stratum_stats.block_height > 0 {
|
||||||
|
stratum_stats.block_height.to_string()
|
||||||
|
} else {
|
||||||
|
"-".into()
|
||||||
|
};
|
||||||
|
View::rounded_box(ui,
|
||||||
|
block_height,
|
||||||
|
t!("network_node.header"),
|
||||||
|
[false, false, false, false]);
|
||||||
|
});
|
||||||
|
columns[2].vertical_centered(|ui| {
|
||||||
|
let hashrate = if stratum_stats.network_hashrate > 0.0 {
|
||||||
|
stratum_stats.network_hashrate.to_string()
|
||||||
|
} else {
|
||||||
|
"-".into()
|
||||||
|
};
|
||||||
|
View::rounded_box(ui,
|
||||||
|
hashrate,
|
||||||
|
t!("network_mining.hashrate"),
|
||||||
|
[false, true, false, true]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
|
|
||||||
|
// Show mining info.
|
||||||
|
ui.vertical_centered_justified(|ui| {
|
||||||
|
View::sub_header(ui, format!("{} {}", CPU, t!("network_mining.miners")));
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
|
|
||||||
|
ui.columns(2, |columns| {
|
||||||
|
columns[0].vertical_centered(|ui| {
|
||||||
|
View::rounded_box(ui,
|
||||||
|
stratum_stats.num_workers.to_string(),
|
||||||
|
t!("network_mining.devices"),
|
||||||
|
[true, false, true, false]);
|
||||||
|
});
|
||||||
|
|
||||||
|
columns[1].vertical_centered(|ui| {
|
||||||
|
View::rounded_box(ui,
|
||||||
|
stratum_stats.blocks_found.to_string(),
|
||||||
|
t!("network_mining.blocks_found"),
|
||||||
|
[false, true, false, true]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
|
|
||||||
|
// Show miners info.
|
||||||
|
if !stratum_stats.worker_stats.is_empty() {
|
||||||
|
//TODO: miners workers
|
||||||
|
} else if ui.available_height() > 142.0 {
|
||||||
|
View::center_content(ui, 142.0, |ui| {
|
||||||
|
ui.label(RichText::new(t!("network_mining.info", "settings" => FADERS))
|
||||||
|
.size(16.0)
|
||||||
|
.color(Colors::INACTIVE_TEXT)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,16 +26,12 @@ pub struct NetworkNode;
|
||||||
|
|
||||||
impl NetworkTab for NetworkNode {
|
impl NetworkTab for NetworkNode {
|
||||||
fn get_type(&self) -> NetworkTabType {
|
fn get_type(&self) -> NetworkTabType {
|
||||||
NetworkTabType::Metrics
|
NetworkTabType::Node
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> String {
|
|
||||||
t!("network.node")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
let server_stats = Node::get_stats();
|
let server_stats = Node::get_stats();
|
||||||
// Show loading spinner when stats are not available or message when server is not enabled.
|
// Show message when node is not running or loading spinner when stats are not available.
|
||||||
if !server_stats.is_some() {
|
if !server_stats.is_some() {
|
||||||
if !Node::is_running() {
|
if !Node::is_running() {
|
||||||
Network::disabled_server_content(ui);
|
Network::disabled_server_content(ui);
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use grin_core::global::ChainTypes;
|
||||||
use crate::gui::views::{NetworkTab, NetworkTabType};
|
use crate::gui::views::{NetworkTab, NetworkTabType};
|
||||||
|
use crate::Settings;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct NetworkSettings;
|
pub struct NetworkSettings;
|
||||||
|
@ -22,11 +24,6 @@ impl NetworkTab for NetworkSettings {
|
||||||
NetworkTabType::Settings
|
NetworkTabType::Settings
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
|
||||||
t!("network.settings")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -196,27 +196,19 @@ impl View {
|
||||||
Spinner::new().size(48.0).color(Colors::GOLD).ui(ui);
|
Spinner::new().size(48.0).color(Colors::GOLD).ui(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let wt = RichText::new(text.to_uppercase()).size(18.0).color(Colors::BUTTON);
|
/// Draw the button that looks like checkbox with callback after change.
|
||||||
// let br = Button::new(wt)
|
pub fn checkbox(ui: &mut egui::Ui, checked: bool, text: String, callback: impl FnOnce()) {
|
||||||
// .stroke(Self::DEFAULT_STROKE)
|
let text_value = match checked {
|
||||||
// .fill(fill_color)
|
|
||||||
// .ui(ui).interact(Sense::click_and_drag());
|
|
||||||
//
|
|
||||||
// Self::on_button_click(ui, br, action);
|
|
||||||
|
|
||||||
/// Draw button that looks like checkbox with callback to change value.
|
|
||||||
pub fn checkbox(ui: &mut egui::Ui, value: bool, text: String, cb: impl FnOnce()) {
|
|
||||||
let text_value = match value {
|
|
||||||
true => { format!("{} {}", CHECK_SQUARE, text)}
|
true => { format!("{} {}", CHECK_SQUARE, text)}
|
||||||
false => { format!("{} {}", SQUARE, text)}
|
false => { format!("{} {}", SQUARE, text)}
|
||||||
};
|
};
|
||||||
let wt = RichText::new(text_value).size(18.0).color(Colors::BUTTON);
|
let wt = RichText::new(text_value).size(19.0).color(Colors::BUTTON);
|
||||||
let br = Button::new(wt)
|
let br = Button::new(wt)
|
||||||
.frame(false)
|
.frame(false)
|
||||||
.stroke(Stroke::NONE)
|
.stroke(Stroke::NONE)
|
||||||
.fill(Colors::TRANSPARENT)
|
.fill(Colors::TRANSPARENT)
|
||||||
.ui(ui).interact(Sense::click_and_drag());
|
.ui(ui).interact(Sense::click_and_drag());
|
||||||
|
|
||||||
Self::on_button_click(ui, br, cb);
|
Self::on_button_click(ui, br, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,11 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::{fs, thread};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
|
|
||||||
use grin_config::{config, ConfigError, ConfigMembers, GlobalConfig};
|
use grin_config::{config, ConfigError, ConfigMembers, GlobalConfig};
|
||||||
use grin_config::config::{API_SECRET_FILE_NAME, FOREIGN_API_SECRET_FILE_NAME, SERVER_CONFIG_FILE_NAME};
|
use grin_config::config::{API_SECRET_FILE_NAME, FOREIGN_API_SECRET_FILE_NAME, SERVER_CONFIG_FILE_NAME};
|
||||||
use grin_core::global::ChainTypes;
|
use grin_core::global::ChainTypes;
|
||||||
|
@ -24,70 +19,49 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::Settings;
|
use crate::Settings;
|
||||||
|
|
||||||
/// Node config that contains [`GlobalConfig`] to be used by [`grin_servers::Server`].
|
/// Wrapped node config to be used by [`grin_servers::Server`].
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct NodeConfig {
|
pub struct NodeConfig {
|
||||||
pub global_config: GlobalConfig,
|
pub members: ConfigMembers
|
||||||
update_needed: AtomicBool,
|
|
||||||
updating: AtomicBool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeConfig {
|
impl NodeConfig {
|
||||||
/// Initialize node config with provided chain type from the disk.
|
/// 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, API_SECRET_FILE_NAME);
|
||||||
let _ = Self::check_api_secret_files(chain_type, FOREIGN_API_SECRET_FILE_NAME);
|
let _ = Self::check_api_secret_files(chain_type, FOREIGN_API_SECRET_FILE_NAME);
|
||||||
|
|
||||||
let config_path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
|
let config_members = Self::for_chain_type(chain_type);
|
||||||
|
|
||||||
// Create default config if it doesn't exist or has wrong format.
|
|
||||||
if !config_path.exists() || toml::from_str::<ConfigMembers>(
|
|
||||||
fs::read_to_string(config_path.clone()).unwrap().as_str()
|
|
||||||
).is_err() {
|
|
||||||
let mut default_config = GlobalConfig::for_chain(chain_type);
|
|
||||||
default_config.update_paths(&Settings::get_working_path(Some(chain_type)));
|
|
||||||
let _ = default_config.write_to_file(config_path.to_str().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
let config = GlobalConfig::new(config_path.to_str().unwrap());
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
global_config: config.unwrap(),
|
members: config_members
|
||||||
update_needed: AtomicBool::new(false),
|
|
||||||
updating: AtomicBool::new(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write node config on disk.
|
/// Initialize config with provided [`ChainTypes`].
|
||||||
pub fn save_config(&self) {
|
pub fn for_chain_type(chain_type: ChainTypes) -> ConfigMembers {
|
||||||
if self.updating.load(Ordering::Relaxed) {
|
let path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
|
||||||
self.update_needed.store(true, Ordering::Relaxed);
|
let parsed = Settings::read_from_file::<ConfigMembers>(path.clone());
|
||||||
return;
|
if !path.exists() || parsed.is_err() {
|
||||||
|
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);
|
||||||
|
config
|
||||||
|
} else {
|
||||||
|
parsed.unwrap()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
thread::spawn(move || loop {
|
/// Save node config to disk.
|
||||||
let config = Settings::get_node_config();
|
pub fn save(&mut self) {
|
||||||
config.update_needed.store(false, Ordering::Relaxed);
|
let chain_type = self.members.server.chain_type;
|
||||||
config.updating.store(true, Ordering::Relaxed);
|
let config_path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
|
||||||
|
Settings::write_to_file(&self.members, config_path);
|
||||||
let chain_type = &config.global_config.members.clone().unwrap().server.chain_type;
|
|
||||||
let config_path = Settings::get_config_path(SERVER_CONFIG_FILE_NAME, Some(chain_type));
|
|
||||||
|
|
||||||
// Write config to file.
|
|
||||||
let conf_out = toml::to_string(&config.global_config.members).unwrap();
|
|
||||||
let mut file = File::create(config_path.to_str().unwrap()).unwrap();
|
|
||||||
file.write_all(conf_out.as_bytes()).unwrap();
|
|
||||||
|
|
||||||
if !config.update_needed.load(Ordering::Relaxed) {
|
|
||||||
config.updating.store(false, Ordering::Relaxed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that the api secret files exist and are valid.
|
/// Check that the api secret files exist and are valid.
|
||||||
fn check_api_secret_files(
|
fn check_api_secret_files(
|
||||||
chain_type: &ChainTypes,
|
chain_type: ChainTypes,
|
||||||
secret_file_name: &str,
|
secret_file_name: &str,
|
||||||
) -> Result<(), ConfigError> {
|
) -> Result<(), ConfigError> {
|
||||||
let grin_path = Settings::get_working_path(Some(chain_type));
|
let grin_path = Settings::get_working_path(Some(chain_type));
|
||||||
|
|
|
@ -45,7 +45,9 @@ pub struct Node {
|
||||||
/// Thread flag to stop the server.
|
/// Thread flag to stop the server.
|
||||||
stop_needed: AtomicBool,
|
stop_needed: AtomicBool,
|
||||||
/// Flag to check if app exit is needed after server stop.
|
/// Flag to check if app exit is needed after server stop.
|
||||||
exit_after_stop: AtomicBool
|
exit_after_stop: AtomicBool,
|
||||||
|
/// Thread flag to start stratum server at separate.
|
||||||
|
start_stratum_server: AtomicBool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Node {
|
impl Default for Node {
|
||||||
|
@ -55,7 +57,8 @@ impl Default for Node {
|
||||||
starting: AtomicBool::new(false),
|
starting: AtomicBool::new(false),
|
||||||
restart_needed: AtomicBool::new(false),
|
restart_needed: AtomicBool::new(false),
|
||||||
stop_needed: AtomicBool::new(false),
|
stop_needed: AtomicBool::new(false),
|
||||||
exit_after_stop: AtomicBool::new(false)
|
exit_after_stop: AtomicBool::new(false),
|
||||||
|
start_stratum_server: AtomicBool::new(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,6 +86,16 @@ impl Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Start stratum server.
|
||||||
|
pub fn start_stratum_server() {
|
||||||
|
NODE_STATE.start_stratum_server.store(true, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if stratum server is starting.
|
||||||
|
pub fn is_stratum_server_starting() -> bool {
|
||||||
|
NODE_STATE.start_stratum_server.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if node is starting.
|
/// Check if node is starting.
|
||||||
pub fn is_starting() -> bool {
|
pub fn is_starting() -> bool {
|
||||||
NODE_STATE.starting.load(Ordering::Relaxed)
|
NODE_STATE.starting.load(Ordering::Relaxed)
|
||||||
|
@ -164,8 +177,20 @@ impl Node {
|
||||||
|
|
||||||
NODE_STATE.starting.store(false, Ordering::Relaxed);
|
NODE_STATE.starting.store(false, Ordering::Relaxed);
|
||||||
NODE_STATE.stop_needed.store(false, Ordering::Relaxed);
|
NODE_STATE.stop_needed.store(false, Ordering::Relaxed);
|
||||||
|
NODE_STATE.start_stratum_server.store(false, Ordering::Relaxed);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
if Self::is_stratum_server_starting() {
|
||||||
|
// Start mining server.
|
||||||
|
let stratum_config = server.config.stratum_mining_config.clone().unwrap();
|
||||||
|
server.start_stratum_server(stratum_config);
|
||||||
|
|
||||||
|
// Wait for mining server to start and update status.
|
||||||
|
thread::sleep(Duration::from_millis(1000));
|
||||||
|
|
||||||
|
NODE_STATE.start_stratum_server.store(false, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
let stats = server.get_server_stats();
|
let stats = server.get_server_stats();
|
||||||
if stats.is_ok() {
|
if stats.is_ok() {
|
||||||
// Update server stats.
|
// Update server stats.
|
||||||
|
@ -308,8 +333,8 @@ impl Node {
|
||||||
/// Start the node [`Server`].
|
/// Start the node [`Server`].
|
||||||
fn start_server() -> Server {
|
fn start_server() -> Server {
|
||||||
// Get current global config
|
// Get current global config
|
||||||
let config = &Settings::get_node_config().global_config;
|
let config = &Settings::node_config_to_read().members;
|
||||||
let server_config = config.members.as_ref().unwrap().server.clone();
|
let server_config = config.server.clone();
|
||||||
|
|
||||||
// Remove temporary file dir
|
// Remove temporary file dir
|
||||||
{
|
{
|
||||||
|
@ -328,7 +353,7 @@ fn start_server() -> Server {
|
||||||
// accept_fee_base, and future_time_limit.
|
// accept_fee_base, and future_time_limit.
|
||||||
// These are read via global and not read from config beyond this point.
|
// These are read via global and not read from config beyond this point.
|
||||||
if !global::GLOBAL_CHAIN_TYPE.is_init() {
|
if !global::GLOBAL_CHAIN_TYPE.is_init() {
|
||||||
global::init_global_chain_type(config.members.as_ref().unwrap().server.chain_type);
|
global::init_global_chain_type(config.server.chain_type);
|
||||||
}
|
}
|
||||||
info!("Chain: {:?}", global::get_chain_type());
|
info!("Chain: {:?}", global::get_chain_type());
|
||||||
|
|
||||||
|
@ -345,12 +370,12 @@ fn start_server() -> Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !global::GLOBAL_ACCEPT_FEE_BASE.is_init() {
|
if !global::GLOBAL_ACCEPT_FEE_BASE.is_init() {
|
||||||
let afb = config.members.as_ref().unwrap().server.pool_config.accept_fee_base;
|
let afb = config.server.pool_config.accept_fee_base;
|
||||||
global::init_global_accept_fee_base(afb);
|
global::init_global_accept_fee_base(afb);
|
||||||
info!("Accept Fee Base: {:?}", global::get_accept_fee_base());
|
info!("Accept Fee Base: {:?}", global::get_accept_fee_base());
|
||||||
}
|
}
|
||||||
if !global::GLOBAL_FUTURE_TIME_LIMIT.is_init() {
|
if !global::GLOBAL_FUTURE_TIME_LIMIT.is_init() {
|
||||||
let future_time_limit = config.members.as_ref().unwrap().server.future_time_limit;
|
let future_time_limit = config.server.future_time_limit;
|
||||||
global::init_global_future_time_limit(future_time_limit);
|
global::init_global_future_time_limit(future_time_limit);
|
||||||
info!("Future Time Limit: {:?}", global::get_future_time_limit());
|
info!("Future Time Limit: {:?}", global::get_future_time_limit());
|
||||||
}
|
}
|
||||||
|
@ -417,13 +442,12 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_getSyncTitle(
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
/// Check if app exit is needed after node stop.
|
/// Check if app exit is needed after node stop to finish Android app at background.
|
||||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_exitAppAfterNodeStop(
|
pub extern "C" fn Java_mw_gri_android_BackgroundService_exitAppAfterNodeStop(
|
||||||
_env: jni::JNIEnv,
|
_env: jni::JNIEnv,
|
||||||
_class: jni::objects::JObject,
|
_class: jni::objects::JObject,
|
||||||
_activity: jni::objects::JObject,
|
_activity: jni::objects::JObject,
|
||||||
) -> jboolean {
|
) -> jboolean {
|
||||||
let exit_after_stop = NODE_STATE.exit_after_stop.load(Ordering::Relaxed);
|
let exit_needed = !Node::is_running() && NODE_STATE.exit_after_stop.load(Ordering::Relaxed);
|
||||||
let is_app_exit_needed = !Node::is_running() && exit_after_stop;
|
return exit_needed as jboolean;
|
||||||
return is_app_exit_needed as jboolean;
|
|
||||||
}
|
}
|
|
@ -38,7 +38,7 @@ pub struct AppConfig {
|
||||||
/// Run node server on startup.
|
/// Run node server on startup.
|
||||||
pub auto_start_node: bool,
|
pub auto_start_node: bool,
|
||||||
/// Chain type for node server.
|
/// Chain type for node server.
|
||||||
pub node_chain_type: ChainTypes
|
node_chain_type: ChainTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppConfig {
|
impl Default for AppConfig {
|
||||||
|
@ -53,62 +53,87 @@ impl Default for AppConfig {
|
||||||
impl AppConfig {
|
impl AppConfig {
|
||||||
/// Initialize application config from the disk.
|
/// Initialize application config from the disk.
|
||||||
pub fn init() -> Self {
|
pub fn init() -> Self {
|
||||||
let config_path = Settings::get_config_path(APP_CONFIG_FILE_NAME, None);
|
let path = Settings::get_config_path(APP_CONFIG_FILE_NAME, None);
|
||||||
let parsed = Settings::read_from_file::<AppConfig>(config_path.clone());
|
let parsed = Settings::read_from_file::<AppConfig>(path.clone());
|
||||||
if !config_path.exists() || parsed.is_err() {
|
if !path.exists() || parsed.is_err() {
|
||||||
let default_config = AppConfig::default();
|
let default_config = AppConfig::default();
|
||||||
Settings::write_to_file(&default_config, config_path);
|
Settings::write_to_file(&default_config, path);
|
||||||
default_config
|
default_config
|
||||||
} else {
|
} else {
|
||||||
parsed.unwrap()
|
parsed.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change chain type and load new [`NodeConfig`] accordingly.
|
||||||
|
pub fn change_chain_type(&mut self, chain_type: ChainTypes) {
|
||||||
|
if self.node_chain_type == chain_type {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self.node_chain_type = chain_type;
|
||||||
|
self.save();
|
||||||
|
|
||||||
|
// Load config for selected chain type.
|
||||||
|
Settings::node_config_to_update().members = NodeConfig::for_chain_type(chain_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save app config to disk.
|
||||||
pub fn save(&self) {
|
pub fn save(&self) {
|
||||||
Settings::write_to_file(self, Settings::get_config_path(APP_CONFIG_FILE_NAME, None));
|
Settings::write_to_file(self, Settings::get_config_path(APP_CONFIG_FILE_NAME, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WORKING_DIRECTORY_NAME: &'static str = ".grim";
|
||||||
|
|
||||||
|
/// Provides access to app and node configs.
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
app_config: Arc<RwLock<AppConfig>>,
|
app_config: Arc<RwLock<AppConfig>>,
|
||||||
node_config: Arc<RwLock<NodeConfig>>
|
node_config: Arc<RwLock<NodeConfig>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
/// Initialize settings with app and node configs from the disk.
|
/// Initialize settings with app and node configs.
|
||||||
fn init() -> Self {
|
fn init() -> Self {
|
||||||
let app_config = AppConfig::init();
|
let app_config = AppConfig::init();
|
||||||
let chain_type = app_config.node_chain_type;
|
let chain_type = app_config.node_chain_type;
|
||||||
Self {
|
Self {
|
||||||
app_config: Arc::new(RwLock::new(app_config)),
|
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(chain_type)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_node_config() -> RwLockReadGuard<'static, NodeConfig> {
|
/// Get node config to read values.
|
||||||
|
pub fn node_config_to_read() -> RwLockReadGuard<'static, NodeConfig> {
|
||||||
SETTINGS_STATE.node_config.read().unwrap()
|
SETTINGS_STATE.node_config.read().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_app_config() -> RwLockReadGuard<'static, AppConfig> {
|
/// Get node config to update values.
|
||||||
|
pub fn node_config_to_update() -> RwLockWriteGuard<'static, NodeConfig> {
|
||||||
|
SETTINGS_STATE.node_config.write().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get app config to read values.
|
||||||
|
pub fn app_config_to_read() -> RwLockReadGuard<'static, AppConfig> {
|
||||||
SETTINGS_STATE.app_config.read().unwrap()
|
SETTINGS_STATE.app_config.read().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_app_config_to_update() -> RwLockWriteGuard<'static, AppConfig> {
|
/// Get app config to update values.
|
||||||
|
pub fn app_config_to_update() -> RwLockWriteGuard<'static, AppConfig> {
|
||||||
SETTINGS_STATE.app_config.write().unwrap()
|
SETTINGS_STATE.app_config.write().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get working directory path for application.
|
/// 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
|
// Check if dir exists.
|
||||||
let mut path = match dirs::home_dir() {
|
let mut path = match dirs::home_dir() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => PathBuf::new(),
|
None => PathBuf::new(),
|
||||||
};
|
};
|
||||||
path.push(".grim");
|
path.push(WORKING_DIRECTORY_NAME);
|
||||||
if chain_type.is_some() {
|
if chain_type.is_some() {
|
||||||
path.push(chain_type.unwrap().shortname());
|
path.push(chain_type.unwrap().shortname());
|
||||||
}
|
}
|
||||||
// Create if the default path doesn't exist
|
// Create if the default path doesn't exist.
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
let _ = fs::create_dir_all(path.clone());
|
let _ = fs::create_dir_all(path.clone());
|
||||||
}
|
}
|
||||||
|
@ -116,14 +141,14 @@ impl Settings {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get config file path from provided name and [`ChainTypes`] if needed.
|
/// 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 main_path = Self::get_working_path(chain_type);
|
||||||
let mut settings_path = main_path.clone();
|
let mut settings_path = main_path.clone();
|
||||||
settings_path.push(config_name);
|
settings_path.push(config_name);
|
||||||
settings_path
|
settings_path
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read config from file
|
/// Read config from a file
|
||||||
pub fn read_from_file<T: DeserializeOwned>(config_path: PathBuf) -> Result<T, ConfigError> {
|
pub fn read_from_file<T: DeserializeOwned>(config_path: PathBuf) -> Result<T, ConfigError> {
|
||||||
let file_content = fs::read_to_string(config_path.clone())?;
|
let file_content = fs::read_to_string(config_path.clone())?;
|
||||||
let parsed = toml::from_str::<T>(file_content.as_str());
|
let parsed = toml::from_str::<T>(file_content.as_str());
|
||||||
|
|
Loading…
Reference in a new issue