From 44c3adb367489e51e021a8fcffab595440bf95b3 Mon Sep 17 00:00:00 2001 From: Nishant Das Date: Fri, 18 Dec 2020 02:03:18 +0800 Subject: [PATCH] Add Public Method To Retrieve Discovery Address (#8143) * add method * fix Co-authored-by: Raul Jordan Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com> --- beacon-chain/p2p/discovery.go | 12 ++++++++++- beacon-chain/p2p/discovery_test.go | 22 ++++++++++++++++++++ beacon-chain/p2p/interfaces.go | 2 ++ beacon-chain/p2p/options.go | 6 +++--- beacon-chain/p2p/service.go | 9 ++++++++ beacon-chain/p2p/testing/fuzz_p2p.go | 5 +++++ beacon-chain/p2p/testing/mock_peermanager.go | 6 ++++++ beacon-chain/p2p/testing/p2p.go | 5 +++++ 8 files changed, 63 insertions(+), 4 deletions(-) diff --git a/beacon-chain/p2p/discovery.go b/beacon-chain/p2p/discovery.go index f508b88b4..1d1e0563e 100644 --- a/beacon-chain/p2p/discovery.go +++ b/beacon-chain/p2p/discovery.go @@ -358,7 +358,17 @@ func convertToSingleMultiAddr(node *enode.Node) (ma.Multiaddr, error) { if err != nil { return nil, errors.Wrap(err, "could not get peer id") } - return multiAddressBuilderWithID(node.IP().String(), uint(node.TCP()), id) + return multiAddressBuilderWithID(node.IP().String(), "tcp", uint(node.TCP()), id) +} + +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) } func peersFromStringAddrs(addrs []string) ([]ma.Multiaddr, error) { diff --git a/beacon-chain/p2p/discovery_test.go b/beacon-chain/p2p/discovery_test.go index b462edfac..4a460c82e 100644 --- a/beacon-chain/p2p/discovery_test.go +++ b/beacon-chain/p2p/discovery_test.go @@ -9,6 +9,7 @@ import ( "os" "path" "strconv" + "strings" "testing" "time" @@ -264,6 +265,27 @@ func TestInboundPeerLimit(t *testing.T) { require.Equal(t, true, s.isPeerAtLimit(true), "not at limit for inbound peers") } +func TestUDPMultiAddress(t *testing.T) { + port := 6500 + ipAddr, pkey := createAddrAndPrivKey(t) + genesisTime := time.Now() + genesisValidatorsRoot := make([]byte, 32) + s := &Service{ + cfg: &Config{UDPPort: uint(port)}, + genesisTime: genesisTime, + genesisValidatorsRoot: genesisValidatorsRoot, + } + listener, err := s.createListener(ipAddr, pkey) + require.NoError(t, err) + defer listener.Close() + s.dv5Listener = listener + + multiAddress, err := s.DiscoveryAddress() + 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")) +} + // addPeer is a helper to add a peer with a given connection state) func addPeer(t *testing.T, p *peers.Status, state peerdata.PeerConnectionState) peer.ID { // Set up some peers with different states diff --git a/beacon-chain/p2p/interfaces.go b/beacon-chain/p2p/interfaces.go index fcc0d4dbc..c5d0d7629 100644 --- a/beacon-chain/p2p/interfaces.go +++ b/beacon-chain/p2p/interfaces.go @@ -10,6 +10,7 @@ import ( "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/multiformats/go-multiaddr" ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" "github.com/prysmaticlabs/prysm/beacon-chain/p2p/encoder" "github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers" @@ -73,6 +74,7 @@ type PeerManager interface { PeerID() peer.ID Host() host.Host ENR() *enr.Record + DiscoveryAddress() (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) diff --git a/beacon-chain/p2p/options.go b/beacon-chain/p2p/options.go index 4fa3bbd88..d3bb85d79 100644 --- a/beacon-chain/p2p/options.go +++ b/beacon-chain/p2p/options.go @@ -85,7 +85,7 @@ func multiAddressBuilder(ipAddr string, port uint) (ma.Multiaddr, error) { return ma.NewMultiaddr(fmt.Sprintf("/ip6/%s/tcp/%d", ipAddr, port)) } -func multiAddressBuilderWithID(ipAddr string, port uint, id peer.ID) (ma.Multiaddr, error) { +func multiAddressBuilderWithID(ipAddr, protocol string, port uint, id peer.ID) (ma.Multiaddr, error) { parsedIP := net.ParseIP(ipAddr) if parsedIP.To4() == nil && parsedIP.To16() == nil { return nil, errors.Errorf("invalid ip address provided: %s", ipAddr) @@ -94,9 +94,9 @@ func multiAddressBuilderWithID(ipAddr string, port uint, id peer.ID) (ma.Multiad return nil, errors.New("empty peer id given") } if parsedIP.To4() != nil { - return ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", ipAddr, port, id.String())) + return ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/%s/%d/p2p/%s", ipAddr, protocol, port, id.String())) } - return ma.NewMultiaddr(fmt.Sprintf("/ip6/%s/tcp/%d/p2p/%s", ipAddr, port, id.String())) + return ma.NewMultiaddr(fmt.Sprintf("/ip6/%s/%s/%d/p2p/%s", ipAddr, protocol, port, id.String())) } // Adds a private key to the libp2p option if the option was provided. diff --git a/beacon-chain/p2p/service.go b/beacon-chain/p2p/service.go index 5481cc64d..7a3f2b449 100644 --- a/beacon-chain/p2p/service.go +++ b/beacon-chain/p2p/service.go @@ -327,6 +327,15 @@ 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) { + if s.dv5Listener == nil { + return nil, nil + } + return convertToUdpMultiAddr(s.dv5Listener.Self()) +} + // Metadata returns a copy of the peer's metadata. func (s *Service) Metadata() *pb.MetaData { return proto.Clone(s.metaData).(*pb.MetaData) diff --git a/beacon-chain/p2p/testing/fuzz_p2p.go b/beacon-chain/p2p/testing/fuzz_p2p.go index 3ccf4e1aa..51467b174 100644 --- a/beacon-chain/p2p/testing/fuzz_p2p.go +++ b/beacon-chain/p2p/testing/fuzz_p2p.go @@ -56,6 +56,11 @@ func (p *FakeP2P) ENR() *enr.Record { return new(enr.Record) } +// DiscoveryAddress -- fake +func (p *FakeP2P) DiscoveryAddress() (multiaddr.Multiaddr, error) { + return nil, nil +} + // FindPeersWithSubnet mocks the p2p func. func (p *FakeP2P) FindPeersWithSubnet(_ context.Context, _ string, _, _ uint64) (bool, error) { return false, nil diff --git a/beacon-chain/p2p/testing/mock_peermanager.go b/beacon-chain/p2p/testing/mock_peermanager.go index 01193d7ab..4551f1218 100644 --- a/beacon-chain/p2p/testing/mock_peermanager.go +++ b/beacon-chain/p2p/testing/mock_peermanager.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" + "github.com/multiformats/go-multiaddr" ) // MockPeerManager is mock of the PeerManager interface. @@ -35,6 +36,11 @@ func (m MockPeerManager) ENR() *enr.Record { return m.Enr } +// DiscoveryAddress . +func (m MockPeerManager) DiscoveryAddress() (multiaddr.Multiaddr, error) { + return nil, nil +} + // RefreshENR . func (m MockPeerManager) RefreshENR() {} diff --git a/beacon-chain/p2p/testing/p2p.go b/beacon-chain/p2p/testing/p2p.go index 64a161ea4..a7b4f5839 100644 --- a/beacon-chain/p2p/testing/p2p.go +++ b/beacon-chain/p2p/testing/p2p.go @@ -236,6 +236,11 @@ func (p *TestP2P) ENR() *enr.Record { return new(enr.Record) } +// DiscoveryAddress -- +func (p *TestP2P) DiscoveryAddress() (multiaddr.Multiaddr, error) { + return nil, nil +} + // AddConnectionHandler handles the connection with a newly connected peer. func (p *TestP2P) AddConnectionHandler(f, _ func(ctx context.Context, id peer.ID) error) { p.BHost.Network().Notify(&network.NotifyBundle{