mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-12-22 14:49:21 +00:00
diagram
This commit is contained in:
parent
5e65d07470
commit
5a686aaa1d
4 changed files with 92 additions and 18 deletions
59
README.md
59
README.md
|
@ -1,6 +1,55 @@
|
||||||
# Gupax - WORK IN PROGRESS
|
# Gupax - WORK IN PROGRESS
|
||||||
![banner.png](https://github.com/hinto-janaiyo/gupax/blob/main/images/png/banner.png)
|
![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
|
## Demo
|
||||||
https://user-images.githubusercontent.com/101352116/194763334-d8e936c9-a71e-474e-ac65-3a339b96a9d2.mp4
|
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)
|
- **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
|
- **Status:** Status tab displaying mining statistics using P2Pool & XMRig's APIs
|
||||||
|
|
||||||
## Goal
|
## Goals
|
||||||
**Gupax is:**
|
**Gupax is:**
|
||||||
* A simple GUI solution to P2Pool mining with max hashrate
|
* A simple GUI solution to P2Pool mining with max hashrate
|
||||||
* External mining software so Monero GUI isn't plagued with anti-virus issues
|
* 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
|
* Fast/lightweight because the context for this software is a ***mining*** computer
|
||||||
|
|
||||||
**Gupax is not:**
|
**Gupax is not:**
|
||||||
* For advanced mining setups
|
* A Monero node/wallet
|
||||||
* A Monero wallet
|
|
||||||
* A Monero node
|
|
||||||
|
|
||||||
Monero GUI + Gupax = Easy, decentralized, max hashrate Monero mining.
|
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
Optimized:
|
Optimized:
|
||||||
|
|
BIN
images/diagrams/stack.png
Normal file
BIN
images/diagrams/stack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 MiB |
46
src/main.rs
46
src/main.rs
|
@ -85,6 +85,8 @@ pub struct App {
|
||||||
reset: bool,
|
reset: bool,
|
||||||
// Static stuff
|
// Static stuff
|
||||||
now: Instant, // Internal timer
|
now: Instant, // Internal timer
|
||||||
|
exe: String, // Path for [Gupax] binary
|
||||||
|
tmp: String, // Tmp folder for updates, random every update
|
||||||
resolution: Vec2, // Frame resolution
|
resolution: Vec2, // Frame resolution
|
||||||
os: &'static str, // OS
|
os: &'static str, // OS
|
||||||
version: String, // Gupax version
|
version: String, // Gupax version
|
||||||
|
@ -121,6 +123,8 @@ impl App {
|
||||||
startup: true,
|
startup: true,
|
||||||
reset: false,
|
reset: false,
|
||||||
now: Instant::now(),
|
now: Instant::now(),
|
||||||
|
exe: "".to_string(),
|
||||||
|
tmp: "".to_string(),
|
||||||
resolution: Vec2::new(1280.0, 720.0),
|
resolution: Vec2::new(1280.0, 720.0),
|
||||||
os: OS,
|
os: OS,
|
||||||
version: format!("{}", GUPAX_VERSION),
|
version: format!("{}", GUPAX_VERSION),
|
||||||
|
@ -129,20 +133,19 @@ impl App {
|
||||||
};
|
};
|
||||||
// Apply arg state
|
// Apply arg state
|
||||||
let mut app = parse_args(app);
|
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
|
// Read disk state if no [--reset] arg
|
||||||
if app.reset == false {
|
if app.reset == false {
|
||||||
app.og = match State::get() {
|
app.og = match State::get() {
|
||||||
Ok(toml) => toml,
|
Ok(toml) => toml,
|
||||||
Err(err) => {
|
Err(err) => { panic_app(err.to_string()); exit(1); },
|
||||||
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);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Make sure thread count is accurate/doesn't overflow
|
|
||||||
app.og.xmrig.max_threads = num_cpus::get();
|
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; }
|
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();
|
app.state = app.og.clone();
|
||||||
|
@ -270,6 +273,33 @@ fn parse_args(mut app: App) -> App {
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_exe_dir() -> Result<String, std::io::Error> {
|
||||||
|
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
|
//---------------------------------------------------------------------------------------------------- [App] frame for [Panic] situations
|
||||||
struct Panic { error_msg: String, }
|
struct Panic { error_msg: String, }
|
||||||
impl Panic {
|
impl Panic {
|
||||||
|
|
|
@ -182,7 +182,7 @@ impl State {
|
||||||
|
|
||||||
// Save [State] onto disk file [gupax.toml]
|
// Save [State] onto disk file [gupax.toml]
|
||||||
pub fn save(&mut self) -> Result<(), TomlError> {
|
pub fn save(&mut self) -> Result<(), TomlError> {
|
||||||
info!("Starting TOML overwrite...");
|
info!("Saving TOML to disk...");
|
||||||
let path = Self::get_path()?;
|
let path = Self::get_path()?;
|
||||||
// Convert path to absolute
|
// Convert path to absolute
|
||||||
self.gupax.absolute_p2pool_path = Self::into_absolute_path(self.gupax.p2pool_path.clone())?;
|
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)) },
|
Err(err) => { error!("Couldn't parse TOML into string"); return Err(TomlError::Serialize(err)) },
|
||||||
};
|
};
|
||||||
match fs::write(path, string) {
|
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)) },
|
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)) },
|
Err(err) => { error!("Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
|
||||||
};
|
};
|
||||||
// Attempt save
|
// Attempt save
|
||||||
info!("Attempting to save to disk...");
|
|
||||||
Self::save(&mut new)?;
|
Self::save(&mut new)?;
|
||||||
Ok(new)
|
Ok(new)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue