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 "../../ballet/txn/fd_txn.h" /* for FD_TXN_ACCT_ADDR_MAX */ 5 : #include "../vm/fd_vm_base.h" /* fd_vm_trace_t */ 6 : 7 : FD_PROTOTYPES_BEGIN 8 : 9 : /* FD_INSTR_SIGNERS_MAX: The (inclusive) maximum number of distinct 10 : signers a single instruction can have. 11 : 12 : This is the runtime bound, which is larger than the transaction 13 : parser bound because during CPI calls PDAs can be promoted to 14 : signers. Therefore in the runtime, the effective limit is the 15 : amount of distinct accounts the transaction can access. */ 16 : #define FD_INSTR_SIGNERS_MAX FD_TXN_ACCT_ADDR_MAX 17 : 18 : /* FD_RUNTIME_MAX_STAKE_ACCOUNTS bounds cached per-stake reward-calculation 19 : results in the runtime stack. Stake-delegation cache capacity is 20 : configured separately. */ 21 : 22 0 : #define FD_RUNTIME_MAX_STAKE_ACCOUNTS (2150000UL) 23 : 24 : /* FD_RUNTIME_MAX_STAKE_DELEGATION_DISK_RECORDS is the maximum number 25 : of records in each stake-delegation disk tier. */ 26 : 27 : #define FD_RUNTIME_MAX_STAKE_DELEGATION_DISK_RECORDS (100000000UL) 28 : 29 : /* The runtime only supports post-validator_admission_ticket banks. The 30 : accumulator can still see one distinct voter per stake account before 31 : the final eligible set is reduced to the VAT limit below. */ 32 : 33 0 : #define FD_RUNTIME_MAX_STAKED_VOTE_ACCOUNTS (FD_RUNTIME_MAX_STAKE_ACCOUNTS) 34 : 35 : /* Maximum number of vote accounts eligible to receive rewards or 36 : meaningfully contribute to consensus after 37 : validator_admission_ticket activation. */ 38 : 39 141691 : #define FD_RUNTIME_MAX_VAT_VOTE_ACCOUNTS (2000UL) 40 : 41 : /* The maximum number of epoch stakes that are needed to be parsed out 42 : from the manifest. Agave produced snapshots include 5 epoch stakes 43 : (MAX_LEADER_SCHEDULE_STAKES), E-3..E+1 for a snapshot in epoch E, and 44 : a block footer may carry a finalization cert from any of E-3..E, so 45 : all 5 are loaded. */ 46 : 47 0 : #define FD_RUNTIME_MANIFEST_EPOCH_STAKES_LEN (5UL) 48 : 49 0 : #define FD_RUNTIME_SLOTS_PER_EPOCH (432000UL) 50 : 51 : /* FD_RUNTIME_ACC_SZ_MAX is the protocol level hardcoded size limit of a 52 : Solana account. */ 53 : 54 317799 : #define FD_RUNTIME_ACC_SZ_MAX (10UL<<20) /* 10MiB */ 55 : 56 : /* Bound the number of distinct writable accounts that can enter the 57 : cost tracker in a 200ms block with raise_block_limits_to_100m, a 50M 58 : CU block (FD_SLOT_PARAMS_200MS_MAX_BLOCK_UNITS*100/60). Clusters 59 : with a larger block cost limit (slower slots or [development.bench]) 60 : are not supported. A transaction with w writable accounts costs at 61 : least 720+300*w CUs and carries at most 64 writable accounts. Thus W 62 : writables need at least ceil(W/64) transactions: 63 : 64 : 300*W + 720*ceil(W/64) <= 50000000 65 : 66 : The largest solution is 160640: 2510 full 64-account transactions 67 : cost 49999200 CUs. A 160641st writable would cost 50000220 CUs. */ 68 : 69 0 : #define FD_RUNTIME_MAX_TXN_ACC_WRITES_PER_SLOT (160640UL) 70 : 71 : /* With 100M stake accounts, ceil(100M/4096)=24415 partitions. 72 : Assuming uniform hashing, one partition has 73 : X~Binomial(100M,1/24415), with mean 4095.84. So, 74 : P(any partition has X>8192) <= 24415*P(X>=8193) ~= 5.75e-686. */ 75 : 76 0 : #define FD_RUNTIME_MAX_EPOCH_REWARD_ACC_WRITES_PER_SLOT (8192UL) 77 : 78 : /* FD_RUNTIME_MAX_ACC_WRITES_PER_SLOT defines a reasonable upper bound 79 : on the number of unique accounts that can be written to in a single 80 : slot. The worst case can be defined by: 81 : 1. Worst case number of writable accounts in a slot from worst-case 82 : transactions. This bound comes from the cost tracker: 160640. 83 : 2. During partitioned epoch rewards. A reasonable upper bound is 84 : 8192 accounts per stake partition since the odds of this happening 85 : are very very low. 86 : 3. All of the other account updates that can happen in a slot. In 87 : the standard case this would be the sysvars, the incinerator, 88 : and the fee collector (7 accounts.) 89 : - Clock 90 : - SlotHashes 91 : - RecentBlockhashes 92 : - SlotHistory 93 : - Epoch Rewards 94 : - Fee Collector 95 : - Incinerator 96 : - Alpenclock (Alpenglow) 97 : - Leader Vote Account (Alpenglow) 98 : 4. Alpenglow rewards can touch the full VAT vote set up to 2 times. 99 : This happens in the case near the epoch boundary where the reward 100 : cert and the finalization cert are in two different epochs. */ 101 0 : #define FD_RUNTIME_MAX_ACC_WRITES_PER_SLOT (FD_RUNTIME_MAX_TXN_ACC_WRITES_PER_SLOT + \ 102 0 : FD_RUNTIME_MAX_EPOCH_REWARD_ACC_WRITES_PER_SLOT + \ 103 0 : 9UL + \ 104 0 : (2UL * FD_RUNTIME_MAX_VAT_VOTE_ACCOUNTS)) 105 : 106 : /* FD_RUNTIME_ACC_DATA_GROWTH_MAX_PER_TXN is the protocol level hardcoded 107 : limit on the total account data growth (sum of resize deltas) across a 108 : single transaction. Defined here (alongside FD_RUNTIME_ACC_SZ_MAX) so 109 : low-level size bounds can reference it; fd_borrowed_account.h's 110 : MAX_PERMITTED_ACCOUNT_DATA_ALLOCS_PER_TXN and fd_vm_private.h's 111 : FD_MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION are kept equal to this via 112 : static asserts in those headers. */ 113 : 114 : #define FD_RUNTIME_ACC_DATA_GROWTH_MAX_PER_TXN (2UL*FD_RUNTIME_ACC_SZ_MAX) /* 20MiB */ 115 : 116 : /* FD_RUNTIME_WRITABLE_ACCOUNTS_MAX is the protocol level hardcoded 117 : limit of writable accounts per transaction. */ 118 : 119 : #define FD_RUNTIME_WRITABLE_ACCOUNTS_MAX (64UL) 120 : 121 : /* Genesis creation times for major Solana clusters */ 122 : 123 0 : #define FD_RUNTIME_GENESIS_CREATION_TIME_MAINNET (1584368940UL) 124 0 : #define FD_RUNTIME_GENESIS_CREATION_TIME_TESTNET (1580834132UL) 125 0 : #define FD_RUNTIME_GENESIS_CREATION_TIME_DEVNET (1597081016UL) 126 : 127 : /* FeeStructure constants. Bank is always initialized with 128 : `FeeStructure::default()` 129 : https://github.com/anza-xyz/agave/blob/v3.1.0-beta.0/runtime/src/bank.rs#L1859 130 : https://github.com/anza-xyz/solana-sdk/blob/badc2c40071e6e7f7a8e8452b792b66613c5164c/fee-structure/src/lib.rs#L100 */ 131 8069 : #define FD_RUNTIME_FEE_STRUCTURE_LAMPORTS_PER_SIGNATURE (5000UL) 132 : 133 : /* Various constant values used by the runtime. */ 134 : 135 16144 : #define MICRO_LAMPORTS_PER_LAMPORT (1000000UL) 136 : 137 8333 : #define SECONDS_PER_YEAR ((double)(365.242199 * 24.0 * 60.0 * 60.0)) 138 : 139 : /* https://github.com/anza-xyz/agave/blob/0d34a1a160129c4293dac248e14231e9e773b4ce/program-runtime/src/compute_budget.rs#L139 */ 140 : #define FD_MAX_INSTRUCTION_TRACE_LENGTH (64UL) 141 : /* https://github.com/anza-xyz/agave/blob/f70ab5598ccd86b216c3928e4397bf4a5b58d723/compute-budget/src/compute_budget.rs#L13 */ 142 4832 : #define FD_MAX_INSTRUCTION_STACK_DEPTH (5UL) 143 : 144 : 145 0 : #define FD_RUNTIME_VM_TRACE_EVENT_MAX (128UL<<20) 146 : 147 0 : #define FD_RUNTIME_VM_TRACE_STATIC_FOOTPRINT (FD_RUNTIME_VM_TRACE_EVENT_MAX + sizeof(fd_vm_trace_t)) 148 0 : #define FD_RUNTIME_VM_TRACE_STATIC_ALIGN (8UL) 149 : 150 : /* Maximum CPI instruction data size. 10 KiB was chosen to ensure that 151 : CPI instructions are not more limited than transaction instructions 152 : if the size of transactions is doubled in the future. 153 : https://github.com/anza-xyz/agave/blob/v3.1.1/transaction-context/src/lib.rs#L33 */ 154 : #define FD_RUNTIME_CPI_MAX_INSTR_DATA_LEN (10240UL) 155 : 156 : /* The bpf loader's serialization footprint (the size of the per-stack- 157 : frame input region buffer) is bounded by FD_BPF_LOADER_INPUT_REGION_ 158 : FOOTPRINT / BPF_LOADER_SERIALIZATION_FOOTPRINT below; see the comment 159 : there for the derivation. Briefly: per-account fixed overhead 160 : (metadata + per-account resize headroom + alignment) for up to 64 161 : unique accounts, plus the total account-data body bounded once by the 162 : per-transaction loaded-data cap (64 MiB) plus the per-transaction data 163 : growth cap (20 MiB), plus instruction/program-id/pointer-array 164 : trailers. This is far tighter than the previous 64 * 10MiB worst 165 : case, which assumed all 64 accounts could simultaneously be at the 166 : per-account max size (the loaded-data + growth caps make that 167 : impossible). */ 168 233462 : #define MAX_PERMITTED_DATA_INCREASE (10240UL) // 10KB 169 166104 : #define FD_BPF_ALIGN_OF_U128 (8UL) 170 310557 : #define FD_ACCOUNT_REC_ALIGN (8UL) 171 : /* https://github.com/anza-xyz/sbpf/blob/v0.12.2/src/ebpf.rs#L37-L38 */ 172 : #define FD_RUNTIME_EBPF_HOST_ALIGN (16UL) 173 : 174 : /* FD_BPF_LOADER_UNIQUE_ACCOUNT_FIXED_FOOTPRINT is the per-unique-account 175 : serialization overhead EXCLUDING the account's data body: the fixed 176 : metadata fields, plus the realloc headroom (MAX_PERMITTED_DATA_INCREASE) 177 : and the worst-case per-account alignment padding (FD_BPF_ALIGN_OF_U128). 178 : The account data body itself is bounded separately, at the region level, 179 : by the per-transaction loaded-accounts-data cap (see below). */ 180 : #define FD_BPF_LOADER_UNIQUE_ACCOUNT_FIXED_FOOTPRINT \ 181 : (1UL /* dup byte */ + \ 182 : sizeof(uchar) /* is_signer */ + \ 183 : sizeof(uchar) /* is_writable */ + \ 184 : sizeof(uchar) /* executable */ + \ 185 : sizeof(uint) /* original_data_len */ + \ 186 : sizeof(fd_pubkey_t) /* key */ + \ 187 : sizeof(fd_pubkey_t) /* owner */ + \ 188 : sizeof(ulong) /* lamports */ + \ 189 : sizeof(ulong) /* data len */ + \ 190 : FD_BPF_ALIGN_OF_U128 /* per-account data alignment padding */ + \ 191 : MAX_PERMITTED_DATA_INCREASE /* realloc headroom (additive to loaded size) */ + \ 192 : sizeof(ulong)) /* rent_epoch */ 193 : #define FD_BPF_LOADER_DUPLICATE_ACCOUNT_FOOTPRINT (8UL) /* 1 dup byte + 7 bytes for padding */ 194 : 195 : /* FD_SYSVAR_INSTRUCTIONS_FOOTPRINT bounds the worst-case serialized 196 : size of the sysvar instructions account. See 197 : fd_sysvar_instructions.c for the format. 198 : 199 : Worst case size for V0/legacy transactions. Each bullet is bounded by 200 : its own maximum; those maxima compete for the same 1232-byte tx and 201 : can't all be reached at once, so the sum is a deliberately loose 202 : over-estimate: 203 : - 2 bytes header (num_instructions) 204 : - instruction offsets: 2 bytes * FD_TXN_INSTR_MAX (64) = 128 bytes 205 : - per-instr fixed: 2 (num_accounts) + 32 (program_id) + 2 (data_len) 206 : = 36 bytes * FD_TXN_INSTR_MAX (64) = 2304 bytes 207 : - account refs: each takes 1 byte (an index) in the tx but serializes 208 : to 33 bytes (1 flag + 32-byte pubkey); a 1232-byte tx holds at most 209 : ~1094 indices across all its instructions, so 33 * 1094 = 36102 bytes 210 : - instr data: bounded by the legacy MTU FD_TXN_MTU_V0 (1232 bytes) 211 : - 2 bytes tail (current_instr_idx) 212 : Total: 39770 bytes 213 : 214 : Worst case size for V1 transactions: 215 : Instruction start offsets are u16, so an accepted sysvar has every 216 : offset <= 65535; a larger offset overflows and is rejected (matching 217 : agave). The worst case is the last instruction starting at 65535: 218 : 219 : - 65535 bytes (offset of the last instruction) 220 : - per-acct ref: 33 bytes * 255 = 8415 bytes 221 : - per-instr fixed: 2 (num_accounts) + 32 (program_id) + 2 (data_len) 222 : = 36 bytes 223 : - instr data: bounded by FD_TXN_MTU (4096 bytes) 224 : - 2 bytes tail (current_instr_idx) 225 : Total: 78084 bytes, rounded up to 81920. */ 226 : #define FD_SYSVAR_INSTRUCTIONS_FOOTPRINT (81920UL) 227 : 228 : /* FD_BPF_LOADER_INPUT_REGION_FOOTPRINT bounds the bytes a single 229 : instruction can serialize into one input region. 230 : 231 : The account data bodies are NOT bounded by account_lock_limit * 232 : FD_RUNTIME_ACC_SZ_MAX (64 * 10 MiB = 640 MiB): a transaction is 233 : rejected before execution (and therefore before serialization) if the 234 : sum of its loaded account data exceeds 235 : FD_VM_LOADED_ACCOUNTS_DATA_SIZE_LIMIT (see 236 : fd_executor_load_transaction_accounts -> 237 : fd_increase_calculated_data_size, called from 238 : fd_runtime_pre_execute_check before fd_execute_txn). Note that this 239 : does not include the instructions sysvar, as this is not counted 240 : towards the loaded accounts data size limit. An instruction 241 : serializes a subset of the transaction's (<= account_lock_limit 242 : unique) accounts, each unique account's data copied at most once (dups 243 : cost 8 bytes). 244 : 245 : However, a program may GROW account data during execution before a 246 : later instruction (or CPI) re-serializes it. Total account-data 247 : growth across a transaction is itself capped, at 248 : FD_RUNTIME_ACC_DATA_GROWTH_MAX_PER_TXN (== fd_borrowed_account.h's 249 : MAX_PERMITTED_ACCOUNT_DATA_ALLOCS_PER_TXN, which fd_borrowed_account.c 250 : enforces by rejecting any resize that pushes accounts_resize_delta 251 : over the cap). So the worst-case account-data body serialized by any 252 : one instruction is bounded by 253 : 254 : FD_VM_LOADED_ACCOUNTS_DATA_SIZE_LIMIT (initial loaded data) 255 : + FD_RUNTIME_ACC_DATA_GROWTH_MAX_PER_TXN (max growth this txn) 256 : 257 : i.e. 64 MiB + 20 MiB = 84 MiB. We charge the data bodies once at the 258 : region level with that combined bound, plus the fixed per-account 259 : overhead (metadata + per-account realloc headroom + alignment). 260 : 261 : When direct_mapping is enabled the data body is mapped rather than 262 : copied, so it costs nothing in this buffer at all. */ 263 : #define FD_BPF_LOADER_INPUT_REGION_FOOTPRINT(account_lock_limit, direct_mapping) \ 264 : (FD_ULONG_ALIGN_UP( (sizeof(ulong) /* acct_cnt */ + \ 265 : account_lock_limit*FD_BPF_LOADER_UNIQUE_ACCOUNT_FIXED_FOOTPRINT + \ 266 : ((direct_mapping) ? 0UL : ((ulong)FD_VM_LOADED_ACCOUNTS_DATA_SIZE_LIMIT + \ 267 : (ulong)FD_RUNTIME_ACC_DATA_GROWTH_MAX_PER_TXN)) + \ 268 : FD_SYSVAR_INSTRUCTIONS_FOOTPRINT + \ 269 : (FD_TXN_INSTR_ACCT_MAX-account_lock_limit)*FD_BPF_LOADER_DUPLICATE_ACCOUNT_FOOTPRINT + \ 270 : sizeof(ulong) /* instr data len */ + \ 271 : FD_RUNTIME_CPI_MAX_INSTR_DATA_LEN /* instr data */ + \ 272 : sizeof(fd_pubkey_t) /* program id */ + \ 273 : (FD_BPF_ALIGN_OF_U128-1UL) + \ 274 : FD_TXN_INSTR_ACCT_MAX*sizeof(ulong) /* direct_account_pointers_in_program_input */), \ 275 : FD_RUNTIME_EBPF_HOST_ALIGN )) 276 : 277 : 278 : 279 : #define BPF_LOADER_SERIALIZATION_FOOTPRINT (FD_BPF_LOADER_INPUT_REGION_FOOTPRINT(64UL, 0)) 280 : 281 0 : #define FD_HARD_FORKS_MAX (64UL) 282 : 283 : FD_PROTOTYPES_END 284 : 285 : #endif /* HEADER_fd_src_flamenco_runtime_fd_runtime_const_h */