Releases: 465media/bitaxe-baller
Releases · 465media/bitaxe-baller
Bitaxe Baller v1.16.3
Maintenance release — version bump only, no functional changes from v1.16.2.
Realigns internal build metadata (the macOS bundle version string had drifted to 1.12.0 across several releases) and refreshes the in-app update feed so existing installs surface the update banner.
v1.16.2
v1.16.2 — email input width + alert storm suppression
Two issues caught by Nathan within minutes of v1.16.1's auto-update
rollout:
1. Email input field rendered narrower than the discord webhook field
next to it. Root cause: CSS at static/style.css:2210 targeted
input[type=\"text\"] only, not input[type=\"email\"]. Added the
email selector to both the visual-styling rule and the flex-grow
sizing rule.
2. Saving an email address fired alerts for EVERY currently-tripping
miner immediately — Nathan got 5 emails the moment he hit save.
Two paths produced this:
a. App had JUST restarted into v1.16.1 (auto-update install), so
the in-memory _alerts_last_fired dict was empty. First poll
after that found 5 miners with tripping conditions, fired all 5.
Fix: 60-second post-startup quiet window in
_alerts_should_fire — first ALERTS_STARTUP_QUIET_S seconds
record the trigger time but suppress the actual firing so the
cooldown clock starts ticking from boot. After that the normal
30-min cooldown applies.
b. Adding a brand-new channel (going from empty → set) should
pre-arm cooldowns so the new destination only sees alerts that
trip from the moment of save forward. Otherwise every miner
whose Discord webhook was already aware of an alert state
double-pings the freshly-saved email. Fix: detect the empty→set
transition in api_alerts_config_set + write \"now\" to every
device's cooldown table.
Both fixes are conservative — they suppress the rare nuisance case
without dropping any legitimate alert. Worst case: 60 seconds of
silence after restart, then everything fires normally.
v1.16.1
v1.16.1 HOTFIX — block-finds Lock → RLock (deadlock fix)
v1.16.0 shipped with a Python `threading.Lock()` for _block_finds_lock.
Lock is NOT reentrant — same thread cannot acquire it twice. But every
public block-finds helper (_pending, _recent, _record, _ack) follows
the pattern:
with _block_finds_lock:
finds = _block_finds_load() # ALSO tries to acquire lock → deadlock
...
The first request to /api/block-finds deadlocks forever, leaving the
lock permanently held. Subsequent requests pile up unanswered.
Symptom: in the browser, the dashboard polls /api/block-finds every
5s. Hung requests exhaust the browser's per-host connection pool
(typically 6), so unrelated calls (/api/license/status, /api/alerts/
config) appear stuck on "Loading" even though they individually
respond in milliseconds. Nathan caught it within 60 minutes of the
v1.16.0 release going live to all desktop users.
Fix: one character — Lock → RLock. RLock is reentrant; the same
thread can acquire it multiple times (incremented internal counter,
released on matched __exit__). Other architecture stays the same.
Smoke test added: call _block_finds_pending() and _record() on a
fresh cache with a tmp path; with v1.16.0 these would have hung
forever, with v1.16.1 they return immediately.
v1.16.0
v1.16.0 — chain detector, email alerts, block-found celebration
v1.15.1
v1.15.1 — bundle queued desktop changes (pool profiles, QR pair, 900 …
v1.15.0
v1.15.0 — Fleet ROI overlay + minor-bump rollup of today's hotfixes New feature: fleet-level block ETA on the home dashboard. Aggregates each online device's blockProbability by chain, sums the per-second rates, inverts to days/years. Renders one tile per active chain below the existing summary HUD — mixed BTC + BCH fleets get one rollup each, single-chain fleets get one tile, empty fleets render nothing. All computation is client-side using the per-device data already in /api/devices — no extra request, no backend changes. Math: per_sec(fleet) = Σ per_sec(device) = (Σ GH/s × 1e9) / (2^32 × diff) holds because share difficulty is linear in hashrate at constant network difficulty. Why minor-version-bump-with-feature instead of v1.14.4: today's suppression rule fix (v1.14.3) only takes effect *after* a user upgrades to it. Users still on v1.14.0/.1/.2 are silenced for any v1.14.x successor. A minor bump (v1.14.x → v1.15.0) bypasses that suppression because (1,14) ≠ (1,15) — so the banner fires correctly for everyone, regardless of which v1.14.x they're stuck on. APP_VERSION bump 1.14.3 → 1.15.0. PRO_FEATURES.md: Fleet ROI overlay moved from "Ideas under consideration" to shipped.
v1.14.3
v1.14.3 — banner on any newer version, drop the patch-only suppression _banner_recommended() only fired on minor/major bumps, on the theory that patches are cosmetic. Today's two patches were real hotfixes — v1.14.1 (localStorage wiping the theme/unit settings) and v1.14.2 (duplicate-card bug from MAC-blind dedup). Neither one woke the banner on users running v1.14.0; from their dashboard's POV nothing new ever shipped. New rule: banner whenever the appcast's latest is greater than the installed version, full stop. The dismiss button already stores dismissals per-version in localStorage, so the original "users will dismiss reflexively" concern is handled there — a user can mute v1.14.3 specifically without losing v1.15.0 etc. APP_VERSION bump 1.14.2 → 1.14.3, matching footer bumps.
v1.14.2
v1.14.2 — MAC-based device dedup + remove button on offline cards Two related fixes for the "scanned a device at DHCP IP, set a static IP, ended up with duplicate cards" workflow: 1. /api/devices/add now compares the new device's macAddr against the last-known macAddr of every existing tracked device. Same MAC at a different IP transparently re-binds: the old entry is removed, the existing label is carried over to the new IP, the rebound_from field in the response tells the caller what happened. Without this you'd end up with two cards for one Bitaxe, one perpetually offline. 2. Offline compact cards now show a × button (top-right) that calls /api/devices/remove after a confirm() prompt. Click handler stops propagation before the wrapping <a> can fire. Online cards still route through the device-detail Remove button. APP_VERSION bump 1.14.1 → 1.14.2, matching footer bumps.
v1.14.1
v1.14.1 — fix pywebview private_mode wiping localStorage on app close The packaged Mac DMG and Windows installer wrap the dashboard in pywebview. pywebview defaults private_mode=True, which runs the embedded WKWebView (macOS) / WebView2 (Windows) in incognito mode — localStorage was getting wiped on every app close, so the theme toggle, hashrate unit (GH/s ↔ TH/s), temperature unit (°C/°F), and every other localStorage-backed UI preference reset on each launch. Fix: pass private_mode=False + an explicit storage_path under _DATA_DIR/webview so the webview persists localStorage, cookies, IndexedDB, etc. across restarts. Storage lives under the same data dir we use for config.json / history.db so it survives Mac DMG reinstalls and Umbrel app updates (bind-mounted to /data on Umbrel). Source-mode (python app.py + system browser) and Umbrel were never affected — those used the system browser / its localStorage. APP_VERSION bump 1.14.0 → 1.14.1, matching footer bumps.
v1.14.0
v1.14.0 — multi-coin awareness + fleet outliers + autotune VR fix - APP_VERSION 1.13.0 → 1.14.0; matching dashboard/device footer bumps - Solo Block Probability widget is coin-aware (BCH/BSV/XEC/DGB/NMC); pool grouping on the home dashboard kicks in when the fleet spans multiple chains; new fleet-outlier rec compares within-chain medians; autotune VR temp abort raised to 85°C (was sharing 65°C with ASIC, which insta-aborted on Gamma 602 boards). - RELEASE_NOTES_v1.14.0.md added.