Skip to content

Commit ded967d

Browse files
replay: fix behaviour when we fail to fetch vote state from funk
1 parent 10e026d commit ded967d

File tree

7 files changed

+62
-27
lines changed

7 files changed

+62
-27
lines changed

src/discof/replay/fd_replay_tile.c

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -548,11 +548,8 @@ publish_stake_weights( fd_replay_tile_t * ctx,
548548
- pubkey: The public key of the vote account to retrieve
549549
- stake: The stake amount associated with this vote account
550550
- vote_tower_out: Output structure to populate with vote state information
551-
552-
Failure modes:
553-
- Vote account data is too large (returns -1)
554-
- Vote account is not found in Funk (returns -1) */
555-
static int
551+
*/
552+
static void
556553
fd_replay_out_vote_tower_from_funk(
557554
fd_accdb_user_t * accdb,
558555
fd_funk_txn_xid_t const * xid,
@@ -571,18 +568,15 @@ fd_replay_out_vote_tower_from_funk(
571568

572569
fd_accdb_peek_t peek[1];
573570
if( FD_UNLIKELY( !fd_accdb_peek( accdb, peek, xid, pubkey->uc ) ) ) {
574-
/* FIXME crash here? */
575-
FD_LOG_WARNING(( "vote account not found. address: %s", FD_BASE58_ENC_32_ALLOCA( pubkey->uc ) ));
576-
return -1;
571+
FD_LOG_CRIT(( "vote account not found. address: %s", FD_BASE58_ENC_32_ALLOCA( pubkey->uc ) ));
577572
}
578573

579574
ulong data_sz = fd_accdb_ref_data_sz( peek->acc );
580575
if( FD_UNLIKELY( data_sz > sizeof(vote_tower_out->acc) ) ) {
581-
FD_LOG_WARNING(( "vote account %s has too large data. dlen %lu > %lu",
576+
FD_LOG_CRIT(( "vote account %s has too large data. dlen %lu > %lu",
582577
FD_BASE58_ENC_32_ALLOCA( pubkey->uc ),
583578
data_sz,
584579
sizeof(vote_tower_out->acc) ));
585-
return -1;
586580
}
587581

588582
fd_memcpy( vote_tower_out->acc, fd_accdb_ref_data_const( peek->acc ), data_sz );
@@ -591,8 +585,6 @@ fd_replay_out_vote_tower_from_funk(
591585
if( FD_LIKELY( fd_accdb_peek_test( peek ) ) ) break;
592586
FD_SPIN_PAUSE();
593587
}
594-
595-
return 0;
596588
}
597589

598590
/* This function buffers all the vote account towers that Tower needs at
@@ -608,7 +600,7 @@ buffer_vote_towers( fd_replay_tile_t * ctx,
608600
ctx->vote_tower_out_idx = 0UL;
609601
ctx->vote_tower_out_len = 0UL;
610602

611-
fd_vote_states_t const * vote_states = fd_bank_vote_states_prev_locking_query( bank );
603+
fd_vote_states_t const * vote_states = fd_bank_vote_states_locking_query( bank );
612604
fd_vote_states_iter_t iter_[1];
613605
for( fd_vote_states_iter_t * iter = fd_vote_states_iter_init( iter_, vote_states );
614606
!fd_vote_states_iter_done( iter );
@@ -617,15 +609,14 @@ buffer_vote_towers( fd_replay_tile_t * ctx,
617609
if( FD_UNLIKELY( vote_state->stake == 0 ) ) continue; /* skip unstaked vote accounts */
618610
fd_pubkey_t const * vote_account_pubkey = &vote_state->vote_account;
619611
if( FD_UNLIKELY( ctx->vote_tower_out_len >= (FD_REPLAY_TOWER_VOTE_ACC_MAX-1UL) ) ) FD_LOG_ERR(( "vote_tower_out_len too large" ));
620-
if( FD_UNLIKELY( fd_replay_out_vote_tower_from_funk( ctx->accdb,
621-
xid,
622-
vote_account_pubkey,
623-
vote_state->stake,
624-
&ctx->vote_tower_out[ctx->vote_tower_out_len++] ) ) ) {
625-
FD_LOG_DEBUG(( "failed to get vote state for vote account %s", FD_BASE58_ENC_32_ALLOCA( vote_account_pubkey->uc ) ));
626-
}
612+
fd_replay_out_vote_tower_from_funk(
613+
ctx->accdb,
614+
xid,
615+
vote_account_pubkey,
616+
vote_state->stake_t_2,
617+
&ctx->vote_tower_out[ ctx->vote_tower_out_len++ ] );
627618
}
628-
fd_bank_vote_states_prev_end_locking_query( bank );
619+
fd_bank_vote_states_end_locking_query( bank );
629620
}
630621

631622
/* This function publishes the next vote tower in the

src/discof/restore/utils/fd_ssload.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,17 @@ fd_ssload_recover( fd_snapshot_manifest_t * manifest,
270270
fd_vote_state_ele_t * vote_state_prev_prev = fd_vote_states_query( vote_stakes_prev_prev, (fd_pubkey_t *)elem->vote_account_pubkey );
271271
ulong prev_prev_stake = vote_state_prev_prev ? vote_state_prev_prev->stake : 0UL;
272272

273+
fd_vote_state_ele_t * vote_state_prev = fd_vote_states_query( vote_stakes_prev, (fd_pubkey_t *)elem->vote_account_pubkey );
274+
ulong prev_stake = vote_state_prev ? vote_state_prev->stake : 0UL;
275+
273276
fd_vote_state_ele_t * vote_state = fd_vote_states_update( vote_states, (fd_pubkey_t *)elem->vote_account_pubkey );
274277

275278
vote_state->node_account = *(fd_pubkey_t *)elem->node_account_pubkey;
276279
vote_state->commission = elem->commission;
277280
vote_state->last_vote_timestamp = elem->last_timestamp;
278281
vote_state->last_vote_slot = elem->last_slot;
279282
vote_state->stake = elem->stake;
283+
vote_state->stake_t_1 = prev_stake;
280284
vote_state->stake_t_2 = prev_prev_stake;
281285
}
282286
fd_bank_vote_states_end_locking_modify( bank );

src/flamenco/runtime/fd_runtime.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,6 +1565,7 @@ fd_runtime_init_bank_from_genesis( fd_banks_t * banks,
15651565
if( !memcmp( acc->account.owner.key, fd_solana_vote_program_id.key, sizeof(fd_pubkey_t) ) ) {
15661566
fd_vote_state_ele_t * vote_state = fd_vote_states_query( vote_states, &acc->key );
15671567

1568+
vote_state->stake_t_1 = vote_state->stake;
15681569
vote_state->stake_t_2 = vote_state->stake;
15691570
}
15701571
}

src/flamenco/runtime/tests/fd_block_harness.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef struct {
3535
using the stake delegations cache. */
3636
static void
3737
fd_solfuzz_block_refresh_vote_accounts( fd_vote_states_t * vote_states,
38+
fd_vote_states_t * vote_states_prev,
3839
fd_vote_states_t * vote_states_prev_prev,
3940
fd_stake_delegations_t * stake_delegations,
4041
ulong epoch ) {
@@ -53,6 +54,7 @@ fd_solfuzz_block_refresh_vote_accounts( fd_vote_states_t * vote_states,
5354
if( !vote_state ) continue;
5455

5556
vote_state->stake += stake;
57+
vote_state->stake_t_1 += stake;
5658
vote_state->stake_t_2 += stake;
5759
}
5860

@@ -70,6 +72,17 @@ fd_solfuzz_block_refresh_vote_accounts( fd_vote_states_t * vote_states,
7072
vote_state->stake_t_2 = epoch>=2UL ? t_2_stake : vote_state->stake;
7173
vote_state->stake_t_2 = vote_state->stake;
7274
}
75+
76+
/* Set stake_t_1 for the vote accounts in the vote states cache. */
77+
for( fd_vote_states_iter_t * iter = fd_vote_states_iter_init( vs_iter_, vote_states_prev );
78+
!fd_vote_states_iter_done( iter );
79+
fd_vote_states_iter_next( iter ) ) {
80+
fd_vote_state_ele_t * vote_state = fd_vote_states_iter_ele( iter );
81+
fd_vote_state_ele_t * vote_state_prev = fd_vote_states_query( vote_states_prev, &vote_state->vote_account );
82+
ulong t_1_stake = !!vote_state_prev ? vote_state_prev->stake : 0UL;
83+
vote_state->stake_t_1 = epoch>=1UL ? t_1_stake : vote_state->stake;
84+
vote_state->stake_t_1 = vote_state->stake;
85+
}
7386
}
7487

7588
/* Registers a single vote account into the current votes cache. The
@@ -180,6 +193,7 @@ fd_solfuzz_pb_block_update_prev_epoch_votes_cache( fd_vote_states_t *
180193
fd_vote_states_update_from_account( vote_states, &vote_address, vote_data, vote_data_len );
181194
fd_vote_state_ele_t * vote_state = fd_vote_states_query( vote_states, &vote_address );
182195
vote_state->stake += stake;
196+
vote_state->stake_t_1 += stake;
183197
vote_state->stake_t_2 += stake;
184198
}
185199
} FD_SPAD_FRAME_END;
@@ -347,7 +361,12 @@ fd_solfuzz_pb_block_ctx_create( fd_solfuzz_runner_t * runner,
347361
runner->spad );
348362

349363
/* Refresh vote accounts to calculate stake delegations */
350-
fd_solfuzz_block_refresh_vote_accounts( vote_states, vote_states_prev_prev, stake_delegations, fd_bank_epoch_get( bank ) );
364+
fd_solfuzz_block_refresh_vote_accounts(
365+
vote_states,
366+
vote_states_prev,
367+
vote_states_prev_prev,
368+
stake_delegations,
369+
fd_bank_epoch_get( bank ) );
351370
fd_bank_vote_states_end_locking_modify( bank );
352371

353372
fd_bank_vote_states_prev_prev_end_locking_modify( bank );
@@ -639,7 +658,7 @@ fd_solfuzz_pb_build_leader_schedule_effects( fd_solfuzz_runner_t *
639658
memcpy( &pubkey, test_ctx->acct_states[i].address, sizeof(fd_pubkey_t) );
640659
fd_solfuzz_block_register_stake_delegation( runner->accdb->funk, xid, stake_delegations, &pubkey );
641660
}
642-
fd_solfuzz_block_refresh_vote_accounts( tmp_vs, tmp_vs, stake_delegations, fd_bank_epoch_get( runner->bank ) );
661+
fd_solfuzz_block_refresh_vote_accounts( tmp_vs, tmp_vs, tmp_vs, stake_delegations, fd_bank_epoch_get( runner->bank ) );
643662
}
644663

645664
/* Build weights from the selected stake source */

src/flamenco/stakes/fd_stakes.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,33 @@ fd_refresh_vote_accounts( fd_bank_t * bank,
8484
to make clock calulations more efficient. This is purely an
8585
optimization. */
8686

87-
fd_vote_states_t const * vote_states_prev = fd_bank_vote_states_prev_prev_locking_query( bank );
87+
fd_vote_states_t const * vote_states_prev_prev = fd_bank_vote_states_prev_prev_locking_query( bank );
88+
if( FD_LIKELY( fd_bank_slot_get( bank )!=0UL ) ) {
89+
fd_vote_states_iter_t vs_iter_[1];
90+
for( fd_vote_states_iter_t * vs_iter = fd_vote_states_iter_init( vs_iter_, vote_states );
91+
!fd_vote_states_iter_done( vs_iter );
92+
fd_vote_states_iter_next( vs_iter ) ) {
93+
fd_vote_state_ele_t * vote_state = fd_vote_states_iter_ele( vs_iter );
94+
fd_vote_state_ele_t * vote_state_prev_prev = fd_vote_states_query( vote_states_prev_prev, &vote_state->vote_account );
95+
vote_state->stake_t_2 = !!vote_state_prev_prev ? vote_state_prev_prev->stake : 0UL;
96+
}
97+
}
98+
fd_bank_vote_states_prev_prev_end_locking_query( bank );
8899

100+
/* Cache the stake from epoch T-1 for the vote accounts in the vote
101+
states cache, to be sent to Tower for it's threshold checks. */
102+
fd_vote_states_t const * vote_states_prev = fd_bank_vote_states_prev_locking_query( bank );
89103
if( FD_LIKELY( fd_bank_slot_get( bank )!=0UL ) ) {
90104
fd_vote_states_iter_t vs_iter_[1];
91105
for( fd_vote_states_iter_t * vs_iter = fd_vote_states_iter_init( vs_iter_, vote_states );
92106
!fd_vote_states_iter_done( vs_iter );
93107
fd_vote_states_iter_next( vs_iter ) ) {
94108
fd_vote_state_ele_t * vote_state = fd_vote_states_iter_ele( vs_iter );
95109
fd_vote_state_ele_t * vote_state_prev = fd_vote_states_query( vote_states_prev, &vote_state->vote_account );
96-
vote_state->stake_t_2 = !!vote_state_prev ? vote_state_prev->stake : 0UL;
110+
vote_state->stake_t_1 = !!vote_state_prev ? vote_state_prev->stake : 0UL;
97111
}
98112
}
99-
fd_bank_vote_states_prev_prev_end_locking_query( bank );
113+
fd_bank_vote_states_prev_end_locking_query( bank );
100114
fd_bank_vote_states_end_locking_modify( bank );
101115
}
102116

src/flamenco/stakes/fd_vote_states.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ fd_vote_states_update( fd_vote_states_t * vote_states,
199199

200200
vote_state->vote_account = *vote_account;
201201
vote_state->stake = 0UL;
202+
vote_state->stake_t_1 = 0UL;
202203
vote_state->stake_t_2 = 0UL;
203204

204205
if( FD_UNLIKELY( !fd_vote_state_map_ele_insert(
@@ -330,6 +331,7 @@ fd_vote_states_reset_stakes( fd_vote_states_t * vote_states ) {
330331
}
331332

332333
vote_state->stake = 0UL;
334+
vote_state->stake_t_1 = 0UL;
333335
vote_state->stake_t_2 = 0UL;
334336
}
335337
}

src/flamenco/stakes/fd_vote_states.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
- stake: stake as of the end of the previous epoch. This is used
5353
eventually for leader schedule calculations. The stake from epoch
5454
T-2 (stake_t_2) is used for the stake in clock calculations.
55+
T-1 (stake_t_1) is used for the stake in Tower's threshold switch checks.
5556
- rewards: this information is only used at the epoch boundary.
5657
*/
5758

@@ -76,8 +77,11 @@ struct fd_vote_state_ele {
7677

7778
/* Vote account stake information which is derived from the stake
7879
delegations. This information is used for leader schedule
79-
calculation and clock stake-weighted median calculations. */
80+
calculation and clock stake-weighted median calculations.
81+
82+
stake_t_1 is used in Tower, for it's threshold switch checks. */
8083
ulong stake;
84+
ulong stake_t_1;
8185
ulong stake_t_2;
8286

8387
/* Vote account information which is derived from the vote account

0 commit comments

Comments
 (0)