logos-messaging-nim/tests/api/test_entry_nodes.nim
fryorcraken bc8acf7611
feat: Waku API create node (#3580)
* introduce createNode

# Conflicts:
#	apps/wakunode2/cli_args.nim

* remove confutils dependency on the library

* test: remove websocket in default test config

* update to latest specs

* test: cli_args

* align to spec changes (sovereign, message conf, entrypoints

* accept enr, entree and multiaddr as entry points

* post rebase

* format

* change from "sovereign" to "core"

* add example

* get example to continue running

* nitpicks

* idiomatic constructors

* fix enum naming

* replace procs with consts

* remove messageConfirmation

* use pure enum

* rename example file
2025-10-01 16:31:34 +10:00

265 lines
8.6 KiB
Nim

{.used.}
import std/options, results, testutils/unittests
import waku/api/entry_nodes
# Since classifyEntryNode is internal, we test it indirectly through processEntryNodes behavior
# The enum is exported so we can test against it
suite "Entry Nodes Classification":
test "Process ENRTree - standard format":
let result = processEntryNodes(
@[
"enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im"
]
)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 1
bootstrapEnrs.len == 0
staticNodes.len == 0
test "Process ENRTree - case insensitive":
let result = processEntryNodes(
@[
"ENRTREE://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im"
]
)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 1
bootstrapEnrs.len == 0
staticNodes.len == 0
test "Process ENR - standard format":
let result = processEntryNodes(
@[
"enr:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g"
]
)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 1
staticNodes.len == 0
test "Process ENR - case insensitive":
let result = processEntryNodes(
@[
"ENR:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g"
]
)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 1
staticNodes.len == 0
test "Process Multiaddress - IPv4":
let result = processEntryNodes(
@[
"/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc"
]
)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 0
staticNodes.len == 1
test "Process Multiaddress - IPv6":
let result = processEntryNodes(
@["/ip6/::1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc"]
)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 0
staticNodes.len == 1
test "Process Multiaddress - DNS":
let result = processEntryNodes(
@[
"/dns4/example.com/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc"
]
)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 0
staticNodes.len == 1
test "Process empty string":
let result = processEntryNodes(@[""])
check:
result.isErr()
result.error == "Entry node error: Empty entry node address"
test "Process invalid format - HTTP URL":
let result = processEntryNodes(@["http://example.com"])
check:
result.isErr()
result.error ==
"Entry node error: Unrecognized entry node format. Must start with 'enrtree:', 'enr:', or '/'"
test "Process invalid format - some string":
let result = processEntryNodes(@["some-string-here"])
check:
result.isErr()
result.error ==
"Entry node error: Unrecognized entry node format. Must start with 'enrtree:', 'enr:', or '/'"
suite "Entry Nodes Processing":
test "Process mixed entry nodes":
let entryNodes =
@[
"enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im",
"/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc",
"enr:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g",
]
let result = processEntryNodes(entryNodes)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 1 # enrtree
bootstrapEnrs.len == 1 # enr
staticNodes.len >= 1 # at least the multiaddr
enrTreeUrls[0] == entryNodes[0] # enrtree unchanged
bootstrapEnrs[0] == entryNodes[2] # enr unchanged
staticNodes[0] == entryNodes[1] # multiaddr added to static
test "Process only ENRTree nodes":
let entryNodes =
@[
"enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im",
"enrtree://ANOTHER_TREE@example.com",
]
let result = processEntryNodes(entryNodes)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 2
bootstrapEnrs.len == 0
staticNodes.len == 0
enrTreeUrls == entryNodes
test "Process only multiaddresses":
let entryNodes =
@[
"/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc",
"/ip4/192.168.1.1/tcp/60001/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYd",
]
let result = processEntryNodes(entryNodes)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 0
staticNodes.len == 2
staticNodes == entryNodes
test "Process only ENR nodes":
let entryNodes =
@[
"enr:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g",
"enr:-QEkuECnZ3IbVAgkOzv-QLnKC4dRKAPRY80m1-R7G8jZ7yfT3ipEfBrhKN7ARcQgQ-vg-h40AQzyvAkPYlHPaFKk6u9MBgmlkgnY0iXNlY3AyNTZrMaEDk49D8JjMSns4p1XVNBvJquOUzT4PENSJknkROspfAFGg3RjcIJ2X4N1ZHCCd2g",
]
let result = processEntryNodes(entryNodes)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 2
staticNodes.len == 0
bootstrapEnrs == entryNodes
# Note: staticNodes may or may not be populated depending on ENR parsing
test "Process empty list":
let entryNodes: seq[string] = @[]
let result = processEntryNodes(entryNodes)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 0
staticNodes.len == 0
test "Process with invalid entry":
let entryNodes = @["enrtree://VALID@example.com", "invalid://notvalid"]
let result = processEntryNodes(entryNodes)
check:
result.isErr()
result.error ==
"Entry node error: Unrecognized entry node format. Must start with 'enrtree:', 'enr:', or '/'"
test "Process different multiaddr formats":
let entryNodes =
@[
"/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc",
"/ip6/::1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYd",
"/dns4/example.com/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYe",
"/dns/node.example.org/tcp/443/wss/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYf",
]
let result = processEntryNodes(entryNodes)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
enrTreeUrls.len == 0
bootstrapEnrs.len == 0
staticNodes.len == 4
staticNodes == entryNodes
test "Process with duplicate entries":
let entryNodes =
@[
"/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc",
"/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc",
"enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im",
"enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im",
]
let result = processEntryNodes(entryNodes)
check:
result.isOk()
let (enrTreeUrls, bootstrapEnrs, staticNodes) = result.get()
check:
# Duplicates are not filtered out (by design - let downstream handle it)
enrTreeUrls.len == 2
bootstrapEnrs.len == 0
staticNodes.len == 2