LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_slot_hashes.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 50 58 86.2 %
Date: 2026-06-21 08:41:42 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #include "fd_sysvar_slot_hashes.h"
       2             : #include "fd_sysvar.h"
       3             : #include "../fd_system_ids.h"
       4             : #include "../fd_accdb_svm.h"
       5             : 
       6             : void
       7             : fd_sysvar_slot_hashes_init( fd_bank_t *        bank,
       8             :                             fd_accdb_t *       accdb,
       9          18 :                             fd_capture_ctx_t * capture_ctx ) {
      10          18 :   uchar data[ FD_SYSVAR_SLOT_HASHES_BINCODE_SZ ] = {0};
      11          18 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_slot_hashes_id, data, FD_SYSVAR_SLOT_HASHES_BINCODE_SZ );
      12          18 : }
      13             : 
      14             : void
      15             : fd_sysvar_slot_hashes_update( fd_bank_t *        bank,
      16             :                               fd_accdb_t *       accdb,
      17        5340 :                               fd_capture_ctx_t * capture_ctx ) {
      18        5340 :   fd_accdb_svm_update_t update[1];
      19        5340 :   fd_acc_t acc = fd_accdb_svm_open_rw( bank, accdb, update, &fd_sysvar_slot_hashes_id, 0 );
      20        5340 :   if( FD_UNLIKELY( !acc.lamports ) ) {
      21             :     /* Agave initializes a new empty slot_hashes if it doesn't exist */
      22          12 :     fd_sysvar_slot_hashes_init( bank, accdb, capture_ctx );
      23          12 :     acc = fd_accdb_svm_open_rw( bank, accdb, update, &fd_sysvar_slot_hashes_id, 0 );
      24          12 :     if( FD_UNLIKELY( !acc.lamports ) ) {
      25           0 :       FD_LOG_ERR(( "state is missing slot hashes sysvar" ));
      26           0 :     }
      27          12 :   }
      28        5340 :   if( FD_UNLIKELY( 0!=memcmp( acc.owner, &fd_sysvar_owner_id, sizeof(fd_pubkey_t) ) ) ) {
      29           0 :     FD_LOG_ERR(( "slot hashes sysvar not owned by sysvar owner" ));
      30           0 :   }
      31        5340 :   uchar * data    = acc.data;
      32        5340 :   ulong   data_sz = acc.data_len;
      33        5340 :   if( FD_UNLIKELY( data_sz < FD_SYSVAR_SLOT_HASHES_BINCODE_SZ ) ) {
      34           0 :     FD_LOG_HEXDUMP_ERR(( "invalid slot hashes sysvar", data, data_sz ));
      35           0 :   }
      36             : 
      37        5340 :   ulong cnt = FD_LOAD( ulong, data );
      38        5340 :   if( FD_UNLIKELY( cnt > FD_SYSVAR_SLOT_HASHES_CAP ) ) {
      39           0 :     FD_LOG_HEXDUMP_ERR(( "corrupt slot hashes sysvar", data, data_sz ));
      40           0 :   }
      41             : 
      42             :   /* Search for existing entry with parent_slot */
      43        5340 :   fd_slot_hash_t * entries = (fd_slot_hash_t *)(data + sizeof(ulong));
      44        5340 :   int found = 0;
      45      400431 :   for( ulong i=0UL; i<cnt; i++ ) {
      46      395094 :     if( entries[i].slot == bank->f.parent_slot ) {
      47           3 :       fd_memcpy( &entries[i].hash, &bank->f.bank_hash, sizeof(fd_hash_t) );
      48           3 :       found = 1;
      49           3 :       break;
      50           3 :     }
      51      395094 :   }
      52             : 
      53        5340 :   if( !found ) {
      54        5337 :     ulong keep = fd_ulong_min( cnt, FD_SYSVAR_SLOT_HASHES_CAP - 1UL );
      55        5337 :     memmove( &entries[1], &entries[0], keep * sizeof(fd_slot_hash_t) );
      56        5337 :     entries[0].slot = bank->f.parent_slot;
      57        5337 :     fd_memcpy( &entries[0].hash, &bank->f.bank_hash, sizeof(fd_hash_t) );
      58        5337 :     FD_STORE( ulong, data, keep + 1UL );
      59        5337 :   }
      60             : 
      61        5340 :   fd_accdb_svm_close_rw( bank, accdb, capture_ctx, &acc, update );
      62        5340 : }
      63             : 
      64             : int
      65             : fd_sysvar_slot_hashes_validate( uchar const * data,
      66        7569 :                                 ulong         sz ) {
      67        7569 :   if( FD_UNLIKELY( sz < sizeof(ulong) ) ) return 0;
      68        7563 :   ulong cnt = FD_LOAD( ulong, data );
      69        7563 :   if( FD_UNLIKELY( cnt > FD_SYSVAR_SLOT_HASHES_CAP ) ) return 0;
      70        7560 :   if( FD_UNLIKELY( sz < sizeof(ulong) + cnt*sizeof(fd_slot_hash_t) ) ) return 0;
      71        7554 :   return 1;
      72        7560 : }
      73             : 
      74             : fd_slot_hashes_t *
      75             : fd_sysvar_slot_hashes_view( fd_slot_hashes_t * view,
      76             :                             uchar const *      data,
      77         153 :                             ulong              sz ) {
      78         153 :   if( FD_UNLIKELY( !fd_sysvar_slot_hashes_validate( data, sz ) ) ) return NULL;
      79         150 :   ulong cnt   = FD_LOAD( ulong, data );
      80         150 :   view->elems = (fd_slot_hash_t const *)( data + sizeof(ulong) );
      81         150 :   view->cnt   = cnt;
      82         150 :   return view;
      83         153 : }

Generated by: LCOV version 1.14