Skip to content

Commit c77a97b

Browse files
committed
gossip: rx_push plumbing for get_prunes call
1 parent 3d366e9 commit c77a97b

File tree

4 files changed

+99
-28
lines changed

4 files changed

+99
-28
lines changed

src/flamenco/gossip/fd_gossip.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,11 @@ process_push_crds( fd_gossip_t * gossip,
600600
return 0;
601601
}
602602

603+
#define SORT_NAME sort_pubkey
604+
#define SORT_KEY_T uchar const *
605+
#define SORT_BEFORE(a,b) (memcmp(a,b,32UL) < 0)
606+
#include "../../util/tmpl/fd_sort.c"
607+
603608
static void
604609
rx_push( fd_gossip_t * gossip,
605610
fd_gossip_view_push_t const * push,
@@ -608,8 +613,11 @@ rx_push( fd_gossip_t * gossip,
608613
fd_stem_context_t * stem ) {
609614
uchar const * relayer_pubkey = payload+push->from_off;
610615
ulong relayer_stake = get_stake( gossip, relayer_pubkey );
616+
uchar const * origin_pubkeys[ FD_GOSSIP_MSG_MAX_CRDS ];
617+
611618
for( ulong i=0UL; i<push->crds_values_len; i++ ) {
612619
uchar const * pubkey = payload+push->crds_values[ i ].pubkey_off;
620+
origin_pubkeys[ i ] = pubkey;
613621
ulong stake = get_stake( gossip, pubkey );
614622

615623
int err = process_push_crds( gossip, &push->crds_values[ i ], payload, pubkey, stake, now, stem );
@@ -623,6 +631,19 @@ rx_push( fd_gossip_t * gossip,
623631
num_duplicates );
624632
}
625633
}
634+
635+
fd_prune_finder_prune_t const * prunes = NULL;
636+
ulong prunes_cnt;
637+
fd_prune_finder_get_prunes( gossip->prune_finder,
638+
gossip->identity_stake,
639+
origin_pubkeys,
640+
push->crds_values_len,
641+
&prunes,
642+
&prunes_cnt );
643+
644+
for( ulong i=0UL; i<prunes_cnt; i++ ) {
645+
/* TODO: generate and send prune message */
646+
}
626647
}
627648

628649
static void

src/flamenco/gossip/fd_prune_finder.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,12 +446,12 @@ prune_origin( fd_prune_finder_t * pf,
446446
}
447447

