diff --git a/CHANGELOG.md b/CHANGELOG.md index bae8bf7..b155358 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,38 @@ +## v0.2.0 +## Prototype Release +* Added `Simple` P2Pool tab: + - Monero address input with valid address check (base58 regex) + - [Community Monero node selector](https://github.com/hinto-janaiyo/gupax/tree/main/README.md#community-monero-nodes) + - Community node ping button (asynchronous `JSON-RPC` calls to all nodes) + - `<300ms = GREEN` + - `<1000ms = YELLOW` + - `<5000ms = RED` + - `>5000ms = BLACK` + - `Auto-select` - Pick the fastest node after ping automatically + - `Auto-ping` - Automatically ping nodes on Gupax startup +* Added `Advanced` P2Pool tab: + - Overriding command arguments to P2Pool + - Manual node database, select/add/delete a custom `Name/IP/RPC/ZMQ` (max 1000 nodes) + - P2Pool main/mini toggle + - Out/In Peers slider + - Log level slider +* Added command arguments: + - `-h | --help Print this help message` + - `-v | --version Print version and build info` + - `-l | --node-list Print the manual node list` + - `-s | --state Print Gupax state` + - `-n | --no-startup Disable all auto-startup settings for this instance` + - `-r | --reset Reset all Gupax state and the manual node list` + - `-f | --ferris Print an extremely cute crab` +* Added a native `File Explorer/Finder/GTK` file selector for picking P2Pool/XMRig binary path in `Gupax` tab +* Added detailed console log levels `RUST_LOG=(trace|debug|info|warn|error) ./gupax` +* [Added new PGP key](https://github.com/hinto-janaiyo/gupax/blob/main/pgp/hinto-janaiyo.asc) +* Created website (HTML/CSS only, no JavaScript): https://gupax.io + + +--- + + ## v0.1.0 ## Prototype Release * Added package updater (by default, via Tor using [`Arti`](https://blog.torproject.org/arti_100_released/)) diff --git a/README.md b/README.md index 7d96f05..477fe06 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ ## Contents * [What is Monero, P2Pool, XMRig, and Gupax?](##what-is-monero-p2pool-xmrig-and-gupax) +* [Community Monero Nodes](#community-monero-nodes) * [Demo](#Demo) * [Implementation](#Implementation) * [Planned](#Planned) @@ -51,6 +52,27 @@ Both Monero and P2Pool have built in miners but XMRig is quite faster than both With Monero GUI managing the Monero node on one side and Gupax managing P2Pool/XMRig on the other, it is (hopefully) very easy for anyone to start mining Monero at **max hashrate in a decentralized, permissionless, and trustless manner**. +## Community Monero Nodes +| Name | IP/Domain | RPC Port | +|----------------|----------------------------------|----------| +| C3pool | node.c3pool.com | 18081 | +| Cake | xmr-node.cakewallet.com | 18081 | +| CakeEu | xmr-node-eu.cakewallet.com | 18081 | +| CakeUk | xmr-node-uk.cakewallet.com | 18081 | +| CakeUs | xmr-node-usa-east.cakewallet.com | 18081 | +| Feather1 | selsta1.featherwallet.net | 18081 | +| Feather2 | selsta2.featherwallet.net | 18081 | +| MajesticBankIs | node.majesticbank.is | 18089 | +| MajesticBankSu | node.majesticbank.su | 18089 | +| Monerujo | nodex.monerujo.io | 18081 | +| Rino | node.community.rino.io | 18081 | +| Seth | node.sethforprivacy.com | 18089 | +| Singapore | node.supportxmr.com | 18081 | +| SupportXmr | node.supportxmr.ir | 18081 | +| SupportXmrIr | singapore.node.xmr.pm | 18089 | +| XmrVsBeast | p2pmd.xmrvsbeast.com | 18081 | +**Note: All have ZMQ port on 18083** + ## Demo https://user-images.githubusercontent.com/101352116/194763334-d8e936c9-a71e-474e-ac65-3a339b96a9d2.mp4 diff --git a/src/README.md b/src/README.md index 52f8f2b..9cb9e5b 100644 --- a/src/README.md +++ b/src/README.md @@ -8,11 +8,11 @@ | File/Folder | Purpose | |----------------|---------| | `constants.rs` | General constants needed in Gupax -| `disk.rs` | Code for writing to disk: `state.toml`, `nodes.toml`; This holds the structs for mutable [State] -| `ferris.rs` | Cute crab `--ferris` +| `disk.rs` | Code for writing to disk: `state.toml`, `node.toml`; This holds the structs for mutable [State] +| `ferris.rs` | Cute crab bytes | `gupax.rs` | `Gupax` tab -| `main.rs` | `App/Tab/State` + misc functions -| `node.rs` | Community node feature +| `main.rs` | `App/Tab/State` + misc data/functions +| `node.rs` | Community node ping code for the `P2Pool` simple tab | `p2pool.rs` | `P2Pool` tab | `status.rs` | `Status` tab | `update.rs` | Update code for the `Gupax` tab @@ -22,29 +22,27 @@ This is how Gupax works internally when starting up, divided into 3 sections. 1. **INIT** - - Initialize custom console logging with `log`, `env_logger` || *warn!* - - Initialize misc data (structs, text styles, thread count, images, etc) || *panic!* - - Check for admin privilege (for XMRig) || *warn!* - - Attempt to read `gupax.toml` || *warn!*, *initialize config with default options* + - Initialize custom console logging with `log`, `env_logger` + - Initialize misc data (structs, text styles, thread count, images, etc) + - Check for admin privilege (for XMRig) + - Start initializing main `App` struct + - Parse command arguments + - Attempt to read disk files `state.toml`, `node.toml` - If errors were found, pop-up window 2. **AUTO** - - If `auto_update` == `true`, pop-up auto-updating window || *info!*, *skip auto-update* - - Multi-threaded GitHub API check on Gupax -> P2Pool -> XMRig || *warn!*, *skip auto-update* - - Multi-threaded download if current version != new version || *warn!*, *skip auto-update* - - After download, atomically replace current binaries with new || *warn!*, *skip auto-update* - - Update version metadata || *warn!*, *skip auto-update* - - If `auto_select` == `true`, ping community nodes and select fastest one || *warn!* + - If `auto_update` == `true`, spawn auto-updating thread + - If `auto_select` == `true`, spawn community node ping thread 3. **MAIN** - - All data must be initialized at this point, either via `gupax.toml` or default options || *panic!* - - Start `App` frame || *panic!* - - Write state to `gupax.toml` on user clicking `Save` (after checking input for correctness) || *warn!* - - If `ask_before_quit` == `true`, check for running processes, unsaved state, and update connections before quitting + - All data should be initialized at this point, either via `state.toml` or default options + - Start `App` frame + - Do `App` stuff + - If `ask_before_quit` == `true`, ask before quitting - Kill processes, kill connections, exit ## State -Internal state is saved in the "OS data folder" as `gupax.toml`, using the [TOML](https://github.com/toml-lang/toml) format. If the version can't be parsed (not in the `vX.X.X` or `vX.X` format), the auto-updater will be skipped. [If not found, a default `gupax.toml` file will be created with `State::default`.](https://github.com/hinto-janaiyo/gupax/blob/main/src/state.rs) Gupax will `panic!` if `gupax.toml` has IO or parsing issues. +Internal state is saved in the "OS data folder" as `state.toml`, using the [TOML](https://github.com/toml-lang/toml) format. If not found, a default `state.toml` file will be created. Given a slightly corrupted state file, Gupax will attempt to merge it with a new default one. This will most likely happen if the internal data structure of `state.toml` is changed in the future (e.g removing an outdated setting). Merging silently in the background is a good non-interactive way to handle this. If Gupax can't read/write to disk at all, or if there are any other big issues, it will show an un-recoverable error window. | OS | Data Folder | Example | |----------|----------------------------------------- |-----------------------------------------------------------| @@ -57,8 +55,7 @@ Every frame, the max available `[width, height]` are calculated, and those are u ``` Main [App] outer frame (default: [1280.0, 720.0]) -├─ Inner frame (1264.0, 704.0) - ├─ TopPanel = [width: (max-90.0)/5.0, height: max/10.0] - ├─ BottomPanel = [width: max, height: max/18.0] - ├─ CentralPanel = [width: (max/8.0), height: the rest + ├─ TopPanel = height: 1/12th + ├─ BottomPanel = height: 1/20th + ├─ CentralPanel = height: the rest ``` diff --git a/src/node.rs b/src/node.rs index ffdf942..861d4ae 100644 --- a/src/node.rs +++ b/src/node.rs @@ -213,6 +213,9 @@ pub fn format_enum(id: NodeEnum) -> String { // default = GRAY #[tokio::main] pub async fn ping(ping: Arc>, og: Arc>) -> Result<(), anyhow::Error> { + // Timer + let now = Instant::now(); + // Start ping ping.lock().unwrap().pinging = true; ping.lock().unwrap().prog = 0.0; @@ -251,6 +254,7 @@ pub async fn ping(ping: Arc>, og: Arc>) -> Result<(), a let info = format!("Fastest node: {}ms ... {} @ {}", node_vec[0].ms, node_vec[0].id, node_vec[0].ip); info!("Ping | {}", info); + info!("Ping | Took [{}] seconds...", now.elapsed().as_secs_f32()); let mut ping = ping.lock().unwrap(); ping.fastest = node_vec[0].id; ping.nodes = node_vec; @@ -267,9 +271,18 @@ async fn response(client: hyper::client::Client, r let id = ip_to_enum(ip); let now = Instant::now(); let ms; + let info; match tokio::time::timeout(Duration::from_secs(5), client.request(request)).await { - Ok(_) => ms = now.elapsed().as_millis(), - Err(e) => { warn!("Ping | {}: {} ... FAIL ... {}", id, ip, e); ms = 5000; }, + Ok(_) => { + ms = now.elapsed().as_millis(); + info = format!("{}ms ... {}: {}", ms, id, ip); + info!("Ping | {}", info) + }, + Err(e) => { + ms = 5000; + info = format!("{}ms ... {}: {}", ms, id, ip); + warn!("Ping | {}", info) + }, }; let color; if ms < 300 { @@ -281,8 +294,6 @@ async fn response(client: hyper::client::Client, r } else { color = Color32::BLACK; } - let info = format!("{}ms ... {}: {}", ms, id, ip); - info!("Ping | {}", info); let mut ping = ping.lock().unwrap(); ping.msg = info; ping.prog += percent;