logos-messaging-nim/tests/wakunode_rest/test_rest_lightpush_legacy.nim
NagyZoltanPeter e0b563ffe5
feat: lightpush v3 (#3279)
* Separate new lightpush protocol
New RPC defined
Rename al occurence of old lightpush to legacy lightpush, fix rest tests of lightpush
New lightpush protocol added back
Setup new lightpush protocol, mounting and rest api for it

	modified:   apps/chat2/chat2.nim
	modified:   tests/node/test_wakunode_lightpush.nim
	modified:   tests/node/test_wakunode_sharding.nim
	modified:   tests/test_peer_manager.nim
	modified:   tests/test_wakunode_lightpush.nim
	renamed:    tests/waku_lightpush/lightpush_utils.nim -> tests/waku_lightpush_legacy/lightpush_utils.nim
	renamed:    tests/waku_lightpush/test_all.nim -> tests/waku_lightpush_legacy/test_all.nim
	renamed:    tests/waku_lightpush/test_client.nim -> tests/waku_lightpush_legacy/test_client.nim
	renamed:    tests/waku_lightpush/test_ratelimit.nim -> tests/waku_lightpush_legacy/test_ratelimit.nim
	modified:   tests/wakunode_rest/test_all.nim
	renamed:    tests/wakunode_rest/test_rest_lightpush.nim -> tests/wakunode_rest/test_rest_lightpush_legacy.nim
	modified:   waku/factory/node_factory.nim
	modified:   waku/node/waku_node.nim
	modified:   waku/waku_api/rest/admin/handlers.nim
	modified:   waku/waku_api/rest/builder.nim
	new file:   waku/waku_api/rest/legacy_lightpush/client.nim
	new file:   waku/waku_api/rest/legacy_lightpush/handlers.nim
	new file:   waku/waku_api/rest/legacy_lightpush/types.nim
	modified:   waku/waku_api/rest/lightpush/client.nim
	modified:   waku/waku_api/rest/lightpush/handlers.nim
	modified:   waku/waku_api/rest/lightpush/types.nim
	modified:   waku/waku_core/codecs.nim
	modified:   waku/waku_lightpush.nim
	modified:   waku/waku_lightpush/callbacks.nim
	modified:   waku/waku_lightpush/client.nim
	modified:   waku/waku_lightpush/common.nim
	modified:   waku/waku_lightpush/protocol.nim
	modified:   waku/waku_lightpush/rpc.nim
	modified:   waku/waku_lightpush/rpc_codec.nim
	modified:   waku/waku_lightpush/self_req_handler.nim
	new file:   waku/waku_lightpush_legacy.nim
	renamed:    waku/waku_lightpush/README.md -> waku/waku_lightpush_legacy/README.md
	new file:   waku/waku_lightpush_legacy/callbacks.nim
	new file:   waku/waku_lightpush_legacy/client.nim
	new file:   waku/waku_lightpush_legacy/common.nim
	new file:   waku/waku_lightpush_legacy/protocol.nim
	new file:   waku/waku_lightpush_legacy/protocol_metrics.nim
	new file:   waku/waku_lightpush_legacy/rpc.nim
	new file:   waku/waku_lightpush_legacy/rpc_codec.nim
	new file:   waku/waku_lightpush_legacy/self_req_handler.nim

Adapt to non-invasive libp2p observers

cherry pick latest lightpush (v1) changes into legacy lightpush code after rebase to latest master

Fix vendor dependencies from origin/master after failed rebase of them

Adjust examples, test to new lightpush - keep using of legacy

Fixup error code mappings

Fix REST admin interface with distinct legacy and new lightpush

Fix lightpush v2 tests

* Utilize new publishEx interface of pubsub libp2p

* Adapt to latest libp2p pubslih design changes. publish returns an outcome as Result error.

* Fix review findings

* Fix tests, re-added lost one

* Fix rebase

* Apply suggestions from code review

Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>

* Addressing review comments

* Fix incentivization tests

* Fix build failed on libwaku

* Change new lightpush endpoint version to 3 instead of 2. Noticed that old and new lightpush metrics can cause trouble in monitoring dashboards so decided to give new name as v3 for the new lightpush metrics and change legacy ones back - temporarly till old lightpush will be decommissioned

* Fixing flaky test with rate limit timing

* Fixing logscope of lightpush and legacy lightpush

---------

Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>
2025-03-05 12:07:56 +01:00

303 lines
9.1 KiB
Nim

{.used.}
import
std/sequtils,
stew/byteutils,
stew/shims/net,
testutils/unittests,
presto,
presto/client as presto_client,
libp2p/crypto/crypto
import
waku/[
waku_api/message_cache,
waku_core,
waku_node,
node/peer_manager,
waku_lightpush_legacy/common,
waku_api/rest/server,
waku_api/rest/client,
waku_api/rest/responses,
waku_api/rest/legacy_lightpush/types,
waku_api/rest/legacy_lightpush/handlers as lightpush_api,
waku_api/rest/legacy_lightpush/client as lightpush_api_client,
waku_relay,
common/rate_limit/setting,
],
../testlib/wakucore,
../testlib/wakunode,
../testlib/testutils
proc testWakuNode(): WakuNode =
let
privkey = generateSecp256k1Key()
bindIp = parseIpAddress("0.0.0.0")
extIp = parseIpAddress("127.0.0.1")
port = Port(0)
return newTestWakuNode(privkey, bindIp, port, some(extIp), some(port))
type RestLightPushTest = object
serviceNode: WakuNode
pushNode: WakuNode
consumerNode: WakuNode
restServer: WakuRestServerRef
client: RestClientRef
proc init(
T: type RestLightPushTest, rateLimit: RateLimitSetting = (0, 0.millis)
): Future[T] {.async.} =
var testSetup = RestLightPushTest()
testSetup.serviceNode = testWakuNode()
testSetup.pushNode = testWakuNode()
testSetup.consumerNode = testWakuNode()
await allFutures(
testSetup.serviceNode.start(),
testSetup.pushNode.start(),
testSetup.consumerNode.start(),
)
await testSetup.consumerNode.mountRelay()
await testSetup.serviceNode.mountRelay()
await testSetup.serviceNode.mountLegacyLightPush(rateLimit)
testSetup.pushNode.mountLegacyLightPushClient()
testSetup.serviceNode.peerManager.addServicePeer(
testSetup.consumerNode.peerInfo.toRemotePeerInfo(), WakuRelayCodec
)
await testSetup.serviceNode.connectToNodes(
@[testSetup.consumerNode.peerInfo.toRemotePeerInfo()]
)
testSetup.pushNode.peerManager.addServicePeer(
testSetup.serviceNode.peerInfo.toRemotePeerInfo(), WakuLegacyLightPushCodec
)
var restPort = Port(0)
let restAddress = parseIpAddress("127.0.0.1")
testSetup.restServer = WakuRestServerRef.init(restAddress, restPort).tryGet()
restPort = testSetup.restServer.httpServer.address.port
# update with bound port for client use
installLightPushRequestHandler(testSetup.restServer.router, testSetup.pushNode)
testSetup.restServer.start()
testSetup.client = newRestHttpClient(initTAddress(restAddress, restPort))
return testSetup
proc shutdown(self: RestLightPushTest) {.async.} =
await self.restServer.stop()
await self.restServer.closeWait()
await allFutures(self.serviceNode.stop(), self.pushNode.stop())
suite "Waku v2 Rest API - lightpush":
asyncTest "Push message with proof":
let restLightPushTest = await RestLightPushTest.init()
let message: RelayWakuMessage = fakeWakuMessage(
contentTopic = DefaultContentTopic,
payload = toBytes("TEST-1"),
proof = toBytes("proof-test"),
)
.toRelayWakuMessage()
check message.proof.isSome()
let requestBody =
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: message)
let response = await restLightPushTest.client.sendPushRequest(body = requestBody)
## Validate that the push request failed because the node is not
## connected to other node but, doesn't fail because of not properly
## handling the proof message attribute within the REST request.
check:
response.data == "Failed to request a message push: not_published_to_any_peer"
asyncTest "Push message request":
# Given
let restLightPushTest = await RestLightPushTest.init()
restLightPushTest.consumerNode.subscribe(
(kind: PubsubSub, topic: DefaultPubsubTopic)
)
restLightPushTest.serviceNode.subscribe(
(kind: PubsubSub, topic: DefaultPubsubTopic)
)
require:
toSeq(restLightPushTest.serviceNode.wakuRelay.subscribedTopics).len == 1
# When
let message: RelayWakuMessage = fakeWakuMessage(
contentTopic = DefaultContentTopic, payload = toBytes("TEST-1")
)
.toRelayWakuMessage()
let requestBody =
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: message)
let response = await restLightPushTest.client.sendPushRequest(requestBody)
echo "response", $response
# Then
check:
response.status == 200
$response.contentType == $MIMETYPE_TEXT
await restLightPushTest.shutdown()
asyncTest "Push message bad-request":
# Given
let restLightPushTest = await RestLightPushTest.init()
restLightPushTest.serviceNode.subscribe(
(kind: PubsubSub, topic: DefaultPubsubTopic)
)
require:
toSeq(restLightPushTest.serviceNode.wakuRelay.subscribedTopics).len == 1
# When
let badMessage1: RelayWakuMessage = fakeWakuMessage(
contentTopic = DefaultContentTopic, payload = toBytes("")
)
.toRelayWakuMessage()
let badRequestBody1 =
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: badMessage1)
let badMessage2: RelayWakuMessage =
fakeWakuMessage(contentTopic = "", payload = toBytes("Sthg")).toRelayWakuMessage()
let badRequestBody2 =
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: badMessage2)
let badRequestBody3 =
PushRequest(pubsubTopic: none(PubsubTopic), message: badMessage2)
var response: RestResponse[string]
response = await restLightPushTest.client.sendPushRequest(badRequestBody1)
echo "response", $response
# Then
check:
response.status == 400
$response.contentType == $MIMETYPE_TEXT
response.data.startsWith("Invalid content body")
# when
response = await restLightPushTest.client.sendPushRequest(badRequestBody2)
# Then
check:
response.status == 400
$response.contentType == $MIMETYPE_TEXT
response.data.startsWith("Invalid content body")
# when
response = await restLightPushTest.client.sendPushRequest(badRequestBody3)
# Then
check:
response.status == 400
$response.contentType == $MIMETYPE_TEXT
response.data.startsWith("Invalid content body")
await restLightPushTest.shutdown()
asyncTest "Request rate limit push message":
# Given
let budgetCap = 3
let tokenPeriod = 500.millis
let restLightPushTest = await RestLightPushTest.init((budgetCap, tokenPeriod))
restLightPushTest.consumerNode.subscribe(
(kind: PubsubSub, topic: DefaultPubsubTopic)
)
restLightPushTest.serviceNode.subscribe(
(kind: PubsubSub, topic: DefaultPubsubTopic)
)
require:
toSeq(restLightPushTest.serviceNode.wakuRelay.subscribedTopics).len == 1
# When
let pushProc = proc() {.async.} =
let message: RelayWakuMessage = fakeWakuMessage(
contentTopic = DefaultContentTopic, payload = toBytes("TEST-1")
)
.toRelayWakuMessage()
let requestBody =
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: message)
let response = await restLightPushTest.client.sendPushRequest(requestBody)
echo "response", $response
# Then
check:
response.status == 200
$response.contentType == $MIMETYPE_TEXT
let pushRejectedProc = proc() {.async.} =
let message: RelayWakuMessage = fakeWakuMessage(
contentTopic = DefaultContentTopic, payload = toBytes("TEST-1")
)
.toRelayWakuMessage()
let requestBody =
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: message)
let response = await restLightPushTest.client.sendPushRequest(requestBody)
echo "response", $response
# Then
check:
response.status == 429
await pushProc()
await pushProc()
await pushProc()
await pushRejectedProc()
await sleepAsync(tokenPeriod)
for runCnt in 0 ..< 3:
let startTime = Moment.now()
for sendCnt in 0 ..< budgetCap:
await pushProc()
let endTime = Moment.now()
let elapsed: Duration = (endTime - startTime)
await sleepAsync(tokenPeriod - elapsed + 10.millis)
await restLightPushTest.shutdown()
## TODO: Re-work this test when lightpush protocol change is done: https://github.com/waku-org/pm/issues/93
## This test is similar when no available peer exists for publish. Currently it is returning success,
## that makes this test not useful.
# asyncTest "Push message request service not available":
# # Given
# let restLightPushTest = await RestLightPushTest.init()
# # When
# let message : RelayWakuMessage = fakeWakuMessage(contentTopic = DefaultContentTopic,
# payload = toBytes("TEST-1")).toRelayWakuMessage()
# let requestBody = PushRequest(pubsubTopic: some("NoExistTopic"),
# message: message)
# let response = await restLightPushTest.client.sendPushRequest(requestBody)
# echo "response", $response
# # Then
# check:
# response.status == 503
# $response.contentType == $MIMETYPE_TEXT
# response.data == "Failed to request a message push: Can not publish to any peers"
# await restLightPushTest.shutdown()