Skip to content

Commit 06e5430

Browse files
committed
simd-0180: implement vote-based leader schedule for firedancer
1 parent a869533 commit 06e5430

File tree

7 files changed

+124
-261
lines changed

7 files changed

+124
-261
lines changed

src/discof/replay/fd_exec.h

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,23 @@
66
#include "../../flamenco/runtime/fd_runtime.h"
77
#include "../../flamenco/stakes/fd_stakes.h"
88
#include "../../flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.h"
9+
#include "../../discof/restore/utils/fd_ssmsg.h"
10+
11+
/* FIXME: SIMD-0180 - set the correct epochs */
12+
#define FD_SIMD0180_ACTIVE_EPOCH_TESTNET (5000)
13+
#define FD_SIMD0180_ACTIVE_EPOCH_MAINNET (5000)
914

1015
/* Replay tile msg link formatting. The following take a pointer into
1116
a dcache region and formats it as a specific message type. */
1217

1318
static inline ulong
14-
generate_stake_weight_msg( fd_exec_slot_ctx_t * slot_ctx,
15-
fd_spad_t * runtime_spad,
16-
ulong epoch,
19+
generate_stake_weight_msg( fd_exec_slot_ctx_t * slot_ctx,
20+
ulong epoch,
1721
fd_vote_accounts_global_t const * vote_accounts,
18-
ulong * stake_weight_msg_out ) {
19-
/* This function needs to be completely rewritten for SIMD-0180.
20-
For now it's a hack that sends old data (pre SIMD-0180) in the new format. */
21-
22-
fd_stake_weight_msg_t * stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out );
23-
fd_vote_stake_weight_t * stake_weights = stake_weight_msg->weights;
24-
ulong staked_cnt = fd_stake_weights_by_node( vote_accounts,
25-
stake_weights,
26-
runtime_spad );
22+
ulong * stake_weight_msg_out ) {
23+
fd_stake_weight_msg_t * stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out );
24+
fd_vote_stake_weight_t * stake_weights = stake_weight_msg->weights;
25+
ulong staked_cnt = fd_stake_weights_by_node( vote_accounts, stake_weights );
2726
fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( slot_ctx->bank );
2827

2928
stake_weight_msg->epoch = epoch;
@@ -36,6 +35,41 @@ generate_stake_weight_msg( fd_exec_slot_ctx_t * slot_ctx,
3635
return fd_stake_weight_msg_sz( staked_cnt );
3736
}
3837

