Skip to content

Commit 5fb8695

Browse files
committed
gui: add metrics for txn chart
1 parent 44ee09a commit 5fb8695

File tree

17 files changed

+761
-623
lines changed

17 files changed

+761
-623
lines changed

book/api/websocket.md

Lines changed: 87 additions & 23 deletions
Large diffs are not rendered by default.

src/disco/gui/dist/assets/index-COvgb_-s.js

Lines changed: 0 additions & 251 deletions
This file was deleted.

src/disco/gui/dist/assets/index-CXR6J9xZ.js

Lines changed: 251 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/disco/gui/dist/assets/index-D9G9NFun.css renamed to src/disco/gui/dist/assets/index-CeMmwSX_.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/disco/gui/dist/assets/index-Cc2d2UuJ.js renamed to src/disco/gui/dist/assets/index-DEoU3Mlp.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/disco/gui/dist/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
/>
2323
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
2424
<title>Firedancer</title>
25-
<script type="module" crossorigin src="/assets/index-COvgb_-s.js"></script>
26-
<link rel="stylesheet" crossorigin href="/assets/index-D9G9NFun.css">
25+
<script type="module" crossorigin src="/assets/index-CXR6J9xZ.js"></script>
26+
<link rel="stylesheet" crossorigin href="/assets/index-CeMmwSX_.css">
2727
</head>
2828
<body>
2929
<div id="root"></div>

src/disco/gui/fd_gui.c

Lines changed: 104 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "../../ballet/base58/fd_base58.h"
88
#include "../../ballet/json/cJSON.h"
99
#include "../../flamenco/genesis/fd_genesis_cluster.h"
10+
#include "../../disco/pack/fd_pack.h"
11+
#include "../../disco/pack/fd_pack_cost.h"
1012

