@@ -7,6 +7,7 @@ import { createEvent } from '../helpers'
77import { Event } from '../../../../src/@types/event'
88import { getCacheConfig } from '../../../../src/cache/client'
99import { SettingsStatic } from '../../../../src/utils/settings'
10+ import { ewmaKey } from '../../../../src/utils/ewma-rate-limiter'
1011
1112let testCacheClient : any
1213const rateLimitKeys : string [ ] = [ ]
@@ -25,7 +26,9 @@ Given(/(\w+)'s message rate is already at the limit/, async function(name: strin
2526 const ws = this . parameters . clients [ name ] as WebSocket
2627 const address = ( ws as any ) . _socket ?. remoteAddress ?? '::1'
2728 const period = 60000
28- const key = `${ address } :message:${ period } `
29+ // EWMA reads its own namespace; seeding the un-namespaced key would leave the
30+ // limiter on a fresh window and the scenario would not rate limit at all.
31+ const key = ewmaKey ( `${ address } :message:${ period } ` )
2932
3033 await testCacheClient . hSet ( key , {
3134 rate : '999' ,
@@ -54,6 +57,22 @@ When(/(\w+) sends a text_note event expecting to be rate limited/, async functio
5457 this . parameters . events [ name ] . push ( event )
5558} )
5659
60+ Given ( / ( \w + ) ' s R e d i s h o l d s a s l i d i n g - w i n d o w k e y l e f t b y a n o l d e r v e r s i o n / , async function ( name : string ) {
61+ const ws = this . parameters . clients [ name ] as WebSocket
62+ const address = ( ws as any ) . _socket ?. remoteAddress ?? '::1'
63+ const period = 60000
64+ // Exactly what a 2.x relay, or a sliding_window run, leaves behind: a sorted
65+ // set under the key name EWMA used to share. Reading it as a hash raised
66+ // WRONGTYPE on every message, which is the regression this guards.
67+ const key = `${ address } :message:${ period } `
68+
69+ await testCacheClient . del ( key )
70+ await testCacheClient . zAdd ( key , [ { score : Date . now ( ) , value : `${ Date . now ( ) } :1` } ] )
71+ await testCacheClient . pExpire ( key , period )
72+
73+ rateLimitKeys . push ( key )
74+ } )
75+
5776After ( { tags : '@rate-limiter' } , async function ( ) {
5877 SettingsStatic . _settings = pipe (
5978 assocPath ( [ 'limits' , 'message' , 'rateLimits' ] , [ ] ) ,
0 commit comments