From f8155b9d2a4c25191f8c0bebb7c086ac8a265bfe Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Mon, 20 Apr 2026 10:37:07 +0000 Subject: [PATCH] cmd/devp2p/v5test: test unsolicited NODES hygiene --- cmd/devp2p/internal/v5test/discv5tests.go | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/cmd/devp2p/internal/v5test/discv5tests.go b/cmd/devp2p/internal/v5test/discv5tests.go index 233fdc9056..9644880a9a 100644 --- a/cmd/devp2p/internal/v5test/discv5tests.go +++ b/cmd/devp2p/internal/v5test/discv5tests.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/p2p/discover/v5wire" "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/netutil" ) @@ -58,6 +59,7 @@ func (s *Suite) AllTests() []utesting.Test { {Name: "FindnodeHandshake", Fn: s.TestFindnodeHandshake}, {Name: "FindnodeZeroDistance", Fn: s.TestFindnodeZeroDistance}, {Name: "FindnodeResults", Fn: s.TestFindnodeResults}, + {Name: "UnsolicitedNodes", Fn: s.TestUnsolicitedNodes}, } } @@ -318,6 +320,38 @@ func (s *Suite) TestFindnodeZeroDistance(t *utesting.T) { } } +func (s *Suite) TestUnsolicitedNodes(t *utesting.T) { + conn, l1 := s.listen1(t) + defer conn.close() + + // Establish session so the unsolicited packet is well-formed and authenticated. + ping := &v5wire.Ping{ReqID: conn.nextReqID()} + if resp := conn.reqresp(l1, ping); resp.Kind() != v5wire.PongMsg { + t.Fatal("expected PONG, got", resp) + } + + fakeConn, fakeL := s.listen1(t) + defer fakeConn.close() + fakeConn.setEndpoint(fakeL) + + unsolicited := &v5wire.Nodes{ + ReqID: conn.nextReqID(), + RespCount: 1, + Nodes: []*enr.Record{fakeConn.localNode.Node().Record()}, + } + conn.write(l1, unsolicited, nil) + + results, err := conn.findnode(l1, []uint{uint(enode.LogDist(fakeConn.localNode.ID(), s.Dest.ID()))}) + if err != nil { + t.Fatal(err) + } + for _, n := range results { + if n.ID() == fakeConn.localNode.ID() { + t.Fatal("FINDNODE result contains node from unsolicited NODES response") + } + } +} + func (s *Suite) TestFindnodeResults(t *utesting.T) { t.Log(`This test pings the node under test from multiple other endpoints and node identities (the 'bystanders'). After waiting for them to be accepted into the remote table, the test checks