Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_sysvar_epoch_schedule_h 2 : #define HEADER_fd_src_flamenco_runtime_sysvar_epoch_schedule_h 3 : 4 : /* fd_sysvar_epoch_schedule provides methods for epoch numbers, a native 5 : concept of the Solana runtime. 6 : 7 : Every Solana slot is assigned an epoch number (ulong), starting with 8 : epoch 0. The epoch number either stays constant or increments by one 9 : between two slots. 10 : 11 : The length of an epoch is the count of consecutive slots that have 12 : the same epoch number. The series of epochs consists of two parts: 13 : The warmup period (which may span zero epochs), and the constant 14 : period (which is infinite). 15 : 16 : In the warmup period, the length of an epoch starts small and 17 : exponentially increases. The length of each epoch in the warmup 18 : period is 2^x where x is (epoch_number - min_exp). min_exp is 19 : ceil(log2(FD_EPOCH_LEN_MIN)). 20 : 21 : In the constant period, the length of each epoch stays the same. 22 : Note that the Solana protocol may introduce a breaking change in the 23 : future that changes the epoch length. The code does not yet account 24 : for that. 25 : 26 : The epoch schedule is used to derive the epoch number of each slot. 27 : It does this by specifying at which slots the epoch number increments 28 : (epoch boundary). 29 : 30 : The epoch schedule sysvar contains epoch scheduling constants used to 31 : make various epoch-related calculations. */ 32 : 33 : #include "../../fd_flamenco_base.h" 34 : #include "../fd_bank.h" 35 : 36 : /* FD_EPOCH_LEN_MIN is a protocol constant specifying the smallest 37 : permitted epoch length. This value is chosen to match 38 : MAX_LOCKOUT_HISTORY, which is the minimum slot count needed to reach 39 : finality in Tower BFT. 40 : 41 : https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/sdk/program/src/epoch_schedule.rs#L21 */ 42 : 43 107223 : #define FD_EPOCH_LEN_MIN (32UL) 44 : 45 : /* FD_EPOCH_LEN_MIN_TRAILING_ZERO stores the number of trailing zeroes of FD_EPOCH_LEN_MIN */ 46 0 : #define FD_EPOCH_LEN_MIN_TRAILING_ZERO (5UL) 47 : 48 : /* FD_EPOCH_LEN_MAX is an implementation-defined epoch size limit. 49 : Technically, there is no epoch length limit (other than the max slot 50 : number ULONG_MAX). We enforce a limit regardless to prevent overflow 51 : in math operations. */ 52 : 53 : #define FD_EPOCH_LEN_MAX (0xFFFFFFFFUL) 54 : 55 : FD_PROTOTYPES_BEGIN 56 : 57 : /* fd_sysvar_epoch_schedule_init initializes the epoch schedule sysvar 58 : account. FIXME document what this actually does. */ 59 : 60 : void 61 : fd_sysvar_epoch_schedule_init( fd_bank_t * bank, 62 : fd_funk_t * funk, 63 : fd_funk_txn_xid_t const * xid, 64 : fd_capture_ctx_t * capture_ctx ); 65 : 66 : /* fd_sysvar_epoch_schedule_read reads the current value of the rent 67 : sysvar from funk. If the account doesn't exist in funk or if the account 68 : has zero lamports, this function returns NULL. */ 69 : 70 : fd_epoch_schedule_t * 71 : fd_sysvar_epoch_schedule_read( fd_funk_t * funk, 72 : fd_funk_txn_xid_t const * xid, 73 : fd_epoch_schedule_t * out ); 74 : 75 : /* fd_sysvar_epoch_schedule_write writes the current value of the epoch 76 : schedule sysvar to funk. */ 77 : 78 : void 79 : fd_sysvar_epoch_schedule_write( fd_bank_t * bank, 80 : fd_funk_t * funk, 81 : fd_funk_txn_xid_t const * xid, 82 : fd_capture_ctx_t * capture_ctx, 83 : fd_epoch_schedule_t const * epoch_schedule ); 84 : 85 : /* fd_epoch_schedule_derive derives an epoch schedule config from the 86 : given parameters. New epoch schedule configurations should only be 87 : created using this function. Returns schedule on success. 88 : On failure, returns NULL and logs reason. 89 : 90 : - schedule points to the epoch schedule struct to be initialized. 91 : - epoch_len configures the target slot count per epoch (>0) 92 : - leader_schedule_slot_offset configures when to generate the leader 93 : schedule for an epoch, measured in number of slots before the start 94 : of that epoch. 95 : - warmup controls whether to set a warmup period (0 if disabled, 96 : 1 if enabled). */ 97 : 98 : fd_epoch_schedule_t * 99 : fd_epoch_schedule_derive( fd_epoch_schedule_t * schedule, 100 : ulong epoch_len, 101 : ulong leader_schedule_slot_offset, 102 : int warmup ); 103 : 104 : /* fd_epoch_slot_cnt returns the number of slots in an epoch given an 105 : epoch schedule config and an epoch number. Return value > 0 */ 106 : 107 : FD_FN_PURE ulong 108 : fd_epoch_slot_cnt( fd_epoch_schedule_t const * schedule, 109 : ulong epoch ); 110 : 111 : /* fd_epoch_slot0 returns the absolute slot number of the first slot 112 : in an epoch. */ 113 : 114 : FD_FN_PURE ulong 115 : fd_epoch_slot0( fd_epoch_schedule_t const * schedule, 116 : ulong epoch ); 117 : 118 : /* fd_slot_to_epoch returns the epoch number of the epoch containing 119 : the given slot number. If out_offset_opt != NULL, on return 120 : *out_offset_opt contains the number of slots that precede the given 121 : slot in the same epoch. U.B. if schedule->slots_per_epoch is zero. */ 122 : 123 : ulong 124 : fd_slot_to_epoch( fd_epoch_schedule_t const * schedule, 125 : ulong slot, 126 : ulong * out_offset_opt ); 127 : 128 : ulong 129 : fd_slot_to_leader_schedule_epoch( fd_epoch_schedule_t const * schedule, 130 : ulong slot ); 131 : 132 : FD_PROTOTYPES_END 133 : 134 : #endif /* HEADER_fd_src_flamenco_runtime_sysvar_epoch_schedule_h */