From 65ccf50c2b2d78cc4e3d047a1ab7993a7cbdfd69 Mon Sep 17 00:00:00 2001 From: Snider Date: Wed, 15 Apr 2026 19:16:45 +0100 Subject: [PATCH] Add p2p peers to core network route --- pkg/display/network.go | 105 ++++++++++++++++++++++++++++++++++++- pkg/display/scheme_test.go | 40 ++++++++++++++ 2 files changed, 143 insertions(+), 2 deletions(-) diff --git a/pkg/display/network.go b/pkg/display/network.go index b23fa9f6..f018c6e9 100644 --- a/pkg/display/network.go +++ b/pkg/display/network.go @@ -8,6 +8,8 @@ import ( "sort" "strings" "time" + + "forge.lthn.ai/core/gui/pkg/p2p" ) type NetworkInterfaceState struct { @@ -21,9 +23,17 @@ type NetworkInterfaceState struct { Loopback bool `json:"loopback"` } +type NetworkPeerState struct { + ID string `json:"id"` + Topic string `json:"topic"` + Connected bool `json:"connected"` + SeenAt time.Time `json:"seen_at"` +} + type NetworkState struct { Hostname string `json:"hostname"` Interfaces []NetworkInterfaceState `json:"interfaces"` + Peers []NetworkPeerState `json:"peers,omitempty"` ObservedAt time.Time `json:"observed_at"` } @@ -64,9 +74,55 @@ func (s *Service) networkState() NetworkState { }) } + state.Peers = s.p2pPeers() return state } +type peerLister interface { + Peers() []p2p.Peer +} + +func (s *Service) p2pPeers() []NetworkPeerState { + if s == nil || s.Core() == nil { + return nil + } + + for _, serviceName := range []string{"p2p", "network"} { + serviceResult := s.Core().Service(serviceName) + if !serviceResult.OK || serviceResult.Value == nil { + continue + } + lister, ok := serviceResult.Value.(peerLister) + if !ok { + continue + } + + peers := lister.Peers() + if len(peers) == 0 { + continue + } + + peerStates := make([]NetworkPeerState, 0, len(peers)) + for _, peer := range peers { + peerStates = append(peerStates, NetworkPeerState{ + ID: peer.ID, + Topic: peer.Topic, + Connected: peer.Connected, + SeenAt: peer.SeenAt, + }) + } + sort.Slice(peerStates, func(i, j int) bool { + if peerStates[i].SeenAt.Equal(peerStates[j].SeenAt) { + return strings.ToLower(peerStates[i].ID) < strings.ToLower(peerStates[j].ID) + } + return peerStates[i].SeenAt.After(peerStates[j].SeenAt) + }) + return peerStates + } + + return nil +} + func (s *Service) renderNetworkPage(state NetworkState) string { var builder strings.Builder builder.WriteString("core://network