diff --git a/README.md b/README.md index 6559daf..e1462cb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,55 @@ # Gupax - WORK IN PROGRESS ![banner.png](https://github.com/hinto-janaiyo/gupax/blob/main/images/png/banner.png) -**Gupax** (*guh-picks*) is a cross-platform GUI for mining [**Monero**](https://github.com/monero-project/monero) on the decentralized [**P2Pool**](https://github.com/SChernykh/p2pool), using the dedicated [**XMRig**](https://github.com/xmrig/xmrig) miner for max hashrate. +**Gupax** (*guh-picks*) is a cross-platform GUI for mining [**Monero**](https://github.com/monero-project/monero) on [**P2Pool**](https://github.com/SChernykh/p2pool), using [**XMRig**](https://github.com/xmrig/xmrig). + +## Contents +* [What is Monero, P2Pool, XMRig, and Gupax?](##what-is-monero-p2pool-xmrig-and-gupax) +* [Demo](#Demo) +* [Implementation](#Implementation) +* [Planned](#Planned) +* [Goals](#Goals) +* [Build](#Build) + +## What is Monero, P2Pool, XMRig, and Gupax? +**Monero** is a secure, private, and untraceable cryptocurrency. + +The **[Monero GUI](https://github.com/monero-project/monero-gui)** software lets you run a **Monero node** (among other things). A Monero node connects you to other peers and lets you download Monero's [blockchain](https://en.wikipedia.org/wiki/Blockchain). But you already knew all of this, right? + +***[More info here.](https://github.com/monero-project/monero)*** + +--- + +**P2Pool** is software that lets you create/join **decentralized peer-to-peer Monero mining pools.** + +P2Pool as a concept was [first developed for Bitcoin](https://en.bitcoin.it/wiki/P2Pool) but was [never fully realized](https://github.com/p2pool/p2pool) due to many limitations. These limitations were fixed when SChernykh rewrote P2Pool from scratch for Monero. P2Pool combines the best of solo mining and traditional pool mining: + +* ***It's decentralized:*** There's no central server that can be shutdown or pool admin that controls your hashrate +* ***It's permissionless:*** It's peer-to-peer so there's no one to decide who can and cannot mine on the pool +* ***It's trustless:*** Funds are never in custody, all pool blocks pay out to miners directly and immediately +* **0% transaction fee, 0 payout fee, immediate ~0.0003 XMR minimum payout** + +***[More info here.](https://github.com/SChernykh/p2pool)*** + +--- + +**XMRig** is an optimized miner which lets you **mine Monero at higher speeds.** + +Both Monero and P2Pool have built in miners but XMRig is quite faster than both of them. Due to issues like [anti-virus flagging](https://github.com/monero-project/monero-gui/pull/3829#issuecomment-1018191461), it is not feasible to integrate XMRig directly into Monero or P2Pool, however, XMRig is still freely available for anyone to download. The issue is: you have to manually set it up yourself. + +***[More info here.](https://github.com/xmrig/xmrig)*** + +--- + +**Gupax** is a GUI that helps with configuring, updating, and managing P2Pool & XMRig (both originally CLI-only). + +***Recap:*** +1. **XMRig** mines to **P2Pool** which fetchs blocks from a **Monero node** +2. **Monero GUI** runs the ***Monero node*** +3. **Gupax** runs ***P2Pool/XMRig*** + +![stack.png](https://github.com/hinto-janaiyo/gupax/blob/main/images/diagrams/stack.png) + +With Monero GUI managing the Monero node on one side and Gupax managing P2Pool/XMRig on the other, it is (hopefully) very easy for anyone to start mining Monero at **max hashrate in a decentralized, permissionless, and trustless manner**. ## Demo https://user-images.githubusercontent.com/101352116/194763334-d8e936c9-a71e-474e-ac65-3a339b96a9d2.mp4 @@ -29,18 +78,14 @@ https://user-images.githubusercontent.com/101352116/194763334-d8e936c9-a71e-474e - **Config:** All the basic configurations you would expect with P2Pool/XMRig (main, mini, peers, thread count, etc) - **Status:** Status tab displaying mining statistics using P2Pool & XMRig's APIs -## Goal +## Goals **Gupax is:** * A simple GUI solution to P2Pool mining with max hashrate * External mining software so Monero GUI isn't plagued with anti-virus issues * Fast/lightweight because the context for this software is a ***mining*** computer **Gupax is not:** -* For advanced mining setups -* A Monero wallet -* A Monero node - -Monero GUI + Gupax = Easy, decentralized, max hashrate Monero mining. +* A Monero node/wallet ## Build Optimized: diff --git a/images/diagrams/stack.png b/images/diagrams/stack.png new file mode 100644 index 0000000..a284ea5 Binary files /dev/null and b/images/diagrams/stack.png differ diff --git a/src/main.rs b/src/main.rs index c1575fa..0acddad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -85,6 +85,8 @@ pub struct App { reset: bool, // Static stuff now: Instant, // Internal timer + exe: String, // Path for [Gupax] binary + tmp: String, // Tmp folder for updates, random every update resolution: Vec2, // Frame resolution os: &'static str, // OS version: String, // Gupax version @@ -121,6 +123,8 @@ impl App { startup: true, reset: false, now: Instant::now(), + exe: "".to_string(), + tmp: "".to_string(), resolution: Vec2::new(1280.0, 720.0), os: OS, version: format!("{}", GUPAX_VERSION), @@ -129,20 +133,19 @@ impl App { }; // Apply arg state let mut app = parse_args(app); + // Get exe path + random tmp folder + app.exe = match get_exe_dir() { + Ok(exe) => exe, + Err(err) => { panic_app(err.to_string()); exit(1); }, + }; + app.tmp = get_rand_tmp(&app.exe); // Read disk state if no [--reset] arg if app.reset == false { app.og = match State::get() { Ok(toml) => toml, - Err(err) => { - error!("{}", err); - let error_msg = err.to_string(); - let options = Panic::options(); - eframe::run_native("Gupax", options, Box::new(|cc| Box::new(Panic::new(cc, error_msg))),); - exit(1); - }, + Err(err) => { panic_app(err.to_string()); exit(1); }, }; } - // Make sure thread count is accurate/doesn't overflow app.og.xmrig.max_threads = num_cpus::get(); if app.og.xmrig.current_threads > app.og.xmrig.max_threads { app.og.xmrig.current_threads = app.og.xmrig.max_threads; } app.state = app.og.clone(); @@ -270,6 +273,33 @@ fn parse_args(mut app: App) -> App { app } +fn get_exe_dir() -> Result { + match std::env::current_exe() { + Ok(mut path) => { path.pop(); Ok(path.into_os_string().into_string().unwrap()) }, + Err(err) => { error!("Couldn't get exe basepath PATH"); return Err(err) }, + } +} + +fn get_rand_tmp(path: &String) -> String { + use rand::{thread_rng, Rng}; + use rand::distributions::Alphanumeric; + let rand: String = thread_rng() + .sample_iter(&Alphanumeric) + .take(10) + .map(char::from) + .collect(); + let path = path.to_string() + "/gupax_tmp_" + &rand; + info!("Generated rand_tmp ... {}", path); + path +} + +fn panic_app(error: String) { + error!("{}", error); + let options = Panic::options(); + eframe::run_native("Gupax", options, Box::new(|cc| Box::new(Panic::new(cc, error))),); + exit(1); +} + //---------------------------------------------------------------------------------------------------- [App] frame for [Panic] situations struct Panic { error_msg: String, } impl Panic { diff --git a/src/state.rs b/src/state.rs index 3810a88..bf1bda4 100644 --- a/src/state.rs +++ b/src/state.rs @@ -182,7 +182,7 @@ impl State { // Save [State] onto disk file [gupax.toml] pub fn save(&mut self) -> Result<(), TomlError> { - info!("Starting TOML overwrite..."); + info!("Saving TOML to disk..."); let path = Self::get_path()?; // Convert path to absolute self.gupax.absolute_p2pool_path = Self::into_absolute_path(self.gupax.p2pool_path.clone())?; @@ -196,7 +196,7 @@ impl State { Err(err) => { error!("Couldn't parse TOML into string"); return Err(TomlError::Serialize(err)) }, }; match fs::write(path, string) { - Ok(_) => { info!("TOML overwrite ... OK"); Ok(()) }, + Ok(_) => { info!("TOML save ... OK"); Ok(()) }, Err(err) => { error!("Couldn't overwrite TOML file"); return Err(TomlError::Io(err)) }, } } @@ -219,7 +219,6 @@ impl State { Err(err) => { error!("Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) }, }; // Attempt save - info!("Attempting to save to disk..."); Self::save(&mut new)?; Ok(new) }