Multiple discovery addresses (#8203)

* multiple discovery addresses

* ipv6 fix

* make len test more robust

* create enr node for testing

* use local node for test

* use mockListener

* remove unused type alias
This commit is contained in:
Radosław Kapka
2021-01-07 14:35:42 +01:00
committed by GitHub
parent 1b6a0703e3
commit 353c1f6387
8 changed files with 64 additions and 18 deletions

View File

@@ -361,14 +361,33 @@ func convertToSingleMultiAddr(node *enode.Node) (ma.Multiaddr, error) {
return multiAddressBuilderWithID(node.IP().String(), "tcp", uint(node.TCP()), id)
}
func convertToUdpMultiAddr(node *enode.Node) (ma.Multiaddr, error) {
func convertToUdpMultiAddr(node *enode.Node) ([]ma.Multiaddr, error) {
pubkey := node.Pubkey()
assertedKey := convertToInterfacePubkey(pubkey)
id, err := peer.IDFromPublicKey(assertedKey)
if err != nil {
return nil, errors.Wrap(err, "could not get peer id")
}
return multiAddressBuilderWithID(node.IP().String(), "udp", uint(node.UDP()), id)
var addresses []ma.Multiaddr
var ip4 enr.IPv4
var ip6 enr.IPv6
if node.Load(&ip4) == nil {
address, ipErr := multiAddressBuilderWithID(net.IP(ip4).String(), "udp", uint(node.UDP()), id)
if ipErr != nil {
return nil, errors.Wrap(ipErr, "could not build IPv4 address")
}
addresses = append(addresses, address)
}
if node.Load(&ip6) == nil {
address, ipErr := multiAddressBuilderWithID(net.IP(ip6).String(), "udp", uint(node.UDP()), id)
if ipErr != nil {
return nil, errors.Wrap(ipErr, "could not build IPv6 address")
}
addresses = append(addresses, address)
}
return addresses, nil
}
func peersFromStringAddrs(addrs []string) ([]ma.Multiaddr, error) {

View File

@@ -280,10 +280,36 @@ func TestUDPMultiAddress(t *testing.T) {
defer listener.Close()
s.dv5Listener = listener
multiAddress, err := s.DiscoveryAddress()
multiAddresses, err := s.DiscoveryAddresses()
require.NoError(t, err)
assert.Equal(t, true, strings.Contains(multiAddress.String(), fmt.Sprintf("%d", port)))
assert.Equal(t, true, strings.Contains(multiAddress.String(), "udp"))
require.Equal(t, true, len(multiAddresses) > 0)
assert.Equal(t, true, strings.Contains(multiAddresses[0].String(), fmt.Sprintf("%d", port)))
assert.Equal(t, true, strings.Contains(multiAddresses[0].String(), "udp"))
}
func TestMultipleDiscoveryAddresses(t *testing.T) {
db, err := enode.OpenDB(t.TempDir())
require.NoError(t, err)
_, key := createAddrAndPrivKey(t)
node := enode.NewLocalNode(db, key)
node.Set(enr.IPv4{127, 0, 0, 1})
node.Set(enr.IPv6{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68})
s := &Service{dv5Listener: mockListener{localNode: node}}
multiAddresses, err := s.DiscoveryAddresses()
require.NoError(t, err)
require.Equal(t, 2, len(multiAddresses))
ipv4Found, ipv6Found := false, false
for _, address := range multiAddresses {
s := address.String()
if strings.Contains(s, "ip4") {
ipv4Found = true
} else if strings.Contains(s, "ip6") {
ipv6Found = true
}
}
assert.Equal(t, true, ipv4Found, "IPv4 discovery address not found")
assert.Equal(t, true, ipv6Found, "IPv6 discovery address not found")
}
// addPeer is a helper to add a peer with a given connection state)

View File

@@ -74,7 +74,7 @@ type PeerManager interface {
PeerID() peer.ID
Host() host.Host
ENR() *enr.Record
DiscoveryAddress() (multiaddr.Multiaddr, error)
DiscoveryAddresses() ([]multiaddr.Multiaddr, error)
RefreshENR()
FindPeersWithSubnet(ctx context.Context, topic string, index, threshold uint64) (bool, error)
AddPingMethod(reqFunc func(ctx context.Context, id peer.ID) error)

View File

@@ -327,9 +327,8 @@ func (s *Service) ENR() *enr.Record {
return s.dv5Listener.Self().Record()
}
// DiscoveryAddress is the multiaddress representation of
// our enr.
func (s *Service) DiscoveryAddress() (multiaddr.Multiaddr, error) {
// DiscoveryAddresses represents our enr addresses as multiaddresses.
func (s *Service) DiscoveryAddresses() ([]multiaddr.Multiaddr, error) {
if s.dv5Listener == nil {
return nil, nil
}

View File

@@ -30,10 +30,12 @@ import (
logTest "github.com/sirupsen/logrus/hooks/test"
)
type mockListener struct{}
type mockListener struct {
localNode *enode.LocalNode
}
func (mockListener) Self() *enode.Node {
panic("implement me")
func (m mockListener) Self() *enode.Node {
return m.localNode.Node()
}
func (mockListener) Close() {

View File

@@ -56,8 +56,8 @@ func (p *FakeP2P) ENR() *enr.Record {
return new(enr.Record)
}
// DiscoveryAddress -- fake
func (p *FakeP2P) DiscoveryAddress() (multiaddr.Multiaddr, error) {
// DiscoveryAddresses -- fake
func (p *FakeP2P) DiscoveryAddresses() ([]multiaddr.Multiaddr, error) {
return nil, nil
}

View File

@@ -36,8 +36,8 @@ func (m MockPeerManager) ENR() *enr.Record {
return m.Enr
}
// DiscoveryAddress .
func (m MockPeerManager) DiscoveryAddress() (multiaddr.Multiaddr, error) {
// DiscoveryAddresses .
func (m MockPeerManager) DiscoveryAddresses() ([]multiaddr.Multiaddr, error) {
return nil, nil
}

View File

@@ -236,8 +236,8 @@ func (p *TestP2P) ENR() *enr.Record {
return new(enr.Record)
}
// DiscoveryAddress --
func (p *TestP2P) DiscoveryAddress() (multiaddr.Multiaddr, error) {
// DiscoveryAddresses --
func (p *TestP2P) DiscoveryAddresses() ([]multiaddr.Multiaddr, error) {
return nil, nil
}