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: 38 43 88.4 %
Date: 2026-10-22 18:10:43 Functions: 4 5 80.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         615 :                                  uchar       out_mem[ static FD_SYSVAR_RECENT_HASHES_BINCODE_SZ ] ) {
       8         615 :   fd_blockhashes_t const * bhq = &bank->f.block_hash_queue;
       9             : 
      10         615 :   ulong queue_sz = fd_blockhash_deq_cnt( bhq->d.deque );
      11         615 :   ulong out_max  = fd_ulong_min( queue_sz, FD_SYSVAR_RECENT_HASHES_CAP );
      12             : 
      13         615 :   uchar * enc = out_mem;
      14         615 :   fd_memcpy( enc, &out_max, sizeof(ulong) );
      15             : 
      16         615 :   enc += sizeof(ulong);
      17             : 
      18         615 :   ulong out_idx = 0UL;
      19         615 :   for( fd_blockhash_deq_iter_t iter = fd_blockhash_deq_iter_init_rev( bhq->d.deque );
      20       92097 :        out_idx<FD_SYSVAR_RECENT_HASHES_CAP &&
      21       92097 :           !fd_blockhash_deq_iter_done_rev( bhq->d.deque, iter );
      22       91482 :        out_idx++,   iter = fd_blockhash_deq_iter_prev( bhq->d.deque, iter ) ) {
      23       91482 :     fd_blockhash_info_t const * n = fd_blockhash_deq_iter_ele_const( bhq->d.deque, iter );
      24       91482 :     fd_memcpy( enc, n->hash.uc, 32 );
      25       91482 :     FD_STORE( ulong, enc+32, n->lamports_per_signature );
      26       91482 :     enc += 40;
      27       91482 :   }
      28         615 : }
      29             : 
      30             : void
      31             : fd_sysvar_recent_hashes_init( fd_bank_t *        bank,
      32             :                               fd_accdb_t *       accdb,
      33           0 :                               fd_capture_ctx_t * capture_ctx ) {
      34           0 :   uchar enc[ FD_SYSVAR_RECENT_HASHES_BINCODE_SZ ] = {0};
      35           0 :   encode_rbh_from_blockhash_queue( bank, enc );
      36           0 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_recent_block_hashes_id, enc, FD_SYSVAR_RECENT_HASHES_BINCODE_SZ );
      37           0 : }
      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         615 :                     fd_hash_t const * hash ) {
      43         615 :   fd_blockhashes_t * bhq = &bank->f.block_hash_queue;
      44         615 :   fd_blockhash_info_t * bh = fd_blockhashes_push_new( bhq, hash );
      45         615 :   bh->lamports_per_signature = bank->f.rbh_lamports_per_sig;
      46         615 : }
      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         615 :                                 fd_capture_ctx_t * capture_ctx ) {
      57         615 :   register_blockhash( bank, &bank->f.poh );
      58             : 
      59         615 :   uchar enc[ FD_SYSVAR_RECENT_HASHES_BINCODE_SZ ] = {0};
      60         615 :   encode_rbh_from_blockhash_queue( bank, enc );
      61         615 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_recent_block_hashes_id, enc, sizeof(enc) );
      62         615 : }
      63             : 
      64             : int
      65             : fd_sysvar_recent_hashes_validate( uchar const * data,
      66       61069 :                                   ulong         sz ) {
      67       61069 :   if( FD_UNLIKELY( sz < sizeof(ulong)) ) return 0;
      68       61069 :   ulong len = FD_LOAD( ulong, data );
      69       61069 :   data += sizeof(ulong); sz -= sizeof(ulong);
      70       61069 :   ulong min_sz;
      71       61069 :   if( FD_UNLIKELY( __builtin_umull_overflow( len, 40UL, &min_sz ) ) ) return 0;
      72       61069 :   if( FD_UNLIKELY( sz < min_sz ) ) return 0;
      73       61069 :   return 1;
      74       61069 : }

Generated by: LCOV version 1.14