From 68c826a3d89f1b633571d3a907d99409c3cc44fa Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 05:33:08 +0000 Subject: [PATCH] Align mining AX naming and comments --- cmd/mining/cmd/doctor.go | 16 ++++---- cmd/mining/cmd/peer.go | 15 ++++---- cmd/mining/cmd/remote.go | 69 +++++++++++++++++------------------ cmd/mining/cmd/serve.go | 36 +++++++++--------- cmd/mining/cmd/status.go | 4 +- pkg/mining/bufpool.go | 45 ++++++++++++----------- pkg/mining/manager.go | 34 ++++++++--------- pkg/mining/miner.go | 12 +++--- pkg/mining/mining.go | 4 +- pkg/mining/mining_profile.go | 15 ++++---- pkg/mining/ratelimiter.go | 2 +- pkg/mining/service.go | 6 +-- pkg/mining/simulated_miner.go | 4 +- pkg/mining/ttminer_start.go | 2 +- pkg/mining/xmrig.go | 2 +- pkg/mining/xmrig_start.go | 4 +- 16 files changed, 134 insertions(+), 136 deletions(-) diff --git a/cmd/mining/cmd/doctor.go b/cmd/mining/cmd/doctor.go index 350d8b7..61bd9b0 100644 --- a/cmd/mining/cmd/doctor.go +++ b/cmd/mining/cmd/doctor.go @@ -15,8 +15,8 @@ import ( const installationCachePointerFileName = ".installed-miners" -// validateConfigPath("/home/alice/.config/lethean-desktop/miners/config.json") // nil -// validateConfigPath("/tmp/config.json") // rejects paths outside XDG_CONFIG_HOME. +// validateConfigPath("/home/alice/.config/lethean-desktop/miners/config.json") returns nil. +// validateConfigPath("/tmp/config.json") rejects paths outside XDG_CONFIG_HOME. func validateConfigPath(configPath string) error { expectedBase := filepath.Join(xdg.ConfigHome, "lethean-desktop") @@ -29,7 +29,7 @@ func validateConfigPath(configPath string) error { return nil } -// doctor refreshes the miner installation cache and refreshes the cached summary on disk. +// doctor refreshes the miner installation cache and writes the refreshed summary on disk. var doctorCmd = &cobra.Command{ Use: "doctor", Short: "Check and refresh the status of installed miners", @@ -42,7 +42,7 @@ var doctorCmd = &cobra.Command{ if err := updateDoctorCache(); err != nil { return fmt.Errorf("failed to run doctor check: %w", err) } - // loadAndDisplayCache() // prints the refreshed miner summary after updateDoctorCache(). + // loadAndDisplayCache() prints the refreshed miner summary after updateDoctorCache(). _, err := loadAndDisplayCache() return err }, @@ -55,10 +55,10 @@ func loadAndDisplayCache() (bool, error) { } signpostPath := filepath.Join(homeDir, installationCachePointerFileName) - // os.Stat(signpostPath) // returns os.ErrNotExist when no cache has been written yet. + // os.Stat(signpostPath) returns os.ErrNotExist when no cache has been written yet. if _, err := os.Stat(signpostPath); os.IsNotExist(err) { fmt.Println("No cached data found. Run 'install' for a miner first.") - return false, nil // loadAndDisplayCache() returns false until install() writes the first cache file. + return false, nil // loadAndDisplayCache returns false until install writes the first cache file. } configPathBytes, err := os.ReadFile(signpostPath) @@ -67,7 +67,7 @@ func loadAndDisplayCache() (bool, error) { } configPath := strings.TrimSpace(string(configPathBytes)) - // validateConfigPath("/home/alice/.config/lethean-desktop/miners/config.json") // blocks path traversal outside XDG_CONFIG_HOME. + // validateConfigPath("/home/alice/.config/lethean-desktop/miners/config.json") blocks path traversal outside XDG_CONFIG_HOME. if err := validateConfigPath(configPath); err != nil { return false, fmt.Errorf("security error: %w", err) } @@ -91,7 +91,7 @@ func loadAndDisplayCache() (bool, error) { fmt.Println() for _, details := range systemInfo.InstalledMinersInfo { - // details.Path = "/home/alice/.local/share/lethean-desktop/miners/xmrig" // maps to a friendly miner label like "XMRig". + // details.Path = "/home/alice/.local/share/lethean-desktop/miners/xmrig" maps to a friendly miner label like "XMRig". var minerName string if details.Path != "" { if strings.Contains(details.Path, "xmrig") { diff --git a/cmd/mining/cmd/peer.go b/cmd/mining/cmd/peer.go index 5b4c2ea..6f0fc16 100644 --- a/cmd/mining/cmd/peer.go +++ b/cmd/mining/cmd/peer.go @@ -43,8 +43,7 @@ to exchange public keys and establish a secure connection.`, return fmt.Errorf("failed to get peer registry: %w", err) } - // For now, just add to registry - actual connection happens with 'node serve' - // In a full implementation, we'd connect here and get the peer's identity + // For now, just add to the registry. `node serve` performs the handshake when the peer connects. peer := &node.Peer{ ID: fmt.Sprintf("pending-%d", time.Now().UnixNano()), Name: name, @@ -152,7 +151,7 @@ var peerPingCmd = &cobra.Command{ } fmt.Printf("Pinging %s (%s)...\n", peer.Name, peer.Address) - // TODO: Actually send ping via transport + // `node serve` performs the live ping over transport once the peer is connected. fmt.Println("Ping functionality requires active connection via 'node serve'") return nil }, @@ -213,21 +212,21 @@ ping latency, hop count, geographic distance, and reliability score.`, func init() { rootCmd.AddCommand(peerCmd) - // rootCmd.AddCommand(peerAddCmd) // exposes `peer add --address 10.0.0.2:9090 --name worker-1` + // rootCmd.AddCommand(peerAddCmd) exposes `peer add --address 10.0.0.2:9090 --name worker-1`. peerCmd.AddCommand(peerAddCmd) peerAddCmd.Flags().StringP("address", "a", "", "Peer address (host:port)") peerAddCmd.Flags().StringP("name", "n", "", "Peer name") - // rootCmd.AddCommand(peerListCmd) // exposes `peer list` + // rootCmd.AddCommand(peerListCmd) exposes `peer list`. peerCmd.AddCommand(peerListCmd) - // rootCmd.AddCommand(peerRemoveCmd) // exposes `peer remove ` + // rootCmd.AddCommand(peerRemoveCmd) exposes `peer remove `. peerCmd.AddCommand(peerRemoveCmd) - // rootCmd.AddCommand(peerPingCmd) // exposes `peer ping ` + // rootCmd.AddCommand(peerPingCmd) exposes `peer ping `. peerCmd.AddCommand(peerPingCmd) - // rootCmd.AddCommand(peerOptimalCmd) // exposes `peer optimal --count 4` + // rootCmd.AddCommand(peerOptimalCmd) exposes `peer optimal --count 4`. peerCmd.AddCommand(peerOptimalCmd) peerOptimalCmd.Flags().IntP("count", "c", 1, "Number of optimal peers to show") } diff --git a/cmd/mining/cmd/remote.go b/cmd/mining/cmd/remote.go index a0eeeef..2459a64 100644 --- a/cmd/mining/cmd/remote.go +++ b/cmd/mining/cmd/remote.go @@ -11,10 +11,10 @@ import ( ) var ( - controller *node.Controller - transport *node.Transport - controllerOnce sync.Once - controllerErr error + remoteController *node.Controller + peerTransport *node.Transport + remoteControllerOnce sync.Once + remoteControllerErr error ) // remote status, remote start, remote stop, remote logs, remote connect, remote disconnect, and remote ping live under this command group. @@ -24,13 +24,13 @@ var remoteCmd = &cobra.Command{ Long: `Send commands to remote worker nodes and retrieve their status.`, } -// remote status a1b2c3d4e5f6 prints stats for one peer, while remote status prints the whole fleet. +// remote status a1b2c3d4e5f6 prints stats for one peer, while `remote status` prints the whole fleet. var remoteStatusCmd = &cobra.Command{ Use: "status [peer-id]", Short: "Get mining status from remote peers", Long: `Display mining statistics from all connected peers or a specific peer.`, RunE: func(cmd *cobra.Command, args []string) error { - controller, err := getController() + remoteController, err := getController() if err != nil { return err } @@ -43,7 +43,7 @@ var remoteStatusCmd = &cobra.Command{ return fmt.Errorf("peer not found: %s", peerID) } - stats, err := controller.GetRemoteStats(peer.ID) + stats, err := remoteController.GetRemoteStats(peer.ID) if err != nil { return fmt.Errorf("failed to get stats: %w", err) } @@ -51,7 +51,7 @@ var remoteStatusCmd = &cobra.Command{ printPeerStats(peer, stats) } else { // Get stats from all peers - allStats := controller.GetAllStats() + allStats := remoteController.GetAllStats() if len(allStats) == 0 { fmt.Println("No connected peers.") return nil @@ -87,7 +87,7 @@ var remoteStartCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { minerType, _ := cmd.Flags().GetString("type") if minerType == "" { - return fmt.Errorf("--type is required (e.g., xmrig, tt-miner)") + return fmt.Errorf("--type is required, for example `xmrig` or `tt-miner`") } profileID, _ := cmd.Flags().GetString("profile") @@ -97,13 +97,13 @@ var remoteStartCmd = &cobra.Command{ return fmt.Errorf("peer not found: %s", peerID) } - controller, err := getController() + remoteController, err := getController() if err != nil { return err } fmt.Printf("Starting %s miner on %s with profile %s...\n", minerType, peer.Name, profileID) - if err := controller.StartRemoteMiner(peer.ID, minerType, profileID, nil); err != nil { + if err := remoteController.StartRemoteMiner(peer.ID, minerType, profileID, nil); err != nil { return fmt.Errorf("failed to start miner: %w", err) } @@ -136,13 +136,13 @@ var remoteStopCmd = &cobra.Command{ return fmt.Errorf("miner name required (as argument or --miner flag)") } - controller, err := getController() + remoteController, err := getController() if err != nil { return err } fmt.Printf("Stopping miner %s on %s...\n", minerName, peer.Name) - if err := controller.StopRemoteMiner(peer.ID, minerName); err != nil { + if err := remoteController.StopRemoteMiner(peer.ID, minerName); err != nil { return fmt.Errorf("failed to stop miner: %w", err) } @@ -167,12 +167,12 @@ var remoteLogsCmd = &cobra.Command{ return fmt.Errorf("peer not found: %s", peerID) } - controller, err := getController() + remoteController, err := getController() if err != nil { return err } - logLines, err := controller.GetRemoteLogs(peer.ID, minerName, lines) + logLines, err := remoteController.GetRemoteLogs(peer.ID, minerName, lines) if err != nil { return fmt.Errorf("failed to get logs: %w", err) } @@ -200,13 +200,13 @@ var remoteConnectCmd = &cobra.Command{ return fmt.Errorf("peer not found: %s", peerID) } - controller, err := getController() + remoteController, err := getController() if err != nil { return err } fmt.Printf("Connecting to %s at %s...\n", peer.Name, peer.Address) - if err := controller.ConnectToPeer(peer.ID); err != nil { + if err := remoteController.ConnectToPeer(peer.ID); err != nil { return fmt.Errorf("failed to connect: %w", err) } @@ -228,13 +228,13 @@ var remoteDisconnectCmd = &cobra.Command{ return fmt.Errorf("peer not found: %s", peerID) } - controller, err := getController() + remoteController, err := getController() if err != nil { return err } fmt.Printf("Disconnecting from %s...\n", peer.Name) - if err := controller.DisconnectFromPeer(peer.ID); err != nil { + if err := remoteController.DisconnectFromPeer(peer.ID); err != nil { return fmt.Errorf("failed to disconnect: %w", err) } @@ -258,7 +258,7 @@ var remotePingCmd = &cobra.Command{ return fmt.Errorf("peer not found: %s", peerID) } - controller, err := getController() + remoteController, err := getController() if err != nil { return err } @@ -269,7 +269,7 @@ var remotePingCmd = &cobra.Command{ var successfulPings int for i := 0; i < count; i++ { - rtt, err := controller.PingPeer(peer.ID) + rtt, err := remoteController.PingPeer(peer.ID) if err != nil { fmt.Printf(" Ping %d: timeout\n", i+1) continue @@ -302,7 +302,7 @@ func init() { // remoteCmd.AddCommand(remoteStartCmd) // exposes `remote start --type xmrig --profile default` remoteCmd.AddCommand(remoteStartCmd) remoteStartCmd.Flags().StringP("profile", "p", "", "Profile ID to use for starting the miner") - remoteStartCmd.Flags().StringP("type", "t", "", "Miner type (e.g., xmrig, tt-miner)") + remoteStartCmd.Flags().StringP("type", "t", "", "Miner type, for example xmrig or tt-miner") // remoteCmd.AddCommand(remoteStopCmd) // exposes `remote stop --miner xmrig-1` remoteCmd.AddCommand(remoteStopCmd) @@ -325,46 +325,45 @@ func init() { // getController returns or creates the controller instance (thread-safe). func getController() (*node.Controller, error) { - controllerOnce.Do(func() { + remoteControllerOnce.Do(func() { nodeManager, err := getNodeManager() if err != nil { - controllerErr = fmt.Errorf("failed to get node manager: %w", err) + remoteControllerErr = fmt.Errorf("failed to get node manager: %w", err) return } if !nodeManager.HasIdentity() { - controllerErr = fmt.Errorf("no node identity found. Run 'node init' first") + remoteControllerErr = fmt.Errorf("no node identity found. Run `node init` first") return } peerRegistry, err := getPeerRegistry() if err != nil { - controllerErr = fmt.Errorf("failed to get peer registry: %w", err) + remoteControllerErr = fmt.Errorf("failed to get peer registry: %w", err) return } - // node.DefaultTransportConfig() // provides the transport settings used by `remote` commands - config := node.DefaultTransportConfig() - transport = node.NewTransport(nodeManager, peerRegistry, config) - controller = node.NewController(nodeManager, peerRegistry, transport) + transportConfig := node.DefaultTransportConfig() + peerTransport = node.NewTransport(nodeManager, peerRegistry, transportConfig) + remoteController = node.NewController(nodeManager, peerRegistry, peerTransport) }) - return controller, controllerErr + return remoteController, remoteControllerErr } -// findPeerByPartialID("a1b2c3") // returns the matching peer by full or partial ID. +// findPeerByPartialID("a1b2c3") returns the peer whose ID starts with `a1b2c3`. func findPeerByPartialID(partialID string) *node.Peer { peerRegistry, err := getPeerRegistry() if err != nil { return nil } - // peerRegistry.GetPeer(partialID) // exact match first + // peerRegistry.GetPeer(partialID) tries the exact peer ID first. peer := peerRegistry.GetPeer(partialID) if peer != nil { return peer } - // peerRegistry.ListPeers() // then fall back to partial ID or exact name matches + // peerRegistry.ListPeers() falls back to partial IDs such as `a1b2c3`. for _, p := range peerRegistry.ListPeers() { if strings.HasPrefix(p.ID, partialID) { return p @@ -378,7 +377,7 @@ func findPeerByPartialID(partialID string) *node.Peer { return nil } -// printPeerStats(peer, stats) // formats the remote stats output for `remote status`. +// printPeerStats(peer, stats) formats the remote stats output for `remote status`. func printPeerStats(peer *node.Peer, stats *node.StatsPayload) { fmt.Printf("\n%s (%s)\n", peer.Name, peer.ID[:16]) fmt.Printf(" Address: %s\n", peer.Address) diff --git a/cmd/mining/cmd/serve.go b/cmd/mining/cmd/serve.go index df62e73..26ac2f5 100644 --- a/cmd/mining/cmd/serve.go +++ b/cmd/mining/cmd/serve.go @@ -42,17 +42,17 @@ var serveCmd = &cobra.Command{ displayAddr := fmt.Sprintf("%s:%d", displayHost, port) listenAddr := fmt.Sprintf("%s:%d", host, port) - // manager := getServiceManager() // `mining serve` and `mining start` share the same manager instance. - manager := getServiceManager() + // miningManager := getServiceManager() shares the same miner lifecycle state across CLI commands. + miningManager := getServiceManager() - service, err := mining.NewService(manager, listenAddr, displayAddr, namespace) + miningService, err := mining.NewService(miningManager, listenAddr, displayAddr, namespace) if err != nil { return fmt.Errorf("failed to create new service: %w", err) } - // service.ServiceStartup(ctx) // starts the HTTP server on 127.0.0.1:9090 while the shell keeps reading stdin. + // miningService.ServiceStartup(ctx) starts the HTTP server while the shell keeps reading stdin. go func() { - if err := service.ServiceStartup(ctx); err != nil { + if err := miningService.ServiceStartup(ctx); err != nil { fmt.Fprintf(os.Stderr, "Failed to start service: %v\n", err) cancel() } @@ -65,7 +65,7 @@ var serveCmd = &cobra.Command{ // go func() { fmt.Print(">> ") } // keeps the interactive shell responsive while the API serves requests. go func() { fmt.Printf("Mining service started on http://%s:%d\n", displayHost, port) - fmt.Printf("Swagger documentation is available at http://%s:%d%s/index.html\n", displayHost, port, service.SwaggerUIPath) + fmt.Printf("Swagger documentation is available at http://%s:%d%s/index.html\n", displayHost, port, miningService.SwaggerUIPath) fmt.Println("Entering interactive shell. Type 'exit' or 'quit' to stop.") fmt.Print(">> ") @@ -101,7 +101,7 @@ var serveCmd = &cobra.Command{ poolURL := commandArgs[1] walletAddress := commandArgs[2] - // poolURL := "stratum+tcp://pool.example.com:3333" // required scheme for the miner configuration. + // poolURL := "stratum+tcp://pool.example.com:3333" keeps the miner configuration valid. if !strings.HasPrefix(poolURL, "stratum+tcp://") && !strings.HasPrefix(poolURL, "stratum+ssl://") && !strings.HasPrefix(poolURL, "stratum://") { @@ -115,7 +115,7 @@ var serveCmd = &cobra.Command{ continue } - // walletAddress := "44Affq5kSiGBoZ..." // keeps the wallet field within the 256-character limit. + // walletAddress := "44Affq5kSiGBoZ..." keeps the wallet field within the 256-character limit. if len(walletAddress) > 256 { fmt.Fprintf(os.Stderr, "Error: Wallet address too long (max 256 chars)\n") fmt.Print(">> ") @@ -135,7 +135,7 @@ var serveCmd = &cobra.Command{ continue } - miner, err := manager.StartMiner(context.Background(), minerType, config) + miner, err := miningManager.StartMiner(context.Background(), minerType, config) if err != nil { fmt.Fprintf(os.Stderr, "Error starting miner: %v\n", err) } else { @@ -144,10 +144,10 @@ var serveCmd = &cobra.Command{ } case "status": if len(commandArgs) < 1 { - fmt.Println("Error: status command requires miner name (e.g., 'status xmrig')") + fmt.Println("Error: status command requires miner name, for example `status xmrig`") } else { minerName := commandArgs[0] - miner, err := manager.GetMiner(minerName) + miner, err := miningManager.GetMiner(minerName) if err != nil { fmt.Fprintf(os.Stderr, "Error getting miner status: %v\n", err) } else { @@ -166,10 +166,10 @@ var serveCmd = &cobra.Command{ } case "stop": if len(commandArgs) < 1 { - fmt.Println("Error: stop command requires miner name (e.g., 'stop xmrig')") + fmt.Println("Error: stop command requires miner name, for example `stop xmrig`") } else { minerName := commandArgs[0] - err := manager.StopMiner(context.Background(), minerName) + err := miningManager.StopMiner(context.Background(), minerName) if err != nil { fmt.Fprintf(os.Stderr, "Error stopping miner: %v\n", err) } else { @@ -177,7 +177,7 @@ var serveCmd = &cobra.Command{ } } case "list": - miners := manager.ListMiners() + miners := miningManager.ListMiners() if len(miners) == 0 { fmt.Println("No miners currently running.") } else { @@ -188,12 +188,12 @@ var serveCmd = &cobra.Command{ } default: fmt.Fprintf(os.Stderr, "Unknown command: %s. Only 'start', 'status', 'stop', 'list' are directly supported in this shell.\n", command) - fmt.Fprintf(os.Stderr, "For other commands, please run them directly from your terminal (e.g., 'mining doctor').\n") + fmt.Fprintf(os.Stderr, "For other commands, please run them directly from your terminal, for example `mining doctor`.\n") } fmt.Print(">> ") } - // scanner.Err() // reports stdin failures such as a closed terminal. + // scanner.Err() reports stdin failures such as a closed terminal. if err := scanner.Err(); err != nil { fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err) } @@ -206,8 +206,8 @@ var serveCmd = &cobra.Command{ case <-ctx.Done(): } - // manager.Stop() // stops miner goroutines and closes the shared manager before exit. - manager.Stop() + // miningManager.Stop() stops miner goroutines and closes the shared manager before exit. + miningManager.Stop() fmt.Println("Mining service stopped.") return nil diff --git a/cmd/mining/cmd/status.go b/cmd/mining/cmd/status.go index 08d0ea6..8f654d0 100644 --- a/cmd/mining/cmd/status.go +++ b/cmd/mining/cmd/status.go @@ -17,9 +17,9 @@ var statusCmd = &cobra.Command{ Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { minerName := args[0] - manager := getServiceManager() + miningManager := getServiceManager() - miner, err := manager.GetMiner(minerName) + miner, err := miningManager.GetMiner(minerName) if err != nil { return fmt.Errorf("failed to get miner: %w", err) } diff --git a/pkg/mining/bufpool.go b/pkg/mining/bufpool.go index e719ebd..b087c03 100644 --- a/pkg/mining/bufpool.go +++ b/pkg/mining/bufpool.go @@ -6,48 +6,49 @@ import ( "sync" ) -// buf := bufferPool.Get().(*bytes.Buffer); buf.Reset(); defer bufferPool.Put(buf) -var bufferPool = sync.Pool{ - New: func() interface{} { +// buffer := jsonBufferPool.Get().(*bytes.Buffer) +// buffer.Reset() +// defer jsonBufferPool.Put(buffer) +var jsonBufferPool = sync.Pool{ + New: func() any { return bytes.NewBuffer(make([]byte, 0, 1024)) }, } -// buf := getBuffer() -// defer putBuffer(buf) -func getBuffer() *bytes.Buffer { - buf := bufferPool.Get().(*bytes.Buffer) - buf.Reset() - return buf +// buffer := acquireJSONBuffer() +// defer releaseJSONBuffer(buffer) +func acquireJSONBuffer() *bytes.Buffer { + buffer := jsonBufferPool.Get().(*bytes.Buffer) + buffer.Reset() + return buffer } -// defer putBuffer(buf) // return buf after use; buffers >64KB are discarded -func putBuffer(buf *bytes.Buffer) { - // Don't pool buffers that grew too large (>64KB) - if buf.Cap() <= 65536 { - bufferPool.Put(buf) +// releaseJSONBuffer(buffer) returns the buffer to the pool when it stays under 64 KB. +func releaseJSONBuffer(buffer *bytes.Buffer) { + if buffer.Cap() <= 65536 { + jsonBufferPool.Put(buffer) } } -// UnmarshalJSON(data, &msg) +// UnmarshalJSON(data, &message) func UnmarshalJSON(data []byte, target interface{}) error { return json.Unmarshal(data, target) } -// data, err := MarshalJSON(stats) // pooled buffer; safe to hold after call +// data, err := MarshalJSON(stats) // safe to keep after the call returns. func MarshalJSON(value interface{}) ([]byte, error) { - buf := getBuffer() - defer putBuffer(buf) + buffer := acquireJSONBuffer() + defer releaseJSONBuffer(buffer) - encoder := json.NewEncoder(buf) - // Don't escape HTML characters (matches json.Marshal behavior for these use cases) + encoder := json.NewEncoder(buffer) + // Keep characters like < and > unchanged so API responses match json.Marshal. encoder.SetEscapeHTML(false) if err := encoder.Encode(value); err != nil { return nil, err } - // json.Encoder.Encode adds a newline; remove it to match json.Marshal - data := buf.Bytes() + // json.Encoder.Encode adds a newline; trim it so callers get compact JSON. + data := buffer.Bytes() if len(data) > 0 && data[len(data)-1] == '\n' { data = data[:len(data)-1] } diff --git a/pkg/mining/manager.go b/pkg/mining/manager.go index f6612d5..5c39e04 100644 --- a/pkg/mining/manager.go +++ b/pkg/mining/manager.go @@ -13,20 +13,20 @@ import ( "forge.lthn.ai/Snider/Mining/pkg/logging" ) -// equalFold("xmrig", "XMRig") // true -// equalFold("tt-miner", "TT-Miner") // true +// equalFold("xmrig", "XMRig") returns true. +// equalFold("tt-miner", "TT-Miner") returns true. func equalFold(left, right string) bool { return bytes.EqualFold([]byte(left), []byte(right)) } -// hasPrefix("xmrig-rx0", "xmrig") // true -// hasPrefix("ttminer-rtx", "xmrig") // false +// hasPrefix("xmrig-rx0", "xmrig") returns true. +// hasPrefix("ttminer-rtx", "xmrig") returns false. func hasPrefix(input, prefix string) bool { return len(input) >= len(prefix) && input[:len(prefix)] == prefix } -// containsStr("peer not found", "not found") // true -// containsStr("connection ok", "not found") // false +// containsStr("peer not found", "not found") returns true. +// containsStr("connection ok", "not found") returns false. func containsStr(haystack, needle string) bool { if len(needle) == 0 { return true @@ -42,7 +42,7 @@ func containsStr(haystack, needle string) bool { return false } -// safeName := instanceNameRegex.ReplaceAllString("my algo!", "_") // "my_algo_" +// safeName := instanceNameRegex.ReplaceAllString("my algo!", "_") // `my_algo_` var instanceNameRegex = regexp.MustCompile(`[^a-zA-Z0-9_/-]`) // var managerInterface ManagerInterface = mining.NewManager() @@ -122,7 +122,7 @@ func NewManagerForSimulation() *Manager { return manager } -// manager.initDatabase() // miners.json with Database.Enabled=true enables database.Initialize(database.Config{Enabled: true, RetentionDays: 30}) +// manager.initDatabase() loads `miners.json` and enables database persistence when `Database.Enabled` is true. 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() // database.Cleanup(30) runs once per hour after NewManager() enables persistence + // manager.startDBCleanup() runs once per hour after NewManager enables persistence. manager.startDBCleanup() } -// manager.startDBCleanup() // with manager.databaseRetention=30, database.Cleanup(30) runs every hour +// manager.startDBCleanup() runs `database.Cleanup(manager.databaseRetention)` on startup and every hour. func (manager *Manager) startDBCleanup() { manager.waitGroup.Add(1) go func() { @@ -168,18 +168,18 @@ func (manager *Manager) startDBCleanup() { logging.Error("panic in database cleanup goroutine", logging.Fields{"panic": r}) } }() - // ticker := time.NewTicker(time.Hour) // checks for expired rows every 60 minutes - ticker := time.NewTicker(time.Hour) - defer ticker.Stop() + // cleanupTicker := time.NewTicker(time.Hour) checks for expired rows every 60 minutes. + cleanupTicker := time.NewTicker(time.Hour) + defer cleanupTicker.Stop() - // database.Cleanup(30) // removes rows older than 30 days during startup + // database.Cleanup(manager.databaseRetention) removes rows older than the configured retention period during startup. if err := database.Cleanup(manager.databaseRetention); err != nil { logging.Warn("database cleanup failed", logging.Fields{"error": err}) } for { select { - case <-ticker.C: + case <-cleanupTicker.C: if err := database.Cleanup(manager.databaseRetention); err != nil { logging.Warn("database cleanup failed", logging.Fields{"error": err}) } @@ -190,7 +190,7 @@ func (manager *Manager) startDBCleanup() { }() } -// manager.syncMinersConfig() // miners.json with only "tt-miner" adds MinerAutostartConfig{MinerType: "xmrig", Autostart: false} +// manager.syncMinersConfig() adds missing entries such as `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() // miners.json with Autostart=true starts xmrig from context.Background() +// manager.autostartMiners() starts entries with `Autostart: true` from `context.Background()`. func (manager *Manager) autostartMiners() { minersConfiguration, err := LoadMinersConfig() if err != nil { diff --git a/pkg/mining/miner.go b/pkg/mining/miner.go index c536fb5..57c3bc8 100644 --- a/pkg/mining/miner.go +++ b/pkg/mining/miner.go @@ -94,7 +94,7 @@ func (logBuffer *LogBuffer) Clear() { // func NewXMRigMiner() *XMRigMiner { return &XMRigMiner{BaseMiner: BaseMiner{MinerType: "xmrig"}} } type BaseMiner struct { Name string `json:"name"` - MinerType string `json:"miner_type"` // Type identifier (e.g., "xmrig", "tt-miner") + MinerType string `json:"miner_type"` // Type identifier such as `xmrig` or `tt-miner`. Version string `json:"version"` URL string `json:"url"` Path string `json:"path"` @@ -112,19 +112,19 @@ type BaseMiner struct { LogBuffer *LogBuffer `json:"-"` } -// minerType := miner.GetType() // "xmrig" or "tt-miner" +// minerType := miner.GetType() // returns values such as `xmrig` or `tt-miner`. func (b *BaseMiner) GetType() string { return b.MinerType } -// name := miner.GetName() // e.g. "xmrig-randomx" or "tt-miner-kawpow" +// name := miner.GetName() // returns values such as `xmrig-randomx` or `tt-miner-kawpow`. func (b *BaseMiner) GetName() string { b.mutex.RLock() defer b.mutex.RUnlock() return b.Name } -// path := miner.GetPath() // e.g. "/home/user/.local/share/lethean-desktop/miners/xmrig" +// path := miner.GetPath() // returns paths such as `/home/alice/.local/share/lethean-desktop/miners/xmrig`. func (b *BaseMiner) GetPath() string { dataPath, err := xdg.DataFile("lethean-desktop/miners/" + b.ExecutableName) if err != nil { @@ -137,7 +137,7 @@ func (b *BaseMiner) GetPath() string { return dataPath } -// binary := miner.GetBinaryPath() // e.g. "/home/user/.local/share/lethean-desktop/miners/xmrig/xmrig" +// binary := miner.GetBinaryPath() // returns paths such as `/home/alice/.local/share/lethean-desktop/miners/xmrig/xmrig`. func (b *BaseMiner) GetBinaryPath() string { b.mutex.RLock() defer b.mutex.RUnlock() @@ -346,7 +346,7 @@ func (b *BaseMiner) findMinerBinary() (string, error) { if err == nil { for _, entry := range dirs { if entry.IsDir() && strings.HasPrefix(entry.Name(), b.ExecutableName+"-") { - // Extract version string, e.g., "xmrig-6.24.0" -> "6.24.0" + // Extract the version suffix from a directory name such as `xmrig-6.24.0`. versionStr := strings.TrimPrefix(entry.Name(), b.ExecutableName+"-") currentVersion := parseVersion(versionStr) diff --git a/pkg/mining/mining.go b/pkg/mining/mining.go index b529490..5a3f69d 100644 --- a/pkg/mining/mining.go +++ b/pkg/mining/mining.go @@ -135,11 +135,11 @@ type Config struct { 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") + GPUAlgo string `json:"gpuAlgo,omitempty"` // GPU algorithm such as `kawpow` or `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") + Devices string `json:"devices,omitempty"` // GPU device selection such as `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 diff --git a/pkg/mining/mining_profile.go b/pkg/mining/mining_profile.go index f9226f7..2468d9e 100644 --- a/pkg/mining/mining_profile.go +++ b/pkg/mining/mining_profile.go @@ -1,20 +1,19 @@ package mining - -// var raw RawConfig -// _ = json.Unmarshal([]byte(`{"pool":"pool.lthn.io:3333"}`), &raw) +// var rawConfig RawConfig +// _ = json.Unmarshal([]byte(`{"pool":"pool.lthn.io:3333"}`), &rawConfig) type RawConfig []byte -// profile := MiningProfile{ID: "abc", Name: "LTHN RandomX", MinerType: "xmrig", Config: raw} +// profile := MiningProfile{ID: "abc", Name: "LTHN RandomX", MinerType: "xmrig", Config: rawConfig} // manager.SaveProfile(profile) type MiningProfile struct { ID string `json:"id"` Name string `json:"name"` - MinerType string `json:"minerType"` // e.g., "xmrig", "ttminer" - Config RawConfig `json:"config" swaggertype:"object"` // The raw JSON config for the specific miner + MinerType string `json:"minerType"` // Miner type such as `xmrig` or `ttminer`. + Config RawConfig `json:"config" swaggertype:"object"` // Raw JSON config for the selected miner profile. } -// data, err := profile.Config.MarshalJSON() +// data, err := profile.Config.MarshalJSON() // returns the config blob unchanged. func (m RawConfig) MarshalJSON() ([]byte, error) { if m == nil { return []byte("null"), nil @@ -22,7 +21,7 @@ func (m RawConfig) MarshalJSON() ([]byte, error) { return m, nil } -// if err := json.Unmarshal(raw, &profile.Config); err != nil { ... } +// if err := json.Unmarshal(rawConfig, &profile.Config); err != nil { ... } func (m *RawConfig) UnmarshalJSON(data []byte) error { if m == nil { return ErrInternal("RawConfig: UnmarshalJSON on nil pointer") diff --git a/pkg/mining/ratelimiter.go b/pkg/mining/ratelimiter.go index c81a2f9..9186edd 100644 --- a/pkg/mining/ratelimiter.go +++ b/pkg/mining/ratelimiter.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" ) -// limiter := NewRateLimiter(10, 20) // 10 req/s, burst 20 +// limiter := NewRateLimiter(10, 20) // 10 requests per second with a burst of 20. // router.Use(limiter.Middleware()) type RateLimiter struct { requestsPerSecond int diff --git a/pkg/mining/service.go b/pkg/mining/service.go index 5d6f593..46ae6dc 100644 --- a/pkg/mining/service.go +++ b/pkg/mining/service.go @@ -34,7 +34,7 @@ import ( // service, err := mining.NewService(manager, "127.0.0.1:9090", "localhost:9090", "/api/v1/mining") // if err != nil { return err } -// service.ServiceStartup(context.Background()) // starts the REST API on 127.0.0.1:9090. +// service.ServiceStartup(context.Background()) starts the REST API on 127.0.0.1:9090. type Service struct { Manager ManagerInterface ProfileManager *ProfileManager @@ -1089,14 +1089,14 @@ func (service *Service) handleGetMinerLogs(c *gin.Context) { c.JSON(http.StatusOK, encodedLogs) } -// c.ShouldBindJSON(&StdinInput{Input: "h"}) // "h" for hashrate, "p" for pause +// c.ShouldBindJSON(&StdinInput{Input: "h"}) // `h` prints hash rate and `p` pauses mining. type StdinInput struct { Input string `json:"input" binding:"required"` } // handleMinerStdin godoc // @Summary Send input to miner stdin -// @Description Send console commands to a running miner's stdin (e.g., 'h' for hashrate, 'p' for pause) +// @Description Send console commands to a running miner's stdin. Use `h` to print hash rate and `p` to pause mining. // @Tags miners // @Accept json // @Produce json diff --git a/pkg/mining/simulated_miner.go b/pkg/mining/simulated_miner.go index 3bcfa01..3c90436 100644 --- a/pkg/mining/simulated_miner.go +++ b/pkg/mining/simulated_miner.go @@ -44,8 +44,8 @@ type SimulatedMiner struct { // SimulatedMinerConfig{Name: "sim-001", Algorithm: "rx/0", BaseHashrate: 5000, Variance: 0.1} type SimulatedMinerConfig struct { - Name string // Miner instance name (e.g., "sim-xmrig-001") - Algorithm string // Algorithm name (e.g., "rx/0", "kawpow", "ethash") + Name string // Miner instance name such as `sim-xmrig-001`. + Algorithm string // Algorithm name such as `rx/0`, `kawpow`, or `ethash`. BaseHashrate int // Base hashrate in H/s Variance float64 // Variance as percentage (0.0-0.2 for 20% variance) PoolName string // Simulated pool name diff --git a/pkg/mining/ttminer_start.go b/pkg/mining/ttminer_start.go index 1a82f47..abb9f00 100644 --- a/pkg/mining/ttminer_start.go +++ b/pkg/mining/ttminer_start.go @@ -191,7 +191,7 @@ func isValidCLIArg(arg string) bool { // Must start with dash (standard CLI argument format) // This is an allowlist approach - only accept valid argument patterns if !strings.HasPrefix(arg, "-") { - // Allow values for flags (e.g., the "3" in "-i 3") + // Allow flag values such as the `3` in `-i 3`. // Values must not contain shell metacharacters return isValidArgValue(arg) } diff --git a/pkg/mining/xmrig.go b/pkg/mining/xmrig.go index 76dfe8b..11ad2fc 100644 --- a/pkg/mining/xmrig.go +++ b/pkg/mining/xmrig.go @@ -79,7 +79,7 @@ func NewXMRigMiner() *XMRigMiner { var getXMRigConfigPath = func(instanceName string) (string, error) { configFileName := "xmrig.json" if instanceName != "" && instanceName != "xmrig" { - // Use instance-specific config file (e.g., xmrig-78.json) + // Use an instance-specific config file such as `xmrig-78.json`. configFileName = instanceName + ".json" } diff --git a/pkg/mining/xmrig_start.go b/pkg/mining/xmrig_start.go index c8fc7c3..aec7ae2 100644 --- a/pkg/mining/xmrig_start.go +++ b/pkg/mining/xmrig_start.go @@ -266,7 +266,7 @@ func (m *XMRigMiner) createConfig(config *Config) error { "enabled": config.GPUEnabled && config.OpenCL && config.Devices != "", } if config.GPUEnabled && config.OpenCL && config.Devices != "" { - // User must explicitly specify devices (e.g., "0" or "0,1") + // User must explicitly specify devices such as `0` or `0,1`. openclConfig["devices"] = config.Devices if config.GPUIntensity > 0 { openclConfig["intensity"] = config.GPUIntensity @@ -282,7 +282,7 @@ func (m *XMRigMiner) createConfig(config *Config) error { "enabled": config.GPUEnabled && config.CUDA && config.Devices != "", } if config.GPUEnabled && config.CUDA && config.Devices != "" { - // User must explicitly specify devices (e.g., "0" or "0,1") + // User must explicitly specify devices such as `0` or `0,1`. cudaConfig["devices"] = config.Devices if config.GPUIntensity > 0 { cudaConfig["intensity"] = config.GPUIntensity