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

Generated by: LCOV version 1.14