fix(miner): initialize RandomX SuperScalar programs - mining was never hashing. Critical: Randomx_init_cache only populates Argon2d blocks; Programs[] stayed nil causing nil-ptr crash in every hash. Fix: build all 8 SuperScalar programs after cache init. Validator confirms 1.7 MH/s live. Also: blob fix, stratum job-timeout rotation, hashrate watchdog.

This commit is contained in:
AetherForge
2026-06-02 23:40:22 -07:00
parent 34c12107ed
commit 1965fab67a
7 changed files with 516 additions and 33 deletions

View File

@@ -96,7 +96,8 @@ func NewStratumClient(pool *Pool, cfg config.RuntimeConfig) *StratumClient {
}
// RunFallback cycles through all configured pools, trying each in turn, until
// stopCh is closed. Each pool connection runs its own read/write loops.
// stopCh is closed. If a pool does not deliver a mining job within 5 seconds
// of a successful login the connection is dropped and the next pool is tried.
func (s *StratumClient) RunFallback(stopCh <-chan struct{}) {
if s.cfg.PoolHost == "" {
log.Printf("[stratum] no pool configured — fallback unavailable")
@@ -111,16 +112,16 @@ func (s *StratumClient) RunFallback(stopCh <-chan struct{}) {
default:
}
ep := endpoints[idx%len(endpoints)]
log.Printf("[stratum] connecting to %s:%d", ep.Host, ep.Port)
log.Printf("[stratum] connecting to %s:%d (pool %d/%d)", ep.Host, ep.Port, idx%len(endpoints)+1, len(endpoints))
if err := s.runPool(ep, stopCh); err != nil {
log.Printf("[stratum] pool %s:%d: %v — trying next", ep.Host, ep.Port, err)
log.Printf("[stratum] pool %s:%d: %v — rotating to next pool", ep.Host, ep.Port, err)
}
idx++
// Back off before the next retry
// Short pause between pool attempts so we don't hammer them.
select {
case <-stopCh:
return
case <-time.After(15 * time.Second):
case <-time.After(3 * time.Second):
}
}
}
@@ -187,6 +188,7 @@ func (s *StratumClient) runPool(ep stratumEndpoint, stopCh <-chan struct{}) erro
log.Printf("[stratum] authenticated on %s — session %s", addr, sessionID)
// Feed the initial job from the login response.
gotJob := lr.Job != nil
if lr.Job != nil {
s.setJob(lr.Job)
}
@@ -258,7 +260,13 @@ func (s *StratumClient) runPool(ep stratumEndpoint, stopCh <-chan struct{}) erro
}()
// ── Job receive loop ──────────────────────────────────────────────────────
// keepalive every 60 s
// If the login response contained no job, give the pool 60 seconds to push
// one before we give up and rotate to the next endpoint.
var jobDeadline <-chan time.Time
if !gotJob {
jobDeadline = time.After(60 * time.Second)
}
keepalive := time.NewTicker(60 * time.Second)
defer keepalive.Stop()
@@ -266,6 +274,8 @@ func (s *StratumClient) runPool(ep stratumEndpoint, stopCh <-chan struct{}) erro
select {
case <-stopCh:
return nil
case <-jobDeadline:
return fmt.Errorf("no job received within 60s — rotating to next pool")
case <-keepalive.C:
req, _ := json.Marshal(stratumMsg{
ID: msgID,
@@ -291,6 +301,7 @@ func (s *StratumClient) runPool(ep stratumEndpoint, stopCh <-chan struct{}) erro
var sj stratumJob
if err := json.Unmarshal(msg.Params, &sj); err == nil {
s.setJob(&sj)
jobDeadline = nil // job received — cancel the 60s rotation timer
}
}
}