Line data Source code
1 : #include "fd_bundle_crank.h"
2 : #include "../../flamenco/runtime/fd_pubkey_utils.h"
3 :
4 : FD_STATIC_ASSERT( sizeof(fd_bundle_crank_tip_payment_config_t)==89UL, config_struct );
5 :
6 : #define MEMO_PROGRAM_ID 0x05U,0x4aU,0x53U,0x5aU,0x99U,0x29U,0x21U,0x06U,0x4dU,0x24U,0xe8U,0x71U,0x60U,0xdaU,0x38U,0x7cU, \
7 : 0x7cU,0x35U,0xb5U,0xddU,0xbcU,0x92U,0xbbU,0x81U,0xe4U,0x1fU,0xa8U,0x40U,0x41U,0x05U,0x44U,0x8dU
8 :
9 : static const fd_bundle_crank_3_t fd_bundle_crank_3_base[1] = {{
10 :
11 : .sig_cnt = 1,
12 : ._sig_cnt = 1,
13 : .ro_signed_cnt = 0,
14 : .ro_unsigned_cnt = 6,
15 : .acct_addr_cnt = 21,
16 :
17 : .system_program = { SYS_PROG_ID },
18 : .compute_budget_program = { COMPUTE_BUDGET_PROG_ID },
19 : .memo_program = { MEMO_PROGRAM_ID },
20 :
21 : .instr_cnt = 5,
22 : .compute_budget_instruction = {
23 : .prog_id = 15,
24 : .acct_cnt = 0,
25 : .data_sz = 5,
26 : .set_cu_limit = 2,
27 : .cus = 103000U
28 : },
29 :
30 : .init_tip_distribution_acct = {
31 : .prog_id = 19,
32 : .acct_cnt = 5,
33 : .acct_idx = { 9, 13, 17, 0, 18 },
34 : .data_sz = 43,
35 : .ix_discriminator = { FD_BUNDLE_CRANK_DISC_INIT_TIP_DISTR },
36 : },
37 :
38 : .change_tip_receiver = {
39 : .prog_id = 16,
40 : .acct_cnt = 13,
41 : .acct_idx = { 10, 11, 13, 12, 1, 2, 3, 4, 5, 6, 7, 8, 0 },
42 : .data_sz = 8,
43 : .ix_discriminator = { FD_BUNDLE_CRANK_DISC_CHANGE_TIP_RCV }
44 : },
45 :
46 : .change_block_builder = {
47 : .prog_id = 16,
48 : .acct_cnt = 13,
49 : .acct_idx = { 10, 13, 12, 14, 1, 2, 3, 4, 5, 6, 7, 8, 0},
50 : .data_sz = 16,
51 : .ix_discriminator = { FD_BUNDLE_CRANK_DISC_CHANGE_BLK_BLD },
52 : },
53 :
54 : .memo = {
55 : .prog_id = 20,
56 : .acct_cnt = 0,
57 : .data_sz = 3
58 : },
59 :
60 : /* Account addresses that depend on the network: */
61 : .tip_payment_accounts = {{ 0 }},
62 : .tip_distribution_program_config = { 0 },
63 : .tip_payment_program_config = { 0 },
64 : .tip_distribution_program = { 0 },
65 : .tip_payment_program = { 0 },
66 :
67 : /* Fields that depend on the validator configuration: */
68 : .authorized_voter = { 0 },
69 : .validator_vote_account = { 0 },
70 : .memo.memo = { 0 },
71 : .init_tip_distribution_acct.merkle_root_upload_authority = { 0 },
72 : .init_tip_distribution_acct.commission_bps = 0,
73 : .init_tip_distribution_acct.bump = 0,
74 :
75 : /* Fields that vary each time: */
76 : .old_tip_receiver = { 0 },
77 : .old_block_builder = { 0 },
78 : .new_tip_receiver = { 0 },
79 : .new_block_builder = { 0 },
80 : .change_block_builder.block_builder_commission_pct = 0UL
81 : }};
82 :
83 : static const fd_bundle_crank_2_t fd_bundle_crank_2_base[1] = {{
84 :
85 : .sig_cnt = 1,
86 : ._sig_cnt = 1,
87 : .ro_signed_cnt = 0,
88 : .ro_unsigned_cnt = 3,
89 : .acct_addr_cnt = 18,
90 :
91 : .compute_budget_program = { COMPUTE_BUDGET_PROG_ID },
92 : .memo_program = { MEMO_PROGRAM_ID },
93 :
94 : .instr_cnt = 4,
95 : .compute_budget_instruction = {
96 : .prog_id = 15,
97 : .acct_cnt = 0,
98 : .data_sz = 5,
99 : .set_cu_limit = 2,
100 : .cus = 83000U
101 : },
102 :
103 : .change_tip_receiver = {
104 : .prog_id = 16,
105 : .acct_cnt = 13,
106 : .acct_idx = { 10, 11, 13, 12, 1, 2, 3, 4, 5, 6, 7, 8, 0 },
107 : .data_sz = 8,
108 : .ix_discriminator = { FD_BUNDLE_CRANK_DISC_CHANGE_TIP_RCV }
109 : },
110 :
111 : .change_block_builder = {
112 : .prog_id = 16,
113 : .acct_cnt = 13,
114 : .acct_idx = { 10, 13, 12, 14, 1, 2, 3, 4, 5, 6, 7, 8, 0},
115 : .data_sz = 16,
116 : .ix_discriminator = { FD_BUNDLE_CRANK_DISC_CHANGE_BLK_BLD },
117 : },
118 :
119 : .memo = {
120 : .prog_id = 17,
121 : .acct_cnt = 0,
122 : .data_sz = 3
123 : },
124 :
125 : /* Account addresses that depend on the network: */
126 : .tip_payment_accounts = {{ 0 }},
127 : .tip_distribution_program_config = { 0 },
128 : .tip_payment_program_config = { 0 },
129 : .tip_payment_program = { 0 },
130 :
131 : /* Fields that depend on the validator configuration: */
132 : .authorized_voter = { 0 },
133 : .memo.memo = { 0 },
134 :
135 : /* Fields that vary each time: */
136 : .old_tip_receiver = { 0 },
137 : .old_block_builder = { 0 },
138 : .new_tip_receiver = { 0 },
139 : .new_block_builder = { 0 },
140 : .change_block_builder.block_builder_commission_pct = 0UL
141 : }};
142 :
143 : static const fd_acct_addr_t null_addr = { 0 };
144 :
145 : #define MAP_NAME pidx_map
146 306 : #define MAP_T fd_bundle_crank_gen_pidx_t
147 1068 : #define MAP_KEY_T fd_acct_addr_t
148 : #define MAP_MEMOIZE 0
149 : #define MAP_QUERY_OPT 2 /* low hit rate */
150 1404 : #define MAP_LG_SLOT_CNT 5 /* 18 entries, space for 32 */
151 399 : #define MAP_KEY_NULL null_addr
152 : #if FD_HAS_AVX
153 1068 : # define MAP_KEY_INVAL(k) _mm256_testz_si256( wb_ldu( (k).b ), wb_ldu( (k).b ) )
154 : #else
155 : # define MAP_KEY_INVAL(k) MAP_KEY_EQUAL(k, null_addr)
156 : #endif
157 660 : #define MAP_KEY_EQUAL(k0,k1) (!memcmp((k0).b,(k1).b, FD_TXN_ACCT_ADDR_SZ))
158 : #define MAP_KEY_EQUAL_IS_SLOW 1
159 : #define MAP_MEMOIZE 0
160 336 : #define MAP_KEY_HASH(key) ((uint)fd_ulong_hash( fd_ulong_load_8( (key).b ) ))
161 :
162 : #include "../../util/tmpl/fd_map.c"
163 :
164 :
165 540 : #define EXPAND_ARR8(arr, i) arr[(i)], arr[(i)+1], arr[(i)+2], arr[(i)+3], arr[(i)+4], arr[(i)+5], arr[(i)+6], arr[(i)+7],
166 135 : #define EXPAND_ARR32(arr, i) EXPAND_ARR8(arr, (i)) EXPAND_ARR8(arr, (i)+8) EXPAND_ARR8(arr, (i)+16) EXPAND_ARR8(arr, (i)+24)
167 :
168 :
169 :
170 : fd_bundle_crank_gen_t *
171 : fd_bundle_crank_gen_init( void * mem,
172 : fd_acct_addr_t const * tip_distribution_program_addr,
173 : fd_acct_addr_t const * tip_payment_program_addr,
174 : fd_acct_addr_t const * validator_vote_acct_addr,
175 : fd_acct_addr_t const * merkle_root_authority_addr,
176 : char const * scheduler_mode,
177 9 : ulong commission_bps ) {
178 9 : fd_bundle_crank_gen_t * g = (fd_bundle_crank_gen_t *)mem;
179 9 : memcpy( g->crank3, fd_bundle_crank_3_base, sizeof(fd_bundle_crank_3_base) );
180 9 : memcpy( g->crank2, fd_bundle_crank_2_base, sizeof(fd_bundle_crank_2_base) );
181 :
182 9 : g->crank3->init_tip_distribution_acct.commission_bps = (ushort)commission_bps;
183 9 : memcpy( g->crank3->tip_distribution_program, tip_distribution_program_addr, 32UL );
184 9 : memcpy( g->crank3->tip_payment_program, tip_payment_program_addr, 32UL );
185 9 : memcpy( g->crank3->validator_vote_account, validator_vote_acct_addr, 32UL );
186 9 : memcpy( g->crank3->init_tip_distribution_acct.merkle_root_upload_authority, merkle_root_authority_addr, 32UL );
187 :
188 : /* What we want here is just an strncpy, but the compiler makes it
189 : really hard to use strncpy to make a deliberately potentially
190 : unterminated string. Rather than fight the compiler, we basically
191 : hand-do it. */
192 9 : int is_nul;
193 9 : is_nul = 0 || (!scheduler_mode[0]); g->crank3->memo.memo[0] = is_nul ? '\0' : scheduler_mode[0];
194 9 : is_nul = is_nul || (!scheduler_mode[1]); g->crank3->memo.memo[1] = is_nul ? '\0' : scheduler_mode[1];
195 9 : is_nul = is_nul || (!scheduler_mode[2]); g->crank3->memo.memo[2] = is_nul ? '\0' : scheduler_mode[2];
196 :
197 9 : uint cerr[1];
198 9 : do {
199 9 : char seed[13] = "TIP_ACCOUNT_0"; /* Not NUL terminated */
200 9 : uchar * seed_ptr[1] = { (uchar *)seed };
201 9 : ulong seed_len = 13;
202 81 : for( ulong i=0UL; i<8UL; i++ ) {
203 72 : seed[12] = (char)((ulong)'0' + i);
204 72 : uchar out_bump[1];
205 72 : FD_TEST( FD_PUBKEY_SUCCESS==fd_pubkey_find_program_address( (fd_pubkey_t const *)tip_payment_program_addr,
206 72 : 1UL, seed_ptr, &seed_len,
207 72 : (fd_pubkey_t *)g->crank3->tip_payment_accounts[i], out_bump, cerr ) );
208 72 : }
209 9 : } while( 0 );
210 :
211 9 : do {
212 9 : char seed[14] = "CONFIG_ACCOUNT"; /* Not NUL terminated */
213 9 : ulong seed_len = 14;
214 9 : uchar out_bump[1];
215 9 : uchar * seed_ptr[1] = { (uchar *)seed };
216 9 : FD_TEST( FD_PUBKEY_SUCCESS==fd_pubkey_find_program_address( (fd_pubkey_t const *)tip_payment_program_addr,
217 9 : 1UL, seed_ptr, &seed_len,
218 9 : (fd_pubkey_t *)g->crank3->tip_payment_program_config, out_bump, cerr ) );
219 : /* Same seed used for tip distribution config account too */
220 9 : FD_TEST( FD_PUBKEY_SUCCESS==fd_pubkey_find_program_address( (fd_pubkey_t const *)tip_distribution_program_addr,
221 9 : 1UL, seed_ptr, &seed_len,
222 9 : (fd_pubkey_t *)g->crank3->tip_distribution_program_config, out_bump, cerr ) );
223 9 : } while( 0 );
224 :
225 : /* Populate crank2 from crank3 */
226 9 : memcpy( g->crank2->tip_payment_accounts, g->crank3->tip_payment_accounts, 8UL*32UL );
227 9 : memcpy( g->crank2->tip_distribution_program_config, g->crank3->tip_distribution_program_config, 32UL );
228 9 : memcpy( g->crank2->tip_payment_program_config, g->crank3->tip_payment_program_config, 32UL );
229 9 : memcpy( g->crank2->tip_payment_program, g->crank3->tip_payment_program, 32UL );
230 9 : memcpy( g->crank2->memo.memo, g->crank3->memo.memo, 3UL );
231 :
232 9 : FD_TEST( sizeof(g->txn3)==fd_txn_parse( (uchar const *)g->crank3, sizeof(g->crank3), g->txn3, NULL ) );
233 9 : FD_TEST( sizeof(g->txn2)==fd_txn_parse( (uchar const *)g->crank2, sizeof(g->crank2), g->txn2, NULL ) );
234 :
235 9 : pidx_map_new( g->map );
236 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[0], 0 ) }} )->idx= 1UL;
237 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[1], 0 ) }} )->idx= 2UL;
238 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[2], 0 ) }} )->idx= 3UL;
239 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[3], 0 ) }} )->idx= 4UL;
240 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[4], 0 ) }} )->idx= 5UL;
241 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[5], 0 ) }} )->idx= 6UL;
242 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[6], 0 ) }} )->idx= 7UL;
243 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_accounts[7], 0 ) }} )->idx= 8UL;
244 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_distribution_program_config, 0 ) }} )->idx= 9UL;
245 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_program_config, 0 ) }} )->idx=10UL;
246 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->compute_budget_program, 0 ) }} )->idx=15UL;
247 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_payment_program, 0 ) }} )->idx=16UL;
248 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->validator_vote_account, 0 ) }} )->idx=17UL;
249 9 : pidx_map_insert( g->map, (fd_acct_addr_t){{ EXPAND_ARR32( g->crank3->tip_distribution_program, 0 ) }} )->idx=19UL;
250 :
251 9 : g->configured_epoch = ULONG_MAX;
252 9 : return g;
253 9 : }
254 :
255 :
256 : static inline void
257 : fd_bundle_crank_update_epoch( fd_bundle_crank_gen_t * g,
258 9 : ulong epoch ) {
259 9 : struct __attribute__((packed)) {
260 9 : char tip_distr_acct[24];
261 9 : uchar vote_pubkey [32];
262 9 : ulong epoch;
263 9 : } seeds[1] = {{
264 9 : .tip_distr_acct = "TIP_DISTRIBUTION_ACCOUNT",
265 9 : .vote_pubkey = { EXPAND_ARR32( g->crank3->validator_vote_account, 0 ) },
266 9 : .epoch = epoch
267 9 : }};
268 9 : FD_STATIC_ASSERT( sizeof(seeds)==24UL+32UL+8UL, seed_struct );
269 9 : ulong seed_len = sizeof(seeds);
270 9 : uint custom_err[1];
271 :
272 9 : uchar * _seeds[1] = { (uchar *)seeds };
273 :
274 9 : FD_TEST( FD_PUBKEY_SUCCESS==fd_pubkey_find_program_address( (fd_pubkey_t const *)g->crank3->tip_distribution_program,
275 9 : 1UL, _seeds, &seed_len,
276 9 : (fd_pubkey_t *)g->crank3->new_tip_receiver,
277 9 : &(g->crank3->init_tip_distribution_acct.bump), custom_err ) );
278 9 : memcpy( g->crank2->new_tip_receiver, g->crank3->new_tip_receiver, 32UL );
279 9 : g->configured_epoch = epoch;
280 :
281 9 : }
282 :
283 : void
284 : fd_bundle_crank_get_addresses( fd_bundle_crank_gen_t * gen,
285 : ulong epoch,
286 : fd_acct_addr_t * out_tip_payment_config,
287 3 : fd_acct_addr_t * out_tip_receiver ) {
288 3 : if( FD_UNLIKELY( epoch!=gen->configured_epoch ) ) fd_bundle_crank_update_epoch( gen, epoch );
289 3 : memcpy( out_tip_payment_config, gen->crank3->tip_payment_program_config, 32UL );
290 3 : memcpy( out_tip_receiver, gen->crank3->new_tip_receiver, 32UL );
291 3 : }
292 :
293 : ulong
294 : fd_bundle_crank_generate( fd_bundle_crank_gen_t * gen,
295 : fd_bundle_crank_tip_payment_config_t const * old_tip_payment_config,
296 : fd_acct_addr_t const * new_block_builder,
297 : fd_acct_addr_t const * identity,
298 : fd_acct_addr_t const * tip_receiver_owner,
299 : ulong epoch,
300 : ulong block_builder_commission,
301 : uchar * out_payload,
302 36 : fd_txn_t * out_txn ) {
303 :
304 36 : if( FD_UNLIKELY( epoch!=gen->configured_epoch ) ) fd_bundle_crank_update_epoch( gen, epoch );
305 :
306 36 : if( FD_UNLIKELY( old_tip_payment_config->discriminator != 0x82ccfa1ee0aa0c9bUL ) ) {
307 0 : FD_LOG_WARNING(( "Found unexpected tip payment config account discriminator %lx. Refusing to crank bundles.",
308 0 : old_tip_payment_config->discriminator ));
309 0 : return ULONG_MAX;
310 0 : }
311 :
312 36 : int swap3 = !fd_memeq( tip_receiver_owner, gen->crank3->tip_distribution_program, sizeof(fd_acct_addr_t) );
313 :
314 36 : if( FD_LIKELY( fd_memeq( old_tip_payment_config->tip_receiver, gen->crank3->new_tip_receiver, 32UL ) &&
315 36 : fd_memeq( old_tip_payment_config->block_builder, new_block_builder, 32UL ) &&
316 36 : !swap3 &&
317 36 : old_tip_payment_config->commission_pct==block_builder_commission ) ) {
318 : /* Everything configured properly! */
319 6 : return 0UL;
320 6 : }
321 :
322 :
323 30 : if( FD_UNLIKELY( swap3 ) ) {
324 3 : memcpy( gen->crank3->authorized_voter, identity, 32UL );
325 3 : memcpy( gen->crank3->new_block_builder, new_block_builder, 32UL );
326 3 : memcpy( gen->crank3->old_tip_receiver, old_tip_payment_config->tip_receiver, 32UL );
327 3 : memcpy( gen->crank3->old_block_builder, old_tip_payment_config->block_builder, 32UL );
328 3 : gen->crank3->change_block_builder.block_builder_commission_pct = block_builder_commission;
329 27 : } else {
330 27 : memcpy( gen->crank2->authorized_voter, identity, 32UL );
331 27 : memcpy( gen->crank2->new_block_builder, new_block_builder, 32UL );
332 27 : memcpy( gen->crank2->old_tip_receiver, old_tip_payment_config->tip_receiver, 32UL );
333 27 : memcpy( gen->crank2->old_block_builder, old_tip_payment_config->block_builder, 32UL );
334 27 : gen->crank2->change_block_builder.block_builder_commission_pct = block_builder_commission;
335 27 : }
336 :
337 : /* If it weren't for the fact that the old tip payment config is
338 : essentially attacker-controlled, we'd be golden. However, someone
339 : trying to grief us can e.g. set the old block builder to the tip
340 : payment program, and if we're not careful, we'll create a
341 : transaction with a duplicate account. We trust identity, new
342 : tip_receiver, and new_block_builder well enough though. Note that
343 : it's not possible for either attacker-controlled address to be the
344 : system program, because the account must be writable, and write
345 : locks to the system program get demoted. */
346 30 : fd_bundle_crank_gen_pidx_t * identity_pidx = pidx_map_insert( gen->map, *(fd_acct_addr_t *)identity );
347 30 : if( FD_UNLIKELY( !identity_pidx ) ) {
348 0 : FD_LOG_WARNING(( "Indentity was already in map. Refusing to crank bundles." ));
349 0 : return ULONG_MAX;
350 0 : }
351 30 : identity_pidx->idx = 0UL;
352 :
353 30 : fd_bundle_crank_gen_pidx_t * new_tr_pidx = pidx_map_insert( gen->map, *(fd_acct_addr_t *)gen->crank3->new_tip_receiver );
354 30 : if( FD_UNLIKELY( !new_tr_pidx ) ) {
355 0 : pidx_map_remove( gen->map, identity_pidx );
356 0 : FD_LOG_WARNING(( "New block builder was already in map. Refusing to crank bundles." ));
357 0 : return ULONG_MAX;
358 0 : }
359 30 : new_tr_pidx->idx = 13UL;
360 :
361 30 : fd_bundle_crank_gen_pidx_t * new_bb_pidx = pidx_map_insert( gen->map, *(fd_acct_addr_t *)new_block_builder );
362 30 : if( FD_UNLIKELY( !new_bb_pidx ) ) {
363 0 : pidx_map_remove( gen->map, new_tr_pidx );
364 0 : pidx_map_remove( gen->map, identity_pidx );
365 0 : FD_LOG_WARNING(( "New block builder was already in map. Refusing to crank bundles." ));
366 0 : return ULONG_MAX;
367 0 : }
368 30 : new_bb_pidx->idx = 14UL;
369 :
370 30 : int inserted1 = 0;
371 30 : int inserted2 = 0;
372 30 : fd_bundle_crank_gen_pidx_t dummy1[1] = {{ .idx = 11UL }};
373 30 : fd_bundle_crank_gen_pidx_t dummy2[1] = {{ .idx = 12UL }};
374 :
375 30 : fd_bundle_crank_gen_pidx_t * old_tr_pidx = pidx_map_query( gen->map, *old_tip_payment_config->tip_receiver, NULL );
376 30 : if( FD_LIKELY( NULL==old_tr_pidx ) ) {
377 15 : old_tr_pidx = pidx_map_insert( gen->map, *old_tip_payment_config->tip_receiver );
378 15 : old_tr_pidx->idx = 11UL;
379 15 : inserted1 = 1;
380 15 : } else if( FD_UNLIKELY( !swap3 && old_tr_pidx->idx>16UL ) ) {
381 0 : old_tr_pidx = dummy1;
382 15 : } else {
383 : /* perturb the old tip receiver pubkey so that it's not a duplicate,
384 : then don't use it. */
385 15 : gen->crank3->old_tip_receiver[0]++;
386 15 : gen->crank2->old_tip_receiver[0]++;
387 15 : }
388 :
389 30 : fd_bundle_crank_gen_pidx_t * old_bb_pidx = pidx_map_query( gen->map, *old_tip_payment_config->block_builder, NULL );
390 30 : if( FD_UNLIKELY( NULL==old_bb_pidx ) ) {
391 6 : old_bb_pidx = pidx_map_insert( gen->map, *old_tip_payment_config->block_builder );
392 6 : old_bb_pidx->idx = 12UL;
393 6 : inserted2 = 1;
394 24 : } else if( FD_UNLIKELY( !swap3 && old_bb_pidx->idx>16UL ) ) {
395 0 : old_bb_pidx = dummy2;
396 24 : } else {
397 : /* perturb, but do it differently so it can't conflict with the
398 : old tip receiver if they're both the same. */
399 24 : gen->crank3->old_block_builder[0]--;
400 24 : gen->crank2->old_block_builder[0]--;
401 24 : }
402 :
403 30 : gen->crank3->change_tip_receiver.acct_idx [1] = (uchar)(old_tr_pidx->idx);
404 30 : gen->crank2->change_tip_receiver.acct_idx [1] = (uchar)(old_tr_pidx->idx);
405 30 : gen->crank3->change_tip_receiver.acct_idx [3] = (uchar)(old_bb_pidx->idx);
406 30 : gen->crank3->change_block_builder.acct_idx[2] = (uchar)(old_bb_pidx->idx);
407 30 : gen->crank2->change_tip_receiver.acct_idx [3] = (uchar)(old_bb_pidx->idx);
408 30 : gen->crank2->change_block_builder.acct_idx[2] = (uchar)(old_bb_pidx->idx);
409 :
410 30 : if( FD_UNLIKELY( inserted2 ) ) pidx_map_remove( gen->map, old_bb_pidx );
411 30 : if( FD_LIKELY ( inserted1 ) ) pidx_map_remove( gen->map, old_tr_pidx );
412 30 : pidx_map_remove( gen->map, new_bb_pidx );
413 30 : pidx_map_remove( gen->map, new_tr_pidx );
414 30 : pidx_map_remove( gen->map, identity_pidx );
415 :
416 30 : if( FD_UNLIKELY( swap3 ) ) {
417 3 : fd_memcpy( out_payload, gen->crank3, sizeof(gen->crank3) );
418 3 : fd_memcpy( out_txn, gen->txn3, sizeof(gen->txn3) );
419 3 : return sizeof(gen->crank3);
420 27 : } else {
421 27 : fd_memcpy( out_payload, gen->crank2, sizeof(gen->crank2) );
422 27 : fd_memcpy( out_txn, gen->txn2, sizeof(gen->txn2) );
423 27 : return sizeof(gen->crank2);
424 27 : }
425 30 : }
426 :
427 : void
428 : fd_bundle_crank_apply( fd_bundle_crank_gen_t * gen,
429 : fd_bundle_crank_tip_payment_config_t * tip_payment_config,
430 : fd_acct_addr_t const * new_block_builder,
431 : fd_acct_addr_t * tip_receiver_owner,
432 : ulong epoch,
433 0 : ulong block_builder_commission ) {
434 :
435 0 : if( FD_UNLIKELY( epoch!=gen->configured_epoch ) ) fd_bundle_crank_update_epoch( gen, epoch );
436 :
437 0 : memcpy( tip_receiver_owner, gen->crank3->tip_distribution_program, sizeof(fd_acct_addr_t) );
438 0 : memcpy( tip_payment_config->tip_receiver, gen->crank3->new_tip_receiver, sizeof(fd_acct_addr_t) );
439 0 : memcpy( tip_payment_config->block_builder, new_block_builder, sizeof(fd_acct_addr_t) );
440 :
441 0 : tip_payment_config->commission_pct = block_builder_commission;
442 0 : }
|