1113
FD_FN_CONST ulong
1214
fd_gui_align( void ) {
@@ -103,8 +105,6 @@ fd_gui_new( void * shmem,
103105
gui->summary.tile_timers_history_idx = 0UL;
104106
for( ulong i=0UL; i<FD_GUI_TILE_TIMER_LEADER_CNT; i++ ) gui->summary.tile_timers_leader_history_slot[ i ] = ULONG_MAX;
105107

106-
gui->cus.offset = 0UL;
107-
108108
gui->block_engine.has_block_engine = 0;
109109

110110
gui->epoch.has_epoch[ 0 ] = 0;
@@ -115,6 +115,7 @@ fd_gui_new( void * shmem,
115115
gui->validator_info.info_cnt = 0UL;
116116

117117
for( ulong i=0UL; i<FD_GUI_SLOTS_CNT; i++ ) gui->slots[ i ]->slot = ULONG_MAX;
118+
gui->pack_txn_idx = 0UL;
118119

119120
return gui;
120121
}
@@ -970,15 +971,16 @@ fd_gui_clear_slot( fd_gui_t * gui,
970971
slot->leader_state = FD_GUI_SLOT_LEADER_UNSTARTED;
971972
slot->completed_time = LONG_MAX;
972973

973-
slot->cus.leader_start_time = LONG_MAX;
974-
slot->cus.leader_end_time = LONG_MAX;
975-
slot->cus.max_compute_units = UINT_MAX;
976-
slot->cus.microblocks_upper_bound = USHORT_MAX;
977-
slot->cus.begin_microblocks = 0U;
978-
slot->cus.end_microblocks = 0U;
979-
slot->cus.reference_ticks = LONG_MAX;
980-
slot->cus.reference_nanos = LONG_MAX;
981-
for( ulong i=0UL; i<65UL; i++ ) slot->cus.has_offset[ i ] = 0;
974+
slot->txs.leader_start_time = LONG_MAX;
975+
slot->txs.leader_end_time = LONG_MAX;
976+
slot->txs.max_compute_units = UINT_MAX;
977+
slot->txs.microblocks_upper_bound = USHORT_MAX;
978+
slot->txs.begin_microblocks = 0U;
979+
slot->txs.end_microblocks = 0U;
980+
slot->txs.reference_ticks = LONG_MAX;
981+
slot->txs.reference_nanos = LONG_MAX;
982+
slot->txs.start_offset = ULONG_MAX;
983+
slot->txs.end_offset = ULONG_MAX;
982984

983985
if( FD_LIKELY( slot->mine ) ) {
984986
/* All slots start off not skipped, until we see it get off the reset
@@ -1618,96 +1620,130 @@ fd_gui_plugin_message( fd_gui_t * gui,
16181620
}
16191621
}
16201622

1623+
static void
1624+
fd_gui_init_slot_txns( fd_gui_t * gui,
1625+
long tickcount,
1626+
ulong _slot ) {
1627+
fd_gui_slot_t * slot = gui->slots[ _slot % FD_GUI_SLOTS_CNT ];
1628+
if( FD_UNLIKELY( slot->slot!=_slot ) ) fd_gui_clear_slot( gui, _slot, ULONG_MAX );
1629+
1630+
/* initialize reference timestamp */
1631+
if ( FD_UNLIKELY( LONG_MAX==slot->txs.reference_ticks ) ) {
1632+
slot->txs.reference_ticks = tickcount;
1633+
slot->txs.reference_nanos = fd_log_wallclock() - (long)((double)(fd_tickcount() - slot->txs.reference_ticks) / fd_tempo_tick_per_ns( NULL ));
1634+
}
1635+
}
1636+
16211637
void
16221638
fd_gui_became_leader( fd_gui_t * gui,
1639+
long tickcount,
16231640
ulong _slot,
16241641
long start_time_nanos,
16251642
long end_time_nanos,
16261643
ulong max_compute_units,
16271644
ulong max_microblocks ) {
1645+
fd_gui_init_slot_txns( gui, tickcount, _slot );
16281646
fd_gui_slot_t * slot = gui->slots[ _slot % FD_GUI_SLOTS_CNT ];
1629-
if( FD_UNLIKELY( slot->slot!=_slot ) ) fd_gui_clear_slot( gui, _slot, ULONG_MAX );
1630-
1631-
slot->cus.leader_start_time = start_time_nanos;
16321647

1633-
long tickcount = fd_tickcount();
1634-
if( FD_LIKELY( slot->cus.reference_ticks==LONG_MAX ) ) slot->cus.reference_ticks = tickcount;
1635-
slot->cus.reference_nanos = fd_log_wallclock() - (long)((double)(tickcount - slot->cus.reference_ticks) / fd_tempo_tick_per_ns( NULL ));
1636-
1637-
slot->cus.leader_end_time = end_time_nanos;
1638-
slot->cus.max_compute_units = (uint)max_compute_units;
1639-
if( FD_LIKELY( slot->cus.microblocks_upper_bound==USHORT_MAX ) ) slot->cus.microblocks_upper_bound = (ushort)max_microblocks;
1648+
slot->txs.leader_start_time = start_time_nanos;
1649+
slot->txs.leader_end_time = end_time_nanos;
1650+
slot->txs.max_compute_units = (uint)max_compute_units;
1651+
if( FD_LIKELY( slot->txs.microblocks_upper_bound==USHORT_MAX ) ) slot->txs.microblocks_upper_bound = (ushort)max_microblocks;
16401652
}
16411653

16421654
void
16431655
fd_gui_unbecame_leader( fd_gui_t * gui,
1656+
long tickcount,
16441657
ulong _slot,
16451658
ulong microblocks_in_slot ) {
1659+
fd_gui_init_slot_txns( gui, tickcount, _slot );
16461660
fd_gui_slot_t * slot = gui->slots[ _slot % FD_GUI_SLOTS_CNT ];
1647-
if( FD_UNLIKELY( slot->slot!=_slot ) ) fd_gui_clear_slot( gui, _slot, ULONG_MAX );
16481661

1649-
slot->cus.microblocks_upper_bound = (ushort)microblocks_in_slot;
1662+
slot->txs.microblocks_upper_bound = (ushort)microblocks_in_slot;
16501663
}
16511664

16521665
void
1653-
fd_gui_execution_begin( fd_gui_t * gui,
1654-
long tickcount,
1655-
ulong _slot,
1656-
ulong bank_idx,
1657-
ulong txn_cnt,
1658-
fd_txn_p_t * txns ) {
1666+
fd_gui_microblock_execution_begin( fd_gui_t * gui,
1667+
long tickcount,
1668+
ulong _slot,
1669+
fd_txn_p_t * txns,
1670+
ulong txn_cnt,
1671+
uint microblock_idx,
1672+
ulong pack_txn_idx ) {
1673+
fd_gui_init_slot_txns( gui, tickcount, _slot );
16591674
fd_gui_slot_t * slot = gui->slots[ _slot % FD_GUI_SLOTS_CNT ];
1660-
if( FD_UNLIKELY( slot->slot!=_slot ) ) fd_gui_clear_slot( gui, _slot, ULONG_MAX );
16611675

1662-
if( FD_UNLIKELY( !slot->cus.has_offset[ 64UL ] ) ) slot->cus.start_offset[ 64UL ] = gui->cus.offset;
1663-
slot->cus.has_offset[ 64UL ] = 1;
1664-
if( FD_UNLIKELY( slot->cus.reference_ticks==LONG_MAX ) ) slot->cus.reference_ticks = tickcount;
1676+
if( FD_UNLIKELY( slot->txs.start_offset==ULONG_MAX ) ) slot->txs.start_offset = pack_txn_idx;
1677+
else slot->txs.start_offset = fd_ulong_min( slot->txs.start_offset, pack_txn_idx );
1678+
1679+
gui->pack_txn_idx = fd_ulong_max( gui->pack_txn_idx, pack_txn_idx+txn_cnt-1UL );
16651680

16661681
for( ulong i=0UL; i<txn_cnt; i++ ) {
1667-
fd_txn_p_t * txn = &txns[ i ];
1668-
1669-
ulong comp = fd_gui_cu_history_compress( FD_GUI_EXECUTION_TYPE_BEGIN,
1670-
bank_idx,
1671-
txn->pack_cu.non_execution_cus + txn->pack_cu.requested_exec_plus_acct_data_cus,
1672-
i==0UL,
1673-
slot->cus.reference_ticks,
1674-
tickcount );
1675-
gui->cus.history[ gui->cus.offset%FD_GUI_COMPUTE_UNITS_HISTORY_SZ ] = comp;
1676-
gui->cus.offset++;
1682+
fd_txn_p_t * txn_payload = &txns[ i ];
1683+
fd_txn_t * txn = TXN( txn_payload );
1684+
1685+
ulong priority_rewards = ULONG_MAX;
1686+
ulong requested_execution_cus = ULONG_MAX;
1687+
ulong precompile_sigs = ULONG_MAX;
1688+
ulong requested_loaded_accounts_data_cost = ULONG_MAX;
1689+
uint _flags;
1690+
ulong cost_estimate = fd_pack_compute_cost( txn, txn_payload->payload, &_flags, &requested_execution_cus, &priority_rewards, &precompile_sigs, &requested_loaded_accounts_data_cost );
1691+
1692+
fd_gui_txn_t * txn_entry = gui->txs[ (pack_txn_idx + i)%FD_GUI_TXN_HISTORY_SZ ];
1693+
txn_entry->compute_units_estimated = cost_estimate & 0x1FFFFFU;
1694+
txn_entry->compute_units_requested = requested_execution_cus & 0x1FFFFFU;
1695+
txn_entry->priority_fee = priority_rewards;
1696+
txn_entry->timestamp_delta_start_nanos = (int)((double)(tickcount - slot->txs.reference_ticks) / fd_tempo_tick_per_ns( NULL ));
1697+
txn_entry->microblock_idx = microblock_idx;
1698+
txn_entry->flags |= (uchar)FD_GUI_TXN_FLAGS_STARTED;
1699+
txn_entry->flags |= (uchar)fd_uint_if(txn_payload->flags & FD_TXN_P_FLAGS_IS_SIMPLE_VOTE, FD_GUI_TXN_FLAGS_IS_SIMPLE_VOTE, 0U);
1700+
txn_entry->flags |= (uchar)fd_uint_if((txn_payload->flags & FD_TXN_P_FLAGS_BUNDLE) || (txn_payload->flags & FD_TXN_P_FLAGS_INITIALIZER_BUNDLE), FD_GUI_TXN_FLAGS_FROM_BUNDLE, 0U);
16771701
}
16781702

1679-
slot->cus.end_offset[ 64UL ] = gui->cus.offset;
1680-
slot->cus.begin_microblocks = (ushort)(slot->cus.begin_microblocks + txn_cnt);
1703+
/* At the moment, bank publishes at most 1 transaction per microblock,
1704+
even if it received microblocks with multiple transactions
1705+
(i.e. a bundle). This means that we need to calulate microblock
1706+
count here based on the transaction count. */
1707+
slot->txs.begin_microblocks = (ushort)(slot->txs.begin_microblocks + txn_cnt);
16811708
}
16821709

16831710
void
1684-
fd_gui_execution_end( fd_gui_t * gui,
1685-
long tickcount,
1686-
ulong bank_idx,
1687-
int is_last_in_bundle,
1688-
ulong _slot,
1689-
ulong txn_cnt,
1690-
fd_txn_p_t * txns ) {
1711+
fd_gui_microblock_execution_end( fd_gui_t * gui,
1712+
long tickcount,
1713+
ulong bank_idx,
1714+
ulong _slot,
1715+
ulong txn_cnt,
1716+
fd_txn_p_t * txns,
1717+
ulong pack_txn_idx,
1718+
uchar txn_start_pct,
1719+
uchar txn_load_end_pct,
1720+
uchar txn_end_pct,
1721+
ulong tips ) {
1722+
if( FD_UNLIKELY( 1UL!=txn_cnt ) ) FD_LOG_ERR(( "gui expects 1 txn per microblock from bank, found %lu", txn_cnt ));
1723+
1724+
fd_gui_init_slot_txns( gui, tickcount, _slot );
16911725
fd_gui_slot_t * slot = gui->slots[ _slot % FD_GUI_SLOTS_CNT ];
1692-
if( FD_UNLIKELY( slot->slot!=_slot ) ) fd_gui_clear_slot( gui, _slot, ULONG_MAX );
16931726

1694-
if( FD_UNLIKELY( !slot->cus.has_offset[ bank_idx ] ) ) slot->cus.start_offset[ bank_idx ] = gui->cus.offset;
1695-
slot->cus.has_offset[ bank_idx ] = 1;
1696-
if( FD_UNLIKELY( slot->cus.reference_ticks==LONG_MAX ) ) slot->cus.reference_ticks = tickcount;
1727+
if( FD_UNLIKELY( slot->txs.end_offset==ULONG_MAX ) ) slot->txs.end_offset = pack_txn_idx + txn_cnt;
1728+
else slot->txs.end_offset = fd_ulong_max( slot->txs.end_offset, pack_txn_idx+txn_cnt );
1729+
1730+
gui->pack_txn_idx = fd_ulong_max( gui->pack_txn_idx, pack_txn_idx+txn_cnt-1UL );
16971731

16981732
for( ulong i=0UL; i<txn_cnt; i++ ) {
1699-
fd_txn_p_t * txn = &txns[ i ];
1700-
1701-
ulong comp = fd_gui_cu_history_compress( FD_GUI_EXECUTION_TYPE_END,
1702-
bank_idx,
1703-
txn->bank_cu.rebated_cus,
1704-
is_last_in_bundle,
1705-
slot->cus.reference_ticks,
1706-
tickcount );
1707-
gui->cus.history[ gui->cus.offset%FD_GUI_COMPUTE_UNITS_HISTORY_SZ ] = comp;
1708-
gui->cus.offset++;
1733+
fd_txn_p_t * txn_p = &txns[ i ];
1734+
1735+
fd_gui_txn_t * txn_entry = gui->txs[ (pack_txn_idx + i)%FD_GUI_TXN_HISTORY_SZ ];
1736+
txn_entry->bank_idx = bank_idx & 0x3FU;
1737+
txn_entry->actual_consumed_cus = txn_p->bank_cu.actual_consumed_cus & 0x1FFFFFU;
1738+
txn_entry->error_code = (txn_p->flags >> 24) & 0x3FU;
1739+
txn_entry->timestamp_delta_end_nanos = (int)((double)(tickcount - slot->txs.reference_ticks) / fd_tempo_tick_per_ns( NULL ));
1740+
txn_entry->txn_start_pct = txn_start_pct;
1741+
txn_entry->txn_load_end_pct = txn_load_end_pct;
1742+
txn_entry->txn_end_pct = txn_end_pct;
1743+
txn_entry->tips = tips;
1744+
txn_entry->flags |= (uchar)FD_GUI_TXN_FLAGS_ENDED;
1745+
txn_entry->flags |= (uchar)fd_uint_if(txn_p->flags & FD_TXN_P_FLAGS_EXECUTE_SUCCESS, FD_GUI_TXN_FLAGS_LANDED_IN_BLOCK, 0U);
17091746
}
17101747

1711-
slot->cus.end_offset[ bank_idx ] = gui->cus.offset;
1712-
slot->cus.end_microblocks = (ushort)(slot->cus.end_microblocks + txn_cnt);
1748+
slot->txs.end_microblocks = slot->txs.end_microblocks + (uint)txn_cnt;
17131749
}

0 commit comments

Comments
 (0)