From 8e42a24faade3569090162889d7f0e184af3ff12 Mon Sep 17 00:00:00 2001 From: cheatfate Date: Fri, 4 Oct 2024 03:18:30 +0300 Subject: [PATCH 1/4] Attempt to fix issue with AnyLocal addresses in last-seen-p2p-address field. --- beacon_chain/rpc/rest_node_api.nim | 78 +++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index b96e0724be..31e8e0b038 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -7,6 +7,7 @@ {.push raises: [].} import + std/algorithm, stew/byteutils, chronicles, eth/p2p/discoveryv5/enr, @@ -97,15 +98,80 @@ proc toString(direction: PeerType): string = of PeerType.Outgoing: "outbound" +proc getProtocolArgument(ma: MultiAddress, + codec: MultiCodec): MaResult[seq[byte]] = + var buffer: seq[byte] + for item in ma: + let + ritem = ? item + code = ? ritem.protoCode() + if code == codec: + let arg = ? ritem.protoAddress() + return ok(arg) + err("Multiaddress codec has not been found") + proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = - # TODO (cheatfate): We need to provide filter here, which will be able to - # filter such multiaddresses like `/ip4/0.0.0.0` or local addresses or - # addresses with peer ids. - let addrs = node.network.switch.peerStore[AddressBook][id] - if len(addrs) > 0: - $addrs[len(addrs) - 1] + # Because `last_seen_p2p_address` is single address but libp2p reports lot of + # addresses, we going to sort list of addresses before selecting one. Here + # sort order list: + # 1. Globally routable IPv6 address. + # 2. Globally routable IPv4 address. + # 3. Non IPv4/IPv6 multiaddress. + # 4. Site-local IPv6 address. + # 5. Site-local IPv4 address. + # 6. Link-local IPv6 address. + # 7. Link-local IPv4 address. + # 8. Loopback IPv6 address. + # 9. Loopback IPv4 address. + # 10. All other IPv6 address types. + # 11. All other IPv4 address types. + proc compare( + a, b: tuple[address: MultiAddress, position: int] + ): int {.closure.} = cmp(a.position, b.position) + let addresses = node.network.switch.peerStore[AddressBook][id] + var temp: seq[tuple[address: MultiAddress, position: int]] + for address in addresses: + let res = + if IP4.matchPartial(address): + let address4 = address.getProtocolArgument(multiCodec("ip4")).valueOr: + continue + var ta4 = TransportAddress(family: AddressFamily.IPv4) + ta4.address_v4[0 .. 3] = address4[0 .. 3] + if ta4.isLoopback(): + (address, 9) + elif ta4.isLinkLocal(): + (address, 7) + elif ta4.isSiteLocal(): + (address, 5) + elif ta4.isGlobal(): + (address, 2) + else: + (address, 11) + elif IP6.matchPartial(address): + let address6 = address.getProtocolArgument(multiCodec("ip4")).valueOr: + continue + var ta6 = TransportAddress(family: AddressFamily.IPv4) + ta6.address_v6[0 .. 15] = address6[0 .. 15] + if ta6.isLoopback(): + (address, 8) + elif ta6.isLinkLocal(): + (address, 6) + elif ta6.isSiteLocal(): + (address, 4) + elif ta6.isGlobal(): + (address, 1) + else: + (address, 10) + else: + (address, 3) + temp.add(res) + + if len(temp) > 0: + sort(temp, compare, SortOrder.Ascending) + $temp[0].address else: "" + proc getDiscoveryAddresses(node: BeaconNode): seq[string] = let typedRec = TypedRecord.fromRecord(node.network.enrRecord()) From 5cc9d0aefc6de6ba6498a6be3ad5034a06d4f56c Mon Sep 17 00:00:00 2001 From: cheatfate Date: Fri, 4 Oct 2024 03:55:20 +0300 Subject: [PATCH 2/4] Address issues with IPv6 and QUIC protocol addresses. --- beacon_chain/rpc/rest_node_api.nim | 65 +++++++++++++++++------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index 31e8e0b038..2f7be73a67 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -132,37 +132,44 @@ proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = var temp: seq[tuple[address: MultiAddress, position: int]] for address in addresses: let res = - if IP4.matchPartial(address): - let address4 = address.getProtocolArgument(multiCodec("ip4")).valueOr: - continue - var ta4 = TransportAddress(family: AddressFamily.IPv4) - ta4.address_v4[0 .. 3] = address4[0 .. 3] - if ta4.isLoopback(): - (address, 9) - elif ta4.isLinkLocal(): - (address, 7) - elif ta4.isSiteLocal(): - (address, 5) - elif ta4.isGlobal(): - (address, 2) + if TCP.matchPartial(address): + # TODO (cheatfate): We match TCP here because `nim-libp2p` do not have + # QUIC support yet. So we give TCP addresses priority. + if IP4.matchPartial(address): + let address4 = address.getProtocolArgument(multiCodec("ip4")).valueOr: + continue + var ta4 = TransportAddress(family: AddressFamily.IPv4) + ta4.address_v4[0 .. 3] = address4[0 .. 3] + if ta4.isLoopback(): + (address, 9) + elif ta4.isLinkLocal(): + (address, 7) + elif ta4.isSiteLocal(): + (address, 5) + elif ta4.isGlobal(): + (address, 2) + else: + (address, 11) + elif IP6.matchPartial(address): + let address6 = address.getProtocolArgument(multiCodec("ip6")).valueOr: + continue + var ta6 = TransportAddress(family: AddressFamily.IPv4) + ta6.address_v6[0 .. 15] = address6[0 .. 15] + if ta6.isLoopback(): + (address, 8) + elif ta6.isLinkLocal(): + (address, 6) + elif ta6.isSiteLocal(): + (address, 4) + elif ta6.isGlobal(): + (address, 1) + else: + (address, 10) else: - (address, 11) - elif IP6.matchPartial(address): - let address6 = address.getProtocolArgument(multiCodec("ip4")).valueOr: - continue - var ta6 = TransportAddress(family: AddressFamily.IPv4) - ta6.address_v6[0 .. 15] = address6[0 .. 15] - if ta6.isLoopback(): - (address, 8) - elif ta6.isLinkLocal(): - (address, 6) - elif ta6.isSiteLocal(): - (address, 4) - elif ta6.isGlobal(): - (address, 1) - else: - (address, 10) + (address, 3) else: + # TODO (chatfate): As soon as QUIC protocol will be implemented in + # `nim-libp2p` - TCP prioritization should be dropped (address, 3) temp.add(res) From 170a1963dd6f531dfa5a4cfff3483fdc4fcbac47 Mon Sep 17 00:00:00 2001 From: cheatfate Date: Fri, 4 Oct 2024 04:11:47 +0300 Subject: [PATCH 3/4] Attempt to avoid QUIC addresses from site-local networks. --- beacon_chain/rpc/rest_node_api.nim | 78 ++++++++++++++++-------------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index 2f7be73a67..3780bab8ca 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -132,45 +132,51 @@ proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = var temp: seq[tuple[address: MultiAddress, position: int]] for address in addresses: let res = - if TCP.matchPartial(address): - # TODO (cheatfate): We match TCP here because `nim-libp2p` do not have - # QUIC support yet. So we give TCP addresses priority. - if IP4.matchPartial(address): - let address4 = address.getProtocolArgument(multiCodec("ip4")).valueOr: - continue - var ta4 = TransportAddress(family: AddressFamily.IPv4) - ta4.address_v4[0 .. 3] = address4[0 .. 3] - if ta4.isLoopback(): - (address, 9) - elif ta4.isLinkLocal(): - (address, 7) - elif ta4.isSiteLocal(): - (address, 5) - elif ta4.isGlobal(): - (address, 2) - else: - (address, 11) - elif IP6.matchPartial(address): - let address6 = address.getProtocolArgument(multiCodec("ip6")).valueOr: - continue - var ta6 = TransportAddress(family: AddressFamily.IPv4) - ta6.address_v6[0 .. 15] = address6[0 .. 15] - if ta6.isLoopback(): - (address, 8) - elif ta6.isLinkLocal(): - (address, 6) - elif ta6.isSiteLocal(): - (address, 4) - elif ta6.isGlobal(): - (address, 1) + block: + let + isUDP = UDP.matchPartial(address) + isTCP = TCP.matchPartial(address) + + if isUDP or isTCP: + # TODO (cheatfate): We match TCP here because `nim-libp2p` do not have + # QUIC support yet. So we give TCP addresses priority. + let boost = if isUDP: 100 else 0 + if IP4.matchPartial(address): + let address4 = + address.getProtocolArgument(multiCodec("ip4")).valueOr: + continue + var ta4 = TransportAddress(family: AddressFamily.IPv4) + ta4.address_v4[0 .. 3] = address4[0 .. 3] + if ta4.isLoopback(): + (address, boost + 9) + elif ta4.isLinkLocal(): + (address, boost + 7) + elif ta4.isSiteLocal(): + (address, boost + 5) + elif ta4.isGlobal(): + (address, boost + 2) + else: + (address, boost + 11) + elif IP6.matchPartial(address): + let address6 = + address.getProtocolArgument(multiCodec("ip6")).valueOr: + continue + var ta6 = TransportAddress(family: AddressFamily.IPv4) + ta6.address_v6[0 .. 15] = address6[0 .. 15] + if ta6.isLoopback(): + (address, boost + 8) + elif ta6.isLinkLocal(): + (address, boost + 6) + elif ta6.isSiteLocal(): + (address, boost + 4) + elif ta6.isGlobal(): + (address, boost + 1) + else: + (address, boost + 10) else: - (address, 10) + (address, boost + 3) else: (address, 3) - else: - # TODO (chatfate): As soon as QUIC protocol will be implemented in - # `nim-libp2p` - TCP prioritization should be dropped - (address, 3) temp.add(res) if len(temp) > 0: From 69cdcf38a3188930cfda80eb7a7403c8fcc1ffba Mon Sep 17 00:00:00 2001 From: cheatfate Date: Fri, 4 Oct 2024 04:45:41 +0300 Subject: [PATCH 4/4] Fix IPv6 handling. --- beacon_chain/rpc/rest_node_api.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index 3780bab8ca..80481ab7a4 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -140,7 +140,7 @@ proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = if isUDP or isTCP: # TODO (cheatfate): We match TCP here because `nim-libp2p` do not have # QUIC support yet. So we give TCP addresses priority. - let boost = if isUDP: 100 else 0 + let boost = if isUDP: 100 else: 0 if IP4.matchPartial(address): let address4 = address.getProtocolArgument(multiCodec("ip4")).valueOr: @@ -161,7 +161,7 @@ proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = let address6 = address.getProtocolArgument(multiCodec("ip6")).valueOr: continue - var ta6 = TransportAddress(family: AddressFamily.IPv4) + var ta6 = TransportAddress(family: AddressFamily.IPv6) ta6.address_v6[0 .. 15] = address6[0 .. 15] if ta6.isLoopback(): (address, boost + 8)