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