Skip to content

Commit 3a013d8

Browse files
GrapeBaBasivaratrisrinivas
authored andcommitted
p2p/discover: expose discv5 functions for portal JSON-RPC interface (ethereum#31117)
Fixes ethereum#31093 Here we add some API functions on the UDPv5 object for the purpose of implementing the Portal Network JSON-RPC API in the shisui client. --------- Signed-off-by: Chen Kai <[email protected]>
1 parent 912d4ca commit 3a013d8

File tree

6 files changed

+92
-26
lines changed

6 files changed

+92
-26
lines changed

cmd/devp2p/discv4cmd.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func discv4Ping(ctx *cli.Context) error {
163163
defer disc.Close()
164164

165165
start := time.Now()
166-
if err := disc.Ping(n); err != nil {
166+
if _, err := disc.Ping(n); err != nil {
167167
return fmt.Errorf("node didn't respond: %v", err)
168168
}
169169
fmt.Printf("node responded to ping (RTT %v).\n", time.Since(start))

cmd/devp2p/discv5cmd.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ func discv5Ping(ctx *cli.Context) error {
8484
disc, _ := startV5(ctx)
8585
defer disc.Close()
8686

87-
fmt.Println(disc.Ping(n))
87+
_, err := disc.Ping(n)
88+
fmt.Println(err)
8889
return nil
8990
}
9091

p2p/discover/table.go

+8
Original file line numberDiff line numberDiff line change
@@ -694,3 +694,11 @@ func pushNode(list []*tableNode, n *tableNode, max int) ([]*tableNode, *tableNod
694694
list[0] = n
695695
return list, removed
696696
}
697+
698+
// deleteNode removes a node from the table.
699+
func (tab *Table) deleteNode(n *enode.Node) {
700+
tab.mutex.Lock()
701+
defer tab.mutex.Unlock()
702+
b := tab.bucket(n.ID())
703+
tab.deleteInBucket(b, n.ID())
704+
}

p2p/discover/v4_udp.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,6 @@ func (t *UDPv4) ourEndpoint() v4wire.Endpoint {
210210
return v4wire.NewEndpoint(addr, uint16(node.TCP()))
211211
}
212212

213-
// Ping sends a ping message to the given node.
214-
func (t *UDPv4) Ping(n *enode.Node) error {
215-
_, err := t.ping(n)
216-
return err
217-
}
218-
219213
// ping sends a ping message to the given node and waits for a reply.
220214
func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {
221215
addr, ok := n.UDPEndpoint()
@@ -229,6 +223,19 @@ func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {
229223
return seq, err
230224
}
231225

226+
// Ping calls PING on a node and waits for a PONG response.
227+
func (t *UDPv4) Ping(n *enode.Node) (pong *v4wire.Pong, err error) {
228+
addr, ok := n.UDPEndpoint()
229+
if !ok {
230+
return nil, errNoUDPEndpoint
231+
}
232+
rm := t.sendPing(n.ID(), addr, nil)
233+
if err = <-rm.errc; err == nil {
234+
pong = rm.reply.(*v4wire.Pong)
235+
}
236+
return pong, err
237+
}
238+
232239
// sendPing sends a ping message to the given node and invokes the callback
233240
// when the reply arrives.
234241
func (t *UDPv4) sendPing(toid enode.ID, toaddr netip.AddrPort, callback func()) *replyMatcher {

p2p/discover/v5_udp.go

+66-16
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,6 @@ func (t *UDPv5) Close() {
200200
})
201201
}
202202

203-
// Ping sends a ping message to the given node.
204-
func (t *UDPv5) Ping(n *enode.Node) error {
205-
_, err := t.ping(n)
206-
return err
207-
}
208-
209203
// Resolve searches for a specific node with the given ID and tries to get the most recent
210204
// version of the node record for it. It returns n if the node could not be resolved.
211205
func (t *UDPv5) Resolve(n *enode.Node) *enode.Node {
@@ -226,6 +220,36 @@ func (t *UDPv5) Resolve(n *enode.Node) *enode.Node {
226220
return n
227221
}
228222

223+
// ResolveNodeId searches for a specific Node with the given ID.
224+
// It returns nil if the nodeId could not be resolved.
225+
func (t *UDPv5) ResolveNodeId(id enode.ID) *enode.Node {
226+
if id == t.Self().ID() {
227+
return t.Self()
228+
}
229+
230+
n := t.tab.getNode(id)
231+
if n != nil {
232+
// Try asking directly. This works if the Node is still responding on the endpoint we have.
233+
if resp, err := t.RequestENR(n); err == nil {
234+
return resp
235+
}
236+
}
237+
238+
// Otherwise do a network lookup.
239+
result := t.Lookup(id)
240+
for _, rn := range result {
241+
if rn.ID() == id {
242+
if n != nil && rn.Seq() <= n.Seq() {
243+
return n
244+
} else {
245+
return rn
246+
}
247+
}
248+
}
249+
250+
return n
251+
}
252+
229253
// AllNodes returns all the nodes stored in the local table.
230254
func (t *UDPv5) AllNodes() []*enode.Node {
231255
t.tab.mutex.Lock()
@@ -240,7 +264,18 @@ func (t *UDPv5) AllNodes() []*enode.Node {
240264
return nodes
241265
}
242266

243-
// LocalNode returns the current local node running the
267+
// AddKnownNode adds a node to the routing table.
268+
// The function should be used for testing only.
269+
func (t *UDPv5) AddKnownNode(n *enode.Node) bool {
270+
return t.tab.addFoundNode(n, true)
271+
}
272+
273+
// DeleteNode removes a node from the routing table. Used for Portal discv5 DeleteEnr API.
274+
func (t *UDPv5) DeleteNode(n *enode.Node) {
275+
t.tab.deleteNode(n)
276+
}
277+
278+
// LocalNode returns the current local Node running the
244279
// protocol.
245280
func (t *UDPv5) LocalNode() *enode.LocalNode {
246281
return t.localNode
@@ -328,7 +363,7 @@ func (t *UDPv5) lookupWorker(destNode *enode.Node, target enode.ID) ([]*enode.No
328363
err error
329364
)
330365
var r []*enode.Node
331-
r, err = t.findnode(destNode, dists)
366+
r, err = t.Findnode(destNode, dists)
332367
if errors.Is(err, errClosed) {
333368
return nil, err
334369
}
@@ -359,21 +394,31 @@ func lookupDistances(target, dest enode.ID) (dists []uint) {
359394

360395
// ping calls PING on a node and waits for a PONG response.
361396
func (t *UDPv5) ping(n *enode.Node) (uint64, error) {
397+
pong, err := t.Ping(n)
398+
if err != nil {
399+
return 0, err
400+
}
401+
402+
return pong.ENRSeq, nil
403+
}
404+
405+
// Ping calls PING on a node and waits for a PONG response.
406+
func (t *UDPv5) Ping(n *enode.Node) (*v5wire.Pong, error) {
362407
req := &v5wire.Ping{ENRSeq: t.localNode.Node().Seq()}
363408
resp := t.callToNode(n, v5wire.PongMsg, req)
364409
defer t.callDone(resp)
365410

366411
select {
367412
case pong := <-resp.ch:
368-
return pong.(*v5wire.Pong).ENRSeq, nil
413+
return pong.(*v5wire.Pong), nil
369414
case err := <-resp.err:
370-
return 0, err
415+
return nil, err
371416
}
372417
}
373418

374419
// RequestENR requests n's record.
375420
func (t *UDPv5) RequestENR(n *enode.Node) (*enode.Node, error) {
376-
nodes, err := t.findnode(n, []uint{0})
421+
nodes, err := t.Findnode(n, []uint{0})
377422
if err != nil {
378423
return nil, err
379424
}
@@ -383,8 +428,8 @@ func (t *UDPv5) RequestENR(n *enode.Node) (*enode.Node, error) {
383428
return nodes[0], nil
384429
}
385430

386-
// findnode calls FINDNODE on a node and waits for responses.
387-
func (t *UDPv5) findnode(n *enode.Node, distances []uint) ([]*enode.Node, error) {
431+
// Findnode calls FINDNODE on a node and waits for responses.
432+
func (t *UDPv5) Findnode(n *enode.Node, distances []uint) ([]*enode.Node, error) {
388433
resp := t.callToNode(n, v5wire.NodesMsg, &v5wire.Findnode{Distances: distances})
389434
return t.waitForNodes(resp, distances)
390435
}
@@ -736,8 +781,8 @@ func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr netip.AddrPort, p v
736781
return true
737782
}
738783

739-
// getNode looks for a node record in table and database.
740-
func (t *UDPv5) getNode(id enode.ID) *enode.Node {
784+
// GetNode looks for a node record in table and database.
785+
func (t *UDPv5) GetNode(id enode.ID) *enode.Node {
741786
if n := t.tab.getNode(id); n != nil {
742787
return n
743788
}
@@ -747,6 +792,11 @@ func (t *UDPv5) getNode(id enode.ID) *enode.Node {
747792
return nil
748793
}
749794

795+
// Nodes returns the nodes in the routing table.
796+
func (t *UDPv5) Nodes() [][]BucketNode {
797+
return t.tab.Nodes()
798+
}
799+
750800
// handle processes incoming packets according to their message type.
751801
func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort) {
752802
switch p := p.(type) {
@@ -776,7 +826,7 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort
776826
func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) {
777827
challenge := &v5wire.Whoareyou{Nonce: p.Nonce}
778828
crand.Read(challenge.IDNonce[:])
779-
if n := t.getNode(fromID); n != nil {
829+
if n := t.GetNode(fromID); n != nil {
780830
challenge.Node = n
781831
challenge.RecordSeq = n.Seq()
782832
}

p2p/discover/v5_udp_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func TestUDPv5_findnodeCall(t *testing.T) {
288288
)
289289
go func() {
290290
var err error
291-
response, err = test.udp.findnode(remote, distances)
291+
response, err = test.udp.Findnode(remote, distances)
292292
done <- err
293293
}()
294294

@@ -398,7 +398,7 @@ func TestUDPv5_callTimeoutReset(t *testing.T) {
398398
done = make(chan error, 1)
399399
)
400400
go func() {
401-
_, err := test.udp.findnode(remote, []uint{distance})
401+
_, err := test.udp.Findnode(remote, []uint{distance})
402402
done <- err
403403
}()
404404

0 commit comments

Comments
 (0)