Skip to content

Commit 51d493f

Browse files
committed
feat(tower): rework confirmed frags and vote txn verify + minor fixes
1 parent 9017cc7 commit 51d493f

File tree

9 files changed

+214
-85
lines changed

9 files changed

+214
-85
lines changed

src/app/firedancer/topology.c

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

598-
/**/ fd_topob_tile_in( topo, "replay", 0UL, "metric_in", "poh_replay", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
599-
FOR(exec_tile_cnt) fd_topob_tile_in( topo, "exec", i, "metric_in", "replay_exec", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
598+
/**/ fd_topob_tile_in ( topo, "replay", 0UL, "metric_in", "poh_replay", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
599+
FOR(exec_tile_cnt) fd_topob_tile_in ( topo, "exec", i, "metric_in", "replay_exec", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
600+
601+
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "dedup_resolv", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
600602
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "genesi_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
601603
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "gossip_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
602604
/**/ fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "replay_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
603605
if( snapshots_enabled ) {
604606
fd_topob_tile_in ( topo, "tower", 0UL, "metric_in", "snapin_manif", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
605607
}
606608
/**/ fd_topob_tile_out( topo, "tower", 0UL, "tower_out", 0UL );
609+
607610
/**/ fd_topob_tile_in ( topo, "send", 0UL, "metric_in", "replay_stake", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
608611
/**/ fd_topob_tile_in ( topo, "send", 0UL, "metric_in", "gossip_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
609612
/**/ 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/disco/gui/fd_gui.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,27 +2425,23 @@ fd_gui_handle_rooted_slot( fd_gui_t * gui, ulong root_slot ) {
24252425
fd_http_server_ws_broadcast( gui->http );
24262426
}
24272427

2428-
/* fd_gui_handle_tower_update handles updates from the tower tile, which
2429-
manages consensus related fork switching, rooting, slot confirmation. */
2428+
/* fd_gui_handle_tower_slot_done handles slot_done frags from the tower
2429+
tile, which manages consensus related fork switching, rooting, slot
2430+
confirmation. */
24302431
void
2431-
fd_gui_handle_tower_update( fd_gui_t * gui,
2432-
fd_tower_slot_done_t const * tower,
2433-
long now ) {
2432+
fd_gui_handle_tower_slot_done( fd_gui_t * gui,
2433+
fd_tower_slot_done_t const * slot_done,
2434+
long now ) {
24342435
(void)now;
24352436

2436-
/* handle new root */
2437-
if( FD_LIKELY( tower->root_slot!=ULONG_MAX && gui->summary.slot_rooted!=tower->root_slot ) ) {
2438-
fd_gui_handle_rooted_slot( gui, tower->root_slot );
2439-
}
2440-
2441-
if( FD_UNLIKELY( gui->summary.vote_distance!=tower->reset_slot-tower->vote_slot ) ) {
2442-
gui->summary.vote_distance = tower->reset_slot-tower->vote_slot;
2437+
if( FD_UNLIKELY( gui->summary.vote_distance!=slot_done->reset_slot-slot_done->vote_slot ) ) {
2438+
gui->summary.vote_distance = slot_done->reset_slot-slot_done->vote_slot;
24432439
fd_gui_printf_vote_distance( gui );
24442440
fd_http_server_ws_broadcast( gui->http );
24452441
}
24462442

24472443
if( FD_LIKELY( gui->summary.vote_state!=FD_GUI_VOTE_STATE_NON_VOTING ) ) {
2448-
if( FD_UNLIKELY( tower->vote_slot==ULONG_MAX || (tower->vote_slot+150UL)<tower->reset_slot ) ) {
2444+
if( FD_UNLIKELY( slot_done->vote_slot==ULONG_MAX || (slot_done->vote_slot+150UL)<slot_done->reset_slot ) ) {
24492445
if( FD_UNLIKELY( gui->summary.vote_state!=FD_GUI_VOTE_STATE_DELINQUENT ) ) {
24502446
gui->summary.vote_state = FD_GUI_VOTE_STATE_DELINQUENT;
24512447
fd_gui_printf_vote_state( gui );
@@ -2463,6 +2459,24 @@ fd_gui_handle_tower_update( fd_gui_t * gui,
24632459
/* todo ... optimistic confirmation, waiting on fd_ghost / fd_notar */
24642460
}
24652461

2462+
/* fd_gui_handle_tower_update handles slot_confirmed frags from the
2463+
tower tile, which indicate when slots are optimistically confirmed or
2464+
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+
}
2476+
2477+
/* todo ... optimistic confirmation, waiting on fd_ghost / fd_notar */
2478+
}
2479+
24662480
void
24672481
fd_gui_handle_replay_update( fd_gui_t * gui,
24682482
fd_gui_slot_completed_t * slot_completed,

src/disco/gui/fd_gui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,7 @@ fd_gui_handle_leader_schedule( fd_gui_t * gui,
826826
long now );
827827

828828
void
829-
fd_gui_handle_tower_update( fd_gui_t * gui,
829+
fd_gui_handle_tower_slot_done( fd_gui_t * gui,
830830
fd_tower_slot_done_t const * msg,
831831
long now );
832832

src/disco/gui/fd_gui_tile.c

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

src/discof/repair/fd_repair_tile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ after_frag( ctx_t * ctx,
774774
fd_policy_reset ( ctx->policy, ctx->forest );
775775
}
776776
} else if( FD_LIKELY( sig == FD_TOWER_SIG_DUPLICATE_CONFIRMED ) ) {
777-
fd_tower_duplicate_confirmed_t const * msg = (fd_tower_duplicate_confirmed_t const *)fd_type_pun_const( ctx->buffer );
777+
fd_tower_slot_confirmed_t const * msg = (fd_tower_slot_confirmed_t const *)fd_type_pun_const( ctx->buffer );
778778
(void)msg;
779779
}
780780
return;

0 commit comments

Comments
 (0)