v1.3.10
Some checks failed
Cache `gupax.io` / build (push) Has been cancelled
CI / ci (macos-14) (push) Has been cancelled
CI / ci (ubuntu-20.04) (push) Has been cancelled
CI / ci (windows-2019) (push) Has been cancelled
gupax.io / build (push) Has been cancelled
Remote Node Ping / build (push) Has been cancelled
Typo / typo (push) Has been cancelled

This commit is contained in:
hinto.janai 2024-11-21 20:16:32 -05:00
parent ab9912fccc
commit f3d29c99de
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
32 changed files with 7797 additions and 6615 deletions

View file

@ -1,14 +0,0 @@
---
name: Feature request
about: Request a feature
title: ''
labels: feature
assignees: ''
---
**Feature request**
Describe the feature you're requesting.
**Additional context**
Add any other context or screenshots about the feature request.

View file

@ -1,4 +1,4 @@
# Forces `gupax.io` to cache stuff every day.
# Forces `gupax.io` to cache.
name: Cache `gupax.io`
on:

View file

@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
os: [windows-2019, macos-12, ubuntu-20.04]
os: [windows-2019, macos-14, ubuntu-20.04]
steps:
- name: Checkout
@ -39,6 +39,7 @@ jobs:
sudo apt install -y libgtk-3-dev
elif [ "$RUNNER_OS" == "macOS" ]; then
cargo install cargo-bundle
rustup target install x86_64-apple-darwin
rustup target install aarch64-apple-darwin
fi
shell: bash
@ -49,9 +50,9 @@ jobs:
- name: Build
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
cargo bundle --release
cargo bundle --release --target x86_64-apple-darwin
cargo bundle --release --target aarch64-apple-darwin
mv target/release/bundle/osx/Gupax.app Gupax-macos-x64.app
mv target/x86_64-apple-darwin/release/bundle/osx/Gupax.app Gupax-macos-x64.app
mv target/aarch64-apple-darwin/release/bundle/osx/Gupax.app Gupax-macos-arm64.app
tar -cf macos.tar Gupax-macos-arm64.app Gupax-macos-x64.app
elif [ "$RUNNER_OS" == "Linux" ]; then

View file

@ -3,8 +3,6 @@
name: Remote Node Ping
on:
schedule:
- cron: "0 4 * * *"
push:
branches: [ "main" ]
pull_request:

View file

