diff --git a/Cargo.lock b/Cargo.lock
index 8f10e85..818714a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3823,9 +3823,9 @@ dependencies = [
[[package]]
name = "sysinfo"
-version = "0.27.0"
+version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d08ba83d6dde63d053e42d7230f0dc7f8d8efeb8d30d3681580d158156461ba"
+checksum = "ccb297c0afb439440834b4bcf02c5c9da8ec2e808e70f36b0d8e815ff403bd24"
dependencies = [
"cfg-if",
"core-foundation-sys",
diff --git a/Cargo.toml b/Cargo.toml
index 83c5949..5fed009 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,10 @@ strip = "symbols"
codegen-units = 1
lto = true
+[features]
+default = []
+distro = []
+
[dependencies]
anyhow = "1.0.65"
arti-client = { version = "0.7.0", features = ["static"] }
diff --git a/README.md b/README.md
index cdcdc36..ca0d6f0 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@ Gupax is a (Windows|macOS|Linux) GUI for mining [**Monero**](https://github.com/
* [Build](#Build)
- [General Info](#General-Info)
- [Linux](#Linux)
+ - [Building for a distribution](#building-for-a-distribution)
- [macOS](#macOS)
- [Windows](#Windows)
* [License](#License)
@@ -126,7 +127,7 @@ P2Pool Simple allows you to ping & connect to a [Community Monero Node](#communi
To start P2Pool, first input the Monero address you'd like to receive payouts from. You must use a primary Monero address to mine on P2Pool (starts with a 4). It is highly recommended to create a new wallet since addresses are public on P2Pool!
-**Warning: [There are negative privacy and security implications when using Monero node not in your control.](https://www.getmonero.org/resources/moneropedia/remote-node.html)** Select a community node that you trust, or better yet, run your own node. If you'd like to manually specify a node to connect to, see [Advanced.](#advanced)
+**Warning: [There are negative privacy/security implications when using a Monero node not in your control.](https://www.getmonero.org/resources/moneropedia/remote-node.html)** Select a community node that you trust, or better yet, run your own node. If you'd like to manually specify a node to connect to, see [Advanced.](#advanced)
---
@@ -141,17 +142,17 @@ Gupax will automatically launch XMRig with administrator privileges to activate
**macOS/Linux:**
Gupax will prompt for your `sudo` password to start XMRig with and do all the things above.
-XMRig Simple will always mine to your own local P2Pool (`localhost:3333`), if you'd like to manually specify a pool to mine to, see [Advanced](#advanced).
+XMRig Simple will always mine to your own local P2Pool (`127.0.0.1:3333`), if you'd like to manually specify a pool to mine to, see [Advanced](#advanced).
## Advanced
### Verifying
It is recommended to verify the hash and PGP signature of the download before using Gupax.
-Download the [`SHA256SUM`](https://github.com/hinto-janaiyo/gupax/releases/latest) file, download and import my [`PGP key`](https://github.com/hinto-janaiyo/gupax/blob/main/pgp/hinto-janaiyo.asc), and verify:
+Download the [`SHA256SUMS`](https://github.com/hinto-janaiyo/gupax/releases/latest) file, download and import my [`PGP key`](https://github.com/hinto-janaiyo/gupax/blob/main/pgp/hinto-janaiyo.asc), and verify:
```bash
-sha256sum -c SHA256SUM
+sha256sum -c SHA256SUMS
gpg --import hinto-janaiyo.asc
-gpg --verify SHA256SUM
+gpg --verify SHA256SUMS
```
Q: How can I be sure the P2Pool/XMRig bundled with Gupax hasn't been tampered with?
@@ -277,11 +278,11 @@ RUST_LOG=debug ./gupax
```
In general:
-- `ERROR` means something has gone wrong and that something will likely break
-- `WARN` means something has gone wrong, but things will likely be fine
+- `ERROR` means something has gone wrong and that something will probably break
+- `WARN` means something has gone wrong, but things will be fine
- `INFO` logs are general info about what Gupax (the GUI thread) is currently doing
- `DEBUG` logs are much more verbose and include what EVERY thread is doing (not just the main GUI thread)
-- `TRACE` logs are insanely verbose and shows the logs of the libraries Gupax uses (HTTP connections, GUI polling, etc)
+- `TRACE` logs are insanely verbose and shows very low-level logs of the libraries Gupax uses (HTTP connections, GUI polling, etc)
---
@@ -464,6 +465,12 @@ You need [`cargo`](https://www.rust-lang.org/learn/get-started), Rust's build to
The `--release` profile in Gupax is set to prefer code performance & small binary sizes over compilation speed (see [`Cargo.toml`](https://github.com/hinto-janaiyo/gupax/blob/main/Cargo.toml)). Gupax itself (with all dependencies already built) takes around 1m30s to build (vs 10s on a normal `--release`) with a Ryzen 5950x.
+There are `20` unit tests throughout the codebase files, you should probably run:
+```
+cargo test
+```
+before attempting a full build.
+
---
### Linux
@@ -474,6 +481,17 @@ After that, run:
cargo build --release
```
+### Building for a distribution
+Gupax has a build flag for use as a package in a Linux distribution:
+```
+cargo build --release --features distro
+```
+This is the same as the `--release` profile, but with some changes:
+| Change | Reason |
+|--------------------------------------------|--------|
+| Built-in `Update` feature is disabled | Updates should be handled by the native package manager
+| Default `P2Pool/XMRig` path is `/usr/bin/` | `P2Pool/XMRig` exist in _[some](https://aur.archlinux.org)_ repositories, which means they'll be installed in `/usr/bin/`
+
---
### macOS
@@ -515,12 +533,12 @@ The latest versions are downloaded using the GitHub API.
* P2Pool [`https://github.com/SChernykh/p2pool`](https://github.com/SChernykh/p2pool)
* XMRig [`https://github.com/xmrig/xmrig`](https://github.com/xmrig/xmrig)
-GitHub's API blocks request that do not have an HTTP `User-Agent` header. [For privacy, Gupax randomly uses a recent version of a `Wget/Curl` user-agent.](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/update.rs#L134)
+GitHub's API blocks request that do not have an HTTP `User-Agent` header. [Gupax uses a random recent version of a `Wget/Curl` user-agent.](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/update.rs#L134)
---
### Can I quit mid-update?
-If you started an update, you should let it finish. If the update has been stuck for a *long* time, it may be worth quitting Gupax. The worst that can happen is that your `Gupax/P2Pool/XMRig` binaries may be moved/deleted. Those can be easily redownloaded. Your actual `Gupax` user data (settings, custom nodes, pools, etc) is never touched.
+If you started an update, you should let it finish. If the update has been stuck for a *long* time, quitting Gupax is probably okay. The worst that can happen is that your `Gupax/P2Pool/XMRig` binaries may be moved/deleted. Those can be easily redownloaded. Your actual `Gupax` user data (settings, custom nodes, pools, etc) is never touched.
Although Gupax uses a temporary folder (`gupax_update_[A-Za-z0-9]`) to store temporary downloaded files, there aren't measures in place to revert an upgrade once the file swapping has actually started. If you quit Gupax anytime before the `Upgrading packages` phase (after metadata, download, extraction), you will technically be safe but this is not recommended as it is risky, especially since these updates can be very fast.
@@ -536,7 +554,7 @@ Although Gupax uses a temporary folder (`gupax_update_[A-Za-z0-9]`) to store tem
### How much memory does Gupax use?
Gupax itself uses around 100-300 megabytes of memory.
-Gupax also holds up to [500,000 bytes](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/helper.rs#L63) of log data from `P2Pool/XMRig` to display in the GUI terminals. These logs are reset once over capacity which takes around 1-2 hours.
+Gupax also holds up to [500,000 bytes](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/helper.rs#L63) of log data from `P2Pool/XMRig` to display in the GUI terminals. These logs are reset once over capacity which takes around 1-4 hours.
Memory usage should *never* be above 500~ megabytes. If you see Gupax using more than this, please send a bug report.
diff --git a/src/README.md b/src/README.md
index 7e289d9..e43d15f 100644
--- a/src/README.md
+++ b/src/README.md
@@ -105,7 +105,7 @@ Exceptions (there are always exceptions...):
- P2Pool hashes are in UPPERCASE
## Sudo
-Unlike Windows, Unix (macOS/Linux) have a userland program that handles all the dirty details of privilege escalation: `sudo`.
+Unlike Windows, Unix (macOS/Linux) has a userland program that handles all the dirty details of privilege escalation: `sudo`.
`sudo` is used in Gupax to execute XMRig, to enable MSR mods and hugepages. After every use of `sudo`, the memory holding the `String` buffer containing the password is wiped with 0's using [`zeroize`](https://docs.rs/zeroize/) to make sure the compiler doesn't optimize away the wipe. Although memory *should* be safe, this prevents passive accidents (core-dumps revealing plain-text password) and active attacks (attackers accessing live process memory) from happening.
diff --git a/src/constants.rs b/src/constants.rs
index f28a082..e69e509 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -15,11 +15,20 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-pub const GUPAX_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION"));
+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 XMRIG_VERSION: &str = "v6.18.0";
pub const COMMIT: &str = include_str!("../.git/refs/heads/main");
-pub const GUPAX_VERSION_UNDERSCORE: &str = concat!("Gupax_v", env!("CARGO_PKG_VERSION"));
+// e.g: Gupax_v1_0_0
+// Would have been [Gupax_v1.0.0] but P2Pool truncates everything after [.]
+pub const GUPAX_VERSION_UNDERSCORE: &str = concat!(
+ "Gupax_v",
+ env!("CARGO_PKG_VERSION_MAJOR"),
+ "_",
+ env!("CARGO_PKG_VERSION_MINOR"),
+ "_",
+ env!("CARGO_PKG_VERSION_PATCH"),
+);
// App frame resolution, [4:3] aspect ratio, [1.33:1]
pub const APP_MIN_WIDTH: f32 = 640.0;
@@ -30,6 +39,11 @@ pub const APP_MAX_HEIGHT: f32 = 1920.0;
pub const APP_DEFAULT_WIDTH: f32 = 1280.0;
pub const APP_DEFAULT_HEIGHT: f32 = 960.0;
+// Constants specific for Linux distro packaging of Gupax
+#[cfg(feature = "distro")]
+pub const DISTRO_NO_UPDATE: &str =
+r#"This [Gupax] was compiled for use as a Linux distro package. Built-in updates are disabled. The below settings [Update-via-Tor] & [Auto-Update] will not do anything. Please use your package manager to update [Gupax/P2Pool/XMRig]."#;
+
// Use macOS shaped icon for macOS
#[cfg(target_os = "macos")]
pub const BYTES_ICON: &[u8] = include_bytes!("../images/icons/icon@2x.png");
diff --git a/src/disk.rs b/src/disk.rs
index b4c6299..6a4c76c 100644
--- a/src/disk.rs
+++ b/src/disk.rs
@@ -53,21 +53,33 @@ use log::*;
const ERROR: &str = "Disk error";
const PATH_ERROR: &str = "PATH for state directory could not be not found";
#[cfg(target_os = "windows")]
-const DIRECTORY: &'static str = r#"Gupax\"#;
+const DIRECTORY: &str = r#"Gupax\"#;
#[cfg(target_os = "macos")]
-const DIRECTORY: &'static str = "Gupax/";
+const DIRECTORY: &str = "Gupax/";
#[cfg(target_os = "linux")]
const DIRECTORY: &str = "gupax/";
#[cfg(target_os = "windows")]
-pub const DEFAULT_P2POOL_PATH: &'static str = r"P2Pool\p2pool.exe";
-#[cfg(target_family = "unix")]
+pub const DEFAULT_P2POOL_PATH: &str = r"P2Pool\p2pool.exe";
+#[cfg(target_os = "macos")]
pub const DEFAULT_P2POOL_PATH: &str = "p2pool/p2pool";
#[cfg(target_os = "windows")]
-pub const DEFAULT_XMRIG_PATH: &'static str = r"XMRig\xmrig.exe";
-#[cfg(target_family = "unix")]
+pub const DEFAULT_XMRIG_PATH: &str = r"XMRig\xmrig.exe";
+#[cfg(target_os = "macos")]
pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
+// Default to [/usr/bin/] for Linux distro builds.
+#[cfg(target_os = "linux")]
+#[cfg(not(feature = "distro"))]
+pub const DEFAULT_P2POOL_PATH: &str = "p2pool/p2pool";
+#[cfg(target_os = "linux")]
+#[cfg(not(feature = "distro"))]
+pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
+#[cfg(feature = "distro")]
+pub const DEFAULT_P2POOL_PATH: &str = "/usr/bin/p2pool";
+#[cfg(feature = "distro")]
+pub const DEFAULT_XMRIG_PATH: &str = "/usr/bin/xmrig";
+
//---------------------------------------------------------------------------------------------------- General functions for all [File]'s
// get_file_path() | Return absolute path to OS data path + filename
// read_to_string() | Convert the file at a given path into a [String]
diff --git a/src/gupax.rs b/src/gupax.rs
index ad1f849..68202eb 100644
--- a/src/gupax.rs
+++ b/src/gupax.rs
@@ -93,7 +93,15 @@ impl Gupax {
let width = width - SPACE;
let updating = *update.lock().unwrap().updating.lock().unwrap();
ui.vertical(|ui| {
+ // If [Gupax] is being built for a Linux distro,
+ // disable built-in updating completely.
+ #[cfg(feature = "distro")]
+ ui.set_enabled(false);
+ #[cfg(feature = "distro")]
+ ui.add_sized([width, height], Button::new("Updates are disabled")).on_disabled_hover_text(DISTRO_NO_UPDATE);
+ #[cfg(not(feature = "distro"))]
ui.set_enabled(!updating);
+ #[cfg(not(feature = "distro"))]
if ui.add_sized([width, height], Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE).clicked() {
Update::spawn_thread(og, self, state_path, update, error_state, restart);
}
diff --git a/src/helper.rs b/src/helper.rs
index 623dafd..12ea8a3 100644
--- a/src/helper.rs
+++ b/src/helper.rs
@@ -1724,6 +1724,18 @@ impl Hashrate {
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
+ #[test]
+ fn reset_gui_output() {
+ let max = crate::helper::GUI_OUTPUT_LEEWAY;
+ let mut string = String::with_capacity(max);
+ for _ in 0..=max {
+ string.push('0');
+ }
+ crate::Helper::check_reset_gui_output(&mut string, crate::ProcessName::P2pool);
+ // Some text gets added, so just check for less than 500 bytes.
+ assert!(string.len() < 500);
+ }
+
#[test]
fn human_number() {
use crate::HumanNumber;
diff --git a/src/main.rs b/src/main.rs
index 12deba5..cf38e12 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -713,6 +713,7 @@ fn init_auto(app: &mut App) {
}
// [Auto-Update]
+ #[cfg(not(feature = "distro"))]
if app.state.gupax.auto_update {
Update::spawn_thread(&app.og, &app.state.gupax, &app.state_path, &app.update, &mut app.error_state, &app.restart);
} else {
@@ -1563,12 +1564,6 @@ impl eframe::App for App {
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
- #[test]
- fn build_app() {
- let mut app = crate::App::new(std::time::Instant::now());
- crate::init_auto(&mut app);
- }
-
#[test]
fn build_regex() {
use regex::Regex;
@@ -1587,9 +1582,4 @@ mod test {
assert!(!Regex::is_match(&r.port, "0"));
assert!(!Regex::is_match(&r.port, "65536"));
}
-
- #[test]
- fn build_images() {
- crate::Images::new();
- }
}
diff --git a/src/update.rs b/src/update.rs
index 98fd544..58a36b7 100644
--- a/src/update.rs
+++ b/src/update.rs
@@ -285,6 +285,14 @@ impl Update {
// an update needs to happen (Gupax tab, auto-update), the
// code only needs to be edited once, here.
pub fn spawn_thread(og: &Arc>, gupax: &crate::disk::Gupax, state_path: &Path, update: &Arc>, error_state: &mut ErrorState, restart: &Arc>) {
+ // We really shouldn't be in the function for
+ // the Linux distro Gupax (UI gets disabled)
+ // but if somehow get in here, just return.
+ #[cfg(feature = "distro")]
+ error!("Update | This is the [Linux distro] version of Gupax, updates are disabled");
+ #[cfg(feature = "distro")]
+ return;
+
// Check P2Pool path for safety
// Attempt relative to absolute path
let p2pool_path = match into_absolute_path(gupax.p2pool_path.clone()) {
@@ -383,6 +391,11 @@ impl Update {
// 5. extract, upgrade
#[tokio::main]
pub async fn start(update: Arc>, _og: Arc>, state_ver: Arc>, restart: Arc>) -> Result<(), anyhow::Error> {
+ #[cfg(feature = "distro")]
+ error!("Update | This is the [Linux distro] version of Gupax, updates are disabled");
+ #[cfg(feature = "distro")]
+ return Err(anyhow!("This is the [Linux distro] version of Gupax, updates are disabled"));
+
//---------------------------------------------------------------------------------------------------- Init
*update.lock().unwrap().updating.lock().unwrap() = true;
// Set timer