@@ -170,14 +170,14 @@ fd_forks_query_const( fd_forks_t const * forks, ulong slot ) {
170
170
// fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot_bank.slot;
171
171
// fork->slot_ctx->slot_bank.slot = curr_slot;
172
172
173
- // fork->slot_ctx-> status_cache = status_cache;
173
+ // fork->slot_ctx. status_cache = status_cache;
174
174
// fd_funk_txn_xid_t xid;
175
175
176
176
// fd_memcpy( xid.uc, blockhash.uc, sizeof( fd_funk_txn_xid_t));
177
- // xid.ul[0] = fork->slot_ctx-> slot_bank.slot;
177
+ // xid.ul[0] = fork->slot_ctx. slot_bank.slot;
178
178
// /* push a new transaction on the stack */
179
179
// fd_funk_start_write( funk );
180
- // fork->slot_ctx-> funk_txn = fd_funk_txn_prepare( funk, fork->slot_ctx-> funk_txn, &xid, 1 );
180
+ // fork->slot_ctx. funk_txn = fd_funk_txn_prepare( funk, fork->slot_ctx. funk_txn, &xid, 1 );
181
181
// fd_funk_end_write( funk );
182
182
183
183
// int res = fd_runtime_publish_old_txns( &fork->slot_ctx, capture_ctx );
@@ -191,64 +191,80 @@ slot_ctx_restore( ulong slot,
191
191
fd_acc_mgr_t * acc_mgr ,
192
192
fd_blockstore_t * blockstore ,
193
193
fd_exec_epoch_ctx_t * epoch_ctx ,
194
- fd_funk_t * funk ,
194
+ fd_funk_t * funk ,
195
195
fd_spad_t * runtime_spad ,
196
196
fd_exec_slot_ctx_t * slot_ctx_out ) {
197
- fd_funk_txn_t * txn_map = fd_funk_txn_map ( funk , fd_funk_wksp ( funk ) );
197
+ fd_funk_txn_map_t txn_map = fd_funk_txn_map ( funk , fd_funk_wksp ( funk ) );
198
198
bool block_exists = fd_blockstore_shreds_complete ( blockstore , slot );
199
199
200
200
FD_LOG_DEBUG ( ( "Current slot %lu" , slot ) );
201
201
if ( !block_exists )
202
202
FD_LOG_ERR ( ( "missing block at slot we're trying to restore" ) );
203
203
204
- fd_funk_txn_xid_t xid = { .ul = { slot , slot } };
204
+ fd_funk_txn_xid_t xid = { .ul = { slot , slot } };
205
205
fd_funk_rec_key_t id = fd_runtime_slot_bank_key ();
206
- fd_funk_txn_t * txn = fd_funk_txn_query ( & xid , txn_map );
207
- if ( !txn ) {
208
- memset ( xid .uc , 0 , sizeof ( fd_funk_txn_xid_t ) );
209
- xid .ul [0 ] = slot ;
210
- txn = fd_funk_txn_query ( & xid , txn_map );
206
+ for ( ; ; ) {
207
+ fd_funk_txn_start_read ( funk );
208
+ fd_funk_txn_t * txn = fd_funk_txn_query ( & xid , & txn_map );
211
209
if ( !txn ) {
212
- FD_LOG_ERR ( ( "missing txn, parent slot %lu" , slot ) );
210
+ memset ( xid .uc , 0 , sizeof ( fd_funk_txn_xid_t ) );
211
+ xid .ul [0 ] = slot ;
212
+ txn = fd_funk_txn_query ( & xid , & txn_map );
213
+ if ( !txn ) {
214
+ FD_LOG_ERR ( ( "missing txn, parent slot %lu" , slot ) );
215
+ }
213
216
}
214
- }
215
- fd_funk_rec_t const * rec = fd_funk_rec_query_global ( funk , txn , & id , NULL );
216
- if ( rec == NULL ) FD_LOG_ERR ( ( "failed to read banks record" ) );
217
- void * val = fd_funk_val ( rec , fd_funk_wksp ( funk ) );
217
+ fd_funk_txn_end_read ( funk );
218
218
219
- uint magic = * (uint * )val ;
219
+ fd_funk_rec_query_t query [1 ];
220
+ fd_funk_rec_t const * rec = fd_funk_rec_query_try_global ( funk , txn , & id , NULL , query );
221
+ if ( rec == NULL ) FD_LOG_ERR ( ( "failed to read banks record" ) );
222
+ void * val = fd_funk_val ( rec , fd_funk_wksp ( funk ) );
220
223
221
- fd_bincode_decode_ctx_t decode_ctx = {
222
- .data = (uchar * )val + sizeof (uint ),
223
- .dataend = (uchar * )val + fd_funk_val_sz ( rec )
224
- };
224
+ uint magic = * (uint * )val ;
225
225
226
- FD_TEST ( slot_ctx_out -> magic == FD_EXEC_SLOT_CTX_MAGIC );
226
+ fd_bincode_decode_ctx_t decode_ctx = {
227
+ .data = (uchar * )val + sizeof (uint ),
228
+ .dataend = (uchar * )val + fd_funk_val_sz ( rec )
229
+ };
227
230
228
- slot_ctx_out -> funk_txn = txn ;
229
- slot_ctx_out -> acc_mgr = acc_mgr ;
230
- slot_ctx_out -> blockstore = blockstore ;
231
- slot_ctx_out -> epoch_ctx = epoch_ctx ;
232
-
233
- if ( FD_LIKELY ( magic == FD_RUNTIME_ENC_BINCODE ) ) {
234
- ulong total_sz = 0UL ;
235
- int err = fd_slot_bank_decode_footprint ( & decode_ctx , & total_sz );
236
- if ( FD_UNLIKELY ( err != FD_BINCODE_SUCCESS ) ) {
237
- FD_LOG_ERR ( ( "failed to decode banks record" ) );
231
+ if ( slot_ctx_out == NULL || slot_ctx_out -> magic != FD_EXEC_SLOT_CTX_MAGIC ) {
232
+ FD_LOG_WARNING (( "bad slot context" ));
233
+ continue ;
238
234
}
239
235
240
- uchar * mem = fd_spad_alloc ( runtime_spad , fd_slot_bank_align (), total_sz );
241
- if ( FD_UNLIKELY ( !mem ) ) {
242
- FD_LOG_ERR ( ( "failed to allocate memory for slot bank" ) );
243
- }
236
+ FD_TEST ( slot_ctx_out -> magic == FD_EXEC_SLOT_CTX_MAGIC );
237
+
238
+ slot_ctx_out -> funk_txn = txn ;
239
+ slot_ctx_out -> acc_mgr = acc_mgr ;
240
+ slot_ctx_out -> blockstore = blockstore ;
241
+ slot_ctx_out -> epoch_ctx = epoch_ctx ;
242
+
243
+ if ( FD_LIKELY ( magic == FD_RUNTIME_ENC_BINCODE ) ) {
244
+ ulong total_sz = 0UL ;
245
+ int err = fd_slot_bank_decode_footprint ( & decode_ctx , & total_sz );
246
+ if ( FD_UNLIKELY ( err != FD_BINCODE_SUCCESS ) ) {
247
+ FD_LOG_WARNING ( ( "failed to decode banks record" ) );
248
+ continue ;
249
+ }
250
+
251
+ uchar * mem = fd_spad_alloc ( runtime_spad , fd_slot_bank_align (), total_sz );
252
+ if ( FD_UNLIKELY ( !mem ) ) {
253
+ FD_LOG_ERR ( ( "failed to allocate memory for slot bank" ) );
254
+ }
255
+
256
+ fd_slot_bank_t * slot_bank = fd_slot_bank_decode ( mem , & decode_ctx );
244
257
245
- fd_slot_bank_t * slot_bank = fd_slot_bank_decode ( mem , & decode_ctx );
258
+ fd_memcpy ( & slot_ctx_out -> slot_bank , slot_bank , sizeof (fd_slot_bank_t ) );
259
+ } else {
260
+ FD_LOG_ERR ( ( "failed to read banks record: invalid magic number" ) );
261
+ }
262
+ FD_TEST ( !fd_runtime_sysvar_cache_load ( slot_ctx_out , runtime_spad ) );
246
263
247
- fd_memcpy ( & slot_ctx_out -> slot_bank , slot_bank , sizeof ( fd_slot_bank_t ) );
248
- } else {
249
- FD_LOG_ERR ( ( "failed to read banks record: invalid magic number" ) );
264
+ if ( FD_LIKELY ( fd_funk_rec_query_test ( query ) == FD_FUNK_SUCCESS ) ) {
265
+ break ;
266
+ }
250
267
}
251
- FD_TEST ( !fd_runtime_sysvar_cache_load ( slot_ctx_out , runtime_spad ) );
252
268
253
269
// TODO how do i get this info, ignoring rewards for now
254
270
// slot_ctx_out->epoch_reward_status = ???
@@ -347,12 +363,27 @@ fd_forks_update( fd_forks_t * forks,
347
363
rec_query_global traverses all the way back to the root. */
348
364
349
365
fd_voter_t * voter = & epoch_voters [i ];
350
- fd_voter_state_t const * state = fd_voter_state ( funk , txn , & voter -> rec );
366
+
367
+ /* Fetch the vote account's vote slot and root slot from the vote account, re-trying if there is
368
+ a Funk conflict.
369
+
370
+ TODO: factor this out into a convenience function. */
371
+ ulong vote = 0UL ;
372
+ ulong root = 0UL ;
373
+ for ( ; ; ) {
374
+ fd_funk_rec_query_t query [1 ];
375
+ fd_voter_state_t const * state = fd_voter_state ( funk , query , txn , & voter -> rec );
376
+ vote = fd_voter_state_vote ( state );
377
+ root = fd_voter_state_root ( state );
378
+
379
+ if ( FD_LIKELY ( fd_funk_rec_query_test ( query ) == FD_FUNK_SUCCESS ) ) {
380
+ break ;
381
+ }
382
+ }
351
383
352
384
/* Only process votes for slots >= root. Ghost requires vote slot
353
385
to already exist in the ghost tree. */
354
386
355
- ulong vote = fd_voter_state_vote ( state );
356
387
if ( FD_LIKELY ( vote != FD_SLOT_NULL && vote >= fd_ghost_root ( ghost )-> slot ) ) {
357
388
fd_ghost_replay_vote ( ghost , voter , vote );
358
389
@@ -376,7 +407,6 @@ fd_forks_update( fd_forks_t * forks,
376
407
/* Check if this voter's root >= ghost root. We can't process
377
408
other voters' roots that precede the ghost root. */
378
409
379
- ulong root = fd_voter_state_root ( state );
380
410
if ( FD_LIKELY ( root != FD_SLOT_NULL && root >= fd_ghost_root ( ghost )-> slot ) ) {
381
411
fd_ghost_node_t const * node = fd_ghost_query ( ghost , root );
382
412
0 commit comments