AX: make mining helpers more descriptive
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

This commit is contained in:
Virgil 2026-04-04 05:21:43 +00:00
parent 6838f26d99
commit 7c214f0c8b
6 changed files with 17 additions and 23 deletions

View file

@ -5,7 +5,7 @@ import (
"path/filepath"
)
// AtomicWriteFile("profiles.json", data, 0644)
// AtomicWriteFile("/home/alice/.config/lethean-desktop/miners.json", data, 0600)
func AtomicWriteFile(path string, data []byte, perm os.FileMode) error {
dir := filepath.Dir(path)

View file

@ -9,7 +9,7 @@ import (
//go:embed component/*
var componentFS embed.FS
// fs, err := mining.GetComponentFS()
// fs, err := GetComponentFS()
// if err != nil { return err }
// router.StaticFS("/component", fs)
func GetComponentFS() (http.FileSystem, error) {

View file

@ -13,11 +13,11 @@ type StatsCollector interface {
CollectStats(ctx context.Context) (*PerformanceMetrics, error)
}
// HTTPStatsConfig{Host: "127.0.0.1", Port: 8080, Endpoint: "/2/summary"}
// config := HTTPStatsConfig{Host: "127.0.0.1", Port: 8080, Endpoint: "/2/summary"}
type HTTPStatsConfig struct {
Host string
Port int
Endpoint string // e.g., "/2/summary" for XMRig, "/summary" for TT-Miner
Endpoint string
}
// var summary XMRigSummary

View file

@ -122,7 +122,7 @@ func NewManagerForSimulation() *Manager {
return manager
}
// manager.initDatabase() // NewManager() calls this after loading miners.json, for example with Database.Enabled = true
// manager.initDatabase() // miners.json with Database.Enabled=true enables database.Initialize(database.Config{Enabled: true, RetentionDays: 30})
func (manager *Manager) initDatabase() {
minersConfiguration, err := LoadMinersConfig()
if err != nil {
@ -154,11 +154,11 @@ func (manager *Manager) initDatabase() {
logging.Info("database persistence enabled", logging.Fields{"retention_days": manager.databaseRetention})
// manager.startDBCleanup() // keeps database.Cleanup(30) running after persistence is enabled
// manager.startDBCleanup() // database.Cleanup(30) runs once per hour after NewManager() enables persistence
manager.startDBCleanup()
}
// manager.startDBCleanup() // runs database.Cleanup(30) once an hour after persistence is enabled
// manager.startDBCleanup() // with manager.databaseRetention=30, database.Cleanup(30) runs every hour
func (manager *Manager) startDBCleanup() {
manager.waitGroup.Add(1)
go func() {
@ -190,7 +190,7 @@ func (manager *Manager) startDBCleanup() {
}()
}
// manager.syncMinersConfig() // when miners.json only contains tt-miner, this adds xmrig with Autostart=false
// manager.syncMinersConfig() // miners.json with only "tt-miner" adds MinerAutostartConfig{MinerType: "xmrig", Autostart: false}
func (manager *Manager) syncMinersConfig() {
minersConfiguration, err := LoadMinersConfig()
if err != nil {
@ -227,7 +227,7 @@ func (manager *Manager) syncMinersConfig() {
}
}
// manager.autostartMiners() // NewManager() uses this to start xmrig when miners.json contains Autostart=true
// manager.autostartMiners() // miners.json with Autostart=true starts xmrig from context.Background()
func (manager *Manager) autostartMiners() {
minersConfiguration, err := LoadMinersConfig()
if err != nil {

View file

@ -133,24 +133,19 @@ func isRetryableError(status int) bool {
status == http.StatusGatewayTimeout
}
// router.Use(securityHeadersMiddleware()) // sets X-Content-Type-Options=nosniff and CSP=default-src 'none' on every response
// router.Use(securityHeadersMiddleware()) // GET /api/v1/mining/status returns X-Content-Type-Options: nosniff and Content-Security-Policy: default-src 'none'
func securityHeadersMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Prevent MIME type sniffing
c.Header("X-Content-Type-Options", "nosniff")
// Prevent clickjacking
c.Header("X-Frame-Options", "DENY")
// Enable XSS filter in older browsers
c.Header("X-XSS-Protection", "1; mode=block")
// Restrict referrer information
c.Header("Referrer-Policy", "strict-origin-when-cross-origin")
// Content Security Policy for API responses
c.Header("Content-Security-Policy", "default-src 'none'; frame-ancestors 'none'")
c.Next()
}
}
// router.Use(contentTypeValidationMiddleware()) // rejects POST/PUT/PATCH without application/json Content-Type
// router.Use(contentTypeValidationMiddleware()) // POST /api/v1/mining/profiles with Content-Type: text/plain returns 415 Unsupported Media Type
func contentTypeValidationMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
@ -165,7 +160,6 @@ func contentTypeValidationMiddleware() gin.HandlerFunc {
}
contentType := c.GetHeader("Content-Type")
// Allow JSON and form data
if strings.HasPrefix(contentType, "application/json") ||
strings.HasPrefix(contentType, "application/x-www-form-urlencoded") ||
strings.HasPrefix(contentType, "multipart/form-data") {
@ -180,7 +174,7 @@ func contentTypeValidationMiddleware() gin.HandlerFunc {
}
}
// router.Use(requestIDMiddleware()) // sets X-Request-ID on every request; uses incoming header if present, otherwise generates one
// router.Use(requestIDMiddleware()) // GET /api/v1/mining/status with X-Request-ID: trace-123 keeps the same ID in the response
func requestIDMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
requestID := c.GetHeader("X-Request-ID")
@ -195,7 +189,7 @@ func requestIDMiddleware() gin.HandlerFunc {
}
}
// requestID := generateRequestID() // e.g. "1712070000123-a1b2c3d4e5f6a7b8"
// requestID := generateRequestID() // "1712070000123-a1b2c3d4e5f6a7b8"
func generateRequestID() string {
randomBytes := make([]byte, 8)
if _, err := rand.Read(randomBytes); err != nil {
@ -204,7 +198,7 @@ func generateRequestID() string {
return strconv.FormatInt(time.Now().UnixMilli(), 10) + "-" + hex.EncodeToString(randomBytes)
}
// reqID := getRequestID(c) // "" if not set, otherwise the X-Request-ID value stored by requestIDMiddleware
// requestID := getRequestID(c) // "trace-123" after requestIDMiddleware stores the incoming X-Request-ID header
func getRequestID(c *gin.Context) string {
if id, exists := c.Get("requestID"); exists {
if stringValue, ok := id.(string); ok {
@ -214,8 +208,8 @@ func getRequestID(c *gin.Context) string {
return ""
}
// logWithRequestID(c, "error", "miner failed to start", logging.Fields{"type": "xmrig"})
// logWithRequestID(c, "info", "miner started", logging.Fields{"name": "xmrig-1"})
// logWithRequestID(c, "error", "miner failed to start", logging.Fields{"type": "xmrig", "name": "xmrig-main"})
// logWithRequestID(c, "info", "miner started", logging.Fields{"name": "xmrig-1", "request_id": "trace-123"})
func logWithRequestID(c *gin.Context, level string, message string, fields logging.Fields) {
if fields == nil {
fields = logging.Fields{}
@ -673,7 +667,7 @@ func (service *Service) SetupRoutes() {
}
}
// Serve the embedded web component
// service.Router.StaticFS("/component", componentFS) // serves the embedded dashboard component bundle returned by GetComponentFS()
componentFS, err := GetComponentFS()
if err == nil {
service.Router.StaticFS("/component", componentFS)