From 6c5a8bc42ff8def80c2ee6ce88184c279d2b77cc Mon Sep 17 00:00:00 2001
From: hinto-janaiyo <hinto.janaiyo@protonmail.com>
Date: Tue, 15 Nov 2022 21:19:30 -0500
Subject: [PATCH] optimize [.lock()], add index counter to p2pool manual nodes

---
 Cargo.lock    | 28 ++++++++++++++++------------
 Cargo.toml    |  3 ++-
 src/disk.rs   | 19 +++++++++++++------
 src/main.rs   | 26 +++++++++++++++-----------
 src/p2pool.rs | 24 +++++++++++++++---------
 5 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 63b854c..71da5bf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -536,9 +536,9 @@ dependencies = [
 
 [[package]]
 name = "chrono"
-version = "0.4.22"
+version = "0.4.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
+checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
 dependencies = [
  "iana-time-zone",
  "js-sys",
@@ -2060,9 +2060,9 @@ dependencies = [
 
 [[package]]
 name = "image"
-version = "0.24.4"
+version = "0.24.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c"
+checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945"
 dependencies = [
  "bytemuck",
  "byteorder",
@@ -2160,9 +2160,9 @@ dependencies = [
 
 [[package]]
 name = "jpeg-decoder"
-version = "0.2.6"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b"
+checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
 dependencies = [
  "rayon",
 ]
@@ -2178,9 +2178,12 @@ dependencies = [
 
 [[package]]
 name = "keccak"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838"
+checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768"
+dependencies = [
+ "cpufeatures",
+]
 
 [[package]]
 name = "khronos_api"
@@ -2758,9 +2761,9 @@ dependencies = [
 
 [[package]]
 name = "owned_ttf_parser"
-version = "0.17.0"
+version = "0.17.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4665508572151759e8d60404e20dc096ef93a99801a05ac2ac6e43bf5b4ca187"
+checksum = "18904d3c65493a9f0d7542293d1a7f69bfdc309a6b9ef4f46dc3e58b0577edc5"
 dependencies = [
  "ttf-parser",
 ]
@@ -3880,9 +3883,9 @@ dependencies = [
 
 [[package]]
 name = "tiff"
-version = "0.7.4"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f71e422515e83e3ab8a03d4781d05ebf864fc61f4546e6ecffa58cbd34181a0"
+checksum = "f17def29300a156c19ae30814710d9c63cd50288a49c6fd3a10ccfbe4cf886fd"
 dependencies = [
  "flate2",
  "jpeg-decoder",
@@ -4094,6 +4097,7 @@ version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
 dependencies = [
+ "indexmap",
  "serde",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index c1d11aa..8592a69 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,7 +47,8 @@ sha2 = "0.10.6"
 tls-api = "0.9.0"
 tls-api-native-tls = "0.9.0"
 tokio = { version = "1.21.2", features = ["full"] }
-toml = "0.5.9"
+#toml = "0.5.9"
+toml = { version = "0.5.9", features = ["preserve_order"] }
 tor-rtcompat = "0.7.0"
 walkdir = "2.3.2"
 
diff --git a/src/disk.rs b/src/disk.rs
index fc91dae..1473d2e 100644
--- a/src/disk.rs
+++ b/src/disk.rs
@@ -35,7 +35,7 @@ use std::fmt::Display;
 use std::path::{Path,PathBuf};
 use std::result::Result;
 use std::sync::{Arc,Mutex};
-use std::collections::HashMap;
+use std::collections::{HashMap,BTreeMap};
 use std::fmt::Write;
 use serde::{Serialize,Deserialize};
 use figment::Figment;
@@ -68,7 +68,7 @@ pub fn get_file_path(file: File) -> Result<PathBuf, TomlError> {
 	// Create directory
 	fs::create_dir_all(&path)?;
 	path.push(name);
-	info!("{:?} path ... {}", file, path.display());
+	info!("{:?} | Path ... {}", file, path.display());
 	Ok(path)
 }
 
@@ -139,6 +139,7 @@ impl State {
 				ip: "localhost".to_string(),
 				rpc: "18081".to_string(),
 				zmq: "18083".to_string(),
+				selected_index: 1,
 				selected_name: "Local Monero Node".to_string(),
 				selected_ip: "localhost".to_string(),
 				selected_rpc: "18081".to_string(),
@@ -167,7 +168,7 @@ impl State {
 	pub fn from_string(string: String) -> Result<Self, TomlError> {
 		match toml::de::from_str(&string) {
 			Ok(state) => {
-				info!("State parse ... OK");
+				info!("State | Parse ... OK");
 				print_toml(&string);
 				Ok(state)
 			}
@@ -284,10 +285,9 @@ impl Node {
 
 	// Convert [String] to [Node] Vec
 	pub fn from_string(string: String) -> Result<Vec<(String, Self)>, TomlError> {
-		let nodes: HashMap<String, Node> = match toml::de::from_str(&string) {
+		let nodes: toml::map::Map<String, toml::Value> = match toml::de::from_str(&string) {
 			Ok(map) => {
 				info!("Node | Parse ... OK");
-				print_toml(&string);
 				map
 			}
 			Err(err) => {
@@ -298,7 +298,13 @@ impl Node {
 		let size = nodes.keys().len();
 		let mut vec = Vec::with_capacity(size);
 		for (key, values) in nodes.iter() {
-			vec.push((key.clone(), values.clone()));
+//			println!("{:#?}", values.get("ip")); std::process::exit(0);
+			let node = Node {
+				ip: values.get("ip").unwrap().as_str().unwrap().to_string(),
+				rpc: values.get("rpc").unwrap().as_str().unwrap().to_string(),
+				zmq: values.get("zmq").unwrap().as_str().unwrap().to_string(),
+			};
+			vec.push((key.clone(), node));
 		}
 		Ok(vec)
 	}
@@ -509,6 +515,7 @@ pub struct P2pool {
 	pub ip: String,
 	pub rpc: String,
 	pub zmq: String,
+	pub selected_index: u16,
 	pub selected_name: String,
 	pub selected_ip: String,
 	pub selected_rpc: String,
diff --git a/src/main.rs b/src/main.rs
index 4b46850..9a76822 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -159,21 +159,23 @@ impl App {
 				Err(err) => { panic_main(err.to_string()); exit(1); },
 			};
 		}
-		app.state = app.og.lock().unwrap().clone();
+		let mut og = app.og.lock().unwrap(); // Lock [og]
+		app.state = og.clone();
 		// Get node list
 		app.node_vec = Node::get().unwrap();
 		// Handle max threads
-		app.og.lock().unwrap().xmrig.max_threads = num_cpus::get();
-		let current = app.og.lock().unwrap().xmrig.current_threads;
-		let max = app.og.lock().unwrap().xmrig.max_threads;
+		og.xmrig.max_threads = num_cpus::get();
+		let current = og.xmrig.current_threads;
+		let max = og.xmrig.max_threads;
 		if current > max {
-			app.og.lock().unwrap().xmrig.current_threads = max;
+			og.xmrig.current_threads = max;
 		}
 		// Apply TOML values to [Update]
-		let p2pool_path = app.og.lock().unwrap().gupax.absolute_p2pool_path.clone();
-		let xmrig_path = app.og.lock().unwrap().gupax.absolute_xmrig_path.clone();
-		let tor = app.og.lock().unwrap().gupax.update_via_tor;
+		let p2pool_path = og.gupax.absolute_p2pool_path.clone();
+		let xmrig_path = og.gupax.absolute_xmrig_path.clone();
+		let tor = og.gupax.update_via_tor;
 		app.update = Arc::new(Mutex::new(Update::new(app.exe.clone(), p2pool_path, xmrig_path, tor)));
+		drop(og); // Unlock [og]
 		app
 	}
 }
@@ -554,16 +556,18 @@ impl eframe::App for Panic {
 
 //---------------------------------------------------------------------------------------------------- Main [App] frame
 fn main() {
+	let now = Instant::now();
 	init_logger();
 	let options = init_options();
 	match clean_dir() {
 		Ok(_) => info!("Temporary folder cleanup ... OK"),
 		Err(e) => warn!("Could not cleanup [gupax_tmp] folders: {}", e),
 	}
-	let app = App::new();
-	let name = app.name_version.clone();
+	let mut app = App::new();
+	app.now = now;
 	init_auto(&app);
-	eframe::run_native(&name, options, Box::new(|cc| Box::new(App::cc(cc, app))),);
+	info!("Initialization DONE ... {} seconds", now.elapsed().as_secs_f32());
+	eframe::run_native(&app.name_version.clone(), options, Box::new(|cc| Box::new(App::cc(cc, app))),);
 }
 
 impl eframe::App for App {
diff --git a/src/p2pool.rs b/src/p2pool.rs
index df9e14b..391e2ab 100644
--- a/src/p2pool.rs
+++ b/src/p2pool.rs
@@ -269,12 +269,17 @@ impl P2pool {
 			ui.spacing_mut().slider_width = width - 8.0;
 			ui.spacing_mut().icon_width = width / 25.0;
 			// [Ping List]
-			let text = RichText::new(format!("{} | {}", self.selected_name, self.selected_ip));
+			let text = RichText::new(format!("{}. {} | {}", self.selected_index, self.selected_name, self.selected_ip));
 			ComboBox::from_id_source("nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
+				let mut n = 1;
 				for (name, node) in node_vec.iter() {
-					let text = RichText::text_style(RichText::new(format!("{}\n     IP: {}\n    RPC: {}\n    ZMQ: {}", name, node.ip, node.rpc, node.zmq)), Monospace);
-					ui.selectable_value(&mut self.selected_name, name.clone(), text);
-//					println!("{}", value.ip);
+					let text = RichText::text_style(RichText::new(format!("{}. {}\n     IP: {}\n    RPC: {}\n    ZMQ: {}", n, name, node.ip, node.rpc, node.zmq)), Monospace);
+					if ui.add(SelectableLabel::new(self.selected_name == *name, text)).clicked() {
+						self.selected_index = n;
+						self.selected_name = name.clone();
+					}
+//					ui.selectable_value(&mut self.selected_name, name.clone(), text);
+					n += 1;
 				}
 			});
 			// [Add] + [Delete]
@@ -284,8 +289,8 @@ impl P2pool {
 				for (name, _) in node_vec.iter() {
 					if *name == self.name { exists = true; }
 				}
-				ui.set_enabled(!incorrect_input && !exists && node_vec_len < 100);
-				let text = format!("{}\n      Max amount of nodes: 100\n      Current amount: [{}/100]", P2POOL_ADD, node_vec_len);
+				ui.set_enabled(!incorrect_input && !exists && node_vec_len < 1000);
+				let text = format!("{}\n    Currently selected node: {}. {}\n    Current amount of nodes: {}/1000", P2POOL_ADD, self.selected_index, self.selected_name, node_vec_len);
 				if ui.add_sized([width, text_edit], Button::new("Add")).on_hover_text(text).clicked() {
 					let node = Node {
 						ip: self.ip.clone(),
@@ -297,7 +302,7 @@ impl P2pool {
 			});
 			ui.horizontal(|ui| {
 				ui.set_enabled(node_vec_len > 1);
-				let text = format!("{}\n      Max amount of nodes: 100\n      Current amount: [{}/100]", P2POOL_DELETE, node_vec_len);
+				let text = format!("{}\n    Currently selected node: {}. {}\n    Current amount of nodes: {}/1000", P2POOL_ADD, self.selected_index, self.selected_name, node_vec_len);
 				if ui.add_sized([width, text_edit], Button::new("Delete")).on_hover_text(text).clicked() {
 					let mut n = 0;
 					for (name, _) in node_vec.iter() {
@@ -305,10 +310,11 @@ impl P2pool {
 							// If deleting [0], make selected = [1]
 							// instead of attempting to [0-1] (panic!)
 							match n {
-								0 => self.selected_name = node_vec[1].0.clone(),
-								_ => self.selected_name = node_vec[n-1].0.clone(),
+								0 => { self.selected_name = node_vec[1].0.clone(); self.selected_index = 1; },
+								_ => { self.selected_name = node_vec[n-1].0.clone(); self.selected_index = n as u16; },
 							};
 							node_vec.remove(n);
+							info!("Node | Removed index [{}. {}]", n+1, self.selected_name);
 							break
 						}
 						n += 1;