From 7c214f0c8be86700e11429b4374bc0d9371a64fd Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 05:21:43 +0000 Subject: [PATCH] AX: make mining helpers more descriptive --- .../{file_utils.go => atomic_write_file.go} | 2 +- ...{component.go => embedded_component_fs.go} | 2 +- ...ats_collector.go => http_stats_fetcher.go} | 4 ++-- ...tor_test.go => http_stats_fetcher_test.go} | 0 pkg/mining/manager.go | 10 ++++----- pkg/mining/service.go | 22 +++++++------------ 6 files changed, 17 insertions(+), 23 deletions(-) rename pkg/mining/{file_utils.go => atomic_write_file.go} (92%) rename pkg/mining/{component.go => embedded_component_fs.go} (89%) rename pkg/mining/{stats_collector.go => http_stats_fetcher.go} (91%) rename pkg/mining/{stats_collector_test.go => http_stats_fetcher_test.go} (100%) diff --git a/pkg/mining/file_utils.go b/pkg/mining/atomic_write_file.go similarity index 92% rename from pkg/mining/file_utils.go rename to pkg/mining/atomic_write_file.go index 9fdf9e6..99eed9d 100644 --- a/pkg/mining/file_utils.go +++ b/pkg/mining/atomic_write_file.go @@ -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) diff --git a/pkg/mining/component.go b/pkg/mining/embedded_component_fs.go similarity index 89% rename from pkg/mining/component.go rename to pkg/mining/embedded_component_fs.go index 49117b5..dfa249b 100644 --- a/pkg/mining/component.go +++ b/pkg/mining/embedded_component_fs.go @@ -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) { diff --git a/pkg/mining/stats_collector.go b/pkg/mining/http_stats_fetcher.go similarity index 91% rename from pkg/mining/stats_collector.go rename to pkg/mining/http_stats_fetcher.go index 441ed64..54282b2 100644 --- a/pkg/mining/stats_collector.go +++ b/pkg/mining/http_stats_fetcher.go @@ -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 diff --git a/pkg/mining/stats_collector_test.go b/pkg/mining/http_stats_fetcher_test.go similarity index 100% rename from pkg/mining/stats_collector_test.go rename to pkg/mining/http_stats_fetcher_test.go diff --git a/pkg/mining/manager.go b/pkg/mining/manager.go index b84b8fc..f6612d5 100644 --- a/pkg/mining/manager.go +++ b/pkg/mining/manager.go @@ -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 { diff --git a/pkg/mining/service.go b/pkg/mining/service.go index 719b859..f8c6d7f 100644 --- a/pkg/mining/service.go +++ b/pkg/mining/service.go @@ -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)