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