LCOV - code coverage report
Current view: top level - discof/backup - fd_ssmanifest_encoder.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 330 0.0 %
Date: 2026-11-11 12:40:43 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /* Serialize a chunk of values.
       2             :    Each call may only produce up to FD_SSMANIFEST_BUF_MIN bytes worth of
       3             :    serialized data.  Therefore, we split the serializer into multiple
       4             :    states. */
       5             : 
       6           0 : ENCODE_FN {
       7           0 :   fd_bank_t const * bank = enc->bank;
       8             : 
       9           0 :   PREP
      10             : 
      11           0 :   switch( enc->state ) {
      12           0 :   case STATE_BLOCKHASH_QUEUE: {
      13           0 :     fd_blockhashes_t const *    bhq   = &bank->f.block_hash_queue;
      14           0 :     fd_blockhash_info_t const * deq   = bhq->d.deque;
      15           0 :     ulong                       total = fd_blockhash_deq_cnt( deq );
      16             : 
      17             :     /* Write the newest FD_BLOCKHASHES_MAX entries by count, each at its
      18             :        own absolute hash_index. with skipped indices it can keep an
      19             :        entry older than max_age. */
      20           0 :     ulong cnt     = fd_ulong_min( total, FD_BLOCKHASHES_MAX );
      21           0 :     ulong to_skip = total - cnt;
      22             : 
      23           0 :     fd_blockhash_info_t const * last = fd_blockhashes_peek_last( bhq );
      24           0 :     PUSH_VAL( ulong, last ? last->hash_index : 0UL ); /* last hash index */
      25           0 :     PUSH_VAL( uchar, !!last );
      26           0 :     if( last ) PUSH_VAL( fd_hash_t, last->hash );
      27             : 
      28           0 :     PUSH_VAL( ulong, cnt );
      29           0 :     for( ulong i=to_skip; i<total; i++ ) {
      30           0 :       fd_blockhash_info_t const * ele = fd_blockhash_deq_peek_index_const( deq, i );
      31           0 :       PUSH_VAL( fd_hash_t, ele->hash );
      32           0 :       PUSH_VAL( ulong,     ele->lamports_per_signature );
      33           0 :       PUSH_VAL( ulong,     ele->hash_index );
      34           0 :       PUSH_VAL( ulong,     0UL ); /* timestamp, ignored */
      35           0 :     }
      36           0 :     PUSH_VAL( ulong, FD_BLOCKHASHES_MAX-1UL ); /* max_age */
      37           0 :     enc->state = STATE_HASHES;
      38           0 :     break;
      39           0 :   }
      40           0 :   case STATE_HASHES: {
      41           0 :     PUSH_VAL( ulong,     0UL ); /* ancestors */
      42           0 :     PUSH_VAL( fd_hash_t, bank->f.bank_hash      );
      43           0 :     PUSH_VAL( fd_hash_t, bank->f.prev_bank_hash );
      44           0 :     PUSH_VAL( ulong,     bank->f.parent_slot    );
      45           0 :     enc->state = STATE_HARD_FORKS;
      46           0 :     break;
      47           0 :   }
      48           0 :   case STATE_HARD_FORKS: {
      49           0 :     PUSH_VAL( ulong, bank->f.hard_fork_cnt );
      50           0 :     for( ulong i=0UL; i<bank->f.hard_fork_cnt; i++ ) {
      51           0 :       PUSH_VAL( ulong, bank->f.hard_forks[ i ].slot );
      52           0 :       PUSH_VAL( ulong, bank->f.hard_forks[ i ].cnt  );
      53           0 :     }
      54           0 :     enc->state = STATE_COUNTERS;
      55           0 :     break;
      56           0 :   }
      57           0 :   case STATE_COUNTERS: {
      58           0 :     PUSH_VAL( ulong,  bank->f.parent_txn_count + bank->f.txn_count                );
      59           0 :     PUSH_VAL( ulong,  bank->f.max_tick_height                                     );
      60           0 :     PUSH_VAL( ulong,  bank->f.signature_count                                     );
      61           0 :     PUSH_VAL( ulong,  bank->f.capitalization                                      );
      62           0 :     PUSH_VAL( ulong,  bank->f.max_tick_height                                     );
      63           0 :     PUSH_VAL( uchar,  0 ); /* hashes_per_tick: None */
      64           0 :     PUSH_VAL( ulong,  bank->f.ticks_per_slot                                      );
      65           0 :     PUSH_VAL( fd_w_u128_t, (fd_w_u128_t){ .ud = bank->f.slot_params.ns_per_slot } );
      66           0 :     PUSH_VAL( ulong,  bank->f.genesis_creation_time                               );
      67           0 :     PUSH_VAL( double, bank->f.slot_params.slots_per_year                          );
      68           0 :     PUSH_VAL( ulong,  0UL ); /* accounts_data_len, unused */
      69           0 :     PUSH_VAL( ulong,  bank->f.slot                                                );
      70           0 :     PUSH_VAL( ulong,  bank->f.epoch                                               );
      71           0 :     PUSH_VAL( ulong,  bank->f.block_height                                        );
      72           0 :     PUSH_VAL( fd_pubkey_t, enc->leader );
      73           0 :     PUSH_VAL( ulong, 0UL ); /* unused_collector_fees */
      74           0 :     PUSH_VAL( ulong, 0UL ); /* unused_fee_calculator */
      75             : 
      76           0 :     fd_fee_rate_governor_t const * frg = &bank->f.fee_rate_governor;
      77           0 :     PUSH_VAL( ulong, frg->target_lamports_per_signature );
      78           0 :     PUSH_VAL( ulong, frg->target_signatures_per_slot    );
      79           0 :     PUSH_VAL( ulong, frg->min_lamports_per_signature    );
      80           0 :     PUSH_VAL( ulong, frg->max_lamports_per_signature    );
      81           0 :     PUSH_VAL( uchar, frg->burn_percent                  );
      82           0 :     PUSH_VAL( ulong, 0UL );
      83           0 :     PUSH_VAL( ulong, bank->f.epoch );
      84             : 
      85           0 :     fd_epoch_schedule_t const * es = &bank->f.epoch_schedule;
      86           0 :     fd_rent_t const * rent = &bank->f.rent;
      87           0 :     PUSH_VAL( ulong,  es->slots_per_epoch                );
      88           0 :     PUSH_VAL( ulong,  es->leader_schedule_slot_offset    );
      89           0 :     PUSH_VAL( uchar,  es->warmup                         );
      90           0 :     PUSH_VAL( ulong,  es->first_normal_epoch             );
      91           0 :     PUSH_VAL( ulong,  es->first_normal_slot              );
      92           0 :     PUSH_VAL( double, bank->f.slot_params.slots_per_year );
      93           0 :     PUSH_VAL( ulong,  rent->lamports_per_uint8_year      );
      94           0 :     PUSH_VAL( double, rent->exemption_threshold          );
      95           0 :     PUSH_VAL( uchar,  rent->burn_percent                 );
      96           0 :     PUSH_VAL( ulong,  es->slots_per_epoch                );
      97           0 :     PUSH_VAL( ulong,  es->leader_schedule_slot_offset    );
      98           0 :     PUSH_VAL( uchar,  es->warmup                         );
      99           0 :     PUSH_VAL( ulong,  es->first_normal_epoch             );
     100           0 :     PUSH_VAL( ulong,  es->first_normal_slot              );
     101             : 
     102           0 :     fd_inflation_t const * inf = &bank->f.inflation;
     103           0 :     PUSH_VAL( double, inf->initial        );
     104           0 :     PUSH_VAL( double, inf->terminal       );
     105           0 :     PUSH_VAL( double, inf->taper          );
     106           0 :     PUSH_VAL( double, inf->foundation     );
     107           0 :     PUSH_VAL( double, inf->foundation_term );
     108           0 :     PUSH_VAL( double, inf->unused          );
     109             : 
     110           0 :     enc->state = STATE_VOTE_ACCOUNTS;
     111           0 :     break;
     112           0 :   }
     113           0 :   case STATE_VOTE_ACCOUNTS: {
     114           0 :     PUSH_VAL( ulong, 0UL ); /* zero vote_accounts */
     115           0 :     PUSH_VAL( ulong, 0UL ); /* zero stake delegations */
     116           0 :     PUSH_VAL( ulong, 0UL ); /* unused */
     117           0 :     PUSH_VAL( ulong, bank->f.epoch );
     118           0 :     enc->state = STATE_STAKE_HISTORY;
     119           0 :     break;
     120           0 :   }
     121           0 :   case STATE_STAKE_DELEGATION: { FD_LOG_ERR(( "TODO")); }
     122           0 :   case STATE_STAKE_EPOCH: { FD_LOG_ERR(( "TODO")); }
     123           0 :   case STATE_STAKE_HISTORY: {
     124           0 :     PUSH_VAL( ulong, 0UL ); /* zero stake history entries */
     125           0 :     enc->state = STATE_BANK_TRAILER;
     126           0 :     break;
     127           0 :   }
     128           0 :   case STATE_BANK_TRAILER: {
     129           0 :     PUSH_VAL( ulong, 0UL ); /* unused_accounts.unused1 */
     130           0 :     PUSH_VAL( ulong, 0UL ); /* unused_accounts.unused2 */
     131           0 :     PUSH_VAL( ulong, 0UL ); /* unused_accounts.unused3 */
     132           0 :     PUSH_VAL( ulong, 0UL ); /* unused_epoch_stakes */
     133           0 :     PUSH_VAL( uchar, 0   ); /* is_delta */
     134           0 :     PUSH_VAL( ulong, 0UL ); /* zero account_storage_entries */
     135           0 :     enc->state = STATE_BANK_HASH_INFO;
     136           0 :     break;
     137           0 :   }
     138           0 :   case STATE_ACCOUNT_STORAGE_ENTRY: { FD_LOG_ERR(( "TODO")); }
     139           0 :   case STATE_BANK_HASH_INFO: {
     140             :     /* AccountsDbFields */
     141           0 :     PUSH_VAL( ulong, 0UL          ); /* write_version, unused */
     142           0 :     PUSH_VAL( ulong, bank->f.slot ); /* slot */
     143           0 :     PUSH_VAL( fd_hash_t, (fd_hash_t){0} ); /* unused_accounts_delta_hash */
     144           0 :     PUSH_VAL( fd_hash_t, (fd_hash_t){0} ); /* unused_accounts_hash */
     145           0 :     PUSH_VAL( ulong, 0UL ); /* num_updated_accounts, unused */
     146           0 :     PUSH_VAL( ulong, 0UL ); /* num_removed_accounts, unused */
     147           0 :     PUSH_VAL( ulong, 0UL ); /* num_lamports_stored, unused */
     148           0 :     PUSH_VAL( ulong, 0UL ); /* total_data_len, unused */
     149           0 :     PUSH_VAL( ulong, 0UL ); /* num_executable_accounts, unused */
     150           0 :     PUSH_VAL( ulong, 0UL ); /* historical_roots, unused */
     151           0 :     PUSH_VAL( ulong, 0UL ); /* historical_roots_with_hash, unused */
     152             :     /* ExtraFieldsToSerialize */
     153           0 :     PUSH_VAL( ulong, bank->f.rbh_lamports_per_sig );
     154           0 :     PUSH_VAL( uchar, 0 ); /* unused_incremental_snapshot_persistence */
     155           0 :     PUSH_VAL( uchar, 0 ); /* unused_epoch_accounts_hash */
     156             : 
     157           0 :     ulong epoch = bank->f.epoch;
     158           0 :     ulong epoch_cnt = fd_ulong_min( epoch, 3UL ) + 2UL; /* keys max(E-3,0)..E+1, as agave retains */
     159           0 :     PUSH_VAL( ulong, epoch_cnt );
     160           0 :     enc->epoch_cnt = (uchar)epoch_cnt;
     161           0 :     enc->epoch_idx = 0;
     162           0 :     enc->state = STATE_EPOCH_STAKES;
     163           0 :     break;
     164           0 :   }
     165           0 :   case STATE_EPOCH_STAKES: {
     166           0 :     ulong epoch_key = epoch_stakes_key      ( bank, enc->epoch_idx );
     167           0 :     int   iter_kind = epoch_stakes_iter_kind( bank, enc->epoch_idx );
     168           0 :     fd_vote_stakes_t * vote_stakes = fd_bank_vote_stakes( bank );
     169           0 :     ushort             fork_id     = bank->vote_stakes_fork_id;
     170             : 
     171           0 :     uint vote_cnt = 0U;
     172           0 :     for( fd_vote_stakes_iter_t * iter = fd_vote_stakes_iter_init( vote_stakes, fork_id, iter_kind, enc->vote_stakes_iter_mem );
     173           0 :          !fd_vote_stakes_iter_done( vote_stakes, fork_id, iter_kind, iter );
     174           0 :          fd_vote_stakes_iter_next( vote_stakes, fork_id, iter_kind, iter ) ) vote_cnt++;
     175           0 :     fd_vote_stakes_iter_init( vote_stakes, fork_id, iter_kind, enc->vote_stakes_iter_mem );
     176           0 :     enc->vote_cnt    = vote_cnt;
     177           0 :     enc->vote_idx    = 0;
     178           0 :     enc->total_stake = 0UL;
     179             : 
     180           0 :     PUSH_VAL( ulong, epoch_key );
     181           0 :     PUSH_VAL( uint,  0U ); /* variant = 0 (VersionedEpochStakes::Current) */
     182           0 :     PUSH_VAL( ulong, (ulong)vote_cnt );
     183             : 
     184           0 :     enc->state = (vote_cnt > 0U) ? STATE_EPOCH_STAKES_STAKES : STATE_EPOCH_STAKES_EPOCH;
     185           0 :     break;
     186           0 :   }
     187           0 :   case STATE_EPOCH_STAKES_STAKES: {
     188           0 :     int iter_kind = epoch_stakes_iter_kind( bank, enc->epoch_idx );
     189             : 
     190           0 :     ulong       ec_cnt            = 0UL;
     191           0 :     fd_epoch_credits_t const * ec = NULL;
     192             : 
     193           0 :     fd_vote_stakes_t * vote_stakes = fd_bank_vote_stakes( bank );
     194           0 :     ushort             fork_id     = bank->vote_stakes_fork_id;
     195             : 
     196           0 :     fd_vote_stakes_iter_t * iter = fd_type_pun( enc->vote_stakes_iter_mem );
     197           0 :     FD_TEST( !fd_vote_stakes_iter_done( vote_stakes, fork_id, iter_kind, iter ) );
     198           0 :     fd_vote_stakes_ele_t ele[1];
     199           0 :     fd_vote_stakes_iter_ele( vote_stakes, fork_id, iter_kind, iter, ele );
     200             : 
     201           0 :     if( iter_kind==FD_VOTE_STAKES_ITER_T_1 ) {
     202           0 :       ec = find_epoch_credits( enc->bank, &ele->pubkey );
     203           0 :       FD_TEST( ec );
     204           0 :       ec_cnt = ec->cnt;
     205           0 :     }
     206             : 
     207             :     /* SIMD-0232 collectors.  t-3..t-5 collectors are never consulted on
     208             :        reload; encoded as zero. */
     209           0 :     fd_pubkey_t inflation_collector = {0};
     210           0 :     fd_pubkey_t block_collector     = {0};
     211           0 :     if( FD_LIKELY( iter_kind==FD_VOTE_STAKES_ITER_T_1 || iter_kind==FD_VOTE_STAKES_ITER_T_2 ) ) {
     212           0 :       inflation_collector = ele->inflation_collector;
     213           0 :       block_collector     = ele->block_collector;
     214           0 :     }
     215             : 
     216             :     /* A zeroed key means no BLS key is registered (serialized as None) */
     217           0 :     static uchar const no_bls_key[ FD_BLS_PUB_COMPRESSED_SZ ] = {0};
     218           0 :     int has_bls      = !fd_memeq( ele->bls_key, no_bls_key, FD_BLS_PUB_COMPRESSED_SZ );
     219           0 :     int has_location = ele->location.x || ele->location.y || ele->location.z;
     220             : 
     221           0 :     enc->total_stake += ele->stake;
     222             : 
     223           0 :     FD_TEST( ec_cnt<=FD_EPOCH_CREDITS_MAX );
     224             : 
     225           0 :     ulong data_length = fd_ulong_if( has_location, FD_VOTE_STATE_V5_SZ, 186UL + fd_ulong_if( !!has_bls, FD_BLS_PUB_COMPRESSED_SZ, 0UL ) + 24UL * ec_cnt );
     226             : 
     227             :     /* Vote account key + stake */
     228           0 :     PUSH_VAL( fd_pubkey_t, ele->pubkey );
     229           0 :     PUSH_VAL( ulong,       ele->stake  );
     230             : 
     231             :     /* AccountSharedData: lamports, data_length */
     232           0 :     PUSH_VAL( ulong, 0UL         );
     233           0 :     PUSH_VAL( ulong, data_length );
     234             : 
     235           0 :     if( has_location ) {
     236           0 :       ulong epoch_key = epoch_stakes_key( bank, enc->epoch_idx );
     237           0 :       ulong ec_skip   = fd_ulong_sat_sub( ec_cnt, FD_VOTE_STATE_V5_ACCUMULATED_LAMPORTS_MAX );
     238           0 :       fd_vote_state_v5_t v5 = {
     239           0 :         .node_pubkey                             = ele->node_account,
     240           0 :         .inflation_rewards_collector             = inflation_collector,
     241           0 :         .block_revenue_collector                 = block_collector,
     242           0 :         .inflation_rewards_commission_bps_len    = 1,
     243           0 :         .block_revenue_commission_bps_len        = 1,
     244           0 :         .pending_delegator_rewards               = ele->pending_delegator_rewards,
     245           0 :         .location                                = ele->location,
     246           0 :         .inflation_rewards_commission_bps_epochs = { epoch_key },
     247           0 :         .inflation_rewards_commission_bps        = { ele->commission },
     248           0 :         .block_revenue_commission_bps_epochs     = { epoch_key },
     249           0 :         .block_revenue_commission_bps            = { ele->block_revenue_commission_bps },
     250           0 :         .latest_vote                             = ULONG_MAX,
     251           0 :         .root_slot                               = ULONG_MAX,
     252           0 :         .accumulated_lamports_len                = (uint)( ec_cnt-ec_skip ),
     253           0 :         .rank_epoch                              = ULONG_MAX,
     254           0 :         .rank                                    = USHORT_MAX
     255           0 :       };
     256           0 :       memcpy( v5.bls_pubkey_compressed, ele->bls_key, FD_BLS_PUB_COMPRESSED_SZ );
     257           0 :       for( ulong j=ec_skip; j<ec_cnt; j++ ) {
     258           0 :         v5.accumulated_lamports[ j-ec_skip ] = (fd_vote_epoch_credits_t){ (ulong)ec->epoch[j],
     259           0 :                                                                           ec->base_credits + (ulong)ec->credits_delta[j],
     260           0 :                                                                           ec->base_credits + (ulong)ec->prev_credits_delta[j] };
     261           0 :       }
     262           0 :       typedef struct { uchar b[ FD_VOTE_STATE_V5_SZ-sizeof(uint)-sizeof(fd_vote_state_v5_t) ]; } v5_tail_t;
     263           0 :       PUSH_VAL( uint,               fd_vote_state_versioned_enum_v5 );
     264           0 :       PUSH_VAL( fd_vote_state_v5_t, v5                              );
     265           0 :       PUSH_VAL( v5_tail_t,          (v5_tail_t){0}                  );
     266           0 :     } else {
     267             :       /* VoteStateV4 */
     268           0 :       PUSH_VAL( uint,       3U           ); /* variant = V4 */
     269           0 :       PUSH_VAL( fd_pubkey_t, ele->node_account ); /* node_pubkey */
     270           0 :       PUSH_VAL( fd_pubkey_t, (fd_pubkey_t){0} ); /* authorized_withdrawer */
     271           0 :       PUSH_VAL( fd_pubkey_t, inflation_collector ); /* inflation_rewards_collector */
     272           0 :       PUSH_VAL( fd_pubkey_t, block_collector     ); /* block_revenue_collector */
     273           0 :       PUSH_VAL( ushort, ele->commission ); /* inflation_rewards_commission_bps */
     274           0 :       PUSH_VAL( ushort, ele->block_revenue_commission_bps ); /* block_revenue_commission_bps */
     275           0 :       PUSH_VAL( ulong,  ele->pending_delegator_rewards    ); /* pending_delegator_rewards */
     276           0 :       if( has_bls ) {
     277           0 :         typedef struct { uchar b[ FD_BLS_PUB_COMPRESSED_SZ ]; } bls_key_compressed_t;
     278           0 :         PUSH_VAL( uchar, 1        ); /* bls_pubkey_compressed = Some */
     279           0 :         PUSH_VAL( bls_key_compressed_t, *(bls_key_compressed_t const *)ele->bls_key );
     280           0 :       } else {
     281           0 :         PUSH_VAL( uchar, 0        ); /* bls_pubkey_compressed = None */
     282           0 :       }
     283           0 :       PUSH_VAL( ulong,  0UL      ); /* votes_length = 0 */
     284           0 :       PUSH_VAL( uchar,  0        ); /* root_slot = None */
     285           0 :       PUSH_VAL( ulong,  0UL      ); /* authorized_voters_length = 0 */
     286             : 
     287             :       /* Epoch credits */
     288           0 :       PUSH_VAL( ulong, ec_cnt );
     289           0 :       for( ulong j=0UL; j<ec_cnt; j++ ) {
     290           0 :         PUSH_VAL( ulong, (ulong)ec->epoch[j] );
     291           0 :         PUSH_VAL( ulong, ec->base_credits + (ulong)ec->credits_delta[j] );
     292           0 :         PUSH_VAL( ulong, ec->base_credits + (ulong)ec->prev_credits_delta[j] );
     293           0 :       }
     294             : 
     295           0 :       PUSH_VAL( ulong, 0UL ); /* last_timestamp_slot */
     296           0 :       PUSH_VAL( ulong, 0UL ); /* last_timestamp_timestamp */
     297           0 :     }
     298             : 
     299             :     /* AccountSharedData trailer */
     300           0 :     PUSH_VAL( fd_pubkey_t, fd_solana_vote_program_id ); /* owner */
     301           0 :     PUSH_VAL( uchar,       1                         ); /* executable */
     302           0 :     PUSH_VAL( ulong,       0UL                       ); /* rent_epoch */
     303             : 
     304           0 :     enc->vote_idx++;
     305           0 :     fd_vote_stakes_iter_next( vote_stakes, fork_id, iter_kind, iter );
     306           0 :     if( enc->vote_idx >= enc->vote_cnt ) enc->state = STATE_EPOCH_STAKES_EPOCH;
     307           0 :     break;
     308           0 :   }
     309           0 :   case STATE_EPOCH_STAKES_EPOCH: {
     310           0 :     ulong epoch_key = epoch_stakes_key( bank, enc->epoch_idx );
     311             : 
     312           0 :     PUSH_VAL( ulong, 0UL       ); /* stake_delegations_length = 0 */
     313           0 :     PUSH_VAL( ulong, 0UL       ); /* unused */
     314           0 :     PUSH_VAL( ulong, epoch_key ); /* epoch */
     315           0 :     PUSH_VAL( ulong, 0UL       ); /* stake_history_length = 0 */
     316           0 :     enc->state = STATE_EPOCH_TOTAL_STAKE;
     317           0 :     break;
     318           0 :   }
     319           0 :   case STATE_EPOCH_TOTAL_STAKE: {
     320           0 :     int iter_kind = epoch_stakes_iter_kind( bank, enc->epoch_idx );
     321           0 :     ulong total_stake = (iter_kind==FD_VOTE_STAKES_ITER_T_1) ? bank->f.total_epoch_stake : enc->total_stake;
     322           0 :     PUSH_VAL( ulong, total_stake );
     323           0 :     enc->state = STATE_NODE_VOTE_ACCOUNTS;
     324           0 :     break;
     325           0 :   }
     326           0 :   case STATE_NODE_VOTE_ACCOUNTS: {
     327             :     /* node_id_to_vote_accounts: HashMap<node, (Vec<vote>, total_stake)> */
     328           0 :     fd_ssmanifest_epoch_map_t const * map = &enc->epoch_map[ enc->epoch_idx ];
     329           0 :     PUSH_VAL( ulong, map->node_cnt );
     330           0 :     for( ulong i=0UL; i<map->vote_cnt; ) {
     331           0 :       fd_pubkey_t const * node = &map->vote[ i ].node;
     332           0 :       ulong j = i;
     333           0 :       ulong total_stake = 0UL;
     334           0 :       for( ; j<map->vote_cnt && fd_memeq( map->vote[ j ].node.uc, node->uc, sizeof(fd_pubkey_t) ); j++ ) {
     335           0 :         total_stake += map->vote[ j ].stake;
     336           0 :       }
     337           0 :       PUSH_VAL( fd_pubkey_t, *node );
     338           0 :       PUSH_VAL( ulong,       j-i   );
     339           0 :       for( ulong k=i; k<j; k++ ) {
     340           0 :         PUSH_VAL( fd_pubkey_t, map->vote[ k ].vote );
     341           0 :       }
     342           0 :       PUSH_VAL( ulong, total_stake );
     343           0 :       i = j;
     344           0 :     }
     345           0 :     enc->state = STATE_AUTH_VOTER;
     346           0 :     break;
     347           0 :   }
     348           0 :   case STATE_AUTH_VOTER: {
     349             :     /* epoch_authorized_voters: HashMap<vote, voter> */
     350           0 :     fd_ssmanifest_epoch_map_t const * map = &enc->epoch_map[ enc->epoch_idx ];
     351           0 :     PUSH_VAL( ulong, map->vote_cnt );
     352           0 :     for( ulong i=0UL; i<map->vote_cnt; i++ ) {
     353           0 :       PUSH_VAL( fd_pubkey_t, map->vote[ i ].vote  );
     354           0 :       PUSH_VAL( fd_pubkey_t, map->vote[ i ].voter );
     355           0 :     }
     356           0 :     enc->epoch_idx++;
     357           0 :     enc->state = (enc->epoch_idx < enc->epoch_cnt) ? STATE_EPOCH_STAKES : STATE_LTHASH;
     358           0 :     break;
     359           0 :   }
     360           0 :   case STATE_LTHASH: {
     361           0 :     PUSH_VAL( uchar, 1 );
     362           0 :     PUSH_VAL( fd_lthash_value_t, bank->f.lthash );
     363           0 :     enc->state = STATE_BLOCK_ID;
     364           0 :     break;
     365           0 :   }
     366           0 :   case STATE_BLOCK_ID: {
     367           0 :     int has_block_id = !fd_hash_check_zero( &bank->f.block_id );
     368           0 :     PUSH_VAL( uchar, (uchar)has_block_id );
     369           0 :     if( has_block_id ) PUSH_VAL( fd_hash_t, bank->f.block_id );
     370           0 :     enc->state = STATE_DONE;
     371           0 :     break;
     372           0 :   }
     373           0 :   case STATE_DONE:
     374           0 :     enc->state = STATE_INIT; /* ready for the next pass */
     375           0 :     return 0UL;
     376           0 :   default:
     377           0 :     FD_LOG_CRIT(( "invalid state reached (%u)", enc->state ));
     378           0 :   }
     379             : 
     380           0 :   return RET_EXPR;
     381           0 : }
     382             : 
     383             : #undef PREP
     384             : #undef ENCODE_FN
     385             : #undef PUSH_VAL
     386             : #undef RET_EXPR

Generated by: LCOV version 1.14