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

Generated by: LCOV version 1.14