mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-07-20 03:30:22 +00:00
Wires the relocated RateLimitManager into the messaging layer at the transmission stage rather than the API entry point: - MessagingClientConf gains a rateLimit: RateLimitConfig field (defaulting to DefaultEpochPeriodSec / DefaultMessagesPerEpoch), and MessagingClient.new hands the constructed manager to SendService. - SendService consults admit() before the first transmission of a task, both in send() and in the retry loop. Re-publishes of an already-propagated message (firstPropagatedTime set) skip admission: they resend the same bytes, which reuse the same RLN proof/nullifier and consume no fresh epoch slot. - An over-budget task parks in the task cache as NextRoundRetry; the service loop re-admits it as the epoch budget frees up. The skeleton admit() is a pass-through, so behaviour is unchanged today. Gating transmissions instead of MessagingClient.send keeps SDS repair rebroadcasts free of API-entry rejection (SDS decides that a repair is needed; the transmission scheduler decides when it fits the budget) while every wire transmission still draws from one node-wide budget -- which network-side RLN enforcement applies to repairs regardless of any local bypass. It is also where RLN proof attachment must happen, since proofs bind to the epoch current at transmission time. Adds tests/messaging/test_rate_limit_manager.nim covering the current disabled + enabled pass-through behaviour, wired into all_tests_waku.nim. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
27 lines
1.0 KiB
Nim
27 lines
1.0 KiB
Nim
{.used.}
|
|
|
|
import chronos, testutils/unittests, stew/byteutils
|
|
|
|
import logos_delivery/messaging/rate_limit_manager/rate_limit_manager
|
|
|
|
suite "RateLimitManager - admission":
|
|
asyncTest "admit is a pass-through when disabled":
|
|
let rl = RateLimitManager.new(
|
|
RateLimitConfig(enabled: false, epochPeriodSec: 600, messagesPerEpoch: 1)
|
|
)
|
|
for _ in 0 ..< 10:
|
|
let res = await rl.admit("payload".toBytes())
|
|
check res.isOk()
|
|
|
|
asyncTest "admit is a pass-through in the skeleton even when enabled":
|
|
## Documents the current skeleton behaviour: per-epoch enforcement is
|
|
## not wired yet, so every call is admitted regardless of the
|
|
## configured budget. This test flips to red as soon as real
|
|
## enforcement lands, at which point it should be replaced with
|
|
## budget-boundary assertions.
|
|
let rl = RateLimitManager.new(
|
|
RateLimitConfig(enabled: true, epochPeriodSec: 600, messagesPerEpoch: 1)
|
|
)
|
|
check (await rl.admit("first".toBytes())).isOk()
|
|
check (await rl.admit("second".toBytes())).isOk()
|