Migrate all log.Printf/Println calls across the codebase to use the
new pkg/logging structured logging package. This provides consistent
log formatting with levels, timestamps, and structured key-value fields.
Files updated:
- pkg/mining/manager.go, service.go, events.go, miner.go
- pkg/mining/xmrig_start.go, ttminer_start.go
- pkg/mining/syslog_unix.go, syslog_windows.go
- pkg/database/hashrate.go
- pkg/node/worker.go, transport.go, peer.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create pkg/logging with:
- Log levels: Debug, Info, Warn, Error
- Structured fields support (key-value pairs)
- Component-based logging (WithComponent)
- Global logger convenience functions
- ParseLevel for configuration
- Full test coverage
The package provides a migration path from log.Printf to
structured logging without external dependencies.
Example usage:
logging.Info("miner started", logging.Fields{"name": minerName})
logger := logging.New(cfg).WithComponent("Manager")
logger.Warn("connection lost", logging.Fields{"pool": pool})
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Collect stats from multiple miners concurrently using goroutines
- Minimize lock duration by taking a snapshot of miners early
- Remove redundant existence check (snapshot is sufficient)
- Extract collectSingleMinerStats for cleaner code
- Add early return when no miners are present
This reduces overall stats collection time when multiple miners
are running, as API calls now happen in parallel instead of
sequentially.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create pkg/mining/miner_factory.go with factory pattern
- Support for miner type aliases (e.g., "ttminer" -> "tt-miner")
- Add global convenience functions: CreateMiner, IsMinerSupported, etc.
- Replace 5 duplicate switch statements in manager.go and service.go
- Makes adding new miner types simpler (single registration point)
- Full test coverage in miner_factory_test.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add pkg/mining/manager_race_test.go with concurrent miner tests
- Add pkg/database/database_race_test.go with concurrent DB tests
- Add TestCleanupRetention, TestGetHashrateHistoryTimeRange tests
- Add TestMultipleMinerStats, TestIsInitialized tests
- Fix AVG() float64 to int scan error in GetHashrateStats
- Fix AVG() float64 to int scan error in GetAllMinerStats
- Fix throttle tests to use NewManagerForSimulation to avoid
autostart conflicts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- TestStartMiner_Ugly: Add algorithm to config for consistent instance naming,
ensuring duplicate detection works correctly
- TestListMiners_Good: Account for autostarted miners by checking delta instead
of absolute count
- TestListMiners: Renamed from TestListMinersEmpty since autostart may add miners
- Add defer manager.Stop() to all tests in mining_test.go for proper cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add requestIDMiddleware that generates/propagates request IDs
- Accepts X-Request-ID from incoming requests or generates new one
- Sets request ID in response header and gin context
- Update CORS to allow/expose X-Request-ID header
Enables request tracing across logs for debugging.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add APIError struct with code, message, details, suggestion, retryable
- Add error code constants (MINER_NOT_FOUND, PROFILE_NOT_FOUND, etc.)
- Add respondWithError helper with automatic suggestions per error type
- Update miner not found and profile not found errors to use new format
- Fix .gitignore to not match pkg/mining directory
Improves DX by providing machine-readable error codes and actionable suggestions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WebSocket Real-Time Events:
- Add EventHub for broadcasting miner events to connected clients
- New event types: miner.starting/started/stopping/stopped/stats/error
- WebSocket endpoint at /ws/events with auto-reconnect support
- Angular WebSocketService with RxJS event streams and fallback to polling
Simulation Mode (miner-ctrl simulate):
- SimulatedMiner generates realistic hashrate data for UI development
- Supports presets: cpu-low, cpu-medium, cpu-high, gpu-ethash, gpu-kawpow
- Features: variance, sine-wave fluctuation, 30s ramp-up, 98% share rate
- XMRig-compatible stats format for full UI compatibility
- NewManagerForSimulation() skips autostart of real miners
Miners Page Redesign:
- Featured cards for installed/recommended miners with gradient styling
- "Installed" (green) and "Recommended" (gold) ribbon badges
- Placeholder cards for 8 planned miners with "Coming Soon" badges
- Algorithm badges, GitHub links, and license info for each miner
- Planned miners: T-Rex, lolMiner, Rigel, BzMiner, SRBMiner, TeamRedMiner, GMiner, NBMiner
Chart Improvements:
- Hybrid data approach: live in-memory data while active, database historical when inactive
- Smoother transitions between data sources
Documentation:
- Updated DEVELOPMENT.md with simulation mode usage
- Updated ARCHITECTURE.md with WebSocket, simulation, and supported miners table
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, StopMiner would fail if the miner was already stopped
(crashed or killed externally), leaving it stuck in the workers list.
Now the miner is always removed from the manager, even if Stop()
returns "miner is not running". This allows cleaning up dead workers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wails:// scheme is not supported by gin-contrib/cors v1.7.6
which requires origins to be http://, https://, or *.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove deprecated GetDB() function that exposed raw DB pointer
- Fix GetLatestHashrate to distinguish sql.ErrNoRows from real errors
- Document async saves in PeerRegistry mutation methods
- Fix deadlock in XMRig/TTMiner Start() by moving CheckInstallation
call before acquiring the main lock (Go RWMutex doesn't allow
recursive locking)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The xdg library caches paths, so setting XDG environment variables
in tests doesn't work when there's already an identity file at the
default path. Added NewNodeManagerWithPaths constructor similar to
NewPeerRegistryWithPath to allow tests to use isolated temp directories.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 30s context timeout for database transactions in hashrate.go
- Add helper function for parsing SQLite timestamps with error logging
- Implement atomic file writes (temp + rename) for profile_manager.go,
config_manager.go, and peer.go to prevent corruption on crash
- Add 5s timeout for stats collection per miner in manager.go
- Add 5s timeout for stdin writes in miner.go
- Clean up config file on failed miner start in xmrig_start.go
- Implement debounced saves (5s) for peer registry to reduce disk I/O
- Fix CheckInstallation data race in xmrig.go and ttminer.go by adding
proper mutex protection around shared field updates
- Add 10s handshake timeout for WebSocket connections in transport.go
- Update peer_test.go to call Close() before reload to flush changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Networking/Protocol fixes:
- Add HTTP server timeouts (Read/Write/Idle/ReadHeader) in service.go
- Fix CORS address parsing to use net.SplitHostPort safely
- Add request body size limit middleware (1MB max)
- Enforce MaxConns limit in WebSocket upgrade handler
- Fix WebSocket origin validation to only allow localhost
- Add read/write deadlines to WebSocket connections
Memory leak fixes:
- Add sync.Once to Manager.Stop() to prevent double-close panic
- Fix controller pending map leak by closing response channel
- Add memory reallocation for hashrate history slices when oversized
- Fix LogBuffer to truncate long lines and force reallocation on trim
- Add process wait timeout to prevent goroutine leaks on zombie processes
- Drain HTTP response body on copy error to allow connection reuse
Segfault/panic prevention:
- Add nil check in GetTotalHashrate for stats pointer
- Fix hashrate history slice reallocation to prevent capacity bloat
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add sync.RWMutex to config_manager.go for file operation synchronization
- Add deprecation warning to unsafe GetDB() function in database.go
- Fix UninstallMiner map modification during iteration in manager.go
- Add server readiness verification via TCP dial in service.go
- Add mutex-protected httpClient getter/setter in xmrig.go
- Update GetLatestVersion to use synchronized HTTP client in ttminer.go
- Update MockMiner in service_test.go to match context-aware GetStats interface
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Critical fixes:
- Release mutex before HTTP calls in GetStats() to prevent blocking
- Fix m.cmd race between Stop() and Wait() goroutine by capturing locally
- Add context support to GetStats() for proper request cancellation
High priority fixes:
- Add existence check in collectMinerStats() before operating on miners
- Add mutex-protected httpClient getter/setter for thread-safe test mocking
Changes:
- Miner interface now requires context.Context for GetStats()
- Stats HTTP requests timeout after 5 seconds (was 30s client default)
- All callers updated to pass context (service uses request context)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create api/swagger.md page to properly document Swagger UI access
instead of linking raw swagger.json in mkdocs nav
- Fix Stop() state management: properly set Running=false and cmd=nil
on all exit paths, wait for process termination to avoid zombies
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix deprecated strings.Title usage with golang.org/x/text/cases
- Replace log.Fatalf in service startup with channel-based error handling
- Add graceful SIGTERM before SIGKILL in Stop() for proper cleanup
- Add mutex protection for LogBuffer access in GetLogs()
- Add instance name sanitization with regex to prevent injection
- Add error logging in updateInstallationCache for failed operations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Security:
- Configure CORS to only allow local origins (localhost, 127.0.0.1, wails://)
- Add CLI args validation for TTMiner to block shell metacharacters
- Add HTTPPort validation (must be 1024-65535)
Reliability:
- Manager.Stop() now stops all running miners before shutdown
- Close stdin pipe on Start() error to prevent resource leak (xmrig, ttminer)
- Fix node_service query parameter parsing (was dead code)
Feature:
- Add TTMiner support in service layer (install, update check, info cache)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Security fixes:
- Remove hardcoded wallet address from CLI defaults (start.go, serve.go)
Pool and wallet are now required flags or must be provided explicitly
- Change file permissions from 0644 to 0600 for sensitive config files
Affects: xmrig config, profiles, settings, config cache
- Fix path traversal in untar() - now returns error instead of silently skipping
Concurrency fix:
- Fix race condition in GetStats() - was using RLock while writing m.FullStats
Changed to Lock/Unlock in both xmrig_stats.go and ttminer_stats.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement GPU mining backends for three new algorithms:
- ProgPowZ (Zano): DAG-based ProgPow variant with 512 parents, dynamic
program generation per period
- ETChash (Ethereum Classic): Standard Ethash with 256 parents and
ECIP-1099 epoch calculation for post-block 11.7M
- Blake3DCR (Decred): Simple Blake3 hash kernel with no DAG requirement,
processing 180-byte block headers
Each implementation includes OpenCL kernels, GPU runners, thread
generators, and build system integration. Also adds fast modulo
optimization to ETCCache for GPU kernel performance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Stratum protocol integration for ETChash, ProgPowZ, Blake3DCR
- EthStratumClient selection for DAG-based algorithms
- Nonce offset handling for all new algorithm families
- AutoClient support for new algorithm detection
- Coin definitions for ETC, ETH, ZANO, DCR
Worker integration:
- CPU worker support for Blake3DCR mining
- GPU worker stubs for ETChash, ProgPowZ, Blake3
- Proper algorithm family handling in CpuWorker/OclWorker
Go CLI integration:
- Updated xmrig_start.go with coin field support
- Improved pool configuration for new algorithms
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GPU config fields: GPUEnabled, GPUPool, GPUWallet, GPUAlgo, CUDA, OpenCL
- XMRig config now supports separate pool/algo for GPU vs CPU mining
- CPU can mine RandomX while GPU mines KawPow on different pools
- Add xmrig_gpu_test.go with tests for dual, GPU-only, and CPU-only configs
- Make getXMRigConfigPath a variable for test overriding
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CPUMaxThreadsHint, priority, pause-on-active/battery to XMRig config
- Create SettingsManager for app preferences (window state, miner defaults)
- Add settings API to desktop app service (GetSettings, SaveWindowState, etc)
- Create throttle_test.go with multi-miner CPU usage verification tests
- Create settings_manager_test.go with concurrent access tests
- Desktop app now remembers window size between launches
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add AvgDifficulty and DiffCurrent fields to PerformanceMetrics
- Calculate avg difficulty as HashesTotal/SharesGood in XMRig stats
- Add difficulty data to TT-Miner stats using pool difficulty
- Display "Avg Diff" stat in stats panel with k/M/G/T formatting
- Add WriteStdin to MockMiner for test interface compliance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add stdin pipe support for sending console commands to running miners (XMRig/TT-Miner)
- Add base64 encoding for log transport to preserve ANSI escape codes
- Add SQLite database for persistent hashrate history storage
- Enhance P2P worker to handle remote miner commands (start/stop/stats/logs)
- Add console UI page with ANSI-to-HTML rendering and command input
- Add E2E tests for navigation, UI elements, and miner start flow
- Update Dockerfile to use Go 1.24 with GOTOOLCHAIN=auto
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement secure peer-to-peer communication between Mining CLI instances
for remote control of mining rigs. Uses Borg library for encryption
(SMSG, STMF, TIM) and Poindexter for KD-tree based peer selection.
Features:
- Node identity management with X25519 keypairs
- Peer registry with multi-factor optimization (ping/hops/geo/score)
- WebSocket transport with SMSG encryption
- Controller/Worker architecture for remote operations
- TIM/STIM encrypted bundles for profile/miner deployment
- CLI commands: node, peer, remote
- REST API endpoints for node/peer/remote operations
- Docker support for P2P testing with multiple nodes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Dashboard:
- Add aggregate stats across all running miners (total hashrate, shares)
- Add workers table with per-miner stats, efficiency, and controls
- Show hashrate bars and efficiency badges for each worker
- Support stopping individual workers or all at once
TT-Miner:
- Implement Install, Start, GetStats, CheckInstallation, Uninstall
- Add TT-Miner to Manager's StartMiner and ListAvailableMiners
- Support GPU-specific config options (devices, intensity, cliArgs)
Chart:
- Improve styling with WA-Pro theme variables
- Add hashrate unit formatting (H/s, kH/s, MH/s)
- Better tooltip and axis styling
Also:
- Fix XMRig download URLs (linux-static-x64, windows-x64)
- Add Playwright E2E testing infrastructure
- Add XMR pool research documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit adds comprehensive Go docstrings to the `pkg/mining` package,
including `mining.go`, `manager.go`, `manager_interface.go`, and `xmrig.go`.
The docstrings cover all public types, interfaces, functions, and methods,
and include examples where appropriate to illustrate usage.
This change improves the developer experience by making the code easier to
understand and use.
Refactors the existing test suite to use a `_Good`, `_Bad`, and `_Ugly` testing structure. This new format improves the clarity and organization of the tests by distinguishing between happy path scenarios (_Good), expected failures (_Bad), and edge cases (_Ugly).
In addition to reorganizing the existing tests, this change also introduces new `_Bad` test cases to `xmrig_test.go` to cover previously untested failure modes, such as a missing miner binary and an unreachable API. This improves the overall quality and robustness of the test suite.
Corrected the build script in `ui/package.json` to correctly bundle the Angular application. Also updated `pkg/mining/service.go` to serve the correct bundled JavaScript file.
Verified the backend server is running and accessible by testing the Swagger UI endpoint.
Added tests for GetMiner and ListMiners in the manager, and for the GetInfo and Doctor endpoints in the service. This increases the overall test coverage of the pkg/mining package.
Added tests for StartMiner and StopMiner in the manager, increasing test coverage for the pkg/mining package.
Refactored the findMinerBinary function to fall back to the system PATH, making the application more robust and easier to test.
This commit introduces a number of new tests for the `pkg/mining` package,
increasing the overall test coverage from 8.2% to 41.4%.
The following changes were made:
- Added tests for the `XMRigMiner` struct, including its methods for
installation, starting, stopping, and getting stats.
- Added tests for the `Service` layer, including the API endpoints for
listing, starting, stopping, and getting stats for miners.
- Added tests for the `Manager`, including starting and stopping multiple
miners, collecting stats, and getting hashrate history.
- Introduced a `ManagerInterface` to decouple the `Service` layer from the
concrete `Manager` implementation, facilitating testing with mocks.
- Fixed a failing test on Windows by creating a Windows-compatible
dummy executable.
- Improved encapsulation in tests by adding and using getter methods for
private fields.
This commit introduces a number of new tests for the `pkg/mining` package,
increasing the overall test coverage from 8.2% to 40.7%.
The following changes were made:
- Added tests for the `XMRigMiner` struct, including its methods for
installation, starting, stopping, and getting stats.
- Added tests for the `Service` layer, including the API endpoints for
listing, starting, stopping, and getting stats for miners.
- Added tests for the `Manager`, including starting and stopping multiple
miners, collecting stats, and getting hashrate history.
- Introduced a `ManagerInterface` to decouple the `Service` layer from the
concrete `Manager` implementation, facilitating testing with mocks.
- Fixed a failing test on Windows by creating a Windows-compatible
dummy executable.
This commit introduces a number of new tests for the `pkg/mining` package,
increasing the overall test coverage from 8.2% to 40.7%.
The following changes were made:
- Added tests for the `XMRigMiner` struct, including its methods for
installation, starting, stopping, and getting stats.
- Added tests for the `Service` layer, including the API endpoints for
listing, starting, stopping, and getting stats for miners.
- Added tests for the `Manager`, including starting and stopping multiple
miners, collecting stats, and getting hashrate history.
- Introduced a `ManagerInterface` to decouple the `Service` layer from the
concrete `Manager` implementation, facilitating testing with mocks.