LCOV - code coverage report
Current view: top level - flamenco/stakes - fd_top_votes.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 2 2 100.0 %
Date: 2026-05-15 07:18:56 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_stakes_fd_top_votes_h
       2             : #define HEADER_fd_src_flamenco_stakes_fd_top_votes_h
       3             : 
       4             : #include "../../funk/fd_funk_base.h"
       5             : #include "../../flamenco/fd_flamenco_base.h"
       6             : #include "../accdb/fd_accdb_base.h"
       7             : 
       8             : /* With the introduction of VAT, the set of vote accounts that receive
       9             :    epoch rewards, participate in clock calculation, and are eligible for
      10             :    becoming leader becomes the top 2000 staked validators.
      11             :    fd_top_votes_t allows for efficiently populating and querying the
      12             :    set of top staked validators.  This data structure is intended to be
      13             :    CoW-able and maintained by the banks.
      14             : 
      15             :    Under the hood, fd_top_votes_t uses a heap, map, and pool to track
      16             :    the top set of vote accounts as they are being added.  The map allows
      17             :    for O(1) lookup of a vote account by its public key.
      18             : 
      19             :    An important tiebreaking rule is that if the minimum stake value has
      20             :    a tie, all accounts with that stake value will be excluded from the
      21             :    top voters set.
      22             : 
      23             :    The semantics around whether an account should be included in the
      24             :    top voters set is quite subtle and is based off of how Agave handles
      25             :    its stakes cache and epoch stakes.  The stakes cache is a cache of
      26             :    vote and stake accounts that is updated through an epoch.  It will
      27             :    always contain the full set of vote/stake accounts that are active
      28             :    for the current epoch.  The Agave epoch stakes are effectively
      29             :    snapshots of the stakes cache that are taken at the end of each
      30             :    epoch.  After VAT is enabled, the Agave client will only include the
      31             :    top 2000 staked vote accounts into the epoch stakes.  This means for
      32             :    the t-1 epoch, the top voters set contains the top 2000 staked vote
      33             :    accounts (with a BLS pubkey) and the account must exist at the epoch
      34             :    boundary.  However, a vote account can be deleted even if it is in
      35             :    the top votes set.  If this is the case, the account will be marked
      36             :    as invalid since it can be recreated. */
      37             : 
      38             : struct fd_top_votes;
      39             : typedef struct fd_top_votes fd_top_votes_t;
      40             : 
      41       14247 : #define FD_TOP_VOTES_ALIGN (128UL)
      42             : 
      43             : /* FD_TOP_VOTES_MAX_FOOTPRINT is the footprint of the fd_top_votes_t
      44             :    structure when the max number of vote accounts is
      45             :    FD_RUNTIME_MAX_VOTE_ACCOUNTS_VAT (2000). */
      46             : 
      47        7491 : #define FD_TOP_VOTES_MAX_FOOTPRINT (194432UL)
      48             : 
      49             : FD_PROTOTYPES_BEGIN
      50             : 
      51             : /* fd_top_votes_align returns the alignment of the fd_top_votes_t
      52             :    structure. */
      53             : 
      54             : ulong
      55             : fd_top_votes_align( void );
      56             : 
      57             : /* fd_top_votes_footprint returns the footprint of the fd_top_votes_t
      58             :    structure given a max number of vote accounts. */
      59             : 
      60             : ulong
      61             : fd_top_votes_footprint( ulong vote_accounts_max );
      62             : 
      63             : /* fd_top_votes_new creates a new fd_top_votes_t structure given a
      64             :    memory buffer, a max number of vote accounts, and a seed. */
      65             : 
      66             : void *
      67             : fd_top_votes_new( void * mem,
      68             :                   ushort vote_accounts_max,
      69             :                   ulong  seed );
      70             : 
      71             : /* fd_top_votes_join joins a fd_top_votes_t structure from a memory
      72             :    region that has been previously initialized with fd_top_votes_new.
      73             :    Returns a pointer to the fd_top_votes_t structure. */
      74             : 
      75             : fd_top_votes_t *
      76             : fd_top_votes_join( void * mem );
      77             : 
      78             : /* fd_top_votes_init is a runtime initialization function for a
      79             :    fd_top_votes_t structure given a pointer to the structure. */
      80             : 
      81             : void
      82             : fd_top_votes_init( fd_top_votes_t * top_votes );
      83             : 
      84             : 
      85             : /* fd_top_votes_insert inserts a new vote account into the top votes set
      86             :    given a vote account, node account, and commission.  If the vote
      87             :    account isn't in the top max_vote_accounts in terms of stake, it is
      88             :    ignored and is treated as a no-op.  If the vote account ties the
      89             :    minimum stake and the struct is full, all elements with that stake
      90             :    are removed. */
      91             : 
      92             : void
      93             : fd_top_votes_insert( fd_top_votes_t *    top_votes,
      94             :                      fd_pubkey_t const * pubkey,
      95             :                      fd_pubkey_t const * node_account,
      96             :                      ulong               stake,
      97             :                      uchar               commission );
      98             : 
      99             : /* fd_top_votes_update updates the last vote timestamp and slot for a
     100             :    given vote account in the top votes set.  If the vote account is not
     101             :    in the top votes set, the update is ignored and is treated as a
     102             :    no-op. */
     103             : 
     104             : void
     105             : fd_top_votes_update( fd_top_votes_t *    top_votes,
     106             :                      fd_pubkey_t const * pubkey,
     107             :                      ulong               last_vote_slot,
     108             :                      long                last_vote_timestamp );
     109             : 
     110             : /* fd_top_votes_invalidate invalidates a vote account in the top votes
     111             :    set.  This would be done in the case a vote account is withdrawn or
     112             :    becomes invalid.  An account that is invalid, will not be returned by
     113             :    fd_top_votes_query. */
     114             : 
     115             : void
     116             : fd_top_votes_invalidate( fd_top_votes_t *    top_votes,
     117             :                          fd_pubkey_t const * pubkey );
     118             : 
     119             : /* fd_top_votes_query queries a fd_top_votes_t structure given a
     120             :    vote account and returns 1 if the vote account is in the top voters
     121             :    set and 0 otherwise.  If the vote account is in the top voters set,
     122             :    the node account, stake, last vote slot, and last vote timestamp are
     123             :    all optionally returned via parameter pointers. */
     124             : 
     125             : int
     126             : fd_top_votes_query( fd_top_votes_t const * top_votes,
     127             :                     fd_pubkey_t const *    pubkey,
     128             :                     fd_pubkey_t *          node_account_out_opt,
     129             :                     ulong *                stake_out_opt,
     130             :                     ulong *                last_vote_slot_out_opt,
     131             :                     long *                 last_vote_timestamp_out_opt,
     132             :                     uchar *                commission_out_opt );
     133             : 
     134             : /* fd_top_votes_refresh refreshes the top votes set given an accdb
     135             :    user and a transaction xid.  The top votes are populated with a
     136             :    snapshot manifest before the account data is loaded in.  Information
     137             :    about latest votes and if the account still exists must be refreshed
     138             :    using the accounts database afterwards. */
     139             : 
     140             : void
     141             : fd_top_votes_refresh( fd_top_votes_t *          top_votes,
     142             :                       fd_accdb_user_t *         accdb,
     143             :                       fd_funk_txn_xid_t const * xid );
     144             : 
     145             : #define FD_TOP_VOTES_ITER_FOOTPRINT (16UL)
     146             : #define FD_TOP_VOTES_ITER_ALIGN     (8UL)
     147             : struct map_iter;
     148             : typedef struct map_iter fd_top_votes_iter_t;
     149             : 
     150             : /* A caller can iterate through the entries in the top votes set.  The
     151             :    iterator is initialized by a call to fd_top_votes_iter_init.  The
     152             :    caller is responsible for managing the memory for the iterator.
     153             :    It is safe to call fd_top_votes_iter_next if the result of
     154             :    fd_top_votes_iter_done() == 0.  It is safe to call
     155             :    fd_top_votes_iter_ele() to get the current entry if there is a valid
     156             :    initialized iterator.
     157             : 
     158             :    Example use:
     159             :    uchar __attribute__((aligned(FD_TOP_VOTES_ITER_ALIGN))) iter_mem[ FD_TOP_VOTES_ITER_FOOTPRINT ];
     160             :    for( fd_top_votes_iter_t * iter = fd_top_votes_iter_init( top_votes, iter_mem );
     161             :         !fd_top_votes_iter_done( top_votes, iter );
     162             :         fd_top_votes_iter_next( top_votes, iter ) ) {
     163             :      int is_valid = fd_top_votes_iter_ele( top_votes, iter, &pubkey, &node_account, &stake, &commission, &last_vote_slot, &last_vote_timestamp );
     164             :    } */
     165             : 
     166             : fd_top_votes_iter_t *
     167             : fd_top_votes_iter_init( fd_top_votes_t const * top_votes,
     168             :                         uchar                  iter_mem[ static FD_TOP_VOTES_ITER_FOOTPRINT ] );
     169             : 
     170             : int
     171             : fd_top_votes_iter_done( fd_top_votes_t const * top_votes,
     172             :                         fd_top_votes_iter_t *  iter );
     173             : 
     174             : void
     175             : fd_top_votes_iter_next( fd_top_votes_t const * top_votes,
     176             :                         fd_top_votes_iter_t *  iter );
     177             : 
     178             : int
     179             : fd_top_votes_iter_ele( fd_top_votes_t const * top_votes,
     180             :                        fd_top_votes_iter_t *  iter,
     181             :                        fd_pubkey_t *          pubkey_out,
     182             :                        fd_pubkey_t *          node_account_out_opt,
     183             :                        ulong *                stake_out_opt,
     184             :                        uchar *                commission_out_opt,
     185             :                        ulong *                last_vote_slot_out_opt,
     186             :                        long *                 last_vote_timestamp_out_opt );
     187             : 
     188             : FD_PROTOTYPES_END
     189             : 
     190             : #endif

Generated by: LCOV version 1.14