Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package atlas
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"crypto-miner-server/internal/strategy"
|
|
)
|
|
|
|
// GossipHint is one negative-knowledge skip shared between LAN siblings.
|
|
type GossipHint struct {
|
|
Tier string `json:"tier"`
|
|
Condition string `json:"condition"`
|
|
Reason string `json:"reason,omitempty"`
|
|
}
|
|
|
|
// SubnetPrefix returns the /24 (IPv4) or /48-ish (IPv6) prefix used for LAN sibling matching.
|
|
func SubnetPrefix(ip string) string {
|
|
return strategy.FingerprintFromAuth("", ip, false).Subnet
|
|
}
|
|
|
|
// NormalizeGossipHint trims and validates one gossip hint.
|
|
func NormalizeGossipHint(h GossipHint) (GossipHint, bool) {
|
|
h.Tier = strings.TrimSpace(h.Tier)
|
|
h.Condition = strings.TrimSpace(h.Condition)
|
|
h.Reason = strings.TrimSpace(h.Reason)
|
|
if h.Tier == "" || h.Condition == "" {
|
|
return GossipHint{}, false
|
|
}
|
|
if h.Reason == "" {
|
|
h.Reason = "lan gossip"
|
|
}
|
|
return h, true
|
|
}
|
|
|
|
// NormalizeGossipHints drops invalid hints while preserving order.
|
|
func NormalizeGossipHints(in []GossipHint) []GossipHint {
|
|
if len(in) == 0 {
|
|
return nil
|
|
}
|
|
out := make([]GossipHint, 0, len(in))
|
|
for _, h := range in {
|
|
if norm, ok := NormalizeGossipHint(h); ok {
|
|
out = append(out, norm)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// SkipsFromHints converts gossip hints to atlas skips for agent merge.
|
|
func SkipsFromHints(hints []GossipHint) []AtlasSkip {
|
|
out := make([]AtlasSkip, 0, len(hints))
|
|
for _, h := range hints {
|
|
if norm, ok := NormalizeGossipHint(h); ok {
|
|
out = append(out, AtlasSkip{
|
|
Tier: norm.Tier,
|
|
Condition: norm.Condition,
|
|
Reason: norm.Reason,
|
|
})
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// MergeGossipSkips merges incoming LAN hints into existing skips without duplicates.
|
|
func MergeGossipSkips(existing []AtlasSkip, incoming []GossipHint) []AtlasSkip {
|
|
hints := NormalizeGossipHints(incoming)
|
|
if len(hints) == 0 {
|
|
return existing
|
|
}
|
|
have := make(map[string]bool, len(existing)+len(hints))
|
|
out := append([]AtlasSkip(nil), existing...)
|
|
for _, s := range existing {
|
|
have[s.Tier+"|"+s.Condition] = true
|
|
}
|
|
for _, h := range hints {
|
|
key := h.Tier + "|" + h.Condition
|
|
if have[key] {
|
|
continue
|
|
}
|
|
have[key] = true
|
|
out = append(out, AtlasSkip{
|
|
Tier: h.Tier,
|
|
Condition: h.Condition,
|
|
Reason: h.Reason,
|
|
})
|
|
}
|
|
return out
|
|
}
|