LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_txncache_private.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 2 7 28.6 %
Date: 2025-11-23 04:57:59 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_fd_txncache_private_h
       2             : #define HEADER_fd_src_flamenco_runtime_fd_txncache_private_h
       3             : 
       4             : #include "fd_txncache_shmem.h"
       5             : #include "../types/fd_types_custom.h"
       6             : #include "../fd_rwlock.h"
       7             : 
       8             : /* The number of transactions in each page.  This needs to be high
       9             :    enough to amoritze the cost of caller code reserving pages from,
      10             :    and returning pages to the pool, but not so high that the memory
      11             :    wasted from blockhashes with only one transaction is significant. */
      12             : 
      13           6 : #define FD_TXNCACHE_TXNS_PER_PAGE (16384UL)
      14             : 
      15             : /* The maximum distance a transaction blockhash reference can be
      16             :    (inclusive).  For example, if no slots were skipped, and the value is
      17             :    151, slot 300 is allowed to reference blockhashes from slots
      18             :    [149, 300). */
      19           3 : #define FD_TXNCACHE_MAX_BLOCKHASH_DISTANCE (151UL)
      20             : 
      21             : struct fd_txncache_single_txn {
      22             :   uint  blockcache_next; /* Pointer to the next element in the blockcache hash chain containing this entry from the pool. */
      23             :   uint  generation;      /* The generation of the fork when this transaction was inserted.  Used to
      24             :                             determine if the transaction is still valid for a fork that might have
      25             :                             advanced since insertion. */
      26             : 
      27             :   fd_txncache_fork_id_t fork_id; /* Fork that the transaction was executed on.  A transaction might be in the cache
      28             :                                     multiple times if it was executed on multiple forks. */
      29             :   uchar txnhash[ 20UL ]; /* The transaction message hash, truncated to 20 bytes.  The hash is not always the first 20
      30             :                             bytes, but is 20 bytes starting at some arbitrary offset given by the txnhash_offset value
      31             :                             of the containing blockcache entry. */
      32             : };
      33             : 
      34             : typedef struct fd_txncache_single_txn fd_txncache_single_txn_t;
      35             : 
      36             : struct fd_txncache_txnpage {
      37             :   ushort                   free; /* The number of free txn entries in this page. */
      38             :   fd_txncache_single_txn_t txns[ FD_TXNCACHE_TXNS_PER_PAGE][ 1 ]; /* The transactions in the page. */
      39             : };
      40             : 
      41             : typedef struct fd_txncache_txnpage fd_txncache_txnpage_t;
      42             : 
      43             : struct fd_txncache_blockcache_shmem {
      44             :   fd_txncache_fork_id_t parent_id;
      45             :   fd_txncache_fork_id_t child_id;
      46             :   fd_txncache_fork_id_t sibling_id;
      47             : 
      48             :   int frozen;            /* This is used to enforce invariants on the caller of the txncache.
      49             :                             -1: invalid
      50             :                              0: active
      51             :                              1: semi frozen, only happens during snapshot load
      52             :                              2: frozen, should not be modified */
      53             : 
      54             :   uint generation;
      55             : 
      56             :   fd_hash_t blockhash;   /* The blockhash that this entry is for. */
      57             :   ulong txnhash_offset;  /* To save memory, the Agave validator decided to truncate the hash of transactions stored in
      58             :                             this memory to 20 bytes rather than 32 bytes.  The bytes used are not the first 20 as you
      59             :                             might expect, but instead the first 20 starting at some random offset into the transaction
      60             :                             hash (starting between 0 and len(hash)-20, a/k/a 44 for signatures, and 12 for hashes).
      61             : 
      62             :                             In an unfortunate turn, the offset is also propogated to peers via. snapshot responses,
      63             :                             which only communicate the offset and the respective 20 bytes.  To make sure we are
      64             :                             deduplicating incoming transactions correctly, we must replicate this system even though
      65             :                             it would be easier to just always take the first 20 bytes.  For transactions that we
      66             :                             insert into the cache ourselves, we do just always use a key_offset of zero, so this is
      67             :                             only nonzero when constructed form a peer snapshot. */
      68             : 
      69             :   ushort pages_cnt;      /* The number of txnpages currently in use to store the transactions in this blockcache. */
      70             : 
      71             :   struct {
      72             :     ulong next;
      73             :   } pool;
      74             : 
      75             :   struct {
      76             :     ulong next;
      77             :   } slist;
      78             : 
      79             :   struct {
      80             :     ulong next;
      81             :     ulong prev;
      82             :   } blockhash_map;
      83             : 
      84             :   struct {
      85             :     ulong next;
      86             :     ulong prev;
      87             :   } fork_map;
      88             : };
      89             : 
      90             : typedef struct fd_txncache_blockcache_shmem fd_txncache_blockcache_shmem_t;
      91             : 
      92             : #define POOL_NAME       blockcache_pool
      93             : #define POOL_T          fd_txncache_blockcache_shmem_t
      94             : #define POOL_IDX_T      ulong
      95           0 : #define POOL_NEXT       pool.next
      96             : #define POOL_IMPL_STYLE 1
      97             : #include "../../util/tmpl/fd_pool.c"
      98             : 
      99             : #define MAP_NAME               blockhash_map
     100             : #define MAP_KEY                blockhash
     101             : #define MAP_ELE_T              fd_txncache_blockcache_shmem_t
     102             : #define MAP_KEY_T              fd_hash_t
     103             : #define MAP_PREV               blockhash_map.prev
     104             : #define MAP_NEXT               blockhash_map.next
     105           0 : #define MAP_KEY_EQ(k0,k1)      fd_hash_eq( k0, k1 )
     106           0 : #define MAP_KEY_HASH(key,seed) (__extension__({ (void)(seed); fd_ulong_load_8_fast( (key)->uc ); }))
     107             : #define MAP_OPTIMIZE_RANDOM_ACCESS_REMOVAL 1
     108             : #define MAP_MULTI              1
     109             : #define MAP_IMPL_STYLE         1
     110             : #include "../../util/tmpl/fd_map_chain.c"
     111             : 
     112             : #define SLIST_NAME       root_slist
     113             : #define SLIST_ELE_T      fd_txncache_blockcache_shmem_t
     114           0 : #define SLIST_IDX_T      ulong
     115           0 : #define SLIST_NEXT       slist.next
     116             : #define SLIST_IMPL_STYLE 1
     117             : #include "../../util/tmpl/fd_slist.c"
     118             : 
     119             : #define SET_NAME descends_set
     120             : #include "../../util/tmpl/fd_set_dynamic.c"
     121             : 
     122             : struct __attribute__((aligned(FD_TXNCACHE_SHMEM_ALIGN))) fd_txncache_shmem_private {
     123             :   /* The txncache is a concurrent structure and will be accessed by multiple threads
     124             :      concurrently.  Insertion and querying only take a read lock as they can be done
     125             :      lockless but all other operations will take a write lock internally.
     126             : 
     127             :      The lock needs to be aligned to 128 bytes to avoid false sharing with other
     128             :      data that might be on the same cache line. */
     129             :   fd_rwlock_t lock[ 1 ] __attribute__((aligned(128UL)));
     130             : 
     131             :   ulong  txn_per_slot_max;
     132             :   ulong  active_slots_max;
     133             :   ushort txnpages_per_blockhash_max;
     134             :   ushort max_txnpages;
     135             : 
     136             :   uint blockcache_generation; /* Incremented for every blockcache. */
     137             :   ushort txnpages_free_cnt; /* The number of pages in the txnpages that are not currently in use. */
     138             : 
     139             :   ulong root_cnt;
     140             :   root_slist_t root_ll[1]; /* A singly linked list of the forks that are roots of fork chains.  The tail is the
     141             :                               most recently added root, the head is the oldest root.  This is used to identify
     142             :                               which forks can be pruned when a new root is added. */
     143             : 
     144             :   ulong magic; /* ==FD_TXNCACHE_MAGIC */
     145             : };
     146             : 
     147             : FD_PROTOTYPES_BEGIN
     148             : 
     149             : FD_FN_CONST ushort
     150             : fd_txncache_max_txnpages_per_blockhash( ulong max_active_slots,
     151             :                                         ulong max_txn_per_slot );
     152             : 
     153             : FD_FN_CONST ushort
     154             : fd_txncache_max_txnpages( ulong max_active_slots,
     155             :                           ulong max_txn_per_slot );
     156             : 
     157             : FD_PROTOTYPES_END
     158             : 
     159             : #endif /* HEADER_fd_src_flamenco_runtime_fd_txncache_private_h */

Generated by: LCOV version 1.14