Line data Source code
1 : #ifndef HEADER_fd_src_disco_gui_fd_gui_h
2 : #define HEADER_fd_src_disco_gui_fd_gui_h
3 :
4 : #include "../fd_disco_base.h"
5 :
6 : #include "../pack/fd_microblock.h"
7 : #include "../../ballet/http/fd_http_server.h"
8 : #include "../../flamenco/types/fd_types.h"
9 : #include "../../flamenco/leaders/fd_leaders.h"
10 :
11 : #include "../topo/fd_topo.h"
12 :
13 0 : #define FD_GUI_SLOTS_CNT (864000UL)
14 0 : #define FD_GUI_TPS_HISTORY_WINDOW_DURATION_SECONDS (10L) /* 10 second moving average */
15 0 : #define FD_GUI_TPS_HISTORY_SAMPLE_CNT (150UL)
16 0 : #define FD_GUI_TILE_TIMER_SNAP_CNT (512UL)
17 0 : #define FD_GUI_TILE_TIMER_LEADER_CNT (4096UL)
18 0 : #define FD_GUI_TILE_TIMER_LEADER_DOWNSAMPLE_CNT (50UL)
19 : #define FD_GUI_TILE_TIMER_TILE_CNT (128UL)
20 :
21 0 : #define FD_GUI_SLOT_LEVEL_INCOMPLETE (0)
22 0 : #define FD_GUI_SLOT_LEVEL_COMPLETED (1)
23 0 : #define FD_GUI_SLOT_LEVEL_OPTIMISTICALLY_CONFIRMED (2)
24 0 : #define FD_GUI_SLOT_LEVEL_ROOTED (3)
25 0 : #define FD_GUI_SLOT_LEVEL_FINALIZED (4)
26 :
27 0 : #define FD_GUI_VOTE_STATE_NON_VOTING (0)
28 0 : #define FD_GUI_VOTE_STATE_VOTING (1)
29 0 : #define FD_GUI_VOTE_STATE_DELINQUENT (2)
30 :
31 0 : #define FD_GUI_START_PROGRESS_TYPE_INITIALIZING ( 0)
32 0 : #define FD_GUI_START_PROGRESS_TYPE_SEARCHING_FOR_FULL_SNAPSHOT ( 1)
33 0 : #define FD_GUI_START_PROGRESS_TYPE_DOWNLOADING_FULL_SNAPSHOT ( 2)
34 0 : #define FD_GUI_START_PROGRESS_TYPE_SEARCHING_FOR_INCREMENTAL_SNAPSHOT ( 3)
35 0 : #define FD_GUI_START_PROGRESS_TYPE_DOWNLOADING_INCREMENTAL_SNAPSHOT ( 4)
36 0 : #define FD_GUI_START_PROGRESS_TYPE_CLEANING_BLOCK_STORE ( 5)
37 0 : #define FD_GUI_START_PROGRESS_TYPE_CLEANING_ACCOUNTS ( 6)
38 0 : #define FD_GUI_START_PROGRESS_TYPE_LOADING_LEDGER ( 7)
39 0 : #define FD_GUI_START_PROGRESS_TYPE_PROCESSING_LEDGER ( 8)
40 0 : #define FD_GUI_START_PROGRESS_TYPE_STARTING_SERVICES ( 9)
41 0 : #define FD_GUI_START_PROGRESS_TYPE_HALTED (10)
42 0 : #define FD_GUI_START_PROGRESS_TYPE_WAITING_FOR_SUPERMAJORITY (11)
43 0 : #define FD_GUI_START_PROGRESS_TYPE_RUNNING (12)
44 :
45 : struct fd_gui_gossip_peer {
46 : fd_pubkey_t pubkey[ 1 ];
47 : ulong wallclock;
48 : ushort shred_version;
49 :
50 : int has_version;
51 : struct {
52 : ushort major;
53 : ushort minor;
54 : ushort patch;
55 :
56 : int has_commit;
57 : uint commit;
58 :
59 : uint feature_set;
60 : } version;
61 :
62 : struct {
63 : uint ipv4;
64 : ushort port;
65 : } sockets[ 12 ];
66 : };
67 :
68 : struct fd_gui_vote_account {
69 : fd_pubkey_t pubkey[ 1 ];
70 : fd_pubkey_t vote_account[ 1 ];
71 :
72 : ulong activated_stake;
73 : ulong last_vote;
74 : ulong root_slot;
75 : ulong epoch_credits;
76 : uchar commission;
77 : int delinquent;
78 : };
79 :
80 : struct fd_gui_validator_info {
81 : fd_pubkey_t pubkey[ 1 ];
82 :
83 : char name[ 64 ];
84 : char website[ 128 ];
85 : char details[ 256 ];
86 : char icon_uri[ 128 ];
87 : };
88 :
89 : struct fd_gui_txn_waterfall {
90 : struct {
91 : ulong quic;
92 : ulong udp;
93 : ulong gossip;
94 : ulong block_engine;
95 : ulong pack_cranked;
96 : } in;
97 :
98 : struct {
99 : ulong net_overrun;
100 : ulong quic_overrun;
101 : ulong quic_frag_drop;
102 : ulong quic_abandoned;
103 : ulong tpu_quic_invalid;
104 : ulong tpu_udp_invalid;
105 : ulong verify_overrun;
106 : ulong verify_parse;
107 : ulong verify_failed;
108 : ulong verify_duplicate;
109 : ulong dedup_duplicate;
110 : ulong resolv_lut_failed;
111 : ulong resolv_expired;
112 : ulong resolv_ancient;
113 : ulong resolv_no_ledger;
114 : ulong resolv_retained;
115 : ulong pack_invalid;
116 : ulong pack_expired;
117 : ulong pack_retained;
118 : ulong pack_wait_full;
119 : ulong pack_leader_slow;
120 : ulong bank_invalid;
121 : ulong block_success;
122 : ulong block_fail;
123 : } out;
124 : };
125 :
126 : typedef struct fd_gui_txn_waterfall fd_gui_txn_waterfall_t;
127 :
128 : struct fd_gui_tile_timers {
129 : ulong caughtup_housekeeping_ticks;
130 : ulong processing_housekeeping_ticks;
131 : ulong backpressure_housekeeping_ticks;
132 :
133 : ulong caughtup_prefrag_ticks;
134 : ulong processing_prefrag_ticks;
135 : ulong backpressure_prefrag_ticks;
136 :
137 : ulong caughtup_postfrag_ticks;
138 : ulong processing_postfrag_ticks;
139 : };
140 :
141 : typedef struct fd_gui_tile_timers fd_gui_tile_timers_t;
142 :
143 : struct fd_gui_tile_stats {
144 : long sample_time_nanos;
145 :
146 : ulong net_in_rx_bytes; /* Number of bytes received by the net tile*/
147 : ulong quic_conn_cnt; /* Number of active QUIC connections */
148 : ulong verify_drop_cnt; /* Number of transactions dropped by verify tiles */
149 : ulong verify_total_cnt; /* Number of transactions received by verify tiles */
150 : ulong dedup_drop_cnt; /* Number of transactions dropped by dedup tile */
151 : ulong dedup_total_cnt; /* Number of transactions received by dedup tile */
152 : ulong pack_buffer_cnt; /* Number of buffered transactions in the pack tile */
153 : ulong pack_buffer_capacity; /* Total size of the pack transaction buffer */
154 : ulong bank_txn_exec_cnt; /* Number of transactions processed by the bank tile */
155 : ulong net_out_tx_bytes; /* Number of bytes sent by the net tile */
156 : };
157 :
158 : typedef struct fd_gui_tile_stats fd_gui_tile_stats_t;
159 :
160 0 : #define FD_GUI_SLOT_LEADER_UNSTARTED (0UL)
161 0 : #define FD_GUI_SLOT_LEADER_STARTED (1UL)
162 0 : #define FD_GUI_SLOT_LEADER_ENDED (2UL)
163 :
164 : struct fd_gui_slot {
165 : ulong slot;
166 : ulong parent_slot;
167 : long completed_time;
168 : int mine;
169 : int skipped;
170 : int must_republish;
171 : int level;
172 : uint total_txn_cnt;
173 : uint vote_txn_cnt;
174 : uint failed_txn_cnt;
175 : uint nonvote_failed_txn_cnt;
176 : uint compute_units;
177 : ulong transaction_fee;
178 : ulong priority_fee;
179 : ulong tips;
180 :
181 : uchar leader_state;
182 :
183 : struct {
184 : long leader_start_time; /* UNIX timestamp of when we first became leader in this slot */
185 : long leader_end_time; /* UNIX timestamp of when we stopped being leader in this slot */
186 :
187 : long reference_ticks; /* A somewhat arbitrary reference tickcount, that we use for compressing the tickcounts
188 : of transaction start and end times in this slot. It is, roughly (not exactly), the
189 : minimum of the first transaction start or end tickcount, and the time of the message
190 : from poh to pack telling it to become leader. */
191 : long reference_nanos; /* The UNIX timestamp in nanoseconds of the reference tick value above. */
192 :
193 : ushort microblocks_upper_bound; /* An upper bound on the number of microblocks in the slot. If the number of
194 : microblocks observed is equal to this, the slot can be considered over.
195 : Generally, the bound is set to a "final" state by a done packing messsage,
196 : which sets it to the exact number of microblocks, but sometimes this message
197 : is not sent, if the max upper bound published by poh was already correct. */
198 : ushort begin_microblocks; /* The number of microblocks we have seen be started (sent) from pack to banks. */
199 : ushort end_microblocks; /* The number of microblocks we have seen be ended (sent) from banks to poh. The
200 : slot is only considered over if the begin and end microblocks seen are both equal
201 : to the microblock upper bound. */
202 :
203 : uint max_compute_units; /* The maximum number of compute units allowed in the slot. Currently fixed at 48M
204 : but will increase dynamically in future according to some feature gates. */
205 : uchar has_offset[ 65UL ]; /* has_offset[ i ] is 1 if the i-th bank has seen any transactions in this slot,
206 : but offset 64 is used for if the bank tile has seen any transactions at all. */
207 : uint start_offset[ 65UL ]; /* If has_offset[ i ] is 1, contains the offset into the GUI state compressed
208 : CUs array where transactions processed by bank i (or sent by pack, for offset
209 : 64) begin in the array. */
210 : uint end_offset[ 65UL ]; /* If has_offset[ i ] is 1, contains the offset into the GUI state compressed
211 : CUs array where transactions processed by bank i (or sent by pack, for offset
212 : 64) end in the array. */
213 : } cus;
214 :
215 : fd_gui_txn_waterfall_t waterfall_begin[ 1 ];
216 : fd_gui_txn_waterfall_t waterfall_end[ 1 ];
217 :
218 : fd_gui_tile_stats_t tile_stats_begin[ 1 ];
219 : fd_gui_tile_stats_t tile_stats_end[ 1 ];
220 :
221 : ulong tile_timers_history_idx;
222 : };
223 :
224 : typedef struct fd_gui_slot fd_gui_slot_t;
225 :
226 : struct fd_gui {
227 : fd_http_server_t * http;
228 : fd_topo_t * topo;
229 :
230 : long next_sample_400millis;
231 : long next_sample_100millis;
232 : long next_sample_10millis;
233 :
234 : ulong debug_in_leader_slot;
235 :
236 : struct {
237 : fd_pubkey_t identity_key[ 1 ];
238 : char identity_key_base58[ FD_BASE58_ENCODED_32_SZ ];
239 :
240 : char const * version;
241 : char const * cluster;
242 :
243 : ulong vote_distance;
244 : int vote_state;
245 :
246 : long startup_time_nanos;
247 :
248 : uchar startup_progress;
249 : int startup_got_full_snapshot;
250 :
251 : ulong startup_incremental_snapshot_slot;
252 : uint startup_incremental_snapshot_peer_ip_addr;
253 : ushort startup_incremental_snapshot_peer_port;
254 : double startup_incremental_snapshot_elapsed_secs;
255 : double startup_incremental_snapshot_remaining_secs;
256 : double startup_incremental_snapshot_throughput;
257 : ulong startup_incremental_snapshot_total_bytes;
258 : ulong startup_incremental_snapshot_current_bytes;
259 :
260 : ulong startup_full_snapshot_slot;
261 : uint startup_full_snapshot_peer_ip_addr;
262 : ushort startup_full_snapshot_peer_port;
263 : double startup_full_snapshot_elapsed_secs;
264 : double startup_full_snapshot_remaining_secs;
265 : double startup_full_snapshot_throughput;
266 : ulong startup_full_snapshot_total_bytes;
267 : ulong startup_full_snapshot_current_bytes;
268 :
269 : ulong startup_ledger_slot;
270 : ulong startup_ledger_max_slot;
271 :
272 : ulong startup_waiting_for_supermajority_slot;
273 : ulong startup_waiting_for_supermajority_stake_pct;
274 :
275 : ulong identity_account_balance;
276 : ulong vote_account_balance;
277 : ulong estimated_slot_duration_nanos;
278 :
279 : ulong net_tile_cnt;
280 : ulong quic_tile_cnt;
281 : ulong verify_tile_cnt;
282 : ulong resolv_tile_cnt;
283 : ulong bank_tile_cnt;
284 : ulong shred_tile_cnt;
285 :
286 : ulong slot_rooted;
287 : ulong slot_optimistically_confirmed;
288 : ulong slot_completed;
289 : ulong slot_estimated;
290 :
291 : ulong estimated_tps_history_idx;
292 : ulong estimated_tps_history[ FD_GUI_TPS_HISTORY_SAMPLE_CNT ][ 3UL ];
293 :
294 : fd_gui_txn_waterfall_t txn_waterfall_reference[ 1 ];
295 : fd_gui_txn_waterfall_t txn_waterfall_current[ 1 ];
296 :
297 : fd_gui_tile_stats_t tile_stats_reference[ 1 ];
298 : fd_gui_tile_stats_t tile_stats_current[ 1 ];
299 :
300 : ulong tile_timers_snap_idx;
301 : ulong tile_timers_snap_idx_slot_start;
302 : /* Temporary storage for samples. Will be downsampled into leader history on slot end. */
303 : fd_gui_tile_timers_t tile_timers_snap[ FD_GUI_TILE_TIMER_SNAP_CNT ][ FD_GUI_TILE_TIMER_TILE_CNT ];
304 : ulong tile_timers_history_idx;
305 : fd_gui_tile_timers_t tile_timers_leader_history[ FD_GUI_TILE_TIMER_LEADER_CNT ][ FD_GUI_TILE_TIMER_LEADER_DOWNSAMPLE_CNT ][ FD_GUI_TILE_TIMER_TILE_CNT ];
306 : ulong tile_timers_leader_history_slot_sample_cnt[ FD_GUI_TILE_TIMER_LEADER_CNT ];
307 : ulong tile_timers_leader_history_slot[ FD_GUI_TILE_TIMER_LEADER_CNT ];
308 : } summary;
309 :
310 : fd_gui_slot_t slots[ FD_GUI_SLOTS_CNT ][ 1 ];
311 :
312 0 : #define FD_GUI_COMPUTE_UNITS_HISTORY_SZ (1UL<<28UL)
313 : struct {
314 : uint offset;
315 :
316 : /* Compacted representation of history of transaction execution,
317 :
318 : bits [0, 0 ]: 0=started, 1=ended
319 : bits [1, 1 ]: 0=bank started, 1=bank ended
320 : bits [2, 7 ]: bank index
321 : bits [8, 29]: compute units delta
322 : bits [30, 63]: timestamp delta */
323 : ulong history[ FD_GUI_COMPUTE_UNITS_HISTORY_SZ ];
324 : } cus;
325 :
326 : struct {
327 : int has_block_engine;
328 : char name[ 16 ];
329 : char url[ 256 ];
330 : int status;
331 : } block_engine;
332 :
333 : struct {
334 : int has_epoch[ 2 ];
335 :
336 : struct {
337 : ulong epoch;
338 : long start_time;
339 : long end_time;
340 :
341 : ulong my_total_slots;
342 : ulong my_skipped_slots;
343 :
344 : ulong start_slot;
345 : ulong end_slot;
346 : ulong excluded_stake;
347 : fd_epoch_leaders_t * lsched;
348 : uchar __attribute__((aligned(FD_EPOCH_LEADERS_ALIGN))) _lsched[ FD_EPOCH_LEADERS_FOOTPRINT(50000UL, 432000UL) ];
349 : fd_stake_weight_t stakes[ 50000UL ];
350 : } epochs[ 2 ];
351 : } epoch;
352 :
353 : struct {
354 : ulong peer_cnt;
355 : struct fd_gui_gossip_peer peers[ 40200 ];
356 : } gossip;
357 :
358 : struct {
359 : ulong vote_account_cnt;
360 : struct fd_gui_vote_account vote_accounts[ 40200 ];
361 : } vote_account;
362 :
363 : struct {
364 : ulong info_cnt;
365 : struct fd_gui_validator_info info[ 40200 ];
366 : } validator_info;
367 : };
368 :
369 : typedef struct fd_gui fd_gui_t;
370 :
371 : FD_PROTOTYPES_BEGIN
372 :
373 : FD_FN_CONST ulong
374 : fd_gui_align( void );
375 :
376 : FD_FN_CONST ulong
377 : fd_gui_footprint( void );
378 :
379 : void *
380 : fd_gui_new( void * shmem,
381 : fd_http_server_t * http,
382 : char const * version,
383 : char const * cluster,
384 : uchar const * identity_key,
385 : int is_voting,
386 : fd_topo_t * topo );
387 :
388 : fd_gui_t *
389 : fd_gui_join( void * shmem );
390 :
391 : void
392 : fd_gui_set_identity( fd_gui_t * gui,
393 : uchar const * identity_pubkey );
394 :
395 : void
396 : fd_gui_ws_open( fd_gui_t * gui,
397 : ulong conn_id );
398 :
399 : int
400 : fd_gui_ws_message( fd_gui_t * gui,
401 : ulong ws_conn_id,
402 : uchar const * data,
403 : ulong data_len );
404 :
405 : void
406 : fd_gui_plugin_message( fd_gui_t * gui,
407 : ulong plugin_msg,
408 : uchar const * msg );
409 :
410 : void
411 : fd_gui_became_leader( fd_gui_t * gui,
412 : ulong slot,
413 : long start_time_nanos,
414 : long end_time_nanos,
415 : ulong max_compute_units,
416 : ulong max_microblocks );
417 :
418 : void
419 : fd_gui_unbecame_leader( fd_gui_t * gui,
420 : ulong slot,
421 : ulong microblocks_in_slot );
422 :
423 : void
424 : fd_gui_execution_begin( fd_gui_t * gui,
425 : long tickcount,
426 : ulong slot,
427 : ulong bank_idx,
428 : ulong txn_cnt,
429 : fd_txn_p_t * txns );
430 :
431 : void
432 : fd_gui_execution_end( fd_gui_t * gui,
433 : long tickcount,
434 : ulong bank_idx,
435 : int is_last_in_bundle,
436 : ulong slot,
437 : ulong txn_cnt,
438 : fd_txn_p_t * txns );
439 :
440 : int
441 : fd_gui_poll( fd_gui_t * gui );
442 :
443 0 : #define FD_GUI_EXECUTION_TYPE_BEGIN (0)
444 0 : #define FD_GUI_EXECUTION_TYPE_END (1)
445 :
446 : static inline ulong
447 : fd_gui_cu_history_compress( int execution_type,
448 : ulong bank_idx,
449 : uint compute_units,
450 : int active_bank_change,
451 : long reference_ticks,
452 0 : long tickcount ) {
453 : /* bits [0, 0 ]: 0=started, 1=ended
454 : bits [1, 1 ]: 0=bank started, 1=bank ended
455 : bits [2, 7 ]: bank index
456 : bits [8, 29]: compute units delta
457 : bits [30, 30]: timestamp signed-ness from reference
458 : bits [31, 63]: timestamp delta from reference in nanoseconds */
459 0 : long nanos_delta = (long)((double)(tickcount - reference_ticks) / fd_tempo_tick_per_ns( NULL ));
460 0 : nanos_delta = fd_long_min( nanos_delta, 0x1FFFFFFFFUL );
461 :
462 0 : ulong comp = 0UL;
463 0 : comp |= (ulong)((execution_type&1)<<0);
464 0 : comp |= (ulong)((active_bank_change&1)<<1);
465 0 : comp |= (bank_idx&0x3FUL)<<2;
466 0 : comp |= (compute_units&0x3FFFFFUL)<<8;
467 0 : comp |= ((ulong)(nanos_delta<0L)) <<30;
468 0 : comp |= (((ulong)fd_long_abs(nanos_delta)&0x1FFFFFFFFUL))<<31;
469 0 : return comp;
470 0 : }
471 :
472 : static inline long
473 : fd_gui_cu_history_decompress_timestamp( long reference_nanos,
474 0 : ulong comp ) {
475 0 : long nanos_sign = (long)((comp>>30)&1UL);
476 0 : long nanos_delta = (long)((comp>>31)&0x1FFFFFFFFUL);
477 0 : return reference_nanos + (nanos_sign ? -nanos_delta : nanos_delta);
478 0 : }
479 :
480 : static inline int
481 0 : fd_gui_cu_history_decompress_type( ulong comp ) {
482 0 : return (int)(comp&1UL);
483 0 : }
484 :
485 : static inline int
486 0 : fd_gui_cu_history_decompress_active_bank_change( ulong comp ) {
487 0 : return (int)((comp>>1)&1UL);
488 0 : }
489 :
490 : static inline ulong
491 0 : fd_gui_cu_history_decompress_bank( ulong comp ) {
492 0 : return (comp>>2)&0x3FUL;
493 0 : }
494 :
495 : static inline ulong
496 0 : fd_gui_cu_history_decompress_compute_units( ulong comp ) {
497 0 : return (comp>>8)&0x3FFFFFUL;
498 0 : }
499 :
500 : FD_PROTOTYPES_END
501 :
502 : #endif /* HEADER_fd_src_disco_gui_fd_gui_h */
|