38+
static inline ulong
39+
generate_stake_weight_msg_manifest( ulong epoch,
40+
fd_epoch_schedule_t const * epoch_schedule,
41+
fd_snapshot_manifest_epoch_stakes_t const * epoch_stakes,
42+
ulong * stake_weight_msg_out ) {
43+
fd_stake_weight_msg_t * stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out );
44+
fd_vote_stake_weight_t * stake_weights = stake_weight_msg->weights;
45+
46+
stake_weight_msg->epoch = epoch;
47+
stake_weight_msg->staked_cnt = epoch_stakes->vote_stakes_len;
48+
stake_weight_msg->start_slot = fd_epoch_slot0( epoch_schedule, epoch );
49+
stake_weight_msg->slot_cnt = epoch_schedule->slots_per_epoch;
50+
stake_weight_msg->excluded_stake = 0UL;
51+
stake_weight_msg->vote_keyed_lsched = 1UL;
52+
53+
/* FIXME: SIMD-0180 - hack to (de)activate in testnet vs mainnet.
54+
This code can be removed once the feature is active. */
55+
{
56+
if( ( 1==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_TESTNET )
57+
|| ( 0==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_MAINNET ) ) {
58+
stake_weight_msg->vote_keyed_lsched = 0UL;
59+
}
60+
}
61+
62+
/* epoch_stakes from manifest are already filtered (stake>0), but not sorted */
63+
for( ulong i=0UL; i<epoch_stakes->vote_stakes_len; i++ ) {
64+
stake_weights[ i ].stake = epoch_stakes->vote_stakes[ i ].stake;
65+
memcpy( stake_weights[ i ].id_key.uc, epoch_stakes->vote_stakes[ i ].identity, sizeof(fd_pubkey_t) );
66+
memcpy( stake_weights[ i ].vote_key.uc, epoch_stakes->vote_stakes[ i ].vote, sizeof(fd_pubkey_t) );
67+
}
68+
sort_vote_weights_by_stake_vote_inplace( stake_weights, epoch_stakes->vote_stakes_len);
69+
70+
return fd_stake_weight_msg_sz( epoch_stakes->vote_stakes_len );
71+
}
72+
3973
static inline void
4074
generate_hash_bank_msg( ulong task_infos_gaddr,
4175
ulong lt_hash_gaddr,

src/discof/replay/fd_replay_tile.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ struct fd_replay_tile_ctx {
292292
/* TODO: Remove this and use the parsed manifest generated by snapin
293293
tiles. */
294294
uchar manifest_scratch[ (1UL<<31UL)+(1UL<<28UL) ] __attribute((aligned(FD_SOLANA_MANIFEST_GLOBAL_ALIGN)));
295+
fd_snapshot_manifest_t * manifest;
295296

296297
int read_only; /* The read-only slot is the slot the validator needs
297298
to replay through before it can proceed with any
@@ -363,22 +364,21 @@ publish_stake_weights( fd_replay_tile_ctx_t * ctx,
363364
if( epoch_stakes_root!=NULL ) {
364365
ulong * stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
365366
ulong epoch = fd_slot_to_leader_schedule_epoch( epoch_schedule, fd_bank_slot_get( slot_ctx->bank ) );
366-
ulong stake_weights_sz = generate_stake_weight_msg( slot_ctx, ctx->runtime_spad, epoch - 1, epoch_stakes, stake_weights_msg );
367+
ulong stake_weights_sz = generate_stake_weight_msg( slot_ctx, epoch - 1, epoch_stakes, stake_weights_msg );
367368
ulong stake_weights_sig = 4UL;
368369
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
369370
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
370371
FD_LOG_NOTICE(("sending current epoch stake weights - epoch: %lu, stake_weight_cnt: %lu, start_slot: %lu, slot_cnt: %lu", stake_weights_msg[0], stake_weights_msg[1], stake_weights_msg[2], stake_weights_msg[3]));
371372
}
372373

373374
fd_bank_epoch_stakes_end_locking_query( slot_ctx->bank );
374-
375375
fd_vote_accounts_global_t const * next_epoch_stakes = fd_bank_next_epoch_stakes_locking_query( slot_ctx->bank );
376376
fd_vote_accounts_pair_global_t_mapnode_t * next_epoch_stakes_root = fd_vote_accounts_vote_accounts_root_join( next_epoch_stakes );
377377

378378
if( next_epoch_stakes_root!=NULL ) {
379379
ulong * stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
380380
ulong epoch = fd_slot_to_leader_schedule_epoch( epoch_schedule, fd_bank_slot_get( slot_ctx->bank ) ); /* epoch */
381-
ulong stake_weights_sz = generate_stake_weight_msg( slot_ctx, ctx->runtime_spad, epoch, next_epoch_stakes, stake_weights_msg );
381+
ulong stake_weights_sz = generate_stake_weight_msg( slot_ctx, epoch, next_epoch_stakes, stake_weights_msg );
382382
ulong stake_weights_sig = 4UL;
383383
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
384384
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
@@ -387,6 +387,30 @@ publish_stake_weights( fd_replay_tile_ctx_t * ctx,
387387
fd_bank_next_epoch_stakes_end_locking_query( slot_ctx->bank );
388388
}
389389

390+
static void
391+
publish_stake_weights_manifest( fd_replay_tile_ctx_t * ctx,
392+
fd_stem_context_t * stem,
393+
fd_snapshot_manifest_t const * manifest ) {
394+
fd_epoch_schedule_t const * schedule = fd_type_pun_const( &manifest->epoch_schedule_params );
395+
ulong epoch = fd_slot_to_epoch( schedule, manifest->slot, NULL );
396+
397+
/* current epoch */
398+
ulong * stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
399+
ulong stake_weights_sz = generate_stake_weight_msg_manifest( epoch, schedule, &manifest->epoch_stakes[0], stake_weights_msg );
400+
ulong stake_weights_sig = 4UL;
401+
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
402+
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
403+
FD_LOG_NOTICE(("sending current epoch stake weights - epoch: %lu, stake_weight_cnt: %lu, start_slot: %lu, slot_cnt: %lu", stake_weights_msg[0], stake_weights_msg[1], stake_weights_msg[2], stake_weights_msg[3]));
404+
405+
/* next current epoch */
406+
stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
407+
stake_weights_sz = generate_stake_weight_msg_manifest( epoch + 1, schedule, &manifest->epoch_stakes[1], stake_weights_msg );
408+
stake_weights_sig = 4UL;
409+
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
410+
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
411+
FD_LOG_NOTICE(("sending next epoch stake weights - epoch: %lu, stake_weight_cnt: %lu, start_slot: %lu, slot_cnt: %lu", stake_weights_msg[0], stake_weights_msg[1], stake_weights_msg[2], stake_weights_msg[3]));
412+
}
413+
390414
static void
391415
block_finalize_tiles_cb( void * para_arg_1,
392416
void * para_arg_2,
@@ -589,6 +613,8 @@ restore_slot_ctx( fd_replay_tile_ctx_t * ctx,
589613
ctx->slot_ctx->status_cache = ctx->status_cache;
590614

591615
uchar const * data = fd_chunk_to_laddr( mem, chunk );
616+
ctx->manifest = (fd_snapshot_manifest_t*)data;
617+
592618
uchar const * manifest_bytes = data+sizeof(fd_snapshot_manifest_t);
593619

594620
fd_bincode_decode_ctx_t decode = {
@@ -616,8 +642,8 @@ restore_slot_ctx( fd_replay_tile_ctx_t * ctx,
616642

617643
static void
618644
kickoff_repair_orphans( fd_replay_tile_ctx_t * ctx, fd_stem_context_t * stem ) {
619-
fd_fseq_update( ctx->published_wmark, fd_bank_slot_get( ctx->slot_ctx->bank ) );
620-
publish_stake_weights( ctx, stem, ctx->slot_ctx );
645+
fd_fseq_update( ctx->published_wmark, ctx->manifest->slot );
646+
publish_stake_weights_manifest( ctx, stem, ctx->manifest );
621647
}
622648

623649
static void

src/discof/shredcap/fd_shredcap_tile.c

Lines changed: 23 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "../../flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.h"
1313
#include "../../disco/fd_disco.h"
1414
#include "../../util/pod/fd_pod_format.h"
15+
#include "../replay/fd_exec.h"
1516

1617
#include <errno.h>
1718
#include <fcntl.h>
@@ -227,74 +228,28 @@ scratch_footprint( fd_topo_tile_t const * tile ) {
227228
return FD_LAYOUT_FINI( l, scratch_align() );
228229
}
229230

230-
ulong
231-
fd_stake_weights_by_node_custom( fd_snapshot_manifest_epoch_stakes_t const * epoch_stakes,
232-
fd_vote_stake_weight_t * weights ) {
233-
234-
for( ulong i=0UL; i<epoch_stakes->vote_stakes_len; i++ ) {
235-
weights[ i ].stake = epoch_stakes->vote_stakes[ i ].stake;
236-
memcpy( weights[ i ].id_key.uc, epoch_stakes->vote_stakes[ i ].identity, sizeof(fd_pubkey_t) );
237-
memcpy( weights[ i ].vote_key.uc, epoch_stakes->vote_stakes[ i ].vote, sizeof(fd_pubkey_t) );
238-
}
239-
sort_vote_weights_by_stake_vote_inplace( weights, epoch_stakes->vote_stakes_len);
240-
return epoch_stakes->vote_stakes_len;
241-
}
242-
243-
static inline ulong
244-
generate_stake_weight_msg( ulong epoch,
245-
fd_epoch_schedule_t const * epoch_schedule,
246-
fd_snapshot_manifest_epoch_stakes_t const * epoch_stakes,
247-
ulong * stake_weight_msg_out ) {
248-
249-
fd_stake_weight_msg_t * stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out );
250-
fd_vote_stake_weight_t * stake_weights = stake_weight_msg->weights;
251-
ulong stake_weight_idx = fd_stake_weights_by_node_custom( epoch_stakes, stake_weights );
252-
253-
stake_weight_msg->epoch = epoch;
254-
stake_weight_msg->staked_cnt = stake_weight_idx;
255-
stake_weight_msg->start_slot = fd_epoch_slot0( epoch_schedule, epoch );
256-
stake_weight_msg->slot_cnt = epoch_schedule->slots_per_epoch;
257-
stake_weight_msg->excluded_stake = 0UL;
258-
stake_weight_msg->vote_keyed_lsched = 0UL;
259-
260-
return fd_stake_weight_msg_sz( epoch_stakes->vote_stakes_len );
261-
}
262231
static void
263-
publish_stake_weights( fd_capture_tile_ctx_t * ctx,
264-
fd_stem_context_t * stem,
265-
fd_snapshot_manifest_t const * manifest ) {
266-
FD_SPAD_FRAME_BEGIN( ctx->shared_spad ) {
267-
268-
/* Process the schedule from manifest. */
269-
fd_epoch_schedule_t schedule[1];
270-
schedule[0].slots_per_epoch = manifest->epoch_schedule_params.slots_per_epoch;
271-
schedule[0].leader_schedule_slot_offset = manifest->epoch_schedule_params.leader_schedule_slot_offset;
272-
schedule[0].warmup = manifest->epoch_schedule_params.warmup;
273-
schedule[0].first_normal_epoch = manifest->epoch_schedule_params.first_normal_epoch;
274-
schedule[0].first_normal_slot = manifest->epoch_schedule_params.first_normal_slot;
275-
ulong epoch = fd_slot_to_epoch( schedule, manifest->slot, NULL );
276-
277-
/* current epoch */
278-
if( 1 ) {
279-
ulong * stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
280-
ulong stake_weights_sz = generate_stake_weight_msg( epoch, schedule, &manifest->epoch_stakes[0], stake_weights_msg );
281-
ulong stake_weights_sig = 4UL;
282-
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
283-
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
284-
FD_LOG_NOTICE(("sending current epoch stake weights - epoch: %lu, stake_weight_cnt: %lu, start_slot: %lu, slot_cnt: %lu", stake_weights_msg[0], stake_weights_msg[1], stake_weights_msg[2], stake_weights_msg[3]));
285-
}
286-
287-
/* next current epoch */
288-
if( 1 ) {
289-
ulong * stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
290-
ulong stake_weights_sz = generate_stake_weight_msg( epoch + 1, schedule, &manifest->epoch_stakes[1], stake_weights_msg );
291-
ulong stake_weights_sig = 4UL;
292-
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
293-
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
294-
FD_LOG_NOTICE(("sending next epoch stake weights - epoch: %lu, stake_weight_cnt: %lu, start_slot: %lu, slot_cnt: %lu", stake_weights_msg[0], stake_weights_msg[1], stake_weights_msg[2], stake_weights_msg[3]));
295-
}
296-
297-
} FD_SPAD_FRAME_END;
232+
publish_stake_weights_manifest( fd_capture_tile_ctx_t * ctx,
233+
fd_stem_context_t * stem,
234+
fd_snapshot_manifest_t const * manifest ) {
235+
fd_epoch_schedule_t const * schedule = fd_type_pun_const( &manifest->epoch_schedule_params );
236+
ulong epoch = fd_slot_to_epoch( schedule, manifest->slot, NULL );
237+
238+
/* current epoch */
239+
ulong * stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
240+
ulong stake_weights_sz = generate_stake_weight_msg_manifest( epoch, schedule, &manifest->epoch_stakes[0], stake_weights_msg );
241+
ulong stake_weights_sig = 4UL;
242+
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
243+
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
244+
FD_LOG_NOTICE(("sending current epoch stake weights - epoch: %lu, stake_weight_cnt: %lu, start_slot: %lu, slot_cnt: %lu", stake_weights_msg[0], stake_weights_msg[1], stake_weights_msg[2], stake_weights_msg[3]));
245+
246+
/* next current epoch */
247+
stake_weights_msg = fd_chunk_to_laddr( ctx->stake_out->mem, ctx->stake_out->chunk );
248+
stake_weights_sz = generate_stake_weight_msg_manifest( epoch + 1, schedule, &manifest->epoch_stakes[1], stake_weights_msg );
249+
stake_weights_sig = 4UL;
250+
fd_stem_publish( stem, 0UL, stake_weights_sig, ctx->stake_out->chunk, stake_weights_sz, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
251+
ctx->stake_out->chunk = fd_dcache_compact_next( ctx->stake_out->chunk, stake_weights_sz, ctx->stake_out->chunk0, ctx->stake_out->wmark );
252+
FD_LOG_NOTICE(("sending next epoch stake weights - epoch: %lu, stake_weight_cnt: %lu, start_slot: %lu, slot_cnt: %lu", stake_weights_msg[0], stake_weights_msg[1], stake_weights_msg[2], stake_weights_msg[3]));
298253
}
299254

300255
static inline int
@@ -483,7 +438,7 @@ after_credit( fd_capture_tile_ctx_t * ctx,
483438

484439
fd_fseq_update( ctx->manifest_wmark, manifest->slot );
485440

486-
publish_stake_weights( ctx, stem, manifest );
441+
publish_stake_weights_manifest( ctx, stem, manifest );
487442
//*charge_busy = 0;
488443
}
489444
/* No need to strcmp every time after_credit is called. */

src/flamenco/runtime/fd_runtime.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fd_runtime_update_leaders( fd_bank_t * bank,
142142
fd_bank_epoch_stakes_end_locking_query( bank );
143143

144144
fd_vote_stake_weight_t * epoch_weights = fd_spad_alloc_check( runtime_spad, alignof(fd_vote_stake_weight_t), vote_acc_cnt * sizeof(fd_vote_stake_weight_t) );
145-
ulong stake_weight_cnt = fd_stake_weights_by_node( epoch_vaccs, epoch_weights, runtime_spad );
145+
ulong stake_weight_cnt = fd_stake_weights_by_node( epoch_vaccs, epoch_weights );
146146

147147
if( FD_UNLIKELY( stake_weight_cnt == ULONG_MAX ) ) {
148148
FD_LOG_ERR(( "fd_stake_weights_by_node() failed" ));

0 commit comments

Comments
 (0)