LCOV - code coverage report
Current view: top level - funk - fd_funk_txn.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 44 44 100.0 %
Date: 2024-11-13 11:58:15 Functions: 55 2112 2.6 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_funk_fd_funk_txn_h
       2             : #define HEADER_fd_src_funk_fd_funk_txn_h
       3             : 
       4             : /* This provides APIs for managing forks (preparing, publishing and
       5             :    cancelling funk transactions).  It is generally not meant to be
       6             :    included directly.  Use fd_funk.h instead. */
       7             : 
       8             : #include "fd_funk_base.h"
       9             : 
      10             : /* FD_FUNK_TXN_{ALIGN,FOOTPRINT} describe the alignment and footprint of
      11             :    a fd_funk_txn_t.  ALIGN will be an power of 2, footprint will be a
      12             :    multiple of align.  These are provided to facilitate compile time
      13             :    declarations. */
      14             : 
      15             : #define FD_FUNK_TXN_ALIGN     (32UL)
      16             : #define FD_FUNK_TXN_FOOTPRINT (96UL)
      17             : 
      18             : /* FD_FUNK_TXN_IDX_NULL gives the map transaction idx value used to
      19             :    represent NULL.  It also is the maximum value for txn_max in a funk
      20             :    to support index compression.  (E.g. could use ushort / USHORT_MAX
      21             :    to use more aggressive compression or ulong / ULONG_MAX to disable
      22             :    index compression.) */
      23             : 
      24  3458916813 : #define FD_FUNK_TXN_IDX_NULL ((ulong)UINT_MAX)
      25             : 
      26             : /* A fd_funk_txn_t is an opaque handle of a in-preparation funk
      27             :    transaction.  The details are exposed here to facilitate inlining
      28             :    various operations. */
      29             : 
      30             : struct __attribute__((aligned(FD_FUNK_TXN_ALIGN))) fd_funk_txn_private {
      31             : 
      32             :   /* These fields are managed by the funk's txn_map */
      33             : 
      34             :   fd_funk_txn_xid_t xid;      /* Transaction id, at a minimum, unique among all in-prepare and the last published transaction,
      35             :                                  ideally globally unique */
      36             :   ulong             map_next; /* Internal use by map */
      37             :   ulong             map_hash; /* Internal use by map */
      38             : 
      39             :   /* These fields are managed by the funk */
      40             : 
      41             :   uint   parent_cidx;       /* compr map index of the in-prep parent         txn, compr FD_FUNK_TXN_IDX_NULL if a funk child */
      42             :   uint   child_head_cidx;   /* "                              oldest   child      "                             childless */
      43             :   uint   child_tail_cidx;   /* "                              youngest child                                    childless */
      44             :   uint   sibling_prev_cidx; /* "                              older sibling                                     oldest sibling */
      45             :   uint   sibling_next_cidx; /* "                              younger sibling                                   youngest sibling */
      46             :   uint   stack_cidx;        /* Internal use by funk */
      47             :   ulong  tag;               /* Internal use by funk */
      48             : 
      49             :   ulong  rec_head_idx;      /* Record map index of the first record, FD_FUNK_REC_IDX_NULL if none (from oldest to youngest) */
      50             :   ulong  rec_tail_idx;      /* "                       last          " */
      51             : };
      52             : 
      53             : typedef struct fd_funk_txn_private fd_funk_txn_t;
      54             : 
      55             : /* fd_funk_txn_map allows for indexing transactions by their xid */
      56             : 
      57             : #define MAP_NAME              fd_funk_txn_map
      58             : #define MAP_T                 fd_funk_txn_t
      59             : #define MAP_KEY_T             fd_funk_txn_xid_t
      60             : #define MAP_KEY               xid
      61   658268538 : #define MAP_KEY_EQ(k0,k1)     fd_funk_txn_xid_eq((k0),(k1))
      62   112571043 : #define MAP_KEY_HASH(k0,seed) fd_funk_txn_xid_hash((k0),(seed))
      63     2547906 : #define MAP_KEY_COPY(kd,ks)   fd_funk_txn_xid_copy((kd),(ks))
      64  1414851072 : #define MAP_NEXT              map_next
      65             : #define MAP_HASH              map_hash
      66             : #define MAP_MAGIC             (0xf173da2ce7172db0UL) /* Firedancer trn db version 0 */
      67             : #define MAP_IMPL_STYLE        1
      68             : #define MAP_MEMOIZE           1
      69             : #include "../util/tmpl/fd_map_giant.c"
      70             : 
      71             : FD_PROTOTYPES_BEGIN
      72             : 
      73             : /* fd_funk_txn_{cidx,idx} convert between an index and a compressed index. */
      74             : 
      75   266596773 : static inline uint  fd_funk_txn_cidx( ulong idx ) { return (uint) idx; }
      76  4516894644 : static inline ulong fd_funk_txn_idx ( uint  idx ) { return (ulong)idx; }
      77             : 
      78             : /* fd_funk_txn_idx_is_null returns 1 if idx is FD_FUNK_TXN_IDX_NULL and
      79             :    0 otherwise. */
      80             : 
      81  2775528462 : static inline int fd_funk_txn_idx_is_null( ulong idx ) { return idx==FD_FUNK_TXN_IDX_NULL; }
      82             : 
      83             : /* Generate a globally unique psuedo-random xid */
      84             : fd_funk_txn_xid_t fd_funk_generate_xid(void);
      85             : 
      86             : /* Accessors */
      87             : 
      88             : /* fd_funk_txn_cnt returns the number of transactions currently in
      89             :    preparation.  Assumes funk is a current local join,
      90             :    map==fd_funk_txn_map( funk, fd_funk_wksp( funk ) ).  See fd_funk.h
      91             :    for fd_funk_txn_max. */
      92             : 
      93    25172139 : FD_FN_PURE static inline ulong fd_funk_txn_cnt( fd_funk_txn_t const * map ) { return fd_funk_txn_map_key_cnt( map ); }
      94             : 
      95             : /* fd_funk_txn_is_full returns 1 if the transaction map is full (i.e.
      96             :    the maximum of transactions that can be in preparation has been
      97             :    reached) and 0 otherwise.  Assumes funk is a current local join,
      98             :    map==fd_funk_txn_map( funk, fd_funk_wksp( funk ) ). */
      99             : 
     100     4165263 : FD_FN_PURE static inline int fd_funk_txn_is_full( fd_funk_txn_t const * map ) { return fd_funk_txn_map_is_full( map ); }
     101             : 
     102             : /* fd_funk_txn_query returns a pointer to an in-preparation transaction
     103             :    whose id is pointed to by xid.  Returns NULL if xid is not an
     104             :    in-preparation transaction.  Assumes funk is a current local join,
     105             :    map==fd_funk_txn_map( funk, fd_funk_wksp( funk ) ), xid points to a
     106             :    transaction id in the caller's address space and there are no
     107             :    concurrent operations on funk or xid.  Retains no interest in xid.
     108             : 
     109             :    The returned pointer is in the caller's address space and, if the
     110             :    return is non-NULL, the lifetime of the returned pointer is the
     111             :    lesser of the funk join or the transaction is published or canceled
     112             :    (either directly or indirectly via publish of a descendant, publish
     113             :    of a competing transaction history or cancel of an ancestor).
     114             : 
     115             :    Callers wanting more control over queries (e.g. concurrent queries,
     116             :    sentinel transactions on failure, queries that don't optimize for
     117             :    future queries by the same xid, etc) should use fd_funk_txn_map_query
     118             :    or fd_funk_txn_map_query_const as appropriate. */
     119             : 
     120             : FD_FN_PURE static inline fd_funk_txn_t *
     121             : fd_funk_txn_query( fd_funk_txn_xid_t const * xid,
     122   474868722 :                    fd_funk_txn_t *           map ) {
     123   474868722 :   return fd_funk_txn_map_query( map, xid, NULL );
     124   474868722 : }
     125             : 
     126             : /* fd_funk_txn_xid returns a pointer in the local address space of the
     127             :    ID of an in-preparation transaction.  Assumes txn points to an
     128             :    in-preparation transaction in the caller's address space.  The
     129             :    lifetime of the returned pointer is the same as the txn's pointer
     130             :    lifetime.  The value at the pointer will be stable for the lifetime
     131             :    of the returned pointer. */
     132             : 
     133  1019925081 : FD_FN_CONST static inline fd_funk_txn_xid_t const * fd_funk_txn_xid( fd_funk_txn_t const * txn ) { return &txn->xid; }
     134             : 
     135             : /* fd_funk_txn_{parent,child_head,child_tail,sibling_prev,sibling_next}
     136             :    return a pointer in the caller's address space to the corresponding
     137             :    relative in-preparation transaction of in-preparation transaction
     138             :    txn.  Assumes map == fd_funk_txn_map( funk, fd_funk_wksp( funk ) ),
     139             :    funk is a current local join and txn points to an in-preparation funk
     140             :    transaction in the caller's address space.  The returned pointer
     141             :    lifetime and address space is as described in fd_funk_txn_query.
     142             :    These are not fortified against map data corruption.
     143             : 
     144             :    Specifically:
     145             : 
     146             :    - parent is the parent transaction.  NULL if txn is a child of funk.
     147             :    - child_head is txn's oldest child.  NULL if txn has no children.
     148             :    - child_tail is txn's youngest child.  NULL if txn has no children.
     149             :    - sibling_prev is txn's closest older sibling.  NULL if txn is the
     150             :      oldest sibling.
     151             :    - sibling_next is txn's closest younger sibling.  NULL if txn is the
     152             :      youngest sibling.
     153             : 
     154             :    E.g. child_head==NULL indicates txn has no children.
     155             :    child_head!=NULL and child_head==child_tail indicates txn has one
     156             :    child.  child_head!=NULL and child_tail!=NULL and
     157             :    child_head!=child_tail indicates txn has many children.
     158             :    sibling_prev==sibling_next==NULL indicate no siblings / locally
     159             :    competing transactions to txn.  If the txn and all its ancestors have
     160             :    no siblings, there are no transaction histories competing with txn
     161             :    globally. */
     162             : 
     163             : #define FD_FUNK_ACCESSOR(field)                     \
     164             : FD_FN_PURE static inline fd_funk_txn_t *            \
     165             : fd_funk_txn_##field( fd_funk_txn_t * txn,           \
     166   399863364 :                      fd_funk_txn_t * map ) {        \
     167   399863364 :   ulong idx = fd_funk_txn_idx( txn->field##_cidx ); \
     168   399863364 :   if( idx==FD_FUNK_TXN_IDX_NULL ) return NULL;      \
     169   399863364 :   return map + idx;                                 \
     170   399863364 : }
     171             : 
     172             : FD_FUNK_ACCESSOR( parent       )
     173             : FD_FUNK_ACCESSOR( child_head   )
     174             : FD_FUNK_ACCESSOR( child_tail   )
     175             : FD_FUNK_ACCESSOR( sibling_prev )
     176             : FD_FUNK_ACCESSOR( sibling_next )
     177             : 
     178             : #undef FD_FUNK_ACCESSOR
     179             : 
     180             : /* fd_funk_txn_frozen returns 1 if the in-preparation transaction is
     181             :    frozen (i.e. has children) and 0 otherwise (i.e. has no children).
     182             :    Assumes txn points to an in-preparation transaction in the caller's
     183             :    address space. */
     184             : 
     185             : FD_FN_PURE static inline int
     186   223895970 : fd_funk_txn_is_frozen( fd_funk_txn_t const * txn ) {
     187   223895970 :   return !fd_funk_txn_idx_is_null( fd_funk_txn_idx( txn->child_head_cidx ) );
     188   223895970 : }
     189             : 
     190             : /* fd_funk_txn_is_only_child returns 1 if the in-preparation transaction
     191             :    txn if is any only child and 0 if it has one or more siblings.
     192             :    Assumes txn points to an in-preparation transaction in the caller's
     193             :    address space. */
     194             : 
     195             : FD_FN_PURE static inline int
     196   164388516 : fd_funk_txn_is_only_child( fd_funk_txn_t const * txn ) {
     197   164388516 :   return ( fd_funk_txn_idx_is_null( fd_funk_txn_idx( txn->sibling_prev_cidx ) ) ) &
     198   164388516 :          ( fd_funk_txn_idx_is_null( fd_funk_txn_idx( txn->sibling_next_cidx ) ) );
     199   164388516 : }
     200             : 
     201             : typedef struct fd_funk_rec fd_funk_rec_t;
     202             : 
     203             : /* Return the first record in a transaction. Returns NULL if the
     204             :    transaction has no records yet. */
     205             : 
     206             : FD_FN_PURE fd_funk_rec_t const *
     207             : fd_funk_txn_first_rec( fd_funk_t *           funk,
     208             :                        fd_funk_txn_t const * txn );
     209             : 
     210             : /* Return the next record in a transaction. Returns NULL if the
     211             :    transaction has no more records. */
     212             : 
     213             : FD_FN_PURE fd_funk_rec_t const *
     214             : fd_funk_txn_next_rec( fd_funk_t *           funk,
     215             :                       fd_funk_rec_t const * rec );
     216             : 
     217             : /* Operations */
     218             : 
     219             : /* fd_funk_txn_ancestor returns a pointer in the caller's address space
     220             :    to the youngest transaction among in-preparation transaction txn and
     221             :    its ancestors that currently has siblings.  Returns NULL if all
     222             :    transactions back to the root transaction have no siblings (e.g.
     223             :    there are no competing transaction histories and thus publishing
     224             :    transaction txn will not require canceling any other competing
     225             :    transactions).  This is a reasonably fast O(length of ancestor
     226             :    history) time (theoretical minimum) and a reasonably small O(1) space
     227             :    (theoretical minimum).  This is not fortified against transaction map
     228             :    data corruption.
     229             : 
     230             :    fd_funk_txn_descendant returns a pointer in the caller's address
     231             :    space to the first transaction among txn and its youngest direct
     232             :    descendant inclusive that currently either has no children or has
     233             :    multiple children.  Returns NULL if txn is not an only child.  This
     234             :    is a reasonably fast O(length of descendant history) time
     235             :    (theoretical minimum) and a reasonably small O(1) space (theoretical
     236             :    minimum).  This is not fortified against transaction map data
     237             :    corruption.
     238             : 
     239             :    That is, if txn's ancestor is NULL, all transactions up to and
     240             :    including txn's descendant (which will be non-NULL) can be published
     241             :    without cancelling any competing transactions.  Further, if the
     242             :    descendant has a child, it has multiple children.  And if has no
     243             :    children, all transactions in preparation are linear from the root to
     244             :    the descendant.
     245             : 
     246             :    In code:
     247             : 
     248             :      if( !fd_funk_txn_ancestor( txn, map ) )
     249             :        fd_funk_publish( funk, fd_funk_txn_descendant( funk, map ) );
     250             : 
     251             :    would publish as much currently uncontested transaction history as
     252             :    possible around txn.
     253             : 
     254             :    Assumes map == fd_funk_txn_map( funk, fd_funk_wksp( funk ) ), funk is
     255             :    a current local join and txn points to an in-preparation transaction
     256             :    of funk in the caller's address space.  The lifetime of the returned
     257             :    pointer is as described in fd_funk_txn_query. */
     258             : 
     259             : FD_FN_PURE static inline fd_funk_txn_t *
     260             : fd_funk_txn_ancestor( fd_funk_txn_t * txn,
     261    46851759 :                       fd_funk_txn_t * map ) {
     262    62095626 :   for(;;) {
     263    62095626 :     if( !fd_funk_txn_is_only_child( txn ) ) break;
     264    15899613 :     fd_funk_txn_t * parent = fd_funk_txn_parent( txn, map );
     265    15899613 :     if( !parent ) return NULL;
     266    15243867 :     txn = parent;
     267    15243867 :   }
     268    46196013 :   return txn;
     269    46851759 : }
     270             : 
     271             : FD_FN_PURE static inline fd_funk_txn_t *
     272             : fd_funk_txn_descendant( fd_funk_txn_t * txn,
     273    49892142 :                         fd_funk_txn_t * map ) {
     274    49892142 :   if( !fd_funk_txn_is_only_child( txn ) ) return NULL; /* TODO: debatable, make contract? */
     275    16555359 :   for(;;) { /* txn is an only child at this point */
     276    16555359 :     fd_funk_txn_t * child = fd_funk_txn_child_head( txn, map );
     277    16555359 :     if( !child || !fd_funk_txn_is_only_child( child ) ) break;
     278     3529692 :     txn = child;
     279     3529692 :   }
     280    13025667 :   return txn;
     281    49892142 : }
     282             : 
     283             : /* IMPORTANT SAFETY TIP! **********************************************/
     284             : 
     285             : /* fd_funk_txn_{prepare,publish,cancel,cancel_siblings,cancel_children}
     286             :    are the pointy end of the stick practically.  As such, these are
     287             :    fortified against transaction map memory corruption.  Since any such
     288             :    corruption would be prima facie evidence of a hardware fault,
     289             :    security compromise or software bug, these will FD_LOG_CRIT if
     290             :    corruption is detected to contain the blast radius and get as much
     291             :    ultra detailed diagnostic information to user (stack backtrace and
     292             :    core) as possible.  (This behavior is straightforward to disable in
     293             :    fd_funk_txn.c.) */
     294             : 
     295             : /**********************************************************************/
     296             : 
     297             : /* fd_funk_txn_prepare starts preparation of a transaction.  The
     298             :    transaction will be a child of the in-preparation transaction pointed
     299             :    to by parent.  A NULL parent means the transaction should be a child
     300             :    of funk.  xid points to transaction id that should be used for the
     301             :    transaction.  This id must be unique over all in-preparation
     302             :    transactions, the root transaction and the last published
     303             :    transaction.  It is strongly recommended to use globally unique ids
     304             :    when possible.  Returns a pointer in the caller's address space to
     305             :    the in-preparation transaction on success and NULL on failure.  The
     306             :    lifetime of the returned pointer is as described in
     307             :    fd_funk_txn_query.
     308             : 
     309             :    At start of preparation, the records in the txn are a clone of the
     310             :    records in its parent transaction.  The funk records can be modified
     311             :    when the funk has no children.  Similarly, the records of an
     312             :    in-preparation transaction can be freely modified when the funk has
     313             :    no children.
     314             : 
     315             :    Assumes funk is a current local join.  Reasons for failure include
     316             :    funk is NULL, the funk's transaction map is full, the parent is
     317             :    neither NULL nor points to an in-preparation funk transaction, xid is
     318             :    NULL, the requested xid is in use (i.e. the last published or matches
     319             :    another in-preparation transaction).  If verbose is non-zero, these
     320             :    will FD_LOG_WARNING details about the reason for failure.
     321             : 
     322             :    This is a reasonably fast O(1) time (theoretical minimum), reasonably
     323             :    small O(1) space (theoretical minimum), does no allocation, does no
     324             :    system calls, and produces no garbage to collect (at this layer at
     325             :    least).  That is, we can scalably track forks until we run out of
     326             :    resources allocated to the funk. */
     327             : 
     328             : fd_funk_txn_t *
     329             : fd_funk_txn_prepare( fd_funk_t *               funk,
     330             :                      fd_funk_txn_t *           parent,
     331             :                      fd_funk_txn_xid_t const * xid,
     332             :                      int                       verbose );
     333             : 
     334             : /* fd_funk_txn_cancel cancels in-preparation transaction txn and any of
     335             :    its in-preparation descendants.  On success, returns the number of
     336             :    transactions cancelled and 0 on failure.  The state of records in the
     337             :    cancelled transactions will be lost and all resources used under the
     338             :    hood are available for reuse.  If this makes the txn's parent
     339             :    childless, this will unfreeze the parent.
     340             : 
     341             :    fd_funk_txn_cancel_siblings cancels txn's siblings and their
     342             :    descendants.
     343             : 
     344             :    fd_funk_txn_cancel_children cancels txn's children and their
     345             :    descendants.  If txn is NULL, all children of funk will be cancelled
     346             :    (such that the number of transactions in preparation afterward will
     347             :    be zero).
     348             : 
     349             :    Cancellations proceed from youngest to oldest in a tree depth first
     350             :    sense.
     351             : 
     352             :    Assumes funk is a current local join.  Reasons for failure include
     353             :    NULL funk or txn does not point to an in-preparation funk
     354             :    transaction.  If verbose is non-zero, these will FD_LOG_WARNING level
     355             :    details about the reason for failure.
     356             : 
     357             :    These are a reasonably fast O(number of cancelled transactions) time
     358             :    (the theoretical minimum), reasonably small O(1) space (the
     359             :    theoretical minimum), does no allocation, does no system calls, and
     360             :    produces no garbage to collect (at this layer at least).  That is, we
     361             :    can scalably track forks until we run out of resources allocated to
     362             :    the funk. */
     363             : 
     364             : ulong
     365             : fd_funk_txn_cancel( fd_funk_t *     funk,
     366             :                     fd_funk_txn_t * txn,
     367             :                     int             verbose );
     368             : 
     369             : ulong
     370             : fd_funk_txn_cancel_siblings( fd_funk_t *     funk,
     371             :                              fd_funk_txn_t * txn,
     372             :                              int             verbose );
     373             : 
     374             : ulong
     375             : fd_funk_txn_cancel_children( fd_funk_t *     funk,
     376             :                              fd_funk_txn_t * txn,
     377             :                              int             verbose );
     378             : 
     379             : ulong
     380             : fd_funk_txn_cancel_all( fd_funk_t *     funk,
     381             :                         int             verbose );
     382             : 
     383             : /* fd_funk_txn_publish publishes in-preparation transaction txn and any
     384             :    of txn's in-preparation ancestors.  Returns the number of
     385             :    transactions published.  Any competing histories to this chain will
     386             :    be cancelled.
     387             : 
     388             :    This follows a principle of least information loss.  Specifically,
     389             :    publications proceed incrementally from the oldest ancestor to txn
     390             :    inclusive.  When a transaction is published, the transaction is first
     391             :    committed to permanent storage.  If this is unsuccessful, the publish
     392             :    is stopped at this transaction and the transaction remains
     393             :    unpublished.  Otherwise, the transaction's siblings and their
     394             :    descendants are cancelled.
     395             : 
     396             :    As such, it is possible in a funk implementation (e.g. permanent
     397             :    storage I/O errors) for fd_funk_txn_publish to only publish some of
     398             :    the ancestors.  Partial publication will only happen on error.  On
     399             :    such a failure, no information is lost about the transaction that
     400             :    failed to publish, its siblings or its descendants.  Likewise, all
     401             :    the failed transaction's ancestors were reliably published.  Funk
     402             :    last publish, query, the various traversals and so forth can be used
     403             :    to diagnose the details about such situations.
     404             : 
     405             :    Assumes funk is a current local join.  Reasons for failure include
     406             :    NULL funk, txn does not point to an in-preparation funk transaction.
     407             :    If verbose is non-zero, these will FD_LOG_WARNING the details about
     408             :    the reason for failure.
     409             : 
     410             :    This is a reasonably fast O(number of published transactions) +
     411             :    O(number of cancelled transactions) time (theoretical minimum),
     412             :    reasonably small O(1) space (theoretical minimum), does no allocation
     413             :    does no system calls, and produces no garbage to collect (at this
     414             :    layer at least).  That is, we can scalably track forks until we run
     415             :    out of resources allocated to the funk. */
     416             : 
     417             : ulong
     418             : fd_funk_txn_publish( fd_funk_t *     funk,
     419             :                      fd_funk_txn_t * txn,
     420             :                      int             verbose );
     421             : 
     422             : /* This version of publish just combines the transaction with its
     423             :    immediate parent. Ancestors will remain unpublished. Any competing
     424             :    histories (siblings of the given transaction) are still cancelled.
     425             : 
     426             :    Returns FD_FUNK_SUCCESS on success or an error code on failure. */
     427             : int
     428             : fd_funk_txn_publish_into_parent( fd_funk_t *     funk,
     429             :                                  fd_funk_txn_t * txn,
     430             :                                  int             verbose );
     431             : 
     432             : /* fd_funk_txn_merge merges all the children into their parent
     433             :    transaction. The intention is to support gathering small,
     434             :    short-term transactions into a large transaction. Strictly
     435             :    speaking, this API isn't required, but a list of small children can
     436             :    be more efficiently and conveniently managed as a single large
     437             :    transaction if the intention is to publish all of them at
     438             :    once. Recall that child transactions can be cancelled due to an
     439             :    error without affecting the parent transaction, which allows
     440             :    robust, incremental assembly of a very big transaction.
     441             : 
     442             :    The children must not have grandchildren.
     443             : 
     444             :    Returns FD_FUNK_SUCCESS on success or an error code on failure.
     445             : 
     446             :    Assumes funk is a current local join.  Reasons for failure include
     447             :    NULL funk or txn does not point to an in-preparation funk
     448             :    transaction.  If verbose is non-zero, these will FD_LOG_WARNING level
     449             :    details about the reason for failure. */
     450             : 
     451             : int
     452             : fd_funk_txn_merge_all_children( fd_funk_t *     funk,
     453             :                                 fd_funk_txn_t * parent_txn,
     454             :                                 int             verbose );
     455             : 
     456             : /* Misc */
     457             : 
     458             : /* fd_funk_txn_verify verifies a transaction map.  Returns
     459             :    FD_FUNK_SUCCESS if the transaction map appears intact and
     460             :    FD_FUNK_ERR_INVAL if not (logs details).  Meant to be called as part
     461             :    of fd_funk_verify.  As such, it assumes funk is non-NULL and
     462             :    fd_funk_{wksp,txn_map} have already been verified to work. */
     463             : 
     464             : int
     465             : fd_funk_txn_verify( fd_funk_t * funk );
     466             : 
     467             : FD_PROTOTYPES_END
     468             : 
     469             : #endif /* HEADER_fd_src_funk_fd_funk_txn_h */

Generated by: LCOV version 1.14