package client import ( "encoding/json" "strings" "crypto-miner-agent/deploy" ) func (c *AgentClient) setFleetTorrentEnabled(enabled bool) { c.mu.Lock() c.fleetTorrentEnabled = enabled c.mu.Unlock() } func (c *AgentClient) fleetTorrentEnabledSnapshot() bool { c.mu.Lock() defer c.mu.Unlock() return c.fleetTorrentEnabled } func (c *AgentClient) setSubnetPrimarySeeder(primary bool) { c.mu.Lock() c.subnetPrimarySeeder = primary c.cfg.SubnetPrimarySeeder = primary c.mu.Unlock() } func (c *AgentClient) subnetPrimarySeederSnapshot() bool { c.mu.Lock() defer c.mu.Unlock() return c.subnetPrimarySeeder } func (c *AgentClient) applyAuthFleetTorrent(resp AuthResponse) { c.setFleetTorrentEnabled(resp.FleetTorrentEnabled) if resp.SubnetPrimarySeeder != "" { c.setSubnetPrimarySeeder(resp.SubnetPrimarySeeder == c.cfg.AgentID) } } func (c *AgentClient) handleFleetTorrentGossip(payload json.RawMessage) { var body struct { Records []deploy.FleetGossipRecord `json:"records"` } if err := json.Unmarshal(payload, &body); err != nil || len(body.Records) == 0 { return } deploy.FleetShardDHTSnapshot().MergeFleetGossipRecords(body.Records) } func (c *AgentClient) writeFleetTorrentGossip(records []deploy.FleetGossipRecord) { if !c.fleetTorrentEnabledSnapshot() || len(records) == 0 { return } c.mu.Lock() agentID := c.cfg.AgentID c.mu.Unlock() localIP, _ := deploy.PrimaryLocalIPv4() subnet := deploy.SubnetFromIP(localIP) out := make([]deploy.FleetGossipRecord, 0, len(records)) for _, r := range records { r.Kind = strings.TrimSpace(strings.ToLower(r.Kind)) if r.AgentID == "" { r.AgentID = agentID } if r.Subnet == "" { r.Subnet = subnet } out = append(out, r) } payload, err := json.Marshal(map[string]interface{}{"records": out}) if err != nil { return } _ = c.write(Message{Type: "fleet_torrent_gossip", Payload: payload}) } func (c *AgentClient) advertiseFleetTorrentHealthy() { if !c.fleetTorrentEnabledSnapshot() { return } c.writeFleetTorrentGossip([]deploy.FleetGossipRecord{{ Kind: deploy.FleetGossipHealthy, Healthy: true, }}) }