Mining/pkg/mining/mining.go
snider 876253f194 feat: Add dual CPU+GPU mining support with separate pools/algos
- 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>
2025-12-30 17:23:59 +00:00

241 lines
10 KiB
Go

package mining
import (
"time"
)
const (
HighResolutionDuration = 5 * time.Minute
HighResolutionInterval = 10 * time.Second
LowResolutionInterval = 1 * time.Minute
LowResHistoryRetention = 24 * time.Hour
)
// Miner defines the standard interface for a cryptocurrency miner.
type Miner interface {
Install() error
Uninstall() error
Start(config *Config) error
Stop() error
GetStats() (*PerformanceMetrics, error)
GetName() string
GetPath() string
GetBinaryPath() string
CheckInstallation() (*InstallationDetails, error)
GetLatestVersion() (string, error)
GetHashrateHistory() []HashratePoint
AddHashratePoint(point HashratePoint)
ReduceHashrateHistory(now time.Time)
GetLogs() []string
WriteStdin(input string) error
}
// InstallationDetails contains information about an installed miner.
type InstallationDetails struct {
IsInstalled bool `json:"is_installed"`
Version string `json:"version"`
Path string `json:"path"`
MinerBinary string `json:"miner_binary"`
ConfigPath string `json:"config_path,omitempty"` // Add path to the miner-specific config
}
// SystemInfo provides general system and miner installation information.
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"`
InstalledMinersInfo []*InstallationDetails `json:"installed_miners_info"`
}
// Config represents the configuration for a miner.
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"`
Algo string `json:"algo,omitempty"`
Coin string `json:"coin,omitempty"`
Password string `json:"password,omitempty"`
UserPass string `json:"userPass,omitempty"`
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"`
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"`
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"`
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"`
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"`
// GPU-specific options (for XMRig dual CPU+GPU mining)
GPUEnabled bool `json:"gpuEnabled,omitempty"` // Enable GPU mining
GPUPool string `json:"gpuPool,omitempty"` // Separate pool for GPU (can differ from CPU)
GPUWallet string `json:"gpuWallet,omitempty"` // Wallet for GPU pool (defaults to main Wallet)
GPUAlgo string `json:"gpuAlgo,omitempty"` // Algorithm for GPU (e.g., "kawpow", "ethash")
GPUPassword string `json:"gpuPassword,omitempty"` // Password for GPU pool
GPUIntensity int `json:"gpuIntensity,omitempty"` // GPU mining intensity (0-100)
GPUThreads int `json:"gpuThreads,omitempty"` // GPU threads per card
Devices string `json:"devices,omitempty"` // GPU device selection (e.g., "0,1,2")
OpenCL bool `json:"opencl,omitempty"` // Enable OpenCL (AMD/Intel GPUs)
CUDA bool `json:"cuda,omitempty"` // Enable CUDA (NVIDIA GPUs)
Intensity int `json:"intensity,omitempty"` // Mining intensity for GPU miners
CLIArgs string `json:"cliArgs,omitempty"` // Additional CLI arguments
}
// PerformanceMetrics represents the performance metrics for a miner.
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"`
AvgDifficulty int `json:"avgDifficulty"` // Average difficulty per accepted share (HashesTotal/SharesGood)
DiffCurrent int `json:"diffCurrent"` // Current job difficulty from pool
ExtraData map[string]interface{} `json:"extraData,omitempty"`
}
// HashratePoint represents a single hashrate measurement at a specific time.
type HashratePoint struct {
Timestamp time.Time `json:"timestamp"`
Hashrate int `json:"hashrate"`
}
// API represents the miner's API configuration.
type API struct {
Enabled bool `json:"enabled"`
ListenHost string `json:"listenHost"`
ListenPort int `json:"listenPort"`
}
// XMRigSummary represents the full JSON response from the XMRig API.
type XMRigSummary struct {
ID string `json:"id"`
WorkerID string `json:"worker_id"`
Uptime int `json:"uptime"`
Restricted bool `json:"restricted"`
Resources struct {
Memory struct {
Free int64 `json:"free"`
Total int64 `json:"total"`
ResidentSetMemory int64 `json:"resident_set_memory"`
} `json:"memory"`
LoadAverage []float64 `json:"load_average"`
HardwareConcurrency int `json:"hardware_concurrency"`
} `json:"resources"`
Features []string `json:"features"`
Results struct {
DiffCurrent int `json:"diff_current"`
SharesGood int `json:"shares_good"`
SharesTotal int `json:"shares_total"`
AvgTime int `json:"avg_time"`
AvgTimeMS int `json:"avg_time_ms"`
HashesTotal int `json:"hashes_total"`
Best []int `json:"best"`
} `json:"results"`
Algo string `json:"algo"`
Connection struct {
Pool string `json:"pool"`
IP string `json:"ip"`
Uptime int `json:"uptime"`
UptimeMS int `json:"uptime_ms"`
Ping int `json:"ping"`
Failures int `json:"failures"`
TLS string `json:"tls"`
TLSFingerprint string `json:"tls-fingerprint"`
Algo string `json:"algo"`
Diff int `json:"diff"`
Accepted int `json:"accepted"`
Rejected int `json:"rejected"`
AvgTime int `json:"avg_time"`
AvgTimeMS int `json:"avg_time_ms"`
HashesTotal int `json:"hashes_total"`
} `json:"connection"`
Version string `json:"version"`
Kind string `json:"kind"`
UA string `json:"ua"`
CPU struct {
Brand string `json:"brand"`
Family int `json:"family"`
Model int `json:"model"`
Stepping int `json:"stepping"`
ProcInfo int `json:"proc_info"`
AES bool `json:"aes"`
AVX2 bool `json:"avx2"`
X64 bool `json:"x64"`
Is64Bit bool `json:"64_bit"`
L2 int `json:"l2"`
L3 int `json:"l3"`
Cores int `json:"cores"`
Threads int `json:"threads"`
Packages int `json:"packages"`
Nodes int `json:"nodes"`
Backend string `json:"backend"`
MSR string `json:"msr"`
Assembly string `json:"assembly"`
Arch string `json:"arch"`
Flags []string `json:"flags"`
} `json:"cpu"`
DonateLevel int `json:"donate_level"`
Paused bool `json:"paused"`
Algorithms []string `json:"algorithms"`
Hashrate struct {
Total []float64 `json:"total"`
Highest float64 `json:"highest"`
} `json:"hashrate"`
Hugepages []int `json:"hugepages"`
}
// AvailableMiner represents a miner that is available for use.
type AvailableMiner struct {
Name string `json:"name"`
Description string `json:"description"`
}