LCOV - code coverage report
Current view: top level - disco/gui - fd_gui_hist.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 18 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 9 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_gui_fd_gui_hist_h
       2             : #define HEADER_fd_src_disco_gui_fd_gui_hist_h
       3             : 
       4             : /* fd_gui_hist is the GUI's historical event store semantics layer.  It
       5             :    sits on top of fd_gui_store and owns everything GUI-specific about
       6             :    the monitoring history: the named DBs (FD_GUI_HIST_* below), their
       7             :    key/value structs, fixed record sizes, the eviction policy, and the
       8             :    query API.
       9             : 
      10             :    There are two kinds of DB:
      11             : 
      12             :      - TIME-SERIES (TS) DBs are append-only streams tagged by a
      13             :        wallclock window. Written by fd_gui_hist_ts_append, read by
      14             :        time-window range scan.
      15             :      - KEY-VALUE (KV) DBs hold one record per key.  Written/read by
      16             :        point key (fd_gui_hist_kv_get_or_create / _get / _get_any).
      17             : */
      18             : 
      19             : #include "../../util/fd_util_base.h"
      20             : #include "fd_gui_store.h"
      21             : #include "../../flamenco/leaders/fd_leaders_base.h"   /* MAX_SLOTS_PER_EPOCH */
      22             : #include "../../flamenco/runtime/fd_slot_params.h"    /* FD_SLOT_PARAMS_200MS */
      23             : 
      24             : struct fd_gui;
      25             : typedef struct fd_gui fd_gui_t;
      26             : 
      27           0 : #define FD_GUI_HIST_MAGIC (0xf17e6d09147802UL)
      28             : 
      29           0 : #define FD_GUI_HIST_RES_1S_NS (1000000000L)
      30             : 
      31           0 : #define FD_GUI_HIST_MAX_LEADER_SLOTS_PER_EPOCH (43200UL) /* 10% capacity should be enough for mainnet/testnet */
      32             : 
      33           0 : #define FD_GUI_HIST_MAX_EPOCHS (64UL) /* Comfortably above typical time between restarts */
      34           0 : #define FD_GUI_HIST_SCHEDULER_COUNTS (0)  /* (ts, type)            */
      35           0 : #define FD_GUI_HIST_TILE_TIMERS      (1)  /* (ts, type)            */
      36           0 : #define FD_GUI_HIST_SHRED_EVENTS     (2)
      37           0 : #define FD_GUI_HIST_TXN_START        (3)  /* (ts, type, bank, txn) */
      38           0 : #define FD_GUI_HIST_TXN_END          (4)  /* (ts, type, bank, txn) */
      39           0 : #define FD_GUI_HIST_SLOT             (5)  /* (slot, bank_seq)      */
      40           0 : #define FD_GUI_HIST_LEADER_SLOT      (6)  /* (slot, bank_seq)      */
      41           0 : #define FD_GUI_HIST_EPOCH            (7)  /* (epoch)               */
      42           0 : #define FD_GUI_HIST_TILE_STATS       (8)  /* (ts, type)            */
      43           0 : #define FD_GUI_HIST_TXN_WATERFALL    (9)  /* (ts, type)            */
      44           0 : #define FD_GUI_HIST_TIMELINE_DAY     (10)
      45           0 : #define FD_GUI_HIST_REPLAY_TXN       (11)
      46           0 : #define FD_GUI_HIST_CNT              (12)
      47             : 
      48             : struct fd_gui_hist_metrics {
      49             :   /* Writes dropped after exhausting region or KV index capacity. */
      50             :   ulong map_full[ FD_GUI_HIST_CNT ];
      51             :   /* Writes that evicted records before succeeding. */
      52             :   ulong reserves [ FD_GUI_HIST_CNT ];
      53             : };
      54             : typedef struct fd_gui_hist_metrics fd_gui_hist_metrics_t;
      55             : 
      56             : struct fd_gui_hist_slot_key        { ulong slot; ulong bank_seq; };
      57             : struct fd_gui_hist_leader_slot_key { ulong slot; ulong bank_seq; };
      58             : struct fd_gui_hist_epoch_key       { ulong epoch; };
      59             : typedef struct fd_gui_hist_slot_key        fd_gui_hist_slot_key_t;
      60             : typedef struct fd_gui_hist_leader_slot_key fd_gui_hist_leader_slot_key_t;
      61             : typedef struct fd_gui_hist_epoch_key       fd_gui_hist_epoch_key_t;
      62             : 
      63             : struct fd_gui_hist_private;
      64             : typedef struct fd_gui_hist_private fd_gui_hist_t;
      65             : 
      66             : /* fd_gui_hist_kv_slot_iter_t iterates every record for `slot` (every
      67             :    fork's block) in a slot-keyed KV DB.  Used to enumerate the
      68             :    equivocating forks of a slot. */
      69             : struct fd_gui_hist_kv_slot_iter {
      70             :   void const *            rec;       /* current record; NULL when done */
      71             :   ulong                   bank_seq;  /* current record's bank_seq      */
      72             :   fd_gui_store_kv_iter_t _it;
      73             : };
      74             : typedef struct fd_gui_hist_kv_slot_iter fd_gui_hist_kv_slot_iter_t;
      75             : 
      76             : /* fd_gui_hist_range_filter_fn is an optional per-record predicate
      77             :    evaluated during a range scan: called with a pointer to the DB's
      78             :    record and the caller's `ctx`, it returns non-zero to emit the record
      79             :    or zero to skip it.  A NULL filter emits every record in the window
      80             :    range. */
      81             : 
      82             : typedef int (*fd_gui_hist_range_filter_fn)( void const * rec, void * ctx );
      83             : 
      84             : /* fd_gui_hist_iter_t iterates the records produced by a time-window
      85             :    range query.
      86             : 
      87             :    Records are emitted oldest-window-first, but the backend does not
      88             :    strictly order records within a window.
      89             : */
      90             : struct fd_gui_hist_iter {
      91             :   void const * rec;
      92             :   ulong        rec_sz;
      93             : 
      94             :   int                         _dbi;
      95             :   int                         _emitted;
      96             :   fd_gui_hist_range_filter_fn _filter;
      97             :   void *                      _filter_ctx;
      98             :   fd_gui_store_ts_iter_t      _it;
      99             : };
     100             : 
     101             : typedef struct fd_gui_hist_iter fd_gui_hist_iter_t;
     102             : 
     103             : FD_PROTOTYPES_BEGIN
     104             : 
     105             : FD_FN_CONST ulong
     106             : fd_gui_hist_align( void );
     107             : 
     108             : FD_FN_CONST ulong
     109             : fd_gui_hist_footprint( void );
     110             : 
     111             : /* fd_gui_hist_new formats the workspace region `mem`
     112             :    (>= fd_gui_hist_footprint bytes, fd_gui_hist_align aligned) as the
     113             :    history semantics layer over the store `db`. Returns `mem` on success
     114             :    or NULL on failure (logged). */
     115             : 
     116             : void *
     117             : fd_gui_hist_new( void *                 mem,
     118             :                  fd_gui_store_t const * db );
     119             : 
     120             : /* fd_gui_hist_join joins a region formatted by fd_gui_hist_new,
     121             :    returning a usable handle (mem may be NULL -> NULL). */
     122             : 
     123             : fd_gui_hist_t *
     124             : fd_gui_hist_join( void * mem );
     125             : 
     126             : void *
     127             : fd_gui_hist_leave( fd_gui_hist_t * hist );
     128             : 
     129             : void *
     130             : fd_gui_hist_delete( void * mem );
     131             : 
     132             : /* fd_gui_hist_db_descs returns a pointer to a static array to be passed
     133             :    to fd_gui_store_new. */
     134             : 
     135             : fd_gui_store_desc_t const *
     136             : fd_gui_hist_db_descs( ulong store_bytes );
     137             : 
     138             : FD_FN_CONST static inline ulong
     139           0 : fd_gui_hist_db_cnt( void ) { return FD_GUI_HIST_CNT; }
     140             : 
     141             : fd_gui_hist_metrics_t const *
     142             : fd_gui_hist_metrics( fd_gui_t const * gui );
     143             : 
     144             : /* ---- TS read/write -------------------------------------------------- */
     145             : 
     146             : /* fd_gui_hist_ts_append copies the record at val into time-series DB
     147             :    dbi, preserving its contents.  The timestamp at the DB's configured
     148             :    offset must be >= the timestamp of the last successful append.
     149             : 
     150             :    Returns 0 on success, -1 for an invalid DB, a decreasing timestamp,
     151             :    or a store append failure. */
     152             : 
     153             : int
     154             : fd_gui_hist_ts_append( fd_gui_t *   gui,
     155             :                        int          dbi,
     156             :                        void const * val );
     157             : 
     158             : /* fd_gui_hist_ts_emplace is fd_gui_hist_ts_append without the copy: it
     159             :    appends a record whose timestamp field is stored_ts and returns a
     160             :    pointer to it in the store, or NULL on the same failures. */
     161             : 
     162             : void *
     163             : fd_gui_hist_ts_emplace( fd_gui_t * gui,
     164             :                         int        dbi,
     165             :                         long       stored_ts );
     166             : 
     167             : int
     168             : fd_gui_hist_range_begin( fd_gui_t *                   gui,
     169             :                          fd_gui_hist_iter_t *         iter,
     170             :                          int                          dbi,
     171             :                          long                         lo_ns,
     172             :                          long                         hi_ns,
     173             :                          fd_gui_hist_range_filter_fn  filter,
     174             :                          void *                       filter_ctx );
     175             : 
     176             : int
     177             : fd_gui_hist_range_next( fd_gui_hist_iter_t * iter );
     178             : 
     179             : void
     180             : fd_gui_hist_range_end( fd_gui_hist_iter_t * iter );
     181             : 
     182             : 
     183             : /* ---- KV read/write -------------------------------------------------- */
     184             : 
     185             : /* fd_gui_hist_kv_get_or_create reserves (creating if absent) the record
     186             :    for `*key` in a KV DB and returns a mutable pointer to the record's
     187             :    value, or NULL on failure.
     188             : 
     189             :    Will evict old entries to make room if necessary.  Returns the value
     190             :    pointer on success, or NULL on error. */
     191             : 
     192             : void *
     193             : fd_gui_hist_kv_get_or_create( fd_gui_t *   gui,
     194             :                               int          dbi,
     195             :                               void const * key );
     196             : 
     197             : /* fd_gui_hist_kv_get is like fd_gui_hist_kv_get_or_create, but returns
     198             :    NULL when the record is not found instead of creating one. */
     199             : 
     200             : void *
     201             : fd_gui_hist_kv_get( fd_gui_t *   gui,
     202             :                     int          dbi,
     203             :                     void const * key );
     204             : 
     205             : /* fd_gui_hist_kv_get_slot_any looks up the slot record for the first
     206             :    key matching (slot, *) and returns a pointer to its value. */
     207             : 
     208             : void *
     209             : fd_gui_hist_kv_get_slot_any( fd_gui_t * gui,
     210             :                              int        dbi,
     211             :                              ulong      slot );
     212             : 
     213             : fd_gui_hist_kv_slot_iter_t *
     214             : fd_gui_hist_kv_iter_begin( fd_gui_t *                   gui,
     215             :                            fd_gui_hist_kv_slot_iter_t * iter,
     216             :                            int                          dbi,
     217             :                            ulong                        slot );
     218             : 
     219             : int
     220             : fd_gui_hist_kv_iter_next( fd_gui_hist_kv_slot_iter_t * iter );
     221             : 
     222             : /* ---- Eviction ------------------------------------------------------- */
     223             : 
     224             : /* fd_gui_hist_evict_step reclaims at most FD_GUI_HIST_EVICT_BATCH
     225             :    records from an oldest excess region once at most one shared region
     226             :    remains free.  Every DB's newest FD_GUI_STORE_BASE_REGIONS regions
     227             :    are protected.  Returns 1 for actual progress, 0 when idle or all
     228             :    candidates pinned.  Writes retry on pressure, then recycle only their
     229             :    own eligible history if no excess candidate remains. */
     230             : 
     231             : int
     232             : fd_gui_hist_evict_step( fd_gui_t * gui );
     233             : 
     234             : FD_PROTOTYPES_END
     235             : 
     236             : #endif /* HEADER_fd_src_disco_gui_fd_gui_hist_h */

Generated by: LCOV version 1.14