mirror of
https://github.com/hinto-janai/gupax.git
synced 2024-12-22 19:09:22 +00:00
v1.0.0
Includes some small fixes:
- [localhost] will always be changed to [127.0.0.1] in the case
of XMRig (it doesn't understand localhost by itself)
- P2Pool/XMRig API path now checks for a [/] or [\]
and correctly applies the endpoint, e.g:
BASEPATH = "/home/hinto/p2pool"
ENDPOINT = "local/stats"
if BASEPATH doesn't end with '/' { BASEPATH.push('/') }
API_PATH = BASEPATH + ENDPOINT ("/home/hinto/p2pool/local/stats")
- P2Pool payout line got changed in: be18ad4177
The regex is now a more generic: [payout of [0-9].[0-9]+ XMR]
This commit is contained in:
parent
6c0ba2be9a
commit
e6bf49b309
10 changed files with 60 additions and 23 deletions
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -1,9 +1,19 @@
|
||||||
# v1.0.0
|
# v1.0.0
|
||||||
## Updates
|
[Download here](https://github.com/hinto-janaiyo/gupax/releases/latest) or at https://gupax.io.
|
||||||
*
|
|
||||||
|
|
||||||
## Fixes
|
[Watch a 3-minute setup guide here.](https://github.com/hinto-janaiyo/gupax#How-To)
|
||||||
*
|
|
||||||
|
## Changes
|
||||||
|
* Optimized PTY output handling (less memory usage)
|
||||||
|
* Added `Select random node`, `<- Last`, `Next ->` buttons in `P2Pool Simple`
|
||||||
|
* Added `Debug Info` screen (`D` key on `About` tab)
|
||||||
|
* Added Linux distro build profile
|
||||||
|
* Added `21` unit tests
|
||||||
|
* Misc fixes/optimizations
|
||||||
|
|
||||||
|
## Bundled Versions
|
||||||
|
* [`P2Pool v2.6`](https://github.com/SChernykh/p2pool/releases/tag/v2.6)
|
||||||
|
* [`XMRig v6.18.1`](https://github.com/xmrig/xmrig/releases/tag/v6.18.1)
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# WORK IN PROGRESS - ETA: December 25th, 2022
|
|
||||||
![banner.png](https://github.com/hinto-janaiyo/gupax/blob/main/images/banner.png)
|
![banner.png](https://github.com/hinto-janaiyo/gupax/blob/main/images/banner.png)
|
||||||
Gupax is a (Windows|macOS|Linux) GUI for mining [**Monero**](https://github.com/monero-project/monero) on [**P2Pool**](https://github.com/SChernykh/p2pool), using [**XMRig**](https://github.com/xmrig/xmrig).
|
Gupax is a (Windows|macOS|Linux) GUI for mining [**Monero**](https://github.com/monero-project/monero) on [**P2Pool**](https://github.com/SChernykh/p2pool), using [**XMRig**](https://github.com/xmrig/xmrig).
|
||||||
|
|
||||||
|
@ -481,6 +480,8 @@ After that, run:
|
||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The Linux release tars come with another file next to the Gupax binary: `Gupax.AppImage`. ***This is not an actual [AppImage](https://en.wikipedia.org/wiki/AppImage)***, it is just a text file that contains: `./gupax`. This allows users to double-click and execute Gupax in file explorers like `Nautilus` in Ubuntu/Debian.
|
||||||
|
|
||||||
### Building for a distribution
|
### Building for a distribution
|
||||||
Gupax has a build flag for use as a package in a Linux distribution:
|
Gupax has a build flag for use as a package in a Linux distribution:
|
||||||
```
|
```
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
pub const GUPAX_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION")); // e.g: Gupax v1.0.0
|
pub const GUPAX_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION")); // e.g: Gupax v1.0.0
|
||||||
pub const P2POOL_VERSION: &str = "v2.5";
|
pub const P2POOL_VERSION: &str = "v2.6";
|
||||||
pub const XMRIG_VERSION: &str = "v6.18.0";
|
pub const XMRIG_VERSION: &str = "v6.18.1";
|
||||||
pub const COMMIT: &str = include_str!("../.git/refs/heads/main");
|
pub const COMMIT: &str = include_str!("../.git/refs/heads/main");
|
||||||
// e.g: Gupax_v1_0_0
|
// e.g: Gupax_v1_0_0
|
||||||
// Would have been [Gupax_v1.0.0] but P2Pool truncates everything after [.]
|
// Would have been [Gupax_v1.0.0] but P2Pool truncates everything after [.]
|
||||||
|
@ -73,7 +73,7 @@ r#"*---------------------------------------*
|
||||||
pub const P2POOL_API_PATH: &str = r"local\stats"; // The default relative FS path of P2Pool's local API
|
pub const P2POOL_API_PATH: &str = r"local\stats"; // The default relative FS path of P2Pool's local API
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
pub const P2POOL_API_PATH: &str = "local/stats";
|
pub const P2POOL_API_PATH: &str = "local/stats";
|
||||||
pub const XMRIG_API_URI: &str = "/1/summary"; // The default relative URI of XMRig's API
|
pub const XMRIG_API_URI: &str = "1/summary"; // The default relative URI of XMRig's API
|
||||||
|
|
||||||
// Process state tooltips (online, offline, etc)
|
// Process state tooltips (online, offline, etc)
|
||||||
pub const P2POOL_ALIVE: &str = "P2Pool is online";
|
pub const P2POOL_ALIVE: &str = "P2Pool is online";
|
||||||
|
|
|
@ -360,7 +360,6 @@ impl Helper {
|
||||||
out_peers: "10".to_string(),
|
out_peers: "10".to_string(),
|
||||||
in_peers: "10".to_string(),
|
in_peers: "10".to_string(),
|
||||||
};
|
};
|
||||||
api_path.push(P2POOL_API_PATH);
|
|
||||||
|
|
||||||
// [Advanced]
|
// [Advanced]
|
||||||
} else {
|
} else {
|
||||||
|
@ -410,9 +409,9 @@ impl Helper {
|
||||||
out_peers: state.out_peers.to_string(),
|
out_peers: state.out_peers.to_string(),
|
||||||
in_peers: state.in_peers.to_string(),
|
in_peers: state.in_peers.to_string(),
|
||||||
};
|
};
|
||||||
api_path.push(P2POOL_API_PATH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
api_path.push(P2POOL_API_PATH);
|
||||||
(args, api_path)
|
(args, api_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,11 +737,11 @@ impl Helper {
|
||||||
match last {
|
match last {
|
||||||
"--threads" => xmrig_image.threads = arg.to_string(),
|
"--threads" => xmrig_image.threads = arg.to_string(),
|
||||||
"--url" => xmrig_image.url = arg.to_string(),
|
"--url" => xmrig_image.url = arg.to_string(),
|
||||||
"--http-host" => api_ip = arg.to_string(),
|
"--http-host" => api_ip = if arg == "localhost" { "127.0.0.1".to_string() } else { arg.to_string() },
|
||||||
"--http-port" => api_port = arg.to_string(),
|
"--http-port" => api_port = arg.to_string(),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
args.push(arg.to_string());
|
args.push(if arg == "localhost" { "127.0.0.1".to_string() } else { arg.to_string() });
|
||||||
last = arg;
|
last = arg;
|
||||||
}
|
}
|
||||||
// Else, build the argument
|
// Else, build the argument
|
||||||
|
@ -791,7 +790,7 @@ impl Helper {
|
||||||
// The XMRig watchdog. Spawns 1 OS thread for reading a PTY (STDOUT+STDERR), and combines the [Child] with a PTY so STDIN actually works.
|
// The XMRig watchdog. Spawns 1 OS thread for reading a PTY (STDOUT+STDERR), and combines the [Child] with a PTY so STDIN actually works.
|
||||||
// This isn't actually async, a tokio runtime is unfortunately needed because [Hyper] is an async library (HTTP API calls)
|
// This isn't actually async, a tokio runtime is unfortunately needed because [Hyper] is an async library (HTTP API calls)
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn spawn_xmrig_watchdog(process: Arc<Mutex<Process>>, gui_api: Arc<Mutex<PubXmrigApi>>, pub_api: Arc<Mutex<PubXmrigApi>>, _priv_api: Arc<Mutex<PrivXmrigApi>>, args: Vec<String>, path: std::path::PathBuf, sudo: Arc<Mutex<SudoState>>, api_ip_port: String) {
|
async fn spawn_xmrig_watchdog(process: Arc<Mutex<Process>>, gui_api: Arc<Mutex<PubXmrigApi>>, pub_api: Arc<Mutex<PubXmrigApi>>, _priv_api: Arc<Mutex<PrivXmrigApi>>, args: Vec<String>, path: std::path::PathBuf, sudo: Arc<Mutex<SudoState>>, mut api_ip_port: String) {
|
||||||
// 1a. Create PTY
|
// 1a. Create PTY
|
||||||
debug!("XMRig | Creating PTY...");
|
debug!("XMRig | Creating PTY...");
|
||||||
let pty = portable_pty::native_pty_system();
|
let pty = portable_pty::native_pty_system();
|
||||||
|
@ -845,6 +844,11 @@ impl Helper {
|
||||||
|
|
||||||
let client: hyper::Client<hyper::client::HttpConnector> = hyper::Client::builder().build(hyper::client::HttpConnector::new());
|
let client: hyper::Client<hyper::client::HttpConnector> = hyper::Client::builder().build(hyper::client::HttpConnector::new());
|
||||||
let start = process.lock().unwrap().start;
|
let start = process.lock().unwrap().start;
|
||||||
|
let api_uri = {
|
||||||
|
if !api_ip_port.ends_with('/') { api_ip_port.push('/'); }
|
||||||
|
"http://".to_owned() + &api_ip_port + XMRIG_API_URI
|
||||||
|
};
|
||||||
|
info!("XMRig | Final API URI: {}", api_uri);
|
||||||
|
|
||||||
// Reset stats before loop
|
// Reset stats before loop
|
||||||
*pub_api.lock().unwrap() = PubXmrigApi::new();
|
*pub_api.lock().unwrap() = PubXmrigApi::new();
|
||||||
|
@ -959,11 +963,11 @@ impl Helper {
|
||||||
|
|
||||||
// Send an HTTP API request
|
// Send an HTTP API request
|
||||||
debug!("XMRig Watchdog | Attempting HTTP API request...");
|
debug!("XMRig Watchdog | Attempting HTTP API request...");
|
||||||
if let Ok(priv_api) = PrivXmrigApi::request_xmrig_api(client.clone(), &api_ip_port).await {
|
if let Ok(priv_api) = PrivXmrigApi::request_xmrig_api(client.clone(), &api_uri).await {
|
||||||
debug!("XMRig Watchdog | HTTP API request OK, attempting [update_from_priv()]");
|
debug!("XMRig Watchdog | HTTP API request OK, attempting [update_from_priv()]");
|
||||||
PubXmrigApi::update_from_priv(&pub_api, priv_api);
|
PubXmrigApi::update_from_priv(&pub_api, priv_api);
|
||||||
} else {
|
} else {
|
||||||
warn!("XMRig Watchdog | Could not send HTTP API request to: {}", api_ip_port);
|
warn!("XMRig Watchdog | Could not send HTTP API request to: {}", api_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep (only if 900ms hasn't passed)
|
// Sleep (only if 900ms hasn't passed)
|
||||||
|
@ -1300,11 +1304,11 @@ impl HumanNumber {
|
||||||
// The following STDLIB implementation takes [0.003~] seconds to find all matches given a [String] with 30k lines:
|
// The following STDLIB implementation takes [0.003~] seconds to find all matches given a [String] with 30k lines:
|
||||||
// let mut n = 0;
|
// let mut n = 0;
|
||||||
// for line in P2POOL_OUTPUT.lines() {
|
// for line in P2POOL_OUTPUT.lines() {
|
||||||
// if line.contains("You received a payout of [0-9].[0-9]+ XMR") { n += 1; }
|
// if line.contains("payout of [0-9].[0-9]+ XMR") { n += 1; }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// This regex function takes [0.0003~] seconds (10x faster):
|
// This regex function takes [0.0003~] seconds (10x faster):
|
||||||
// let regex = Regex::new("You received a payout of [0-9].[0-9]+ XMR").unwrap();
|
// let regex = Regex::new("payout of [0-9].[0-9]+ XMR").unwrap();
|
||||||
// let n = regex.find_iter(P2POOL_OUTPUT).count();
|
// let n = regex.find_iter(P2POOL_OUTPUT).count();
|
||||||
//
|
//
|
||||||
// Both are nominally fast enough where it doesn't matter too much but meh, why not use regex.
|
// Both are nominally fast enough where it doesn't matter too much but meh, why not use regex.
|
||||||
|
@ -1316,7 +1320,7 @@ struct P2poolRegex {
|
||||||
impl P2poolRegex {
|
impl P2poolRegex {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
payout: regex::Regex::new("You received a payout of [0-9].[0-9]+ XMR").unwrap(),
|
payout: regex::Regex::new("payout of [0-9].[0-9]+ XMR").unwrap(),
|
||||||
float: regex::Regex::new("[0-9].[0-9]+").unwrap(),
|
float: regex::Regex::new("[0-9].[0-9]+").unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1685,10 +1689,10 @@ impl PrivXmrigApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send an HTTP request to XMRig's API, serialize it into [Self] and return it
|
// Send an HTTP request to XMRig's API, serialize it into [Self] and return it
|
||||||
async fn request_xmrig_api(client: hyper::Client<hyper::client::HttpConnector>, api_ip_port: &str) -> Result<Self, anyhow::Error> {
|
async fn request_xmrig_api(client: hyper::Client<hyper::client::HttpConnector>, api_uri: &str) -> Result<Self, anyhow::Error> {
|
||||||
let request = hyper::Request::builder()
|
let request = hyper::Request::builder()
|
||||||
.method("GET")
|
.method("GET")
|
||||||
.uri("http://".to_string() + api_ip_port + XMRIG_API_URI)
|
.uri(api_uri)
|
||||||
.body(hyper::Body::empty())?;
|
.body(hyper::Body::empty())?;
|
||||||
let response = tokio::time::timeout(std::time::Duration::from_millis(500), client.request(request)).await?;
|
let response = tokio::time::timeout(std::time::Duration::from_millis(500), client.request(request)).await?;
|
||||||
let body = hyper::body::to_bytes(response?.body_mut()).await?;
|
let body = hyper::body::to_bytes(response?.body_mut()).await?;
|
||||||
|
@ -1868,9 +1872,9 @@ mod test {
|
||||||
use std::sync::{Arc,Mutex};
|
use std::sync::{Arc,Mutex};
|
||||||
let public = Arc::new(Mutex::new(PubP2poolApi::new()));
|
let public = Arc::new(Mutex::new(PubP2poolApi::new()));
|
||||||
let output_parse = Arc::new(Mutex::new(String::from(
|
let output_parse = Arc::new(Mutex::new(String::from(
|
||||||
r#"You received a payout of 5.000000000001 XMR in block 1111
|
r#"payout of 5.000000000001 XMR in block 1111
|
||||||
You received a payout of 5.000000000001 XMR in block 1112
|
payout of 5.000000000001 XMR in block 1112
|
||||||
You received a payout of 5.000000000001 XMR in block 1113"#
|
payout of 5.000000000001 XMR in block 1113"#
|
||||||
)));
|
)));
|
||||||
let output_pub = Arc::new(Mutex::new(String::new()));
|
let output_pub = Arc::new(Mutex::new(String::new()));
|
||||||
let elapsed = std::time::Duration::from_secs(60);
|
let elapsed = std::time::Duration::from_secs(60);
|
||||||
|
|
22
utils/create_tmp_env.sh
Executable file
22
utils/create_tmp_env.sh
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Sets up a packaging environment in [/tmp]
|
||||||
|
|
||||||
|
# Make sure we're in the [gupax/utils] directory
|
||||||
|
set -ex
|
||||||
|
[[ $PWD = */gupax ]]
|
||||||
|
|
||||||
|
# Make sure the folder doesn't already exist
|
||||||
|
GIT_COMMIT=$(cat .git/refs/heads/main)
|
||||||
|
FOLDER="gupax_${GIT_COMMIT}"
|
||||||
|
[[ ! -e /tmp/${FOLDER} ]]
|
||||||
|
|
||||||
|
mkdir /tmp/${FOLDER}
|
||||||
|
cp -r utils/* /tmp/${FOLDER}/
|
||||||
|
cp CHANGELOG.md /tmp/${FOLDER}/skel/
|
||||||
|
|
||||||
|
set +ex
|
||||||
|
|
||||||
|
echo
|
||||||
|
ls --color=always /tmp/${FOLDER}
|
||||||
|
echo "/tmp/${FOLDER} ... OK"
|
0
utils/skel/macos/Gupax.app/Gupax → utils/skel/linux/Gupax.AppImage
Normal file → Executable file
0
utils/skel/macos/Gupax.app/Gupax → utils/skel/linux/Gupax.AppImage
Normal file → Executable file
0
utils/skel/linux/gupax
Normal file → Executable file
0
utils/skel/linux/gupax
Normal file → Executable file
0
utils/skel/macos/Gupax.app/Contents/Info.plist
Executable file
0
utils/skel/macos/Gupax.app/Contents/Info.plist
Executable file
0
utils/skel/macos/Gupax.app/Contents/MacOS/Gupax
Normal file
0
utils/skel/macos/Gupax.app/Contents/MacOS/Gupax
Normal file
0
utils/skel/macos/Gupax.app/Contents/Resources/Gupax.icns
Executable file
0
utils/skel/macos/Gupax.app/Contents/Resources/Gupax.icns
Executable file
Loading…
Reference in a new issue