448448
void
449-
fd_prune_finder_get_prunes( fd_prune_finder_t * pf,
450-
ulong my_stake,
451-
uchar const * const * origins,
452-
ulong origins_len,
453-
fd_prune_finder_prune_t ** out_prunes,
454-
ulong * out_prunes_len ) {
449+
fd_prune_finder_get_prunes( fd_prune_finder_t * pf,
450+
ulong my_stake,
451+
uchar const * const * origins,
452+
ulong origins_len,
453+
fd_prune_finder_prune_t const ** out_prunes,
454+
ulong * out_prunes_len ) {
455455
/* Clear out current prunes map */
456456
for( ulong i=0UL; i<pf->prunes.count; i++ ) {
457457
fd_prune_finder_prune_t * p = prunes_pool_ele( pf->prunes.pool, i );

src/flamenco/gossip/fd_prune_finder.h

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,17 @@ fd_prune_finder_record( fd_prune_finder_t * pf,
125125

126126
/* fd_prune_finder_get_prunes generates a list of out_prunes_len
127127
fd_prune_finder_prune_t entries in out_prunes. This should be called
128-
at the end of every rx_push loop. out_prunes_len can be unbounded.
129-
130-
origins holds a unique list of pubkeys which should be considered
131-
for pruning. All origins must have been recorded with
132-
fd_prune_finder_record at least once since the last call to
133-
fd_prune_finder_get_prunes. Since the maximum number of unique
134-
origins that can be encountered during a single rx_push loop is
135-
bounded by FD_GOSSIP_MSG_MAX_CRDS, origins_len should not exceed
136-
that.
128+
at the end of every push rx loop. out_prunes_len is bounded by
129+
origins_len*relayer_max_per_origin (supplied in
130+
fd_prune_finder_new).
131+
132+
origins holds a list of pubkeys which should be considered
133+
for pruning. Duplicates are OK, and will be skipped.
134+
All origins must have been recorded with fd_prune_finder_record at
135+
least once since the last call to fd_prune_finder_get_prunes. Since
136+
the maximum number of unique origins that can be encountered during
137+
a single rx_push loop is bounded by FD_GOSSIP_MSG_MAX_CRDS,
138+
origins_len should not exceed that.
137139
138140
Origins that appear in any out_prunes entry will have their prune
139141
finder state reset. Therefore all prune messages must be
@@ -142,12 +144,12 @@ fd_prune_finder_record( fd_prune_finder_t * pf,
142144
call. */
143145

144146
void
145-
fd_prune_finder_get_prunes( fd_prune_finder_t * pf,
146-
ulong my_stake,
147-
uchar const * const * origins,
148-
ulong origins_len,
149-
fd_prune_finder_prune_t ** out_prunes,
150-
ulong * out_prunes_len );
147+
fd_prune_finder_get_prunes( fd_prune_finder_t * pf,
148+
ulong my_stake,
149+
uchar const * const * origins,
150+
ulong origins_len,
151+
fd_prune_finder_prune_t const ** out_prunes,
152+
ulong * out_prunes_len );
151153

152154
FD_PROTOTYPES_END
153155

src/flamenco/gossip/test_prune_finder.c

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ test_get_prunes_insufficient_upserts( void ) {
9292
}
9393

9494
uchar const * origins[1] = { origin.pubkey };
95-
fd_prune_finder_prune_t * out_prunes;
95+
fd_prune_finder_prune_t const * out_prunes;
9696
ulong out_prunes_len;
9797

9898
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 ) {
128128
}
129129

130130
uchar const * origins[1] = { origin.pubkey };
131-
fd_prune_finder_prune_t * out_prunes;
131+
fd_prune_finder_prune_t const * out_prunes;
132132
ulong out_prunes_len;
133133

134134
fd_prune_finder_get_prunes( pf, 1000000UL, origins, 1UL, &out_prunes, &out_prunes_len );
@@ -178,7 +178,7 @@ test_get_prunes_basic( void ) {
178178
fd_prune_finder_record( pf, origin.pubkey, origin.stake, good_relayer_1.pubkey, good_relayer_1.stake, 0UL );
179179

180180
uchar const * origins[1] = { origin.pubkey };
181-
fd_prune_finder_prune_t * out_prunes;
181+
fd_prune_finder_prune_t const * out_prunes;
182182
ulong out_prunes_len;
183183

184184
fd_prune_finder_get_prunes( pf, 1000000UL, origins, 1UL, &out_prunes, &out_prunes_len );
@@ -227,7 +227,7 @@ test_get_prunes_tiebreaker( void ) {
227227
}
228228

229229
uchar const * origins[1] = { origin.pubkey };
230-
fd_prune_finder_prune_t * out_prunes;
230+
fd_prune_finder_prune_t const * out_prunes;
231231
ulong out_prunes_len;
232232

233233
fd_prune_finder_get_prunes( pf, 1000000UL, origins, 1UL, &out_prunes, &out_prunes_len );
@@ -266,7 +266,7 @@ test_get_prunes_reset_origin( void ) {
266266
}
267267

268268
uchar const * origins[1] = { origin.pubkey };
269-
fd_prune_finder_prune_t * out_prunes;
269+
fd_prune_finder_prune_t const * out_prunes;
270270
ulong out_prunes_len;
271271

272272
fd_prune_finder_get_prunes( pf, 1000000UL, origins, 1UL, &out_prunes, &out_prunes_len );
@@ -301,6 +301,51 @@ test_get_prunes_reset_origin( void ) {
301301
free( bytes );
302302
}
303303

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+
304349
void
305350
test_relayer_eviction( void ) {
306351
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 ) {
395440
}
396441

397442
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;
399444
ulong out_prunes_len;
400445

401446
fd_prune_finder_get_prunes( pf, 1000000UL, origins, 2UL, &out_prunes, &out_prunes_len );
@@ -455,7 +500,7 @@ test_stake_threshold_with_pruning( void ) {
455500
}
456501

457502
uchar const * origins[1] = { origin.pubkey };
458-
fd_prune_finder_prune_t * out_prunes;
503+
fd_prune_finder_prune_t const * out_prunes;
459504
ulong out_prunes_len;
460505

461506
fd_prune_finder_get_prunes( pf, 1000000UL, origins, 1UL, &out_prunes, &out_prunes_len );
@@ -495,6 +540,9 @@ main( int argc,
495540
test_get_prunes_tiebreaker();
496541
FD_LOG_NOTICE(( "test_get_prunes_tiebreaker() passed" ));
497542

543+
test_get_prunes_duplicate_origins();
544+
FD_LOG_NOTICE(( "test_get_prunes_duplicate_origins() passed" ));
545+
498546
test_relayer_eviction();
499547
FD_LOG_NOTICE(( "test_relayer_eviction() passed" ));
500548

0 commit comments

Comments
 (0)