@@ -3,7 +3,11 @@ import { SlotNumber } from '@aztec/foundation/branded-types';
33
44import { mock } from 'jest-mock-extended' ;
55
6- import { MAXIMUM_GOSSIP_CLOCK_DISPARITY_MS , isWithinClockTolerance } from './clock_tolerance.js' ;
6+ import {
7+ MAXIMUM_GOSSIP_CLOCK_DISPARITY_MS ,
8+ isWithinClockTolerance ,
9+ isWithinPipeliningGracePeriod ,
10+ } from './clock_tolerance.js' ;
711
812describe ( 'clock_tolerance' , ( ) => {
913 describe ( 'MAXIMUM_GOSSIP_CLOCK_DISPARITY_MS' , ( ) => {
@@ -204,4 +208,98 @@ describe('clock_tolerance', () => {
204208 expect ( isWithinClockTolerance ( messageSlot , currentSlot , epochCache ) ) . toBe ( false ) ;
205209 } ) ;
206210 } ) ;
211+
212+ describe ( 'isWithinPipeliningGracePeriod' , ( ) => {
213+ let epochCache : ReturnType < typeof mock < EpochCacheInterface > > ;
214+
215+ beforeEach ( ( ) => {
216+ epochCache = mock < EpochCacheInterface > ( ) ;
217+ epochCache . getSlotNow . mockReturnValue ( SlotNumber ( 100 ) ) ;
218+ epochCache . isProposerPipeliningEnabled . mockReturnValue ( true ) ;
219+ } ) ;
220+
221+ it ( 'returns true when pipelining enabled, message is for current slot, and within grace period' , ( ) => {
222+ // Grace period = DEFAULT_P2P_PROPAGATION_TIME * 1000 = 2000ms
223+ epochCache . getEpochAndSlotNow . mockReturnValue ( {
224+ epoch : 1 as any ,
225+ slot : SlotNumber ( 100 ) ,
226+ ts : 1000n ,
227+ nowMs : 1001000n , // 1000ms elapsed, within 2000ms grace period
228+ } ) ;
229+
230+ expect ( isWithinPipeliningGracePeriod ( SlotNumber ( 100 ) , epochCache ) ) . toBe ( true ) ;
231+ } ) ;
232+
233+ it ( 'returns true at exactly 0ms elapsed' , ( ) => {
234+ epochCache . getEpochAndSlotNow . mockReturnValue ( {
235+ epoch : 1 as any ,
236+ slot : SlotNumber ( 100 ) ,
237+ ts : 1000n ,
238+ nowMs : 1000000n , // 0ms elapsed
239+ } ) ;
240+
241+ expect ( isWithinPipeliningGracePeriod ( SlotNumber ( 100 ) , epochCache ) ) . toBe ( true ) ;
242+ } ) ;
243+
244+ it ( 'returns false when elapsed time exceeds grace period' , ( ) => {
245+ // 3000ms elapsed > 2000ms grace period
246+ epochCache . getEpochAndSlotNow . mockReturnValue ( {
247+ epoch : 1 as any ,
248+ slot : SlotNumber ( 100 ) ,
249+ ts : 1000n ,
250+ nowMs : 1003000n , // 3000ms elapsed
251+ } ) ;
252+
253+ expect ( isWithinPipeliningGracePeriod ( SlotNumber ( 100 ) , epochCache ) ) . toBe ( false ) ;
254+ } ) ;
255+
256+ it ( 'returns false at exactly the grace period boundary' , ( ) => {
257+ // 2000ms elapsed = DEFAULT_P2P_PROPAGATION_TIME * 1000 (not strictly less than)
258+ epochCache . getEpochAndSlotNow . mockReturnValue ( {
259+ epoch : 1 as any ,
260+ slot : SlotNumber ( 100 ) ,
261+ ts : 1000n ,
262+ nowMs : 1002000n , // 2000ms elapsed
263+ } ) ;
264+
265+ expect ( isWithinPipeliningGracePeriod ( SlotNumber ( 100 ) , epochCache ) ) . toBe ( false ) ;
266+ } ) ;
267+
268+ it ( 'returns false when pipelining is disabled' , ( ) => {
269+ epochCache . isProposerPipeliningEnabled . mockReturnValue ( false ) ;
270+
271+ epochCache . getEpochAndSlotNow . mockReturnValue ( {
272+ epoch : 1 as any ,
273+ slot : SlotNumber ( 100 ) ,
274+ ts : 1000n ,
275+ nowMs : 1001000n , // 1000ms elapsed, within grace period
276+ } ) ;
277+
278+ expect ( isWithinPipeliningGracePeriod ( SlotNumber ( 100 ) , epochCache ) ) . toBe ( false ) ;
279+ } ) ;
280+
281+ it ( 'returns false when message is not for current slot' , ( ) => {
282+ epochCache . getEpochAndSlotNow . mockReturnValue ( {
283+ epoch : 1 as any ,
284+ slot : SlotNumber ( 100 ) ,
285+ ts : 1000n ,
286+ nowMs : 1001000n ,
287+ } ) ;
288+
289+ // Message for slot 99, current slot is 100
290+ expect ( isWithinPipeliningGracePeriod ( SlotNumber ( 99 ) , epochCache ) ) . toBe ( false ) ;
291+ } ) ;
292+
293+ it ( 'returns false when message is for a future slot' , ( ) => {
294+ epochCache . getEpochAndSlotNow . mockReturnValue ( {
295+ epoch : 1 as any ,
296+ slot : SlotNumber ( 100 ) ,
297+ ts : 1000n ,
298+ nowMs : 1001000n ,
299+ } ) ;
300+
301+ // Message for slot 101, current slot is 100
302+ expect ( isWithinPipeliningGracePeriod ( SlotNumber ( 101 ) , epochCache ) ) . toBe ( false ) ;
303+ } ) ;
304+ } ) ;
207305} ) ;
0 commit comments