Line data Source code
1 : #include "fd_voter.h"
2 :
3 : #include <string.h>
4 :
5 : void *
6 0 : fd_voter_new( void * shmem ) {
7 0 : if( FD_UNLIKELY( !shmem ) ) {
8 0 : FD_LOG_WARNING( ( "NULL mem" ) );
9 0 : return NULL;
10 0 : }
11 :
12 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_voter_align() ) ) ) {
13 0 : FD_LOG_WARNING( ( "misaligned mem" ) );
14 0 : return NULL;
15 0 : }
16 :
17 0 : ulong footprint = fd_voter_footprint();
18 0 : if( FD_UNLIKELY( !footprint ) ) {
19 0 : FD_LOG_WARNING( ( "bad mem" ) );
20 0 : return NULL;
21 0 : }
22 :
23 0 : return shmem;
24 0 : }
25 :
26 : fd_voter_t *
27 0 : fd_voter_join( void * shvoter ) {
28 :
29 0 : if( FD_UNLIKELY( !shvoter ) ) {
30 0 : FD_LOG_WARNING( ( "NULL voter" ) );
31 0 : return NULL;
32 0 : }
33 :
34 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shvoter, fd_voter_align() ) ) ) {
35 0 : FD_LOG_WARNING( ( "misaligned voter" ) );
36 0 : return NULL;
37 0 : }
38 :
39 0 : return (fd_voter_t *)shvoter;
40 0 : }
41 :
42 : void *
43 0 : fd_voter_leave( fd_voter_t const * voter ) {
44 :
45 0 : if( FD_UNLIKELY( !voter ) ) {
46 0 : FD_LOG_WARNING( ( "NULL voter" ) );
47 0 : return NULL;
48 0 : }
49 :
50 0 : return (void *)voter;
51 0 : }
52 :
53 : void *
54 0 : fd_voter_delete( void * voter ) {
55 :
56 0 : if( FD_UNLIKELY( !voter ) ) {
57 0 : FD_LOG_WARNING( ( "NULL voter" ) );
58 0 : return NULL;
59 0 : }
60 :
61 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)voter, fd_voter_align() ) ) ) {
62 0 : FD_LOG_WARNING( ( "misaligned voter" ) );
63 0 : return NULL;
64 0 : }
65 :
66 0 : return voter;
67 0 : }
68 :
69 : ulong
70 : fd_voter_txn_generate( fd_voter_t const * voter,
71 : fd_compact_vote_state_update_t const * tower_sync,
72 : fd_hash_t const * recent_blockhash,
73 : uchar txn_meta_out[static FD_TXN_MAX_SZ],
74 0 : uchar txn_out[static FD_TXN_MTU] ) {
75 0 : FD_LOG_NOTICE(( "[%s]: vote acc addr %s", __func__, FD_BASE58_ENC_32_ALLOCA( &voter->vote_acc_addr ) ));
76 :
77 0 : int same_addr = !memcmp( &voter->validator_identity,
78 0 : &voter->vote_authority,
79 0 : sizeof( fd_pubkey_t ) );
80 0 : if( FD_LIKELY( same_addr ) ) {
81 :
82 : /* 0: validator identity
83 : 1: vote account address
84 : 2: vote program */
85 :
86 0 : fd_txn_accounts_t accts;
87 0 : accts.signature_cnt = 1;
88 0 : accts.readonly_signed_cnt = 0;
89 0 : accts.readonly_unsigned_cnt = 1;
90 0 : accts.acct_cnt = 3;
91 0 : accts.signers_w = &voter->validator_identity;
92 0 : accts.signers_r = NULL;
93 0 : accts.non_signers_w = &voter->vote_acc_addr;
94 0 : accts.non_signers_r = &fd_solana_vote_program_id;
95 0 : FD_TEST( fd_txn_base_generate( txn_meta_out,
96 0 : txn_out,
97 0 : accts.signature_cnt,
98 0 : &accts,
99 0 : recent_blockhash->uc ) );
100 0 : } else {
101 :
102 : /* 0: validator identity
103 : 1: vote authority
104 : 2: vote account address
105 : 3: vote program */
106 :
107 0 : fd_txn_accounts_t accts;
108 0 : accts.signature_cnt = 2;
109 0 : accts.readonly_signed_cnt = 1;
110 0 : accts.readonly_unsigned_cnt = 1;
111 0 : accts.acct_cnt = 4;
112 0 : accts.signers_w = &voter->validator_identity;
113 0 : accts.signers_r = &voter->vote_authority;
114 0 : accts.non_signers_w = &voter->vote_acc_addr;
115 0 : accts.non_signers_r = &fd_solana_vote_program_id;
116 0 : FD_TEST( fd_txn_base_generate( txn_meta_out,
117 0 : txn_out,
118 0 : accts.signature_cnt,
119 0 : &accts,
120 0 : recent_blockhash->uc ) );
121 0 : }
122 :
123 : /* Add the vote instruction to the transaction. */
124 :
125 0 : fd_vote_instruction_t vote_ix;
126 0 : uchar vote_ix_buf[FD_TXN_MTU];
127 0 : vote_ix.discriminant = fd_vote_instruction_enum_compact_update_vote_state;
128 0 : vote_ix.inner.compact_update_vote_state = *tower_sync;
129 0 : fd_bincode_encode_ctx_t encode = { .data = vote_ix_buf, .dataend = ( vote_ix_buf + FD_TXN_MTU ) };
130 0 : fd_vote_instruction_encode( &vote_ix, &encode );
131 0 : ushort vote_ix_size = (ushort)fd_vote_instruction_size( &vote_ix );
132 :
133 0 : ulong txn_sz;
134 0 : if( FD_LIKELY( same_addr ) ) {
135 0 : uchar ix_accs[2];
136 0 : ix_accs[0] = 1; /* vote account address */
137 0 : ix_accs[1] = 0; /* vote authority */
138 0 : uchar program_id = 2; /* vote program */
139 :
140 0 : txn_sz = fd_txn_add_instr( txn_meta_out,
141 0 : txn_out,
142 0 : program_id,
143 0 : ix_accs,
144 0 : 2,
145 0 : vote_ix_buf,
146 0 : vote_ix_size );
147 0 : } else {
148 0 : uchar ix_accs[2];
149 0 : ix_accs[0] = 2; /* vote account address */
150 0 : ix_accs[1] = 1; /* vote authority */
151 0 : uchar program_id = 3; /* vote program */
152 :
153 0 : txn_sz = fd_txn_add_instr( txn_meta_out,
154 0 : txn_out,
155 0 : program_id,
156 0 : ix_accs,
157 0 : 2,
158 0 : vote_ix_buf,
159 0 : vote_ix_size );
160 0 : }
161 0 : return txn_sz;
162 0 : }
163 :
164 : // int
165 : // fd_voter_txn_parse( uchar txn[static FD_TXN_MTU], ulong txn_sz, fd_voter_vote_t * voter_votes_out
166 : // ) {
167 : // uchar out_buf[FD_TXN_MAX_SZ];
168 : // fd_txn_t * parsed_txn = (fd_txn_t *)fd_type_pun( out_buf );
169 : // ulong out_sz = fd_txn_parse( txn, txn_sz, out_buf, NULL );
170 : // FD_TEST( out_sz );
171 : // FD_TEST( parsed_txn );
172 : // FD_TEST( parsed_txn->ix_cnt == 1 );
173 :
174 : // uchar program_id = parsed_txn->ix[0].program_id;
175 : // uchar * program_account_addr = txn + parsed_txn->acct_addr_off + FD_TXN_ACCT_ADDR_SZ *
176 : // program_id;
177 :
178 : // if( FD_UNLIKELY( memcmp( program_account_addr,
179 : // fd_solana_vote_program_id.key,
180 : // sizeof( fd_pubkey_t ) ) ) ) {
181 : // FD_LOG_WARNING(( "[fd_voter_txn_parse] txn program %s was not vote program id %s",
182 : // FD_BASE58_ENC_32_ALLOCA( program_account_addr ),
183 : // FD_BASE58_ENC_32_ALLOCA( fd_solana_vote_program_id.key ) ));
184 : // return -1;
185 : // }
186 :
187 : // ushort ix_data_sz = parsed_txn->ix[0].data_sz;
188 : // uchar * ix_data = txn + parsed_txn->ix[0].data_off;
189 : // fd_valloc_t valloc = fd_scratch_virtual();
190 : // fd_bincode_decode_ctx_t decode = { .data = ix_data,
191 : // .dataend = ix_data + ix_data_sz,
192 : // .valloc = valloc };
193 :
194 : // fd_vote_instruction_t * vote_instruction = fd_valloc_malloc( valloc,
195 : // alignof( fd_vote_instruction_t ),
196 : // sizeof( fd_vote_instruction_t ) );
197 : // int rc = fd_vote_instruction_decode( vote_instruction, &decode );
198 : // if( FD_UNLIKELY( rc != FD_BINCODE_SUCCESS ) ) {
199 : // FD_LOG_WARNING( ( "fd_vote_txn_parse: fail at decoding vote instruction" ) );
200 : // return -1;
201 : // }
202 :
203 : // /* https://github.com/anza-xyz/agave/blob/v2.0.1/vote/src/vote_parser.rs#L47-L78 */
204 :
205 : // switch ( vote_instruction->discriminant ) {
206 : // case fd_vote_instruction_enum_vote: {
207 : // for( deq_ulong_iter_t iter = deq_ulong_iter_init( vote_instruction->inner.vote.slots );
208 : // !deq_ulong_iter_done( vote_instruction->inner.vote.slots, iter );
209 : // iter = deq_ulong_iter_next( vote_instruction->inner.vote.slots, iter ) ) {
210 : // ulong slot = deq_ulong_iter_ele( vote_instruction->inner.vote.slots, iter );
211 : // fd_voter_votes_push_tail( vote_instruction->inner.vote.slots, slot);
212 : // }
213 : // break;
214 : // }
215 : // case fd_vote_instruction_enum_vote_switch: {
216 : // break;
217 : // }
218 : // case fd_vote_instruction_enum_update_vote_state: {
219 : // break;
220 : // }
221 : // case fd_vote_instruction_enum_update_vote_state_switch: {
222 : // break;
223 : // }
224 : // case fd_vote_instruction_enum_compact_update_vote_state: {
225 : // break;
226 : // }
227 : // case fd_vote_instruction_enum_compact_update_vote_state_switch: {
228 : // break;
229 : // }
230 : // case fd_vote_instruction_enum_voter_sync: {
231 : // break;
232 : // }
233 : // case fd_vote_instruction_enum_voter_sync_switch: {
234 : // break;
235 : // }
236 : // };
237 :
238 : // for (ulong i = 0; i < 8; i++) {
239 : // if (vote_instruction->discriminant == discriminants[i]) {
240 : // return vote_instruction;
241 : // }
242 : // }
243 : // return NULL;
244 :
245 : // if( FD_UNLIKELY( vote_instruction->discriminant !=
246 : // discriminants ||
247 : // vote_instruction->discriminant != fd_vote_instruction_enum_voter_sync ) ) {
248 : // FD_LOG_WARNING( ( "fd_vote_txn_parse: not compact_update_vote_state instruction" ) );
249 : // return NULL;
250 : // }
251 :
252 : // return vote_instruction;
253 : // }
|