Skip to content

gui: add wait for supermajority#8949

Draft
jherrera-jump wants to merge 2 commits intofiredancer-io:mainfrom
jherrera-jump:jherrera/gui-wait-for-supermajority
Draft

gui: add wait for supermajority#8949
jherrera-jump wants to merge 2 commits intofiredancer-io:mainfrom
jherrera-jump:jherrera/gui-wait-for-supermajority

Conversation

@jherrera-jump
Copy link
Contributor

No description provided.

@jherrera-jump jherrera-jump force-pushed the jherrera/gui-wait-for-supermajority branch 2 times, most recently from 6d2e371 to 2cd354d Compare March 17, 2026 22:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the Firedancer GUI/WebSocket API to expose “waiting for supermajority” (WFS) boot progress details, including a new boot phase, additional summary fields, and a new websocket topic that streams which staked peers are currently offline during WFS.

Changes:

  • Add a new boot progress phase waiting_for_supermajority and export WFS-related progress/identity fields in the summary.boot_progress websocket payload.
  • Wire snapshot manifest messages into the GUI tile so the GUI/peers view can derive restart-attempt information and build the staked-peer set for WFS offline tracking.
  • Add a new websocket topic wfs_offline_peers.update that emits edge-triggered add/remove updates for staked peers that are offline/online during WFS.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/disco/topo/fd_topo.h Adds GUI tile config fields for WFS bank hash and expected shred version.
src/disco/gui/fd_gui_tile.c Adds a new GUI input link kind for snapshot manifests and initializes GUI WFS summary fields.
src/disco/gui/fd_gui_printf.h Declares a new peers printf function for wfs_offline_peers updates.
src/disco/gui/fd_gui_printf.c Emits WFS fields in summary.boot_progress and implements wfs_offline_peers.update serialization.
src/disco/gui/fd_gui_peers.h Adds WFS offline peer tracking structures and manifest handler declaration.
src/disco/gui/fd_gui_peers.c Builds WFS peer set from snapshot manifest, tracks online/offline transitions, and publishes websocket updates.
src/disco/gui/fd_gui.h Adds WFS fields to GUI summary and declares snapshot manifest handler; adds new boot progress phase constant.
src/disco/gui/fd_gui.c Integrates gossip WFS state into boot progress state machine; parses manifest to derive restart attempt.
src/app/firedancer/topology.c Wires snapin_manif into the GUI tile and passes WFS config values into GUI tile config.
book/api/websocket.md Documents new WFS summary fields, prev_stake, and the new wfs_offline_peers topic.

Comment on lines +1533 to +1535
if( FD_UNLIKELY( peers->wfs_peers[ i ].is_online ) ) peers->scratch.wfs_peers[ added_cnt++ ] = i;
}
fd_gui_peers_printf_wfs_offline_update( peers, peers->scratch.wfs_peers, peers->wfs_peers_cnt, NULL, 0UL );
Comment on lines +1093 to +1123
void
fd_gui_peers_handle_manifest( fd_gui_peers_ctx_t * peers,
fd_snapshot_manifest_t const * manifest ) {
fd_vote_stake_weight_t scratch[ FD_RUNTIME_MAX_VOTE_ACCOUNTS ];
ulong scratch_cnt = 0UL;
for( ulong i=0UL; i<manifest->vote_accounts_len; i++ ) {
if( FD_UNLIKELY( manifest->vote_accounts[ i ].stake==0UL ) ) continue;
fd_memcpy( scratch[ scratch_cnt ].id_key.uc, manifest->vote_accounts[ i ].node_account_pubkey, 32UL );
fd_memcpy( scratch[ scratch_cnt ].vote_key.uc, manifest->vote_accounts[ i ].vote_account_pubkey, 32UL );
scratch[ scratch_cnt ].stake = manifest->vote_accounts[ i ].stake;
scratch_cnt++;
}

/* Mirrors gossip WFS logic */
fd_stake_weight_t id_weights[ FD_RUNTIME_MAX_VOTE_ACCOUNTS ];
ulong id_cnt = compute_id_weights_from_vote_weights( id_weights, scratch, scratch_cnt );

/* Restore invariant: sorted by identity key */
fd_stake_weight_key_sort_inplace( id_weights, id_cnt );

for( ulong i=0UL; i<id_cnt; i++ ) {
peers->wfs_peers[ i ].identity_key = id_weights[ i ].key;
peers->wfs_peers[ i ].stake = id_weights[ i ].stake;
peers->wfs_peers[ i ].is_online = 0;
peers->wfs_peers[ i ].wallclock_nanos = 0L;
peers->wfs_peers[ i ].fresh_prev = ULONG_MAX;
peers->wfs_peers[ i ].fresh_next = ULONG_MAX;
}
peers->wfs_peers_cnt = id_cnt;
wfs_fresh_dlist_join( wfs_fresh_dlist_new( peers->wfs_fresh_dlist ) );
}
}
FD_TEST( found );
#endif
wfs_handle_contact_info_remove( peers, (fd_pubkey_t *)update->origin );
differently from the `gossip.network_stats.health` activated stake
(which is from the start of the epoch). These fields account for any
stake that is activating/deactivating in the current epoch and any stake
that was explicilty undelegated prior to restart (e.g. inactive testnet
Comment on lines +583 to +584
| wait_for_supermajority_total_peers | `number\|null` | If the phase is at least `waiting_for_supermajority`, this is the total number of peers with a active stake |
| wait_for_supermajority_connected_peers | `number\|null` | If the phase is at least `waiting_for_supermajority`, this is the number of peers with active stake currently active on gossip and waiting for the restart threshold |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants