Skip to content

Commit

Permalink
fd_wsample: improve performance
Browse files Browse the repository at this point in the history
Switch from using treap to using a light-weight radix-9 tree inspired by
a B-tree.  Almost entirely branch-free because branch mispredictions
were killer.
  • Loading branch information
ptaffet-jump committed Jan 31, 2024
1 parent 6aeab43 commit 0bb91a0
Show file tree
Hide file tree
Showing 11 changed files with 514 additions and 252 deletions.
2 changes: 1 addition & 1 deletion src/app/fdctl/run/tiles/fd_shred.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ after_frag( void * _ctx,

for( ulong j=0UL; j<*max_dest_cnt; j++ ) send_shred( ctx, *out_shred, sdest, dests[ j ], ctx->tsorig );
}
if( FD_UNLIKELY( rv!=FD_FEC_RESOLVER_SHRED_COMPLETES ) ) return;
if( FD_LIKELY( rv!=FD_FEC_RESOLVER_SHRED_COMPLETES ) ) return;

FD_TEST( ctx->fec_sets <= *out_fec_set );
ctx->send_fec_set_idx = (ulong)(*out_fec_set - ctx->fec_sets);
Expand Down
516 changes: 355 additions & 161 deletions src/ballet/wsample/fd_wsample.c

Large diffs are not rendered by default.

25 changes: 19 additions & 6 deletions src/ballet/wsample/fd_wsample.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,28 @@
struct fd_wsample_private;
typedef struct fd_wsample_private fd_wsample_t;

#define FD_WSAMPLE_ALIGN (32UL)
#define FD_WSAMPLE_FOOTPRINT( ele_cnt, restore_enabled ) (((ele_cnt)<UINT_MAX) ? \
( 64UL + ((restore_enabled)?64UL:32UL)*(ele_cnt) ) : 0UL)
#define FD_WSAMPLE_ALIGN (64UL)
/* fd_leaders really wants a compile time-compatible footprint... The
internal count is 1/8 * (9^ceil(log_9(ele_cnt)) - 1) */
#define FD_WSAMPLE_FOOTPRINT( ele_cnt, restore_enabled ) \
(192UL + 64UL*((restore_enabled)?2UL:1UL)*( \
((ele_cnt)<= 1UL)? 0UL : \
((ele_cnt)<= 9UL)? 1UL : \
((ele_cnt)<= 81UL)? 10UL : \
((ele_cnt)<= 729UL)? 91UL : \
((ele_cnt)<= 6561UL)? 820UL : \
((ele_cnt)<= 59049UL)? 7381UL : \
((ele_cnt)<= 531441UL)? 66430UL : \
((ele_cnt)<= 4782969UL)? 597871UL : \
((ele_cnt)<= 43046721UL)? 5380840UL : \
((ele_cnt)<= 387420489UL)? 48427561UL : \
((ele_cnt)<=3486784401UL)?435848050UL : 3922632451UL )) \

/* fd_wsample_{align, footprint} give the alignment and footprint
respectively required to create a weighted sampler with at most
ele_cnt stake weights. If restore_enabled is zero, calls to
wsample_restore_all will be no-ops, but the footprint required will
be smaller.
be smaller. ele_cnt in [0, UINT_MAX-1) (note, not ULONG MAX).
fd_wsample_{join,leave} join and leave a memory region formatted as a
weighted sampler, respectively. They both are simple casts.
Expand Down Expand Up @@ -88,7 +101,7 @@ void * fd_wsample_delete ( void * shmem );
fd_wsample_new_add adds a weight to a partially formatted memory
region. shmem must be a partially constructed region of memory, as
returned by fd_wsample_new_init or fd_wsample_new_add_weight weight
returned by fd_wsample_new_init or fd_wsample_new_add_weight, weight
must be strictly positive, and the cumulative sum of this weight and
all other weights must be less than ULONG_MAX.
Expand Down
45 changes: 35 additions & 10 deletions src/ballet/wsample/test_wsample.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
#include <math.h>

#define MAX 1024UL
#define MAX_FOOTPRINT (1024UL + 64UL*MAX)
#define MAX_FOOTPRINT (128UL + 128UL*(MAX*9UL+7UL)/8UL)

uchar _shmem[MAX_FOOTPRINT] __attribute__((aligned(128)));
uchar _shmem [MAX_FOOTPRINT] __attribute__((aligned(128)));
uchar _shmem2[MAX_FOOTPRINT] __attribute__((aligned(128)));
ulong weights[MAX];
ulong counts[MAX];

Expand Down Expand Up @@ -220,6 +221,7 @@ test_matches_solana( void ) {
tree = fd_wsample_join( fd_wsample_new_fini( partial ) );
fd_wsample_seed_rng( fd_wsample_get_rng( tree ), zero_seed );


FD_TEST( fd_wsample_sample_and_remove( tree ) == 9UL );
FD_TEST( fd_wsample_sample_and_remove( tree ) == 3UL );
FD_TEST( fd_wsample_sample_and_remove( tree ) == 12UL );
Expand Down Expand Up @@ -252,8 +254,8 @@ test_sharing( void ) {
fd_chacha20rng_t * rng = fd_chacha20rng_join( fd_chacha20rng_new( _rng, FD_CHACHA20RNG_MODE_SHIFT ) );
fd_chacha20rng_init( rng, zero_seed );

void * pl1 = fd_wsample_new_init( _shmem, rng, 2UL, 0, FD_WSAMPLE_HINT_FLAT );
void * pl2 = fd_wsample_new_init( _shmem+MAX_FOOTPRINT/2UL, rng, 2UL, 0, FD_WSAMPLE_HINT_FLAT );
void * pl1 = fd_wsample_new_init( _shmem , rng, 2UL, 0, FD_WSAMPLE_HINT_FLAT );
void * pl2 = fd_wsample_new_init( _shmem2, rng, 2UL, 0, FD_WSAMPLE_HINT_FLAT );
fd_wsample_t * sample1 = fd_wsample_join( fd_wsample_new_fini( fd_wsample_new_add( fd_wsample_new_add( pl1, 2UL ), 1UL ) ) );
fd_wsample_t * sample2 = fd_wsample_join( fd_wsample_new_fini( fd_wsample_new_add( fd_wsample_new_add( pl2, 2UL ), 1UL ) ) );

Expand Down Expand Up @@ -283,8 +285,8 @@ test_restore_disabled( void ) {
fd_chacha20rng_t * rng = fd_chacha20rng_join( fd_chacha20rng_new( _rng, FD_CHACHA20RNG_MODE_SHIFT ) );
fd_chacha20rng_init( rng, zero_seed );

void * partial1 = fd_wsample_new_init( _shmem, rng, 2UL, 0, FD_WSAMPLE_HINT_FLAT );
void * partial2 = fd_wsample_new_init( _shmem+MAX_FOOTPRINT/2UL, rng, 2UL, 1, FD_WSAMPLE_HINT_FLAT );
void * partial1 = fd_wsample_new_init( _shmem, rng, 2UL, 0, FD_WSAMPLE_HINT_FLAT );
void * partial2 = fd_wsample_new_init( _shmem2, rng, 2UL, 1, FD_WSAMPLE_HINT_FLAT );
fd_wsample_t * sample1 = fd_wsample_join( fd_wsample_new_fini( fd_wsample_new_add( fd_wsample_new_add( partial1, 2UL ), 1UL ) ) );
fd_wsample_t * sample2 = fd_wsample_join( fd_wsample_new_fini( fd_wsample_new_add( fd_wsample_new_add( partial2, 2UL ), 1UL ) ) );

Expand Down Expand Up @@ -378,24 +380,47 @@ test_empty( void ) {
fd_chacha20rng_delete( fd_chacha20rng_leave( rng ) );
}

static void
test_footprint( void ) {
/* Looping over all integers up to UINT_MAX took too long. A CBMC
proof would be nice. */
for( ulong i=0UL; i<1000UL; i++ ) {
FD_TEST( FD_WSAMPLE_FOOTPRINT( i, 0 ) == fd_wsample_footprint( i, 0 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i, 1 ) == fd_wsample_footprint( i, 1 ) );
}
for( ulong i=729UL; i<UINT_MAX; i*=3UL ) {
FD_TEST( FD_WSAMPLE_FOOTPRINT( i-1UL, 0 ) == fd_wsample_footprint( i-1UL, 0 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i-1UL, 1 ) == fd_wsample_footprint( i-1UL, 1 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i, 0 ) == fd_wsample_footprint( i, 0 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i, 1 ) == fd_wsample_footprint( i, 1 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i+1UL, 0 ) == fd_wsample_footprint( i+1UL, 0 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i+1UL, 1 ) == fd_wsample_footprint( i+1UL, 1 ) );
}
for( ulong i=512UL; i<UINT_MAX; i*=2UL ) {
FD_TEST( FD_WSAMPLE_FOOTPRINT( i-1UL, 0 ) == fd_wsample_footprint( i-1UL, 0 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i-1UL, 1 ) == fd_wsample_footprint( i-1UL, 1 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i, 0 ) == fd_wsample_footprint( i, 0 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i, 1 ) == fd_wsample_footprint( i, 1 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i+1UL, 0 ) == fd_wsample_footprint( i+1UL, 0 ) );
FD_TEST( FD_WSAMPLE_FOOTPRINT( i+1UL, 1 ) == fd_wsample_footprint( i+1UL, 1 ) );
}
}

int
main( int argc,
char ** argv ) {
fd_boot( &argc, &argv );

FD_TEST( fd_wsample_footprint( UINT_MAX, 1 ) == 0UL );
FD_TEST( fd_wsample_footprint( MAX, 1 ) );
FD_TEST( fd_wsample_footprint( MAX, 1 )<MAX_FOOTPRINT );

for( ulong i=0UL; i<=(ulong)UINT_MAX+11UL; i+=11UL ) FD_TEST( fd_wsample_footprint( i, 0 ) == FD_WSAMPLE_FOOTPRINT( i, 0 ) );
for( ulong i=0UL; i<=(ulong)UINT_MAX+11UL; i+=11UL ) FD_TEST( fd_wsample_footprint( i, 11 ) == FD_WSAMPLE_FOOTPRINT( i, 21 ) );

test_matches_solana();
test_map();
test_sharing();
test_restore_disabled();
test_remove_idx();
test_empty();
test_footprint();

test_probability_dist_replacement();
test_probability_dist_noreplacement();
Expand Down
51 changes: 35 additions & 16 deletions src/disco/shred/fd_shred_dest.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ struct __attribute__((packed)) shred_dest_input {
typedef struct shred_dest_input shred_dest_input_t;

ulong
fd_shred_dest_footprint( ulong cnt ) {
fd_shred_dest_footprint( ulong staked_cnt, ulong unstaked_cnt ) {
ulong cnt = staked_cnt+unstaked_cnt;
int lg_cnt = fd_ulong_find_msb( fd_ulong_pow2_up( 2UL*fd_ulong_max( cnt, 1UL ) ) );
return FD_LAYOUT_FINI( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND(
FD_LAYOUT_INIT,
fd_shred_dest_align(), sizeof(fd_shred_dest_t) ),
fd_wsample_align(), fd_wsample_footprint( cnt, 1 ) ),
fd_wsample_align(), fd_wsample_footprint( 0UL, 1 ) ),
pubkey_to_idx_align(), pubkey_to_idx_footprint( lg_cnt ) ),
alignof(fd_shred_dest_weighted_t), sizeof(fd_shred_dest_weighted_t)*cnt ),
fd_wsample_align(), fd_wsample_footprint( staked_cnt, 1 )),
alignof(ulong), sizeof(ulong)*unstaked_cnt ),
FD_SHRED_DEST_ALIGN );
}

