mirror of
https://code.gri.mw/GUI/grim.git
synced 2026-07-04 05:57:29 +00:00
node: ability to launch API, P2P and Stratum at all interfaces with IPv6 support
This commit is contained in:
@@ -302,6 +302,7 @@ network_settings:
|
||||
max_outbound_count: 'Maximale Anzahl von ausgehenden Peer-Verbindungen:'
|
||||
reset_data_desc: Reset-Knotendaten. Verwenden Sie diese Funktion nur, wenn es Probleme mit der Synchronisation gibt.
|
||||
reset_data: Daten zurücksetzten
|
||||
ip_listen_all: Hören Sie auf allen Schnittstellen
|
||||
modal:
|
||||
cancel: Abbrechen
|
||||
save: Speichern
|
||||
|
||||
@@ -302,6 +302,7 @@ network_settings:
|
||||
max_outbound_count: 'Maximum number of outbound peer connections:'
|
||||
reset_data_desc: Reset the node data. Use it with a caution only if there are problems with synchronization.
|
||||
reset_data: Reset data
|
||||
ip_listen_all: Listen on all interfaces
|
||||
modal:
|
||||
cancel: Cancel
|
||||
save: Save
|
||||
|
||||
@@ -302,6 +302,7 @@ network_settings:
|
||||
max_outbound_count: 'Nombre maximum de connexions de pairs sortants :'
|
||||
reset_data_desc: Réinitialisez les données du noeud. Utilisez-le avec prudence uniquement en cas de problème de synchronisation.
|
||||
reset_data: Réinitialisation des données
|
||||
ip_listen_all: Écoutez sur toutes les interfaces
|
||||
modal:
|
||||
cancel: Annuler
|
||||
save: Sauvegarder
|
||||
|
||||
@@ -302,6 +302,7 @@ network_settings:
|
||||
max_outbound_count: 'Максимальное количество исходящих подключений к пирам:'
|
||||
reset_data_desc: Сбросить данные узла. Используйте с осторожностью, только при наличии проблем с синхронизацией.
|
||||
reset_data: Сброс данных
|
||||
ip_listen_all: Слушать на всех интерфейсах
|
||||
modal:
|
||||
cancel: Отмена
|
||||
save: Сохранить
|
||||
|
||||
@@ -302,6 +302,7 @@ network_settings:
|
||||
max_outbound_count: 'Maksimum giden Peer baglanti sayisi:'
|
||||
reset_data_desc: Node verisini sifirlama. Sadece senkronizasyonda sorun varsa dikkatli kullanin.
|
||||
reset_data: Verileri sifirlama
|
||||
ip_listen_all: Tüm arayüzlerde dinle
|
||||
modal:
|
||||
cancel: Iptal
|
||||
save: Kaydet
|
||||
|
||||
@@ -302,6 +302,7 @@ network_settings:
|
||||
max_outbound_count: '最大出站网络对点连接数:'
|
||||
reset_data_desc: 重置节点数据。只有在出现同步问题时才需谨慎使用.
|
||||
reset_data: 重置数据
|
||||
ip_listen_all: 在所有接口上监听
|
||||
modal:
|
||||
cancel: 取消
|
||||
save: 保存
|
||||
|
||||
@@ -105,8 +105,9 @@ impl ContentContainer for ConnectionsContent {
|
||||
|ui| {
|
||||
let r = View::item_rounding(0, 1, true);
|
||||
View::item_button(ui, r, QR_CODE, None, || {
|
||||
let (api_address, api_port) = NodeConfig::get_api_address();
|
||||
if let Ok(c) = ShareConnectionContent::new(ShareConnection {
|
||||
url: format!("http://{}", NodeConfig::get_api_address()),
|
||||
url: format!("http://{}:{}", api_address, api_port),
|
||||
username: "grin".to_string(),
|
||||
secret: NodeConfig::get_api_secret(true).unwrap_or("".to_string()),
|
||||
}) {
|
||||
@@ -277,9 +278,11 @@ impl ConnectionsContent {
|
||||
ui.add_space(1.0);
|
||||
|
||||
// Setup node API address text.
|
||||
let api_address = NodeConfig::get_api_address();
|
||||
let address_text =
|
||||
format!("{} http://{}", COMPUTER_TOWER, api_address);
|
||||
let (api_address, api_port) = NodeConfig::get_api_address();
|
||||
let address_text = format!(
|
||||
"{} http://{}:{}",
|
||||
COMPUTER_TOWER, api_address, api_port
|
||||
);
|
||||
ui.label(
|
||||
RichText::new(address_text).size(15.0).color(Colors::gray()),
|
||||
);
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
use egui::{RichText, ScrollArea};
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROW_COUNTER_CLOCKWISE, TRASH};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
@@ -26,6 +23,9 @@ use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::gui::views::{Content, Modal, View};
|
||||
use crate::node::{Node, NodeConfig};
|
||||
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
use egui::{RichText, ScrollArea};
|
||||
|
||||
/// Integrated node settings tab content.
|
||||
pub struct NetworkSettings {
|
||||
/// Integrated node general setup content.
|
||||
@@ -162,39 +162,75 @@ impl NetworkSettings {
|
||||
ips: &Vec<String>,
|
||||
on_change: impl FnOnce(&String),
|
||||
) {
|
||||
let mut selected_ip = saved_ip;
|
||||
|
||||
// Set first IP address as current if saved is not present at system.
|
||||
if !ips.contains(saved_ip) {
|
||||
selected_ip = ips.get(0).unwrap();
|
||||
let mut all = NodeConfig::ALL_INTERFACES.to_string();
|
||||
let all_ips = saved_ip == &all || saved_ip == &format!("[{}]", &all);
|
||||
if all_ips {
|
||||
all = saved_ip.clone();
|
||||
}
|
||||
|
||||
ui.add_space(2.0);
|
||||
let mut selected_ip = saved_ip.clone();
|
||||
|
||||
// Show available IP addresses on the system.
|
||||
let _ = ips
|
||||
.chunks(2)
|
||||
.map(|x| {
|
||||
if x.len() == 2 {
|
||||
ui.columns(2, |columns| {
|
||||
let ip_left = x.get(0).unwrap();
|
||||
columns[0].vertical_centered(|ui| {
|
||||
View::radio_value(ui, &mut selected_ip, ip_left, ip_left.to_string());
|
||||
let mut listen_all_changed = false;
|
||||
View::checkbox(ui, all_ips, t!("network_settings.ip_listen_all"), || {
|
||||
listen_all_changed = true;
|
||||
});
|
||||
if listen_all_changed {
|
||||
let new_ip = if all_ips {
|
||||
ips.get(0).unwrap_or(&all).clone()
|
||||
} else {
|
||||
all.clone()
|
||||
};
|
||||
selected_ip = new_ip;
|
||||
}
|
||||
|
||||
ui.add_space(8.0);
|
||||
|
||||
if selected_ip != all {
|
||||
// Set first IP address as current if saved is not present at system.
|
||||
if !ips.contains(&saved_ip) {
|
||||
selected_ip = ips.get(0).unwrap().clone();
|
||||
}
|
||||
|
||||
// Show available IP addresses on the system.
|
||||
let _ = ips
|
||||
.chunks(2)
|
||||
.map(|x| {
|
||||
if x.len() == 2 {
|
||||
ui.columns(2, |columns| {
|
||||
let ip_left = x.get(0).unwrap();
|
||||
let val = if all_ips {
|
||||
&mut ip_left.clone()
|
||||
} else {
|
||||
&mut selected_ip
|
||||
};
|
||||
columns[0].vertical_centered(|ui| {
|
||||
View::radio_value(ui, val, ip_left.clone(), ip_left.to_string());
|
||||
});
|
||||
let ip_right = x.get(1).unwrap();
|
||||
let val = if all_ips {
|
||||
&mut ip_right.clone()
|
||||
} else {
|
||||
&mut selected_ip
|
||||
};
|
||||
columns[1].vertical_centered(|ui| {
|
||||
View::radio_value(ui, val, ip_right.clone(), ip_right.to_string());
|
||||
})
|
||||
});
|
||||
let ip_right = x.get(1).unwrap();
|
||||
columns[1].vertical_centered(|ui| {
|
||||
View::radio_value(ui, &mut selected_ip, ip_right, ip_right.to_string());
|
||||
})
|
||||
});
|
||||
} else {
|
||||
let ip = x.get(0).unwrap();
|
||||
View::radio_value(ui, &mut selected_ip, ip, ip.to_string());
|
||||
}
|
||||
ui.add_space(12.0);
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
} else {
|
||||
let ip = x.get(0).unwrap();
|
||||
let val = if all_ips {
|
||||
&mut ip.clone()
|
||||
} else {
|
||||
&mut selected_ip
|
||||
};
|
||||
View::radio_value(ui, val, ip.clone(), ip.to_string());
|
||||
}
|
||||
ui.add_space(12.0);
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
|
||||
if saved_ip != selected_ip {
|
||||
if saved_ip != &selected_ip {
|
||||
on_change(&selected_ip.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ const FTL_MODAL: &'static str = "node_ftl";
|
||||
|
||||
impl Default for NodeSetup {
|
||||
fn default() -> Self {
|
||||
let (api_ip, api_port) = NodeConfig::get_api_ip_port();
|
||||
let (api_ip, api_port) = NodeConfig::get_api_address();
|
||||
let is_api_port_available = NodeConfig::is_api_port_available(&api_ip, &api_port);
|
||||
Self {
|
||||
data_path_edit: NodeConfig::get_chain_data_path(),
|
||||
@@ -204,7 +204,7 @@ impl ContentContainer for NodeSetup {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show API IP addresses to select.
|
||||
let (api_ip, api_port) = NodeConfig::get_api_ip_port();
|
||||
let (api_ip, api_port) = NodeConfig::get_api_address();
|
||||
NetworkSettings::ip_addrs_ui(ui, &api_ip, &self.available_ips, |selected_ip| {
|
||||
let api_available = NodeConfig::is_api_port_available(selected_ip, &api_port);
|
||||
self.is_api_port_available = api_available;
|
||||
@@ -416,7 +416,7 @@ impl NodeSetup {
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
|
||||
let (_, port) = NodeConfig::get_api_ip_port();
|
||||
let (_, port) = NodeConfig::get_api_address();
|
||||
View::button(
|
||||
ui,
|
||||
format!("{} {}", PLUG, &port),
|
||||
@@ -436,6 +436,7 @@ impl NodeSetup {
|
||||
ui.add_space(6.0);
|
||||
|
||||
if !self.is_api_port_available {
|
||||
ui.add_space(6.0);
|
||||
// Show error when API server port is unavailable.
|
||||
ui.label(
|
||||
RichText::new(t!("network_settings.port_unavailable"))
|
||||
@@ -451,7 +452,7 @@ impl NodeSetup {
|
||||
fn api_port_modal(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
let on_save = |c: &mut NodeSetup| {
|
||||
// Check if port is available.
|
||||
let (api_ip, _) = NodeConfig::get_api_ip_port();
|
||||
let (api_ip, _) = NodeConfig::get_api_address();
|
||||
let available = NodeConfig::is_api_port_available(&api_ip, &c.api_port_edit);
|
||||
c.api_port_available_edit = available;
|
||||
if available {
|
||||
|
||||
@@ -45,6 +45,9 @@ pub struct P2PSetup {
|
||||
/// Flag to check if p2p port is available.
|
||||
port_available_edit: bool,
|
||||
|
||||
/// IP Addresses available at system.
|
||||
available_ips: Vec<String>,
|
||||
|
||||
/// Flag to check if p2p port from saved config value is available.
|
||||
is_port_available: bool,
|
||||
|
||||
@@ -90,7 +93,8 @@ pub const MAX_OUTBOUND_MODAL: &'static str = "p2p_max_outbound";
|
||||
impl Default for P2PSetup {
|
||||
fn default() -> Self {
|
||||
let port = NodeConfig::get_p2p_port();
|
||||
let is_port_available = NodeConfig::is_p2p_port_available(&port);
|
||||
let ip = NodeConfig::get_p2p_host();
|
||||
let is_port_available = NodeConfig::is_p2p_port_available(&ip, &port);
|
||||
let default_main_seeds = Node::MAINNET_DNS_SEEDS
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
@@ -102,9 +106,10 @@ impl Default for P2PSetup {
|
||||
Self {
|
||||
port_edit: port,
|
||||
port_available_edit: is_port_available,
|
||||
available_ips: NodeConfig::get_ip_addrs(),
|
||||
is_port_available,
|
||||
address_check: Bind::new(false),
|
||||
address_available: Some(true),
|
||||
is_port_available,
|
||||
peer_edit: "".to_string(),
|
||||
default_main_seeds,
|
||||
default_test_seeds,
|
||||
@@ -152,8 +157,8 @@ impl ContentContainer for P2PSetup {
|
||||
ui.add_space(6.0);
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
// Show p2p port setup.
|
||||
self.port_ui(ui);
|
||||
// Show p2p address setup.
|
||||
self.address_ui(ui);
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
@@ -229,8 +234,14 @@ impl ContentContainer for P2PSetup {
|
||||
const DNS_SEEDS_TITLE: &'static str = "DNS Seeds";
|
||||
|
||||
impl P2PSetup {
|
||||
/// Draw p2p port setup content.
|
||||
fn port_ui(&mut self, ui: &mut egui::Ui) {
|
||||
/// Draw p2p address setup content.
|
||||
fn address_ui(&mut self, ui: &mut egui::Ui) {
|
||||
// Show message when IP addresses are not available on the system.
|
||||
if self.available_ips.is_empty() {
|
||||
NetworkSettings::no_ip_address_ui(ui);
|
||||
return;
|
||||
}
|
||||
|
||||
ui.label(
|
||||
RichText::new(t!("network_settings.p2p_port"))
|
||||
.size(16.0)
|
||||
@@ -238,7 +249,17 @@ impl P2PSetup {
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
|
||||
let ip = NodeConfig::get_p2p_host();
|
||||
let port = NodeConfig::get_p2p_port();
|
||||
|
||||
NetworkSettings::ip_addrs_ui(ui, &ip, &self.available_ips, |selected_ip| {
|
||||
NodeConfig::save_p2p_host(selected_ip);
|
||||
let p2p_available = NodeConfig::is_p2p_port_available(selected_ip, &port);
|
||||
self.is_port_available = p2p_available;
|
||||
});
|
||||
|
||||
ui.add_space(6.0);
|
||||
|
||||
View::button(
|
||||
ui,
|
||||
format!("{} {}", PLUG, &port),
|
||||
@@ -272,7 +293,8 @@ impl P2PSetup {
|
||||
fn port_modal(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
let on_save = |c: &mut P2PSetup| {
|
||||
// Check if port is available.
|
||||
let available = NodeConfig::is_p2p_port_available(&c.port_edit);
|
||||
let ip = NodeConfig::get_p2p_host();
|
||||
let available = NodeConfig::is_p2p_port_available(&ip, &c.port_edit);
|
||||
c.port_available_edit = available;
|
||||
|
||||
// Save port at config if it's available.
|
||||
|
||||
+172
-74
@@ -16,7 +16,7 @@ use local_ip_address::list_afinet_netifas;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener, ToSocketAddrs};
|
||||
use std::net::{IpAddr, SocketAddr, TcpListener, ToSocketAddrs};
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -29,6 +29,7 @@ use grin_p2p::msg::PeerAddrs;
|
||||
use grin_p2p::{PeerAddr, Seeding};
|
||||
use grin_servers::common::types::ChainValidationMode;
|
||||
use rand::Rng;
|
||||
use url::Url;
|
||||
|
||||
use crate::node::Node;
|
||||
use crate::{AppConfig, Settings};
|
||||
@@ -136,6 +137,9 @@ pub struct NodeConfig {
|
||||
}
|
||||
|
||||
impl NodeConfig {
|
||||
/// To launch on all available interfaces (including IPv6).
|
||||
pub const ALL_INTERFACES: &str = "::";
|
||||
|
||||
/// Initialize config fields from provided [`ChainTypes`].
|
||||
pub fn for_chain_type(chain_type: &ChainTypes) -> Self {
|
||||
// Check secret files for current chain type.
|
||||
@@ -210,8 +214,7 @@ impl NodeConfig {
|
||||
(api, p2p)
|
||||
}
|
||||
};
|
||||
let api_addr = config.server.api_http_addr.split_once(":").unwrap().0;
|
||||
config.server.api_http_addr = format!("{}:{}", api_addr, api);
|
||||
config.server.api_http_addr = format!("127.0.0.1:{}", api);
|
||||
config.server.p2p_config.port = p2p;
|
||||
}
|
||||
|
||||
@@ -290,30 +293,18 @@ impl NodeConfig {
|
||||
|
||||
/// Check whether a port is available on the provided host.
|
||||
fn is_host_port_available(host: &String, port: &String) -> bool {
|
||||
if host == Self::ALL_INTERFACES {
|
||||
return true;
|
||||
}
|
||||
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();
|
||||
if let Ok(ip) = IpAddr::from_str(&host) {
|
||||
let addr = SocketAddr::new(ip, p);
|
||||
return TcpListener::bind(addr).is_ok();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Check whether a port is available across the system at all hosts.
|
||||
fn is_port_available(port: &String) -> bool {
|
||||
if let Ok(p) = port.parse::<u16>() {
|
||||
for ip in Self::get_ip_addrs() {
|
||||
let ip_addr = Ipv4Addr::from_str(ip.as_str()).unwrap();
|
||||
let ipv4 = SocketAddrV4::new(ip_addr, p);
|
||||
if TcpListener::bind(ipv4).is_err() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Get chain data path.
|
||||
pub fn get_chain_data_path() -> String {
|
||||
let r_config = Settings::node_config_to_read();
|
||||
@@ -327,6 +318,60 @@ impl NodeConfig {
|
||||
w_config.save();
|
||||
}
|
||||
|
||||
/// Get default Stratum server port.
|
||||
fn default_stratum_port() -> u16 {
|
||||
match AppConfig::chain_type() {
|
||||
ChainTypes::Mainnet => 3416,
|
||||
_ => 13416,
|
||||
}
|
||||
}
|
||||
|
||||
/// Format address to support ipv6.
|
||||
fn format_address(ip: &String, port: &String) -> String {
|
||||
let addr = if ip.contains(Self::ALL_INTERFACES) {
|
||||
&format!("[{}]", ip)
|
||||
} else {
|
||||
ip
|
||||
};
|
||||
format!("{}:{}", addr, port)
|
||||
}
|
||||
|
||||
/// Parse host to support ipv6.
|
||||
fn parse_host(host: &String) -> String {
|
||||
if host.contains(Self::ALL_INTERFACES) {
|
||||
host.replace("[", "").replace("]", "")
|
||||
} else {
|
||||
host.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse saved address, returning default host or port on fail.
|
||||
fn parse_address_port(
|
||||
addr: &String,
|
||||
default_host: &str,
|
||||
default_port: u16,
|
||||
) -> (String, String) {
|
||||
let addr = if addr.contains("http") {
|
||||
addr.to_string()
|
||||
} else {
|
||||
format!("http://{}", addr)
|
||||
};
|
||||
if let Ok(url) = Url::parse(addr.as_str()) {
|
||||
let host = if let Some(h) = url.host() {
|
||||
Self::parse_host(&h.to_string())
|
||||
} else {
|
||||
default_host.to_string()
|
||||
};
|
||||
let port = if let Some(p) = url.port() {
|
||||
p.to_string()
|
||||
} else {
|
||||
default_port.to_string()
|
||||
};
|
||||
return (host, port);
|
||||
}
|
||||
(default_host.to_string(), default_port.to_string())
|
||||
}
|
||||
|
||||
/// Get stratum server IP address and port.
|
||||
pub fn get_stratum_address() -> (String, String) {
|
||||
let r_config = Settings::node_config_to_read();
|
||||
@@ -339,13 +384,16 @@ impl NodeConfig {
|
||||
.stratum_server_addr
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let (addr, port) = saved_stratum_addr.split_once(":").unwrap();
|
||||
(addr.into(), port.into())
|
||||
Self::parse_address_port(
|
||||
saved_stratum_addr,
|
||||
"127.0.0.1",
|
||||
Self::default_stratum_port(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Save stratum server IP address and port.
|
||||
pub fn save_stratum_address(addr: &String, port: &String) {
|
||||
let addr_to_save = format!("{}:{}", addr, port);
|
||||
pub fn save_stratum_address(host: &String, port: &String) {
|
||||
let addr_to_save = Self::format_address(host, port);
|
||||
let mut w_config = Settings::node_config_to_update();
|
||||
w_config
|
||||
.node
|
||||
@@ -358,28 +406,32 @@ impl NodeConfig {
|
||||
}
|
||||
|
||||
/// Check if stratum server port is available across the system and config.
|
||||
pub fn is_stratum_port_available(ip: &String, port: &String) -> bool {
|
||||
if Node::get_stratum_stats().is_running {
|
||||
// Check if Stratum server with same address is running.
|
||||
let (cur_ip, cur_port) = Self::get_stratum_address();
|
||||
let same_running = ip == &cur_ip && port == &cur_port;
|
||||
return same_running || Self::is_not_running_stratum_port_available(ip, port);
|
||||
}
|
||||
Self::is_not_running_stratum_port_available(&ip, &port)
|
||||
}
|
||||
pub fn is_stratum_port_available(host: &String, port: &String) -> bool {
|
||||
let host = Self::parse_host(host);
|
||||
|
||||
/// Check if stratum port is available when server is not running.
|
||||
fn is_not_running_stratum_port_available(ip: &String, port: &String) -> bool {
|
||||
if Self::is_host_port_available(&ip, &port) {
|
||||
if &Self::get_p2p_port() != port {
|
||||
let (api_ip, api_port) = Self::get_api_ip_port();
|
||||
return if &api_ip == ip {
|
||||
&api_port != port
|
||||
} else {
|
||||
true
|
||||
};
|
||||
// Check if Stratum server with same address is running.
|
||||
if Node::get_stratum_stats().is_running {
|
||||
let (cur_ip, cur_port) = Self::get_stratum_address();
|
||||
let same_running = host == cur_ip && port == &cur_port;
|
||||
if same_running {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if address not conflicts with p2p and api.
|
||||
if Self::is_host_port_available(&host, &port) {
|
||||
let p2p_ip = Self::get_p2p_host();
|
||||
let p2p_port = Self::get_p2p_port();
|
||||
if p2p_ip == host && &p2p_port == port {
|
||||
return false;
|
||||
}
|
||||
let (api_ip, api_port) = Self::get_api_address();
|
||||
return if api_ip == host {
|
||||
&api_port != port
|
||||
} else {
|
||||
true
|
||||
};
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
@@ -493,38 +545,55 @@ impl NodeConfig {
|
||||
w_config.save();
|
||||
}
|
||||
|
||||
/// Get API server address.
|
||||
pub fn get_api_address() -> String {
|
||||
let r_config = Settings::node_config_to_read();
|
||||
r_config.node.server.api_http_addr.clone()
|
||||
/// Get default Stratum server port.
|
||||
fn default_api_port() -> u16 {
|
||||
match AppConfig::chain_type() {
|
||||
ChainTypes::Mainnet => 3413,
|
||||
_ => 13413,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get API server IP and port.
|
||||
pub fn get_api_ip_port() -> (String, String) {
|
||||
let saved_addr = Self::get_api_address();
|
||||
let (addr, port) = saved_addr.split_once(":").unwrap();
|
||||
(addr.into(), port.into())
|
||||
pub fn get_api_address() -> (String, String) {
|
||||
let r_config = Settings::node_config_to_read();
|
||||
let saved_api_addr = r_config.node.server.api_http_addr.clone();
|
||||
Self::parse_address_port(&saved_api_addr, "127.0.0.1", Self::default_api_port())
|
||||
}
|
||||
|
||||
/// Save API server IP address and port.
|
||||
pub fn save_api_address(addr: &String, port: &String) {
|
||||
let addr_to_save = format!("{}:{}", addr, port);
|
||||
let addr_to_save = Self::format_address(addr, port);
|
||||
let mut w_config = Settings::node_config_to_update();
|
||||
w_config.node.server.api_http_addr = addr_to_save;
|
||||
w_config.save();
|
||||
}
|
||||
|
||||
/// Check if api server port is available across the system and config.
|
||||
pub fn is_api_port_available(ip: &String, port: &String) -> bool {
|
||||
pub fn is_api_port_available(host: &String, port: &String) -> bool {
|
||||
let host = Self::parse_host(host);
|
||||
|
||||
// Check if API server with same address is running.
|
||||
if Node::is_running() {
|
||||
// Check if API server with same address is running.
|
||||
let same_running = NodeConfig::get_api_address() == format!("{}:{}", ip, port);
|
||||
if same_running || Self::is_host_port_available(ip, port) {
|
||||
return &Self::get_p2p_port() != port;
|
||||
let (cur_ip, cur_port) = Self::get_api_address();
|
||||
let same_running = host == cur_ip && port == &cur_port;
|
||||
if same_running {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if Self::is_host_port_available(ip, port) {
|
||||
return &Self::get_p2p_port() != port;
|
||||
}
|
||||
|
||||
// Check if address not conflicts with p2p and stratum.
|
||||
if Self::is_host_port_available(&host, port) {
|
||||
let p2p_ip = Self::get_p2p_host();
|
||||
let p2p_port = Self::get_p2p_port();
|
||||
if p2p_ip == host && &p2p_port == port {
|
||||
return false;
|
||||
}
|
||||
let (str_ip, str_port) = Self::get_stratum_address();
|
||||
return if str_ip == host {
|
||||
&str_port != port
|
||||
} else {
|
||||
true
|
||||
};
|
||||
}
|
||||
false
|
||||
}
|
||||
@@ -662,6 +731,25 @@ impl NodeConfig {
|
||||
w_config.save();
|
||||
}
|
||||
|
||||
/// Get P2P server IP address.
|
||||
pub fn get_p2p_host() -> String {
|
||||
let host = Settings::node_config_to_read()
|
||||
.node
|
||||
.server
|
||||
.p2p_config
|
||||
.host
|
||||
.to_string();
|
||||
Self::parse_host(&host)
|
||||
}
|
||||
|
||||
/// Get P2P server IP address.
|
||||
pub fn save_p2p_host(host: &String) {
|
||||
let mut w_config = Settings::node_config_to_update();
|
||||
w_config.node.server.p2p_config.host =
|
||||
IpAddr::from_str(host).unwrap_or(IpAddr::from_str(Self::ALL_INTERFACES).unwrap());
|
||||
w_config.save();
|
||||
}
|
||||
|
||||
/// Get P2P server port.
|
||||
pub fn get_p2p_port() -> String {
|
||||
Settings::node_config_to_read()
|
||||
@@ -673,20 +761,30 @@ impl NodeConfig {
|
||||
}
|
||||
|
||||
/// Check if P2P server port is available across the system and config.
|
||||
pub fn is_p2p_port_available(port: &String) -> bool {
|
||||
if port.parse::<u16>().is_err() {
|
||||
return false;
|
||||
}
|
||||
let (_, api_port) = Self::get_api_ip_port();
|
||||
pub fn is_p2p_port_available(host: &String, port: &String) -> bool {
|
||||
let host = Self::parse_host(host);
|
||||
|
||||
// Check if P2P server with same address is running.
|
||||
if Node::is_running() {
|
||||
// Check if P2P server with same port is running.
|
||||
let same_running = &NodeConfig::get_p2p_port() == port;
|
||||
if same_running || Self::is_port_available(port) {
|
||||
return &api_port != port;
|
||||
let same_running =
|
||||
&NodeConfig::get_p2p_port() == port && NodeConfig::get_p2p_host() == host;
|
||||
if same_running {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if Self::is_port_available(port) {
|
||||
return &api_port != port;
|
||||
}
|
||||
|
||||
// Check if address not conflicts with stratum and api.
|
||||
if Self::is_host_port_available(&host, &port) {
|
||||
let (str_ip, str_port) = Self::get_stratum_address();
|
||||
if str_ip == host && &str_port == port {
|
||||
return false;
|
||||
}
|
||||
let (api_ip, api_port) = Self::get_api_address();
|
||||
return if api_ip == host {
|
||||
&api_port != port
|
||||
} else {
|
||||
true
|
||||
};
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
@@ -29,13 +29,10 @@ use safelog::DisplayRedacted;
|
||||
use sha2::Sha512;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::Duration;
|
||||
use std::{fs, thread};
|
||||
use tls_api::{TlsConnector as TlsConnectorTrait, TlsConnectorBuilder};
|
||||
use tls_api_native_tls::TlsConnector;
|
||||
use tor_hscrypto::pk::{HsIdKey, HsIdKeypair};
|
||||
use tor_hsrproxy::OnionServiceReverseProxy;
|
||||
use tor_hsrproxy::config::{
|
||||
|
||||
@@ -235,7 +235,8 @@ impl Wallet {
|
||||
/// Create [`HTTPNodeClient`] from provided config.
|
||||
fn create_node_client(config: &WalletConfig) -> Result<HTTPNodeClient, Error> {
|
||||
let integrated = || {
|
||||
let api_url = format!("http://{}", NodeConfig::get_api_address());
|
||||
let (api_address, api_port) = NodeConfig::get_api_address();
|
||||
let api_url = format!("http://{}:{}", api_address, api_port);
|
||||
let api_secret = NodeConfig::get_api_secret(true);
|
||||
(api_url, api_secret)
|
||||
};
|
||||
@@ -2222,7 +2223,7 @@ fn start_api_server(wallet: &Wallet) -> Result<(ApiServer, u16), Error> {
|
||||
return match TcpListener::bind((host, port.to_owned())) {
|
||||
Ok(_) => {
|
||||
let node_p2p_port = NodeConfig::get_p2p_port();
|
||||
let node_api_port = NodeConfig::get_api_ip_port().1;
|
||||
let node_api_port = NodeConfig::get_api_address().1;
|
||||
let free =
|
||||
port.to_string() != node_p2p_port && port.to_string() != node_api_port;
|
||||
if free {
|
||||
|
||||
Reference in New Issue
Block a user