Skip to content

Commit d1eb5fc

Browse files
committed
feat(tower): rework confirmed frags and vote txn verify + minor fixes
1 parent 13c7c77 commit d1eb5fc

File tree

12 files changed

+257
-104
lines changed

12 files changed

+257
-104
lines changed

src/app/firedancer/topology.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,15 +615,18 @@ fd_topo_initialize( config_t * config ) {
615615
fd_topob_tile_in ( topo, "replay", 0UL, "metric_in", "snapin_manif", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
616616
}
617617

618-
/**/ fd_topob_tile_in( topo, "replay", 0UL, "metric_in", "poh_replay", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
619-
FOR(exec_tile_cnt) fd_topob_tile_in( topo, "exec", i, "metric_in", "replay_exec", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
618+
/**/ fd_topob_tile_in ( topo, "replay", 0UL, "metric_in", "poh_replay", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
619+
FOR(exec_tile_cnt) fd_topob_tile_in ( topo, "exec", i, "metric_in", "replay_exec", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
620+
621+
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "dedup_resolv", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
620622
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "genesi_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
621623
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "gossip_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
622624
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "replay_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
623625
if( snapshots_enabled ) {
624626
fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "snapin_manif", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
625627
}
626628
/**/ fd_topob_tile_out( topo, "tower", 0UL, "tower_out", 0UL );
629+
627630
/**/ fd_topob_tile_in ( topo, "send", 0UL, "metric_in", "replay_stake", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
628631
/**/ fd_topob_tile_in ( topo, "send", 0UL, "metric_in", "gossip_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
629632
/**/ fd_topob_tile_in ( topo, "send", 0UL, "metric_in", "tower_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );

src/choreo/notar/fd_notar.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -94,31 +94,23 @@ fd_notar_delete( void * notar ) {
9494
return notar;
9595
}
9696

97-
int
97+
fd_notar_blk_t *
9898
fd_notar_count_vote( fd_notar_t * notar,
9999
ulong total_stake,
100100
fd_pubkey_t const * addr,
101101
ulong vote_slot,
102102
fd_hash_t const * vote_block_id ) {
103103

104-
if( FD_UNLIKELY( !notar ) ) {
105-
FD_LOG_WARNING(( "NULL notar" ));
106-
return 0;
107-
}
104+
if( FD_UNLIKELY( !notar ) ) { FD_LOG_WARNING(( "NULL notar" )); return NULL; }
108105

109106
/* Ignore if this vote slot isn't in range. */
110107

111-
if( FD_UNLIKELY( vote_slot < notar->lo_wmark || vote_slot > notar->hi_wmark ) ) return 0;
108+
if( FD_UNLIKELY( vote_slot < notar->lo_wmark || vote_slot > notar->hi_wmark ) ) return NULL;
112109

113110
/* Ignore if this vote account isn't in the voter set. */
114111

115112
fd_notar_vtr_t const * vtr = fd_notar_vtr_query( notar->vtr_map, *addr, NULL );
116-
if( FD_UNLIKELY( !vtr ) ) return 0;
117-
118-
/* Ignore if this notar blk was already duplicate confirmed. */
119-
120-
fd_notar_blk_t * notar_blk = fd_notar_blk_query( notar->blk_map, *vote_block_id, NULL );
121-
if( FD_LIKELY( notar_blk && notar_blk->dup_conf ) ) return 0;
113+
if( FD_UNLIKELY( !vtr ) ) return NULL;
122114

123115
/* Check we haven't already counted the voter's stake for this slot.
124116
If a voter voted for multiple block ids for the same slot, we only
@@ -138,12 +130,13 @@ fd_notar_count_vote( fd_notar_t * notar,
138130
fd_notar_slot_vtrs_null( notar_slot->prev_vtrs );
139131
fd_notar_slot_vtrs_null( notar_slot->vtrs );
140132
}
141-
if( FD_LIKELY( fd_notar_slot_vtrs_test( notar_slot->vtrs, vtr->bit ) ) ) return 0;
133+
if( FD_LIKELY( fd_notar_slot_vtrs_test( notar_slot->vtrs, vtr->bit ) ) ) return NULL;
142134
fd_notar_slot_vtrs_insert( notar_slot->vtrs, vtr->bit );
143135
notar_slot->stake += vtr->stake;
144136

145137
/* Get the actual block with the block_id. */
146138

139+
fd_notar_blk_t * notar_blk = fd_notar_blk_query( notar->blk_map, *vote_block_id, NULL );
147140
if( FD_UNLIKELY( !notar_blk ) ) {
148141
notar_blk = fd_notar_blk_insert( notar->blk_map, *vote_block_id );
149142
notar_blk->slot = vote_slot;
@@ -152,8 +145,9 @@ fd_notar_count_vote( fd_notar_t * notar,
152145
notar_slot->block_ids[notar_slot->block_ids_cnt++] = *vote_block_id;
153146
}
154147
notar_blk->stake += vtr->stake;
155-
notar_blk->dup_conf = (double)notar_blk->stake / (double)total_stake > 0.52; /* duplicate confirmed if > 52% stake */
156-
return notar_blk->dup_conf;
148+
notar_blk->dup_conf = ((double)notar_blk->stake / (double)total_stake) > 0.52;
149+
notar_blk->opt_conf = ((double)notar_blk->stake / (double)total_stake) > (2.0/3.0);
150+
return notar_blk;
157151
}
158152

159153
void

src/choreo/notar/fd_notar.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
important in two contexts:
1111
1212
1. When becoming leader, we need to check that our "previous"
13-
leader block _as of_ the parent slot we're building on, has
14-
propagated. If it's not propagated, we need to instead
15-
retransmit our last block that failed to propagate. "Previous"
16-
is quoted, because there is a grace period of one leader
17-
rotation for leader blocks to propagate.
13+
leader block _as of_ the parent slot we're building on, has
14+
propagated. If it's not propagated, we need to instead
15+
retransmit our last block that failed to propagate. "Previous"
16+
is quoted, because there is a grace period of one leader
17+
rotation for leader blocks to propagate.
1818
1919
2. When voting, we need to check our previous leader block _as of_
20-
the slot we're voting for has propagated (unless we're voting
21-
for one of our leader blocks). We cannot vote for slots in
22-
which our last leader block failed to propagate.
20+
the slot we're voting for has propagated (unless we're voting
21+
for one of our leader blocks). We cannot vote for slots in
22+
which our last leader block failed to propagate.
2323
2424
- duplicate confirmed: a block is duplicate confirmed if it has
2525
received votes from at least 52% of stake in the cluster. The
@@ -85,6 +85,10 @@
8585
#define FD_NOTAR_PARANOID 1
8686
#endif
8787

88+
#define FD_NOTAR_FLAG_CONFIRMED_PROPAGATED (0)
89+
#define FD_NOTAR_FLAG_CONFIRMED_DUPLICATE (1)
90+
#define FD_NOTAR_FLAG_CONFIRMED_OPTIMISTIC (2)
91+
8892
#define SET_NAME fd_notar_slot_vtrs
8993
#define SET_MAX FD_VOTER_MAX
9094
#include "../../util/tmpl/fd_set.c"
@@ -95,7 +99,7 @@ struct fd_notar_slot {
9599
ulong prev_leader_slot; /* previous slot in which we were leader */
96100
ulong stake; /* amount of stake that has voted for this slot */
97101
int is_leader; /* whether this slot was our own leader slot */
98-
int is_propagated; /* whether this slot has reached 33% of stake */
102+
int is_propagated; /* whether this slot has reached 1/3 of stake */
99103

100104
fd_hash_t block_ids[FD_VOTER_MAX]; /* one block id per voter per slot */
101105
ulong block_ids_cnt; /* count of block ids */
@@ -105,13 +109,13 @@ struct fd_notar_slot {
105109
};
106110
typedef struct fd_notar_slot fd_notar_slot_t;
107111

108-
109112
struct fd_notar_blk {
110113
fd_hash_t block_id; /* map key */
111114
uint hash; /* reserved for fd_map_dynamic */
112115
ulong slot; /* slot associated with this block */
113116
ulong stake; /* sum of stake that has voted for this block_id */
114117
int dup_conf; /* whether this block has reached 52% of stake */
118+
int opt_conf; /* whether this block has reached 2/3 of stake */
115119
};
116120
typedef struct fd_notar_blk fd_notar_blk_t;
117121

@@ -161,7 +165,7 @@ struct __attribute__((aligned(128UL))) fd_notar {
161165
ulong epoch; /* highest replayed epoch */
162166
ulong lo_wmark; /* notar ignores votes < lo_wmark */
163167
ulong hi_wmark; /* notar ignores votes > hi_wmark */
164-
ulong slot_max; /* maximum slot number */
168+
ulong slot_max; /* maximum number of slots notar can track */
165169

166170
fd_notar_slot_t * slot_map; /* tracks who has voted for a given slot */
167171
fd_notar_blk_t * blk_map; /* tracks amount of stake for a given block (keyed by block id) */
@@ -237,7 +241,7 @@ fd_notar_delete( void * notar );
237241
account in the current epoch, slot is slot being voted for, block_id
238242
is the voter's proposed block id for this vote slot. */
239243

240-
int
244+
fd_notar_blk_t *
241245
fd_notar_count_vote( fd_notar_t * notar,
242246
ulong total_stake,
243247
fd_pubkey_t const * addr,

src/choreo/tower/fd_tower.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ fd_tower_to_vote_txn( fd_tower_t const * tower,
641641
for( fd_tower_iter_t iter = fd_tower_iter_init( tower );
642642
!fd_tower_iter_done( tower, iter );
643643
iter = fd_tower_iter_next( tower, iter ) ) {
644-
fd_tower_t const * vote = fd_tower_iter_ele_const( tower, iter );
644+
fd_tower_t const * vote = fd_tower_iter_ele_const( tower, iter );
645645
tower_sync.lockouts[i].offset = vote->slot - prev;
646646
tower_sync.lockouts[i].confirmation_count = (uchar)vote->conf;
647647
prev = vote->slot;

src/disco/gui/fd_gui.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,27 +2428,22 @@ fd_gui_handle_rooted_slot( fd_gui_t * gui, ulong root_slot ) {
24282428
fd_http_server_ws_broadcast( gui->http );
24292429
}
24302430

2431-
/* fd_gui_handle_tower_update handles updates from the tower tile, which
2432-
manages consensus related fork switching, rooting, slot confirmation. */
2431+
/* fd_gui_handle_tower_slot_done handles slot_done frags from the tower
2432+
tile, which provides the reset slot and vote slot. */
24332433
void
2434-
fd_gui_handle_tower_update( fd_gui_t * gui,
2435-
fd_tower_slot_done_t const * tower,
2436-
long now ) {
2434+
fd_gui_handle_tower_slot_done( fd_gui_t * gui,
2435+
fd_tower_slot_done_t const * slot_done,
2436+
long now ) {
24372437
(void)now;
24382438

2439-
/* handle new root */
2440-
if( FD_LIKELY( tower->root_slot!=ULONG_MAX && gui->summary.slot_rooted!=tower->root_slot ) ) {
2441-
fd_gui_handle_rooted_slot( gui, tower->root_slot );
2442-
}
2443-
2444-
if( FD_UNLIKELY( gui->summary.vote_distance!=tower->reset_slot-tower->vote_slot ) ) {
2445-
gui->summary.vote_distance = tower->reset_slot-tower->vote_slot;
2439+
if( FD_UNLIKELY( gui->summary.vote_distance!=slot_done->reset_slot-slot_done->vote_slot ) ) {
2440+
gui->summary.vote_distance = slot_done->reset_slot-slot_done->vote_slot; /* TODO doesn't seem correct? */
24462441
fd_gui_printf_vote_distance( gui );
24472442
fd_http_server_ws_broadcast( gui->http );
24482443
}
24492444

24502445
if( FD_LIKELY( gui->summary.vote_state!=FD_GUI_VOTE_STATE_NON_VOTING ) ) {
2451-
if( FD_UNLIKELY( tower->vote_slot==ULONG_MAX || (tower->vote_slot+150UL)<tower->reset_slot ) ) {
2446+
if( FD_UNLIKELY( slot_done->vote_slot==ULONG_MAX || (slot_done->vote_slot+150UL)<slot_done->reset_slot ) ) {
24522447
if( FD_UNLIKELY( gui->summary.vote_state!=FD_GUI_VOTE_STATE_DELINQUENT ) ) {
24532448
gui->summary.vote_state = FD_GUI_VOTE_STATE_DELINQUENT;
24542449
fd_gui_printf_vote_state( gui );
@@ -2462,6 +2457,22 @@ fd_gui_handle_tower_update( fd_gui_t * gui,
24622457
}
24632458
}
24642459
}
2460+
}
2461+
2462+
/* fd_gui_handle_tower_slot_confirmed handles slot_confirmed frags from
2463+
the tower tile, which indicate when slots are optimistically
2464+
confirmed or rooted. */
2465+
2466+
void
2467+
fd_gui_handle_tower_slot_confirmed( fd_gui_t * gui,
2468+
fd_tower_slot_confirmed_t const * slot_confirmed,
2469+
long now ) {
2470+
(void)now;
2471+
2472+
/* handle new root */
2473+
if( FD_LIKELY( slot_confirmed->kind==FD_TOWER_SLOT_CONFIRMED_ROOTED && gui->summary.slot_rooted!=slot_confirmed->slot ) ) {
2474+
fd_gui_handle_rooted_slot( gui, slot_confirmed->slot );
2475+
}
24652476

24662477
/* todo ... optimistic confirmation, waiting on fd_ghost / fd_notar */
24672478
}

src/disco/gui/fd_gui.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,10 +833,15 @@ fd_gui_handle_leader_schedule( fd_gui_t * gui,
833833
long now );
834834

835835
void
836-
fd_gui_handle_tower_update( fd_gui_t * gui,
836+
fd_gui_handle_tower_slot_done( fd_gui_t * gui,
837837
fd_tower_slot_done_t const * msg,
838838
long now );
839839

840+
void
841+
fd_gui_handle_tower_slot_confirmed( fd_gui_t * gui,
842+
fd_tower_slot_confirmed_t const * slot_confirmed,
843+
long now );
844+
840845
void
841846
fd_gui_handle_replay_update( fd_gui_t * gui,
842847
fd_gui_slot_completed_t * slot_completed,

src/disco/gui/fd_gui_tile.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,11 @@ after_frag( fd_gui_ctx_t * ctx,
385385
case IN_KIND_TOWER_OUT: {
386386
FD_TEST( ctx->is_full_client );
387387
if( FD_LIKELY( sig==FD_TOWER_SIG_SLOT_DONE )) {
388-
fd_tower_slot_done_t const * tower = (fd_tower_slot_done_t const *)ctx->buf;
389-
fd_gui_handle_tower_update( ctx->gui, tower, fd_clock_now( ctx->clock ) );
388+
fd_tower_slot_done_t const * slot_done = (fd_tower_slot_done_t const *)ctx->buf;
389+
fd_gui_handle_tower_slot_done( ctx->gui, slot_done, fd_clock_now( ctx->clock ) );
390+
} else if ( FD_LIKELY( sig==FD_TOWER_SIG_SLOT_CONFIRMED ) ) {
391+
fd_tower_slot_confirmed_t const * slot_confirmed = (fd_tower_slot_confirmed_t const *)ctx->buf;
392+
fd_gui_handle_tower_slot_confirmed( ctx->gui, slot_confirmed, fd_clock_now( ctx->clock ) );
390393
}
391394
break;
392395
}

src/discof/backtest/fd_backtest_tile.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,6 @@ returnable_frag( fd_backt_tile_t * ctx,
308308
dst->vote_slot = msg->slot;
309309
dst->reset_slot = msg->slot;
310310
dst->reset_block_id = msg->block_id;
311-
dst->root_slot = msg->slot;
312-
dst->root_block_id = msg->block_id;
313311

314312
fd_stem_publish( stem, ctx->tower_out->idx, 0UL, ctx->tower_out->chunk, sizeof(fd_tower_slot_done_t), 0UL, tspub, fd_frag_meta_ts_comp( fd_tickcount() ) );
315313
ctx->tower_out->chunk = fd_dcache_compact_next( ctx->tower_out->chunk, sizeof(fd_tower_slot_done_t), ctx->tower_out->chunk0, ctx->tower_out->wmark );

src/discof/repair/fd_repair_tile.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,8 +795,12 @@ after_frag( ctx_t * ctx,
795795
}
796796

797797
if( FD_UNLIKELY( in_kind==IN_KIND_TOWER ) ) {
798-
fd_tower_slot_done_t const * msg = (fd_tower_slot_done_t const *)fd_type_pun_const( ctx->buffer );
799-
if( FD_LIKELY( msg->new_root ) ) fd_forest_publish( ctx->forest, msg->root_slot );
798+
if( FD_LIKELY( sig == FD_TOWER_SIG_SLOT_CONFIRMED ) ) {
799+
fd_tower_slot_confirmed_t const * msg = (fd_tower_slot_confirmed_t const *)fd_type_pun_const( ctx->buffer );
800+
if( FD_LIKELY( msg->kind==FD_TOWER_SLOT_CONFIRMED_ROOTED ) ) {
801+
fd_forest_publish( ctx->forest, msg->slot );
802+
}
803+
}
800804
return;
801805
}
802806

@@ -806,12 +810,14 @@ after_frag( ctx_t * ctx,
806810
}
807811

808812
if( FD_UNLIKELY( in_kind==IN_KIND_SHRED ) ) {
813+
809814
/* There are 3 message types from shred:
810815
1. resolver evict - incomplete FEC set is evicted by resolver
811816
2. fec complete - FEC set is completed by resolver. Also contains a shred.
812817
3. shred - new shred
813818
814819
Msgs 2 and 3 have a shred header in ctx->buffer */
820+
815821
int resolver_evicted = sz == 0;
816822
int fec_completes = sz == FD_SHRED_DATA_HEADER_SZ + sizeof(fd_hash_t) + sizeof(fd_hash_t) + sizeof(int);
817823
if( FD_UNLIKELY( resolver_evicted ) ) {

src/discof/replay/fd_replay_tile.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct fd_replay_tile {
146146
fd_txncache_t * txncache;
147147
fd_store_t * store;
148148
fd_banks_t * banks;
149+
ulong reset_bank_idx; /* most recent reset bank idx, used for determining root distance */
149150

150151
/* This flag is 1 If we have seen a vote signature that our node has
151152
sent out get rooted at least one time. The value is 0 otherwise.
@@ -2123,9 +2124,9 @@ process_exec_task_done( fd_replay_tile_t * ctx,
21232124
}
21242125

21252126
static void
2126-
process_tower_update( fd_replay_tile_t * ctx,
2127-
fd_stem_context_t * stem,
2128-
fd_tower_slot_done_t const * msg ) {
2127+
process_tower_slot_done( fd_replay_tile_t * ctx,
2128+
fd_stem_context_t * stem,
2129+
fd_tower_slot_done_t const * msg ) {
21292130
ctx->reset_block_id = msg->reset_block_id;
21302131
ctx->reset_slot = msg->reset_slot;
21312132
ctx->reset_timestamp_nanos = fd_log_wallclock();
@@ -2148,7 +2149,6 @@ process_tower_update( fd_replay_tile_t * ctx,
21482149
FD_LOG_CRIT(( "invariant violation: bank not found for bank index %lu", reset_bank_idx ));
21492150
}
21502151

2151-
if( FD_LIKELY( msg->root_slot!=ULONG_MAX ) ) FD_TEST( msg->root_slot<=msg->reset_slot );
21522152
ctx->reset_bank = bank;
21532153

21542154
if( FD_LIKELY( ctx->replay_out->idx!=ULONG_MAX ) ) {
@@ -2184,22 +2184,36 @@ process_tower_update( fd_replay_tile_t * ctx,
21842184
ctx->replay_out->chunk = fd_dcache_compact_next( ctx->replay_out->chunk, sizeof(fd_poh_reset_t), ctx->replay_out->chunk0, ctx->replay_out->wmark );
21852185
}
21862186

2187-
FD_LOG_INFO(( "tower_update(reset_slot=%lu, next_leader_slot=%lu, vote_slot=%lu, root_slot=%lu, root_block_id=%s)", msg->reset_slot, ctx->next_leader_slot, msg->vote_slot, msg->root_slot, FD_BASE58_ENC_32_ALLOCA( &msg->root_block_id ) ));
2187+
FD_LOG_INFO(( "tower_slot_done(reset_slot=%lu, next_leader_slot=%lu, vote_slot=%lu)", msg->reset_slot, ctx->next_leader_slot, msg->vote_slot ));
21882188
maybe_become_leader( ctx, stem );
2189+
}
21892190

2190-
if( FD_LIKELY( msg->root_slot!=ULONG_MAX ) ) {
2191+
static void
2192+
process_tower_slot_confirmed( fd_replay_tile_t * ctx,
2193+
fd_stem_context_t * stem,
2194+
fd_tower_slot_confirmed_t const * msg ) {
2195+
if( FD_LIKELY( msg->kind==FD_TOWER_SLOT_CONFIRMED_ROOTED ) ) {
21912196

2192-
FD_TEST( msg->root_slot>=ctx->consensus_root_slot );
2193-
fd_block_id_ele_t * block_id_ele = fd_block_id_map_ele_query( ctx->block_id_map, &msg->root_block_id, NULL, ctx->block_id_arr );
2197+
FD_TEST( msg->slot>=ctx->consensus_root_slot );
2198+
fd_block_id_ele_t * block_id_ele = fd_block_id_map_ele_query( ctx->block_id_map, &msg->block_id, NULL, ctx->block_id_arr );
21942199
FD_TEST( block_id_ele );
21952200

2196-
ctx->consensus_root_slot = msg->root_slot;
2197-
ctx->consensus_root = msg->root_block_id;
2201+
ctx->consensus_root_slot = msg->slot;
2202+
ctx->consensus_root = msg->block_id;
21982203
ctx->consensus_root_bank_idx = fd_block_id_ele_get_idx( ctx->block_id_arr, block_id_ele );
21992204

22002205
publish_root_advanced( ctx, stem );
22012206
}
22022207

2208+
/* If tower roots a slot, it always publishes the frag immediately
2209+
after the slot_done message, so ctx->reset_bank_idx should still be
2210+
valid at this point (it could not have been published away). */
2211+
2212+
fd_bank_t * bank = fd_banks_bank_query( ctx->banks, ctx->reset_bank_idx );
2213+
if( FD_UNLIKELY( !bank ) ) {
2214+
FD_LOG_CRIT(( "invariant violation: bank not found for bank index %lu", ctx->reset_bank_idx ));
2215+
}
2216+
22032217
ulong distance = 0UL;
22042218
fd_bank_t * parent = bank;
22052219
while( parent ) {
@@ -2369,7 +2383,8 @@ returnable_frag( fd_replay_tile_t * ctx,
23692383
break;
23702384
}
23712385
case IN_KIND_TOWER: {
2372-
if( FD_LIKELY( sig==FD_TOWER_SIG_SLOT_DONE ) ) process_tower_update( ctx, stem, fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk ) );
2386+
if ( FD_LIKELY( sig==FD_TOWER_SIG_SLOT_DONE ) ) process_tower_slot_done ( ctx, stem, fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk ) );
2387+
else if( FD_LIKELY( sig==FD_TOWER_SIG_SLOT_CONFIRMED ) ) process_tower_slot_confirmed( ctx, stem, fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk ) );
23732388
break;
23742389
}
23752390
case IN_KIND_SHRED: {

0 commit comments

Comments
 (0)