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