LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_slot_history.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 103 0.0 %
Date: 2025-01-08 12:08:44 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #include "fd_sysvar_slot_history.h"
       2             : #include "fd_sysvar.h"
       3             : #include "fd_sysvar_rent.h"
       4             : #include "../fd_executor_err.h"
       5             : #include "../fd_system_ids.h"
       6             : #include "../context/fd_exec_epoch_ctx.h"
       7             : 
       8             : /* FIXME These constants should be header defines */
       9             : 
      10             : static const ulong slot_history_min_account_size = 131097;
      11             : 
      12             : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_history.rs#L37 */
      13             : static const ulong slot_history_max_entries = 1024 * 1024;
      14             : 
      15             : /* TODO: move into seperate bitvec library */
      16             : static const ulong bits_per_block = 8 * sizeof(ulong);
      17             : 
      18             : void
      19             : fd_sysvar_slot_history_set( fd_slot_history_t * history,
      20           0 :                             ulong               i ) {
      21           0 :   if( FD_UNLIKELY( i > history->next_slot && i - history->next_slot >= slot_history_max_entries ) ) {
      22           0 :     FD_LOG_WARNING(( "Ignoring out of bounds (i=%lu next_slot=%lu)", i, history->next_slot ));
      23           0 :     return;
      24           0 :   }
      25             : 
      26             :   // Skipped slots, delete them from history
      27           0 :   for( ulong j = history->next_slot; j < i; j++ ) {
      28           0 :     ulong block_idx = (j / bits_per_block) % (history->bits.bits->blocks_len);
      29           0 :     history->bits.bits->blocks[ block_idx ] &= ~( 1UL << ( j % bits_per_block ) );
      30           0 :   }
      31           0 :   ulong block_idx = (i / bits_per_block) % (history->bits.bits->blocks_len);
      32           0 :   history->bits.bits->blocks[ block_idx ] |= ( 1UL << ( i % bits_per_block ) );
      33           0 : }
      34             : 
      35             : static const ulong blocks_len = slot_history_max_entries / bits_per_block;
      36             : 
      37             : int fd_sysvar_slot_history_write_history( fd_exec_slot_ctx_t * slot_ctx,
      38           0 :                                           fd_slot_history_t * history ) {
      39           0 :   ulong sz = fd_slot_history_size( history );
      40           0 :   if (sz < slot_history_min_account_size)
      41           0 :     sz = slot_history_min_account_size;
      42           0 :   uchar enc[ sz ];
      43           0 :   fd_memset( enc, 0, sz );
      44           0 :   fd_bincode_encode_ctx_t ctx;
      45           0 :   ctx.data = enc;
      46           0 :   ctx.dataend = enc + sz;
      47           0 :   int err = fd_slot_history_encode( history, &ctx );
      48           0 :   if (0 != err)
      49           0 :     return err;
      50           0 :   return fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_slot_history_id, enc, sz, slot_ctx->slot_bank.slot );
      51           0 : }
      52             : 
      53             : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_history.rs#L16 */
      54             : void
      55           0 : fd_sysvar_slot_history_init( fd_exec_slot_ctx_t * slot_ctx ) {
      56             :   /* Create a new slot history instance */
      57           0 :   fd_slot_history_t history = {0};
      58           0 :   fd_slot_history_inner_t * inner = fd_valloc_malloc( slot_ctx->valloc, 8UL, sizeof(fd_slot_history_inner_t) );
      59           0 :   inner->blocks = fd_valloc_malloc( slot_ctx->valloc, 8UL, sizeof(ulong) * blocks_len );
      60           0 :   memset( inner->blocks, 0, sizeof(ulong) * blocks_len );
      61           0 :   inner->blocks_len = blocks_len;
      62           0 :   history.bits.bits = inner;
      63           0 :   history.bits.len = slot_history_max_entries;
      64             : 
      65             :   /* TODO: handle slot != 0 init case */
      66           0 :   fd_sysvar_slot_history_set( &history, slot_ctx->slot_bank.slot );
      67           0 :   history.next_slot = slot_ctx->slot_bank.slot + 1;
      68             : 
      69           0 :   fd_sysvar_slot_history_write_history( slot_ctx, &history );
      70           0 :   fd_bincode_destroy_ctx_t ctx = { .valloc = slot_ctx->valloc };
      71           0 :   fd_slot_history_destroy( &history, &ctx );
      72           0 : }
      73             : 
      74             : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/runtime/src/bank.rs#L2345 */
      75             : int
      76           0 : fd_sysvar_slot_history_update( fd_exec_slot_ctx_t * slot_ctx ) {
      77             :   /* Set current_slot, and update next_slot */
      78             : 
      79           0 :   fd_pubkey_t const * key = &fd_sysvar_slot_history_id;
      80             : 
      81           0 :   FD_BORROWED_ACCOUNT_DECL(rec);
      82           0 :   int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, key, rec);
      83           0 :   if (err)
      84           0 :     FD_LOG_CRIT(( "fd_acc_mgr_view(slot_history) failed: %d", err ));
      85             : 
      86           0 :   fd_bincode_decode_ctx_t ctx;
      87           0 :   ctx.data    = rec->const_data;
      88           0 :   ctx.dataend = rec->const_data + rec->const_meta->dlen;
      89           0 :   ctx.valloc  = slot_ctx->valloc;
      90           0 :   fd_slot_history_t history[1];
      91           0 :   if( fd_slot_history_decode( history, &ctx ) )
      92           0 :     FD_LOG_ERR(("fd_slot_history_decode failed"));
      93             : 
      94             :   /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_history.rs#L48 */
      95           0 :   fd_sysvar_slot_history_set( history, slot_ctx->slot_bank.slot );
      96           0 :   history->next_slot = slot_ctx->slot_bank.slot + 1;
      97             : 
      98           0 :   ulong sz = fd_slot_history_size( history );
      99           0 :   if( sz < slot_history_min_account_size )
     100           0 :     sz = slot_history_min_account_size;
     101             : 
     102           0 :   err = fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, key, 1, sz, rec );
     103           0 :   if (err)
     104           0 :     FD_LOG_CRIT(( "fd_acc_mgr_modify(slot_history) failed: %d", err ));
     105             : 
     106           0 :   fd_bincode_encode_ctx_t e_ctx = {
     107           0 :     .data    = rec->data,
     108           0 :     .dataend = rec->data+sz
     109           0 :   };
     110           0 :   if( fd_slot_history_encode( history, &e_ctx ) )
     111           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     112             : 
     113           0 :   fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx );
     114           0 :   rec->meta->info.lamports = fd_rent_exempt_minimum_balance( &epoch_bank->rent, sz );
     115             : 
     116           0 :   rec->meta->dlen = sz;
     117           0 :   fd_memcpy( rec->meta->info.owner, fd_sysvar_owner_id.key, sizeof(fd_pubkey_t) );
     118             : 
     119           0 :   fd_bincode_destroy_ctx_t ctx_d = { .valloc = slot_ctx->valloc };
     120           0 :   fd_slot_history_destroy( history, &ctx_d );
     121             : 
     122           0 :   return 0;
     123           0 : }
     124             : 
     125             : int
     126             : fd_sysvar_slot_history_read( fd_exec_slot_ctx_t * slot_ctx,
     127             :                             fd_valloc_t valloc,
     128           0 :                             fd_slot_history_t * out_history) {
     129             :   /* Set current_slot, and update next_slot */
     130             : 
     131           0 :   fd_pubkey_t const * key = &fd_sysvar_slot_history_id;
     132             : 
     133           0 :   FD_BORROWED_ACCOUNT_DECL(rec);
     134           0 :   int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, key, rec);
     135           0 :   if (err)
     136           0 :     FD_LOG_CRIT(( "fd_acc_mgr_view(slot_history) failed: %d", err ));
     137             : 
     138           0 :   fd_bincode_decode_ctx_t ctx;
     139           0 :   ctx.data    = rec->const_data;
     140           0 :   ctx.dataend = rec->const_data + rec->const_meta->dlen;
     141           0 :   ctx.valloc  = valloc;
     142           0 :   if( fd_slot_history_decode( out_history, &ctx ) )
     143           0 :     FD_LOG_ERR(("fd_slot_history_decode failed"));
     144             : 
     145           0 :   return 0;
     146           0 : }
     147             : 
     148             : int
     149             : fd_sysvar_slot_history_find_slot( fd_slot_history_t const * history,
     150           0 :                                   ulong slot ) {
     151           0 :   if( slot > history->next_slot - 1) {
     152           0 :     return FD_SLOT_HISTORY_SLOT_FUTURE;
     153           0 :   } else if ( slot < fd_ulong_sat_sub( history->next_slot, slot_history_max_entries ) ) {
     154           0 :     return FD_SLOT_HISTORY_SLOT_TOO_OLD;
     155           0 :   } else {
     156           0 :     ulong block_idx = (slot / bits_per_block) % (history->bits.bits->blocks_len);
     157           0 :     if( history->bits.bits->blocks[ block_idx ] & ( 1UL << ( slot % bits_per_block ) ) ) {
     158           0 :       return FD_SLOT_HISTORY_SLOT_FOUND;
     159           0 :     } else {
     160           0 :       return FD_SLOT_HISTORY_SLOT_NOTFOUND;
     161           0 :     }
     162           0 :   }
     163           0 : }

Generated by: LCOV version 1.14