LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_blockstore.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 77 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 1666 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_fd_blockstore_h
       2             : #define HEADER_fd_src_flamenco_runtime_fd_blockstore_h
       3             : 
       4             : /* Blockstore is a high-performance database for storing, building, and tracking blocks.
       5             : 
       6             :    `fd_blockstore` defines a number of useful types e.g. `fd_block_t`, `fd_block_shred`, etc. */
       7             : 
       8             : #include "../../ballet/block/fd_microblock.h"
       9             : #include "../../ballet/shred/fd_deshredder.h"
      10             : #include "../../ballet/shred/fd_shred.h"
      11             : #include "../fd_flamenco_base.h"
      12             : #include "../types/fd_types.h"
      13             : #include "fd_rwseq_lock.h"
      14             : #include "stdbool.h"
      15             : 
      16             : /* FD_BLOCKSTORE_{ALIGN,FOOTPRINT} describe the alignment and footprint needed
      17             :    for a blockstore.  ALIGN should be a positive integer power of 2.
      18             :    FOOTPRINT is multiple of ALIGN.  These are provided to facilitate
      19             :    compile time declarations.  */
      20             : 
      21             : /* clang-format off */
      22             : #define FD_BLOCKSTORE_ALIGN        (128UL)
      23             : #define FD_BLOCKSTORE_FOOTPRINT    (256UL)
      24           0 : #define FD_BLOCKSTORE_MAGIC        (0xf17eda2ce7b10c00UL) /* firedancer bloc version 0 */
      25             : 
      26             : /* DO NOT MODIFY. */
      27             : #define FD_BUF_SHRED_MAP_MAX (1UL << 24UL) /* 16 million shreds can be buffered */
      28             : #define FD_TXN_MAP_LG_MAX    (24)          /* 16 million txns can be stored in the txn map */
      29             : 
      30             : /* TODO this can be removed if we explicitly manage a memory pool for
      31             :    the fd_block_map_t entries */
      32           0 : #define FD_BLOCKSTORE_CHILD_SLOT_MAX (32UL) /* the maximum # of children a slot can have */
      33             : 
      34             : // TODO centralize these
      35             : // https://github.com/firedancer-io/solana/blob/v1.17.5/sdk/program/src/clock.rs#L34
      36             : #define FD_MS_PER_TICK 6
      37             : 
      38             : // https://github.com/firedancer-io/solana/blob/v1.17.5/core/src/repair/repair_service.rs#L55
      39             : #define FD_REPAIR_TIMEOUT (200 / FD_MS_PER_TICK)
      40             : 
      41           0 : #define FD_BLOCKSTORE_OK                  0
      42           0 : #define FD_BLOCKSTORE_OK_SLOT_COMPLETE    1
      43             : #define FD_BLOCKSTORE_ERR_SHRED_FULL      -1 /* no space left for shreds */
      44           0 : #define FD_BLOCKSTORE_ERR_SLOT_FULL       -2 /* no space left for slots */
      45             : #define FD_BLOCKSTORE_ERR_TXN_FULL        -3 /* no space left for txns */
      46             : #define FD_BLOCKSTORE_ERR_SHRED_MISSING   -4
      47           0 : #define FD_BLOCKSTORE_ERR_SLOT_MISSING    -5
      48           0 : #define FD_BLOCKSTORE_ERR_TXN_MISSING     -6
      49           0 : #define FD_BLOCKSTORE_ERR_SHRED_INVALID   -7 /* shred was invalid */
      50           0 : #define FD_BLOCKSTORE_ERR_DESHRED_INVALID -8 /* deshredded block was invalid */
      51           0 : #define FD_BLOCKSTORE_ERR_NO_MEM          -9 /* no mem */
      52           0 : #define FD_BLOCKSTORE_ERR_UNKNOWN         -99
      53             : 
      54             : /* clang-format on */
      55             : 
      56             : struct fd_shred_key {
      57             :   ulong slot;
      58             :   uint  idx;
      59             : };
      60             : typedef struct fd_shred_key fd_shred_key_t;
      61             : 
      62             : /* clang-format off */
      63             : static const fd_shred_key_t     fd_shred_key_null = { 0 };
      64             : #define FD_SHRED_KEY_NULL       fd_shred_key_null
      65             : #define FD_SHRED_KEY_INVAL(key) (!((key).slot) & !((key).idx))
      66           0 : #define FD_SHRED_KEY_EQ(k0,k1)  (!(((k0).slot) ^ ((k1).slot))) & !(((k0).idx) ^ (((k1).idx)))
      67           0 : #define FD_SHRED_KEY_HASH(key)  ((uint)(((key).slot)<<15UL) | (((key).idx))) /* current max shred idx is 32KB = 2 << 15*/
      68             : /* clang-format on */
      69             : 
      70             : /* fd_buf_shred is a thin wrapper around fd_shred_t that facilitates
      71             :    buffering data shreds before all the shreds for a slot have been
      72             :    received. After all shreds are received, these buffered shreds are
      73             :    released back into memory pool and future queries for the shreds are
      74             :    offset into the block data directly.
      75             : 
      76             :    The blockstore is only aware of data shreds and all APIs involving
      77             :    shreds refers to data shreds.
      78             : 
      79             :    Shreds are buffered into a map as they are received:
      80             : 
      81             :    | 0 | 1 | 2 | x | x | 5 | x |
      82             :              ^           ^
      83             :              c           r
      84             : 
      85             :    c = "consumed" = contiguous window starting from index 0
      86             :    r = "received" = highest index received so far
      87             : 
      88             :    Shred memory layout while stored in the map:
      89             : 
      90             :    | shred hdr | shred payload |
      91             : */
      92             : struct fd_buf_shred {
      93             :   fd_shred_key_t key;
      94             :   ulong          next;
      95             :   union {
      96             :     fd_shred_t hdr;                  /* data shred header */
      97             :     uchar      raw[FD_SHRED_MAX_SZ]; /* the data shred as raw bytes, both header and payload. */
      98             :   };
      99             : };
     100             : typedef struct fd_buf_shred fd_buf_shred_t;
     101             : 
     102             : #define POOL_NAME fd_buf_shred_pool
     103           0 : #define POOL_T    fd_buf_shred_t
     104             : #include "../../util/tmpl/fd_pool.c"
     105             : 
     106             : /* clang-format off */
     107             : #define MAP_NAME               fd_buf_shred_map
     108             : #define MAP_ELE_T              fd_buf_shred_t
     109             : #define MAP_KEY_T              fd_shred_key_t
     110           0 : #define MAP_KEY_EQ(k0,k1)      (FD_SHRED_KEY_EQ(*k0,*k1))
     111           0 : #define MAP_KEY_HASH(key,seed) (FD_SHRED_KEY_HASH(*key)^seed)
     112             : #include "../../util/tmpl/fd_map_chain.c"
     113             : /* clang-format on */
     114             : 
     115             : #define DEQUE_NAME fd_blockstore_slot_deque
     116           0 : #define DEQUE_T    ulong
     117             : #include "../../util/tmpl/fd_deque_dynamic.c"
     118             : 
     119             : /* A shred that has been deshredded and is part of a block (beginning at off) */
     120             : struct fd_block_shred {
     121             :   fd_shred_t hdr; /* ptr to the data shred header */
     122             :   uchar      merkle[FD_SHRED_MERKLE_ROOT_SZ + FD_SHRED_MERKLE_NODE_SZ*9U /* FD_FEC_SET_MAX_BMTREE_DEPTH */];
     123             :   ulong      merkle_sz;
     124             :   ulong      off; /* offset to the payload relative to the start of the block's data region */
     125             : };
     126             : typedef struct fd_block_shred fd_block_shred_t;
     127             : 
     128             : /* A microblock (otherwise known as an "entry" in Solana parlance) that has been parsed and is part
     129             :    of a block (beginning at off) */
     130             : struct fd_block_micro {
     131             :   ulong off; /* offset into block data */
     132             : };
     133             : typedef struct fd_block_micro fd_block_micro_t;
     134             : 
     135             : /* A transaction that has been parsed and is part of a block (beginning at txn_off) */
     136             : struct fd_block_txn_ref {
     137             :   ulong txn_off; /* offset into block data of transaction */
     138             :   ulong id_off;  /* offset into block data of transaction identifiers */
     139             :   ulong sz;
     140             : };
     141             : typedef struct fd_block_txn_ref fd_block_txn_ref_t;
     142             : 
     143             : /* If the 0th bit is set, this indicates the block is preparing, which
     144             :    means it might be partially executed e.g. a subset of the microblocks
     145             :    have been executed.  It is not safe to remove, relocate, or modify
     146             :    the block in any way at this time.
     147             : 
     148             :    Callers holding a pointer to a block should always make sure to
     149             :    inspect this flag.
     150             : 
     151             :    Other flags mainly provide useful metadata for read-only callers, eg.
     152             :    RPC. */
     153             : 
     154           0 : #define FD_BLOCK_FLAG_SHREDDING 0 /* xxxxxxx1 still receiving shreds */
     155           0 : #define FD_BLOCK_FLAG_COMPLETED 1 /* xxxxxx1x received all shreds (DATA_COMPLETE) */
     156           0 : #define FD_BLOCK_FLAG_REPLAYING 2 /* xxxxx1xx replay in progress (DO NOT REMOVE) */
     157           0 : #define FD_BLOCK_FLAG_PROCESSED 3 /* xxxx1xxx successfully replayed the block */
     158           0 : #define FD_BLOCK_FLAG_EQVOCSAFE 4 /* xxxx1xxx 52% of cluster has voted on this (slot, bank hash) */
     159           0 : #define FD_BLOCK_FLAG_CONFIRMED 5 /* xxx1xxxx 2/3 of cluster has voted on this (slot, bank hash) */
     160           0 : #define FD_BLOCK_FLAG_FINALIZED 6 /* xx1xxxxx 2/3 of cluster has rooted this slot */
     161             : #define FD_BLOCK_FLAG_DEADBLOCK 7 /* x1xxxxxx failed to replay the block */
     162             : 
     163             : /* Rewards assigned after block is executed */
     164             : 
     165             : struct fd_block_rewards {
     166             :   ulong collected_fees;
     167             :   fd_hash_t leader;
     168             :   ulong post_balance;
     169             : };
     170             : typedef struct fd_block_rewards fd_block_rewards_t;
     171             : 
     172             : /* Remaining bits [4, 8) are reserved.
     173             : 
     174             :    To avoid confusion, please use `fd_bits.h` API
     175             :    ie. `fd_uchar_set_bit`, `fd_uchar_extract_bit`. */
     176             : 
     177             : struct fd_block {
     178             : 
     179             :   /* Computed rewards */
     180             : 
     181             :   fd_block_rewards_t rewards;
     182             : 
     183             :   /* data region
     184             : 
     185             :   A block's data region is indexed to support iterating by shred, microblock, or
     186             :   transaction. This is done by iterating the headers for each, stored in allocated memory. To
     187             :   iterate shred payloads, for example, a caller should iterate the headers in tandem with the data region
     188             :   (offsetting by the bytes indicated in the shred header).
     189             : 
     190             :   Note random access of individual shred indices is not performant, due to the variable-length
     191             :   nature of shreds. */
     192             : 
     193             :   ulong data_gaddr;   /* ptr to the beginning of the block's allocated data region */
     194             :   ulong data_sz;      /* block size */
     195             :   ulong shreds_gaddr; /* ptr to the first fd_block_shred_t */
     196             :   ulong shreds_cnt;
     197             :   ulong micros_gaddr; /* ptr to the list of fd_blockstore_micro_t */
     198             :   ulong micros_cnt;
     199             :   ulong txns_gaddr;   /* ptr to the list of fd_blockstore_txn_ref_t */
     200             :   ulong txns_cnt;
     201             :   ulong txns_meta_gaddr; /* ptr to the allocation for txn meta data */
     202             :   ulong txns_meta_sz;
     203             : };
     204             : typedef struct fd_block fd_block_t;
     205             : 
     206             : struct fd_block_map {
     207             :   ulong slot; /* map key */
     208             :   ulong next; /* reserved for use by fd_map_giant.c */
     209             : 
     210             :   /* Ancestry */
     211             : 
     212             :   ulong parent_slot;
     213             :   ulong child_slots[FD_BLOCKSTORE_CHILD_SLOT_MAX];
     214             :   ulong child_slot_cnt;
     215             : 
     216             :   /* Metadata */
     217             : 
     218             :   ulong     height;
     219             :   fd_hash_t block_hash;
     220             :   fd_hash_t bank_hash;
     221             :   uchar     flags;
     222             :   uchar     reference_tick; /* the tick when the leader prepared the block. */
     223             :   long      ts;             /* the wallclock time when we finished receiving the block. */
     224             : 
     225             :   /* Windowing */
     226             : 
     227             :   uint consumed_idx; /* the highest shred idx of the contiguous window from idx 0 (inclusive). */
     228             :   uint received_idx; /* the highest shred idx we've received (exclusive). */
     229             :   uint complete_idx; /* the shred idx with the FD_SHRED_DATA_FLAG_SLOT_COMPLETE flag set. */
     230             : 
     231             :   /* Block */
     232             : 
     233             :   ulong block_gaddr; /* global address to the start of the allocated fd_block_t */
     234             : };
     235             : typedef struct fd_block_map fd_block_map_t;
     236             : 
     237             : /* clang-format off */
     238             : #define MAP_NAME         fd_block_map
     239           0 : #define MAP_T            fd_block_map_t
     240           0 : #define MAP_KEY          slot
     241             : #include "../../util/tmpl/fd_map_giant.c"
     242             : /* clang-format on */
     243             : 
     244             : struct fd_blockstore_txn_key {
     245             :   ulong v[FD_ED25519_SIG_SZ / sizeof( ulong )];
     246             : };
     247             : typedef struct fd_blockstore_txn_key fd_blockstore_txn_key_t;
     248             : 
     249             : struct fd_blockstore_txn_map {
     250             :   fd_blockstore_txn_key_t sig;
     251             :   ulong                   next;
     252             :   ulong                   slot;
     253             :   ulong                   offset;
     254             :   ulong                   sz;
     255             :   ulong                   meta_gaddr; /* ptr to the transaction metadata */
     256             :   ulong                   meta_sz;    /* metadata size */
     257             : };
     258             : typedef struct fd_blockstore_txn_map fd_blockstore_txn_map_t;
     259             : 
     260             : /* clang-format off */
     261             : #define MAP_NAME  fd_blockstore_txn_map
     262           0 : #define MAP_T     fd_blockstore_txn_map_t
     263           0 : #define MAP_KEY   sig
     264             : #define MAP_KEY_T fd_blockstore_txn_key_t
     265             : int fd_blockstore_txn_key_equal(fd_blockstore_txn_key_t const * k0, fd_blockstore_txn_key_t const * k1);
     266           0 : #define MAP_KEY_EQ(k0,k1)    fd_blockstore_txn_key_equal(k0,k1)
     267             : ulong fd_blockstore_txn_key_hash(fd_blockstore_txn_key_t const * k, ulong seed);
     268           0 : #define MAP_KEY_HASH(k,seed) fd_blockstore_txn_key_hash(k, seed)
     269             : #include "../../util/tmpl/fd_map_giant.c"
     270             : 
     271             : // TODO make this private
     272             : struct __attribute__((aligned(FD_BLOCKSTORE_ALIGN))) fd_blockstore_private {
     273             : 
     274             :   /* Metadata */
     275             : 
     276             :   ulong magic;
     277             :   ulong blockstore_gaddr;
     278             :   ulong wksp_tag;
     279             :   ulong seed;
     280             : 
     281             :   /* Concurrency */
     282             : 
     283             :   fd_rwseq_lock_t lock;
     284             : 
     285             :   /* Slot metadata */
     286             : 
     287             :   ulong min;  /* minimum slot in the blockstore with a block. we retain
     288             :                  blocks prior to the smr to serve repair and RPC */
     289             :   ulong max;  /* maximum slot in the blockstore with a block */
     290             :   ulong lps;  /* latest processed slot */
     291             :   ulong hcs;  /* highest confirmed slot */
     292             :   ulong smr;  /* supermajority root. DO NOT MODIFY DIRECTLY, instead use fd_blockstore_publish */
     293             : 
     294             :   /* Internal data structures */
     295             : 
     296             :   ulong shred_max;        /* max number of temporary shreds */
     297             :   ulong shred_pool_gaddr; /* pool of temporary shreds */
     298             :   ulong shred_map_gaddr;  /* map of (slot, shred_idx)->shred */
     299             : 
     300             :   ulong slot_max;           /* maximum # of blocks */
     301             :   ulong slot_map_gaddr;     /* map of slot->(slot_meta, block) */
     302             :   ulong slot_deque_gaddr;   /* deque of slots (ulongs) used to traverse blockstore ancestry */
     303             : 
     304             :   ulong lg_txn_max;
     305             :   ulong txn_map_gaddr;
     306             : 
     307             :   /* The blockstore alloc is used for allocating wksp resources for shred headers, microblock
     308             :      headers, and blocks.  This is an fd_alloc. Allocations from this allocator will be tagged with
     309             :      wksp_tag and operations on this allocator will use concurrency group 0. */
     310             : 
     311             :   ulong alloc_gaddr;
     312             : };
     313             : /* clang-format on */
     314             : 
     315             : struct fd_blockstore_private;
     316             : typedef struct fd_blockstore_private fd_blockstore_t;
     317             : 
     318             : FD_PROTOTYPES_BEGIN
     319             : 
     320             : /* Construction API */
     321             : 
     322             : /* TODO document lifecycle methods */
     323             : 
     324             : FD_FN_CONST ulong
     325             : fd_blockstore_align( void );
     326             : 
     327             : FD_FN_CONST ulong
     328             : fd_blockstore_footprint( void );
     329             : 
     330             : void *
     331             : fd_blockstore_new( void * shmem,
     332             :                    ulong  wksp_tag,
     333             :                    ulong  seed,
     334             :                    ulong  shred_max,
     335             :                    ulong  slot_max,
     336             :                    ulong  lg_txn_max );
     337             : 
     338             : fd_blockstore_t *
     339             : fd_blockstore_join( void * shblockstore );
     340             : 
     341             : void *
     342             : fd_blockstore_leave( fd_blockstore_t * blockstore );
     343             : 
     344             : void *
     345             : fd_blockstore_delete( void * shblockstore );
     346             : 
     347             : /* fd_blockstore_init initializes a blockstore with slot_bank. slot_bank
     348             :    should be the bank upon finishing a snapshot load if booting from a
     349             :    snapshot, genesis bank otherwise.  Blockstore then initializes fields
     350             :    and creates a mock block using this slot bank.  This metadata for
     351             :    this block's slot will be populated (fd_block_map_t) but the actual
     352             :    block data (fd_block_t) won't exist.  This is needed to bootstrap the
     353             :    various componenets for live replay (turbine, repair, etc.) */
     354             : 
     355             : fd_blockstore_t *
     356             : fd_blockstore_init( fd_blockstore_t * blockstore, fd_slot_bank_t const * slot_bank );
     357             : 
     358             : /* Accessor API */
     359             : 
     360             : /* fd_blockstore_wksp returns the local join to the wksp backing the
     361             :    blockstore. The lifetime of the returned pointer is at least as long
     362             :    as the lifetime of the local join.  Assumes blockstore is a current
     363             :    local join. */
     364             : 
     365             : FD_FN_PURE static inline fd_wksp_t *
     366           0 : fd_blockstore_wksp( fd_blockstore_t * blockstore ) {
     367           0 :   return (fd_wksp_t *)( ( (ulong)blockstore ) - blockstore->blockstore_gaddr );
     368           0 : }
     369             : 
     370             : /* fd_blockstore_wksp_tag returns the workspace allocation tag used by
     371             :    the blockstore for its wksp allocations.  Will be positive.  Assumes
     372             :    blockstore is a current local join. */
     373             : 
     374             : FD_FN_PURE static inline ulong
     375           0 : fd_blockstore_wksp_tag( fd_blockstore_t * blockstore ) {
     376           0 :   return blockstore->wksp_tag;
     377           0 : }
     378             : 
     379             : /* fd_blockstore_seed returns the hash seed used by the blockstore for various hash
     380             :    functions.  Arbitrary value.  Assumes blockstore is a current local join.
     381             :    TODO: consider renaming hash_seed? */
     382             : FD_FN_PURE static inline ulong
     383           0 : fd_blockstore_seed( fd_blockstore_t * blockstore ) {
     384           0 :   return blockstore->seed;
     385           0 : }
     386             : 
     387             : /* fd_blockstore_buf_shred_pool returns a pointer in the caller's
     388             :    address space to the pool pointer fd_buf_shred_t * in the blockstore
     389             :    wksp.  Assumes blockstore is local join.  Lifetime of the returned
     390             :    pointer is that of the local join. */
     391             : 
     392             : FD_FN_PURE static inline fd_buf_shred_t *
     393           0 : fd_blockstore_buf_shred_pool( fd_blockstore_t * blockstore ) {
     394           0 :   return (fd_buf_shred_t *)fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ),
     395           0 :                                                blockstore->shred_pool_gaddr );
     396           0 : }
     397             : 
     398             : /* fd_blockstore_buf_shred_map returns a pointer in the caller's address
     399             :    space to the fd_buf_shred_map_t * in the blockstore wksp.  Assumes
     400             :    blockstore is local join.  Lifetime of the returned pointer is that
     401             :    of the local join. */
     402             : 
     403             : FD_FN_PURE static inline fd_buf_shred_map_t *
     404           0 : fd_blockstore_buf_shred_map( fd_blockstore_t * blockstore ) {
     405           0 :   return (fd_buf_shred_map_t *)fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ),
     406           0 :                                                    blockstore->shred_map_gaddr );
     407           0 : }
     408             : 
     409             : /* fd_block_map returns a pointer in the caller's address space to the
     410             :    fd_block_map_t in the blockstore wksp.  Assumes blockstore is local
     411             :    join.  Lifetime of the returned pointer is that of the local join. */
     412             : FD_FN_PURE static inline fd_block_map_t *
     413           0 : fd_blockstore_block_map( fd_blockstore_t * blockstore ) {
     414           0 :   return (fd_block_map_t *)fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ),
     415           0 :                                                blockstore->slot_map_gaddr );
     416           0 : }
     417             : 
     418             : /* fd_blockstore_txn_map returns a pointer in the caller's address space to the blockstore's
     419             :    block map. Assumes blockstore is local join. Lifetime of the returned pointer is that of the
     420             :    local join. */
     421             : 
     422             : FD_FN_PURE static inline fd_blockstore_txn_map_t *
     423           0 : fd_blockstore_txn_map( fd_blockstore_t * blockstore ) {
     424           0 :   return (fd_blockstore_txn_map_t *)fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ),
     425           0 :                                                         blockstore->txn_map_gaddr );
     426           0 : }
     427             : 
     428             : /* fd_blockstore_alloc returns a pointer in the caller's address space to
     429             :    the blockstore's allocator. */
     430             : 
     431             : FD_FN_PURE static inline fd_alloc_t * /* Lifetime is that of the local join */
     432           0 : fd_blockstore_alloc( fd_blockstore_t * blockstore ) {
     433           0 :   return (fd_alloc_t *)fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ),
     434           0 :                                            blockstore->alloc_gaddr );
     435           0 : }
     436             : 
     437             : /* fd_blockstore_block_data_laddr returns a local pointer to the block's data. The returned pointer
     438             :  * lifetime is until the block is removed. Check return value for error info. */
     439             : 
     440             : FD_FN_PURE static inline uchar *
     441           0 : fd_blockstore_block_data_laddr( fd_blockstore_t * blockstore, fd_block_t * block ) {
     442           0 :   return fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ), block->data_gaddr );
     443           0 : }
     444             : 
     445             : FD_FN_PURE static inline ulong
     446           0 : fd_blockstore_block_cnt( fd_blockstore_t * blockstore ) {
     447           0 :   return blockstore->max - blockstore->min + 1;
     448           0 : }
     449             : 
     450             : /* Operations */
     451             : 
     452             : /* Insert shred into the blockstore, fast O(1).  Fail if this shred is already in the blockstore or
     453             :  * the blockstore is full. Returns an error code indicating success or failure.
     454             :  *
     455             :  * TODO eventually this will need to support "upsert" duplicate shred handling.
     456             :  */
     457             : int
     458             : fd_buf_shred_insert( fd_blockstore_t * blockstore, fd_shred_t const * shred );
     459             : 
     460             : /* Query blockstore for shred at slot, shred_idx. Returns a pointer to the shred or NULL if not in
     461             :  * blockstore. The returned pointer lifetime is until the shred is removed. Check return value for
     462             :  * error info. This API only works for shreds from incomplete blocks.
     463             :  *
     464             :  * Callers should hold the read lock during the entirety of its read to ensure the pointer remains
     465             :  * valid.
     466             :  */
     467             : fd_shred_t *
     468             : fd_buf_shred_query( fd_blockstore_t * blockstore, ulong slot, uint shred_idx );
     469             : 
     470             : /* Query blockstore for shred at slot, shred_idx. Copies the shred
     471             :  * data to the given buffer and returns the data size. Returns -1 on failure.
     472             :  *
     473             :  * Callers should hold the read lock during the entirety of this call.
     474             :  */
     475             : long
     476             : fd_buf_shred_query_copy_data( fd_blockstore_t * blockstore,
     477             :                               ulong             slot,
     478             :                               uint              shred_idx,
     479             :                               void *            buf,
     480             :                               ulong             buf_max );
     481             : 
     482             : /* Query blockstore for block at slot. Returns a pointer to the block or NULL if not in
     483             :  * blockstore. The returned pointer lifetime is until the block is removed. Check return value for
     484             :  * error info. */
     485             : fd_block_t *
     486             : fd_blockstore_block_query( fd_blockstore_t * blockstore, ulong slot );
     487             : 
     488             : /* Query blockstore for the block hash at slot. This is the final poh
     489             : hash for a slot. */
     490             : fd_hash_t const *
     491             : fd_blockstore_block_hash_query( fd_blockstore_t * blockstore, ulong slot );
     492             : 
     493             : /* Query blockstore for the bank hash for a given slot. */
     494             : fd_hash_t const *
     495             : fd_blockstore_bank_hash_query( fd_blockstore_t * blockstore, ulong slot );
     496             : 
     497             : /* Query blockstore for the block map entry at slot. Returns a pointer
     498             :    to the slot meta or NULL if not in blockstore. The returned pointer
     499             :    lifetime is until the slot meta is removed. */
     500             : fd_block_map_t *
     501             : fd_blockstore_block_map_query( fd_blockstore_t * blockstore, ulong slot );
     502             : 
     503             : /* Query the parent slot of slot. */
     504             : ulong
     505             : fd_blockstore_parent_slot_query( fd_blockstore_t * blockstore, ulong slot );
     506             : 
     507             : /* fd_blockstore_child_slots_query queries slot's child slots.  Return
     508             :    values are saved in slots_out and slot_cnt.  Returns FD_BLOCKSTORE_OK
     509             :    on success, FD_BLOCKSTORE_ERR_SLOT_MISSING if slot is not in the
     510             :    blockstore.  The returned slot array is always <= the max size
     511             :    FD_BLOCKSTORE_CHILD_SLOT_MAX and contiguous.  Empty slots in the
     512             :    array are set to FD_SLOT_NULL. */
     513             : 
     514             : int
     515             : fd_blockstore_child_slots_query( fd_blockstore_t * blockstore, ulong slot, ulong ** slots_out, ulong * slot_cnt );
     516             : 
     517             : /* Query the frontier ie. all the blocks that need to be replayed that haven't been. These are the
     518             :    slot children of the current frontier that are shred complete. */
     519             : fd_block_t *
     520             : fd_blockstore_block_frontier_query( fd_blockstore_t * blockstore,
     521             :                                     ulong *           parents,
     522             :                                     ulong             parents_sz );
     523             : 
     524             : /* fd_blockstore_block_data_query_volatile queries the block map entry
     525             :    (metadata and block data) in a lock-free thread-safe manner that does
     526             :    not block writes.  Copies the metadata (fd_block_map_t) into
     527             :    block_map_entry_out.  Allocates a new block data (uchar *) using
     528             :    alloc, copies the block data into it, and sets the block_data_out
     529             :    pointer.  Caller provides the allocator via alloc for the copied
     530             :    block data (an allocator is needed because the block data sz is not
     531             :    known apriori).  Returns FD_BLOCKSTORE_SLOT_MISSING if slot is
     532             :    missing: caller MUST ignore out pointers in this case. Otherwise this
     533             :    call cannot fail and returns FD_BLOCKSTORE_OK. */
     534             : 
     535             : int
     536             : fd_blockstore_block_data_query_volatile( fd_blockstore_t * blockstore, ulong slot, fd_block_map_t * block_map_entry_out, fd_block_rewards_t * rewards_out, fd_hash_t * parent_block_hash_out, fd_valloc_t alloc, uchar ** block_data_out, ulong * block_data_out_sz );
     537             : 
     538             : /* fd_blockstore_block_map_query_volatile is the same as above except it
     539             :    only copies out the metadata (fd_block_map_t).  Returns
     540             :    FD_BLOCKSTORE_SLOT_MISSING if slot is missing, otherwise
     541             :    FD_BLOCKSTORE_OK. */
     542             : 
     543             : int
     544             : fd_blockstore_block_map_query_volatile( fd_blockstore_t * blockstore, ulong slot, fd_block_map_t * block_map_entry_out );
     545             : 
     546             : /* Query the transaction data for the given signature */
     547             : fd_blockstore_txn_map_t *
     548             : fd_blockstore_txn_query( fd_blockstore_t * blockstore, uchar const sig[static FD_ED25519_SIG_SZ] );
     549             : 
     550             : /* Query the transaction data for the given signature in a thread
     551             :    safe manner. The transaction data is copied out. txn_data_out can
     552             :    be NULL if you are only interested in the transaction metadata. */
     553             : int
     554             : fd_blockstore_txn_query_volatile( fd_blockstore_t * blockstore, uchar const sig[static FD_ED25519_SIG_SZ], fd_blockstore_txn_map_t * txn_out, long * blk_ts, uchar * blk_flags, uchar txn_data_out[FD_TXN_MTU] );
     555             : 
     556             : /* Remove slot from blockstore, including all relevant internal structures. */
     557             : void
     558             : fd_blockstore_slot_remove( fd_blockstore_t * blockstore, ulong slot );
     559             : 
     560             : /* Remove all the unassembled shreds for a slot */
     561             : int
     562             : fd_blockstore_buffered_shreds_remove( fd_blockstore_t * blockstore, ulong slot );
     563             : 
     564             : /* Set the block height. */
     565             : void
     566             : fd_blockstore_block_height_update( fd_blockstore_t * blockstore, ulong slot, ulong block_height );
     567             : 
     568             : /* fd_blockstore_publish publishes root to the blockstore, pruning any
     569             :    paths that are not in root's subtree.  Removes all blocks in the
     570             :    pruned paths.  Returns FD_BLOCKSTORE_OK on success,
     571             :    FD_BLOCKSTORE_ERR_X otherwise.  Caller MUST hold the write lock. */
     572             : int
     573             : fd_blockstore_publish( fd_blockstore_t * blockstore, ulong root_slot );
     574             : 
     575             : /* Acquire a read lock */
     576             : static inline void
     577           0 : fd_blockstore_start_read( fd_blockstore_t * blockstore ) {
     578           0 :   fd_rwseq_start_read( &blockstore->lock );
     579           0 : }
     580             : 
     581             : /* Release a read lock */
     582             : static inline void
     583           0 : fd_blockstore_end_read( fd_blockstore_t * blockstore ) {
     584           0 :   fd_rwseq_end_read( &blockstore->lock );
     585           0 : }
     586             : 
     587             : /* Acquire a write lock */
     588             : static inline void
     589           0 : fd_blockstore_start_write( fd_blockstore_t * blockstore ) {
     590           0 :   fd_rwseq_start_write( &blockstore->lock );
     591           0 : }
     592             : 
     593             : /* Release a write lock */
     594             : static inline void
     595           0 : fd_blockstore_end_write( fd_blockstore_t * blockstore ) {
     596           0 :   fd_rwseq_end_write( &blockstore->lock );
     597           0 : }
     598             : 
     599             : void
     600             : fd_blockstore_log_block_status( fd_blockstore_t * blockstore, ulong around_slot );
     601             : 
     602             : /* fd_blockstore_log_mem_usage logs the memory usage of blockstore in a
     603             : human-readable format.  Caller MUST hold the read lock. */
     604             : void
     605             : fd_blockstore_log_mem_usage( fd_blockstore_t * blockstore );
     606             : 
     607             : FD_PROTOTYPES_END
     608             : 
     609             : #endif /* HEADER_fd_src_flamenco_runtime_fd_blockstore_h */

Generated by: LCOV version 1.14