Line data Source code
1 : #ifndef HEADER_fd_src_discof_replay_fd_exec_h 2 : #define HEADER_fd_src_discof_replay_fd_exec_h 3 : 4 : #include "../../flamenco/fd_flamenco_base.h" 5 : #include "../../flamenco/runtime/context/fd_exec_slot_ctx.h" 6 : #include "../../flamenco/runtime/fd_runtime.h" 7 : #include "../../flamenco/stakes/fd_stakes.h" 8 : #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 0 : #define FD_SIMD0180_ACTIVE_EPOCH_TESTNET (5000) 13 0 : #define FD_SIMD0180_ACTIVE_EPOCH_MAINNET (5000) 14 : 15 : /* Replay tile msg link formatting. The following take a pointer into 16 : a dcache region and formats it as a specific message type. */ 17 : 18 : static inline ulong 19 : generate_stake_weight_msg( fd_exec_slot_ctx_t * slot_ctx, 20 : ulong epoch, 21 : fd_vote_accounts_global_t const * vote_accounts, 22 0 : ulong * stake_weight_msg_out ) { 23 0 : fd_stake_weight_msg_t * stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out ); 24 0 : fd_vote_stake_weight_t * stake_weights = stake_weight_msg->weights; 25 0 : ulong staked_cnt = fd_stake_weights_by_node( vote_accounts, stake_weights ); 26 0 : fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( slot_ctx->bank ); 27 : 28 0 : stake_weight_msg->epoch = epoch; 29 0 : stake_weight_msg->staked_cnt = staked_cnt; 30 0 : stake_weight_msg->start_slot = fd_epoch_slot0( epoch_schedule, stake_weight_msg_out[0] ); 31 0 : stake_weight_msg->slot_cnt = epoch_schedule->slots_per_epoch; 32 0 : stake_weight_msg->excluded_stake = 0UL; 33 0 : stake_weight_msg->vote_keyed_lsched = (ulong)fd_runtime_should_use_vote_keyed_leader_schedule( slot_ctx->bank ); 34 : 35 0 : return fd_stake_weight_msg_sz( staked_cnt ); 36 0 : } 37 : 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 0 : ulong * stake_weight_msg_out ) { 43 0 : fd_stake_weight_msg_t * stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out ); 44 0 : fd_vote_stake_weight_t * stake_weights = stake_weight_msg->weights; 45 : 46 0 : stake_weight_msg->epoch = epoch; 47 0 : stake_weight_msg->staked_cnt = epoch_stakes->vote_stakes_len; 48 0 : stake_weight_msg->start_slot = fd_epoch_slot0( epoch_schedule, epoch ); 49 0 : stake_weight_msg->slot_cnt = epoch_schedule->slots_per_epoch; 50 0 : stake_weight_msg->excluded_stake = 0UL; 51 0 : 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 0 : { 56 0 : if( ( 1==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_TESTNET ) 57 0 : || ( 0==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_MAINNET ) ) { 58 0 : stake_weight_msg->vote_keyed_lsched = 0UL; 59 0 : } 60 0 : } 61 : 62 : /* epoch_stakes from manifest are already filtered (stake>0), but not sorted */ 63 0 : for( ulong i=0UL; i<epoch_stakes->vote_stakes_len; i++ ) { 64 0 : stake_weights[ i ].stake = epoch_stakes->vote_stakes[ i ].stake; 65 0 : memcpy( stake_weights[ i ].id_key.uc, epoch_stakes->vote_stakes[ i ].identity, sizeof(fd_pubkey_t) ); 66 0 : memcpy( stake_weights[ i ].vote_key.uc, epoch_stakes->vote_stakes[ i ].vote, sizeof(fd_pubkey_t) ); 67 0 : } 68 0 : sort_vote_weights_by_stake_vote_inplace( stake_weights, epoch_stakes->vote_stakes_len); 69 : 70 0 : return fd_stake_weight_msg_sz( epoch_stakes->vote_stakes_len ); 71 0 : } 72 : 73 : static inline void 74 : generate_hash_bank_msg( ulong task_infos_gaddr, 75 : ulong lt_hash_gaddr, 76 : ulong start_idx, 77 : ulong end_idx, 78 : ulong curr_slot, 79 0 : fd_runtime_public_hash_bank_msg_t * hash_msg_out ) { 80 0 : hash_msg_out->task_infos_gaddr = task_infos_gaddr; 81 0 : hash_msg_out->lthash_gaddr = lt_hash_gaddr; 82 0 : hash_msg_out->start_idx = start_idx; 83 0 : hash_msg_out->end_idx = end_idx; 84 0 : hash_msg_out->slot = curr_slot; 85 0 : } 86 : 87 : /* Execution tracking helpers */ 88 : 89 : struct fd_slice_exec { 90 : uchar * buf; /* Pointer to the memory region sized for max sz of a block. */ 91 : ulong wmark; /* Offset into slice where previous bytes have been executed, and following bytes have not. Will be on a transaction or microblock boundary. */ 92 : ulong sz; /* Total bytes this slice occupies in mbatch memory. New slices are placed at this offset */ 93 : ulong mblks_rem; /* Number of microblocks remaining in the current batch iteration. */ 94 : ulong txns_rem; /* Number of txns remaining in current microblock iteration. */ 95 : 96 : ulong last_mblk_off; /* Stored offset to the last microblock header seen. Updated during block execution. */ 97 : int last_batch; /* Signifies last batch execution. */ 98 : }; 99 : typedef struct fd_slice_exec fd_slice_exec_t; 100 : 101 : /* Note the current usage of slice_exec is that it is embedded directly 102 : in replay_tile_ctx_t, so there's no need for (_new) currently. */ 103 : 104 : fd_slice_exec_t * 105 : fd_slice_exec_join( void * slmem ); 106 : 107 : void 108 : fd_slice_exec_txn_parse( fd_slice_exec_t * slice_exec_ctx, 109 : fd_txn_p_t * txn_p_out ); 110 : 111 : void 112 : fd_slice_exec_microblock_parse( fd_slice_exec_t * slice_exec_ctx ); 113 : 114 : void 115 : fd_slice_exec_reset( fd_slice_exec_t * slice_exec_ctx ); 116 : 117 : void 118 : fd_slice_exec_begin( fd_slice_exec_t * slice_exec_ctx, 119 : ulong slice_sz, 120 : int last_batch ); 121 : 122 : static inline int 123 0 : fd_slice_exec_txn_ready( fd_slice_exec_t * slice_exec_ctx ) { 124 0 : return slice_exec_ctx->txns_rem > 0UL; 125 0 : } 126 : 127 : static inline int 128 0 : fd_slice_exec_microblock_ready( fd_slice_exec_t * slice_exec_ctx ) { 129 0 : return slice_exec_ctx->txns_rem == 0 && slice_exec_ctx->mblks_rem > 0UL; 130 0 : } 131 : 132 : static inline int 133 0 : fd_slice_exec_slice_ready( fd_slice_exec_t * slice_exec_ctx ) { 134 0 : return slice_exec_ctx->txns_rem == 0 && slice_exec_ctx->mblks_rem == 0UL; 135 0 : } 136 : 137 : static inline int 138 0 : fd_slice_exec_slot_complete( fd_slice_exec_t * slice_exec_ctx ) { 139 0 : return slice_exec_ctx->last_batch && slice_exec_ctx->mblks_rem == 0 && slice_exec_ctx->txns_rem == 0; 140 0 : } 141 : 142 : #endif /* HEADER_fd_src_discof_replay_fd_exec_h */