From 65fc74a4e87218c05c87211303974269bd12489d Mon Sep 17 00:00:00 2001 From: "J. Eckert" Date: Fri, 9 Jan 2026 15:25:25 -0800 Subject: [PATCH] ghost system address fix.. again --- README.md | 2 +- routing_table.go | 19 ++-------- storage.go | 95 ------------------------------------------------ web-interface.go | 59 +++++++++++++++++++----------- 4 files changed, 42 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index 103947d..5997a89 100644 --- a/README.md +++ b/README.md @@ -342,4 +342,4 @@ To add your node as a seed: ## License -MIT +MIT \ No newline at end of file diff --git a/routing_table.go b/routing_table.go index 218f4e2..3d38869 100644 --- a/routing_table.go +++ b/routing_table.go @@ -222,7 +222,9 @@ func (rt *RoutingTable) CacheSystem(sys *System, learnedFrom uuid.UUID, verified if shouldUpdate { existing.System = sys existing.LearnedAt = now - if verified && rt.storage != nil { + // Always persist updates with newer InfoVersion to storage + // The storage layer has its own InfoVersion check to prevent stale overwrites + if rt.storage != nil { rt.storage.SavePeerSystem(sys) } } @@ -515,18 +517,3 @@ func (rt *RoutingTable) PruneCache(maxAge time.Duration) int { return pruned } - -// SaveSnapshot saves the routing table state to storage -func (rt *RoutingTable) SaveSnapshot() error { - if rt.storage == nil { - return nil - } - - nodes := rt.GetAllRoutingTableNodes() - for _, sys := range nodes { - if err := rt.storage.SavePeerSystem(sys); err != nil { - return err - } - } - return nil -} diff --git a/storage.go b/storage.go index f764e76..a16678c 100644 --- a/storage.go +++ b/storage.go @@ -429,38 +429,6 @@ func (s *Storage) SaveAttestation(attestation *Attestation, receivedBy uuid.UUID return err } -// GetAttestations retrieves all attestations for a system -func (s *Storage) GetAttestations(systemID uuid.UUID) ([]*Attestation, error) { - rows, err := s.db.Query(` - SELECT from_system_id, to_system_id, timestamp, message_type, signature, public_key - FROM attestations - WHERE from_system_id = ? OR to_system_id = ? - ORDER BY timestamp ASC - `, systemID.String(), systemID.String()) - - if err != nil { - return nil, err - } - defer rows.Close() - - var attestations []*Attestation - for rows.Next() { - var att Attestation - var fromID, toID string - - err := rows.Scan(&fromID, &toID, &att.Timestamp, &att.MessageType, &att.Signature, &att.PublicKey) - if err != nil { - continue - } - - att.FromSystemID = uuid.MustParse(fromID) - att.ToSystemID = uuid.MustParse(toID) - attestations = append(attestations, &att) - } - - return attestations, nil -} - // GetAttestationCount returns the count of verified attestations func (s *Storage) GetAttestationCount(systemID uuid.UUID) (int, error) { var count int @@ -610,16 +578,6 @@ func (s *Storage) GetDatabaseStats() (map[string]interface{}, error) { return stats, nil } -// CountKnownSystems returns the total number of unique systems we've heard about -func (s *Storage) CountKnownSystems() int { - var count int - err := s.db.QueryRow(`SELECT COUNT(*) FROM peer_systems`).Scan(&count) - if err != nil { - return 0 - } - return count -} - // GetAllPeerSystems returns all cached peer system info (not just direct peers) func (s *Storage) GetAllPeerSystems() ([]*System, error) { rows, err := s.db.Query(` @@ -829,59 +787,6 @@ type TopologyEdge struct { ToName string `json:"to_name"` } -// GetRecentTopology returns inferred connections from recent attestations -func (s *Storage) GetRecentTopology(maxAge time.Duration) ([]TopologyEdge, error) { - cutoff := time.Now().Add(-maxAge).Unix() - - rows, err := s.db.Query(` - SELECT DISTINCT from_system_id, to_system_id - FROM attestations - WHERE timestamp > ? - `, cutoff) - if err != nil { - return nil, err - } - defer rows.Close() - - // Collect unique edges (deduplicate A→B and B→A) - edgeMap := make(map[string]TopologyEdge) - - for rows.Next() { - var fromID, toID string - if err := rows.Scan(&fromID, &toID); err != nil { - continue - } - - // Create canonical edge key (smaller ID first) to deduplicate - var key string - if fromID < toID { - key = fromID + ":" + toID - } else { - key = toID + ":" + fromID - } - - if _, exists := edgeMap[key]; !exists { - fromName := s.getSystemName(fromID) - toName := s.getSystemName(toID) - - edgeMap[key] = TopologyEdge{ - FromID: fromID, - FromName: fromName, - ToID: toID, - ToName: toName, - } - } - } - - // Convert map to slice - edges := make([]TopologyEdge, 0, len(edgeMap)) - for _, edge := range edgeMap { - edges = append(edges, edge) - } - - return edges, nil -} - // getSystemName looks up a system name from peer_systems cache func (s *Storage) getSystemName(systemID string) string { var name string diff --git a/web-interface.go b/web-interface.go index adbd844..30ffa3b 100644 --- a/web-interface.go +++ b/web-interface.go @@ -823,6 +823,7 @@ const indexTemplate = ` function onMouseDown(event) { if (!scope.enabled) return; event.preventDefault(); + markMapInteraction(); if (event.button === 0) { state = STATE.ROTATE; rotateStart.set(event.clientX, event.clientY); @@ -876,6 +877,7 @@ const indexTemplate = ` function onWheel(event) { if (!scope.enabled || !scope.enableZoom) return; event.preventDefault(); + markMapInteraction(); if (event.deltaY < 0) scale *= Math.pow(0.95, scope.zoomSpeed); else if (event.deltaY > 0) scale /= Math.pow(0.95, scope.zoomSpeed); scope.update(); @@ -921,6 +923,18 @@ const indexTemplate = ` let currentKnownSystems = [...knownSystems]; let currentLivePeerIDs = new Set(livePeerIDs); + // Track user interaction to avoid disrupting browsing + let lastMapInteraction = 0; + const MAP_INTERACTION_COOLDOWN = 60000; // Don't refresh map for 60s after interaction + + function markMapInteraction() { + lastMapInteraction = Date.now(); + } + + function isUserBrowsingMap() { + return (Date.now() - lastMapInteraction) < MAP_INTERACTION_COOLDOWN; + } + async function fetchConnections() { try { const resp = await fetch('/api/connections'); @@ -1497,27 +1511,30 @@ const indexTemplate = ` document.getElementById('stat-galaxy').textContent = totalSystems + ' total'; document.getElementById('galaxy-title').textContent = 'Galaxy Map (' + totalSystems + ' systems)'; - // Update live peer IDs set from peers response - currentLivePeerIDs = new Set(peers.map(p => p.id)); - - // Update known systems for map (convert to map format) - currentKnownSystems = systems.map(s => ({ - id: s.id, - name: s.name, - x: s.x, - y: s.y, - z: s.z, - color: s.stars?.primary?.color || '#ffffff', - starClass: s.stars?.primary?.class || 'M', - starDesc: s.stars?.primary?.description || '' - })); - - // Fetch fresh connections - const connectionsResp = await fetch('/api/connections'); - cachedConnections = await connectionsResp.json() || []; - - // Rebuild the 3D map with updated data - rebuildMapContent(); + // Only update map data if user isn't actively browsing + if (!isUserBrowsingMap()) { + // Update live peer IDs set from peers response + currentLivePeerIDs = new Set(peers.map(p => p.id)); + + // Update known systems for map (convert to map format) + currentKnownSystems = systems.map(s => ({ + id: s.id, + name: s.name, + x: s.x, + y: s.y, + z: s.z, + color: s.stars?.primary?.color || '#ffffff', + starClass: s.stars?.primary?.class || 'M', + starDesc: s.stars?.primary?.description || '' + })); + + // Fetch fresh connections + const connectionsResp = await fetch('/api/connections'); + cachedConnections = await connectionsResp.json() || []; + + // Rebuild the 3D map with updated data + rebuildMapContent(); + } } catch (err) { console.error('Failed to refresh stats:', err);