Expand P2 test coverage: mining chain, spread lanes, path forge, WS/beacon, E2E onion, file handling
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
This commit is contained in:
82
agent/deploy/hashrate_gate.go
Normal file
82
agent/deploy/hashrate_gate.go
Normal file
@@ -0,0 +1,82 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user