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