LCOV - code coverage report
Current view: top level - discof/replay - fd_exec.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 70 0.0 %
Date: 2025-09-19 04:41:14 Functions: 0 91 0.0 %

          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/stakes/fd_stakes.h"
       6             : #include "../../flamenco/runtime/fd_runtime.h"
       7             : #include "../../flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.h"
       8             : #include "../../discof/restore/utils/fd_ssmsg.h"
       9             : 
      10             : /* FIXME: SIMD-0180 - set the correct epochs */
      11           0 : #define FD_SIMD0180_ACTIVE_EPOCH_TESTNET (829)
      12           0 : #define FD_SIMD0180_ACTIVE_EPOCH_MAINNET (841)
      13             : 
      14             : /* Replay tile msg link formatting. The following take a pointer into
      15             :    a dcache region and formats it as a specific message type. */
      16             : 
      17             : static inline ulong
      18             : generate_stake_weight_msg( ulong                       epoch,
      19             :                            fd_epoch_schedule_t const * epoch_schedule,
      20             :                            fd_vote_states_t const *    epoch_stakes,
      21           0 :                            ulong *                     stake_weight_msg_out ) {
      22           0 :   fd_stake_weight_msg_t *  stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out );
      23           0 :   fd_vote_stake_weight_t * stake_weights    = stake_weight_msg->weights;
      24             : 
      25           0 :   stake_weight_msg->epoch             = epoch;
      26           0 :   stake_weight_msg->start_slot        = fd_epoch_slot0( epoch_schedule, epoch );
      27           0 :   stake_weight_msg->slot_cnt          = epoch_schedule->slots_per_epoch;
      28           0 :   stake_weight_msg->excluded_stake    = 0UL;
      29           0 :   stake_weight_msg->vote_keyed_lsched = 1UL;
      30             : 
      31             :   /* FIXME: SIMD-0180 - hack to (de)activate in testnet vs mainnet.
      32             :      This code can be removed once the feature is active. */
      33           0 :   if( (1==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_TESTNET) ||
      34           0 :       (0==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_MAINNET) ) {
      35           0 :     stake_weight_msg->vote_keyed_lsched = 0UL;
      36           0 :   }
      37             : 
      38             :   /* epoch_stakes from manifest are already filtered (stake>0), but not sorted */
      39           0 :   fd_vote_states_iter_t iter_[1];
      40           0 :   ulong idx = 0UL;
      41           0 :   for( fd_vote_states_iter_t * iter = fd_vote_states_iter_init( iter_, epoch_stakes ); !fd_vote_states_iter_done( iter ); fd_vote_states_iter_next( iter ) ) {
      42           0 :     fd_vote_state_ele_t * vote_state = fd_vote_states_iter_ele( iter );
      43           0 :     if( FD_UNLIKELY( !vote_state->stake ) ) continue;
      44             : 
      45           0 :     stake_weights[ idx ].stake = vote_state->stake;
      46           0 :     memcpy( stake_weights[ idx ].id_key.uc, &vote_state->node_account, sizeof(fd_pubkey_t) );
      47           0 :     memcpy( stake_weights[ idx ].vote_key.uc, &vote_state->vote_account, sizeof(fd_pubkey_t) );
      48           0 :     idx++;
      49           0 :   }
      50           0 :   stake_weight_msg->staked_cnt = idx;
      51           0 :   sort_vote_weights_by_stake_vote_inplace( stake_weights, idx );
      52             : 
      53           0 :   return fd_stake_weight_msg_sz( idx );
      54           0 : }
      55             : 
      56             : static inline ulong
      57             : generate_stake_weight_msg_manifest( ulong                                       epoch,
      58             :                                     fd_epoch_schedule_t const *                 epoch_schedule,
      59             :                                     fd_snapshot_manifest_epoch_stakes_t const * epoch_stakes,
      60           0 :                                     ulong *                                     stake_weight_msg_out ) {
      61           0 :   fd_stake_weight_msg_t *  stake_weight_msg = (fd_stake_weight_msg_t *)fd_type_pun( stake_weight_msg_out );
      62           0 :   fd_vote_stake_weight_t * stake_weights    = stake_weight_msg->weights;
      63             : 
      64           0 :   stake_weight_msg->epoch             = epoch;
      65           0 :   stake_weight_msg->staked_cnt        = epoch_stakes->vote_stakes_len;
      66           0 :   stake_weight_msg->start_slot        = fd_epoch_slot0( epoch_schedule, epoch );
      67           0 :   stake_weight_msg->slot_cnt          = epoch_schedule->slots_per_epoch;
      68           0 :   stake_weight_msg->excluded_stake    = 0UL;
      69           0 :   stake_weight_msg->vote_keyed_lsched = 1UL;
      70             : 
      71             :   /* FIXME: SIMD-0180 - hack to (de)activate in testnet vs mainnet.
      72             :      This code can be removed once the feature is active. */
      73           0 :   {
      74           0 :     if(    ( 1==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_TESTNET )
      75           0 :         || ( 0==epoch_schedule->warmup && epoch<FD_SIMD0180_ACTIVE_EPOCH_MAINNET ) ) {
      76           0 :       stake_weight_msg->vote_keyed_lsched = 0UL;
      77           0 :     }
      78           0 :   }
      79             : 
      80             :   /* epoch_stakes from manifest are already filtered (stake>0), but not sorted */
      81           0 :   for( ulong i=0UL; i<epoch_stakes->vote_stakes_len; i++ ) {
      82           0 :     stake_weights[ i ].stake = epoch_stakes->vote_stakes[ i ].stake;
      83           0 :     memcpy( stake_weights[ i ].id_key.uc, epoch_stakes->vote_stakes[ i ].identity, sizeof(fd_pubkey_t) );
      84           0 :     memcpy( stake_weights[ i ].vote_key.uc, epoch_stakes->vote_stakes[ i ].vote, sizeof(fd_pubkey_t) );
      85           0 :   }
      86           0 :   sort_vote_weights_by_stake_vote_inplace( stake_weights, epoch_stakes->vote_stakes_len);
      87             : 
      88           0 :   return fd_stake_weight_msg_sz( epoch_stakes->vote_stakes_len );
      89           0 : }
      90             : 
      91             : /* Execution tracking helpers */
      92             : 
      93             : struct fd_slice_exec {
      94             :   uchar * buf;       /* Pointer to the memory region sized for max sz of a block. */
      95             :   ulong   wmark;     /* Offset into slice where previous bytes have been executed, and following bytes have not. Will be on a transaction or microblock boundary. */
      96             :   ulong   sz;        /* Total bytes this slice occupies in mbatch memory. New slices are placed at this offset */
      97             :   ulong   mblks_rem; /* Number of microblocks remaining in the current batch iteration. */
      98             :   ulong   txns_rem;  /* Number of txns remaining in current microblock iteration. */
      99             : 
     100             :   ulong   last_mblk_off; /* Stored offset to the last microblock header seen. Updated during block execution. */
     101             :   int     last_batch;    /* Signifies last batch execution. */
     102             : };
     103             : typedef struct fd_slice_exec fd_slice_exec_t;
     104             : 
     105             : /* Note the current usage of slice_exec is that it is embedded directly
     106             :    in replay_tile_ctx_t, so there's no need for (_new) currently. */
     107             : 
     108             : fd_slice_exec_t *
     109             : fd_slice_exec_join( void * slmem );
     110             : 
     111             : void
     112             : fd_slice_exec_txn_parse( fd_slice_exec_t * slice_exec_ctx,
     113             :                          fd_txn_p_t      * txn_p_out );
     114             : 
     115             : void
     116             : fd_slice_exec_microblock_parse( fd_slice_exec_t * slice_exec_ctx );
     117             : 
     118             : void
     119             : fd_slice_exec_reset( fd_slice_exec_t * slice_exec_ctx );
     120             : 
     121             : void
     122             : fd_slice_exec_begin( fd_slice_exec_t * slice_exec_ctx,
     123             :                      ulong             slice_sz,
     124             :                      int               last_batch );
     125             : 
     126             : static inline void
     127           0 : fd_slice_exec_skip_slice( fd_slice_exec_t * slice_exec_ctx ) {
     128           0 :   slice_exec_ctx->mblks_rem = 0UL;
     129           0 :   slice_exec_ctx->txns_rem  = 0UL;
     130           0 : }
     131             : 
     132             : static inline int
     133           0 : fd_slice_exec_txn_ready( fd_slice_exec_t const * slice_exec_ctx ) {
     134           0 :   return slice_exec_ctx->txns_rem > 0UL;
     135           0 : }
     136             : 
     137             : static inline int
     138           0 : fd_slice_exec_microblock_ready( fd_slice_exec_t const * slice_exec_ctx ) {
     139           0 :   return slice_exec_ctx->txns_rem == 0 && slice_exec_ctx->mblks_rem > 0UL;
     140           0 : }
     141             : 
     142             : static inline int
     143           0 : fd_slice_exec_slice_ready( fd_slice_exec_t const * slice_exec_ctx ) {
     144           0 :   return slice_exec_ctx->txns_rem == 0 && slice_exec_ctx->mblks_rem == 0UL;
     145           0 : }
     146             : 
     147             : static inline int
     148           0 : fd_slice_exec_slot_complete( fd_slice_exec_t const * slice_exec_ctx ) {
     149           0 :   return slice_exec_ctx->last_batch && slice_exec_ctx->mblks_rem == 0 && slice_exec_ctx->txns_rem == 0;
     150           0 : }
     151             : 
     152             : /* Exec tile msg link formatting. The following take a pointer into
     153             :    a dcache region and formats it as a specific message type. */
     154             : 
     155             : /* definition of the public/readable workspace */
     156           0 : #define EXEC_NEW_TXN_SIG         (0x777777UL)
     157             : 
     158           0 : #define FD_WRITER_BOOT_SIG       (0xAABB0011UL)
     159             : #define FD_WRITER_SLOT_SIG       (0xBBBB1122UL)
     160           0 : #define FD_WRITER_TXN_SIG        (0xBBCC2233UL)
     161             : 
     162             : #define FD_EXEC_STATE_NOT_BOOTED (0xFFFFFFFFUL)
     163             : #define FD_EXEC_STATE_BOOTED     (1<<1UL      )
     164             : 
     165             : #define FD_EXEC_ID_SENTINEL      (UINT_MAX    )
     166             : 
     167             : /**********************************************************************/
     168             : 
     169             : /* fd_exec_txn_msg_t is the message that is sent from the replay tile to
     170             :    the exec tile.  This represents all of the information that is needed
     171             :    to identify and execute a transaction against a bank.  An idx to the
     172             :    bank in the bank pool must be sent over because the key of the bank
     173             :    will change as FEC sets are processed. */
     174             : 
     175             : struct fd_exec_txn_msg {
     176             :   ulong      bank_idx;
     177             :   fd_txn_p_t txn;
     178             : };
     179             : typedef struct fd_exec_txn_msg fd_exec_txn_msg_t;
     180             : 
     181             : /* fd_exec_writer_boot_msg_t is the message sent from the exec tile to
     182             :    the writer tile on boot.  This message contains the offset of the
     183             :    txn_ctx in the tile's exec spad. */
     184             : 
     185             : struct fd_exec_writer_boot_msg {
     186             :   uint txn_ctx_offset;
     187             : };
     188             : typedef struct fd_exec_writer_boot_msg fd_exec_writer_boot_msg_t;
     189             : FD_STATIC_ASSERT( sizeof(fd_exec_writer_boot_msg_t)<=FD_EXEC_WRITER_MTU, exec_writer_msg_mtu );
     190             : 
     191             : /* fd_exec_writer_txn_msg is the message sent from the exec tile to the
     192             :    writer tile after a transaction has been executed.  This message
     193             :    contains the id of the exec tile that executed the transaction. */
     194             : 
     195             : struct fd_exec_writer_txn_msg {
     196             :   uchar exec_tile_id;
     197             : };
     198             : typedef struct fd_exec_writer_txn_msg fd_exec_writer_txn_msg_t;
     199             : FD_STATIC_ASSERT( sizeof(fd_exec_writer_txn_msg_t)<=FD_EXEC_WRITER_MTU, exec_writer_msg_mtu );
     200             : 
     201             : /* Writer->Replay message APIs ****************************************/
     202             : 
     203             : /* fd_writer_replay_txn_finalized_msg_t is the message sent from
     204             :    writer tile to replay tile, notifying the replay tile that a txn has
     205             :    been finalized. */
     206             : 
     207             : struct __attribute__((packed)) fd_writer_replay_txn_finalized_msg {
     208             :   int exec_tile_id;
     209             : };
     210             : typedef struct fd_writer_replay_txn_finalized_msg fd_writer_replay_txn_finalized_msg_t;
     211             : 
     212             : #endif /* HEADER_fd_src_discof_replay_fd_exec_h */

Generated by: LCOV version 1.14