@@ -92,7 +92,7 @@ test_get_prunes_insufficient_upserts( void ) {
92
92
}
93
93
94
94
uchar const * origins [1 ] = { origin .pubkey };
95
- fd_prune_finder_prune_t * out_prunes ;
95
+ fd_prune_finder_prune_t const * out_prunes ;
96
96
ulong out_prunes_len ;
97
97
98
98
fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 1UL , & out_prunes , & out_prunes_len );
@@ -128,7 +128,7 @@ test_get_prunes_insufficient_ingress_nodes( void ) {
128
128
}
129
129
130
130
uchar const * origins [1 ] = { origin .pubkey };
131
- fd_prune_finder_prune_t * out_prunes ;
131
+ fd_prune_finder_prune_t const * out_prunes ;
132
132
ulong out_prunes_len ;
133
133
134
134
fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 1UL , & out_prunes , & out_prunes_len );
@@ -178,7 +178,7 @@ test_get_prunes_basic( void ) {
178
178
fd_prune_finder_record ( pf , origin .pubkey , origin .stake , good_relayer_1 .pubkey , good_relayer_1 .stake , 0UL );
179
179
180
180
uchar const * origins [1 ] = { origin .pubkey };
181
- fd_prune_finder_prune_t * out_prunes ;
181
+ fd_prune_finder_prune_t const * out_prunes ;
182
182
ulong out_prunes_len ;
183
183
184
184
fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 1UL , & out_prunes , & out_prunes_len );
@@ -227,7 +227,7 @@ test_get_prunes_tiebreaker( void ) {
227
227
}
228
228
229
229
uchar const * origins [1 ] = { origin .pubkey };
230
- fd_prune_finder_prune_t * out_prunes ;
230
+ fd_prune_finder_prune_t const * out_prunes ;
231
231
ulong out_prunes_len ;
232
232
233
233
fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 1UL , & out_prunes , & out_prunes_len );
@@ -266,7 +266,7 @@ test_get_prunes_reset_origin( void ) {
266
266
}
267
267
268
268
uchar const * origins [1 ] = { origin .pubkey };
269
- fd_prune_finder_prune_t * out_prunes ;
269
+ fd_prune_finder_prune_t const * out_prunes ;
270
270
ulong out_prunes_len ;
271
271
272
272
fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 1UL , & out_prunes , & out_prunes_len );
@@ -301,6 +301,51 @@ test_get_prunes_reset_origin( void ) {
301
301
free ( bytes );
302
302
}
303
303
304
+ void
305
+ test_get_prunes_duplicate_origins ( void ) {
306
+ fd_rng_t _rng [1 ]; fd_rng_t * rng = fd_rng_join ( fd_rng_new ( _rng , 0U , 0UL ) );
307
+ FD_TEST ( rng );
308
+
309
+ ulong origin_max = 16UL ;
310
+ ulong relayer_max_per_origin = 8UL ;
311
+
312
+ void * bytes = aligned_alloc ( fd_prune_finder_align (), fd_prune_finder_footprint ( origin_max , relayer_max_per_origin ) );
313
+ FD_TEST ( bytes );
314
+
315
+ fd_prune_finder_t * pf = fd_prune_finder_join ( fd_prune_finder_new ( bytes , origin_max , relayer_max_per_origin , rng ) );
316
+ FD_TEST ( pf );
317
+
318
+ test_peer_t origin = generate_random_peer ( rng );
319
+ test_peer_t good_relayer_1 = generate_random_peer ( rng );
320
+ test_peer_t good_relayer_2 = generate_random_peer ( rng );
321
+ test_peer_t bad_relayer = generate_random_peer ( rng );
322
+
323
+ /* Record enough messages to trigger pruning */
324
+ for ( ulong i = 0UL ; i < 25UL ; i ++ ) {
325
+ fd_prune_finder_record ( pf , origin .pubkey , origin .stake , good_relayer_1 .pubkey , good_relayer_1 .stake , 0UL );
326
+ fd_prune_finder_record ( pf , origin .pubkey , origin .stake , good_relayer_2 .pubkey , good_relayer_2 .stake , 0UL );
327
+ /* Bad relayer gets duplicates (num_dups=2) */
328
+ fd_prune_finder_record ( pf , origin .pubkey , origin .stake , bad_relayer .pubkey , bad_relayer .stake , 1UL );
329
+ }
330
+
331
+ /* add extra record for one of the good relayers since to avoid tiebreaker */
332
+ fd_prune_finder_record ( pf , origin .pubkey , origin .stake , good_relayer_1 .pubkey , good_relayer_1 .stake , 0UL );
333
+
334
+ /* Pass in duplicate origins */
335
+ uchar const * origins [3 ] = { origin .pubkey , origin .pubkey , origin .pubkey };
336
+ fd_prune_finder_prune_t const * out_prunes ;
337
+ ulong out_prunes_len ;
338
+
339
+ fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 3UL , & out_prunes , & out_prunes_len );
340
+ /* Should generate prunes for the bad relayer */
341
+ FD_TEST ( out_prunes_len == 1UL );
342
+ FD_TEST ( !memcmp ( out_prunes [0 ].relayer_pubkey .uc , bad_relayer .pubkey , 32UL ) );
343
+ FD_TEST ( out_prunes [0 ].prune_len == 1UL );
344
+ FD_TEST ( !memcmp ( out_prunes [0 ].prunes [0 ].uc , origin .pubkey , 32UL ) );
345
+
346
+ free ( bytes );
347
+ }
348
+
304
349
void
305
350
test_relayer_eviction ( void ) {
306
351
fd_rng_t _rng [1 ]; fd_rng_t * rng = fd_rng_join ( fd_rng_new ( _rng , 0U , 0UL ) );
@@ -395,7 +440,7 @@ test_multiple_origins( void ) {
395
440
}
396
441
397
442
uchar const * origins [2 ] = { origin1 .pubkey , origin2 .pubkey };
398
- fd_prune_finder_prune_t * out_prunes ;
443
+ fd_prune_finder_prune_t const * out_prunes ;
399
444
ulong out_prunes_len ;
400
445
401
446
fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 2UL , & out_prunes , & out_prunes_len );
@@ -455,7 +500,7 @@ test_stake_threshold_with_pruning( void ) {
455
500
}
456
501
457
502
uchar const * origins [1 ] = { origin .pubkey };
458
- fd_prune_finder_prune_t * out_prunes ;
503
+ fd_prune_finder_prune_t const * out_prunes ;
459
504
ulong out_prunes_len ;
460
505
461
506
fd_prune_finder_get_prunes ( pf , 1000000UL , origins , 1UL , & out_prunes , & out_prunes_len );
@@ -495,6 +540,9 @@ main( int argc,
495
540
test_get_prunes_tiebreaker ();
496
541
FD_LOG_NOTICE (( "test_get_prunes_tiebreaker() passed" ));
497
542
543
+ test_get_prunes_duplicate_origins ();
544
+ FD_LOG_NOTICE (( "test_get_prunes_duplicate_origins() passed" ));
545
+
498
546
test_relayer_eviction ();
499
547
FD_LOG_NOTICE (( "test_relayer_eviction() passed" ));
500
548
0 commit comments