LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_clock.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 30 50 60.0 %
Date: 2026-11-11 12:40:43 Functions: 3 5 60.0 %

          Line data    Source code
       1             : #include "fd_sysvar_clock.h"
       2             : #include "fd_sysvar_epoch_schedule.h"
       3             : #include "../fd_system_ids.h"
       4             : #include "../sysvar/fd_sysvar.h"
       5             : 
       6             : /* Do all intermediate calculations at nanosecond precision, to mirror
       7             :    Solana's behavior. */
       8           0 : #define NS_IN_S ((long)1e9)
       9             : 
      10             : /* https://github.com/anza-xyz/agave/blob/v2.3.7/runtime/src/bank.rs#L2110-L2117 */
      11             : static inline long
      12           0 : unix_timestamp_from_genesis( fd_bank_t * bank ) {
      13             :   /* TODO: genesis_creation_time needs to be a long in the bank. */
      14           0 :   return fd_long_sat_add(
      15           0 :       (long)bank->f.genesis_creation_time,
      16           0 :       (long)( fd_uint128_sat_mul( bank->f.slot, bank->f.slot_params.ns_per_slot ) / NS_IN_S ) );
      17           0 : }
      18             : 
      19             : static void
      20             : fd_sysvar_clock_write( fd_bank_t *                   bank,
      21             :                        fd_accdb_t *                  accdb,
      22             :                        fd_capture_ctx_t *            capture_ctx,
      23         610 :                        fd_sol_sysvar_clock_t const * clock ) {
      24         610 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_clock_id, clock, sizeof(fd_sol_sysvar_clock_t) );
      25         610 : }
      26             : 
      27             : fd_sol_sysvar_clock_t *
      28             : fd_sysvar_clock_read( fd_accdb_t *            accdb,
      29             :                       fd_accdb_fork_id_t      fork_id,
      30         611 :                       fd_sol_sysvar_clock_t * clock ) {
      31         611 :   fd_acc_t acc = fd_accdb_read_one( accdb, fork_id, fd_sysvar_clock_id.uc );
      32         611 :   if( FD_UNLIKELY( !acc.lamports || acc.data_len<sizeof(fd_sol_sysvar_clock_t) ) ) {
      33           0 :     fd_accdb_unread_one( accdb, &acc );
      34           0 :     return NULL;
      35           0 :   }
      36             : 
      37         611 :   fd_memcpy( clock, acc.data, sizeof(fd_sol_sysvar_clock_t) );
      38         611 :   fd_accdb_unread_one( accdb, &acc );
      39         611 :   return clock;
      40         611 : }
      41             : 
      42             : void
      43             : fd_sysvar_clock_init( fd_bank_t *        bank,
      44             :                       fd_accdb_t *       accdb,
      45           0 :                       fd_capture_ctx_t * capture_ctx ) {
      46           0 :   long timestamp = unix_timestamp_from_genesis( bank );
      47             : 
      48           0 :   fd_sol_sysvar_clock_t clock = {
      49           0 :     .slot                  = bank->f.slot,
      50           0 :     .epoch                 = 0,
      51           0 :     .epoch_start_timestamp = timestamp,
      52           0 :     .leader_schedule_epoch = 1,
      53           0 :     .unix_timestamp        = timestamp,
      54           0 :   };
      55           0 :   fd_sysvar_clock_write( bank, accdb, capture_ctx, &clock );
      56           0 : }
      57             : 
      58             : void
      59             : fd_sysvar_clock_update_slot( fd_bank_t *        bank,
      60             :                              fd_accdb_t *       accdb,
      61         611 :                              fd_capture_ctx_t * capture_ctx ) {
      62         611 :   fd_sol_sysvar_clock_t clock_[1];
      63         611 :   fd_sol_sysvar_clock_t * clock = fd_sysvar_clock_read( accdb, bank->accdb_fork_id, clock_ );
      64         611 :   if( FD_UNLIKELY( !clock ) ) FD_LOG_ERR(( "fd_sysvar_clock_read failed" ));
      65             : 
      66         611 :   fd_epoch_schedule_t const * epoch_schedule = &bank->f.epoch_schedule;
      67         611 :   ulong current_epoch = fd_slot_to_epoch( epoch_schedule, bank->f.slot,        NULL );
      68         611 :   ulong parent_epoch  = fd_slot_to_epoch( epoch_schedule, bank->f.parent_slot, NULL );
      69             : 
      70         611 :   long epoch_start_timestamp;
      71         611 :   if(      FD_UNLIKELY( !bank->f.slot               ) ) epoch_start_timestamp = unix_timestamp_from_genesis( bank );
      72         611 :   else if( FD_UNLIKELY( parent_epoch!=current_epoch ) ) epoch_start_timestamp = clock->unix_timestamp;
      73         583 :   else                                                  epoch_start_timestamp = clock->epoch_start_timestamp;
      74             : 
      75         611 :   *clock = (fd_sol_sysvar_clock_t){
      76         611 :     .slot                  = bank->f.slot,
      77         611 :     .epoch_start_timestamp = epoch_start_timestamp,
      78         611 :     .epoch                 = current_epoch,
      79         611 :     .leader_schedule_epoch = fd_slot_to_leader_schedule_epoch( epoch_schedule, bank->f.slot ),
      80         611 :     .unix_timestamp        = clock->unix_timestamp, /* parent's footer timestamp */
      81         611 :   };
      82         611 :   fd_sysvar_clock_write( bank, accdb, capture_ctx, clock );
      83         611 : }

Generated by: LCOV version 1.14