LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_recent_hashes.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 43 43 100.0 %
Date: 2026-06-20 08:01:41 Functions: 5 5 100.0 %

          Line data    Source code
       1             : #include "fd_sysvar_recent_hashes.h"
       2             : #include "fd_sysvar.h"
       3             : #include "../fd_system_ids.h"
       4             : 
       5             : static void
       6             : encode_rbh_from_blockhash_queue( fd_bank_t * bank,
       7         534 :                                  uchar       out_mem[ static FD_SYSVAR_RECENT_HASHES_BINCODE_SZ ] ) {
       8         534 :   fd_blockhashes_t const * bhq = &bank->f.block_hash_queue;
       9             : 
      10         534 :   ulong queue_sz = fd_blockhash_deq_cnt( bhq->d.deque );
      11         534 :   ulong out_max  = fd_ulong_min( queue_sz, FD_SYSVAR_RECENT_HASHES_CAP );
      12             : 
      13         534 :   uchar * enc = out_mem;
      14         534 :   fd_memcpy( enc, &out_max, sizeof(ulong) );
      15             : 
      16         534 :   enc += sizeof(ulong);
      17             : 
      18         534 :   ulong out_idx = 0UL;
      19         534 :   for( fd_blockhash_deq_iter_t iter = fd_blockhash_deq_iter_init_rev( bhq->d.deque );
      20       34671 :        out_idx<FD_SYSVAR_RECENT_HASHES_CAP &&
      21       34671 :           !fd_blockhash_deq_iter_done_rev( bhq->d.deque, iter );
      22       34137 :        out_idx++,   iter = fd_blockhash_deq_iter_prev( bhq->d.deque, iter ) ) {
      23       34137 :     fd_blockhash_info_t const * n = fd_blockhash_deq_iter_ele_const( bhq->d.deque, iter );
      24       34137 :     fd_memcpy( enc, n->hash.uc, 32 );
      25       34137 :     FD_STORE( ulong, enc+32, n->lamports_per_signature );
      26       34137 :     enc += 40;
      27       34137 :   }
      28         534 : }
      29             : 
      30             : void
      31             : fd_sysvar_recent_hashes_init( fd_bank_t *        bank,
      32             :                               fd_accdb_t *       accdb,
      33           3 :                               fd_capture_ctx_t * capture_ctx ) {
      34           3 :   uchar enc[ FD_SYSVAR_RECENT_HASHES_BINCODE_SZ ] = {0};
      35           3 :   encode_rbh_from_blockhash_queue( bank, enc );
      36           3 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_recent_block_hashes_id, enc, FD_SYSVAR_RECENT_HASHES_BINCODE_SZ );
      37           3 : }
      38             : 
      39             : // https://github.com/anza-xyz/agave/blob/e8750ba574d9ac7b72e944bc1227dc7372e3a490/accounts-db/src/blockhash_queue.rs#L113
      40             : static void
      41             : register_blockhash( fd_bank_t *       bank,
      42         531 :                     fd_hash_t const * hash ) {
      43         531 :   fd_blockhashes_t * bhq = &bank->f.block_hash_queue;
      44         531 :   fd_blockhash_info_t * bh = fd_blockhashes_push_new( bhq, hash );
      45         531 :   bh->lamports_per_signature = bank->f.rbh_lamports_per_sig;
      46         531 : }
      47             : 
      48             : /* This implementation is more consistent with Agave's bank implementation for updating the block hashes sysvar:
      49             :    1. Update the block hash queue with the latest poh
      50             :    2. Take the first 150 blockhashes from the queue (or fewer if there are)
      51             :    3. Manually serialize the recent blockhashes
      52             :    4. Set the sysvar account with the new data */
      53             : void
      54             : fd_sysvar_recent_hashes_update( fd_bank_t *        bank,
      55             :                                 fd_accdb_t *       accdb,
      56         531 :                                 fd_capture_ctx_t * capture_ctx ) {
      57         531 :   register_blockhash( bank, &bank->f.poh );
      58             : 
      59         531 :   uchar enc[ FD_SYSVAR_RECENT_HASHES_BINCODE_SZ ] = {0};
      60         531 :   encode_rbh_from_blockhash_queue( bank, enc );
      61         531 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_recent_block_hashes_id, enc, sizeof(enc) );
      62         531 : }
      63             : 
      64             : int
      65             : fd_sysvar_recent_hashes_validate( uchar const * data,
      66        7722 :                                   ulong         sz ) {
      67        7722 :   if( FD_UNLIKELY( sz < sizeof(ulong)) ) return 0;
      68        7719 :   ulong len = FD_LOAD( ulong, data );
      69        7719 :   data += sizeof(ulong); sz -= sizeof(ulong);
      70        7719 :   ulong min_sz;
      71        7719 :   if( FD_UNLIKELY( __builtin_umull_overflow( len, 40UL, &min_sz ) ) ) return 0;
      72        7719 :   if( FD_UNLIKELY( sz < min_sz ) ) return 0;
      73        7713 :   return 1;
      74        7719 : }

Generated by: LCOV version 1.14