p2p/discover: add helper methods to UDPv5 (#20918)

This adds two new methods to UDPv5, AllNodes and LocalNode.

AllNodes returns all the nodes stored in the local table; this is
useful for the purposes of metrics collection and also debugging any
potential issues with other discovery v5 implementations.

LocalNode returns the local node object. The reason for exposing this
is so that users can modify and set/delete new key-value entries in
the local record.
This commit is contained in:
Nishant Das 2020-04-16 21:58:37 +08:00 committed by GitHub
parent 3bf1054a13
commit 7a63faf734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 0 deletions

@ -216,6 +216,26 @@ func (t *UDPv5) Resolve(n *enode.Node) *enode.Node {
return n return n
} }
// AllNodes returns all the nodes stored in the local table.
func (t *UDPv5) AllNodes() []*enode.Node {
t.tab.mutex.Lock()
defer t.tab.mutex.Unlock()
nodes := make([]*enode.Node, 0)
for _, b := range &t.tab.buckets {
for _, n := range b.entries {
nodes = append(nodes, unwrapNode(n))
}
}
return nodes
}
// LocalNode returns the current local node running the
// protocol.
func (t *UDPv5) LocalNode() *enode.LocalNode {
return t.localNode
}
func (t *UDPv5) RandomNodes() enode.Iterator { func (t *UDPv5) RandomNodes() enode.Iterator {
if t.tab.len() == 0 { if t.tab.len() == 0 {
// All nodes were dropped, refresh. The very first query will hit this // All nodes were dropped, refresh. The very first query will hit this

@ -445,6 +445,28 @@ func TestUDPv5_lookup(t *testing.T) {
checkLookupResults(t, lookupTestnet, <-resultC) checkLookupResults(t, lookupTestnet, <-resultC)
} }
// This test checks the local node can be utilised to set key-values.
func TestUDPv5_LocalNode(t *testing.T) {
t.Parallel()
var cfg Config
node := startLocalhostV5(t, cfg)
defer node.Close()
localNd := node.LocalNode()
// set value in node's local record
testVal := [4]byte{'A', 'B', 'C', 'D'}
localNd.Set(enr.WithEntry("testing", &testVal))
// retrieve the value from self to make sure it matches.
outputVal := [4]byte{}
if err := node.Self().Load(enr.WithEntry("testing", &outputVal)); err != nil {
t.Errorf("Could not load value from record: %v", err)
}
if testVal != outputVal {
t.Errorf("Wanted %#x to be retrieved from the record but instead got %#x", testVal, outputVal)
}
}
// udpV5Test is the framework for all tests above. // udpV5Test is the framework for all tests above.
// It runs the UDPv5 transport on a virtual socket and allows testing outgoing packets. // It runs the UDPv5 transport on a virtual socket and allows testing outgoing packets.
type udpV5Test struct { type udpV5Test struct {