Feat/678 monero mining economics - #682
Merged
Merged
Conversation
Add signed daily growth calculations that preserve BigInt inputs, an explicit paid-back-or-never projection over a bounded ten-year horizon, and break-even helpers for token price and network difficulty. Keep the existing current-difficulty payback calculation unchanged so current callers retain their behavior. Cover growing, flat, and falling difficulty, invalid boundaries, non-paying rigs, and break-even round trips with focused unit tests.
Add a hashrate-specific coverage boundary and a pure trend aggregator that prefers thirty days, falls back to seven, preserves difficulty as BigInt-derived strings, validates history freshness, and calculates signed network and price changes plus observed blocks per hour. Enrich the existing mining economics service in parallel and isolate trend failures behind a nullable field so missing or malformed history never removes today's calculator inputs. Extend focused tests for window selection, signed trends, aligned block timing, and incomplete data.
Add focused, accessible sections for observed Monero difficulty, hashrate, price, and block-rate trends plus user-specific current and trend-adjusted payback and break-even thresholds. Keep the projection explicit about holding XMR price constant and render a first-class never-pays-back state. Move personal economics wiring into a pure utility, keep current values canonical on the root economics contract, and avoid duplicating them inside the trend payload. Localize every new label and explanation in English, Portuguese, and Russian, and cover the no-history fallback while preserving the existing calculator results.
The trend block was all-or-nothing: buildMiningNetworkTrend returned null unless every input was present and fresh. A price series that lagged by a couple of days therefore erased the difficulty and hashrate trends, the blocks-per-hour figure and - worst - the trend-adjusted payback, which depends on the difficulty growth rate alone and has nothing to do with price. This was not hypothetical: local price data trailing by five days hid the whole section. Each metric is now derived on its own. Snapshot-derived figures and the price change are computed separately, absent ones become null, and the block is dropped only when nothing at all could be derived. Rows without a value render a dash or disappear rather than taking the section down with them. Difficulty gets the same treatment in the service. A malformed value used to abort the entire economics object, so the calculator showed "data unavailable" over one unparseable number; it now nulls just the break-even-difficulty row. Since that row is also null when electricity is free - a genuinely unbounded threshold - the two cases are told apart by an explicit difficultyAvailable flag, so the UI never reports missing data as "unbounded".
Move the core snapshot plus fee, emission, and pool derivations into a pure utility so service orchestration stays small and each optional source can degrade independently. Treat transaction metrics, supply, and pool statistics as best-effort inputs. Preserve the calculator when pool statistics are absent by making the weighted fee nullable, omitting the unavailable average option, and guarding the network header instead of inventing a fee. Use reward-parseable fee counters, the permanent tail subsidy fallback, BigInt-validated pool hashrates, and focused tests for missing and malformed inputs.
Render independently available 24-hour network fees, tail-emission economics, and the five largest verified pools after the personal economics section. Keep small Monero fees visible with the existing significant-digit formatter, format emission and pool values by locale, and connect the selected pool to an accessible highlighted table row. Add matching English, Portuguese, and Russian copy while keeping the calculator page focused through three presentational components.
The top-pools table listed the five largest known pools and nothing else, so on current data it showed five rows summing to 28% of blocks found and gave no hint that the remaining 72% existed. Attribution is partial by nature - pools publish their blocks voluntarily, and right now about 70% of the hashrate lands in the synthetic "unknown" bucket - so a reader would reasonably conclude the network is far more evenly split than it is. The existing pool table on the network profile already faces this and solves it by keeping the unknown bucket visible, pinned last. The calculator has room for five rows, not the full list, so it now carries the same information as a caption: what the listed pools add up to, and how much is attributed to no known pool. Both figures are nullable and computed from the stats already fetched, so a missing unknown bucket drops half the sentence rather than the table.
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #678
Turns the mining calculator into the one-page "Monero Bloomberg" the issue asks
for, by building on it rather than adding a new page. No new routes, migrations
or indexer jobs — every figure comes from data already indexed.
Network trend — difficulty, hashrate and price change over a 30d window
(falling back to 7d, hidden below that), plus blocks per hour, captioned with
the window actually used.
What it means for you — the point of the slice.
estimateHardwarePaybackDayswas a plain
cost / profitdivision, so it assumed today's yield lasts foreverand was optimistic by a wide margin. Payback at the current difficulty now sits
next to payback at the observed trend (37 vs 62 days on live data). Since
electricity is fixed while revenue decays, the accumulated profit can peak below
the hardware cost — that renders as "does not pay back", not a huge number.
Plus break-even XMR price and break-even difficulty.
Fees, emission, top pools — average tx fee and fee share of block rewards,
current subsidy against the tail floor with annual issuance and inflation, and
the five largest pools. The pool table states what it covers: on current data
those five are 28% of blocks found and 70% is attributed to no known pool —
without that caption it reads as if the network were far more evenly split.
Every metric degrades on its own: a lagging price series no longer blanks the
difficulty trend or the payback that depends only on it, and an unparseable
difficulty drops one row instead of the whole calculator.