Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_program_vote_fd_vote_codec_h
2 : #define HEADER_fd_src_flamenco_runtime_program_vote_fd_vote_codec_h
3 :
4 : #include "../../../fd_flamenco_base.h"
5 :
6 : /* Vote program type definitions and (de)serializers.
7 :
8 : Supported versions: v1_14_11, v3, v4. */
9 :
10 : /**********************************************************************/
11 : /* Constants -- vote state */
12 : /**********************************************************************/
13 :
14 : /* Note we add to each of the bounds for the max capacity to account
15 : for edge cases where elements are added beyond theoretical capacity
16 : and then popped within execution. */
17 :
18 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/state/mod.rs#L39 */
19 4326 : #define MAX_LOCKOUT_HISTORY (31UL)
20 4326 : #define MAX_LOCKOUT_HISTORY_CAPACITY (MAX_LOCKOUT_HISTORY+1UL)
21 :
22 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/state/mod.rs#L43 */
23 168 : #define MAX_EPOCH_CREDITS_HISTORY (64UL)
24 165 : #define MAX_EPOCH_CREDITS_HISTORY_CAPACITY (MAX_EPOCH_CREDITS_HISTORY+1UL)
25 :
26 : /* This is an implicit bound derived from the vote program logic. When
27 : authorized voters are updated inside the vote program, any authorized
28 : voters outside of the [epoch-1, epoch+2] range are purged. In
29 : between execution, up to 2 authorized voters can be added, so we
30 : need to allocate extra capacity accordingly. */
31 8652 : #define MAX_AUTHORIZED_VOTERS (4UL)
32 8652 : #define MAX_AUTHORIZED_VOTERS_CAPACITY (MAX_AUTHORIZED_VOTERS+2UL)
33 :
34 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/state/mod.rs#L154 */
35 0 : #define PRIOR_VOTERS_MAX (32UL)
36 :
37 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/state/mod.rs#L33 */
38 19848 : #define FD_BLS_PUBKEY_COMPRESSED_SZ (48UL)
39 462 : #define FD_BLS_PUBKEY_UNCOMPRESSED_SZ (96UL)
40 :
41 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.0.0/vote-interface/src/state/mod.rs#L36 */
42 : #define FD_BLS_PROOF_OF_POSSESSION_COMPRESSED_SZ (96UL)
43 :
44 : /**********************************************************************/
45 : /* Constants -- vote instruction footprints */
46 : /**********************************************************************/
47 :
48 : /* Some vote instruction types are dynamically sized:
49 : - tower_sync_switch (contains deque of fd_vote_lockout_t)
50 : - tower_sync (contains deque of fd_vote_lockout_t)
51 : - compact_vote_state_update_switch (vector of fd_lockout_offset_t)
52 : - compact_vote_state_update (vector of fd_lockout_offset_t)
53 : - authorize_checked_with_seed (char vector of current_authority_derived_key_seed)
54 : - authorize_with_seed (char vector of current_authority_derived_key_seed)
55 : - update_vote_state_switch (contains deque of fd_vote_lockout_t)
56 : - update_vote_state (contains deque of fd_vote_lockout_t)
57 : - vote_switch (deque of slot numbers)
58 : - vote (deque of slot numbers)
59 : All other vote instruction types are statically sized.
60 :
61 : A loose bound on the max amount of encoded fd_vote_lockout_t
62 : possible is 1232 bytes/(12 bytes/per lockout) = 102 lockouts. So
63 : the worst case bound for the deque of fd_vote_lockout is
64 : 32 + (102 * sizeof(fd_vote_lockout_t)) = 1644 bytes.
65 :
66 : The worst case vector of fd_lockout_offset_t is one where each
67 : encoded element is 2 bytes. This means that we can have 1232/2 =
68 : 616 elements. They are represented as being 16 bytes each, so the
69 : total footprint would be 9856 bytes.
70 :
71 : The deque of slot numbers is a vector of ulong, which is 8 bytes.
72 : So the worst case is 1232 bytes/8 bytes = 154 elements. So, the
73 : total footprint is 32 + (154 * 8 bytes) = 1264 bytes.
74 :
75 : The worst case char vector is 1232 bytes as each element is 1 byte
76 : up to the txn MTU.
77 :
78 : With this, that means that the compact_vote_state_update_switch
79 : can have the largest worst case footprint where the struct is
80 : 104 bytes (sizeof(fd_compact_vote_state_update_switch_t) + the
81 : worst case lockout vector of 616 elements. */
82 0 : #define FD_VOTE_INSTR_MAX_LOCKOUTS_LEN (102UL)
83 3 : #define FD_VOTE_INSTR_MAX_LOCKOUT_OFFSETS_LEN (616UL)
84 0 : #define FD_VOTE_INSTR_MAX_SLOT_NUMS_LEN (154UL)
85 :
86 : /* Footprints for embedded memory arrays inside vote instruction
87 : sub-structs. Validated by test_vote_instruction_footprints
88 : in test_vote_program. */
89 : #define FD_VOTE_INSTR_SLOTS_ALIGN (8UL)
90 : #define FD_VOTE_INSTR_SLOTS_FOOTPRINT (1264UL)
91 : #define FD_VOTE_INSTR_UPDATE_LOCKOUTS_ALIGN (8UL)
92 : #define FD_VOTE_INSTR_UPDATE_LOCKOUTS_FOOTPRINT (1664UL)
93 : #define FD_VOTE_INSTR_LOCKOUT_OFFSET_ALIGN (8UL)
94 : #define FD_VOTE_INSTR_LOCKOUT_OFFSET_FOOTPRINT (9856UL)
95 : #define FD_VOTE_INSTR_SEED_MAX (1232UL)
96 :
97 : /* Footprints for runtime buffers that hold lockouts / landed votes
98 : derived from vote instruction data. The max element count is
99 : FD_VOTE_INSTR_MAX_LOCKOUT_OFFSETS_LEN (616) because the tower sync
100 : and compact vote state update paths can produce that many entries. */
101 : #define FD_VOTE_INSTR_LOCKOUTS_ALIGN (8UL)
102 : #define FD_VOTE_INSTR_LOCKOUTS_FOOTPRINT (9888UL)
103 : #define FD_VOTE_INSTR_LANDED_VOTES_ALIGN (8UL)
104 : #define FD_VOTE_INSTR_LANDED_VOTES_FOOTPRINT (14816UL)
105 :
106 : /**********************************************************************/
107 : /* Constants -- vote account state footprints */
108 : /**********************************************************************/
109 :
110 : /* Alignments and footprints for the authorized voters pool and treap at
111 : MAX_AUTHORIZED_VOTERS_CAPACITY. Validated by
112 : test_authorized_voters_footprint in test_vote_program. */
113 : #define FD_AUTHORIZED_VOTERS_POOL_ALIGN (128UL)
114 : #define FD_AUTHORIZED_VOTERS_POOL_FOOTPRINT (512UL)
115 : #define FD_AUTHORIZED_VOTERS_TREAP_ALIGN (8UL)
116 : #define FD_AUTHORIZED_VOTERS_TREAP_FOOTPRINT (24UL)
117 :
118 : /* Alignment and footprint for the landed votes at
119 : MAX_LOCKOUT_HISTORY_CAPACITY. Validated by
120 : test_landed_votes_footprint in test_vote_program. */
121 : #define FD_LANDED_VOTES_FOOTPRINT (800UL)
122 : #define FD_LANDED_VOTES_ALIGN (8UL)
123 :
124 : /* Alignment and footprint for the epoch credits at
125 : MAX_EPOCH_CREDITS_HISTORY_CAPACITY. Validated by
126 : test_epoch_credits_footprint in test_vote_program. */
127 : #define FD_EPOCH_CREDITS_FOOTPRINT (1576UL)
128 : #define FD_EPOCH_CREDITS_ALIGN (8UL)
129 :
130 : /**********************************************************************/
131 : /* Shared leaf types */
132 : /**********************************************************************/
133 :
134 : struct fd_vote_lockout {
135 : ulong slot;
136 : uint confirmation_count;
137 : };
138 : typedef struct fd_vote_lockout fd_vote_lockout_t;
139 : #define FD_VOTE_LOCKOUT_ALIGN alignof(fd_vote_lockout_t)
140 :
141 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/authorized_voters.rs#L11-L13 */
142 : struct fd_vote_authorized_voter {
143 : ulong epoch;
144 : fd_pubkey_t pubkey;
145 :
146 : /* Treap/pool index fields. uchar is sufficient because the max
147 : authorized voters capacity is MAX_AUTHORIZED_VOTERS_CAPACITY (6). */
148 : uchar parent;
149 : uchar left;
150 : uchar right;
151 : uchar prio;
152 : };
153 : typedef struct fd_vote_authorized_voter fd_vote_authorized_voter_t;
154 : #define FD_VOTE_AUTHORIZED_VOTER_ALIGN alignof(fd_vote_authorized_voter_t)
155 :
156 : struct fd_vote_prior_voter {
157 : fd_pubkey_t pubkey;
158 : ulong epoch_start;
159 : ulong epoch_end;
160 : };
161 : typedef struct fd_vote_prior_voter fd_vote_prior_voter_t;
162 : #define FD_VOTE_PRIOR_VOTER_ALIGN alignof(fd_vote_prior_voter_t)
163 :
164 : struct __attribute__((packed)) fd_vote_epoch_credits {
165 : ulong epoch;
166 : ulong credits;
167 : ulong prev_credits;
168 : };
169 : typedef struct fd_vote_epoch_credits fd_vote_epoch_credits_t;
170 : #define FD_VOTE_EPOCH_CREDITS_ALIGN alignof(fd_vote_epoch_credits_t)
171 :
172 : /* fd_vote_epoch_credits_is_alpenglow_marker returns 1 if ec is the
173 : tower->Alpenglow migration sentinel, 0 otherwise. */
174 :
175 : FD_FN_PURE static inline int
176 123 : fd_vote_epoch_credits_is_alpenglow_marker( fd_vote_epoch_credits_t const * ec ) {
177 123 : return ec->epoch==ULONG_MAX && ec->credits==ULONG_MAX && ec->prev_credits==ULONG_MAX;
178 123 : }
179 :
180 : struct fd_vote_block_timestamp {
181 : ulong slot;
182 : long timestamp;
183 : };
184 : typedef struct fd_vote_block_timestamp fd_vote_block_timestamp_t;
185 : #define FD_VOTE_BLOCK_TIMESTAMP_ALIGN alignof(fd_vote_block_timestamp_t)
186 :
187 : struct fd_vote_prior_voters {
188 : fd_vote_prior_voter_t buf[PRIOR_VOTERS_MAX];
189 : ulong idx;
190 : uchar is_empty;
191 : };
192 : typedef struct fd_vote_prior_voters fd_vote_prior_voters_t;
193 : #define FD_VOTE_PRIOR_VOTERS_ALIGN alignof(fd_vote_prior_voters_t)
194 :
195 : /* This type is reused between all vote states for simplicity. */
196 : struct fd_landed_vote {
197 : /* Latency is only used in v3+ vote states. */
198 : uchar latency;
199 : fd_vote_lockout_t lockout;
200 : };
201 : typedef struct fd_landed_vote fd_landed_vote_t;
202 : #define FD_LANDED_VOTE_ALIGN alignof(fd_landed_vote_t)
203 :
204 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.0.0/vote-interface/src/state/vote_instruction_data.rs#L253 */
205 : struct fd_voter_with_bls_args {
206 : uchar bls_pubkey[FD_BLS_PUBKEY_COMPRESSED_SZ];
207 : uchar bls_proof_of_possession[FD_BLS_PROOF_OF_POSSESSION_COMPRESSED_SZ];
208 : };
209 : typedef struct fd_voter_with_bls_args fd_voter_with_bls_args_t;
210 : #define FD_VOTER_WITH_BLS_ARGS_ALIGN alignof(fd_voter_with_bls_args_t)
211 :
212 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_state/mod.rs#L230 */
213 : struct fd_vote_init {
214 : fd_pubkey_t node_pubkey;
215 : fd_pubkey_t authorized_voter;
216 : fd_pubkey_t authorized_withdrawer;
217 : uchar commission;
218 : };
219 : typedef struct fd_vote_init fd_vote_init_t;
220 : #define FD_VOTE_INIT_ALIGN alignof(fd_vote_init_t)
221 :
222 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.0.0/vote-interface/src/state/vote_instruction_data.rs#L213 */
223 : struct fd_vote_init_v2 {
224 : fd_pubkey_t node_pubkey;
225 : fd_pubkey_t authorized_voter;
226 : uchar authorized_voter_bls_pubkey[FD_BLS_PUBKEY_COMPRESSED_SZ];
227 : uchar authorized_voter_bls_proof_of_possession[FD_BLS_PROOF_OF_POSSESSION_COMPRESSED_SZ];
228 : fd_pubkey_t authorized_withdrawer;
229 : ushort inflation_rewards_commission_bps;
230 : fd_pubkey_t inflation_rewards_collector;
231 : ushort block_revenue_commission_bps;
232 : fd_pubkey_t block_revenue_collector;
233 : };
234 : typedef struct fd_vote_init_v2 fd_vote_init_v2_t;
235 : #define FD_VOTE_INIT_V2_ALIGN alignof(fd_vote_init_v2_t)
236 :
237 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.0.0/vote-interface/src/state/vote_instruction_data.rs#L277 */
238 : struct fd_vote_authorize {
239 : uint discriminant;
240 : fd_voter_with_bls_args_t voter_with_bls;
241 : };
242 : typedef struct fd_vote_authorize fd_vote_authorize_t;
243 : #define FD_VOTE_AUTHORIZE_ALIGN alignof(fd_vote_authorize_t)
244 :
245 : enum {
246 : fd_vote_authorize_enum_voter = 0,
247 : fd_vote_authorize_enum_withdrawer = 1,
248 : fd_vote_authorize_enum_voter_with_bls = 2,
249 : };
250 :
251 : /**********************************************************************/
252 : /* Static asserts for wire-compatible struct layouts. */
253 : /* The custom vote deserializers use direct memcpy for these types, */
254 : /* relying on the in-memory layout matching the bincode wire format */
255 : /* on little-endian platforms. */
256 : /**********************************************************************/
257 :
258 : FD_STATIC_ASSERT( sizeof(fd_vote_prior_voter_t)==48UL, vote_prior_voter_layout );
259 : FD_STATIC_ASSERT( sizeof(fd_vote_epoch_credits_t)==24UL, vote_epoch_credits_layout );
260 : FD_STATIC_ASSERT( sizeof(fd_vote_block_timestamp_t)==16UL, vote_block_timestamp_layout );
261 : FD_STATIC_ASSERT( sizeof(fd_vote_init_t)==97UL, vote_init_layout );
262 :
263 : typedef struct fd_vote_authorized_voters_treap_private fd_vote_authorized_voters_treap_t;
264 :
265 : struct fd_vote_authorized_voters {
266 : fd_vote_authorized_voter_t * pool;
267 : fd_vote_authorized_voters_treap_t * treap;
268 : };
269 : typedef struct fd_vote_authorized_voters fd_vote_authorized_voters_t;
270 : #define FD_VOTE_AUTHORIZED_VOTERS_ALIGN alignof(fd_vote_authorized_voters_t)
271 :
272 : /**********************************************************************/
273 : /* Vote state structs (per version) */
274 : /**********************************************************************/
275 :
276 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/state/vote_state_1_14_11.rs#L16-L46 */
277 : struct fd_vote_state_1_14_11 {
278 : fd_pubkey_t node_pubkey;
279 : fd_pubkey_t authorized_withdrawer;
280 : uchar commission;
281 : fd_landed_vote_t * votes;
282 : ulong root_slot;
283 : uchar has_root_slot;
284 : fd_vote_authorized_voters_t authorized_voters;
285 : fd_vote_prior_voters_t prior_voters;
286 : fd_vote_epoch_credits_t * epoch_credits;
287 : fd_vote_block_timestamp_t last_timestamp;
288 : };
289 : typedef struct fd_vote_state_1_14_11 fd_vote_state_1_14_11_t;
290 :
291 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/state/vote_state_v3.rs#L30-L60 */
292 : struct fd_vote_state_v3 {
293 : fd_pubkey_t node_pubkey;
294 : fd_pubkey_t authorized_withdrawer;
295 : uchar commission;
296 : fd_landed_vote_t * votes;
297 : ulong root_slot;
298 : uchar has_root_slot;
299 : fd_vote_authorized_voters_t authorized_voters;
300 : fd_vote_prior_voters_t prior_voters;
301 : fd_vote_epoch_credits_t * epoch_credits;
302 : fd_vote_block_timestamp_t last_timestamp;
303 : };
304 : typedef struct fd_vote_state_v3 fd_vote_state_v3_t;
305 :
306 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.1.1/vote-interface/src/state/vote_state_v4.rs#L30-L71 */
307 : struct fd_vote_state_v4 {
308 : fd_pubkey_t node_pubkey;
309 : fd_pubkey_t authorized_withdrawer;
310 : fd_pubkey_t inflation_rewards_collector;
311 : fd_pubkey_t block_revenue_collector;
312 : ushort inflation_rewards_commission_bps;
313 : ushort block_revenue_commission_bps;
314 : ulong pending_delegator_rewards;
315 : uchar bls_pubkey_compressed[FD_BLS_PUBKEY_COMPRESSED_SZ];
316 : uchar has_bls_pubkey_compressed;
317 : fd_landed_vote_t * votes;
318 : ulong root_slot;
319 : uchar has_root_slot;
320 : fd_vote_authorized_voters_t authorized_voters;
321 : fd_vote_epoch_credits_t * epoch_credits;
322 : fd_vote_block_timestamp_t last_timestamp;
323 : };
324 : typedef struct fd_vote_state_v4 fd_vote_state_v4_t;
325 :
326 : /**********************************************************************/
327 : /* Versioned vote state (discriminated union) */
328 : /**********************************************************************/
329 :
330 : struct fd_vote_state_versioned {
331 : uint kind;
332 : union {
333 : fd_vote_state_1_14_11_t v1_14_11;
334 : fd_vote_state_v3_t v3;
335 : fd_vote_state_v4_t v4;
336 : };
337 :
338 : /* Memory for dynamic sub-structures */
339 : uchar landed_votes_mem [ FD_LANDED_VOTES_FOOTPRINT ] __attribute__((aligned(FD_LANDED_VOTES_ALIGN)));
340 : uchar epoch_credits_mem [ FD_EPOCH_CREDITS_FOOTPRINT ] __attribute__((aligned(FD_EPOCH_CREDITS_ALIGN)));
341 : uchar authorized_voters_pool_mem [ FD_AUTHORIZED_VOTERS_POOL_FOOTPRINT ] __attribute__((aligned(FD_AUTHORIZED_VOTERS_POOL_ALIGN)));
342 : uchar authorized_voters_treap_mem [ FD_AUTHORIZED_VOTERS_TREAP_FOOTPRINT] __attribute__((aligned(FD_AUTHORIZED_VOTERS_TREAP_ALIGN)));
343 : };
344 : typedef struct fd_vote_state_versioned fd_vote_state_versioned_t;
345 :
346 : enum {
347 : fd_vote_state_versioned_enum_uninitialized = 0,
348 : fd_vote_state_versioned_enum_v1_14_11 = 1,
349 : fd_vote_state_versioned_enum_v3 = 2,
350 : fd_vote_state_versioned_enum_v4 = 3,
351 : };
352 :
353 : /**********************************************************************/
354 : /* Vote instruction sub-types */
355 : /**********************************************************************/
356 :
357 : struct fd_lockout_offset {
358 : ulong offset;
359 : uchar confirmation_count;
360 : };
361 : typedef struct fd_lockout_offset fd_lockout_offset_t;
362 : #define FD_LOCKOUT_OFFSET_ALIGN alignof(fd_lockout_offset_t)
363 :
364 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_state/mod.rs#L133 */
365 : struct fd_vote {
366 : ulong * slots;
367 : fd_hash_t hash;
368 : long timestamp;
369 : uchar has_timestamp;
370 : uchar slots_mem[ FD_VOTE_INSTR_SLOTS_FOOTPRINT ] __attribute__((aligned(FD_VOTE_INSTR_SLOTS_ALIGN)));
371 : };
372 : typedef struct fd_vote fd_vote_t;
373 : #define FD_VOTE_ALIGN alignof(fd_vote_t)
374 :
375 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_instruction.rs#L37 */
376 : struct fd_vote_authorize_pubkey {
377 : fd_pubkey_t pubkey;
378 : fd_vote_authorize_t vote_authorize;
379 : };
380 : typedef struct fd_vote_authorize_pubkey fd_vote_authorize_pubkey_t;
381 : #define FD_VOTE_AUTHORIZE_PUBKEY_ALIGN alignof(fd_vote_authorize_pubkey_t)
382 :
383 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_instruction.rs#L78 */
384 : struct fd_vote_switch {
385 : fd_vote_t vote;
386 : fd_hash_t hash;
387 : };
388 : typedef struct fd_vote_switch fd_vote_switch_t;
389 : #define FD_VOTE_SWITCH_ALIGN alignof(fd_vote_switch_t)
390 :
391 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_state/mod.rs#L185 */
392 : struct fd_vote_state_update {
393 : fd_vote_lockout_t * lockouts;
394 : ulong root;
395 : uchar has_root;
396 : fd_hash_t hash;
397 : long timestamp;
398 : uchar has_timestamp;
399 : uchar lockouts_mem[ FD_VOTE_INSTR_UPDATE_LOCKOUTS_FOOTPRINT ] __attribute__((aligned(FD_VOTE_INSTR_UPDATE_LOCKOUTS_ALIGN)));
400 : };
401 : typedef struct fd_vote_state_update fd_vote_state_update_t;
402 : #define FD_VOTE_STATE_UPDATE_ALIGN alignof(fd_vote_state_update_t)
403 :
404 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_instruction.rs#L104 */
405 : struct fd_update_vote_state_switch {
406 : fd_vote_state_update_t vote_state_update;
407 : fd_hash_t hash;
408 : };
409 : typedef struct fd_update_vote_state_switch fd_update_vote_state_switch_t;
410 : #define FD_UPDATE_VOTE_STATE_SWITCH_ALIGN alignof(fd_update_vote_state_switch_t)
411 :
412 : struct fd_compact_vote_state_update {
413 : ulong root;
414 : ushort lockouts_len;
415 : fd_lockout_offset_t * lockouts;
416 : fd_hash_t hash;
417 : long timestamp;
418 : uchar has_timestamp;
419 : uchar lockouts_mem[ FD_VOTE_INSTR_LOCKOUT_OFFSET_FOOTPRINT ] __attribute__((aligned(FD_VOTE_INSTR_LOCKOUT_OFFSET_ALIGN)));
420 : };
421 : typedef struct fd_compact_vote_state_update fd_compact_vote_state_update_t;
422 : #define FD_COMPACT_VOTE_STATE_UPDATE_ALIGN alignof(fd_compact_vote_state_update_t)
423 :
424 : /* https://github.com/solana-labs/solana/blob/252438e28fbfb2c695fe1215171b83456e4b761c/programs/vote/src/vote_instruction.rs#L143 */
425 : struct fd_compact_vote_state_update_switch {
426 : fd_compact_vote_state_update_t compact_vote_state_update;
427 : fd_hash_t hash;
428 : };
429 : typedef struct fd_compact_vote_state_update_switch fd_compact_vote_state_update_switch_t;
430 : #define FD_COMPACT_VOTE_STATE_UPDATE_SWITCH_ALIGN alignof(fd_compact_vote_state_update_switch_t)
431 :
432 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_state/mod.rs#L185 */
433 : struct fd_tower_sync {
434 : fd_vote_lockout_t * lockouts;
435 : ulong lockouts_cnt;
436 : ulong root;
437 : uchar has_root;
438 : fd_hash_t hash;
439 : long timestamp;
440 : uchar has_timestamp;
441 : fd_hash_t block_id;
442 : uchar lockouts_mem[ FD_VOTE_INSTR_LOCKOUTS_FOOTPRINT ] __attribute__((aligned(FD_VOTE_INSTR_LOCKOUTS_ALIGN)));
443 : };
444 : typedef struct fd_tower_sync fd_tower_sync_t;
445 : #define FD_TOWER_SYNC_ALIGN alignof(fd_tower_sync_t)
446 :
447 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_instruction.rs#L104 */
448 : struct fd_tower_sync_switch {
449 : fd_tower_sync_t tower_sync;
450 : fd_hash_t hash;
451 : };
452 : typedef struct fd_tower_sync_switch fd_tower_sync_switch_t;
453 : #define FD_TOWER_SYNC_SWITCH_ALIGN alignof(fd_tower_sync_switch_t)
454 :
455 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_state/mod.rs#L244 */
456 : struct fd_vote_authorize_with_seed_args {
457 : fd_vote_authorize_t authorization_type;
458 : fd_pubkey_t current_authority_derived_key_owner;
459 : ulong current_authority_derived_key_seed_len;
460 : uchar current_authority_derived_key_seed[ FD_VOTE_INSTR_SEED_MAX ];
461 : fd_pubkey_t new_authority;
462 : };
463 : typedef struct fd_vote_authorize_with_seed_args fd_vote_authorize_with_seed_args_t;
464 : #define FD_VOTE_AUTHORIZE_WITH_SEED_ARGS_ALIGN alignof(fd_vote_authorize_with_seed_args_t)
465 :
466 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/programs/vote/src/vote_state/mod.rs#L252 */
467 : struct fd_vote_authorize_checked_with_seed_args {
468 : fd_vote_authorize_t authorization_type;
469 : fd_pubkey_t current_authority_derived_key_owner;
470 : ulong current_authority_derived_key_seed_len;
471 : uchar current_authority_derived_key_seed[ FD_VOTE_INSTR_SEED_MAX ];
472 : };
473 : typedef struct fd_vote_authorize_checked_with_seed_args fd_vote_authorize_checked_with_seed_args_t;
474 : #define FD_VOTE_AUTHORIZE_CHECKED_WITH_SEED_ARGS_ALIGN alignof(fd_vote_authorize_checked_with_seed_args_t)
475 :
476 : /* https://github.com/anza-xyz/solana-sdk/blob/vote-interface%40v5.0.0/vote-interface/src/instruction.rs#L28-L31 */
477 : struct fd_commission_kind {
478 : uint discriminant;
479 : };
480 : typedef struct fd_commission_kind fd_commission_kind_t;
481 : #define FD_COMMISSION_KIND_ALIGN alignof(fd_commission_kind_t)
482 :
483 : enum {
484 : fd_commission_kind_enum_inflation_rewards = 0,
485 : fd_commission_kind_enum_block_revenue = 1,
486 : };
487 :
488 : struct fd_update_commission_bps_args {
489 : ushort commission_bps;
490 : fd_commission_kind_t kind;
491 : };
492 : typedef struct fd_update_commission_bps_args fd_update_commission_bps_args_t;
493 : #define FD_UPDATE_COMMISSION_BPS_ARGS_ALIGN alignof(fd_update_commission_bps_args_t)
494 :
495 : struct fd_deposit_delegator_rewards_args {
496 : ulong deposit;
497 : };
498 : typedef struct fd_deposit_delegator_rewards_args fd_deposit_delegator_rewards_args_t;
499 : #define FD_DEPOSIT_DELEGATOR_REWARDS_ARGS_ALIGN alignof(fd_deposit_delegator_rewards_args_t)
500 :
501 : /**********************************************************************/
502 : /* Vote instruction (discriminated union) */
503 : /**********************************************************************/
504 :
505 : /* https://github.com/firedancer-io/solana/blob/53a4e5d6c58b2ffe89b09304e4437f8ca198dadd/programs/vote/src/vote_instruction.rs#L21 */
506 : struct fd_vote_instruction {
507 : uint discriminant;
508 : union {
509 : fd_vote_init_t initialize_account;
510 : fd_vote_authorize_pubkey_t authorize;
511 : fd_vote_t vote;
512 : ulong withdraw;
513 : uchar update_commission;
514 : fd_vote_switch_t vote_switch;
515 : fd_vote_authorize_t authorize_checked;
516 : fd_vote_state_update_t update_vote_state;
517 : fd_update_vote_state_switch_t update_vote_state_switch;
518 : fd_vote_authorize_with_seed_args_t authorize_with_seed;
519 : fd_vote_authorize_checked_with_seed_args_t authorize_checked_with_seed;
520 : fd_compact_vote_state_update_t compact_update_vote_state;
521 : fd_compact_vote_state_update_switch_t compact_update_vote_state_switch;
522 : fd_tower_sync_t tower_sync;
523 : fd_tower_sync_switch_t tower_sync_switch;
524 : fd_vote_init_v2_t initialize_account_v2;
525 : fd_commission_kind_t update_commission_collector;
526 : fd_update_commission_bps_args_t update_commission_bps;
527 : fd_deposit_delegator_rewards_args_t deposit_delegator_rewards;
528 : };
529 : };
530 : typedef struct fd_vote_instruction fd_vote_instruction_t;
531 :
532 : enum {
533 : fd_vote_instruction_enum_initialize_account = 0,
534 : fd_vote_instruction_enum_authorize = 1,
535 : fd_vote_instruction_enum_vote = 2,
536 : fd_vote_instruction_enum_withdraw = 3,
537 : fd_vote_instruction_enum_update_validator_identity = 4,
538 : fd_vote_instruction_enum_update_commission = 5,
539 : fd_vote_instruction_enum_vote_switch = 6,
540 : fd_vote_instruction_enum_authorize_checked = 7,
541 : fd_vote_instruction_enum_update_vote_state = 8,
542 : fd_vote_instruction_enum_update_vote_state_switch = 9,
543 : fd_vote_instruction_enum_authorize_with_seed = 10,
544 : fd_vote_instruction_enum_authorize_checked_with_seed = 11,
545 : fd_vote_instruction_enum_compact_update_vote_state = 12,
546 : fd_vote_instruction_enum_compact_update_vote_state_switch = 13,
547 : fd_vote_instruction_enum_tower_sync = 14,
548 : fd_vote_instruction_enum_tower_sync_switch = 15,
549 : fd_vote_instruction_enum_initialize_account_v2 = 16,
550 : fd_vote_instruction_enum_update_commission_collector = 17,
551 : fd_vote_instruction_enum_update_commission_bps = 18,
552 : fd_vote_instruction_enum_deposit_delegator_rewards = 19,
553 : };
554 :
555 : /**********************************************************************/
556 : /* Function declarations */
557 : /**********************************************************************/
558 :
559 : FD_PROTOTYPES_BEGIN
560 :
561 : /* Initializes a fd_vote_state_versioned_t and its dynamic members
562 : (votes deque, epoch_credits deque, authorized_voters pool,
563 : authorized_voters treap). Based on the discriminant, the appropriate
564 : version-specific struct is initialized.
565 :
566 : Returns a pointer to the initialized fd_vote_state_versioned_t, or
567 : NULL if mem is NULL or kind is an unsupported vote state version. */
568 : fd_vote_state_versioned_t *
569 : fd_vote_state_versioned_new( fd_vote_state_versioned_t * self,
570 : uint kind );
571 :
572 : /* Deserializes the vote state from a bincode-encoded buffer into the
573 : provided vote state versioned struct. On success returns self.
574 : Returns NULL on failure (malformed data). */
575 : fd_vote_state_versioned_t *
576 : fd_vote_state_versioned_deserialize( fd_vote_state_versioned_t * self,
577 : uchar const * payload,
578 : ulong payload_sz );
579 :
580 : /* Serializes the vote state into a bincode-encoded buffer. buf must
581 : have at least enough space for the encoded representation. Returns
582 : 0 on success, 1 on failure (e.g. buffer too small). */
583 : int
584 : fd_vote_state_versioned_serialize( fd_vote_state_versioned_t const * self,
585 : uchar * buf,
586 : ulong buf_sz );
587 :
588 : /* Computes the serialized size of self arithmetically without
589 : writing. Returns the size in bytes, or 0 if self has an unrecognized
590 : discriminant. */
591 : ulong
592 : fd_vote_state_versioned_serialized_size( fd_vote_state_versioned_t const * self );
593 :
594 : /**********************************************************************/
595 : /* Direct field accessors */
596 : /* Read fields directly from raw bincode-encoded vote account data */
597 : /* without full deserialization. */
598 : /**********************************************************************/
599 :
600 : /* Reads the node_pubkey directly from raw bincode-encoded vote
601 : account data. Returns 0 on success, 1 on error. */
602 : int
603 : fd_vote_account_node_pubkey( uchar const * data,
604 : ulong data_sz,
605 : fd_pubkey_t * out );
606 :
607 : /* Reads the compressed BLS voting pubkey directly from raw
608 : bincode-encoded v4 vote account data. Returns 0 on success, 1 on
609 : error (not v4, no bls pubkey set, or truncated). */
610 : int
611 : fd_vote_account_bls_pubkey( uchar const * data,
612 : ulong data_sz,
613 : uchar out[ static FD_BLS_PUBKEY_COMPRESSED_SZ ] );
614 :
615 : /* Returns the commission in basis points. If commission_rate_in_bps is
616 : set, returns the v4 commission rate as a raw basis points value.
617 : Otherwise, returns the v4 commission rate in basis points, rounded
618 : down to the nearest whole percentage. For v1_14_11/v3, returns the
619 : raw commission byte * 100.
620 :
621 : Returns 0 on success, 1 on error. */
622 : int
623 : fd_vote_account_commission_bps( uchar const * data,
624 : ulong data_sz,
625 : int commission_rate_in_bps,
626 : ushort * out );
627 :
628 : /* Reads the SIMD-0232 commission collectors directly from raw
629 : bincode-encoded vote account data. Pre-v4 states have no collector
630 : fields and return the defaults: vote_pubkey (inflation) and
631 : node_pubkey (block revenue). Returns 0 on success, 1 on error. */
632 : int
633 : fd_vote_account_collectors( uchar const * data,
634 : ulong data_sz,
635 : fd_pubkey_t const * vote_pubkey,
636 : fd_pubkey_t const * node_pubkey,
637 : fd_pubkey_t * inflation_rewards_collector_out,
638 : fd_pubkey_t * block_revenue_collector_out );
639 :
640 : /* Reads the last_timestamp directly from raw bincode-encoded vote
641 : account data. Returns 0 on success, 1 on error. */
642 : int
643 : fd_vote_account_last_timestamp( uchar const * data,
644 : ulong data_sz,
645 : fd_vote_block_timestamp_t * out );
646 :
647 : /* Returns 1 if the vote account is v4 with has_bls_pubkey_compressed
648 : set, 0 otherwise. */
649 : int
650 : fd_vote_account_is_v4_with_bls_pubkey( uchar const * data,
651 : ulong data_sz );
652 :
653 : /* Seeks through variable-length fields and returns a zero-copy pointer
654 : to the epoch_credits entries inside the raw buffer. *cnt is set to
655 : the number of entries. Returns NULL on error. */
656 : fd_vote_epoch_credits_t const *
657 : fd_vote_account_epoch_credits( uchar const * data,
658 : ulong data_sz,
659 : ulong * cnt );
660 :
661 : /* fd_vote_instruction_deserialize deserializes a vote instruction from
662 : bincode-encoded data into the provided instruction struct. Dynamic
663 : data (deques, arrays) is placed in memory embedded within the
664 : sub-structs of instruction.
665 :
666 : Only bytes up to FD_TXN_MTU_V0 are parsed, the rest are discarded,
667 : matching Agave's limited_deserialize(data, PACKET_DATA_SIZE).
668 :
669 : On success returns instruction. Returns NULL on failure (malformed
670 : data). */
671 :
672 : fd_vote_instruction_t *
673 : fd_vote_instruction_deserialize( fd_vote_instruction_t * instruction,
674 : uchar const * data,
675 : ulong data_sz );
676 :
677 : FD_PROTOTYPES_END
678 :
679 : #endif /* HEADER_fd_src_flamenco_runtime_program_vote_fd_vote_codec_h */
|