Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_fd_runtime_const_h 2 : #define HEADER_fd_src_flamenco_runtime_fd_runtime_const_h 3 : 4 : #include "../leaders/fd_leaders.h" 5 : #include "../types/fd_types.h" 6 : #include "../../ballet/txn/fd_txn.h" /* for fd_acct_addr_t */ 7 : #include "../vm/fd_vm_base.h" /* fd_vm_trace_t */ 8 : 9 : FD_PROTOTYPES_BEGIN 10 : 11 : /* All of the variable bounds in the bank should be deteremined by the 12 : max number of vote accounts and stake accounts that the system 13 : supports. These are not protocol-level bounds, but rather bounds 14 : that are used to determine the max amount of memory that various 15 : data structures require. */ 16 : 17 0 : #define FD_RUNTIME_MAX_VOTE_ACCOUNTS (40200UL) /* ~40k vote accounts */ 18 : 19 26448 : #define FD_RUNTIME_MAX_STAKE_ACCOUNTS (3000000UL) /* 3M stake accounts */ 20 : 21 : #define FD_RUNTIME_SLOTS_PER_EPOCH (432000UL) /* 432k slots per epoch */ 22 : 23 : /* Maximum amount of writable accounts per transaction 24 : https://github.com/anza-xyz/agave/blob/v3.0.8/runtime/src/bank.rs#L2946 */ 25 93 : #define FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_TRANSACTION (64UL) 26 : 27 : /* The initial block id hash is a dummy value for the initial block id 28 : as one is not provided in snapshots. This does not have an 29 : equivalent in Agave. 30 : 31 : TODO: This should be removed in favor of repairing the last shred of 32 : the snapshot slot to get the actual block id of the snapshot slot. */ 33 : 34 0 : #define FD_RUNTIME_INITIAL_BLOCK_ID (0xF17EDA2CE7B1DUL) 35 : 36 : /* The stake program is now a BPF program which means that there is a 37 : variable cost in CUs to execute the stake program. This is the 38 : absolute minimum cost of executing the stake program. 39 : 40 : FIXME: This is a reasonable estimate based off of BPF withdraw 41 : instructions. The hard bound still needs to be determined. */ 42 : 43 15 : #define FD_RUNTIME_MIN_STAKE_INSN_CUS (6000UL) 44 : 45 : /* FD_RUNTIME_ACC_SZ_MAX is the protocol level hardcoded size limit of a 46 : Solana account. */ 47 : 48 0 : #define FD_RUNTIME_ACC_SZ_MAX (10UL<<20) /* 10MiB */ 49 : 50 : /* FD_RUNTIME_WRITABLE_ACCOUNTS_MAX is the protocol level hardcoded 51 : limit of writable accounts per transaction. */ 52 : 53 : #define FD_RUNTIME_WRITABLE_ACCOUNTS_MAX (64UL) 54 : 55 : /* Genesis creation times for major Solana clusters */ 56 : 57 0 : #define FD_RUNTIME_GENESIS_CREATION_TIME_MAINNET (1584368940UL) 58 0 : #define FD_RUNTIME_GENESIS_CREATION_TIME_TESTNET (1580834132UL) 59 0 : #define FD_RUNTIME_GENESIS_CREATION_TIME_DEVNET (1597081016UL) 60 : 61 : 62 : /* FeeStructure constants. Bank is always initialized with 63 : `FeeStructure::default()` 64 : https://github.com/anza-xyz/agave/blob/v3.1.0-beta.0/runtime/src/bank.rs#L1859 65 : https://github.com/anza-xyz/solana-sdk/blob/badc2c40071e6e7f7a8e8452b792b66613c5164c/fee-structure/src/lib.rs#L100 */ 66 0 : #define FD_RUNTIME_FEE_STRUCTURE_LAMPORTS_PER_SIGNATURE (5000UL) 67 : 68 : static const fd_cluster_version_t FD_RUNTIME_CLUSTER_VERSION = { 69 : .major = 3UL, 70 : .minor = 0UL, 71 : .patch = 3UL 72 : }; 73 : 74 : /* Various constant values used by the runtime. */ 75 : 76 0 : #define MICRO_LAMPORTS_PER_LAMPORT (1000000UL) 77 : 78 0 : #define DEFAULT_HASHES_PER_TICK (12500) 79 : #define UPDATED_HASHES_PER_TICK2 (17500) 80 : #define UPDATED_HASHES_PER_TICK3 (27500) 81 : #define UPDATED_HASHES_PER_TICK4 (47500) 82 : #define UPDATED_HASHES_PER_TICK5 (57500) 83 : #define UPDATED_HASHES_PER_TICK6 (62500) 84 : 85 0 : #define SECONDS_PER_YEAR ((double)(365.242199 * 24.0 * 60.0 * 60.0)) 86 : 87 : /* https://github.com/anza-xyz/agave/blob/0d34a1a160129c4293dac248e14231e9e773b4ce/program-runtime/src/compute_budget.rs#L139 */ 88 : #define FD_MAX_INSTRUCTION_TRACE_LENGTH (64UL) 89 : /* https://github.com/anza-xyz/agave/blob/f70ab5598ccd86b216c3928e4397bf4a5b58d723/compute-budget/src/compute_budget.rs#L13 */ 90 0 : #define FD_MAX_INSTRUCTION_STACK_DEPTH (5UL) 91 : 92 : 93 0 : #define FD_RUNTIME_VM_TRACE_EVENT_MAX (128UL<<20) 94 0 : #define FD_RUNTIME_VM_TRACE_EVENT_DATA_MAX (2048UL) 95 : 96 0 : #define FD_RUNTIME_VM_TRACE_STATIC_FOOTPRINT (FD_RUNTIME_VM_TRACE_EVENT_MAX + sizeof(fd_vm_trace_t)) 97 0 : #define FD_RUNTIME_VM_TRACE_STATIC_ALIGN (8UL) 98 : 99 : /* Maximum CPI instruction data size. 10 KiB was chosen to ensure that 100 : CPI instructions are not more limited than transaction instructions 101 : if the size of transactions is doubled in the future. 102 : https://github.com/anza-xyz/agave/blob/v3.1.1/transaction-context/src/lib.rs#L33 */ 103 : #define FD_RUNTIME_CPI_MAX_INSTR_DATA_LEN (10240UL) 104 : 105 : /* The bpf loader's serialization footprint is bounded in the worst case 106 : by 64 unique writable accounts which are each 10MiB in size (bounded 107 : by the amount of transaction accounts). We can also have up to 108 : FD_INSTR_ACCT_MAX (256) referenced accounts in an instruction. 109 : 110 : - 8 bytes for the account count 111 : For each account: 112 : If duplicated: 113 : - 8 bytes for each duplicated account 114 : If not duplicated: 115 : - header for each unique account (96 bytes) 116 : - 1 account idx byte 117 : - 1 is_signer byte 118 : - 1 is_writable byte 119 : - 1 executable byte 120 : - 4 bytes for the original data length 121 : - 32 bytes for the key 122 : - 32 bytes for the owner 123 : - 8 bytes for the lamports 124 : - 8 bytes for the data length 125 : - 8 bytes for the rent epoch 126 : - 10MiB for the data (10485760 bytes) 127 : - 10240 bytes for resizing the data 128 : - 0 padding bytes because this is already 8 byte aligned 129 : - 8 bytes for instruction data length 130 : - 1232 bytes for the instruction data (TXN_MTU) 131 : - 32 bytes for the program id 132 : 133 : So the total footprint is: 134 : 8 header bytes + 135 : 192 duplicate accounts (256 instr accounts - 64 unique accounts) * 8 bytes = 1536 duplicate account bytes + 136 : 64 unique accounts * (96 header bytes + 10485760 bytes + 10240 resizing bytes) = 671750144 unique account bytes + 137 : 8 + 1232 + 32 = 1272 bytes trailer bytes + program id = 671751416 bytes 138 : Total footprint: 671752960 bytes 139 : 140 : This is a reasonably tight-ish upper bound on the input region 141 : footprint for a single instruction at a single stack depth. In 142 : reality the footprint would be slightly smaller because the 143 : instruction data can't be equal to the transaction MTU. 144 : */ 145 0 : #define MAX_PERMITTED_DATA_INCREASE (10240UL) // 10KB 146 0 : #define FD_BPF_ALIGN_OF_U128 (8UL) 147 0 : #define FD_ACCOUNT_REC_ALIGN (8UL) 148 : /* https://github.com/anza-xyz/sbpf/blob/v0.12.2/src/ebpf.rs#L37-L38 */ 149 : #define FD_RUNTIME_EBPF_HOST_ALIGN (16UL) 150 0 : #define FD_INSTR_ACCT_MAX (256) 151 : 152 : 153 : #define FD_BPF_LOADER_UNIQUE_ACCOUNT_FOOTPRINT(direct_mapping) \ 154 : (1UL /* dup byte */ + \ 155 : sizeof(uchar) /* is_signer */ + \ 156 : sizeof(uchar) /* is_writable */ + \ 157 : sizeof(uchar) /* executable */ + \ 158 : sizeof(uint) /* original_data_len */ + \ 159 : sizeof(fd_pubkey_t) /* key */ + \ 160 : sizeof(fd_pubkey_t) /* owner */ + \ 161 : sizeof(ulong) /* lamports */ + \ 162 : sizeof(ulong) /* data len */ + \ 163 : (direct_mapping ? FD_BPF_ALIGN_OF_U128 : FD_ULONG_ALIGN_UP( FD_RUNTIME_ACC_SZ_MAX, FD_BPF_ALIGN_OF_U128 )) + \ 164 : MAX_PERMITTED_DATA_INCREASE + \ 165 : sizeof(ulong)) /* rent_epoch */ 166 : #define FD_BPF_LOADER_DUPLICATE_ACCOUNT_FOOTPRINT (8UL) /* 1 dup byte + 7 bytes for padding */ 167 : 168 : #define FD_BPF_LOADER_INPUT_REGION_FOOTPRINT(account_lock_limit, direct_mapping) \ 169 : (FD_ULONG_ALIGN_UP( (sizeof(ulong) /* acct_cnt */ + \ 170 : account_lock_limit*FD_BPF_LOADER_UNIQUE_ACCOUNT_FOOTPRINT(direct_mapping) + \ 171 : (FD_INSTR_ACCT_MAX-account_lock_limit)*FD_BPF_LOADER_DUPLICATE_ACCOUNT_FOOTPRINT + \ 172 : sizeof(ulong) /* instr data len */ + \ 173 : FD_TXN_MTU /* No instr data */ + \ 174 : sizeof(fd_pubkey_t)), /* program id */ \ 175 : FD_RUNTIME_EBPF_HOST_ALIGN )) 176 : 177 : 178 : 179 : #define BPF_LOADER_SERIALIZATION_FOOTPRINT (671752960UL) 180 : FD_STATIC_ASSERT( BPF_LOADER_SERIALIZATION_FOOTPRINT==FD_BPF_LOADER_INPUT_REGION_FOOTPRINT(64UL, 0), bpf_loader_serialization_footprint ); 181 : 182 : 183 : /* Some vote instruction types are dynamically sized: 184 : - tower_sync_switch (contains deque of fd_vote_lockout_t) 185 : - tower_sync (contains deque of fd_vote_lockout_t) 186 : - compact_vote_state_update_switch (vector of fd_lockout_offset_t) 187 : - compact_vote_state_update (vector of fd_lockout_offset_t) 188 : - authorize_checked_with_seed (char vector of current_authority_derived_key_seed) 189 : - authorize_with_seed (char vector of current_authority_derived_key_seed) 190 : - update_vote_state_switch (contains deque of fd_vote_lockout_t) 191 : - update_vote_state (contains deque of fd_vote_lockout_t) 192 : - vote_switch (deque of slot numbers) 193 : - vote (deque of slot numbers) 194 : All other vote instruction types are statically sized. 195 : 196 : A loose bound on the max amount of encoded fd_vote_lockout_t 197 : possible is 1232 bytes/(12 bytes/per lockout) = 102 lockouts. So 198 : the worst case bound for the deque of fd_vote_lockout is 199 : 32 + (102 * sizeof(fd_vote_lockout_t)) = 1644 bytes. 200 : 201 : The worst case vector of fd_lockout_offset_t is one where each 202 : encoded element is 2 bytes. This means that we can have 1232/2 = 203 : 616 elements. They are represented as being 16 bytes each, so the 204 : total footprint would be 9856 bytes. 205 : 206 : The deque of slot numbers is a vector of ulong, which is 8 bytes. 207 : So the worst case is 1232 bytes/8 bytes = 154 elements. So, the 208 : total footprint is 32 + (154 * 8 bytes) = 1264 bytes. 209 : 210 : The worst case char vector is 1232 bytes as each element is 1 byte 211 : up to the txn MTU. 212 : 213 : With this, that means that the compact_vote_state_update_switch 214 : can have the largest worst case footprint where the struct is 215 : 104 bytes (sizeof(fd_compact_vote_state_update_switch_t) + the 216 : worst case lockout vector of 616 elements. */ 217 : #define FD_LOCKOUT_OFFSET_FOOTPRINT (9856UL) 218 : #define FD_VOTE_INSTRUCTION_FOOTPRINT (sizeof(fd_vote_instruction_t) + FD_LOCKOUT_OFFSET_FOOTPRINT) 219 : 220 : /* TODO: This is the value as generated by fd_types bincode decoding of 221 : fd_vote_state_versioned_t. This should eventually be replaced. */ 222 : #define FD_VOTE_STATE_VERSIONED_FOOTPRINT (9248UL) 223 : 224 : /* The footprint of a fd_vote_authorized_voters_t struct is defined as a 225 : fd_vote_authorized_voters_t followed by a pool and then a treap. */ 226 : #define FD_AUTHORIZED_VOTERS_ALIGN (128UL) 227 : #define FD_AUTHORIZED_VOTERS_FOOTPRINT (4888UL) 228 : 229 : /* TODO: These footprints are currently overprovisioned due to test 230 : fixtures which currently violate protocol invariants. */ 231 : 232 : /* The footprint of the landed votes is determined by a deque with max 233 : cnt of 31. The footprint is as follows: 234 : alignof(DEQUE_T) == alignof(fd_landed_vote_t) == 8 235 : sizeof(DEQUE_T) == sizeof(fd_landed_vote_t) == 24 236 : return fd_ulong_align_up( fd_ulong_align_up( 32UL, alignof(DEQUE_T) ) + sizeof(DEQUE_T)*max, alignof(DEQUE_(private_t)) ); 237 : return fd_ulong_align_up( fd_ulong_align_up( 32UL, 8UL ) ) + 24UL*31UL, 8UL ); 238 : return fd_ulong_align_up( 32UL + 744, 8UL ) == 776 */ 239 : #define FD_LANDED_VOTES_ALIGN (32UL) 240 : #define FD_LANDED_VOTES_FOOTPRINT (FD_VOTE_STATE_VERSIONED_FOOTPRINT) 241 : 242 : /* The calculation for the landed votes footprint is the same as the 243 : calculation for the landed votes but the sizeof(fd_vote_lockout_t) 244 : is 16 bytes: 245 : return fd_ulong_align_up( 32UL + 16UL * 31UL, 8UL ) == 528UL */ 246 : #define FD_VOTE_LOCKOUTS_ALIGN (32UL) 247 : #define FD_VOTE_LOCKOUTS_FOOTPRINT (FD_VOTE_STATE_VERSIONED_FOOTPRINT) 248 : 249 : FD_PROTOTYPES_END 250 : 251 : #endif /* HEADER_fd_src_flamenco_runtime_fd_runtime_const_h */