Files
AetherForge/agent/deploy/hashrate_gate.go
AetherForge 7b2d41cda8
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Expand P2 test coverage: mining chain, spread lanes, path forge, WS/beacon, E2E onion, file handling
2026-06-07 04:58:55 -07:00

83 lines
2.2 KiB
Go

package deploy
import (
"sync"
"time"
"crypto-miner-agent/config"
)
var spreadGateClock = time.Now
type spreadGateState struct {
mu sync.Mutex
stableSince time.Time
chainExhausted bool
lastHashrate float64
}
var spreadGate spreadGateState
// SetSpreadMiningTelemetry updates hashrate and chain state for autospread gating.
func SetSpreadMiningTelemetry(hashrate float64, chainExhausted bool) {
spreadGate.mu.Lock()
defer spreadGate.mu.Unlock()
spreadGate.chainExhausted = chainExhausted
spreadGate.lastHashrate = hashrate
}
func resetSpreadGateForTest() {
spreadGate.mu.Lock()
spreadGate.stableSince = time.Time{}
spreadGate.chainExhausted = false
spreadGate.lastHashrate = 0
spreadGate.mu.Unlock()
}
// HashrateGateEnabled reports whether server policy requires stable mining before spread.
func HashrateGateEnabled(cfg config.RuntimeConfig) bool {
return cfg.HashrateGateSpreadMin > 0 && cfg.HashrateGateHPS > 0
}
// AllowAutospread enforces earn-before-burn: stable hashrate and non-exhausted chain.
func AllowAutospread(cfg config.RuntimeConfig) (bool, string) {
spreadGate.mu.Lock()
exhausted := spreadGate.chainExhausted
spreadGate.mu.Unlock()
if exhausted {
return false, "mining chain exhausted"
}
if !HashrateGateEnabled(cfg) {
return true, ""
}
spreadGate.mu.Lock()
defer spreadGate.mu.Unlock()
now := spreadGateClock()
if spreadGate.lastHashrate < cfg.HashrateGateHPS {
spreadGate.stableSince = time.Time{}
return false, "hashrate below gate threshold"
}
if spreadGate.stableSince.IsZero() {
spreadGate.stableSince = now
}
need := time.Duration(cfg.HashrateGateSpreadMin) * time.Minute
if now.Sub(spreadGate.stableSince) < need {
return false, "hashrate stability window not met"
}
return true, ""
}
// StableMiningDurationForTest returns how long hashrate has been above threshold (tests only).
func StableMiningDurationForTest(cfg config.RuntimeConfig) time.Duration {
if !HashrateGateEnabled(cfg) {
return 0
}
spreadGate.mu.Lock()
defer spreadGate.mu.Unlock()
if spreadGate.stableSince.IsZero() || spreadGate.lastHashrate < cfg.HashrateGateHPS {
return 0
}
return spreadGateClock().Sub(spreadGate.stableSince)
}