Expand All @@ -66,8 +67,6 @@ fd_shred_dest_new( void * mem,
FD_SCRATCH_ALLOC_INIT( footprint, mem );
fd_shred_dest_t * sdest;
/* */ sdest = FD_SCRATCH_ALLOC_APPEND( footprint, fd_shred_dest_align(), sizeof(fd_shred_dest_t) );
void * _wsample = FD_SCRATCH_ALLOC_APPEND( footprint, fd_wsample_align(), fd_wsample_footprint( cnt, 1 ) );
/* */ FD_SCRATCH_ALLOC_APPEND( footprint, fd_wsample_align(), fd_wsample_footprint( 0UL, 1 ) );
void * _map = FD_SCRATCH_ALLOC_APPEND( footprint, pubkey_to_idx_align(), pubkey_to_idx_footprint( lg_cnt ) );
void * _info = FD_SCRATCH_ALLOC_APPEND( footprint, alignof(fd_shred_dest_weighted_t), sizeof(fd_shred_dest_weighted_t)*cnt );

Expand All @@ -89,13 +88,13 @@ fd_shred_dest_new( void * mem,
ulong staked_cnt = cnts[0];
ulong unstaked_cnt = cnts[1];

void * _wsample = FD_SCRATCH_ALLOC_APPEND( footprint, fd_wsample_align(), fd_wsample_footprint( staked_cnt, 1 ));
void * _unstaked = FD_SCRATCH_ALLOC_APPEND( footprint, alignof(ulong), sizeof(ulong)*unstaked_cnt );


fd_chacha20rng_t * rng = fd_chacha20rng_join( fd_chacha20rng_new( sdest->rng, FD_CHACHA20RNG_MODE_SHIFT ) );

/* We reserved enough space in _wsample for both the staked and
unstaked info */
void * _staked = fd_wsample_new_init( _wsample, rng, staked_cnt, 1, FD_WSAMPLE_HINT_POWERLAW_REMOVE );
ulong * unstaked = (ulong *)fd_ulong_align_up( ((ulong)_wsample + fd_wsample_footprint( staked_cnt, 1 )), alignof(ulong) );

for( ulong i=0UL; i<staked_cnt; i++ ) _staked = fd_wsample_new_add( _staked, info[i].stake_lamports );
_staked = fd_wsample_new_fini( _staked );
Expand All @@ -115,7 +114,7 @@ fd_shred_dest_new( void * mem,
sdest->cnt = cnt;
sdest->all_destinations = copy;
sdest->staked = fd_wsample_join( _staked );
sdest->unstaked = unstaked;
sdest->unstaked = _unstaked;
sdest->unstaked_unremoved_cnt = 0UL; /* unstaked doesn't get initialized until it's needed */
sdest->staked_cnt = staked_cnt;
sdest->unstaked_cnt = unstaked_cnt;
Expand Down Expand Up @@ -335,6 +334,9 @@ fd_shred_dest_compute_children( fd_shred_dest_t * sdest,

ulong max_dest_cnt = 0UL;

ulong staked_shuffle[ sdest->staked_cnt+1UL ];
ulong staked_shuffle_populated_cnt = 0UL;

for( ulong i=0UL; i<shred_cnt; i++ ) {
/* Remove the leader. */
if( FD_LIKELY( query && leader_is_staked ) ) fd_wsample_remove_idx( sdest->staked, leader_idx );
Expand All @@ -344,10 +346,14 @@ fd_shred_dest_compute_children( fd_shred_dest_t * sdest,

if( FD_UNLIKELY( !i_am_staked ) ) {
/* Quickly burn through all the staked nodes since I'll be in the
unstaked portion. There can't be too many of them since
otherwise we would have taken the quick exit at the start of
the function. */
while( fd_wsample_sample_and_remove( sdest->staked ) != FD_WSAMPLE_EMPTY ) my_idx++;
unstaked portion. We don't care about the values, but we need
to advance the RNG the right number of times, and sadly there's
no other way to do it than this. There can't be too many of
them since otherwise we would have taken the quick exit at the
start of the function. */
staked_shuffle_populated_cnt = sdest->staked_cnt + 1UL;
fd_wsample_sample_and_remove_many( sdest->staked, staked_shuffle, staked_shuffle_populated_cnt );
my_idx += sdest->staked_cnt - (ulong)(query && leader_is_staked);

prepare_unstaked_sampling( sdest, leader_idx );
while( my_idx <= fanout ) {
Expand All @@ -357,8 +363,14 @@ fd_shred_dest_compute_children( fd_shred_dest_t * sdest,
my_idx++;
}
} else {
staked_shuffle_populated_cnt = fd_ulong_min( fanout+1UL, sdest->staked_cnt+1UL );
fd_wsample_sample_and_remove_many( sdest->staked, staked_shuffle, staked_shuffle_populated_cnt );
while( my_idx <= fanout ) {
ulong sample = fd_wsample_sample_and_remove( sdest->staked );
/* my_idx < fanout+1UL because of the while loop condition.
my_idx < staked_cnt+1UL because my_idx==staked_cnt will
trigger sample==FD_WSAMPLE_EMPTY below. Thus, this access is
safe. */
ulong sample = staked_shuffle[ my_idx ];
if( FD_UNLIKELY( sample==my_orig_idx ) ) break; /* Found me! */
if( FD_UNLIKELY( sample==FD_WSAMPLE_EMPTY ) ) return NULL; /* I couldn't find myself. This should be impossible. */
my_idx++;
Expand Down Expand Up @@ -389,8 +401,15 @@ fd_shred_dest_compute_children( fd_shred_dest_t * sdest,
ulong cursor = my_idx+1UL;
ulong stored_cnt = 0UL;

while( cursor<=last_dest_idx ) {
ulong sample = fd_wsample_sample_and_remove( sdest->staked );
if( FD_LIKELY( (last_dest_idx>=staked_shuffle_populated_cnt) & (staked_shuffle_populated_cnt<sdest->staked_cnt+1UL ) ) ) {
ulong adtl = fd_ulong_min( last_dest_idx+1UL, sdest->staked_cnt+1UL ) - staked_shuffle_populated_cnt;

fd_wsample_sample_and_remove_many( sdest->staked, staked_shuffle+staked_shuffle_populated_cnt, adtl );
staked_shuffle_populated_cnt += adtl;
}

while( cursor<=fd_ulong_min( last_dest_idx, sdest->staked_cnt ) ) {
ulong sample = staked_shuffle[ cursor ];
if( FD_UNLIKELY( sample==FD_WSAMPLE_EMPTY ) ) break;

if( FD_UNLIKELY( cursor == my_idx + stride*(stored_cnt+1UL) ) ) {
Expand Down
13 changes: 10 additions & 3 deletions src/disco/shred/fd_shred_dest.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,23 @@ struct __attribute__((aligned(FD_SHRED_DEST_ALIGN))) fd_shred_dest_private {
pubkey_to_idx_t * pubkey_to_idx_map; /* maps pubkey -> [0, staked_cnt+unstaked_cnt) */

ulong source_validator_orig_idx; /* in [0, staked_cnt+unstaked_cnt) */
/* Struct followed by:
* pubkey_to_idx map
* all_destinations
* staked
* unstaked
*/
};
typedef struct fd_shred_dest_private fd_shred_dest_t;


/* fd_shred_dest_{align, footprint} return the alignment and footprint
(respectively) required of a region of memory to format it as an
fd_shred_dest_t object. cnt is the number of destinations, both
staked and unstaked, that this object can store. */
fd_shred_dest_t object. staked_cnt is the number of destinations
with positive stake while unstaked_cnt is the number of destinations
with zero stake that this object can store. */
static inline ulong fd_shred_dest_align ( void ) { return FD_SHRED_DEST_ALIGN; }
/* */ ulong fd_shred_dest_footprint( ulong cnt );
/* */ ulong fd_shred_dest_footprint( ulong staked_cnt, ulong unstaked_cnt );

/* fd_shred_dest_new formats a region of memory for use as an
fd_shred_dest_t object. mem points to the first byte of a region of
Expand Down
7 changes: 4 additions & 3 deletions src/disco/shred/fd_stake_ci.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@

#define MAX_SHRED_DESTS 40200UL
#define MAX_SLOTS_PER_EPOCH 432000UL
/* MAX_SHRED_DEST_FOOTPRINT==fd_shred_dest_footprint( MAX_SHRED_DESTS ),
runtime asserted in the tests. The size of fd_shred_dest_t, varies
/* staked+unstaked <= MAX_SHRED_DESTS implies
MAX_SHRED_DEST_FOOTPRINT>=fd_shred_dest_footprint( staked, unstaked )
This is asserted in the tests. The size of fd_shred_dest_t, varies
based on FD_SHA256_BATCH_FOOTPRINT, which depends on the compiler
settings. */
#define MAX_SHRED_DEST_FOOTPRINT (10067072UL + sizeof(fd_shred_dest_t))
#define MAX_SHRED_DEST_FOOTPRINT (8708224UL + sizeof(fd_shred_dest_t))

#define FD_STAKE_CI_STAKE_MSG_SZ (32UL + MAX_SHRED_DESTS * 40UL)

Expand Down
16 changes: 8 additions & 8 deletions src/disco/shred/test_shred_dest.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ test_compute_first_matches_solana( void ) {
ulong cnt = t1_dest_info_sz / sizeof(fd_shred_dest_weighted_t);
fd_shred_dest_weighted_t const * info = (fd_shred_dest_weighted_t const *)t1_dest_info;
fd_pubkey_t const * src_key = (fd_pubkey_t const *)t1_pubkey;
FD_TEST( fd_shred_dest_footprint ( cnt ) <= TEST_MAX_FOOTPRINT );
FD_TEST( fd_epoch_leaders_footprint( cnt, 10000UL ) <= TEST_MAX_FOOTPRINT );

ulong staked = 0UL;
for( ulong i=0UL; i<cnt; i++ ) {
Expand All @@ -31,6 +29,8 @@ test_compute_first_matches_solana( void ) {
stakes[i].stake = info[i].stake_lamports;
staked += (info[i].stake_lamports>0UL);
}
FD_TEST( fd_shred_dest_footprint ( staked, staked-cnt ) <= TEST_MAX_FOOTPRINT );
FD_TEST( fd_epoch_leaders_footprint( cnt, 10000UL ) <= TEST_MAX_FOOTPRINT );

fd_epoch_leaders_t * lsched = fd_epoch_leaders_join( fd_epoch_leaders_new( _l_footprint, 0UL, 0UL, 10000UL, staked, stakes ) );

Expand Down Expand Up @@ -71,8 +71,6 @@ test_compute_children_matches_solana( void ) {
ulong cnt = t1_dest_info_sz / sizeof(fd_shred_dest_weighted_t);
fd_shred_dest_weighted_t const * info = (fd_shred_dest_weighted_t const *)t1_dest_info;
fd_pubkey_t const * src_key = (fd_pubkey_t const *)t1_pubkey;
FD_TEST( fd_shred_dest_footprint ( cnt ) <= TEST_MAX_FOOTPRINT );
FD_TEST( fd_epoch_leaders_footprint( cnt, 2000UL ) <= TEST_MAX_FOOTPRINT );

ulong staked = 0UL;
for( ulong i=0UL; i<cnt; i++ ) {
Expand All @@ -81,6 +79,9 @@ test_compute_children_matches_solana( void ) {
staked += (info[i].stake_lamports>0UL);
}

FD_TEST( fd_shred_dest_footprint ( staked, cnt-staked ) <= TEST_MAX_FOOTPRINT );
FD_TEST( fd_epoch_leaders_footprint( cnt, 2000UL ) <= TEST_MAX_FOOTPRINT );

fd_epoch_leaders_t * lsched = fd_epoch_leaders_join( fd_epoch_leaders_new( _l_footprint, 0UL, 0UL, 4000UL, staked, stakes ) );

fd_shred_dest_t * sdest = fd_shred_dest_join( fd_shred_dest_new( _sd_footprint, info, cnt, lsched, src_key ) );
Expand Down Expand Up @@ -332,18 +333,17 @@ test_performance( void ) {

fd_pubkey_t const * src_key = (fd_pubkey_t const *)(&info[18].pubkey);
FD_TEST( cnt <= TEST_MAX_VALIDATORS );
FD_TEST( fd_shred_dest_footprint ( cnt ) <= TEST_MAX_FOOTPRINT );
FD_TEST( fd_epoch_leaders_footprint( cnt, 10000UL ) <= TEST_MAX_FOOTPRINT );

ulong staked = 0UL;
ulong total_stake = 0UL;
for( ulong i=0UL; i<cnt; i++ ) {
stakes[i].key = info[i].pubkey;
stakes[i].stake = info[i].stake_lamports;
total_stake += info[i].stake_lamports;
staked += (info[i].stake_lamports>0UL);
}

FD_TEST( fd_shred_dest_footprint ( staked, cnt-staked ) <= TEST_MAX_FOOTPRINT );
FD_TEST( fd_epoch_leaders_footprint( cnt, 10000UL ) <= TEST_MAX_FOOTPRINT );

long dt = -fd_log_wallclock();
fd_epoch_leaders_t * lsched = fd_epoch_leaders_join( fd_epoch_leaders_new( _l_footprint, 0UL, 0UL, 10000UL, staked, stakes ) );
fd_shred_dest_t * sdest = fd_shred_dest_join ( fd_shred_dest_new ( _sd_footprint, info, cnt, lsched, src_key ) );
Expand Down
Loading

0 comments on commit 0bb91a0

Please sign in to comment.