Skip to content

Commit 80c7c14

Browse files
committed
feat(replay): publish slot dead frags
1 parent 0b5b196 commit 80c7c14

File tree

6 files changed

+104
-53
lines changed

6 files changed

+104
-53
lines changed

src/choreo/hfork/fd_hfork.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ static void
55
check( fd_hfork_t * hfork,
66
ulong total_stake,
77
candidate_t * candidate,
8-
int invalid,
8+
int dead,
99
fd_hash_t * our_bank_hash ) {
1010

1111
if( FD_LIKELY( candidate->checked ) ) return; /* already checked this bank hash against our own */
1212
if( FD_LIKELY( candidate->stake * 100UL / total_stake < 52UL ) ) return; /* not enough stake to compare */
1313

14-
if( FD_UNLIKELY( invalid ) ) {
14+
if( FD_UNLIKELY( dead ) ) {
1515
char msg[ 4096UL ];
1616
FD_BASE58_ENCODE_32_BYTES( candidate->key.block_id.uc, _block_id );
1717
FD_TEST( fd_cstr_printf_check( msg, sizeof( msg ), NULL,
@@ -183,7 +183,10 @@ fd_hfork_count_vote( fd_hfork_t * hfork,
183183
/* Get the vtr. */
184184

185185
vtr_t * vtr = vtr_map_query( hfork->vtr_map, *vote_acc, NULL );
186-
if( FD_UNLIKELY( !vtr ) ) vtr = vtr_map_insert( hfork->vtr_map, *vote_acc );
186+
if( FD_UNLIKELY( !vtr ) ) {
187+
FD_TEST( vtr_map_key_cnt( hfork->vtr_map ) < vtr_map_key_max( hfork->vtr_map ) );
188+
vtr = vtr_map_insert( hfork->vtr_map, *vote_acc );
189+
}
187190

188191
/* Ignore out of order or duplicate votes. */
189192

@@ -240,11 +243,10 @@ fd_hfork_count_vote( fd_hfork_t * hfork,
240243
blk_t * blk = blk_map_query( hfork->blk_map, *block_id, NULL );
241244
if( FD_UNLIKELY( !blk ) ) {
242245
FD_TEST( blk_map_key_cnt( hfork->blk_map ) < blk_map_key_max( hfork->blk_map ) ); /* invariant violation: blk_map full */
243-
blk = blk_map_insert( hfork->blk_map, *block_id );
244-
FD_TEST( blk );
245-
blk->bank_hashes = NULL;
246-
blk->replayed = 0;
247-
blk->invalid = 0;
246+
blk = blk_map_insert( hfork->blk_map, *block_id );
247+
blk->bank_hashes = NULL;
248+
blk->replayed = 0;
249+
blk->dead = 0;
248250
}
249251
int found = 0;
250252
ulong cnt = 0;
@@ -256,8 +258,8 @@ fd_hfork_count_vote( fd_hfork_t * hfork,
256258
curr = bank_hash_pool_ele( hfork->bank_hash_pool, curr->next );
257259
cnt++;
258260
}
259-
260261
if( FD_UNLIKELY( !found ) ) {
262+
FD_TEST( bank_hash_pool_free( hfork->bank_hash_pool ) );
261263
bank_hash_t * ele = bank_hash_pool_ele_acquire( hfork->bank_hash_pool );
262264
ele->bank_hash = *bank_hash;
263265
ele->next = bank_hash_pool_idx_null( hfork->bank_hash_pool );
@@ -274,7 +276,7 @@ fd_hfork_count_vote( fd_hfork_t * hfork,
274276

275277
/* Check for hard forks. */
276278

277-
if( FD_LIKELY( blk->replayed ) ) check( hfork, total_stake, candidate, blk->invalid, &blk->our_bank_hash );
279+
if( FD_LIKELY( blk->replayed ) ) check( hfork, total_stake, candidate, blk->dead, &blk->our_bank_hash );
278280
}
279281

280282
void
@@ -287,14 +289,14 @@ fd_hfork_record_our_bank_hash( fd_hfork_t * hfork,
287289
blk = blk_map_insert( hfork->blk_map, *block_id );
288290
blk->replayed = 1;
289291
}
290-
if( FD_LIKELY( bank_hash ) ) { blk->invalid = 0; blk->our_bank_hash = *bank_hash; }
291-
else blk->invalid = 1;
292+
if( FD_LIKELY( bank_hash ) ) { blk->dead = 0; blk->our_bank_hash = *bank_hash; }
293+
else blk->dead = 1;
292294

293295
bank_hash_t * curr = blk->bank_hashes;
294296
while( FD_LIKELY( curr ) ) {
295297
candidate_key_t key = { .block_id = *block_id, .bank_hash = curr->bank_hash };
296298
candidate_t * candidate = candidate_map_query( hfork->candidate_map, key, NULL );
297-
if( FD_LIKELY( candidate ) ) check( hfork, total_stake, candidate, blk->invalid, &blk->our_bank_hash );
299+
if( FD_LIKELY( candidate ) ) check( hfork, total_stake, candidate, blk->dead, &blk->our_bank_hash );
298300
curr = bank_hash_pool_ele( hfork->bank_hash_pool, curr->next );
299301
}
300302
}

src/choreo/hfork/fd_hfork_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct blk {
1515
uint hash;
1616
int forked; /* whether this block id has hard forked (multiple candidate bank hashes) */
1717
int replayed; /* whether we've replayed */
18-
int invalid; /* whether we marked the block as invalid during replay (must ignore our_bank_hash) */
18+
int dead; /* whether we marked the block as dead during replay (must ignore our_bank_hash) */
1919
fd_hash_t our_bank_hash; /* our bank hash for this block_id after replay */
2020
bank_hash_t * bank_hashes;
2121
};

src/choreo/hfork/test_hfork.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
void
55
test_hfork_simple( fd_wksp_t * wksp ) {
66
ulong max_live_slots = 2;
7-
ulong max_vote_accounts = 2;
7+
ulong max_vote_accounts = 4;
88

99
void * mem = fd_wksp_alloc_laddr( wksp, fd_hfork_align(), fd_hfork_footprint( max_live_slots, max_vote_accounts ), 1UL );
1010
fd_hfork_t * hfork = fd_hfork_join( fd_hfork_new( mem, max_live_slots, max_vote_accounts, 42, 0 ) );
@@ -22,9 +22,15 @@ test_hfork_simple( fd_wksp_t * wksp ) {
2222
fd_hash_t block_id2 = { .ul = { slot2 } };
2323
fd_hash_t bank_hash2 = { .ul = { slot2 } };
2424

25-
fd_hash_t voters[2] = {
25+
ulong slot3 = 368778156;
26+
// fd_hash_t block_id3 = { .ul = { slot3 } };
27+
fd_hash_t bank_hash3 = { .ul = { slot3 } };
28+
29+
fd_hash_t voters[4] = {
2630
(fd_hash_t){ .ul = { 1 } },
2731
(fd_hash_t){ .ul = { 2 } },
32+
(fd_hash_t){ .ul = { 3 } },
33+
(fd_hash_t){ .ul = { 4 } },
2834
};
2935

3036
fd_hfork_metrics_t metrics = { 0 };
@@ -58,6 +64,22 @@ test_hfork_simple( fd_wksp_t * wksp ) {
5864
FD_TEST( candidate->stake==51 );
5965
FD_TEST( candidate->cnt ==1 );
6066

67+
/* max bank hashes for a given block_id */
68+
69+
fd_hfork_count_vote( hfork, &voters[0], &block_id, &bank_hash, slot3, 1, 100, &metrics );
70+
fd_hfork_count_vote( hfork, &voters[1], &block_id, &bank_hash1, slot3, 51, 100, &metrics );
71+
fd_hfork_count_vote( hfork, &voters[2], &block_id, &bank_hash2, slot3, 2, 100, &metrics );
72+
fd_hfork_count_vote( hfork, &voters[3], &block_id, &bank_hash3, slot3, 3, 100, &metrics );
73+
74+
blk_t * blk = blk_map_query( hfork->blk_map, block_id, NULL );
75+
bank_hash_t * curr = blk->bank_hashes;
76+
ulong cnt = 0;
77+
while( FD_LIKELY( curr ) ) {
78+
curr = bank_hash_pool_ele( hfork->bank_hash_pool, curr->next );
79+
cnt++;
80+
}
81+
FD_TEST( cnt==4 );
82+
6183
fd_wksp_free_laddr( fd_hfork_delete( fd_hfork_leave( hfork ) ) );
6284
}
6385

src/discof/replay/fd_replay_tile.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,17 @@ publish_slot_completed( fd_replay_tile_t * ctx,
735735
ctx->replay_out->chunk = fd_dcache_compact_next( ctx->replay_out->chunk, sizeof(fd_replay_slot_completed_t), ctx->replay_out->chunk0, ctx->replay_out->wmark );
736736
}
737737

738+
static void
739+
publish_slot_dead( fd_replay_tile_t * ctx,
740+
fd_stem_context_t * stem,
741+
fd_bank_t * bank ) {
742+
fd_replay_slot_dead_t * slot_dead = fd_chunk_to_laddr( ctx->replay_out->mem, ctx->replay_out->chunk );
743+
slot_dead->slot = fd_bank_slot_get( bank );
744+
slot_dead->block_id = ctx->block_id_arr[ bank->idx ].block_id;
745+
fd_stem_publish( stem, ctx->replay_out->idx, REPLAY_SIG_SLOT_DEAD, ctx->replay_out->chunk, sizeof(fd_replay_slot_dead_t), 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
746+
ctx->replay_out->chunk = fd_dcache_compact_next( ctx->replay_out->chunk, sizeof(fd_replay_slot_dead_t), ctx->replay_out->chunk0, ctx->replay_out->wmark );
747+
}
748+
738749
static void
739750
replay_block_finalize( fd_replay_tile_t * ctx,
740751
fd_stem_context_t * stem,
@@ -1610,8 +1621,9 @@ can_process_fec( fd_replay_tile_t * ctx ) {
16101621
}
16111622

16121623
static void
1613-
process_fec_set( fd_replay_tile_t * ctx,
1614-
fd_reasm_fec_t * reasm_fec ) {
1624+
process_fec_set( fd_replay_tile_t * ctx,
1625+
fd_stem_context_t * stem,
1626+
fd_reasm_fec_t * reasm_fec ) {
16151627
long now = fd_log_wallclock();
16161628

16171629
/* Linking only requires a shared lock because the fields that are
@@ -1722,7 +1734,9 @@ process_fec_set( fd_replay_tile_t * ctx,
17221734
sched_fec->alut_ctx->els = ctx->published_root_slot;
17231735

17241736
if( FD_UNLIKELY( !fd_sched_fec_ingest( ctx->sched, sched_fec ) ) ) {
1725-
fd_banks_mark_bank_dead( ctx->banks, fd_banks_bank_query( ctx->banks, sched_fec->bank_idx ) );
1737+
fd_bank_t * bank = fd_banks_bank_query( ctx->banks, sched_fec->bank_idx );
1738+
publish_slot_dead( ctx, stem, bank );
1739+
fd_banks_mark_bank_dead( ctx->banks, bank );
17261740
}
17271741
}
17281742

@@ -1861,12 +1875,12 @@ after_credit( fd_replay_tile_t * ctx,
18611875

18621876
/* Now we can process all of the FECs. */
18631877
for( ulong i=fec_cnt; i>0UL; i-- ) {
1864-
process_fec_set( ctx, fecs[i-1UL] );
1878+
process_fec_set( ctx, stem, fecs[i-1UL] );
18651879
}
18661880
} else {
18671881
/* Standard case. */
18681882
fec = fd_reasm_out( ctx->reasm );
1869-
process_fec_set( ctx, fec );
1883+
process_fec_set( ctx, stem, fec );
18701884
}
18711885

18721886
*charge_busy = 1;
@@ -1915,6 +1929,7 @@ process_solcap_account_update( fd_replay_tile_t * ctx,
19151929

19161930
static void
19171931
process_exec_task_done( fd_replay_tile_t * ctx,
1932+
fd_stem_context_t * stem,
19181933
fd_exec_task_done_msg_t * msg,
19191934
ulong sig ) {
19201935
if( FD_UNLIKELY( sig==0UL ) ) {
@@ -1945,6 +1960,7 @@ process_exec_task_done( fd_replay_tile_t * ctx,
19451960
/* Every transaction in a valid block has to execute.
19461961
Otherwise, we should mark the block as dead. Also freeze the
19471962
bank if possible. */
1963+
publish_slot_dead( ctx, stem, bank );
19481964
fd_banks_mark_bank_dead( ctx->banks, bank );
19491965
fd_sched_block_abandon( ctx->sched, bank->idx );
19501966
}
@@ -1959,6 +1975,7 @@ process_exec_task_done( fd_replay_tile_t * ctx,
19591975
/* Every transaction in a valid block has to sigverify.
19601976
Otherwise, we should mark the block as dead. Also freeze the
19611977
bank if possible. */
1978+
publish_slot_dead( ctx, stem, bank );
19621979
fd_banks_mark_bank_dead( ctx->banks, bank );
19631980
fd_sched_block_abandon( ctx->sched, bank->idx );
19641981
}
@@ -2223,7 +2240,7 @@ returnable_frag( fd_replay_tile_t * ctx,
22232240
maybe_verify_shred_version( ctx );
22242241
break;
22252242
case IN_KIND_EXEC: {
2226-
process_exec_task_done( ctx, fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk ), sig );
2243+
process_exec_task_done( ctx, stem, fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk ), sig );
22272244
break;
22282245
}
22292246
case IN_KIND_POH: {

src/discof/replay/fd_replay_tile.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#include "../../flamenco/types/fd_types_custom.h"
77

88
#define REPLAY_SIG_SLOT_COMPLETED (0)
9-
#define REPLAY_SIG_ROOT_ADVANCED (1)
9+
#define REPLAY_SIG_SLOT_DEAD (1)
10+
#define REPLAY_SIG_ROOT_ADVANCED (2)
1011
#define REPLAY_SIG_RESET (3)
1112
#define REPLAY_SIG_BECAME_LEADER (4)
1213

@@ -67,6 +68,12 @@ struct fd_replay_slot_completed {
6768

6869
typedef struct fd_replay_slot_completed fd_replay_slot_completed_t;
6970

71+
struct fd_replay_slot_dead {
72+
ulong slot;
73+
fd_hash_t block_id;
74+
};
75+
typedef struct fd_replay_slot_dead fd_replay_slot_dead_t;
76+
7077
struct fd_replay_root_advanced {
7178
ulong bank_idx;
7279
};

0 commit comments

Comments
 (0)