From ed6d31a696d69937b008163dd70f119a816ec1b3 Mon Sep 17 00:00:00 2001 From: Chase Wright Date: Thu, 16 Jul 2026 18:25:22 -0500 Subject: [PATCH 1/2] Fix startup session/pool bugs: set node on initiator sessions, lock LoadInitialNodesFromDB --- discv5/protocol/handler.go | 4 ++++ nodes/flattable.go | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/discv5/protocol/handler.go b/discv5/protocol/handler.go index 3d3a256..cc8987f 100644 --- a/discv5/protocol/handler.go +++ b/discv5/protocol/handler.go @@ -704,6 +704,10 @@ func (h *Handler) handleWHOAREYOUPacket(packet *Packet, from *net.UDPAddr, local } } + if sess.GetNode() == nil && remoteNode != nil { + sess.SetNode(remoteNode) + } + h.config.Sessions.Put(sess) // Call OnHandshakeComplete callback for outgoing handshake diff --git a/nodes/flattable.go b/nodes/flattable.go index a412713..98e4c76 100644 --- a/nodes/flattable.go +++ b/nodes/flattable.go @@ -195,7 +195,14 @@ func (t *FlatTable) LoadInitialNodesFromDB() error { // Load random nodes from DB to bootstrap the active pool randomNodes := t.db.LoadRandomNodes(t.maxActiveNodes) + t.mu.Lock() + defer t.mu.Unlock() + for _, n := range randomNodes { + if _, exists := t.activeNodes[n.ID()]; exists { + continue + } + if t.ipLimiter.CanAdd(n) { t.activeNodes[n.ID()] = n t.ipLimiter.Add(n) From e10a691b495f9b7b5d609a4475b6f4f3fd45a564 Mon Sep 17 00:00:00 2001 From: Chase Wright Date: Thu, 16 Jul 2026 18:30:20 -0500 Subject: [PATCH 2/2] Re-admit demoted nodes to the active pool on traffic --- bootnode/service.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bootnode/service.go b/bootnode/service.go index b28017b..ca3d6ef 100644 --- a/bootnode/service.go +++ b/bootnode/service.go @@ -1046,12 +1046,15 @@ func (s *Service) onNodeSeen(n *v5node.Node, timestamp time.Time) { // Look up the generic node from the table if genericNode := s.elTable.Get(nodeID); genericNode != nil { genericNode.SetLastSeen(timestamp) // This marks it dirty + // Get falls back to the DB, so Add re-admits demoted nodes + s.elTable.Add(genericNode) s.elNodeDB.QueueUpdate(genericNode) } } else if s.enrManager.FilterCLNode(n.Record()) && s.clTable != nil && s.clNodeDB != nil { // Look up the generic node from the table if genericNode := s.clTable.Get(nodeID); genericNode != nil { genericNode.SetLastSeen(timestamp) // This marks it dirty + s.clTable.Add(genericNode) s.clNodeDB.QueueUpdate(genericNode) } }