@ -1,3 +1,22 @@
# v1.3.10
## Changes
* [Remote Node](https://github.com/hinto-janai/gupax#remote-monero-nodes) changes:
- Removed `monero1.heitechsoft.com`
- Removed `node.cryptocano.de`
- Removed `fbx.tranbert.com`
- Removed `home.allantaylor.kiwi`
- Removed `sf.xmr.support`
* Text/visual changes
## Bundled Versions
* [`P2Pool v4.2`](https://github.com/SChernykh/p2pool/releases/tag/v4.2)
* [`XMRig v6.22.2`](https://github.com/xmrig/xmrig/releases/tag/v6.22.2)
---
# v1.3.9
## Changes
* [Remote Node](https://github.com/hinto-janai/gupax#remote-monero-nodes) changes:

2071
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
[package]
name = "gupax"
version = "1.3.9"
version = "1.3.10"
authors = ["hinto-janai <hinto.janai@protonmail.com>"]
description = "GUI for P2Pool+XMRig"
documentation = "https://github.com/hinto-janai/gupax"
@ -106,7 +106,7 @@ tls-api-native-tls = "0.9.0"
# Windows dependencies
[target.'cfg(windows)'.dependencies]
zip = "1.2.2"
zip = "1"
is_elevated = "0.1.2"
wgpu = { version = "0.19.4", features = ["angle"] }
@ -121,3 +121,213 @@ name = "Gupax"
identifier = "com.github.hinto-janai.gupax"
icon = ["images/icons/icon@2x.png"]
category = "public.app-category.utilities"
[workspace.lints.clippy]
borrow_as_ptr = "deny"
case_sensitive_file_extension_comparisons = "deny"
cast_lossless = "deny"
cast_ptr_alignment = "deny"
checked_conversions = "deny"
cloned_instead_of_copied = "deny"
const_is_empty = "deny"
doc_lazy_continuation = "deny"
doc_link_with_quotes = "deny"
duplicated_attributes = "deny"
empty_enum = "deny"
enum_glob_use = "deny"
expl_impl_clone_on_copy = "deny"
explicit_into_iter_loop = "deny"
filter_map_next = "deny"
flat_map_option = "deny"
from_iter_instead_of_collect = "deny"
if_not_else = "deny"
ignored_unit_patterns = "deny"
inconsistent_struct_constructor = "deny"
index_refutable_slice = "deny"
inefficient_to_string = "deny"
invalid_upcast_comparisons = "deny"
iter_filter_is_ok = "deny"
iter_filter_is_some = "deny"
implicit_clone = "deny"
legacy_numeric_constants = "deny"
manual_c_str_literals = "deny"
manual_pattern_char_comparison = "deny"
manual_instant_elapsed = "deny"
manual_inspect = "deny"
manual_is_variant_and = "deny"
manual_let_else = "deny"
manual_ok_or = "deny"
manual_string_new = "deny"
manual_unwrap_or_default = "deny"
map_unwrap_or = "deny"
match_bool = "deny"
match_same_arms = "deny"
match_wildcard_for_single_variants = "deny"
mismatching_type_param_order = "deny"
missing_transmute_annotations = "deny"
mut_mut = "deny"
needless_bitwise_bool = "deny"
needless_character_iteration = "deny"
needless_continue = "deny"
needless_for_each = "deny"
needless_maybe_sized = "deny"
needless_raw_string_hashes = "deny"
no_effect_underscore_binding = "deny"
no_mangle_with_rust_abi = "deny"
option_as_ref_cloned = "deny"
option_option = "deny"
ptr_as_ptr = "deny"
ptr_cast_constness = "deny"
pub_underscore_fields = "deny"
redundant_closure_for_method_calls = "deny"
ref_as_ptr = "deny"
ref_option_ref = "deny"
same_functions_in_if_condition = "deny"
semicolon_if_nothing_returned = "deny"
trivially_copy_pass_by_ref = "deny"
uninlined_format_args = "deny"
unnecessary_join = "deny"
unnested_or_patterns = "deny"
unused_async = "deny"
unused_self = "deny"
used_underscore_binding = "deny"
zero_sized_map_values = "deny"
as_ptr_cast_mut = "deny"
clear_with_drain = "deny"
collection_is_never_read = "deny"
debug_assert_with_mut_call = "deny"
derive_partial_eq_without_eq = "deny"
empty_line_after_doc_comments = "deny"
empty_line_after_outer_attr = "deny"
equatable_if_let = "deny"
iter_on_empty_collections = "deny"
iter_on_single_items = "deny"
iter_with_drain = "deny"
needless_collect = "deny"
needless_pass_by_ref_mut = "deny"
negative_feature_names = "deny"
non_send_fields_in_send_ty = "deny"
nonstandard_macro_braces = "deny"
path_buf_push_overwrite = "deny"
read_zero_byte_vec = "deny"
redundant_clone = "deny"
redundant_feature_names = "deny"
trailing_empty_array = "deny"
trait_duplication_in_bounds = "deny"
type_repetition_in_bounds = "deny"
uninhabited_references = "deny"
unnecessary_struct_initialization = "deny"
unused_peekable = "deny"
unused_rounding = "deny"
use_self = "deny"
useless_let_if_seq = "deny"
wildcard_dependencies = "deny"
unseparated_literal_suffix = "deny"
unnecessary_safety_doc = "deny"
unnecessary_safety_comment = "deny"
unnecessary_self_imports = "deny"
string_to_string = "deny"
rest_pat_in_fully_bound_structs = "deny"
redundant_type_annotations = "deny"
infinite_loop = "deny"
zero_repeat_side_effects = "deny"
cast_possible_truncation = "deny"
cast_possible_wrap = "deny"
cast_precision_loss = "deny"
cast_sign_loss = "deny"
copy_iterator = "deny"
doc_markdown = "deny"
explicit_deref_methods = "deny"
explicit_iter_loop = "deny"
float_cmp = "deny"
fn_params_excessive_bools = "deny"
into_iter_without_iter = "deny"
iter_without_into_iter = "deny"
iter_not_returning_iterator = "deny"
large_digit_groups = "deny"
large_types_passed_by_value = "deny"
manual_assert = "deny"
maybe_infinite_iter = "deny"
missing_fields_in_debug = "deny"
needless_pass_by_value = "deny"
range_minus_one = "deny"
range_plus_one = "deny"
redundant_else = "deny"
ref_binding_to_reference = "deny"
return_self_not_must_use = "deny"
single_match_else = "deny"
string_add_assign = "deny"
transmute_ptr_to_ptr = "deny"
unchecked_duration_subtraction = "deny"
unnecessary_box_returns = "deny"
unnecessary_wraps = "deny"
branches_sharing_code = "deny"
fallible_impl_from = "deny"
missing_const_for_fn = "deny"
significant_drop_in_scrutinee = "deny"
significant_drop_tightening = "deny"
try_err = "deny"
lossy_float_literal = "deny"
let_underscore_must_use = "deny"
iter_over_hash_type = "deny"
get_unwrap = "deny"
error_impl_error = "deny"
empty_structs_with_brackets = "deny"
empty_enum_variants_with_brackets = "deny"
empty_drop = "deny"
clone_on_ref_ptr = "deny"
upper_case_acronyms = "deny"
allow_attributes = "deny"
# inline_always = "deny"
# large_futures = "deny"
# large_stack_arrays = "deny"
# linkedlist = "deny"
# missing_errors_doc = "deny"
# missing_panics_doc = "deny"
# should_panic_without_expect = "deny"
# similar_names = "deny"
# too_many_lines = "deny"
# unreadable_literal = "deny"
# wildcard_imports = "deny"
# allow_attributes_without_reason = "deny"
# missing_assert_message = "deny"
# missing_docs_in_private_items = "deny"
undocumented_unsafe_blocks = "deny"
# multiple_unsafe_ops_per_block = "deny"
# single_char_lifetime_names = "deny"
# wildcard_enum_match_arm = "deny"
[workspace.lints.rust]
future_incompatible = { level = "deny", priority = -1 }
nonstandard_style = { level = "deny", priority = -1 }
absolute_paths_not_starting_with_crate = "deny"
explicit_outlives_requirements = "deny"
keyword_idents_2018 = "deny"
keyword_idents_2024 = "deny"
missing_abi = "deny"
non_ascii_idents = "deny"
non_local_definitions = "deny"
redundant_lifetimes = "deny"
single_use_lifetimes = "deny"
trivial_casts = "deny"
trivial_numeric_casts = "deny"
unsafe_op_in_unsafe_fn = "deny"
unused_crate_dependencies = "deny"
unused_import_braces = "deny"
unused_lifetimes = "deny"
unused_macro_rules = "deny"
ambiguous_glob_imports = "deny"
unused_unsafe = "deny"
let_underscore = { level = "deny", priority = -1 }
unreachable_pub = "deny"
unused_qualifications = "deny"
variant_size_differences = "deny"
non_camel_case_types = "deny"
# unused_results = "deny"
# non_exhaustive_omitted_patterns = "deny"
# missing_docs = "deny"
# missing_copy_implementations = "deny"

130
README.md
View file

@ -3,9 +3,9 @@
Gupax is a GUI for mining [**Monero**](https://github.com/monero-project/monero) on [**P2Pool**](https://github.com/SChernykh/p2pool), using [**XMRig**](https://github.com/xmrig/xmrig).
**To see a 3-minute video guide on how to set-up Gupax: [click here.](#Guide)**
To see a 3-minute video guide on how to set-up Gupax: [click here.](#Guide)
[![CI](https://github.com/hinto-janai/gupax/actions/workflows/ci.yml/badge.svg)](https://github.com/hinto-janai/gupax/actions/workflows/ci.yml) [![gupax.io](https://github.com/hinto-janai/gupax/actions/workflows/download.yml/badge.svg)](https://github.com/hinto-janai/gupax/actions/workflows/download.yml) [![Remote Node Ping](https://github.com/hinto-janai/gupax/actions/workflows/ping.yml/badge.svg)](https://github.com/hinto-janai/gupax/actions/workflows/ping.yml)
[![CI](https://github.com/hinto-janai/gupax/actions/workflows/ci.yml/badge.svg)](https://github.com/hinto-janai/gupax/actions/workflows/ci.yml) [![gupax.io](https://github.com/hinto-janai/gupax/actions/workflows/download.yml/badge.svg)](https://github.com/hinto-janai/gupax/actions/workflows/download.yml)
</div>
@ -19,11 +19,10 @@ Gupax is a GUI for mining [**Monero**](https://github.com/monero-project/monero)
- [XMRig](#XMRig)
* [Advanced](#Advanced)
- [Verifying](#Verifying)
- [Running a Local Monero Node](#running-a-local-monero-node)
- [Running a Local Monero node](#running-a-local-monero-node)
- [Command Line](#Command-Line)
- [Key Shortcuts](#Key-Shortcuts)
- [Resolution](#Resolution)
- [Tor/Arti](#TorArti)
- [Tor](#Tor)
- [Logs](#Logs)
- [Disk](#Disk)
- [Swapping P2Pool/XMRig](#Swapping-P2PoolXMRig)
@ -32,7 +31,7 @@ Gupax is a GUI for mining [**Monero**](https://github.com/monero-project/monero)
- [P2Pool](#P2Pool-1)
- [XMRig](#XMRig-1)
* [Connections](#Connections)
* [Remote Monero Nodes](#remote-monero-nodes)
* [Remote Monero nodes](#remote-monero-nodes)
* [Build](#Build)
- [General Info](#General-Info)
- [Linux](#Linux)
@ -54,7 +53,7 @@ Gupax is a GUI for mining [**Monero**](https://github.com/monero-project/monero)
## What is Monero/P2Pool/XMRig/Gupax?
[**`Monero`**](https://getmonero.org) is a secure, private, and untraceable cryptocurrency.
[Monero GUI](https://github.com/monero-project/monero-gui) allows you to run a Monero node (among other things).
[Monero GUI](https://github.com/monero-project/monero-gui) allows you to run a Monero node, among other things.
---
@ -69,17 +68,17 @@ 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**
* **0% transaction fee, 0 payout fee, immediate ~0.00027 XMR minimum payout**
---
[**`XMRig`**](https://github.com/xmrig/xmrig) is an optimized miner that can mine Monero.
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.
Both Monero and P2Pool have built in miners but XMRig is 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.
---
[**`Gupax`**](https://github.com/hinto-janai/gupax) is a GUI that helps manage P2Pool & XMRig (both originally CLI-only).
[**`Gupax`**](https://github.com/hinto-janai/gupax) is a GUI that helps manage P2Pool & XMRig which are both CLI-only.
<img src="images/local.png" align="left" width="50%"/>
@ -97,7 +96,7 @@ Both Monero and P2Pool have built in miners but XMRig is quite faster than both
<img src="images/remote.png" align="left" width="50%"/>
By default, Gupax will use a [Remote Monero Node](#remote-monero-nodes) so you don't have to run [your own Monero node](#running-a-local-monero-node) to start mining on P2Pool.
By default, Gupax will use a [Remote Monero node](#remote-monero-nodes) so you don't have to run [your own Monero node](#running-a-local-monero-node) to start mining on P2Pool.
<br clear="left"/>
@ -110,7 +109,7 @@ https://user-images.githubusercontent.com/101352116/207978455-6ffdc0cc-204c-4594
2. Extract
3. Launch Gupax
4. Input your Monero address in the `P2Pool` tab
5. Select a [`Remote Monero Node`](#remote-monero-nodes) (or run your own local [Monero Node](#running-a-local-monero-node))
5. Select a [`Remote Monero node`](#remote-monero-nodes) (or run your own local [Monero node](#running-a-local-monero-node))
6. Start P2Pool
7. Start XMRig
@ -167,8 +166,8 @@ This tab has the updater and general Gupax settings.
If `Check for updates` is pressed, Gupax will update your `Gupax/P2Pool/XMRig` (if needed) using the [GitHub API](#where-are-updates-downloaded-from).
Below that, there are some general Gupax settings:
| Setting | What does it do? |
|--------------------|-------------------|
| Setting | What it does |
|--------------------|--------------|
| `Update via Tor` | Causes updates to be fetched via the Tor network. Tor is embedded within Gupax; a Tor system proxy is not required
| `Auto-Update` | Gupax will automatically check for updates at startup
| `Auto-P2Pool` | Gupax will automatically start P2Pool at startup
@ -179,7 +178,7 @@ Below that, there are some general Gupax settings:
---
### P2Pool
P2Pool Simple allows you to ping & connect to a [Remote Monero Node](#remote-monero-nodes) and start your own local P2Pool instance on the `Mini` sidechain.
P2Pool Simple allows you to ping & connect to a [Remote Monero node](#remote-monero-nodes) and start your own local P2Pool instance on the `Mini` sidechain.
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!
@ -204,30 +203,27 @@ XMRig Simple will always mine to your own local P2Pool (`127.0.0.1:3333`), if yo
### Verifying
It is recommended to verify the hash and PGP signature of the download before using Gupax.
Download the [`SHA256SUMS`](https://github.com/hinto-janai/gupax/releases/latest) file, download and import my [`PGP key`](https://github.com/hinto-janai/gupax/blob/main/pgp/hinto-janai.asc), and verify:
Download the [`SHA256SUMS`](https://github.com/hinto-janai/gupax/releases/latest) file, download and import this [`PGP key`](https://github.com/hinto-janai/gupax/blob/main/pgp/hinto-janai.asc), and verify:
```bash
sha256sum -c SHA256SUMS
gpg --import hinto-janai.asc
gpg --verify SHA256SUMS
```
Q: How can I be sure the P2Pool/XMRig bundled with Gupax hasn't been tampered with?
A: Verify the hash.
You can always compare the hash of the `P2Pool/XMRig` binaries bundled with Gupax with the hashes of the binaries found here:
You can compare the hash of the `P2Pool/XMRig` binaries bundled with Gupax with the hashes of the binaries found here:
- https://github.com/SChernykh/p2pool/releases
- https://github.com/xmrig/xmrig/releases
Make sure the _version_ you are comparing against is correct, and make sure you are comparing the _binary_ to the _binary_, not the `tar/zip`. If they match, you can be sure they are the exact same. Verifying the PGP signature is also recommended:
Make sure the _version_ you are comparing against is correct, and make sure you are comparing the _binary_ to the _binary_, not the `tar/zip`. If they match, they are the exact same. Verifying the PGP signature is also recommended:
- P2Pool - [`SChernykh.asc`](https://github.com/monero-project/gitian.sigs/blob/master/gitian-pubkeys/SChernykh.asc)
- XMRig - [`xmrig.asc`](https://github.com/xmrig/xmrig/blob/master/doc/gpg_keys/xmrig.asc)
---
### Running a Local Monero Node
Running and using your own local Monero node improves privacy and security. It also means you won't be depending on one of the [Remote Monero Nodes](#remote-monero-nodes) provided by Gupax. This comes at the cost of downloading and syncing Monero's blockchain yourself (currently `155GB`).
### Running a Local Monero node
Running and using your own local Monero node improves privacy and security. It also means you won't be depending on one of the [Remote Monero nodes](#remote-monero-nodes) provided by Gupax. This comes at the cost of downloading and syncing Monero's blockchain yourself.
If you'd like to run and use your own local Monero node for P2Pool, follow these steps:
To run and use your own local Monero node for P2Pool, follow these steps:
<div align="center">
<img src="images/local_node.png" width="66%"/>
@ -237,11 +233,10 @@ If you'd like to run and use your own local Monero node for P2Pool, follow these
3. Enable `Local node`
4. Enter `--zmq-pub=tcp://127.0.0.1:18083` into `Daemon startup flags`
5. [(Optionally)](https://github.com/SChernykh/p2pool#windows) enter `--disable-dns-checkpoints --enable-dns-blocklist` into `Daemon startup flags`
6. Start and fully sync node
</div>
After syncing the blockchain, you will now have your own Monero node.
The 4th step enables `ZMQ`, which is extra Monero node functionality that is needed for P2Pool to work correctly.
The 5th step:
@ -249,14 +244,10 @@ The 5th step:
- `--disable-dns-checkpoints` avoids periodical lag when DNS is updated (it's not needed when mining)
- `--enable-dns-blocklist` bans known bad nodes
[For more detailed information on configuring a Monero node, click here.](https://monerodocs.org)
---
### Command Line
By default, Gupax has `auto-update` & `auto-ping` enabled. This can only be turned off in the GUI which causes a chicken-and-egg problem.
To get around this, start Gupax with `--no-startup`. This will disable all `auto` features for that instance.
By default, Gupax has `auto-update` & `auto-ping` enabled. This can only be turned off in the GUI. To get around this, start Gupax with `--no-startup`. This will disable all `auto` features for that instance.
```
USAGE: ./gupax [--flag]
@ -276,9 +267,6 @@ USAGE: ./gupax [--flag]
---
### Key Shortcuts
The letter keys (Z/X/C/V/S/R) will only work if nothing is in focus, i.e, you _are not_ editing a text box.
An ALT+F4 will also trigger the exit confirm screen (if enabled).
```
*---------------------------------------*
| Key shortcuts |
@ -298,23 +286,10 @@ An ALT+F4 will also trigger the exit confirm screen (if enabled).
---
### Resolution
The default resolution of Gupax is `1280x960` which is a `4:3` aspect ratio.
This can be changed by dragging the corner of the window itself or by using the resolution sliders in the `Gupax Advanced` tab. After a resolution change, Gupax will fade-in/out of black and will take a second to resize all the UI elements to scale correctly to the new resolution.
If you have changed your OS's pixel scaling, you may need to resize Gupax to see all UI correctly.
The minimum window size is: `640x480`
The maximum window size is: `3840x2160`
Fullscreen mode can also be entered by pressing `F11`.
---
### Tor/Arti
### Tor
By default, Gupax updates via Tor. In particular, it uses [`Arti`](https://gitlab.torproject.org/tpo/core/arti), the official Rust implementation of Tor.
Instead of bootstrapping onto the Tor network every time, Arti saves state/cache about the Tor network (circuits, guards, etc) for later reuse onto the disk:
Arti saves state/cache about the Tor network (circuits, guards, etc) for later reuse onto the disk:
State:
| OS | Data Folder |
@ -354,10 +329,8 @@ The current files saved to disk:
---
### Logs
Gupax has console logs that show with increasing detail, what exactly it is is doing.
There are multiple log filter levels but by default, `INFO` and above are enabled.
To view more detailed console debug information, start Gupax with the environment variable `RUST_LOG` set to a log level like so:
To view more detailed console debug information, start Gupax with the environment variable `RUST_LOG` set to a log level:
```bash
RUST_LOG=(trace|debug|info|warn|error) ./gupax
```
@ -366,12 +339,11 @@ For example:
RUST_LOG=debug ./gupax
```
In general:
- `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 very low-level logs
- `ERROR`: has gone wrong and that something will probably break
- `WARN`: something has gone wrong, but things will be fine
- `INFO`: general info about what Gupax (the GUI thread) is currently doing
- `DEBUG`: much more verbose and include what EVERY thread is doing (not just the main GUI thread)
- `TRACE`: insanely verbose and shows very low-level logs
---
@ -463,13 +435,13 @@ Along with the updater and settings mentioned in [Simple](#simple), `Gupax Advan
- The selected tab on startup
- Gupax's resolution
**Warning:** Gupax will use your custom PATH/binary and will replace them if you use `Check for updates` in the `[Gupax]` tab. There are sanity checks in place, however. Your PATH MUST end in a value that _appears_ correct or else the updater will refuse to start:
**Warning:** Gupax will use your custom PATH/binary and will replace them if you use `Check for updates` in the `[Gupax]` tab. Your PATH must end in a value that appears correct or else the updater will refuse to start:
| Binary | Accepted values | Good PATH | Bad PATH |
|----------|----------------------------------|-----------------|----------|
| `P2Pool` | `P2POOL, P2Pool, P2pool, p2pool` | `P2pool/p2pool` | `Documents/my_really_important_file`
| `P2Pool` | `P2POOL, P2Pool, P2pool, p2pool` | `P2pool/p2pool` | `Documents/important_file`
| `XMRig` | `XMRIG, XMRig, Xmrig, xmrig` | `XMRig/XMRig` | `Desktop/`
If using Windows, the PATH _must_ end with `.exe`.
If using Windows, the PATH must end with `.exe`.
---
@ -488,9 +460,9 @@ The manual node list allows you save and connect up-to 1000 custom Monero nodes:
| Data Field | Purpose | Limits | Max Length |
|------------|---------------------------------------------------------------|--------------------------------------------------------|----------------|
| `Name` | A unique name to identify this node (only for Gupax purposes) | Only `[A-Za-z0-9-_.]` and spaces allowed | 30 characters |
| `IP` | The Monero Node IP to connect to with P2Pool | It must be a valid IPv4 address or a valid domain name | 255 characters |
| `RPC` | The RPC port of the Monero node | `[1-65535]` | 5 characters |
| `ZMQ` | The ZMQ port of the Monero node | `[1-65535]` | 5 characters |
| `IP` | The Monero node IP to connect to with P2Pool | It must be a valid IPv4 address or a valid domain name | 255 characters |
| `RPC` | The RPC port of the Monero node | `[1-65535]` | 5 characters |
| `ZMQ` | The ZMQ port of the Monero node | `[1-65535]` | 5 characters |
The `Main/Mini` selector allows you to change which P2Pool sidechain you mine on:
| P2Pool Sidechain | Description | Use-case |
@ -514,7 +486,6 @@ The remaining sliders control miscellaneous settings:
| `In peers` | How many in-bound peers P2Pool will allow to connect to you | `10` | `10..450` |
| `Log level` | Verbosity of the P2Pool console log | `3` | `0..6` |
---
### XMRig
@ -537,7 +508,7 @@ The manual pool list allows you save and connect up-to 1000 custom Pools (regard
|------------|---------------------------------------------------------------|--------------------------------------------------------|----------------|
| `Name` | A unique name to identify this pool (only for Gupax purposes) | Only `[A-Za-z0-9-_.]` and spaces allowed | 30 characters |
| `IP` | The pool IP to connect to with XMRig | It must be a valid IPv4 address or a valid domain name | 255 characters |
| `Port` | The port of the pool | `[1-65535]` | 5 characters |
| `Port` | The port of the pool | `[1-65535]` | 5 characters |
| `Rig` | An optional rig ID; This will be the name shown on the pool | Only `[A-Za-z0-9-_]` and spaces allowed | 30 characters |
The HTTP API textboxes allow you to change to IP/Port XMRig's HTTP API opens up on:
@ -558,25 +529,20 @@ For transparency, here's all the connections Gupax makes:
| Domain | Why | When | Where |
|--------------------|-------------------------------------------------------|------|-------|
| https://github.com | Fetching metadata information on packages + download | `[Gupax]` tab -> `Check for updates` | [`update.rs`](https://github.com/hinto-janai/gupax/blob/main/src/update.rs) |
| Remote Monero Nodes | Connecting to with P2Pool, measuring ping latency | `[P2Pool Simple]` tab | [`node.rs`](https://github.com/hinto-janai/gupax/blob/main/src/node.rs) |
| Remote Monero nodes | Connecting to with P2Pool, measuring ping latency | `[P2Pool Simple]` tab | [`node.rs`](https://github.com/hinto-janai/gupax/blob/main/src/node.rs) |
| DNS | DNS connections will usually be handled by your OS (or whatever custom DNS setup you have). If using Tor, DNS requests for updates [*should*](https://tpo.pages.torproject.net/core/doc/rust/arti/) be routed through the Tor network automatically | All of the above | All of the above |
## Remote Monero Nodes
## Remote Monero nodes
These are the remote nodes used by Gupax in the `[P2Pool Simple]` tab.
| IP/Domain | Location | RPC Port | ZMQ Port |
|-------------------------|-------------------|----------|----------|
| monero.10z.com.ar | 🇦🇷 Argentina | 18089 | 18084 |
| monero1.heitechsoft.com | 🇨🇦 Canada | 18081 | 18084 |
| node.monerodevs.org | 🇨🇦 Canada | 18089 | 18084 |
| node.cryptocano.de | 🇩🇪 Germany | 18089 | 18083 |
| p2pmd.xmrvsbeast.com | 🇩🇪 Germany | 18081 | 18083 |
| fbx.tranbert.com | 🇫🇷 France | 18089 | 18084 |
| node2.monerodevs.org | 🇫🇷 France | 18089 | 18084 |
| home.allantaylor.kiwi | 🇳🇿 New Zealand | 18089 | 18083 |
| p2pool.uk | 🇬🇧 United Kingdom | 18089 | 18084 |
| xmr.support | 🇺🇸 United States | 18081 | 18083 |
| sf.xmr.support | 🇺🇸 United States | 18081 | 18083 |
| xmrbandwagon.hopto.org | 🇺🇸 United States | 18081 | 18084 |
| xmr.spotlightsound.com | 🇺🇸 United States | 18081 | 18084 |
| node.richfowler.net | 🇺🇸 United States | 18089 | 18084 |
@ -585,16 +551,10 @@ These are the remote nodes used by Gupax in the `[P2Pool Simple]` tab.
### General Info
You need [`cargo`](https://www.rust-lang.org/learn/get-started), Rust's build tool and package manager.
There are `41` unit tests, you should probably run:
```
cargo test
```
before attempting a full build.
---
### Linux
The pre-compiled Linux binaries are built on Debian 11, you'll need these packages to build:
The pre-compiled Linux binaries are built on Ubuntu 20.04, you'll need these packages to build:
```
sudo apt install build-essential cmake libgtk-3-dev
```
@ -706,17 +666,17 @@ 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-janai/gupax/blob/2c5bd0d7f6a39415353769427d60c0ca57f29710/src/update.rs#L178)
### P2Pool connection errors
**TL;DR: Run & use your own Monero Node.**
**TL;DR: Run & use your own Monero node.**
If you are using the [default P2Pool settings](#P2Pool) then you are using a [Remote Monero Node](#remote-monero-nodes). Using a remote node is convenient but comes at the cost of privacy and reliability. You may encounter connections issues with these nodes that look like this:
If you are using the [default P2Pool settings](#P2Pool) then you are using a [Remote Monero node](#remote-monero-nodes). Using a remote node is convenient but comes at the cost of privacy and reliability. You may encounter connections issues with these nodes that look like this:
```
2023-01-05 12:27:37.7962 P2PServer peer 23.233.96.72:37888 is ahead on mainchain (height 2792939, your height 2792936). Is your monerod stuck or lagging?
```
To fix this you can select a different remote node, or better yet: [Run your own local Monero Node](#running-a-local-monero-node).
To fix this you can select a different remote node, or better yet: [Run your own local Monero node](#running-a-local-monero-node).
Running and using your own local Monero node improves privacy and ensures your connection is as stable as your own internet connection. This comes at the cost of downloading and syncing Monero's blockchain yourself (currently 155GB). If you have the disk space, consider using the [P2Pool Advanced](#p2pool-1) tab and connecting to your own Monero node.
For a simple guide, see the [Running a Local Monero Node](#running-a-local-monero-node) section.
For a simple guide, see the [Running a Local Monero node](#running-a-local-monero-node) section.
### 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, 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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

View file

@ -21,7 +21,6 @@
| cpu.json | [XMRig benchmark data in JSON](https://github.com/hinto-janai/xmrig-benchmarks)
| constants.rs | General constants used in Gupax
| disk.rs | Code for writing to disk: `state.toml/node.toml/pool.toml`; This holds the structs for the [State] struct
| ferris.rs | Cute crab bytes
| gupax.rs | `Gupax` tab
| helper.rs | The "helper" thread that runs for the entire duration Gupax is alive. All the processing that needs to be done without blocking the main GUI thread runs here, including everything related to handling P2Pool/XMRig
| human.rs | Code for displaying human readable numbers & time

View file

@ -16,8 +16,8 @@
// 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: v1.0.0
pub const P2POOL_VERSION: &str = "v3.10";
pub const XMRIG_VERSION: &str = "v6.21.3";
pub const P2POOL_VERSION: &str = "v4.2";
pub const XMRIG_VERSION: &str = "v6.22.2";
pub const COMMIT: &str = env!("COMMIT"); // set in build.rs
// e.g: Gupax_v1_0_0
// Would have been [Gupax_v1.0.0] but P2Pool truncates everything after [.]
@ -164,10 +164,10 @@ pub const STATUS_GUPAX_SYSTEM_CPU_MODEL: &str =
pub const STATUS_P2POOL_UPTIME: &str = "How long P2Pool has been online";
pub const STATUS_P2POOL_PAYOUTS: &str = "The total amount of payouts received in this instance of P2Pool and an extrapolated estimate of how many you will receive.
Note: these stats will be quite inaccurate if your P2Pool hasn't been running for a long time!";
Note: these stats will be quite inaccurate if your P2Pool hasn't been running for a long time.";
pub const STATUS_P2POOL_XMR: &str = "The total amount of XMR mined in this instance of P2Pool and an extrapolated estimate of how many you will mine in the future.
Note: these stats will be quite inaccurate if your P2Pool hasn't been running for a long time!";
Note: these stats will be quite inaccurate if your P2Pool hasn't been running for a long time.";
pub const STATUS_P2POOL_HASHRATE: &str = "The total amount of hashrate your P2Pool has pointed at it in 15 minute, 1 hour, and 24 hour averages";
pub const STATUS_P2POOL_SHARES: &str = "The total amount of shares found on P2Pool";
pub const STATUS_P2POOL_EFFORT: &str =
@ -259,8 +259,8 @@ pub const GUPAX_UPDATE_VIA_TOR: &str = "Update through the Tor network. Tor is
Note: This option is unstable on macOS.";
pub const GUPAX_ASK_BEFORE_QUIT: &str = "Ask before quitting Gupax";
pub const GUPAX_SAVE_BEFORE_QUIT: &str = "Automatically save any changed settings before quitting";
pub const GUPAX_AUTO_P2POOL: &str = "Automatically start P2Pool on Gupax startup. If you are using [P2Pool Simple], this will NOT wait for your [Auto-Ping] to finish, it will start P2Pool on the pool you already have selected. This option will fail if your P2Pool settings aren't valid!";
pub const GUPAX_AUTO_XMRIG: &str = "Automatically start XMRig on Gupax startup. This option will fail if your XMRig settings aren't valid!";
pub const GUPAX_AUTO_P2POOL: &str = "Automatically start P2Pool on Gupax startup. If you are using [P2Pool Simple], this will NOT wait for your [Auto-Ping] to finish, it will start P2Pool on the pool you already have selected. This option will fail if your P2Pool settings aren't valid.";
pub const GUPAX_AUTO_XMRIG: &str = "Automatically start XMRig on Gupax startup. This option will fail if your XMRig settings aren't valid.";
pub const GUPAX_ADJUST: &str = "Adjust and set the width/height of the Gupax window";
pub const GUPAX_WIDTH: &str = "Set the width of the Gupax window";
pub const GUPAX_HEIGHT: &str = "Set the height of the Gupax window";
@ -312,16 +312,16 @@ pub const P2POOL_SELECT_RANDOM: &str = "Select a random remote Monero node";
pub const P2POOL_SELECT_LAST: &str = "Select the previous remote Monero node";
pub const P2POOL_SELECT_NEXT: &str = "Select the next remote Monero node";
pub const P2POOL_PING: &str = "Ping the built-in remote Monero nodes";
pub const P2POOL_ADDRESS: &str = "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!";
pub const P2POOL_ADDRESS: &str = "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.";
pub const P2POOL_COMMUNITY_NODE_WARNING: &str = r#"--- Run and use your own Monero node ---
Using a remote Monero node is convenient but comes at the cost of privacy and reliability.
You may encounter connection issues with remote nodes which may cause mining performance loss! Late info from laggy nodes will cause your mining jobs to start later than they should.
You may encounter connection issues with remote nodes which may cause mining performance loss. Late info from remote nodes may cause mining jobs to start later than they should.
Running and using your own local Monero node improves privacy and ensures your connection is as stable as your own internet connection. This comes at the cost of downloading and syncing Monero's blockchain yourself (currently ~170GB). If you have the disk space, consider using the [Advanced] tab and connecting to your own Monero node.
Running and using your own local Monero node improves privacy and ensures your connection is as stable as your own internet connection. This comes at the cost of downloading and syncing Monero's blockchain. If you have the disk space, consider using the [Advanced] tab and connecting to your own Monero node.
For a simple guide, see the [Running a Local Monero Node] section on Gupax's GitHub by clicking this message."#;
For a simple guide, see the [Running a Local Monero Node] documentation by clicking this message."#;
pub const P2POOL_INPUT: &str = "Send a command to P2Pool";
pub const P2POOL_ARGUMENTS: &str = r#"Note: [--no-color] & [--data-api <PATH>] & [--local-api] must be set so that the [Status] tab can work!
@ -415,9 +415,9 @@ For more information, see link below:
<https://github.com/hinto-janai/gupax>"#;
//---------------------------------------------------------------------------------------------------- Visuals
use egui::epaint::{Rounding, Shadow, Stroke};
use egui::epaint::{Rounding, Stroke};
use egui::{style::Spacing, Color32, Visuals};
use egui::{Color32, Visuals};
use egui::style::{Selection, WidgetVisuals, Widgets};
use once_cell::sync::Lazy;
@ -499,7 +499,9 @@ pub static VISUALS: Lazy<Visuals> = Lazy::new(|| {
mod test {
#[test]
fn gupax_version_is_semver() {
assert_eq!(crate::GUPAX_VERSION.len(), 6);
let len = crate::GUPAX_VERSION.len();
println!("{len}");
assert!(len == 6 || len == 7);
}
#[test]

11685
src/cpu.json

File diff suppressed because it is too large Load diff

View file

@ -817,13 +817,13 @@ impl GupaxP2poolApi {
"GupaxP2poolApi | Deleting old folder at [{}]...",
path.display()
);
std::fs::remove_dir_all(&path)?;
std::fs::remove_dir_all(path)?;
info!(
"GupaxP2poolApi | Creating new default folder at [{}]...",
path.display()
);
create_gupax_p2pool_dir(&path)?;
Self::create_all_files(&path)?;
create_gupax_p2pool_dir(path)?;
Self::create_all_files(path)?;
Ok(())
}

File diff suppressed because one or more lines are too long

View file

@ -19,7 +19,7 @@ use crate::State;
use crate::{constants::*, macros::*, update::*, ErrorState, Restart, Tab};
use egui::{
Button, Checkbox, Label, ProgressBar, RichText, SelectableLabel, Slider, Spinner, TextEdit,
TextStyle, TextStyle::Monospace, Vec2,
Vec2,
};
use log::*;
use serde::{Deserialize, Serialize};
@ -70,7 +70,7 @@ pub enum Ratio {
//---------------------------------------------------------------------------------------------------- Gupax
impl crate::disk::Gupax {
#[inline(always)] // called once
#[expect(clippy::too_many_arguments)]
pub fn show(
&mut self,
og: &Arc<Mutex<State>>,
@ -81,7 +81,7 @@ impl crate::disk::Gupax {
restart: &Arc<Mutex<Restart>>,
width: f32,
height: f32,
frame: &mut eframe::Frame,
_frame: &mut eframe::Frame,
_ctx: &egui::Context,
ui: &mut egui::Ui,
) {
@ -512,7 +512,7 @@ impl crate::disk::Gupax {
lock!(file_window).thread = true;
thread::spawn(move || {
match rfd::FileDialog::new()
.set_title(&format!("Select {} Binary for Gupax", name))
.set_title(format!("Select {} Binary for Gupax", name))
.pick_file()
{
Some(path) => {

View file

@ -264,6 +264,7 @@ impl std::fmt::Display for ProcessName {
//---------------------------------------------------------------------------------------------------- [Helper]
impl Helper {
//---------------------------------------------------------------------------------------------------- General Functions
#[expect(clippy::too_many_arguments)]
pub fn new(
instant: std::time::Instant,
pub_sys: Arc<Mutex<Sys>>,
@ -318,7 +319,6 @@ impl Helper {
i += 1;
}
}
drop(i);
while let Some(Ok(line)) = stdout.next() {
// println!("{}", line); // For debugging.
@ -358,7 +358,6 @@ impl Helper {
i += 1;
}
}
drop(i);
while let Some(Ok(line)) = stdout.next() {
// println!("{}", line); // For debugging.
@ -398,7 +397,7 @@ impl Helper {
"{} Watchdog | Output is nearing {} bytes, resetting!",
name, MAX_GUI_OUTPUT_BYTES
);
let text = format!("{}\n{} GUI log is exceeding the maximum: {} bytes!\nI've reset the logs for you!\n{}\n\n\n\n", HORI_CONSOLE, name, MAX_GUI_OUTPUT_BYTES, HORI_CONSOLE);
let text = format!("{}\n{} GUI log is exceeding the maximum: {} bytes!\nResetting the logs...\n{}\n\n\n\n", HORI_CONSOLE, name, MAX_GUI_OUTPUT_BYTES, HORI_CONSOLE);
output.clear();
output.push_str(&text);
debug!("{} Watchdog | Resetting GUI output ... OK", name);
@ -687,6 +686,7 @@ impl Helper {
#[cold]
#[inline(never)]
#[expect(clippy::too_many_arguments)]
// The P2Pool watchdog. Spawns 1 OS thread for reading a PTY (STDOUT+STDERR), and combines the [Child] with a PTY so STDIN actually works.
fn spawn_p2pool_watchdog(
process: Arc<Mutex<Process>>,
@ -1109,7 +1109,7 @@ impl Helper {
// The actual binary we're executing is [sudo], technically
// the XMRig path is just an argument to sudo, so add it.
// Before that though, add the ["--prompt"] flag and set it
// to emptyness so that it doesn't show up in the output.
// to emptiness so that it doesn't show up in the output.
if cfg!(unix) {
args.push(r#"--prompt="#.to_string());
args.push("--".to_string());
@ -1262,7 +1262,7 @@ impl Helper {
// 1a. Create PTY
debug!("XMRig | Creating PTY...");
let pty = portable_pty::native_pty_system();
let mut pair = pty
let pair = pty
.openpty(portable_pty::PtySize {
rows: 100,
cols: 1000,
@ -2395,7 +2395,7 @@ impl PubXmrigApi {
// Formats raw private data into ready-to-print human readable version.
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigApi) {
let mut public = lock!(public);
let hashrate_raw = match private.hashrate.total.get(0) {
let hashrate_raw = match private.hashrate.total.first() {
Some(Some(h)) => *h,
_ => 0.0,
};
@ -2911,7 +2911,7 @@ mod test {
"hugepages": true
}"#;
use crate::helper::PrivXmrigApi;
let priv_api = serde_json::from_str::<PrivXmrigApi>(&data).unwrap();
let priv_api = serde_json::from_str::<PrivXmrigApi>(data).unwrap();
let json = serde_json::ser::to_string_pretty(&priv_api).unwrap();
println!("{}", json);
let data_after_ser = r#"{

View file

@ -281,14 +281,14 @@ mod test {
fn human_number() {
use crate::human::HumanNumber;
assert!(HumanNumber::to_percent(0.001).to_string() == "0%");
assert!(HumanNumber::to_percent(12.123123123123).to_string() == "12.12%");
assert!(HumanNumber::to_percent(12.123_123).to_string() == "12.12%");
assert!(HumanNumber::to_percent_3_point(0.001).to_string() == "0.001%");
assert!(
HumanNumber::from_hashrate([Some(123.1), Some(11111.1), None]).to_string()
== "[123 H/s, 11,111 H/s, ??? H/s]"
);
assert!(
HumanNumber::from_hashrate([None, Some(1.123), Some(123123.312)]).to_string()
HumanNumber::from_hashrate([None, Some(1.123), Some(123_123.31)]).to_string()
== "[??? H/s, 1 H/s, 123,123 H/s]"
);
assert!(
@ -299,8 +299,8 @@ mod test {
HumanNumber::from_load([None, Some(4321.43), Some(1234.1)]).to_string()
== "[???, 4321.43, 1234.10]"
);
assert!(HumanNumber::from_f32(123_123.123123123).to_string() == "123,123");
assert!(HumanNumber::from_f64(123_123_123.123123123123123).to_string() == "123,123,123");
assert!(HumanNumber::from_f32(123_123.125).to_string() == "123,123");
assert!(HumanNumber::from_f64(123_123_123.123_123_12).to_string() == "123,123,123");
assert!(HumanNumber::from_u16(1_000).to_string() == "1,000");
assert!(HumanNumber::from_u16(65_535).to_string() == "65,535");
assert!(HumanNumber::from_u32(65_536).to_string() == "65,536");

View file

@ -88,7 +88,7 @@ mod test {
use std::sync::{Arc, Mutex};
let arc_mutex = Arc::new(Mutex::new(false));
*lock!(arc_mutex) = true;
assert!(*lock!(arc_mutex) == true);
assert!(*lock!(arc_mutex));
}
#[test]
@ -101,19 +101,19 @@ mod test {
a: Arc::new(Mutex::new(false)),
}));
*lock2!(arc_mutex, a) = true;
assert!(*lock2!(arc_mutex, a) == true);
assert!(*lock2!(arc_mutex, a));
}
#[test]
fn arc_mut() {
let a = arc_mut!(false);
assert!(*lock!(a) == false);
assert!(!(*lock!(a)));
}
#[test]
fn flip() {
let mut b = true;
flip!(b);
assert!(b == false);
assert!(!b);
}
}

View file

@ -29,9 +29,8 @@ compile_error!("gupax is only built for windows/macos/linux");
// egui/eframe
use eframe::{egui, NativeOptions};
use egui::{
Align, Button, CentralPanel, Color32, FontFamily::Proportional, FontId, Hyperlink, Key, Label,
Layout, Modifiers, RichText, SelectableLabel, Spinner, Stroke, TextEdit, TextStyle,
TextStyle::*, TopBottomPanel, Vec2,
Align, Button, CentralPanel, Color32, FontId, Hyperlink, Key, Label, Layout, Modifiers,
RichText, SelectableLabel, Spinner, TextEdit, TextStyle, TextStyle::*, TopBottomPanel, Vec2,
};
use egui_extras::RetainedImage;
// Logging
@ -57,7 +56,6 @@ use sysinfo::SystemExt;
//mod benchmark;
mod constants;
mod disk;
mod ferris;
mod free;
mod gupax;
mod helper;
@ -71,10 +69,7 @@ mod status;
mod update;
mod xmr;
mod xmrig;
use {
crate::regex::*, constants::*, disk::*, ferris::*, gupax::*, helper::*, macros::*, node::*,
update::*,
};
use {crate::regex::*, constants::*, disk::*, gupax::*, helper::*, macros::*, node::*, update::*};
// Sudo (dummy values for Windows)
mod sudo;
@ -153,7 +148,6 @@ pub struct App {
now: Instant, // Internal timer
exe: String, // Path for [Gupax] binary
dir: String, // Directory [Gupax] binary is in
resolution: Vec2, // Frame resolution
os: &'static str, // OS
admin: bool, // Are we admin? (for Windows)
os_data_path: PathBuf, // OS data path (e.g: ~/.local/share/gupax/)
@ -161,7 +155,6 @@ pub struct App {
state_path: PathBuf, // State file path
node_path: PathBuf, // Node file path
pool_path: PathBuf, // Pool file path
version: &'static str, // Gupax version
name_version: String, // [Gupax vX.X.X]
img: Images, // Custom Struct holding pre-compiled bytes of [Images]
}
@ -176,7 +169,7 @@ impl App {
crate::free::clamp_scale(app.state.gupax.selected_scale),
);
cc.egui_ctx.set_visuals(VISUALS.clone());
Self { resolution, ..app }
Self { ..app }
}
#[cold]
@ -237,7 +230,7 @@ impl App {
let cpu = sysinfo.cpus()[0].brand();
let mut json: Vec<Benchmark> =
serde_json::from_slice(include_bytes!("cpu.json")).unwrap();
json.sort_by(|a, b| cmp_f64(strsim::jaro(&b.cpu, &cpu), strsim::jaro(&a.cpu, &cpu)));
json.sort_by(|a, b| cmp_f64(strsim::jaro(&b.cpu, cpu), strsim::jaro(&a.cpu, cpu)));
json
};
info!("App Init | Assuming user's CPU is: {}", benchmarks[0].cpu);
@ -297,14 +290,12 @@ impl App {
admin: false,
exe: String::new(),
dir: String::new(),
resolution: Vec2::new(APP_DEFAULT_HEIGHT, APP_DEFAULT_WIDTH),
os: OS,
os_data_path: PathBuf::new(),
gupax_p2pool_api_path: PathBuf::new(),
state_path: PathBuf::new(),
node_path: PathBuf::new(),
pool_path: PathBuf::new(),
version: GUPAX_VERSION,
name_version: format!("Gupax {}", GUPAX_VERSION),
img: Images::new(),
};
@ -494,7 +485,7 @@ impl App {
og.p2pool.selected_index,
app.og_node_vec.len()
);
let (name, node) = match app.og_node_vec.get(0) {
let (name, node) = match app.og_node_vec.first() {
Some(zero) => zero.clone(),
None => Node::new_tuple(),
};
@ -517,7 +508,7 @@ impl App {
og.xmrig.selected_index,
app.og_pool_vec.len()
);
let (name, pool) = match app.og_pool_vec.get(0) {
let (name, pool) = match app.og_pool_vec.first() {
Some(zero) => zero.clone(),
None => Pool::new_tuple(),
};
@ -627,7 +618,7 @@ impl App {
continue;
}
let (ip, rpc, zmq) = RemoteNode::get_ip_rpc_zmq(&pinged_node.ip);
let (ip, rpc, zmq) = RemoteNode::get_ip_rpc_zmq(pinged_node.ip);
let node = Node {
ip: ip.into(),
@ -779,12 +770,6 @@ impl ErrorState {
//---------------------------------------------------------------------------------------------------- [Images] struct
struct Images {
banner: RetainedImage,
happy: RetainedImage,
cute: RetainedImage,
oops: RetainedImage,
error: RetainedImage,
panic: RetainedImage,
sudo: RetainedImage,
}
impl Images {
@ -793,12 +778,6 @@ impl Images {
fn new() -> Self {
Self {
banner: RetainedImage::from_image_bytes("banner.png", BYTES_BANNER).unwrap(),
happy: RetainedImage::from_image_bytes("happy.png", FERRIS_HAPPY).unwrap(),
cute: RetainedImage::from_image_bytes("cute.png", FERRIS_CUTE).unwrap(),
oops: RetainedImage::from_image_bytes("oops.png", FERRIS_OOPS).unwrap(),
error: RetainedImage::from_image_bytes("error.png", FERRIS_ERROR).unwrap(),
panic: RetainedImage::from_image_bytes("panic.png", FERRIS_PANIC).unwrap(),
sudo: RetainedImage::from_image_bytes("panic.png", FERRIS_SUDO).unwrap(),
}
}
}
@ -872,10 +851,6 @@ impl KeyPressed {
fn is_v(&self) -> bool {
*self == Self::V
}
#[inline]
fn is_none(&self) -> bool {
*self == Self::None
}
}
//---------------------------------------------------------------------------------------------------- Init functions
@ -1227,10 +1202,6 @@ fn parse_args<S: Into<String>>(mut app: App, panic: S) -> App {
println!("Gupax {} [OS: {}, Commit: {}]\nThis Gupax was originally bundled with:\n - P2Pool {}\n - XMRig {}\n\n{}", GUPAX_VERSION, OS_NAME, &COMMIT[..40], P2POOL_VERSION, XMRIG_VERSION, ARG_COPYRIGHT);
exit(0);
}
"--ferris" => {
println!("{}", FERRIS_ANSI);
exit(0);
}
_ => (),
}
}
@ -1479,7 +1450,8 @@ fn main() {
&app.name_version.clone(),
options,
Box::new(move |cc| Box::new(App::cc(cc, resolution, app))),
);
)
.unwrap();
}
impl eframe::App for App {
@ -1723,18 +1695,9 @@ impl eframe::App for App {
// Display ferris
use ErrorFerris::*;
use ErrorButtons::*;
let ferris = match self.error_state.ferris {
Happy => &self.img.happy,
Cute => &self.img.cute,
Oops => &self.img.oops,
Error => &self.img.error,
Panic => &self.img.panic,
ErrorFerris::Sudo => &self.img.sudo,
};
match self.error_state.buttons {
Debug => ui.add_sized([width, height/4.0], Label::new("--- Debug Info ---\n\nPress [ESC] to quit")),
_ => ferris.show_max_size(ui, Vec2::new(width, height)),
};
if self.error_state.buttons == Debug {
ui.add_sized([width, height/4.0], Label::new("--- Debug Info ---\n\nPress [ESC] to quit"));
}
// Error/Quit screen
match self.error_state.buttons {
@ -1895,17 +1858,12 @@ impl eframe::App for App {
// They don't need to be compared anyway.
debug!("App | Checking diff between [og] & [state]");
let og = lock!(self.og);
if og.status != self.state.status
self.diff = og.status != self.state.status
|| og.gupax != self.state.gupax
|| og.p2pool != self.state.p2pool
|| og.xmrig != self.state.xmrig
|| self.og_node_vec != self.node_vec
|| self.og_pool_vec != self.pool_vec
{
self.diff = true;
} else {
self.diff = false;
}
|| self.og_pool_vec != self.pool_vec;
drop(og);
// Top: Tabs
@ -2253,8 +2211,8 @@ impl eframe::App for App {
.on_hover_text("Restart P2Pool")
.clicked()
{
lock!(self.og).update_absolute_path();
self.state.update_absolute_path();
let _ = lock!(self.og).update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::restart_p2pool(
&self.helper,
&self.state.p2pool,
@ -2308,8 +2266,8 @@ impl eframe::App for App {
.on_disabled_hover_text(text)
.clicked()
{
lock!(self.og).update_absolute_path();
self.state.update_absolute_path();
let _ = lock!(self.og).update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::start_p2pool(
&self.helper,
&self.state.p2pool,
@ -2363,8 +2321,8 @@ impl eframe::App for App {
.on_hover_text("Restart XMRig")
.clicked()
{
lock!(self.og).update_absolute_path();
self.state.update_absolute_path();
let _ = lock!(self.og).update_absolute_path();
let _ = self.state.update_absolute_path();
if cfg!(windows) {
Helper::restart_xmrig(
&self.helper,
@ -2424,8 +2382,8 @@ impl eframe::App for App {
.on_disabled_hover_text(text)
.clicked()
{
lock!(self.og).update_absolute_path();
self.state.update_absolute_path();
let _ = lock!(self.og).update_absolute_path();
let _ = self.state.update_absolute_path();
if cfg!(windows) {
Helper::start_xmrig(
&self.helper,
@ -2601,7 +2559,7 @@ mod test {
let benchmarks: Vec<Benchmark> = {
let mut json: Vec<Benchmark> =
serde_json::from_slice(include_bytes!("cpu.json")).unwrap();
json.sort_by(|a, b| cmp_f64(strsim::jaro(&b.cpu, &cpu), strsim::jaro(&a.cpu, &cpu)));
json.sort_by(|a, b| cmp_f64(strsim::jaro(&b.cpu, cpu), strsim::jaro(&a.cpu, cpu)));
json
};

View file

@ -20,7 +20,6 @@ use egui::Color32;
use hyper::{client::HttpConnector, Body, Client, Request};
use log::*;
use rand::{thread_rng, Rng};
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
@ -28,18 +27,13 @@ use std::time::{Duration, Instant};
// Remote Monero Nodes with ZMQ enabled.
// The format is an array of tuples consisting of: (IP, LOCATION, RPC_PORT, ZMQ_PORT)
pub const REMOTE_NODES: [(&str, &str, &str, &str); 14] = [
pub const REMOTE_NODES: [(&str, &str, &str, &str); 9] = [
("monero.10z.com.ar", "Argentina", "18089", "18084"),
("monero1.heitechsoft.com", "Canada", "18081", "18084"),
("node.monerodevs.org", "Canada", "18089", "18084"),
("node.cryptocano.de", "Germany", "18089", "18083"),
("p2pmd.xmrvsbeast.com", "Germany", "18081", "18083"),
("fbx.tranbert.com", "France", "18089", "18084"),
("node2.monerodevs.org", "France", "18089", "18084"),
("home.allantaylor.kiwi", "New Zealand", "18089", "18083"),
("p2pool.uk", "United Kingdom", "18089", "18084"),
("xmr.support", "United States", "18081", "18083"),
("sf.xmr.support", "United States", "18081", "18083"),
("xmrbandwagon.hopto.org", "United States", "18081", "18084"),
("xmr.spotlightsound.com", "United States", "18081", "18084"),
("node.richfowler.net", "United States", "18089", "18084"),
@ -260,10 +254,10 @@ pub fn format_ip_location(og_ip: &str, extra_space: bool) -> String {
}
pub fn format_ip(ip: &str) -> String {
const _: () = if 23 != REMOTE_NODE_MAX_CHARS {
const _: () = if 22 != REMOTE_NODE_MAX_CHARS {
panic!();
};
format!("{ip: >23}")
format!("{ip: >22}")
}
//---------------------------------------------------------------------------------------------------- Node data
@ -409,7 +403,7 @@ impl Ping {
let mut handles = Vec::with_capacity(REMOTE_NODE_LENGTH);
let node_vec = arc_mut!(Vec::with_capacity(REMOTE_NODE_LENGTH));
for (ip, _, rpc, zmq) in REMOTE_NODES {
for (ip, _country, rpc, _zmq) in REMOTE_NODES {
let client = client.clone();
let ping = Arc::clone(&ping);
let node_vec = Arc::clone(&node_vec);
@ -531,7 +525,7 @@ mod test {
#[ignore]
async fn full_ping() {
use crate::{REMOTE_NODES, REMOTE_NODE_LENGTH};
use hyper::{client::HttpConnector, Body, Client, Request};
use hyper::{client::HttpConnector, Client, Request};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]

View file

@ -22,11 +22,10 @@ use egui::{
Slider, Spinner, TextEdit, TextStyle::*,
};
use log::*;
use regex::Regex;
use std::sync::{Arc, Mutex};
impl crate::disk::P2pool {
#[inline(always)] // called once
#[expect(clippy::too_many_arguments)]
pub fn show(
&mut self,
node_vec: &mut Vec<(String, Node)>,
@ -323,7 +322,7 @@ impl crate::disk::P2pool {
ui.add_sized(
[width, height / 2.0],
Hyperlink::from_label_and_url(
"WARNING: It is recommended to use your own Monero Node (hover for details)",
"Warning: It is recommended to use your own Monero node.",
"https://github.com/hinto-janai/gupax#running-a-local-monero-node",
),
)
@ -431,11 +430,10 @@ impl crate::disk::P2pool {
debug!("P2Pool Tab | Rendering [Node List]");
let text = RichText::new(format!("{}. {}", self.selected_index+1, self.selected_name));
ComboBox::from_id_source("manual_nodes").selected_text(text).width(width).show_ui(ui, |ui| {
let mut n = 0;
for (name, node) in node_vec.iter() {
let text = RichText::new(format!("{}. {}\n IP: {}\n RPC: {}\n ZMQ: {}", n+1, name, node.ip, node.rpc, node.zmq));
for (i, (name, node)) in node_vec.iter().enumerate() {
let text = RichText::new(format!("{}. {}\n IP: {}\n RPC: {}\n ZMQ: {}", i+1, name, node.ip, node.rpc, node.zmq));
if ui.add(SelectableLabel::new(self.selected_name == *name, text)).clicked() {
self.selected_index = n;
self.selected_index = i;
let node = node.clone();
self.selected_name = name.clone();
self.selected_ip = node.ip.clone();
@ -446,7 +444,6 @@ impl crate::disk::P2pool {
self.rpc = node.rpc;
self.zmq = node.zmq;
}
n += 1;
}
});
// [Add/Save]

View file

@ -21,9 +21,9 @@ use once_cell::sync::Lazy;
use regex::Regex;
//---------------------------------------------------------------------------------------------------- Lazy
pub static REGEXES: Lazy<Regexes> = Lazy::new(|| Regexes::new());
pub static P2POOL_REGEX: Lazy<P2poolRegex> = Lazy::new(|| P2poolRegex::new());
pub static XMRIG_REGEX: Lazy<XmrigRegex> = Lazy::new(|| XmrigRegex::new());
pub static REGEXES: Lazy<Regexes> = Lazy::new(Regexes::new);
pub static P2POOL_REGEX: Lazy<P2poolRegex> = Lazy::new(P2poolRegex::new);
pub static XMRIG_REGEX: Lazy<XmrigRegex> = Lazy::new(XmrigRegex::new);
//---------------------------------------------------------------------------------------------------- [Regexes] struct
// General purpose Regexes, mostly used in the GUI.

View file

@ -21,13 +21,13 @@ use crate::{
};
use egui::{
Hyperlink, Label, ProgressBar, RichText, SelectableLabel, Slider, Spinner, TextEdit, TextStyle,
TextStyle::Monospace, TextStyle::Name,
TextStyle::Name,
};
use log::*;
use std::sync::{Arc, Mutex};
impl crate::disk::Status {
#[inline(always)] // called once
#[expect(clippy::too_many_arguments)]
pub fn show(
&mut self,
sys: &Arc<Mutex<Sys>>,

View file

@ -40,6 +40,12 @@ use log::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AtomicUnit(u64);
impl Default for AtomicUnit {
fn default() -> Self {
Self::new()
}
}
impl AtomicUnit {
pub const fn new() -> Self {
Self(0)
@ -136,18 +142,16 @@ impl PayoutOrd {
if a.0.len() != b.0.len() {
return false;
}
let mut n = 0;
for (date, atomic_unit, block) in &a.0 {
if *date != b.0[n].0 {
for (i, (date, atomic_unit, block)) in a.0.iter().enumerate() {
if *date != b.0[i].0 {
return false;
}
if *atomic_unit != b.0[n].1 {
if *atomic_unit != b.0[i].1 {
return false;
}
if *block != b.0[n].2 {
if *block != b.0[i].2 {
return false;
}
n += 1;
}
true
}
@ -340,8 +344,6 @@ mod test {
#[test]
fn push_to_payout_ord() {
use crate::human::HumanNumber;
use crate::xmr::AtomicUnit;
use crate::xmr::PayoutOrd;
let mut payout_ord = PayoutOrd::from_vec(vec![]);
let should_be = "2022-09-08 18:42:55.4636 | 0.000000000001 XMR | Block 2,654,321\n";
@ -357,7 +359,7 @@ mod test {
use crate::human::HumanNumber;
use crate::xmr::AtomicUnit;
use crate::xmr::PayoutOrd;
let mut payout_ord = PayoutOrd::from_vec(vec![
let payout_ord = PayoutOrd::from_vec(vec![
(
"2022-09-08 18:42:55.4636".to_string(),
AtomicUnit::from_u64(1),
@ -453,11 +455,11 @@ mod test {
println!("1: {:#?}", payout_ord);
println!("2: {:#?}", payout_ord);
assert!(PayoutOrd::is_same(&payout_ord, &payout_ord_2) == true);
assert!(PayoutOrd::is_same(&payout_ord, &payout_ord_2));
payout_ord.push_raw("2022-09-08 18:42:55.4636", 1000000000, 2654321);
println!("1: {:#?}", payout_ord);
println!("2: {:#?}", payout_ord);
assert!(PayoutOrd::is_same(&payout_ord, &payout_ord_2) == false);
assert!(!PayoutOrd::is_same(&payout_ord, &payout_ord_2));
}
#[test]
@ -465,7 +467,7 @@ mod test {
use crate::human::HumanNumber;
use crate::xmr::AtomicUnit;
use crate::xmr::PayoutOrd;
let mut payout_ord = PayoutOrd::from_vec(vec![
let payout_ord = PayoutOrd::from_vec(vec![
(
"2022-09-08 18:42:55.4636".to_string(),
AtomicUnit::from_u64(1000000000),

View file

@ -21,11 +21,10 @@ use egui::{
Button, Checkbox, ComboBox, Label, RichText, SelectableLabel, Slider, TextEdit, TextStyle::*,
};
use log::*;
use regex::Regex;
use std::sync::{Arc, Mutex};
impl crate::disk::Xmrig {
#[inline(always)] // called once
#[expect(clippy::too_many_arguments)]
pub fn show(
&mut self,
pool_vec: &mut Vec<(String, Pool)>,
@ -282,8 +281,7 @@ impl crate::disk::Xmrig {
debug!("XMRig Tab | Rendering [Node List] ComboBox");
let text = RichText::new(format!("{}. {}", self.selected_index+1, self.selected_name));
ComboBox::from_id_source("manual_pool").selected_text(text).width(width).show_ui(ui, |ui| {
let mut n = 0;
for (name, pool) in pool_vec.iter() {
for (n, (name, pool)) in pool_vec.iter().enumerate() {
let text = format!("{}. {}\n IP: {}\n Port: {}\n Rig: {}", n+1, name, pool.ip, pool.port, pool.rig);
if ui.add(SelectableLabel::new(self.selected_name == *name, text)).clicked() {
self.selected_index = n;
@ -297,7 +295,6 @@ impl crate::disk::Xmrig {
self.ip = pool.ip;
self.port = pool.port;
}
n += 1;
}
});
// [Add/Save]

View file

@ -2,4 +2,5 @@
extend-exclude = [
"src/cpu.json",
"pgp/",
"external",
]