chore: do not mount lightpush without relay (fixes #2808) (#3540)

* chore: do not mount lightpush without relay (fixes #2808)

- Change mountLightPush signature to return Result[void, string]
- Return error when relay is not mounted
- Update all call sites to handle Result return type
- Add test verifying mounting fails without relay
- Only advertise lightpush capability when relay is enabled

* chore: don't mount legacy lightpush without relay
This commit is contained in:
Sergei Tikhomirov 2025-12-11 10:51:47 +01:00 committed by GitHub
parent 868d43164e
commit 7d1c6abaac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 88 additions and 44 deletions

View File

@ -480,7 +480,9 @@ proc processInput(rfd: AsyncFD, rng: ref HmacDrbgContext) {.async.} =
if conf.lightpushnode != "":
let peerInfo = parsePeerInfo(conf.lightpushnode)
if peerInfo.isOk():
await mountLegacyLightPush(node)
(await node.mountLegacyLightPush()).isOkOr:
error "failed to mount legacy lightpush", error = error
quit(QuitFailure)
node.mountLegacyLightPushClient()
node.peerManager.addServicePeer(peerInfo.value, WakuLightpushCodec)
else:

View File

@ -13,6 +13,7 @@ import
node/peer_manager,
node/waku_node,
node/kernel_api,
node/kernel_api/lightpush,
waku_lightpush_legacy,
waku_lightpush_legacy/common,
waku_lightpush_legacy/protocol_metrics,
@ -56,7 +57,7 @@ suite "Waku Legacy Lightpush - End To End":
(await server.mountRelay()).isOkOr:
assert false, "Failed to mount relay"
await server.mountLegacyLightpush() # without rln-relay
check (await server.mountLegacyLightpush()).isOk() # without rln-relay
client.mountLegacyLightpushClient()
serverRemotePeerInfo = server.peerInfo.toRemotePeerInfo()
@ -147,7 +148,7 @@ suite "RLN Proofs as a Lightpush Service":
(await server.mountRelay()).isOkOr:
assert false, "Failed to mount relay"
await server.mountRlnRelay(wakuRlnConfig)
await server.mountLegacyLightPush()
check (await server.mountLegacyLightPush()).isOk()
client.mountLegacyLightPushClient()
let manager1 = cast[OnchainGroupManager](server.wakuRlnRelay.groupManager)
@ -213,7 +214,7 @@ suite "Waku Legacy Lightpush message delivery":
assert false, "Failed to mount relay"
(await bridgeNode.mountRelay()).isOkOr:
assert false, "Failed to mount relay"
await bridgeNode.mountLegacyLightPush()
check (await bridgeNode.mountLegacyLightPush()).isOk()
lightNode.mountLegacyLightPushClient()
discard await lightNode.peerManager.dialPeer(
@ -249,3 +250,19 @@ suite "Waku Legacy Lightpush message delivery":
## Cleanup
await allFutures(lightNode.stop(), bridgeNode.stop(), destNode.stop())
suite "Waku Legacy Lightpush mounting behavior":
asyncTest "fails to mount when relay is not mounted":
## Given a node without Relay mounted
let
key = generateSecp256k1Key()
node = newTestWakuNode(key, parseIpAddress("0.0.0.0"), Port(0))
# Do not mount Relay on purpose
check node.wakuRelay.isNil()
## Then mounting Legacy Lightpush must fail
let res = await node.mountLegacyLightPush()
check:
res.isErr()
res.error == MountWithoutRelayError

View File

@ -13,6 +13,7 @@ import
node/peer_manager,
node/waku_node,
node/kernel_api,
node/kernel_api/lightpush,
waku_lightpush,
waku_rln_relay,
],
@ -55,7 +56,7 @@ suite "Waku Lightpush - End To End":
(await server.mountRelay()).isOkOr:
assert false, "Failed to mount relay"
await server.mountLightpush() # without rln-relay
check (await server.mountLightpush()).isOk() # without rln-relay
client.mountLightpushClient()
serverRemotePeerInfo = server.peerInfo.toRemotePeerInfo()
@ -147,7 +148,7 @@ suite "RLN Proofs as a Lightpush Service":
(await server.mountRelay()).isOkOr:
assert false, "Failed to mount relay"
await server.mountRlnRelay(wakuRlnConfig)
await server.mountLightPush()
check (await server.mountLightPush()).isOk()
client.mountLightPushClient()
let manager1 = cast[OnchainGroupManager](server.wakuRlnRelay.groupManager)
@ -213,7 +214,7 @@ suite "Waku Lightpush message delivery":
assert false, "Failed to mount relay"
(await bridgeNode.mountRelay()).isOkOr:
assert false, "Failed to mount relay"
await bridgeNode.mountLightPush()
check (await bridgeNode.mountLightPush()).isOk()
lightNode.mountLightPushClient()
discard await lightNode.peerManager.dialPeer(
@ -251,3 +252,19 @@ suite "Waku Lightpush message delivery":
## Cleanup
await allFutures(lightNode.stop(), bridgeNode.stop(), destNode.stop())
suite "Waku Lightpush mounting behavior":
asyncTest "fails to mount when relay is not mounted":
## Given a node without Relay mounted
let
key = generateSecp256k1Key()
node = newTestWakuNode(key, parseIpAddress("0.0.0.0"), Port(0))
# Do not mount Relay on purpose
check node.wakuRelay.isNil()
## Then mounting Lightpush must fail
let res = await node.mountLightPush()
check:
res.isErr()
res.error == MountWithoutRelayError

View File

@ -282,7 +282,7 @@ suite "Sharding":
asyncTest "lightpush":
# Given a connected server and client subscribed to the same pubsub topic
client.mountLegacyLightPushClient()
await server.mountLightpush()
check (await server.mountLightpush()).isOk()
let
topic = "/waku/2/rs/0/1"
@ -405,7 +405,7 @@ suite "Sharding":
asyncTest "lightpush (automatic sharding filtering)":
# Given a connected server and client using the same content topic (with two different formats)
client.mountLegacyLightPushClient()
await server.mountLightpush()
check (await server.mountLightpush()).isOk()
let
contentTopicShort = "/toychat/2/huilong/proto"
@ -563,7 +563,7 @@ suite "Sharding":
asyncTest "lightpush - exclusion (automatic sharding filtering)":
# Given a connected server and client using different content topics
client.mountLegacyLightPushClient()
await server.mountLightpush()
check (await server.mountLightpush()).isOk()
let
contentTopic1 = "/toychat/2/huilong/proto"
@ -874,7 +874,7 @@ suite "Sharding":
asyncTest "Waku LightPush Sharding (Static Sharding)":
# Given a connected server and client using two different pubsub topics
client.mountLegacyLightPushClient()
await server.mountLightpush()
check (await server.mountLightpush()).isOk()
# Given a connected server and client subscribed to multiple pubsub topics
let

View File

@ -61,7 +61,7 @@ proc init(
assert false, "Failed to mount relay: " & $error
(await testSetup.serviceNode.mountRelay()).isOkOr:
assert false, "Failed to mount relay: " & $error
await testSetup.serviceNode.mountLightPush(rateLimit)
check (await testSetup.serviceNode.mountLightPush(rateLimit)).isOk()
testSetup.pushNode.mountLightPushClient()
testSetup.serviceNode.peerManager.addServicePeer(

View File

@ -61,7 +61,7 @@ proc init(
assert false, "Failed to mount relay"
(await testSetup.serviceNode.mountRelay()).isOkOr:
assert false, "Failed to mount relay"
await testSetup.serviceNode.mountLegacyLightPush(rateLimit)
check (await testSetup.serviceNode.mountLegacyLightPush(rateLimit)).isOk()
testSetup.pushNode.mountLegacyLightPushClient()
testSetup.serviceNode.peerManager.addServicePeer(

View File

@ -606,7 +606,7 @@ proc build*(
let relayShardedPeerManagement = builder.relayShardedPeerManagement.get(false)
let wakuFlags = CapabilitiesBitfield.init(
lightpush = lightPush,
lightpush = lightPush and relay,
filter = filterServiceConf.isSome,
store = storeServiceConf.isSome,
relay = relay,

View File

@ -368,8 +368,11 @@ proc setupProtocols(
# NOTE Must be mounted after relay
if conf.lightPush:
try:
await mountLightPush(node, node.rateLimitSettings.getSetting(LIGHTPUSH))
await mountLegacyLightPush(node, node.rateLimitSettings.getSetting(LIGHTPUSH))
(await mountLightPush(node, node.rateLimitSettings.getSetting(LIGHTPUSH))).isOkOr:
return err("failed to mount waku lightpush protocol: " & $error)
(await mountLegacyLightPush(node, node.rateLimitSettings.getSetting(LIGHTPUSH))).isOkOr:
return err("failed to mount waku legacy lightpush protocol: " & $error)
except CatchableError:
return err("failed to mount waku lightpush protocol: " & getCurrentExceptionMsg())

View File

@ -34,26 +34,27 @@ import
logScope:
topics = "waku node lightpush api"
const MountWithoutRelayError* = "cannot mount lightpush because relay is not mounted"
## Waku lightpush
proc mountLegacyLightPush*(
node: WakuNode, rateLimit: RateLimitSetting = DefaultGlobalNonRelayRateLimit
) {.async.} =
): Future[Result[void, string]] {.async.} =
info "mounting legacy light push"
let pushHandler =
if node.wakuRelay.isNil:
info "mounting legacy lightpush without relay (nil)"
legacy_lightpush_protocol.getNilPushHandler()
if node.wakuRelay.isNil():
return err(MountWithoutRelayError)
info "mounting legacy lightpush with relay"
let rlnPeer =
if node.wakuRlnRelay.isNil():
info "mounting legacy lightpush without rln-relay"
none(WakuRLNRelay)
else:
info "mounting legacy lightpush with relay"
let rlnPeer =
if isNil(node.wakuRlnRelay):
info "mounting legacy lightpush without rln-relay"
none(WakuRLNRelay)
else:
info "mounting legacy lightpush with rln-relay"
some(node.wakuRlnRelay)
legacy_lightpush_protocol.getRelayPushHandler(node.wakuRelay, rlnPeer)
info "mounting legacy lightpush with rln-relay"
some(node.wakuRlnRelay)
let pushHandler =
legacy_lightpush_protocol.getRelayPushHandler(node.wakuRelay, rlnPeer)
node.wakuLegacyLightPush =
WakuLegacyLightPush.new(node.peerManager, node.rng, pushHandler, some(rateLimit))
@ -64,6 +65,9 @@ proc mountLegacyLightPush*(
node.switch.mount(node.wakuLegacyLightPush, protocolMatcher(WakuLegacyLightPushCodec))
info "legacy lightpush mounted successfully"
return ok()
proc mountLegacyLightPushClient*(node: WakuNode) =
info "mounting legacy light push client"
@ -146,23 +150,21 @@ proc legacyLightpushPublish*(
proc mountLightPush*(
node: WakuNode, rateLimit: RateLimitSetting = DefaultGlobalNonRelayRateLimit
) {.async.} =
): Future[Result[void, string]] {.async.} =
info "mounting light push"
let pushHandler =
if node.wakuRelay.isNil():
info "mounting lightpush v2 without relay (nil)"
lightpush_protocol.getNilPushHandler()
if node.wakuRelay.isNil():
return err(MountWithoutRelayError)
info "mounting lightpush with relay"
let rlnPeer =
if node.wakuRlnRelay.isNil():
info "mounting lightpush without rln-relay"
none(WakuRLNRelay)
else:
info "mounting lightpush with relay"
let rlnPeer =
if isNil(node.wakuRlnRelay):
info "mounting lightpush without rln-relay"
none(WakuRLNRelay)
else:
info "mounting lightpush with rln-relay"
some(node.wakuRlnRelay)
lightpush_protocol.getRelayPushHandler(node.wakuRelay, rlnPeer)
info "mounting lightpush with rln-relay"
some(node.wakuRlnRelay)
let pushHandler = lightpush_protocol.getRelayPushHandler(node.wakuRelay, rlnPeer)
node.wakuLightPush = WakuLightPush.new(
node.peerManager, node.rng, pushHandler, node.wakuAutoSharding, some(rateLimit)
@ -174,6 +176,9 @@ proc mountLightPush*(
node.switch.mount(node.wakuLightPush, protocolMatcher(WakuLightPushCodec))
info "lightpush mounted successfully"
return ok()
proc mountLightPushClient*(node: WakuNode) =
info "mounting light push client"