LCOV - code coverage report
Current view: top level - discof/backup - fd_ssmanifest_writer.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 112 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 5 0.0 %

          Line data    Source code
       1             : #include "fd_ssmanifest_writer.h"
       2             : #include "../../flamenco/runtime/fd_system_ids.h"
       3             : #include "../../flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.h"
       4             : #include "../../flamenco/runtime/program/vote/fd_vote_state_versioned.h"
       5             : #include "../../ballet/bls/fd_bls.h"
       6             : 
       7             : #define SORT_NAME        sort_epoch_vote_by_node
       8           0 : #define SORT_KEY_T       fd_ssmanifest_epoch_vote_t
       9           0 : #define SORT_BEFORE(a,b) (0>memcmp( (a).node.uc, (b).node.uc, sizeof(fd_pubkey_t) ))
      10             : #include "../../util/tmpl/fd_sort.c"
      11             : 
      12           0 : #define STATE_BLOCKHASH_QUEUE        1
      13           0 : #define STATE_HASHES                 2
      14           0 : #define STATE_HARD_FORKS             3
      15           0 : #define STATE_COUNTERS               4
      16           0 : #define STATE_VOTE_ACCOUNTS          5
      17           0 : #define STATE_STAKE_DELEGATION       6
      18           0 : #define STATE_STAKE_EPOCH            7
      19           0 : #define STATE_STAKE_HISTORY          8
      20           0 : #define STATE_BANK_TRAILER           9
      21           0 : #define STATE_ACCOUNT_STORAGE_ENTRY 10
      22           0 : #define STATE_BANK_HASH_INFO        11
      23           0 : #define STATE_EPOCH_STAKES          12
      24           0 : #define STATE_EPOCH_STAKES_STAKES   13
      25           0 : #define STATE_EPOCH_STAKES_EPOCH    14
      26           0 : #define STATE_EPOCH_STAKE_HISTORY   15
      27           0 : #define STATE_EPOCH_TOTAL_STAKE     16
      28           0 : #define STATE_NODE_VOTE_ACCOUNTS    17
      29           0 : #define STATE_AUTH_VOTER            18
      30           0 : #define STATE_LTHASH                19
      31           0 : #define STATE_BLOCK_ID              20
      32           0 : #define STATE_DONE                  21
      33           0 : #define STATE_INIT STATE_BLOCKHASH_QUEUE
      34             : 
      35             : /* Epoch stakes entries are keyed max(E-3,0)..E+1, as agave retains.
      36             :    Key E+1 is the t-1 set with credits, E the t-2 set, E-1..E-3 the
      37             :    t-3..t-5 sets. */
      38             : 
      39             : static inline ulong
      40             : epoch_stakes_key( fd_bank_t const * bank,
      41           0 :                   ulong             epoch_idx ) {
      42           0 :   ulong epoch = bank->f.epoch;
      43           0 :   return ( epoch>3UL ? epoch-3UL : 0UL ) + epoch_idx;
      44           0 : }
      45             : 
      46             : static inline int
      47             : epoch_stakes_iter_kind( fd_bank_t const * bank,
      48           0 :                         ulong             epoch_idx ) {
      49           0 :   return (int)( bank->f.epoch + 2UL - epoch_stakes_key( bank, epoch_idx ) );
      50           0 : }
      51             : 
      52             : static fd_epoch_credits_t const *
      53             : find_epoch_credits( fd_bank_t *          bank,
      54           0 :                     fd_pubkey_t const * pubkey ) {
      55           0 :   ulong                      epoch_credits_len;
      56           0 :   fd_epoch_credits_t const * epoch_credits_arr = fd_epoch_credits_store_peek( fd_bank_epoch_credits( bank ), bank->epoch_credits_fork_id, &epoch_credits_len );
      57           0 :   for( ulong i=0UL; i<epoch_credits_len; i++ ) {
      58           0 :     fd_epoch_credits_t const * epoch_credits = &epoch_credits_arr[ i ];
      59           0 :     if( fd_memeq( epoch_credits->pubkey, pubkey, sizeof(fd_pubkey_t) ) ) return epoch_credits;
      60           0 :   }
      61           0 :   return NULL;
      62           0 : }
      63             : 
      64             : /* Size estimate */
      65             : 
      66             : #define ENCODE_FN     static ulong manifest_estimate( fd_ssmanifest_writer_t * enc )
      67           0 : #define PREP          ulong sz = 0UL;
      68           0 : #define PUSH_VAL(t,n) do { sz += sizeof(t); (void)(n); } while(0)
      69           0 : #define RET_EXPR      sz
      70             : #include "fd_ssmanifest_encoder.c"
      71             : 
      72             : fd_ssmanifest_writer_t *
      73             : fd_ssmanifest_writer_init( fd_ssmanifest_writer_t * enc,
      74             :                            fd_bank_t *              bank,
      75             :                            fd_pubkey_t const *      leader,
      76             :                            fd_accdb_t *             accdb,
      77             :                            fd_accdb_fork_id_t       accdb_fork_id,
      78           0 :                            uchar *                  acc_data ) {
      79           0 :   enc->state       = STATE_BLOCKHASH_QUEUE;
      80           0 :   enc->bank        = bank;
      81           0 :   enc->leader      = *leader;
      82           0 :   enc->epoch_idx   = 0;
      83           0 :   enc->epoch_cnt   = 0;
      84           0 :   enc->vote_cnt    = 0;
      85           0 :   enc->vote_idx    = 0;
      86           0 :   enc->total_stake = 0UL;
      87             : 
      88           0 :   fd_vote_stakes_t * vote_stakes = fd_bank_vote_stakes( bank );
      89           0 :   ulong              fork_id     = bank->vote_stakes_fork_id;
      90           0 :   ulong              epoch_cnt   = fd_ulong_min( bank->f.epoch, 3UL ) + 2UL;
      91           0 :   for( ulong epoch_idx=0UL; epoch_idx<epoch_cnt; epoch_idx++ ) {
      92           0 :     fd_ssmanifest_epoch_map_t * map = &enc->epoch_map[ epoch_idx ];
      93           0 :     ulong epoch_key = epoch_stakes_key( bank, epoch_idx );
      94           0 :     int   iter_kind = epoch_stakes_iter_kind( bank, epoch_idx );
      95             : 
      96             :     /* Agave only reads the maps of the previous, current and next
      97             :        epoch.  Older sets keep empty maps. */
      98           0 :     map->vote_cnt = 0UL;
      99           0 :     map->node_cnt = 0UL;
     100           0 :     if( iter_kind>FD_VOTE_STAKES_ITER_T_3 ) continue;
     101             : 
     102           0 :     for( fd_vote_stakes_iter_t * iter = fd_vote_stakes_iter_init( vote_stakes, fork_id, iter_kind, enc->vote_stakes_iter_mem );
     103           0 :          !fd_vote_stakes_iter_done( vote_stakes, fork_id, iter_kind, iter );
     104           0 :          fd_vote_stakes_iter_next( vote_stakes, fork_id, iter_kind, iter ) ) {
     105           0 :       fd_ssmanifest_epoch_vote_t * ele = &map->vote[ map->vote_cnt ];
     106           0 :       fd_vote_stakes_ele_t vs_ele[1];
     107           0 :       fd_vote_stakes_iter_ele( vote_stakes, fork_id, iter_kind, iter, vs_ele );
     108           0 :       ele->vote  = vs_ele->pubkey;
     109           0 :       ele->node  = vs_ele->node_account;
     110           0 :       ele->stake = vs_ele->stake;
     111             : 
     112           0 :       ulong lamports;
     113           0 :       int   executable;
     114           0 :       uchar owner[ 32UL ];
     115           0 :       ulong data_len;
     116           0 :       fd_accdb_read_one_nocache( accdb, accdb_fork_id, ele->vote.uc, &lamports, &executable, owner, acc_data, &data_len );
     117           0 :       if( FD_UNLIKELY( !lamports ||
     118           0 :                        !fd_vsv_is_correct_size_owner_and_init( owner, acc_data, data_len ) ||
     119           0 :                        fd_vote_account_authorized_voter( acc_data, data_len, epoch_key, &ele->voter ) ) ) {
     120           0 :         continue;
     121           0 :       }
     122           0 :       map->vote_cnt++;
     123           0 :     }
     124             : 
     125           0 :     sort_epoch_vote_by_node_inplace( map->vote, map->vote_cnt );
     126           0 :     for( ulong i=0UL; i<map->vote_cnt; i++ ) {
     127           0 :       int new_node = ( i==0UL ) || !fd_memeq( map->vote[ i ].node.uc, map->vote[ i-1UL ].node.uc, sizeof(fd_pubkey_t) );
     128           0 :       if( new_node ) {
     129           0 :         map->node_cnt++;
     130           0 :       }
     131           0 :     }
     132           0 :   }
     133             : 
     134           0 :   enc->serialized_sz = 0UL;
     135           0 :   for(;;) {
     136           0 :     ulong chunk = manifest_estimate( enc );
     137           0 :     if( FD_UNLIKELY( !chunk ) ) break;
     138           0 :     enc->serialized_sz += chunk;
     139           0 :   }
     140           0 :   return enc;
     141           0 : }
     142             : 
     143             : /* Actual encoder */
     144             : 
     145             : __attribute__((cold,noreturn))
     146             : static void fail( fd_ssmanifest_writer_t const * enc,
     147             :                   ulong buf_sz,
     148           0 :                   ulong line_nr ) {
     149           0 :   FD_LOG_ERR(( "buffer overflow (state=%u, buf_sz=%lu, line_nr=%lu)", enc->state, buf_sz, line_nr ));
     150           0 : }
     151             : 
     152             : #define ENCODE_FN                                                         \
     153             :   ulong                                                                   \
     154             :   fd_snap_manifest_serialize( fd_ssmanifest_writer_t * enc,               \
     155             :                               uchar out_buf[ FD_SSMANIFEST_BUF_MIN ],     \
     156             :                               ulong buf_sz )
     157             : #define PREP                                                              \
     158           0 :   uchar * p  = out_buf;                                                   \
     159           0 :   uchar * p1 = out_buf+buf_sz;
     160             : #define PUSH_VAL( t, n )                                                  \
     161           0 :   FD_STORE( t, __extension__({                                            \
     162           0 :     /* compile time bounds check elide */                                 \
     163           0 :     if( FD_UNLIKELY( p+sizeof(t) > p1 ) ) fail( enc, buf_sz, __LINE__ );  \
     164           0 :     uchar * ret = p;                                                      \
     165           0 :     p += sizeof(t);                                                       \
     166           0 :     ret;                                                                  \
     167           0 :   }), (n) )
     168           0 : #define RET_EXPR (ulong)( p - out_buf )
     169             : #include "fd_ssmanifest_encoder.c"

Generated by: LCOV version 1.14