Skip to content

Commit 6caa606

Browse files
fjlDergarcon
authored andcommitted
p2p/discover: add liveness check in collectTableNodes (ethereum#28686)
* p2p/discover: add liveness check in collectTableNodes * p2p/discover: fix test * p2p/discover: rename to appendLiveNodes * p2p/discover: add dedup logic back * p2p/discover: simplify * p2p/discover: fix issue found by test
1 parent b09ad08 commit 6caa606

File tree

7 files changed

+37
-23
lines changed

7 files changed

+37
-23
lines changed

p2p/discover/table.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,26 @@ func (tab *Table) findnodeByID(target enode.ID, nresults int, preferLive bool) *
459459
return nodes
460460
}
461461

462+
// appendLiveNodes adds nodes at the given distance to the result slice.
463+
func (tab *Table) appendLiveNodes(dist uint, result []*enode.Node) []*enode.Node {
464+
if dist > 256 {
465+
return result
466+
}
467+
if dist == 0 {
468+
return append(result, tab.self())
469+
}
470+
471+
tab.mutex.Lock()
472+
defer tab.mutex.Unlock()
473+
for _, n := range tab.bucketAtDistance(int(dist)).entries {
474+
if n.livenessChecks >= 1 {
475+
node := n.Node // avoid handing out pointer to struct field
476+
result = append(result, &node)
477+
}
478+
}
479+
return result
480+
}
481+
462482
// len returns the number of nodes in the table.
463483
func (tab *Table) len() (n int) {
464484
tab.mutex.Lock()

p2p/discover/table_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ func TestTable_findnodeByID(t *testing.T) {
199199
tab, db := newTestTable(transport)
200200
defer db.Close()
201201
defer tab.close()
202-
fillTable(tab, test.All)
202+
fillTable(tab, test.All, true)
203203

204204
// check that closest(Target, N) returns nodes
205205
result := tab.findnodeByID(test.Target, test.N, false).entries

p2p/discover/table_util_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,11 @@ func fillBucket(tab *Table, n *node) (last *node) {
109109

110110
// fillTable adds nodes the table to the end of their corresponding bucket
111111
// if the bucket is not full. The caller must not hold tab.mutex.
112-
func fillTable(tab *Table, nodes []*node) {
112+
func fillTable(tab *Table, nodes []*node, setLive bool) {
113113
for _, n := range nodes {
114+
if setLive {
115+
n.livenessChecks = 1
116+
}
114117
tab.addSeenNode(n)
115118
}
116119
}

p2p/discover/v4_lookup_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func TestUDPv4_Lookup(t *testing.T) {
4040
}
4141

4242
// Seed table with initial node.
43-
fillTable(test.table, []*node{wrapNode(lookupTestnet.node(256, 0))})
43+
fillTable(test.table, []*node{wrapNode(lookupTestnet.node(256, 0))}, true)
4444

4545
// Start the lookup.
4646
resultC := make(chan []*enode.Node, 1)
@@ -74,7 +74,7 @@ func TestUDPv4_LookupIterator(t *testing.T) {
7474
for i := range lookupTestnet.dists[256] {
7575
bootnodes[i] = wrapNode(lookupTestnet.node(256, i))
7676
}
77-
fillTable(test.table, bootnodes)
77+
fillTable(test.table, bootnodes, true)
7878
go serveTestnet(test, lookupTestnet)
7979

8080
// Create the iterator and collect the nodes it yields.
@@ -109,7 +109,7 @@ func TestUDPv4_LookupIteratorClose(t *testing.T) {
109109
for i := range lookupTestnet.dists[256] {
110110
bootnodes[i] = wrapNode(lookupTestnet.node(256, i))
111111
}
112-
fillTable(test.table, bootnodes)
112+
fillTable(test.table, bootnodes, true)
113113
go serveTestnet(test, lookupTestnet)
114114

115115
it := test.udp.RandomNodes()

p2p/discover/v4_udp_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func TestUDPv4_findnode(t *testing.T) {
269269
}
270270
nodes.push(n, numCandidates)
271271
}
272-
fillTable(test.table, nodes.entries)
272+
fillTable(test.table, nodes.entries, false)
273273

274274
// ensure there's a bond with the test node,
275275
// findnode won't be accepted otherwise.

p2p/discover/v5_udp.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ func (t *UDPv5) handleFindnode(p *v5wire.Findnode, fromID enode.ID, fromAddr *ne
851851

852852
// collectTableNodes creates a FINDNODE result set for the given distances.
853853
func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*enode.Node {
854+
var bn []*enode.Node
854855
var nodes []*enode.Node
855856
var processed = make(map[uint]struct{})
856857
for _, dist := range distances {
@@ -859,21 +860,11 @@ func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*en
859860
if seen || dist > 256 {
860861
continue
861862
}
862-
863-
// Get the nodes.
864-
var bn []*enode.Node
865-
if dist == 0 {
866-
bn = []*enode.Node{t.Self()}
867-
} else if dist <= 256 {
868-
t.tab.mutex.Lock()
869-
bn = unwrapNodes(t.tab.bucketAtDistance(int(dist)).entries)
870-
t.tab.mutex.Unlock()
871-
}
872863
processed[dist] = struct{}{}
873864

874-
// Apply some pre-checks to avoid sending invalid nodes.
875-
for _, n := range bn {
876-
// TODO livenessChecks > 1
865+
for _, n := range t.tab.appendLiveNodes(dist, bn[:0]) {
866+
// Apply some pre-checks to avoid sending invalid nodes.
867+
// Note liveness is checked by appendLiveNodes.
877868
if netutil.CheckRelayIP(rip, n.IP()) != nil {
878869
continue
879870
}

p2p/discover/v5_udp_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ func TestUDPv5_findnodeHandling(t *testing.T) {
159159
nodes253 := nodesAtDistance(test.table.self().ID(), 253, 16)
160160
nodes249 := nodesAtDistance(test.table.self().ID(), 249, 4)
161161
nodes248 := nodesAtDistance(test.table.self().ID(), 248, 10)
162-
fillTable(test.table, wrapNodes(nodes253))
163-
fillTable(test.table, wrapNodes(nodes249))
164-
fillTable(test.table, wrapNodes(nodes248))
162+
fillTable(test.table, wrapNodes(nodes253), true)
163+
fillTable(test.table, wrapNodes(nodes249), true)
164+
fillTable(test.table, wrapNodes(nodes248), true)
165165

166166
// Requesting with distance zero should return the node's own record.
167167
test.packetIn(&v5wire.Findnode{ReqID: []byte{0}, Distances: []uint{0}})
@@ -589,7 +589,7 @@ func TestUDPv5_lookup(t *testing.T) {
589589

590590
// Seed table with initial node.
591591
initialNode := lookupTestnet.node(256, 0)
592-
fillTable(test.table, []*node{wrapNode(initialNode)})
592+
fillTable(test.table, []*node{wrapNode(initialNode)}, true)
593593

594594
// Start the lookup.
595595
resultC := make(chan []*enode.Node, 1)

0 commit comments

Comments
 (0)