Merge pull request #7 from Snider/add-docstrings-to-mining-package
Add comprehensive docstrings to the mining package
This commit is contained in:
commit
d9dfb242d6
4 changed files with 448 additions and 162 deletions
|
|
@ -8,17 +8,30 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Manager handles miner lifecycle and operations
|
||||
// Manager handles the lifecycle and operations of multiple miners.
|
||||
// It provides a centralized way to start, stop, and manage different miner
|
||||
// instances, while also collecting and exposing their performance data.
|
||||
// The Manager is safe for concurrent use.
|
||||
type Manager struct {
|
||||
miners map[string]Miner
|
||||
mu sync.RWMutex // Mutex to protect the miners map
|
||||
mu sync.RWMutex
|
||||
stopChan chan struct{}
|
||||
waitGroup sync.WaitGroup
|
||||
}
|
||||
|
||||
var _ ManagerInterface = (*Manager)(nil)
|
||||
|
||||
// NewManager creates a new miner manager
|
||||
// NewManager creates a new miner manager.
|
||||
// It initializes the manager and starts a background goroutine for periodic
|
||||
// statistics collection from the miners.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a new manager
|
||||
// manager := mining.NewManager()
|
||||
// defer manager.Stop()
|
||||
//
|
||||
// // Now you can use the manager to start and stop miners
|
||||
func NewManager() *Manager {
|
||||
m := &Manager{
|
||||
miners: make(map[string]Miner),
|
||||
|
|
@ -29,7 +42,33 @@ func NewManager() *Manager {
|
|||
return m
|
||||
}
|
||||
|
||||
// StartMiner starts a new miner with the given configuration
|
||||
// StartMiner starts a new miner with the given configuration.
|
||||
// It takes the miner type and a configuration object, and returns the
|
||||
// created miner instance or an error if the miner could not be started.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a new manager
|
||||
// manager := mining.NewManager()
|
||||
// defer manager.Stop()
|
||||
//
|
||||
// // Create a new configuration for the XMRig miner
|
||||
// config := &mining.Config{
|
||||
// Miner: "xmrig",
|
||||
// Pool: "your-pool-address",
|
||||
// Wallet: "your-wallet-address",
|
||||
// Threads: 4,
|
||||
// TLS: true,
|
||||
// }
|
||||
//
|
||||
// // Start the miner
|
||||
// miner, err := manager.StartMiner("xmrig", config)
|
||||
// if err != nil {
|
||||
// log.Fatalf("Failed to start miner: %v", err)
|
||||
// }
|
||||
//
|
||||
// // Stop the miner when you are done
|
||||
// defer manager.StopMiner(miner.GetName())
|
||||
func (m *Manager) StartMiner(minerType string, config *Config) (Miner, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
|
@ -61,7 +100,9 @@ func (m *Manager) StartMiner(minerType string, config *Config) (Miner, error) {
|
|||
return miner, nil
|
||||
}
|
||||
|
||||
// StopMiner stops a running miner
|
||||
// StopMiner stops a running miner.
|
||||
// It takes the name of the miner to be stopped and returns an error if the
|
||||
// miner could not be stopped.
|
||||
func (m *Manager) StopMiner(name string) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
|
@ -80,7 +121,8 @@ func (m *Manager) StopMiner(name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetMiner retrieves a miner by ID
|
||||
// GetMiner retrieves a running miner by its name.
|
||||
// It returns the miner instance or an error if the miner is not found.
|
||||
func (m *Manager) GetMiner(name string) (Miner, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
|
@ -93,7 +135,7 @@ func (m *Manager) GetMiner(name string) (Miner, error) {
|
|||
return miner, nil
|
||||
}
|
||||
|
||||
// ListMiners returns all miners
|
||||
// ListMiners returns a slice of all running miners.
|
||||
func (m *Manager) ListMiners() []Miner {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
|
@ -105,7 +147,8 @@ func (m *Manager) ListMiners() []Miner {
|
|||
return miners
|
||||
}
|
||||
|
||||
// ListAvailableMiners returns a list of available miners
|
||||
// ListAvailableMiners returns a list of available miners that can be started.
|
||||
// This provides a way to discover the types of miners supported by the manager.
|
||||
func (m *Manager) ListAvailableMiners() []AvailableMiner {
|
||||
return []AvailableMiner{
|
||||
{
|
||||
|
|
@ -115,7 +158,7 @@ func (m *Manager) ListAvailableMiners() []AvailableMiner {
|
|||
}
|
||||
}
|
||||
|
||||
// startStatsCollection starts a goroutine to periodically collect stats from active miners
|
||||
// startStatsCollection starts a goroutine to periodically collect stats from active miners.
|
||||
func (m *Manager) startStatsCollection() {
|
||||
m.waitGroup.Add(1)
|
||||
go func() {
|
||||
|
|
@ -134,7 +177,7 @@ func (m *Manager) startStatsCollection() {
|
|||
}()
|
||||
}
|
||||
|
||||
// collectMinerStats iterates through active miners and collects their stats
|
||||
// collectMinerStats iterates through active miners and collects their stats.
|
||||
func (m *Manager) collectMinerStats() {
|
||||
m.mu.RLock()
|
||||
minersToCollect := make([]Miner, 0, len(m.miners))
|
||||
|
|
@ -159,7 +202,9 @@ func (m *Manager) collectMinerStats() {
|
|||
}
|
||||
}
|
||||
|
||||
// GetMinerHashrateHistory returns the hashrate history for a specific miner
|
||||
// GetMinerHashrateHistory returns the hashrate history for a specific miner.
|
||||
// It takes the name of the miner and returns a slice of hashrate points
|
||||
// or an error if the miner is not found.
|
||||
func (m *Manager) GetMinerHashrateHistory(name string) ([]HashratePoint, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
|
@ -172,7 +217,9 @@ func (m *Manager) GetMinerHashrateHistory(name string) ([]HashratePoint, error)
|
|||
return miner.GetHashrateHistory(), nil
|
||||
}
|
||||
|
||||
// Stop stops the manager and its background goroutines
|
||||
// Stop stops the manager and its background goroutines.
|
||||
// It should be called when the manager is no longer needed to ensure a
|
||||
// graceful shutdown of the statistics collection goroutine.
|
||||
func (m *Manager) Stop() {
|
||||
close(m.stopChan)
|
||||
m.waitGroup.Wait() // Wait for the stats collection goroutine to finish
|
||||
|
|
|
|||
|
|
@ -1,12 +1,38 @@
|
|||
package mining
|
||||
|
||||
// ManagerInterface defines the interface for a miner manager.
|
||||
// This interface abstracts the core functionalities of a miner manager,
|
||||
// allowing for different implementations to be used interchangeably. It provides
|
||||
// a standard way to manage the lifecycle of miners and retrieve their data.
|
||||
type ManagerInterface interface {
|
||||
// StartMiner starts a new miner with the given configuration.
|
||||
// It takes the miner type and a configuration object, and returns the
|
||||
// created miner instance or an error if the miner could not be started.
|
||||
StartMiner(minerType string, config *Config) (Miner, error)
|
||||
|
||||
// StopMiner stops a running miner.
|
||||
// It takes the name of the miner to be stopped and returns an error if the
|
||||
// miner could not be stopped.
|
||||
StopMiner(name string) error
|
||||
|
||||
// GetMiner retrieves a running miner by its name.
|
||||
// It returns the miner instance or an error if the miner is not found.
|
||||
GetMiner(name string) (Miner, error)
|
||||
|
||||
// ListMiners returns a slice of all running miners.
|
||||
ListMiners() []Miner
|
||||
|
||||
// ListAvailableMiners returns a list of available miners that can be started.
|
||||
// This provides a way to discover the types of miners supported by the manager.
|
||||
ListAvailableMiners() []AvailableMiner
|
||||
|
||||
// GetMinerHashrateHistory returns the hashrate history for a specific miner.
|
||||
// It takes the name of the miner and returns a slice of hashrate points
|
||||
// or an error if the miner is not found.
|
||||
GetMinerHashrateHistory(name string) ([]HashratePoint, error)
|
||||
|
||||
// Stop stops the manager and its background goroutines.
|
||||
// It should be called when the manager is no longer needed to ensure a
|
||||
// graceful shutdown of any background processes.
|
||||
Stop()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,184 +17,351 @@ const (
|
|||
LowResHistoryRetention = 24 * time.Hour // Example: keep 24 hours of 1-minute averages
|
||||
)
|
||||
|
||||
// Miner is the interface for a miner
|
||||
// Miner defines the standard interface for a cryptocurrency miner.
|
||||
// This interface abstracts the core functionalities of a miner, such as installation,
|
||||
// starting, stopping, and statistics retrieval, allowing for different miner
|
||||
// implementations to be used interchangeably.
|
||||
type Miner interface {
|
||||
// Install handles the setup and installation of the miner software.
|
||||
// This may include downloading binaries, creating configuration files,
|
||||
// and setting up necessary permissions.
|
||||
Install() error
|
||||
|
||||
// Uninstall removes the miner software and any related configuration files.
|
||||
Uninstall() error
|
||||
Start(config *Config) error
|
||||
Stop() error
|
||||
GetStats() (*PerformanceMetrics, error)
|
||||
GetName() string
|
||||
GetPath() string
|
||||
GetBinaryPath() string // New method to get the full path to the miner executable
|
||||
GetBinaryPath() string
|
||||
|
||||
// CheckInstallation verifies if the miner is installed correctly and returns
|
||||
// details about the installation, such as the version and path.
|
||||
CheckInstallation() (*InstallationDetails, error)
|
||||
|
||||
// GetLatestVersion retrieves the latest available version of the miner software.
|
||||
GetLatestVersion() (string, error)
|
||||
GetHashrateHistory() []HashratePoint // New method to get hashrate history
|
||||
AddHashratePoint(point HashratePoint) // New method to add a hashrate point
|
||||
ReduceHashrateHistory(now time.Time) // New method to trigger history reduction
|
||||
|
||||
// GetHashrateHistory returns the recent hashrate history of the miner.
|
||||
GetHashrateHistory() []HashratePoint
|
||||
|
||||
// AddHashratePoint adds a new hashrate data point to the miner's history.
|
||||
AddHashratePoint(point HashratePoint)
|
||||
|
||||
// ReduceHashrateHistory processes the raw hashrate data, potentially
|
||||
// aggregating high-resolution data into a lower-resolution format for
|
||||
// long-term storage.
|
||||
ReduceHashrateHistory(now time.Time)
|
||||
}
|
||||
|
||||
// InstallationDetails contains information about an installed miner
|
||||
// InstallationDetails contains information about an installed miner.
|
||||
// It provides a standard structure for reporting the status of a miner's
|
||||
// installation, including whether it's present, its version, and its location.
|
||||
type InstallationDetails struct {
|
||||
IsInstalled bool `json:"is_installed"`
|
||||
Version string `json:"version"`
|
||||
Path string `json:"path"`
|
||||
// IsInstalled is true if the miner is installed, false otherwise.
|
||||
IsInstalled bool `json:"is_installed"`
|
||||
// Version is the detected version of the installed miner.
|
||||
Version string `json:"version"`
|
||||
// Path is the installation path of the miner.
|
||||
Path string `json:"path"`
|
||||
// MinerBinary is the name of the miner's executable file.
|
||||
MinerBinary string `json:"miner_binary"`
|
||||
}
|
||||
|
||||
// SystemInfo provides general system and miner installation information
|
||||
// SystemInfo provides general system and miner installation information.
|
||||
// This struct aggregates various details about the system's environment,
|
||||
// such as operating system, architecture, and available resources, as well
|
||||
// as information about installed miners.
|
||||
type SystemInfo struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
OS string `json:"os"`
|
||||
Architecture string `json:"architecture"`
|
||||
GoVersion string `json:"go_version"`
|
||||
AvailableCPUCores int `json:"available_cpu_cores"`
|
||||
TotalSystemRAMGB float64 `json:"total_system_ram_gb"`
|
||||
// Timestamp is the time when the system information was collected.
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
// OS is the operating system of the host.
|
||||
OS string `json:"os"`
|
||||
// Architecture is the system's hardware architecture (e.g., amd64, arm64).
|
||||
Architecture string `json:"architecture"`
|
||||
// GoVersion is the version of the Go runtime.
|
||||
GoVersion string `json:"go_version"`
|
||||
// AvailableCPUCores is the number of available CPU cores.
|
||||
AvailableCPUCores int `json:"available_cpu_cores"`
|
||||
// TotalSystemRAMGB is the total system RAM in gigabytes.
|
||||
TotalSystemRAMGB float64 `json:"total_system_ram_gb"`
|
||||
// InstalledMinersInfo is a slice containing details of all installed miners.
|
||||
InstalledMinersInfo []*InstallationDetails `json:"installed_miners_info"`
|
||||
}
|
||||
|
||||
// Config represents the configuration for a miner.
|
||||
// This struct includes general mining parameters as well as specific options
|
||||
// for different miner implementations like XMRig. It is designed to be
|
||||
|
||||
// Config represents the config for a miner, including XMRig specific options
|
||||
// flexible and comprehensive, covering a wide range of settings from network
|
||||
// and CPU configurations to logging and miscellaneous options.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a new configuration for the XMRig miner
|
||||
// config := &mining.Config{
|
||||
// Miner: "xmrig",
|
||||
// Pool: "your-pool-address",
|
||||
// Wallet: "your-wallet-address",
|
||||
// Threads: 4,
|
||||
// TLS: true,
|
||||
// }
|
||||
type Config struct {
|
||||
Miner string `json:"miner"`
|
||||
Pool string `json:"pool"`
|
||||
Wallet string `json:"wallet"`
|
||||
Threads int `json:"threads"`
|
||||
TLS bool `json:"tls"`
|
||||
HugePages bool `json:"hugePages"`
|
||||
// Miner is the name of the miner to be used (e.g., "xmrig").
|
||||
Miner string `json:"miner"`
|
||||
// Pool is the address of the mining pool.
|
||||
Pool string `json:"pool"`
|
||||
// Wallet is the user's wallet address for receiving mining rewards.
|
||||
Wallet string `json:"wallet"`
|
||||
// Threads is the number of CPU threads to be used for mining.
|
||||
Threads int `json:"threads"`
|
||||
// TLS indicates whether to use a secure TLS connection to the pool.
|
||||
TLS bool `json:"tls"`
|
||||
// HugePages enables or disables the use of huge pages for performance optimization.
|
||||
HugePages bool `json:"hugePages"`
|
||||
|
||||
// Network options
|
||||
Algo string `json:"algo,omitempty"`
|
||||
Coin string `json:"coin,omitempty"`
|
||||
Password string `json:"password,omitempty"` // Corresponds to -p, not --userpass
|
||||
UserPass string `json:"userPass,omitempty"` // Corresponds to -O
|
||||
Proxy string `json:"proxy,omitempty"`
|
||||
Keepalive bool `json:"keepalive,omitempty"`
|
||||
Nicehash bool `json:"nicehash,omitempty"`
|
||||
RigID string `json:"rigId,omitempty"`
|
||||
TLSSingerprint string `json:"tlsFingerprint,omitempty"`
|
||||
Retries int `json:"retries,omitempty"`
|
||||
RetryPause int `json:"retryPause,omitempty"`
|
||||
UserAgent string `json:"userAgent,omitempty"`
|
||||
DonateLevel int `json:"donateLevel,omitempty"`
|
||||
DonateOverProxy bool `json:"donateOverProxy,omitempty"`
|
||||
// Algo specifies the mining algorithm to be used.
|
||||
Algo string `json:"algo,omitempty"`
|
||||
// Coin specifies the cryptocurrency to be mined.
|
||||
Coin string `json:"coin,omitempty"`
|
||||
// Password is the pool password.
|
||||
Password string `json:"password,omitempty"`
|
||||
// UserPass is the username and password for the pool.
|
||||
UserPass string `json:"userPass,omitempty"`
|
||||
// Proxy is the address of a proxy to be used for the connection.
|
||||
Proxy string `json:"proxy,omitempty"`
|
||||
// Keepalive enables or disables the TCP keepalive feature.
|
||||
Keepalive bool `json:"keepalive,omitempty"`
|
||||
// Nicehash enables or disables Nicehash support.
|
||||
Nicehash bool `json:"nicehash,omitempty"`
|
||||
// RigID is the identifier of the mining rig.
|
||||
RigID string `json:"rigId,omitempty"`
|
||||
// TLSSingerprint is the TLS fingerprint of the pool.
|
||||
TLSSingerprint string `json:"tlsFingerprint,omitempty"`
|
||||
// Retries is the number of times to retry connecting to the pool.
|
||||
Retries int `json:"retries,omitempty"`
|
||||
// RetryPause is the pause in seconds between connection retries.
|
||||
RetryPause int `json:"retryPause,omitempty"`
|
||||
// UserAgent is the user agent string to be used for the connection.
|
||||
UserAgent string `json:"userAgent,omitempty"`
|
||||
// DonateLevel is the donation level to the miner developers.
|
||||
DonateLevel int `json:"donateLevel,omitempty"`
|
||||
// DonateOverProxy enables or disables donation over a proxy.
|
||||
DonateOverProxy bool `json:"donateOverProxy,omitempty"`
|
||||
|
||||
// CPU backend options
|
||||
NoCPU bool `json:"noCpu,omitempty"`
|
||||
CPUAffinity string `json:"cpuAffinity,omitempty"`
|
||||
AV int `json:"av,omitempty"`
|
||||
CPUPriority int `json:"cpuPriority,omitempty"`
|
||||
CPUMaxThreadsHint int `json:"cpuMaxThreadsHint,omitempty"`
|
||||
CPUMemoryPool int `json:"cpuMemoryPool,omitempty"`
|
||||
CPUNoYield bool `json:"cpuNoYield,omitempty"`
|
||||
HugepageSize int `json:"hugepageSize,omitempty"`
|
||||
HugePagesJIT bool `json:"hugePagesJIT,omitempty"`
|
||||
ASM string `json:"asm,omitempty"`
|
||||
Argon2Impl string `json:"argon2Impl,omitempty"`
|
||||
RandomXInit int `json:"randomXInit,omitempty"`
|
||||
RandomXNoNUMA bool `json:"randomXNoNuma,omitempty"`
|
||||
RandomXMode string `json:"randomXMode,omitempty"`
|
||||
RandomX1GBPages bool `json:"randomX1GBPages,omitempty"`
|
||||
RandomXWrmsr string `json:"randomXWrmsr,omitempty"`
|
||||
RandomXNoRdmsr bool `json:"randomXNoRdmsr,omitempty"`
|
||||
RandomXCacheQoS bool `json:"randomXCacheQoS,omitempty"`
|
||||
// NoCPU disables the CPU backend.
|
||||
NoCPU bool `json:"noCpu,omitempty"`
|
||||
// CPUAffinity sets the CPU affinity for the miner.
|
||||
CPUAffinity string `json:"cpuAffinity,omitempty"`
|
||||
// AV is the algorithm variation.
|
||||
AV int `json:"av,omitempty"`
|
||||
// CPUPriority is the CPU priority for the miner.
|
||||
CPUPriority int `json:"cpuPriority,omitempty"`
|
||||
// CPUMaxThreadsHint is the maximum number of threads hint for the CPU.
|
||||
CPUMaxThreadsHint int `json:"cpuMaxThreadsHint,omitempty"`
|
||||
// CPUMemoryPool is the CPU memory pool size.
|
||||
CPUMemoryPool int `json:"cpuMemoryPool,omitempty"`
|
||||
// CPUNoYield enables or disables CPU yield.
|
||||
CPUNoYield bool `json:"cpuNoYield,omitempty"`
|
||||
// HugepageSize is the size of huge pages in kilobytes.
|
||||
HugepageSize int `json:"hugepageSize,omitempty"`
|
||||
// HugePagesJIT enables or disables huge pages for JIT compiled code.
|
||||
HugePagesJIT bool `json:"hugePagesJIT,omitempty"`
|
||||
// ASM enables or disables the ASM compiler.
|
||||
ASM string `json:"asm,omitempty"`
|
||||
// Argon2Impl is the Argon2 implementation.
|
||||
Argon2Impl string `json:"argon2Impl,omitempty"`
|
||||
// RandomXInit is the RandomX initialization value.
|
||||
RandomXInit int `json:"randomXInit,omitempty"`
|
||||
// RandomXNoNUMA enables or disables NUMA support for RandomX.
|
||||
RandomXNoNUMA bool `json:"randomXNoNuma,omitempty"`
|
||||
// RandomXMode is the RandomX mode.
|
||||
RandomXMode string `json:"randomXMode,omitempty"`
|
||||
// RandomX1GBPages enables or disables 1GB pages for RandomX.
|
||||
RandomX1GBPages bool `json:"randomX1GBPages,omitempty"`
|
||||
// RandomXWrmsr is the RandomX MSR value.
|
||||
RandomXWrmsr string `json:"randomXWrmsr,omitempty"`
|
||||
// RandomXNoRdmsr enables or disables MSR reading for RandomX.
|
||||
RandomXNoRdmsr bool `json:"randomXNoRdmsr,omitempty"`
|
||||
// RandomXCacheQoS enables or disables QoS for the RandomX cache.
|
||||
RandomXCacheQoS bool `json:"randomXCacheQoS,omitempty"`
|
||||
|
||||
// API options (can be overridden or supplemented here)
|
||||
APIWorkerID string `json:"apiWorkerId,omitempty"`
|
||||
APIID string `json:"apiId,omitempty"`
|
||||
HTTPHost string `json:"httpHost,omitempty"`
|
||||
HTTPPort int `json:"httpPort,omitempty"`
|
||||
HTTPAccessToken string `json:"httpAccessToken,omitempty"`
|
||||
HTTPNoRestricted bool `json:"httpNoRestricted,omitempty"`
|
||||
// APIWorkerID is the worker ID for the API.
|
||||
APIWorkerID string `json:"apiWorkerId,omitempty"`
|
||||
// APIID is the ID for the API.
|
||||
APIID string `json:"apiId,omitempty"`
|
||||
// HTTPHost is the host for the HTTP API.
|
||||
HTTPHost string `json:"httpHost,omitempty"`
|
||||
// HTTPPort is the port for the HTTP API.
|
||||
HTTPPort int `json:"httpPort,omitempty"`
|
||||
// HTTPAccessToken is the access token for the HTTP API.
|
||||
HTTPAccessToken string `json:"httpAccessToken,omitempty"`
|
||||
// HTTPNoRestricted enables or disables restricted access to the HTTP API.
|
||||
HTTPNoRestricted bool `json:"httpNoRestricted,omitempty"`
|
||||
|
||||
// Logging options
|
||||
Syslog bool `json:"syslog,omitempty"`
|
||||
LogFile string `json:"logFile,omitempty"`
|
||||
PrintTime int `json:"printTime,omitempty"`
|
||||
HealthPrintTime int `json:"healthPrintTime,omitempty"`
|
||||
NoColor bool `json:"noColor,omitempty"`
|
||||
Verbose bool `json:"verbose,omitempty"`
|
||||
LogOutput bool `json:"logOutput,omitempty"` // New field to control stdout/stderr logging
|
||||
// Syslog enables or disables logging to the system log.
|
||||
Syslog bool `json:"syslog,omitempty"`
|
||||
// LogFile is the path to the log file.
|
||||
LogFile string `json:"logFile,omitempty"`
|
||||
// PrintTime is the interval in seconds for printing performance metrics.
|
||||
PrintTime int `json:"printTime,omitempty"`
|
||||
// HealthPrintTime is the interval in seconds for printing health metrics.
|
||||
HealthPrintTime int `json:"healthPrintTime,omitempty"`
|
||||
// NoColor disables color output in the logs.
|
||||
NoColor bool `json:"noColor,omitempty"`
|
||||
// Verbose enables verbose logging.
|
||||
Verbose bool `json:"verbose,omitempty"`
|
||||
// LogOutput enables or disables logging of stdout/stderr.
|
||||
LogOutput bool `json:"logOutput,omitempty"`
|
||||
|
||||
// Misc options
|
||||
Background bool `json:"background,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
NoTitle bool `json:"noTitle,omitempty"`
|
||||
PauseOnBattery bool `json:"pauseOnBattery,omitempty"`
|
||||
PauseOnActive int `json:"pauseOnActive,omitempty"`
|
||||
Stress bool `json:"stress,omitempty"`
|
||||
Bench string `json:"bench,omitempty"`
|
||||
Submit bool `json:"submit,omitempty"`
|
||||
Verify string `json:"verify,omitempty"`
|
||||
Seed string `json:"seed,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
NoDMI bool `json:"noDMI,omitempty"`
|
||||
// Background runs the miner in the background.
|
||||
Background bool `json:"background,omitempty"`
|
||||
// Title sets the title of the miner window.
|
||||
Title string `json:"title,omitempty"`
|
||||
// NoTitle disables the miner window title.
|
||||
NoTitle bool `json:"noTitle,omitempty"`
|
||||
// PauseOnBattery pauses the miner when the system is on battery power.
|
||||
PauseOnBattery bool `json:"pauseOnBattery,omitempty"`
|
||||
// PauseOnActive pauses the miner when the user is active.
|
||||
PauseOnActive int `json:"pauseOnActive,omitempty"`
|
||||
// Stress enables stress testing mode.
|
||||
Stress bool `json:"stress,omitempty"`
|
||||
// Bench enables benchmark mode.
|
||||
Bench string `json:"bench,omitempty"`
|
||||
// Submit enables or disables submitting shares.
|
||||
Submit bool `json:"submit,omitempty"`
|
||||
// Verify enables or disables share verification.
|
||||
Verify string `json:"verify,omitempty"`
|
||||
// Seed is the seed for the random number generator.
|
||||
Seed string `json:"seed,omitempty"`
|
||||
// Hash is the hash for the random number generator.
|
||||
Hash string `json:"hash,omitempty"`
|
||||
// NoDMI disables DMI/SMBIOS probing.
|
||||
NoDMI bool `json:"noDMI,omitempty"`
|
||||
}
|
||||
|
||||
// PerformanceMetrics represents the performance metrics for a miner
|
||||
// PerformanceMetrics represents the performance metrics for a miner.
|
||||
// This struct provides a standardized way to report key performance indicators
|
||||
// such as hashrate, shares, and uptime, allowing for consistent monitoring
|
||||
// and comparison across different miners.
|
||||
type PerformanceMetrics struct {
|
||||
Hashrate int `json:"hashrate"`
|
||||
Shares int `json:"shares"`
|
||||
Rejected int `json:"rejected"`
|
||||
Uptime int `json:"uptime"`
|
||||
LastShare int64 `json:"lastShare"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
// Hashrate is the current hashrate of the miner in H/s.
|
||||
Hashrate int `json:"hashrate"`
|
||||
// Shares is the number of shares submitted by the miner.
|
||||
Shares int `json:"shares"`
|
||||
// Rejected is the number of rejected shares.
|
||||
Rejected int `json:"rejected"`
|
||||
// Uptime is the duration the miner has been running, in seconds.
|
||||
Uptime int `json:"uptime"`
|
||||
// LastShare is the timestamp of the last submitted share.
|
||||
LastShare int64 `json:"lastShare"`
|
||||
// Algorithm is the mining algorithm currently in use.
|
||||
Algorithm string `json:"algorithm"`
|
||||
// ExtraData provides a flexible way to include additional, miner-specific
|
||||
// performance data that is not covered by the standard fields.
|
||||
ExtraData map[string]interface{} `json:"extraData,omitempty"`
|
||||
}
|
||||
|
||||
// History represents the history of a miner
|
||||
// History represents the historical performance data for a miner.
|
||||
// It contains a collection of performance metrics snapshots, allowing for
|
||||
// the tracking of a miner's performance over time.
|
||||
type History struct {
|
||||
Miner string `json:"miner"`
|
||||
Stats []PerformanceMetrics `json:"stats"`
|
||||
Updated int64 `json:"updated"`
|
||||
// Miner is the name of the miner.
|
||||
Miner string `json:"miner"`
|
||||
// Stats is a slice of performance metrics, representing the historical data.
|
||||
Stats []PerformanceMetrics `json:"stats"`
|
||||
// Updated is the timestamp of the last update to the history.
|
||||
Updated int64 `json:"updated"`
|
||||
}
|
||||
|
||||
// HashratePoint represents a single hashrate measurement at a specific time
|
||||
// HashratePoint represents a single hashrate measurement at a specific time.
|
||||
// This struct is used to build a time-series history of a miner's hashrate,
|
||||
// which is essential for performance analysis and visualization.
|
||||
type HashratePoint struct {
|
||||
// Timestamp is the time at which the hashrate was measured.
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Hashrate int `json:"hashrate"`
|
||||
// Hashrate is the measured hashrate in H/s.
|
||||
Hashrate int `json:"hashrate"`
|
||||
}
|
||||
|
||||
// XMRigMiner represents an XMRig miner
|
||||
// XMRigMiner represents an XMRig miner, encapsulating its configuration,
|
||||
// state, and operational details. This struct provides a comprehensive
|
||||
// representation of an XMRig miner instance, including its identity,
|
||||
// connection details, and performance history.
|
||||
type XMRigMiner struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
URL string `json:"url"`
|
||||
Path string `json:"path"` // This will now be the versioned folder path
|
||||
MinerBinary string `json:"miner_binary"` // New field for the full path to the miner executable
|
||||
Running bool `json:"running"`
|
||||
LastHeartbeat int64 `json:"lastHeartbeat"`
|
||||
ConfigPath string `json:"configPath"`
|
||||
API *API `json:"api"`
|
||||
mu sync.Mutex
|
||||
cmd *exec.Cmd `json:"-"`
|
||||
HashrateHistory []HashratePoint `json:"hashrateHistory"` // High-resolution (10s)
|
||||
LowResHashrateHistory []HashratePoint `json:"lowResHashrateHistory"` // Low-resolution (1m averages)
|
||||
LastLowResAggregation time.Time `json:"-"` // Timestamp of the last low-res aggregation
|
||||
// Name is the name of the miner.
|
||||
Name string `json:"name"`
|
||||
// Version is the version of the XMRig miner.
|
||||
Version string `json:"version"`
|
||||
// URL is the download URL for the XMRig miner.
|
||||
URL string `json:"url"`
|
||||
// Path is the installation path of the miner.
|
||||
Path string `json:"path"`
|
||||
// MinerBinary is the full path to the miner's executable file.
|
||||
MinerBinary string `json:"miner_binary"`
|
||||
// Running indicates whether the miner is currently running.
|
||||
Running bool `json:"running"`
|
||||
// LastHeartbeat is the timestamp of the last heartbeat from the miner.
|
||||
LastHeartbeat int64 `json:"lastHeartbeat"`
|
||||
// ConfigPath is the path to the miner's configuration file.
|
||||
ConfigPath string `json:"configPath"`
|
||||
// API provides access to the miner's API for statistics and control.
|
||||
API *API `json:"api"`
|
||||
// mu is a mutex to protect against concurrent access to the miner's state.
|
||||
mu sync.Mutex
|
||||
// cmd is the command used to execute the miner process.
|
||||
cmd *exec.Cmd `json:"-"`
|
||||
// HashrateHistory is a slice of high-resolution hashrate data points.
|
||||
HashrateHistory []HashratePoint `json:"hashrateHistory"`
|
||||
// LowResHashrateHistory is a slice of low-resolution hashrate data points.
|
||||
LowResHashrateHistory []HashratePoint `json:"lowResHashrateHistory"`
|
||||
// LastLowResAggregation is the timestamp of the last low-resolution aggregation.
|
||||
LastLowResAggregation time.Time `json:"-"`
|
||||
}
|
||||
|
||||
// API represents the XMRig API configuration
|
||||
// API represents the XMRig API configuration.
|
||||
// It specifies the details needed to connect to the miner's API,
|
||||
// enabling programmatic monitoring and control.
|
||||
type API struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
// Enabled indicates whether the API is enabled.
|
||||
Enabled bool `json:"enabled"`
|
||||
// ListenHost is the host on which the API is listening.
|
||||
ListenHost string `json:"listenHost"`
|
||||
ListenPort int `json:"listenPort"`
|
||||
// ListenPort is the port on which the API is listening.
|
||||
ListenPort int `json:"listenPort"`
|
||||
}
|
||||
|
||||
// XMRigSummary represents the summary from the XMRig API
|
||||
// XMRigSummary represents the summary of an XMRig miner's performance,
|
||||
// as retrieved from its API. This struct provides a structured way to
|
||||
// access key performance indicators from the miner's API.
|
||||
type XMRigSummary struct {
|
||||
// Hashrate contains the hashrate data from the API.
|
||||
Hashrate struct {
|
||||
Total []float64 `json:"total"`
|
||||
} `json:"hashrate"`
|
||||
// Results contains the share statistics from the API.
|
||||
Results struct {
|
||||
SharesGood uint64 `json:"shares_good"`
|
||||
SharesTotal uint64 `json:"shares_total"`
|
||||
} `json:"results"`
|
||||
Uptime uint64 `json:"uptime"`
|
||||
// Uptime is the duration the miner has been running, in seconds.
|
||||
Uptime uint64 `json:"uptime"`
|
||||
// Algorithm is the mining algorithm currently in use.
|
||||
Algorithm string `json:"algorithm"`
|
||||
}
|
||||
|
||||
// AvailableMiner represents a miner that is available to be started
|
||||
// AvailableMiner represents a miner that is available for use.
|
||||
// It provides a simple way to list and describe the miners that can be
|
||||
// started and managed by the system.
|
||||
type AvailableMiner struct {
|
||||
Name string `json:"name"`
|
||||
// Name is the name of the available miner.
|
||||
Name string `json:"name"`
|
||||
// Description is a brief description of the miner.
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,20 @@ var httpClient = &http.Client{
|
|||
Timeout: 30 * time.Second,
|
||||
}
|
||||
|
||||
// NewXMRigMiner creates a new XMRig miner
|
||||
// NewXMRigMiner creates a new XMRig miner instance with default settings.
|
||||
// This is the entry point for creating a new XMRig miner that can be managed
|
||||
// by the Manager. The returned miner is ready to be installed and started.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a new XMRig miner
|
||||
// xmrigMiner := mining.NewXMRigMiner()
|
||||
//
|
||||
// // Now you can use the miner to perform actions like
|
||||
// // installing, starting, and stopping.
|
||||
func NewXMRigMiner() *XMRigMiner {
|
||||
return &XMRigMiner{
|
||||
Name: "xmrig", // Changed to lowercase for consistency
|
||||
Name: "xmrig",
|
||||
Version: "latest",
|
||||
URL: "https://github.com/xmrig/xmrig/releases",
|
||||
API: &API{
|
||||
|
|
@ -43,28 +53,30 @@ func NewXMRigMiner() *XMRigMiner {
|
|||
}
|
||||
}
|
||||
|
||||
// GetName returns the name of the miner
|
||||
// GetName returns the name of the miner.
|
||||
func (m *XMRigMiner) GetName() string {
|
||||
return m.Name
|
||||
}
|
||||
|
||||
// GetPath returns the path of the miner
|
||||
// This now returns the base installation directory for xmrig, not the versioned one.
|
||||
// GetPath returns the base installation directory for the XMRig miner.
|
||||
// This is the directory where different versions of the miner are stored.
|
||||
func (m *XMRigMiner) GetPath() string {
|
||||
dataPath, err := xdg.DataFile("lethean-desktop/miners/xmrig")
|
||||
if err != nil {
|
||||
// Fallback for safety, though it should ideally not fail if Install works.
|
||||
return ""
|
||||
}
|
||||
return dataPath
|
||||
}
|
||||
|
||||
// GetBinaryPath returns the full path to the miner executable.
|
||||
// GetBinaryPath returns the full path to the miner's executable file.
|
||||
// This path is set after a successful installation or check of the installation status.
|
||||
func (m *XMRigMiner) GetBinaryPath() string {
|
||||
return m.MinerBinary
|
||||
}
|
||||
|
||||
// GetLatestVersion returns the latest version of XMRig
|
||||
// GetLatestVersion fetches the latest version of XMRig from the GitHub API.
|
||||
// It returns the version string (e.g., "v6.18.0") or an error if the
|
||||
// version could not be retrieved.
|
||||
func (m *XMRigMiner) GetLatestVersion() (string, error) {
|
||||
resp, err := httpClient.Get("https://api.github.com/repos/xmrig/xmrig/releases/latest")
|
||||
if err != nil {
|
||||
|
|
@ -85,7 +97,9 @@ func (m *XMRigMiner) GetLatestVersion() (string, error) {
|
|||
return release.TagName, nil
|
||||
}
|
||||
|
||||
// Download and install the latest version of XMRig
|
||||
// Install downloads and installs the latest version of the XMRig miner.
|
||||
// It determines the correct release for the current operating system,
|
||||
// downloads it, and extracts it to the appropriate installation directory.
|
||||
func (m *XMRigMiner) Install() error {
|
||||
version, err := m.GetLatestVersion()
|
||||
if err != nil {
|
||||
|
|
@ -156,14 +170,17 @@ func (m *XMRigMiner) Install() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Uninstall removes the miner files
|
||||
// Uninstall removes all files related to the XMRig miner.
|
||||
// This is a destructive operation that will remove the entire installation
|
||||
// directory of the miner.
|
||||
func (m *XMRigMiner) Uninstall() error {
|
||||
// Uninstall should remove the base path, which contains the versioned folder
|
||||
return os.RemoveAll(m.GetPath())
|
||||
}
|
||||
|
||||
// findMinerBinary searches for the miner executable, first in the standard installation path,
|
||||
// then falls back to the system's PATH.
|
||||
// findMinerBinary searches for the miner's executable file.
|
||||
// It first checks the standard installation path, and if not found, falls
|
||||
// back to searching the system's PATH. This allows for both managed
|
||||
// installations and pre-existing installations to be used.
|
||||
func (m *XMRigMiner) findMinerBinary() (string, error) {
|
||||
executableName := "xmrig"
|
||||
if runtime.GOOS == "windows" {
|
||||
|
|
@ -198,7 +215,10 @@ func (m *XMRigMiner) findMinerBinary() (string, error) {
|
|||
return "", errors.New("miner executable not found in standard directory or system PATH")
|
||||
}
|
||||
|
||||
// CheckInstallation checks if the miner is installed and returns its details
|
||||
// CheckInstallation verifies if the XMRig miner is installed correctly.
|
||||
// It returns details about the installation, such as whether it is installed,
|
||||
// its version, and the path to the executable. This method also updates the
|
||||
// miner's internal state with the installation details.
|
||||
func (m *XMRigMiner) CheckInstallation() (*InstallationDetails, error) {
|
||||
details := &InstallationDetails{}
|
||||
|
||||
|
|
@ -236,7 +256,28 @@ func (m *XMRigMiner) CheckInstallation() (*InstallationDetails, error) {
|
|||
return details, nil
|
||||
}
|
||||
|
||||
// Start the miner
|
||||
// Start launches the XMRig miner with the specified configuration.
|
||||
// It creates a configuration file, constructs the necessary command-line
|
||||
// arguments, and starts the miner process in the background.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a new XMRig miner and a configuration
|
||||
// xmrigMiner := mining.NewXMRigMiner()
|
||||
// config := &mining.Config{
|
||||
// Pool: "your-pool-address",
|
||||
// Wallet: "your-wallet-address",
|
||||
// Threads: 4,
|
||||
// }
|
||||
//
|
||||
// // Start the miner
|
||||
// err := xmrigMiner.Start(config)
|
||||
// if err != nil {
|
||||
// log.Fatalf("Failed to start miner: %v", err)
|
||||
// }
|
||||
//
|
||||
// // Stop the miner when you are done
|
||||
// defer xmrigMiner.Stop()
|
||||
func (m *XMRigMiner) Start(config *Config) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
|
@ -500,7 +541,8 @@ func (m *XMRigMiner) Start(config *Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Stop the miner
|
||||
// Stop terminates the XMRig miner process.
|
||||
// It sends a kill signal to the running miner process.
|
||||
func (m *XMRigMiner) Stop() error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
|
@ -512,7 +554,9 @@ func (m *XMRigMiner) Stop() error {
|
|||
return m.cmd.Process.Kill()
|
||||
}
|
||||
|
||||
// GetStats returns the stats for the miner
|
||||
// GetStats retrieves the performance statistics from the running XMRig miner.
|
||||
// It queries the miner's API and returns a PerformanceMetrics struct
|
||||
// containing the hashrate, share counts, and uptime.
|
||||
func (m *XMRigMiner) GetStats() (*PerformanceMetrics, error) {
|
||||
m.mu.Lock()
|
||||
running := m.Running
|
||||
|
|
@ -552,6 +596,7 @@ func (m *XMRigMiner) GetStats() (*PerformanceMetrics, error) {
|
|||
}
|
||||
|
||||
// GetHashrateHistory returns the combined high-resolution and low-resolution hashrate history.
|
||||
// This provides a complete view of the miner's performance over time.
|
||||
func (m *XMRigMiner) GetHashrateHistory() []HashratePoint {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
|
@ -565,73 +610,69 @@ func (m *XMRigMiner) GetHashrateHistory() []HashratePoint {
|
|||
}
|
||||
|
||||
// AddHashratePoint adds a new hashrate measurement to the high-resolution history.
|
||||
// This method is called periodically by the Manager to record the miner's performance.
|
||||
func (m *XMRigMiner) AddHashratePoint(point HashratePoint) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.HashrateHistory = append(m.HashrateHistory, point)
|
||||
// No trimming here; trimming is handled by ReduceHashrateHistory
|
||||
}
|
||||
|
||||
// ReduceHashrateHistory aggregates older high-resolution data into 1-minute averages
|
||||
// and adds them to the low-resolution history.
|
||||
// GetHighResHistoryLength returns the number of data points in the high-resolution hashrate history.
|
||||
func (m *XMRigMiner) GetHighResHistoryLength() int {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
return len(m.HashrateHistory)
|
||||
}
|
||||
|
||||
// GetLowResHistoryLength returns the number of data points in the low-resolution hashrate history.
|
||||
func (m *XMRigMiner) GetLowResHistoryLength() int {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
return len(m.LowResHashrateHistory)
|
||||
}
|
||||
|
||||
// ReduceHashrateHistory aggregates older high-resolution hashrate data into
|
||||
// lower-resolution data, and trims the history to a manageable size.
|
||||
// This method is called periodically by the Manager to maintain the hashrate
|
||||
// history.
|
||||
func (m *XMRigMiner) ReduceHashrateHistory(now time.Time) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
// Only aggregate if enough time has passed since the last aggregation
|
||||
// or if it's the first aggregation
|
||||
if !m.LastLowResAggregation.IsZero() && now.Sub(m.LastLowResAggregation) < LowResolutionInterval {
|
||||
return
|
||||
}
|
||||
|
||||
// Find points in HashrateHistory that are older than HighResolutionDuration
|
||||
// These are the candidates for aggregation into low-resolution history.
|
||||
var pointsToAggregate []HashratePoint
|
||||
var newHighResHistory []HashratePoint
|
||||
|
||||
// The cutoff is exclusive: points *at or before* this time are candidates for aggregation.
|
||||
// We want to aggregate points that are *strictly older* than HighResolutionDuration ago.
|
||||
// So, if HighResolutionDuration is 5 minutes, points older than (now - 5 minutes) are aggregated.
|
||||
cutoff := now.Add(-HighResolutionDuration)
|
||||
|
||||
for _, p := range m.HashrateHistory {
|
||||
if p.Timestamp.Before(cutoff) { // Use Before to ensure strict older-than
|
||||
if p.Timestamp.Before(cutoff) {
|
||||
pointsToAggregate = append(pointsToAggregate, p)
|
||||
} else {
|
||||
newHighResHistory = append(newHighResHistory, p)
|
||||
}
|
||||
}
|
||||
m.HashrateHistory = newHighResHistory // Update high-res history to only contain recent points
|
||||
m.HashrateHistory = newHighResHistory
|
||||
|
||||
if len(pointsToAggregate) == 0 {
|
||||
// If no points to aggregate, just update LastLowResAggregation and return
|
||||
m.LastLowResAggregation = now
|
||||
return
|
||||
}
|
||||
|
||||
// Aggregate into 1-minute slices
|
||||
// Group points by minute (truncated timestamp)
|
||||
// Group points by minute and calculate average hashrate
|
||||
minuteGroups := make(map[time.Time][]int)
|
||||
for _, p := range pointsToAggregate {
|
||||
// Round timestamp down to the nearest minute for grouping
|
||||
minute := p.Timestamp.Truncate(LowResolutionInterval)
|
||||
minuteGroups[minute] = append(minuteGroups[minute], p.Hashrate)
|
||||
}
|
||||
|
||||
// Calculate average for each minute and add to low-res history
|
||||
var newLowResPoints []HashratePoint
|
||||
for minute, hashrates := range minuteGroups {
|
||||
if len(hashrates) > 0 {
|
||||
|
|
@ -647,7 +688,6 @@ func (m *XMRigMiner) ReduceHashrateHistory(now time.Time) {
|
|||
}
|
||||
}
|
||||
|
||||
// Sort new low-res points by timestamp to maintain chronological order
|
||||
sort.Slice(newLowResPoints, func(i, j int) bool {
|
||||
return newLowResPoints[i].Timestamp.Before(newLowResPoints[j].Timestamp)
|
||||
})
|
||||
|
|
@ -656,15 +696,14 @@ func (m *XMRigMiner) ReduceHashrateHistory(now time.Time) {
|
|||
|
||||
// Trim low-resolution history to LowResHistoryRetention
|
||||
lowResCutoff := now.Add(-LowResHistoryRetention)
|
||||
// Find the first point that is *after* or equal to the lowResCutoff
|
||||
firstValidLowResIndex := 0
|
||||
for i, p := range m.LowResHashrateHistory {
|
||||
if p.Timestamp.After(lowResCutoff) || p.Timestamp.Equal(lowResCutoff) {
|
||||
firstValidLowResIndex = i
|
||||
break
|
||||
}
|
||||
if i == len(m.LowResHashrateHistory)-1 { // All points are older than cutoff
|
||||
firstValidLowResIndex = len(m.LowResHashrateHistory) // Clear all
|
||||
if i == len(m.LowResHashrateHistory)-1 {
|
||||
firstValidLowResIndex = len(m.LowResHashrateHistory)
|
||||
}
|
||||
}
|
||||
m.LowResHashrateHistory = m.LowResHashrateHistory[firstValidLowResIndex:]
|
||||
|
|
@ -672,6 +711,9 @@ func (m *XMRigMiner) ReduceHashrateHistory(now time.Time) {
|
|||
m.LastLowResAggregation = now
|
||||
}
|
||||
|
||||
// createConfig creates a JSON configuration file for the XMRig miner.
|
||||
// This allows for a consistent and reproducible way to configure the miner,
|
||||
// based on the provided Config struct.
|
||||
func (m *XMRigMiner) createConfig(config *Config) error {
|
||||
configPath, err := xdg.ConfigFile("lethean-desktop/xmrig.json")
|
||||
if err != nil {
|
||||
|
|
@ -717,6 +759,8 @@ func (m *XMRigMiner) createConfig(config *Config) error {
|
|||
return os.WriteFile(m.ConfigPath, data, 0644)
|
||||
}
|
||||
|
||||
// unzip extracts a zip archive to a destination directory.
|
||||
// This is a helper function used during the installation of the miner.
|
||||
func (m *XMRigMiner) unzip(src, dest string) error {
|
||||
r, err := zip.OpenReader(src)
|
||||
if err != nil {
|
||||
|
|
@ -762,6 +806,8 @@ func (m *XMRigMiner) unzip(src, dest string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// untar extracts a tar.gz archive to a destination directory.
|
||||
// This is a helper function used during the installation of the miner.
|
||||
func (m *XMRigMiner) untar(src, dest string) error {
|
||||
file, err := os.Open(src)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue