Attempt to fix issue with AnyLocal addresses in last-seen-p2p-address field.

This commit is contained in:
cheatfate 2024-10-04 03:18:30 +03:00
parent a461bb102f
commit a9e53a4a84
No known key found for this signature in database
GPG Key ID: 46ADD633A7201F95

View File

@ -7,6 +7,7 @@
{.push raises: [].} {.push raises: [].}
import import
std/algorithm,
stew/byteutils, stew/byteutils,
chronicles, chronicles,
eth/p2p/discoveryv5/enr, eth/p2p/discoveryv5/enr,
@ -97,15 +98,80 @@ proc toString(direction: PeerType): string =
of PeerType.Outgoing: of PeerType.Outgoing:
"outbound" "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 = proc getLastSeenAddress(node: BeaconNode, id: PeerId): string =
# TODO (cheatfate): We need to provide filter here, which will be able to # Because `last_seen_p2p_address` is single address but libp2p reports lot of
# filter such multiaddresses like `/ip4/0.0.0.0` or local addresses or # addresses, we going to sort list of addresses before selecting one. Here
# addresses with peer ids. # sort order list:
let addrs = node.network.switch.peerStore[AddressBook][id] # 1. Globally routable IPv6 address.
if len(addrs) > 0: # 2. Globally routable IPv4 address.
$addrs[len(addrs) - 1] # 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: else:
"" ""
proc getDiscoveryAddresses(node: BeaconNode): seq[string] = proc getDiscoveryAddresses(node: BeaconNode): seq[string] =
let let
typedRec = TypedRecord.fromRecord(node.network.enrRecord()) typedRec = TypedRecord.fromRecord(node.network.enrRecord())