logos-messaging-nim/tests/v2/test_enr_utils.nim
Aaryamann Challani 13b7153aad feat(discv5): advertise custom multiaddresses (#1512)
* feat(discv5): allow custom multiaddr advertisement in discv5

feat(discv5): allow custom multiaddr advertisement in discv5

feat(discv5): move discv5 setup from wakunode2 to waku_node

fix(waku_node): def param

test(discv5): test for ext multiaddr

fix(discv5): address comments

fix(discv5): address comments

fix(wakunode2): discoveryconfig in var before init

fix(discv5): pass multiaddr to discv5 directly

fix(discv5): make multiaddrs optional

fix(test): discv5 init

fix(discv5): split discv5 mounting from waku_node

chore(discv5): s/WakuAddressMetadata/WakuNodeAddrMeta/g

* fix(waku_node): 1.25 max conns

* fix(discv5): s/WakuNodeAddrMeta/NetConfig/g

* fix(discv5): address reviews

* fix(discv5): smaller try-catches

* fix(discv5): missing arg

* fix: compile error
2023-02-07 18:36:50 +05:30

218 lines
9.4 KiB
Nim
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{.used.}
import
std/[options,sequtils],
chronos,
stew/byteutils,
testutils/unittests,
../../waku/v2/utils/wakuenr,
../test_helpers
procSuite "ENR utils":
asyncTest "Parse multiaddr field":
let
reasonable = "0x000A047F0000010601BADD03".hexToSeqByte()
reasonableDns4 = ("0x002F36286E6F64652D30312E646F2D616D73332E77616B7576322E746" &
"573742E737461747573696D2E6E65740601BBDE03003837316E6F64652D" &
"30312E61632D636E2D686F6E676B6F6E672D632E77616B7576322E74657" &
"3742E737461747573696D2E6E65740601BBDE030029BD03ADADEC040BE0" &
"47F9658668B11A504F3155001F231A37F54C4476C07FB4CC139ED7E30304D2DE03").hexToSeqByte()
tooLong = "0x000B047F0000010601BADD03".hexToSeqByte()
tooShort = "0x000A047F0000010601BADD0301".hexToSeqByte()
gibberish = "0x3270ac4e5011123c".hexToSeqByte()
empty = newSeq[byte]()
## Note: we expect to fail optimistically, i.e. extract
## any addresses we can and ignore other errors.
## Worst case scenario is we return an empty `multiaddrs` seq.
check:
# Expected cases
reasonable.toMultiAddresses().contains(MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[])
reasonableDns4.toMultiAddresses().contains(MultiAddress.init("/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss")[])
# Buffer exceeded
tooLong.toMultiAddresses().len() == 0
# Buffer remainder
tooShort.toMultiAddresses().contains(MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[])
# Gibberish
gibberish.toMultiAddresses().len() == 0
# Empty
empty.toMultiAddresses().len() == 0
asyncTest "Init ENR for Waku Usage":
# Tests RFC31 encoding "happy path"
let
enrIp = ValidIpAddress.init("127.0.0.1")
enrTcpPort, enrUdpPort = Port(61101)
enrKey = wakuenr.crypto.PrivateKey.random(Secp256k1, rng[])[]
wakuFlags = initWakuFlags(false, true, false, true)
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[],
MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss")[]]
let
record = enr.Record.init(enrKey, some(enrIp),
some(enrTcpPort), some(enrUdpPort),
some(wakuFlags),
multiaddrs)
typedRecord = record.toTypedRecord.get()
# Check EIP-778 ENR fields
check:
@(typedRecord.secp256k1.get()) == enrKey.getPublicKey()[].getRawBytes()[]
ipv4(typedRecord.ip.get()) == enrIp
Port(typedRecord.tcp.get()) == enrTcpPort
Port(typedRecord.udp.get()) == enrUdpPort
# Check Waku ENR fields
let
decodedFlags = record.get(WAKU_ENR_FIELD, seq[byte])[]
decodedAddrs = record.get(MULTIADDR_ENR_FIELD, seq[byte])[].toMultiAddresses()
check:
decodedFlags == @[wakuFlags.byte]
decodedAddrs.contains(MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[])
decodedAddrs.contains(MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss")[])
asyncTest "Strip multiaddr peerId":
# Tests that peerId is stripped of multiaddrs as per RFC31
let
enrIp = ValidIpAddress.init("127.0.0.1")
enrTcpPort, enrUdpPort = Port(61102)
enrKey = wakuenr.crypto.PrivateKey.random(Secp256k1, rng[])[]
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr31iDQpSN5Qa882BCjjwgrD")[]]
let
record = enr.Record.init(enrKey, some(enrIp),
some(enrTcpPort), some(enrUdpPort),
none(WakuEnrBitfield),
multiaddrs)
# Check Waku ENR fields
let
decodedAddrs = record.get(MULTIADDR_ENR_FIELD, seq[byte])[].toMultiAddresses()
check decodedAddrs.contains(MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss")[]) # Peer Id has been stripped
asyncTest "Decode ENR with multiaddrs field":
let
# Known values correspond to shared test vectors with other Waku implementations
knownIp = ValidIpAddress.init("18.223.219.100")
knownUdpPort = some(9000.int)
knownTcpPort = none(int)
knownMultiaddrs = @[MultiAddress.init("/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss")[],
MultiAddress.init("/dns6/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss")[]]
knownEnr = "enr:-QEnuEBEAyErHEfhiQxAVQoWowGTCuEF9fKZtXSd7H_PymHFhGJA3rGAYDVSH" &
"KCyJDGRLBGsloNbS8AZF33IVuefjOO6BIJpZIJ2NIJpcIQS39tkim11bHRpYWRkcn" &
"O4lgAvNihub2RlLTAxLmRvLWFtczMud2FrdXYyLnRlc3Quc3RhdHVzaW0ubmV0BgG" &
"73gMAODcxbm9kZS0wMS5hYy1jbi1ob25na29uZy1jLndha3V2Mi50ZXN0LnN0YXR1" &
"c2ltLm5ldAYBu94DACm9A62t7AQL4Ef5ZYZosRpQTzFVAB8jGjf1TER2wH-0zBOe1" &
"-MDBNLeA4lzZWNwMjU2azGhAzfsxbxyCkgCqq8WwYsVWH7YkpMLnU2Bw5xJSimxKav-g3VkcIIjKA"
var enrRecord: Record
check:
enrRecord.fromURI(knownEnr)
let typedRecord = enrRecord.toTypedRecord.get()
# Check EIP-778 ENR fields
check:
ipv4(typedRecord.ip.get()) == knownIp
typedRecord.tcp == knownTcpPort
typedRecord.udp == knownUdpPort
# Check Waku ENR fields
let
decodedAddrs = enrRecord.get(MULTIADDR_ENR_FIELD, seq[byte])[].toMultiAddresses()
for knownMultiaddr in knownMultiaddrs:
check decodedAddrs.contains(knownMultiaddr)
asyncTest "Supports specific capabilities encoded in the ENR":
let
enrIp = ValidIpAddress.init("127.0.0.1")
enrTcpPort, enrUdpPort = Port(60000)
enrKey = wakuenr.crypto.PrivateKey.random(Secp256k1, rng[])[]
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[]]
# TODO: Refactor enr.Record.init, provide enums as inputs enr.Record.init(capabilites=[Store,Filter])
# TODO: safer than a util function and directly using the bits
# test all flag combinations 2^4 = 16 (b0000-b1111)
records = toSeq(0b0000_0000'u8..0b0000_1111'u8)
.mapIt(enr.Record.init(enrKey,
some(enrIp),
some(enrTcpPort),
some(enrUdpPort),
some(uint8(it)),
multiaddrs))
# same order:  lightpush | filter| store | relay
expectedCapabilities = @[[false, false, false, false],
[false, false, false, true],
[false, false, true, false],
[false, false, true, true],
[false, true, false, false],
[false, true, false, true],
[false, true, true, false],
[false, true, true, true],
[true, false, false, false],
[true, false, false, true],
[true, false, true, false],
[true, false, true, true],
[true, true, false, false],
[true, true, false, true],
[true, true, true, false],
[true, true, true, true]]
for i, record in records:
for j, capability in @[Lightpush, Filter, Store, Relay]:
check expectedCapabilities[i][j] == record.supportsCapability(capability)
asyncTest "Get all supported capabilities encoded in the ENR":
let
enrIp = ValidIpAddress.init("127.0.0.1")
enrTcpPort, enrUdpPort = Port(60000)
enrKey = wakuenr.crypto.PrivateKey.random(Secp256k1, rng[])[]
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[]]
records = @[0b0000_0000'u8,
0b0000_1111'u8,
0b0000_1001'u8,
0b0000_1110'u8,
0b0000_1000'u8,]
.mapIt(enr.Record.init(enrKey,
some(enrIp),
some(enrTcpPort),
some(enrUdpPort),
some(uint8(it)),
multiaddrs))
# expected capabilities, ordered LSB to MSB
expectedCapabilities: seq[seq[Capabilities]] = @[
#[0b0000_0000]# @[],
#[0b0000_1111]# @[Relay, Store, Filter, Lightpush],
#[0b0000_1001]# @[Relay, Lightpush],
#[0b0000_1110]# @[Store, Filter, Lightpush],
#[0b0000_1000]# @[Lightpush]]
for i, actualExpetedTuple in zip(records, expectedCapabilities):
check actualExpetedTuple[0].getCapabilities() == actualExpetedTuple[1]
asyncTest "Get supported capabilities of a non waku node":
# non waku enr, i.e. Ethereum one
let nonWakuEnr = "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2G"&
"xb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNl"&
"Y3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA"
var nonWakuEnrRecord: Record
check:
nonWakuEnrRecord.fromURI(nonWakuEnr)
# check that it doesn't support any capability and it doesnt't break
check:
nonWakuEnrRecord.getCapabilities() == []
nonWakuEnrRecord.supportsCapability(Relay) == false
nonWakuEnrRecord.supportsCapability(Store) == false
nonWakuEnrRecord.supportsCapability(Filter) == false
nonWakuEnrRecord.supportsCapability(Lightpush) == false