Line data Source code
1 : #ifndef HEADER_fd_src_discof_restore_utils_fd_ssmsg_h
2 : #define HEADER_fd_src_discof_restore_utils_fd_ssmsg_h
3 :
4 : #include "../../../flamenco/runtime/fd_runtime_const.h"
5 : #include "../../../flamenco/runtime/fd_blockhashes.h"
6 :
7 0 : #define FD_SSMSG_MANIFEST_FULL (0) /* A snapshot manifest message from the full snapshot */
8 0 : #define FD_SSMSG_MANIFEST_INCREMENTAL (1) /* A snapshot manifest message from the incremental snapshot */
9 0 : #define FD_SSMSG_DONE (2) /* Indicates the snapshot is fully loaded and tiles are shutting down */
10 0 : #define FD_SSMSG_EXPECTED_SLOT (3) /* Expected rooted slot from incremental snapshot */
11 :
12 : FD_FN_CONST static inline ulong
13 0 : fd_ssmsg_sig( ulong message ) {
14 0 : return (message & 0x3UL);
15 0 : }
16 :
17 0 : FD_FN_CONST static inline ulong fd_ssmsg_sig_message( ulong sig ) { return (sig & 0x3UL); }
18 : struct epoch_credits {
19 : ulong epoch;
20 : ulong credits;
21 : ulong prev_credits;
22 : };
23 :
24 : typedef struct epoch_credits epoch_credits_t;
25 :
26 : /* fd_epoch_credits_is_alpenglow_marker returns 1 if ec is the
27 : tower->Alpenglow migration sentinel, 0 otherwise. */
28 :
29 : FD_FN_PURE static inline int
30 0 : fd_epoch_credits_is_alpenglow_marker( epoch_credits_t const * ec ) {
31 0 : return ec->epoch==ULONG_MAX && ec->credits==ULONG_MAX && ec->prev_credits==ULONG_MAX;
32 0 : }
33 :
34 : /* The FD_SSMSG_EXPECTED_SLOT uses the tsorig and tspub fields
35 : of the fd_frag_meta_t struct to store the low and high 32 bits of
36 : the slot number. */
37 : static inline void
38 : fd_ssmsg_slot_to_frag( ulong slot,
39 : uint* low,
40 0 : uint* high ) {
41 0 : *low = (uint)(slot & 0xFFFFFFFFUL);
42 0 : *high = (uint)((slot >> 32UL) & 0xFFFFFFFFUL);
43 0 : }
44 :
45 : static inline void
46 : fd_ssmsg_frag_to_slot( ulong low,
47 : ulong high,
48 0 : ulong* slot ) {
49 0 : *slot = (high << 32UL) | low;
50 0 : }
51 :
52 : struct fd_snapshot_manifest_vote_account {
53 : /* The pubkey of the vote account */
54 : uchar vote_account_pubkey[ 32UL ];
55 :
56 : /* The pubkey of the node account */
57 : uchar node_account_pubkey[ 32UL ];
58 :
59 : ulong stake;
60 : };
61 :
62 : typedef struct fd_snapshot_manifest_vote_account fd_snapshot_manifest_vote_account_t;
63 :
64 : /* TODO: Consider combining this struct with
65 : fd_snapshot_manifest_vote_account. */
66 :
67 : struct fd_snapshot_manifest_vote_stakes {
68 : /* The vote pubkey */
69 : uchar vote[ 32UL ];
70 :
71 : /* The validator identity pubkey, aka node pubkey */
72 : uchar identity[ 32UL ];
73 :
74 : /* The commission account for inflation rewards (vote, before SIMD-0232) */
75 : uchar commission_inflation[ 32UL ];
76 :
77 : /* The commission account for block revenue (identity, before SIMD-0232) */
78 : uchar commission_block[ 32UL ];
79 :
80 : /* Whether this vote account has a BLS pubkey set */
81 : uchar has_identity_bls;
82 :
83 : /* The validator BLS pubkey (used after SIMD-0326: Alpenglow) */
84 : uchar identity_bls[ 48UL ];
85 :
86 : /* The total amount of active stake for the vote account */
87 : ulong stake;
88 :
89 : /* The latest slot and timestamp that the vote account voted on in
90 : the given epoch. */
91 : ulong slot;
92 : long timestamp;
93 :
94 : /* The validator's commission rate as of the given epoch. */
95 : ushort commission;
96 :
97 : /* The validator's block revenue commission (basis points) */
98 : ushort commission_block_bps;
99 :
100 : /* The validator's pending delegator rewards as of the given epoch */
101 : ulong pending_delegator_rewards;
102 :
103 : /* The epoch credits array tracks the history of how many credits the
104 : provided vote account earned in each recorded epoch. Entries are
105 : ordered by strictly increasing epoch: epoch_credits[0] is the
106 : oldest and epoch_credits[epoch_credits_history_len-1] is the
107 : newest. Epochs with no recorded credits can be absent. When
108 : booting a new chain from genesis, or for new vote accounts, the
109 : epoch credits history may be short. The maximum number of entries
110 : in the epoch credits history is 64.
111 :
112 : Note one entry may be the Alpenglow migration marker (all three
113 : fields ULONG_MAX, see fd_epoch_credits_is_alpenglow_marker). */
114 : ulong epoch_credits_history_len;
115 : epoch_credits_t epoch_credits[ FD_EPOCH_CREDITS_MAX ];
116 : };
117 :
118 : typedef struct fd_snapshot_manifest_vote_stakes fd_snapshot_manifest_vote_stakes_t;
119 :
120 : struct fd_snapshot_manifest_epoch_stakes {
121 : /* The epoch for which these vote accounts and stakes are valid for */
122 : ulong epoch;
123 : /* The total amount of active stake at the end of the given epoch.*/
124 : ulong total_stake;
125 :
126 : /* The vote accounts and their stakes for a given epoch.
127 : FIXME: Snapshot manifest has to support a much larger bound. */
128 : ulong vote_stakes_len;
129 : fd_snapshot_manifest_vote_stakes_t vote_stakes[ FD_RUNTIME_MAX_VAT_VOTE_ACCOUNTS ];
130 : };
131 :
132 : typedef struct fd_snapshot_manifest_epoch_stakes fd_snapshot_manifest_epoch_stakes_t;
133 :
134 : struct fd_snapshot_manifest_inflation_params {
135 : /* The initial inflation percentage starting at genesis. This value is
136 : set at genesis to 8%, and is only changed at the boundary when
137 : double_disinflation_rate activates. */
138 : double initial;
139 :
140 : /* The terminal inflation percentage is the long-term steady state
141 : inflation rate after a period of disinflation. This value is set
142 : at genesis to 1.5% and is not expected to change. */
143 : double terminal;
144 :
145 : /* The rate per year at which inflation is lowered until it reaches
146 : the terminal inflation rate. This value is set to 15% at genesis
147 : and only changes at the boundary when double_disinflation_rate
148 : activates. */
149 : double taper;
150 :
151 : /* The percentage of total inflation allocated to the foundation.
152 : This value is set at genesis to 5% and is not expected to change. */
153 : double foundation;
154 :
155 : /* The number of years in which a portion of the total inflation is
156 : allocated to the foundation (see foundation field). This value is
157 : set to 7 years at genesis and is not expected to change. */
158 : double foundation_term;
159 : };
160 :
161 : typedef struct fd_snapshot_manifest_inflation_params fd_snapshot_manifest_inflation_params_t;
162 :
163 : struct fd_snapshot_manifest_epoch_schedule_params {
164 : /* The maximum number of slots in each epoch. */
165 : ulong slots_per_epoch;
166 :
167 : /* A number of slots before beginning of an epoch to calculate a
168 : leader schedule for that epoch. This value is set to
169 : slots_per_epoch (basically one epoch) and is unlikely to change. */
170 : ulong leader_schedule_slot_offset;
171 :
172 : /* Whether there is a warmup period where epochs are short and grow by
173 : powers of two until they reach the default epoch length of
174 : slots_per_epoch. This value is set by default to true at genesis,
175 : though it may be configured differently in development
176 : environments. */
177 : uchar warmup;
178 :
179 : /* TODO: Probably remove this? Redundant and can be calculated from
180 : the above. */
181 : ulong first_normal_epoch;
182 : ulong first_normal_slot;
183 : };
184 :
185 : typedef struct fd_snapshot_manifest_epoch_schedule_params fd_snapshot_manifest_epoch_schedule_params_t;
186 :
187 : struct fd_snapshot_manifest_fee_rate_governor {
188 : /* Transaction fees are calculated by charging a cost for each
189 : signature. There is a mechanism to dynamically adjust the cost per
190 : signature based on the cluster's transaction processing capacity.
191 : In this mechanism, the cost per signature can vary between 50% to
192 : 1000% of the target_lamports_per_signature value, which is the cost
193 : per signature when the cluster is operating at the desired
194 : transaction processing capacity defined by
195 : target_signatures_per_slot.
196 :
197 : This value is fixed at 10,000 from genesis onwards but may be
198 : changed in the future with feature flags. */
199 : ulong target_lamports_per_signature;
200 :
201 : /* The cluster transaction processing capacity is measured by
202 : signatures per slot. Solana defines the desired transaction
203 : processing capacity using the value target_signatures_per_slot.
204 :
205 : This value is fixed at 20,000 from genesis onwards but may be
206 : changed in the future with feature flags. */
207 : ulong target_signatures_per_slot;
208 :
209 : /* The minimum cost per signature is 50% of the
210 : target_lamports_per_signature value. Under the current default for
211 : target_lamports_per_signature, this value is at 5,000 lamports per
212 : signature. */
213 : ulong min_lamports_per_signature;
214 :
215 : /* The maximum cost per signature is 1000% of the
216 : target_lamports_per_signature value. Under the current default for
217 : target_lamports_per_signature, this value is at 100,000 lamports
218 : per signature.*/
219 : ulong max_lamports_per_signature;
220 :
221 : /* The percent of collected fees that are burned. This value is
222 : currently set to a fixed value of 50% from genesis onwards, but
223 : may be changed in the future with feature flags. */
224 : uchar burn_percent;
225 : };
226 :
227 : typedef struct fd_snapshot_manifest_fee_rate_governor fd_snapshot_manifest_fee_rate_governor_t;
228 :
229 : struct fd_snapshot_manifest_rent {
230 : ulong lamports_per_uint8_year;
231 : double exemption_threshold;
232 : uchar burn_percent;
233 : };
234 :
235 : typedef struct fd_snapshot_manifest_rent fd_snapshot_manifest_rent_t;
236 :
237 : struct fd_snapshot_manifest_blockhash {
238 : uchar hash[ 32UL ];
239 : ulong lamports_per_signature;
240 : ulong hash_index;
241 : ulong timestamp;
242 : };
243 :
244 : typedef struct fd_snapshot_manifest_blockhash fd_snapshot_manifest_blockhash_t;
245 :
246 : struct fd_snapshot_manifest {
247 : /* The UNIX timestamp when the genesis block was for this chain
248 : was created, in seconds.
249 : https://github.com/anza-xyz/agave/blob/v4.0.0-beta.1/runtime/src/bank.rs#L2108-L2114 */
250 : ulong creation_time_seconds;
251 :
252 : /* At genesis, certain parameters can be set which control the
253 : inflation rewards going forward. This includes what the initial
254 : inflation is and how the inflation curve changes over time.
255 :
256 : These parameters may change with feature gate activations, for
257 : example double_disinflation_rate. */
258 : fd_snapshot_manifest_inflation_params_t inflation_params;
259 :
260 : /* At genesis, certain parameters can be set which control the
261 : epoch schedule going forward. This includes how many slots
262 : there are per epoch, and certain development settings like if
263 : epochs start short and grow longer as the chain progresses.
264 :
265 : Currently, these parameters can never change and are fixed from
266 : genesis onwards, although in future they may change with new
267 : feature flags. */
268 : fd_snapshot_manifest_epoch_schedule_params_t epoch_schedule_params;
269 :
270 : /* At genesis, certain parameters can be set which control
271 : how transaction fees are dynamically adjusted going forward.
272 :
273 : Currently, these parameters can never change and are fixed from
274 : genesis onwards, although in future they may change with new
275 : feature flags. */
276 : fd_snapshot_manifest_fee_rate_governor_t fee_rate_governor;
277 :
278 : fd_snapshot_manifest_rent_t rent_params;
279 :
280 : /* The slot number for this snapshot */
281 : ulong slot;
282 :
283 : /* The number of blocks that have been built since genesis. This is
284 : kind of like the slot number, in that it increments by 1 for every
285 : landed block, but it does not increment for skipped slots, so the
286 : block_height will always be less than or equal to the slot. */
287 : ulong block_height;
288 :
289 : /* TODO: Document */
290 : ulong collector_fees;
291 :
292 : /* The parent slot is the slot that this block builds on top of. It
293 : is typically slot-1, but can be an arbitrary amount of slots
294 : earlier in case of forks, when the block skips over preceding
295 : slots. */
296 : ulong parent_slot;
297 :
298 : /* The bank hash of the slot represented by this snapshot. The bank
299 : hash is used by the validator to detect mismatches. All validators
300 : must agree on a bank hash for each slot or they will fork off.
301 :
302 : The bank hash is created for every slot by hashing together the
303 : parent bank hash with the accounts delta hash, the most recent
304 : Proof of History blockhash, and the number of signatures in the
305 : slot.
306 :
307 : The bank hash includes the epoch accounts hash when the epoch
308 : accounts hash is ready at slot 324000 in the current epoch. See the
309 : epoch_accounts_hash for more details regarding the epcoh accounts
310 : hash calculation . */
311 : uchar bank_hash[ 32UL ];
312 :
313 : /* The bank hash of the parent slot. */
314 : uchar parent_bank_hash[ 32UL ];
315 :
316 : /* The merkle-based hash of all account state on chain at the slot the
317 : snapshot is created. The accounts hash is calculated when producing
318 : a snapshot. */
319 : uchar accounts_hash[ 32UL ];
320 :
321 : /* The merkle-based hash of modified accounts for the slot the
322 : snapshot is created. The accounts_delta_hash is computed at
323 : the end of every slot and included into each bank hash. It is
324 : computed by hashing all modified account state together. */
325 : uchar accounts_delta_hash[ 32UL ];
326 :
327 : /* The lattice hash of all account state on chain. */
328 : int has_accounts_lthash;
329 : uchar accounts_lthash[ 2048UL ];
330 :
331 : /* The hash of all accounts at this snapshot's epoch.
332 : The epoch account hash is very expensive to calculate, so it is
333 : only calculated once per epoch during the epoch account hash
334 : calculation window, which is a range of slots in an epoch starting
335 : at slot 108000 and ending at slot 324000, where each epoch has
336 : 432000 slots.
337 :
338 : The epoch_account_hash may be empty if the snapshot was produced
339 : before the epoch account hash calculation window. */
340 : int has_epoch_account_hash;
341 : uchar epoch_account_hash[ 32UL ];
342 :
343 : /* The merkle root of the snapshot slot's block.
344 : Only present in snapshots generated by Agave >=4.1. */
345 : int has_block_id;
346 : uchar block_id[ 32UL ];
347 :
348 : ulong blockhashes_len;
349 : fd_snapshot_manifest_blockhash_t blockhashes[ FD_BLOCKHASHES_MAX ];
350 :
351 : ushort accdb_fork_id; /* The fork_id in the account database for the root slot. */
352 : ushort txncache_fork_id; /* The fork_id in the status cache for the root slot. */
353 :
354 : /* A list of ancestor slots has been deprecated. Agave's bank now
355 : creates an ancestor set with a single entry (the current slot):
356 : https://github.com/anza-xyz/agave/blob/v4.0.0-beta.1/runtime/src/bank.rs#L1846 */
357 :
358 : /* A hard fork is a deliberate deviation from the canonical blockchain
359 : progression. This contains the list of slots which have
360 : historically undergone a hard fork. The typical case for these is
361 : a feature is deactivated and the cluster is restarted. */
362 : ulong hard_fork_cnt;
363 : fd_hard_fork_t hard_forks[ FD_HARD_FORKS_MAX ];
364 :
365 : /* The proof of history component "proves" the passage of time (see
366 : extended discussion in PoH tile for what that actually means) by
367 : continually doing sha256 hashes. A certain number of hashes are
368 : required to be in each slot, to prove the leader spent some amount
369 : of time on the slot and didn't end it too early.
370 :
371 : In all clusters and environments that matter, this value is fixed
372 : at 64 and is unlikely to change, however it might be configured
373 : differently in development environments. */
374 : ulong ticks_per_slot;
375 :
376 : /* TODO: Document */
377 : ulong ns_per_slot;
378 :
379 : /* TODO: Document */
380 : double slots_per_year;
381 :
382 : /* The proof of history component typically requires every block to
383 : have 64 "ticks" in it (although this is configurable during
384 : development), but each tick is some flexible number of recursive
385 : sha256 hashes defined at genesis.
386 :
387 : The number of hashes for mainnet genesis is 12,500, meaning there
388 : will be 800,000 hashes per slot.
389 :
390 : There are various features, named like update_hashes_per_tick*
391 : which if enabled update the hashes_per_tick of the chain as-of the
392 : epoch where they are enabled. This value incorporates any changes
393 : due to such features.
394 :
395 : In development environments, sometimes hashes_per_tick will not be
396 : specified (has_hashes_per_tick will be 0). Agave refers to this as
397 : a "low power" mode, where ticks have just one hash in them. It is
398 : distinct from just setting hahes_per_tick to 1, because it also
399 : reduces the slot duration from 400ms down to 0ms (or however long
400 : it takes to produce the hash). See comments in the PoH tile for
401 : more extended discussion. */
402 : int has_hashes_per_tick;
403 : ulong hashes_per_tick;
404 :
405 : /* The sum of all account balances in lamports as of this snapshots
406 : slot. Total capitalization is used when computing inflation
407 : rewards and validating snapshots. */
408 : ulong capitalization;
409 :
410 : /* TODO: Why is this needed? */
411 : ulong tick_height;
412 : ulong max_tick_height;
413 :
414 : /* TODO: What is this? */
415 : ulong lamports_per_signature;
416 :
417 : /* TODO: Why is this needed? */
418 : ulong transaction_count;
419 :
420 : /* TODO: Why is this needed? */
421 : ulong signature_count;
422 :
423 : /* Every staked vote account and its stake, taken from the stakes
424 : cache rather than a single epoch's admitted set. This field is only
425 : used for wait for supermajority cluster restarts, which measures
426 : what fraction of activated stake is visible in gossip. */
427 : ulong vote_accounts_len;
428 : fd_snapshot_manifest_vote_account_t vote_accounts[ FD_RUNTIME_MAX_SNAPSHOT_VOTE_ACCOUNTS ];
429 :
430 : /* Epoch stakes represent the exact amount staked to each vote
431 : account at the beginning of a previous epoch. They are primarily
432 : used to derive the leader schedule.
433 :
434 : Let's say the manifest is at epoch E.
435 :
436 : The field versioned_epoch_stakes in the manifest is a map
437 :
438 : <epoch> -> <VersionedEpochStakes>
439 :
440 : where <epoch> assumes these values:
441 :
442 : E-3 - represents the stakes at the beginning of epoch E-4.
443 : E-2 - represents the stakes at the beginning of epoch E-3.
444 : Agave retains MAX_LEADER_SCHEDULE_STAKES (5) entries and
445 : a block footer may carry a finalization cert from any
446 : epoch it retains, so these are loaded as well.
447 :
448 : E-1 - represents the stakes at the beginning of epoch E-2,
449 : used to compute the leader schedule at E-1. Also used
450 : by delay_commission_updates (SIMD-0249) to determine
451 : the commission rate for partitioned epoch rewards
452 : recalculation at boot.
453 :
454 : E - represents the stakes at the beginning of epoch E-1,
455 : used to compute the leader schedule at E.
456 :
457 : E+1 - represents the stakes at the beginning of epoch E,
458 : used to compute the leader schedule at E+1.
459 :
460 : The epoch stakes are stored in an array indexed from
461 : epoch_stakes_base = max( E-3, 0 ):
462 : epoch_stakes[0] = epoch E-3
463 : epoch_stakes[1] = epoch E-2
464 : epoch_stakes[2] = epoch E-1
465 : epoch_stakes[3] = epoch E
466 : epoch_stakes[4] = epoch E+1
467 : Entries the snapshot does not carry keep epoch ULONG_MAX. */
468 : fd_snapshot_manifest_epoch_stakes_t epoch_stakes[ FD_RUNTIME_MANIFEST_EPOCH_STAKES_LEN ];
469 : };
470 :
471 : typedef struct fd_snapshot_manifest fd_snapshot_manifest_t;
472 :
473 : #endif /* HEADER_fd_src_discof_restore_utils_fd_ssmsg_h */
|