LCOV - code coverage report
Current view: top level - flamenco/stakes - fd_vote_stakes.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 1 1 100.0 %
Date: 2026-08-16 04:31:21 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_stakes_fd_vote_stakes_h
       2             : #define HEADER_fd_src_flamenco_stakes_fd_vote_stakes_h
       3             : 
       4             : #include "../../util/fd_util_base.h"
       5             : #include "../fd_flamenco_base.h"
       6             : #include "../accdb/fd_accdb_base.h"
       7             : 
       8        3657 : #define FD_VOTE_STAKES_ALIGN (128UL)
       9             : 
      10             : /* fd_vote_stakes is the Firedancer equivalent of the Agave epoch stakes
      11             :    data structure.  It is a fork aware data structure that maintains the
      12             :    vote account state that is used for clock and VM syscall calculations
      13             :    during execution.
      14             : 
      15             :    The underlying data structure is a tiered set of caches:
      16             :    - t-2/t-3: these are caches used for the vote account states at the
      17             :      end of the t-2 epoch and the t-3 epoch assuming you are currently
      18             :      in the t epoch.  These caches are shared across all forks.
      19             :    - t-1: these are sized to max_fork_width and are computed at the
      20             :      most recent epoch boundary.  These caches are ref-cnt'd and fork
      21             :      specific.  After the epoch boundary slot is rooted, then there will
      22             :      only be 1 active t-1 cache.
      23             :    - state: each bank has its own view of the t-2 state of vote
      24             :      accounts.  This is what is actually used for clock calculations
      25             :      which is a stake weighted median of the last vote slot and
      26             :      timestamp.
      27             : 
      28             :    fd_vote_stakes also handles the creation of new vote stakes caches.
      29             :    The creation of new vote stakes caches happens at the epoch boundary
      30             :    and follows the rules defined in the validator_admission_ticket
      31             :    feature where every vote account must be in the top 2000 by stake.
      32             :    Under the hood, this is managed by a stake-sorted heap that is shared
      33             :    across all forks.
      34             : 
      35             :    NOTE:
      36             :    This system assumes that multiple forks can cross an epoch boundary
      37             :    but only one epoch boundary can be crossed at a time.  This means
      38             :    that there can be multiple t-1 forks after an epoch boundary, but
      39             :    only one will be active when the first fork crosses into an epoch
      40             :    boundary.  Similarly, this means that there will be 2 t-2 sets active
      41             :    during an epoch boundary crossing and 1 most of the time. */
      42             : 
      43             : struct fd_vote_stakes;
      44             : typedef struct fd_vote_stakes fd_vote_stakes_t;
      45             : 
      46             : FD_PROTOTYPES_BEGIN
      47             : 
      48             : ulong
      49             : fd_vote_stakes_align( void );
      50             : 
      51             : ulong
      52             : fd_vote_stakes_footprint( ulong max_live_slots,
      53             :                           ulong max_fork_width );
      54             : 
      55             : void *
      56             : fd_vote_stakes_new( void * mem,
      57             :                     ulong  max_live_slots,
      58             :                     ulong  max_fork_width,
      59             :                     ulong  seed );
      60             : 
      61             : fd_vote_stakes_t *
      62             : fd_vote_stakes_join( void * mem );
      63             : 
      64             : /* fd_vote_stakes_fork_epoch returns the epoch of the fork. */
      65             : 
      66             : ulong
      67             : fd_vote_stakes_fork_epoch( ulong fork_id );
      68             : 
      69             : /* fd_vote_stakes_init initializes the vote stakes data structure for a
      70             :    given epoch. */
      71             : 
      72             : ulong
      73             : fd_vote_stakes_init( fd_vote_stakes_t * vote_stakes,
      74             :                      ulong              epoch );
      75             : 
      76             : /* fd_vote_stakes_reset resets the vote stakes data structure. */
      77             : 
      78             : void
      79             : fd_vote_stakes_reset( fd_vote_stakes_t * vote_stakes );
      80             : 
      81             : /* fd_vote_stakes_snap_insert_t_1 inserts a new vote account into the
      82             :    t-1 set.  This skips over any vote account validation and should
      83             :    only be used when loading in vote accounts from a snapshot. */
      84             : 
      85             : void
      86             : fd_vote_stakes_snap_insert_t_1( fd_vote_stakes_t *  vote_stakes,
      87             :                                 ulong               fork_id,
      88             :                                 fd_pubkey_t const * pubkey,
      89             :                                 fd_pubkey_t const * node_account,
      90             :                                 ulong               stake,
      91             :                                 ushort              commission );
      92             : 
      93             : /* fd_vote_stakes_snap_insert_t_2 inserts a new vote account into the
      94             :    t-2 set.  This skips over any vote account validation and should
      95             :    only be used when loading in vote accounts from a snapshot. */
      96             : 
      97             : void
      98             : fd_vote_stakes_snap_insert_t_2( fd_vote_stakes_t *  vote_stakes,
      99             :                                 ulong               fork_id,
     100             :                                 fd_pubkey_t const * pubkey,
     101             :                                 fd_pubkey_t const * node_account,
     102             :                                 ulong               stake,
     103             :                                 ushort              commission );
     104             : 
     105             : /* fd_vote_stakes_insert inserts a new vote account into the t-1 set.
     106             :    This can be called repeatedly after a boundary-crossing
     107             :    fd_vote_stakes_new_fork.  An account will only be inserted if it
     108             :    matches the semantics of the validator_admission_ticket feature.
     109             :    The top 2000 vote accounts by stake are inserted into the t-1 set. */
     110             : 
     111             : void
     112             : fd_vote_stakes_insert( fd_vote_stakes_t *  vote_stakes,
     113             :                        ulong               fork_id,
     114             :                        fd_pubkey_t const * pubkey,
     115             :                        fd_pubkey_t const * node_account,
     116             :                        ulong               stake,
     117             :                        ushort              commission );
     118             : 
     119             : /* fd_vote_stakes_purge_fork removes a t-1 set.  This should be called
     120             :    when the banks are evicting a bank or during root advancement. */
     121             : 
     122             : void
     123             : fd_vote_stakes_purge_fork( fd_vote_stakes_t * vote_stakes,
     124             :                            ulong              fork_id );
     125             : 
     126             : /* fd_vote_stakes_new_fork creates a child of the given parent fork.
     127             :    Within an epoch, the child shares the parent's t-1 set and receives a
     128             :    copy of its t-2 state.  At an epoch boundary, it rotates t-1 into
     129             :    t-2 and acquires fresh t-1 and t-2 state. */
     130             : 
     131             : ulong
     132             : fd_vote_stakes_new_fork( fd_vote_stakes_t * vote_stakes,
     133             :                          ulong              parent_fork_id,
     134             :                          ulong              epoch );
     135             : 
     136             : /* fd_vote_stakes_update updates the vote account state for a given
     137             :    fork id.  It is a no-op if the pubkey corresponds to an account not
     138             :    in the t-2 set.  If is_valid==0, the last vote arguments will be
     139             :    ignored. */
     140             : 
     141             : void
     142             : fd_vote_stakes_update_state( fd_vote_stakes_t *  vote_stakes,
     143             :                              ulong               fork_id,
     144             :                              fd_pubkey_t const * pubkey,
     145             :                              ulong               last_vote_slot,
     146             :                              long                last_vote_ts,
     147             :                              uchar               is_valid );
     148             : 
     149             : void
     150             : fd_vote_stakes_refresh( fd_vote_stakes_t * vote_stakes,
     151             :                         ulong              fork_id,
     152             :                         fd_accdb_t *        accdb,
     153             :                         fd_accdb_fork_id_t  accdb_fork_id );
     154             : 
     155             : /* fd_vote_stakes_query_t_1 queries the fork's t-1 vote account.
     156             :    Returns 1 if the account exists in t-1 and 0 otherwise. */
     157             : 
     158             : int
     159             : fd_vote_stakes_query_t_1( fd_vote_stakes_t const * vote_stakes,
     160             :                           ulong                    fork_id,
     161             :                           fd_pubkey_t const *      pubkey,
     162             :                           fd_pubkey_t *            node_account_out_opt,
     163             :                           ulong *                  stake_out_opt,
     164             :                           ushort *                 commission_out_opt );
     165             : 
     166             : /* fd_vote_stakes_query_t_2 queries the t-2 vote account and fork-local
     167             :    vote state.  Returns 1 if the account exists in t-2 and 0 otherwise. */
     168             : 
     169             : int
     170             : fd_vote_stakes_query_t_2( fd_vote_stakes_t const * vote_stakes,
     171             :                           ulong                    fork_id,
     172             :                           fd_pubkey_t const *      pubkey,
     173             :                           fd_pubkey_t *            node_account_out_opt,
     174             :                           ulong *                  stake_out_opt,
     175             :                           ulong *                  last_vote_slot_out_opt,
     176             :                           long *                   last_vote_ts_out_opt,
     177             :                           ushort *                 commission_out_opt,
     178             :                           uchar *                  is_valid_out_opt );
     179             : 
     180             : /* fd_vote_stakes_query_t_3 queries the fork's t-3 vote account.
     181             :    Returns 1 if the account exists in t-3 and 0 otherwise. */
     182             : 
     183             : int
     184             : fd_vote_stakes_query_t_3( fd_vote_stakes_t const * vote_stakes,
     185             :                           ulong                    fork_id,
     186             :                           fd_pubkey_t const *      pubkey,
     187             :                           fd_pubkey_t *            node_account_out_opt,
     188             :                           ulong *                  stake_out_opt,
     189             :                           ushort *                 commission_out_opt );
     190             : 
     191             : /* fd_vote_stakes_cnt_t_{1,2} returns the number of vote accounts in the
     192             :    t-1 and t-2 sets respectively. */
     193             : 
     194             : ulong
     195             : fd_vote_stakes_cnt_t_1( fd_vote_stakes_t const * vote_stakes,
     196             :                         ulong                    fork_id );
     197             : 
     198             : ulong
     199             : fd_vote_stakes_cnt_t_2( fd_vote_stakes_t const * vote_stakes,
     200             :                         ulong                    fork_id );
     201             : 
     202             : /* Defined below are the iterators for the t-1 and t-2 sets.  These
     203             :    iterators will NOT skip over invalid vote accounts intentionally.
     204             :    The reason being is that invalid vote accounts are still considered
     205             :    for stake and leader calculations: the caller is expected to handle
     206             :    the state of each account correctly. */
     207             : 
     208             : #define FD_VOTE_STAKES_ITER_FOOTPRINT     (16UL)
     209             : #define FD_VOTE_STAKES_ITER_ALIGN         (8UL)
     210             : #define FD_VOTE_STAKES_T_1_ITER_FOOTPRINT FD_VOTE_STAKES_ITER_FOOTPRINT
     211             : #define FD_VOTE_STAKES_T_1_ITER_ALIGN     FD_VOTE_STAKES_ITER_ALIGN
     212             : #define FD_VOTE_STAKES_T_2_ITER_FOOTPRINT FD_VOTE_STAKES_ITER_FOOTPRINT
     213             : #define FD_VOTE_STAKES_T_2_ITER_ALIGN     FD_VOTE_STAKES_ITER_ALIGN
     214             : 
     215             : struct vacc_map_iter;
     216             : typedef struct vacc_map_iter fd_vote_stakes_iter_t;
     217             : typedef fd_vote_stakes_iter_t fd_vote_stakes_t_1_iter_t;
     218             : typedef fd_vote_stakes_iter_t fd_vote_stakes_t_2_iter_t;
     219             : 
     220             : fd_vote_stakes_t_1_iter_t *
     221             : fd_vote_stakes_t_1_iter_init( fd_vote_stakes_t const * vote_stakes,
     222             :                               ulong                    fork_id,
     223             :                               uchar                    iter_mem[ static FD_VOTE_STAKES_T_1_ITER_FOOTPRINT ] );
     224             : 
     225             : int
     226             : fd_vote_stakes_t_1_iter_done( fd_vote_stakes_t const *    vote_stakes,
     227             :                               ulong                       fork_id,
     228             :                               fd_vote_stakes_t_1_iter_t * iter );
     229             : 
     230             : void
     231             : fd_vote_stakes_t_1_iter_next( fd_vote_stakes_t const *    vote_stakes,
     232             :                               ulong                       fork_id,
     233             :                               fd_vote_stakes_t_1_iter_t * iter );
     234             : 
     235             : void
     236             : fd_vote_stakes_t_1_iter_ele( fd_vote_stakes_t const *    vote_stakes,
     237             :                              ulong                       fork_id,
     238             :                              fd_vote_stakes_t_1_iter_t * iter,
     239             :                              fd_pubkey_t *               pubkey_out,
     240             :                              fd_pubkey_t *               node_account_out_opt,
     241             :                              ulong *                     stake_out_opt,
     242             :                              ushort *                    commission_out_opt );
     243             : 
     244             : fd_vote_stakes_t_2_iter_t *
     245             : fd_vote_stakes_t_2_iter_init( fd_vote_stakes_t const * vote_stakes,
     246             :                               ulong                    fork_id,
     247             :                               uchar                    iter_mem[ static FD_VOTE_STAKES_T_2_ITER_FOOTPRINT ] );
     248             : 
     249             : int
     250             : fd_vote_stakes_t_2_iter_done( fd_vote_stakes_t const *    vote_stakes,
     251             :                               ulong                       fork_id,
     252             :                               fd_vote_stakes_t_2_iter_t * iter );
     253             : 
     254             : void
     255             : fd_vote_stakes_t_2_iter_next( fd_vote_stakes_t const *    vote_stakes,
     256             :                               ulong                       fork_id,
     257             :                               fd_vote_stakes_t_2_iter_t * iter );
     258             : 
     259             : void
     260             : fd_vote_stakes_t_2_iter_ele( fd_vote_stakes_t const *    vote_stakes,
     261             :                              ulong                       fork_id,
     262             :                              fd_vote_stakes_t_2_iter_t * iter,
     263             :                              fd_pubkey_t *               pubkey_out,
     264             :                              fd_pubkey_t *               node_account_out_opt,
     265             :                              ulong *                     stake_out_opt,
     266             :                              ulong *                     last_vote_slot_out_opt,
     267             :                              long *                      last_vote_ts_out_opt,
     268             :                              ushort *                    commission_out_opt,
     269             :                              uchar *                     is_valid_out_opt );
     270             : 
     271             : FD_PROTOTYPES_END
     272             : 
     273             : #endif /* HEADER_fd_src_flamenco_stakes_fd_vote_stakes_h */

Generated by: LCOV version 1.14