LCOV - code coverage report
Current view: top level - choreo/forks - fd_forks.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 16 0.0 %
Date: 2025-08-05 05:04:49 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_choreo_forks_fd_forks_h
       2             : #define HEADER_fd_src_choreo_forks_fd_forks_h
       3             : 
       4             : #include "../../flamenco/runtime/context/fd_exec_slot_ctx.h"
       5             : #include "../fd_choreo_base.h"
       6             : #include "../ghost/fd_ghost.h"
       7             : #include "../voter/fd_voter.h"
       8             : 
       9             : /* FD_FORKS_USE_HANDHOLDING:  Define this to non-zero at compile time
      10             :    to turn on additional runtime checks and logging. */
      11             : 
      12             : #ifndef FD_FORKS_USE_HANDHOLDING
      13             : #define FD_FORKS_USE_HANDHOLDING 1
      14             : #endif
      15             : 
      16             : struct fd_fork {
      17             :   ulong slot; /* the fork head and frontier key */
      18             :   ulong next; /* reserved for use by fd_pool and fd_map_chain */
      19             :   ulong prev; /* reserved for use by fd_forks_publish */
      20             :   int   lock; /* IMPORTANT SAFETY TIP! lock is a boolean indicating
      21             :                  whether a fork's most recent block is still being
      22             :                  actively replayed (executed) and should generally not
      23             :                  be read or written to by downstream consumers (eg.
      24             :                  consensus, publishing) and should definitely not be
      25             :                  removed. */
      26             : };
      27             : 
      28             : typedef struct fd_fork fd_fork_t;
      29             : 
      30             : #define POOL_NAME fd_fork_pool
      31           0 : #define POOL_T    fd_fork_t
      32             : #include "../../util/tmpl/fd_pool.c"
      33             : 
      34             : #define MAP_NAME  fd_fork_frontier
      35             : #define MAP_ELE_T fd_fork_t
      36           0 : #define MAP_KEY   slot
      37             : #include "../../util/tmpl/fd_map_chain.c"
      38             : 
      39             : /* fd_forks maintains all the outstanding fork heads known as the
      40             :    frontier.  The memory required for these fork heads is pre-allocated
      41             :    in `pool`.
      42             : 
      43             :    {processed, confirmed, finalized} correspond to the highest slots
      44             :    that have achieved each of these cluster commitment levels. This is
      45             :    based on what Firedancer has locally observed, so these values are
      46             :    not atomically synchronized with other nodes in the cluster (ie.
      47             :    other nodes may report higher or lower slot numbers for each of
      48             :    these) but are "eventually consistent" as long as Firedancer is
      49             :    connected to the cluster and replaying blocks. All three values are
      50             :    strictly monotonically increasing.
      51             : 
      52             :    processed - a slot has been replayed.
      53             :    confirmed - a slot has been "optimistically confirmed" ie. 2/3 of
      54             :                stake has voted for it.
      55             :    finalized - a slot has been "supermajority rooted" ie. 2/3 of stake
      56             :                has rooted it or any of its descendants. */
      57             : 
      58             : struct fd_forks {
      59             :   fd_fork_frontier_t * frontier; /* map of slot->fd_fork_t */
      60             :   fd_fork_t *          pool;     /* memory pool of fd_fork_t */
      61             :   ulong                processed;
      62             :   ulong                confirmed;
      63             :   ulong                finalized;
      64             : };
      65             : typedef struct fd_forks fd_forks_t;
      66             : 
      67             : /* fd_forks_{align,footprint} return the required alignment and
      68             :    footprint of a memory region suitable for use as forks with up to max
      69             :    fork heads in the frontier. */
      70             : 
      71             : FD_FN_CONST static inline ulong
      72           0 : fd_forks_align( void ) {
      73           0 :   return alignof( fd_forks_t );
      74           0 : }
      75             : 
      76             : FD_FN_CONST static inline ulong
      77           0 : fd_forks_footprint( ulong max ) {
      78           0 :   return FD_LAYOUT_FINI(
      79           0 :     FD_LAYOUT_APPEND(
      80           0 :     FD_LAYOUT_APPEND(
      81           0 :     FD_LAYOUT_APPEND(
      82           0 :     FD_LAYOUT_INIT,
      83           0 :       alignof(fd_forks_t),      sizeof(fd_forks_t) ),
      84           0 :       fd_fork_pool_align(),     fd_fork_pool_footprint( max ) ),
      85           0 :       fd_fork_frontier_align(), fd_fork_frontier_footprint( max ) ),
      86           0 :     alignof(fd_forks_t) );
      87           0 : }
      88             : 
      89             : /* fd_forks_new formats an unused memory region for use as a forks.  mem
      90             :    is a non-NULL pointer to this region in the local address space with
      91             :    the required footprint and alignment. */
      92             : 
      93             : void *
      94             : fd_forks_new( void * shmem, ulong max, ulong seed );
      95             : 
      96             : /* fd_forks_join joins the caller to the forks.  forks points to the
      97             :    first byte of the memory region backing the forks in the caller's
      98             :    address space.
      99             : 
     100             :    Returns a pointer in the local address space to forks on success. */
     101             : 
     102             : fd_forks_t *
     103             : fd_forks_join( void * forks );
     104             : 
     105             : /* fd_forks_leave leaves a current local join.  Returns a pointer to the
     106             :    underlying shared memory region on success and NULL on failure (logs
     107             :    details).  Reasons for failure include forks is NULL. */
     108             : 
     109             : void *
     110             : fd_forks_leave( fd_forks_t const * forks );
     111             : 
     112             : /* fd_forks_delete unformats a memory region used as a forks.  Assumes
     113             :    only the local process is joined to the region. Returns a pointer to
     114             :    the underlying shared memory region or NULL if used obviously in
     115             :    error (e.g. forks is obviously not a forks ... logs details).  The
     116             :    ownership of the memory region is transferred to the caller. */
     117             : 
     118             : void *
     119             : fd_forks_delete( void * forks );
     120             : 
     121             : /* fd_forks_init initializes forks.  Assumes forks is a valid local join
     122             :    and no one else is joined, and slot  Inserts the first fork.
     123             :    Returns fork on success, NULL on failure.
     124             : 
     125             :    In general, this should be called by the same process that formatted
     126             :    forks' memory, ie. the caller of fd_forks_new. */
     127             : 
     128             : fd_fork_t *
     129             : fd_forks_init( fd_forks_t * forks, ulong slot );
     130             : 
     131             : /* fd_forks_query queries for the fork corresponding to slot in the
     132             :    frontier.  Returns the fork if found, otherwise NULL. */
     133             : 
     134             : fd_fork_t *
     135             : fd_forks_query( fd_forks_t * forks, ulong slot );
     136             : 
     137             : /* fd_forks_query_const is the const version of the above. */
     138             : 
     139             : fd_fork_t const *
     140             : fd_forks_query_const( fd_forks_t const * forks, ulong slot );
     141             : 
     142             : /* fd_forks_advance advances a parent_slot to slot in the frontier.
     143             :    Assumes parent_slot corresponds to a fork currently in the frontier
     144             :    (ie. has already been prepared), slot is a child of parent_slot, and
     145             :    parent_slot has already been replayed.  Fails if fork is not frozen.
     146             :    Returns the updated fork on success, NULL on failure. */
     147             : 
     148             : fd_fork_t *
     149             : fd_forks_advance( fd_forks_t const * forks, fd_fork_t * fork, ulong slot );
     150             : 
     151             : /* fd_forks_prepare prepares a fork for execution.  The fork will either
     152             :    be an existing fork in the frontier if parent_slot is already a fork
     153             :    head or it will start a new fork at parent_slot and add it to the
     154             :    frontier.
     155             : 
     156             :    Returns fork on success, NULL on failure.  Failure reasons include
     157             :    parent_slot is not present in the blockstore, is not present in funk,
     158             :    or does not have a valid ancestry.
     159             : 
     160             :    It is possible for the fork to return NULL in a non-error condition.
     161             :    For example, a leader tries to rollback and start a new fork from a
     162             :    very old slot that the blockstore has already pruned. In this
     163             :    scenario, we cannot prepare a new fork at parent_slot because we have
     164             :    already rooted past it. */
     165             : 
     166             : fd_fork_t *
     167             : fd_forks_prepare( fd_forks_t const * forks, ulong parent_slot );
     168             : 
     169             : /* fd_forks_publish publishes a new root into forks.  Assumes root is a
     170             :    valid slot that exists in the cluster and has already been replayed.
     171             :    This prunes all the existing forks in the frontier except descendants
     172             :    of root.  Forks that are not frozen will also not be pruned (warns
     173             :    when handholding is enabled).  */
     174             : 
     175             : void
     176             : fd_forks_publish( fd_forks_t * fork, ulong root );
     177             : 
     178             : /* fd_forks_print prints a forks as a list of the frontiers and number
     179             :    of forks (pool eles acquired). */
     180             : 
     181             : void
     182             : fd_forks_print( fd_forks_t const * forks );
     183             : 
     184             : #endif /* HEADER_fd_src_choreo_forks_fd_forks_h */

Generated by: LCOV version 1.14