LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_rocksdb.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 47 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 380 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_fd_rocksdb_h
       2             : #define HEADER_fd_src_flamenco_runtime_fd_rocksdb_h
       3             : 
       4             : #include "../../ballet/block/fd_microblock.h"
       5             : #include "fd_blockstore.h"
       6             : 
       7             : /** allocations made for offline-replay in the blockstore */
       8             : struct fd_block {
       9             :   /* Used only in offline at the moment. Stored in the blockstore
      10             :      memory and used to iterate the block's contents.
      11             : 
      12             :    A block's data region is indexed to support iterating by shred,
      13             :    microblock/entry batch, microblock/entry, or transaction.
      14             :    This is done by iterating the headers for each, stored in allocated
      15             :    memory.
      16             :    To iterate shred payloads, for example, a caller should iterate the headers in tandem with the data region
      17             :    (offsetting by the bytes indicated in the shred header).
      18             : 
      19             :    Note random access of individual shred indices is not performant, due to the variable-length
      20             :    nature of shreds. */
      21             : 
      22             :   ulong data_gaddr;   /* ptr to the beginning of the block's allocated data region */
      23             :   ulong data_sz;      /* block size */
      24             :   ulong shreds_gaddr; /* ptr to the first fd_block_shred_t */
      25             :   ulong shreds_cnt;
      26             :   ulong batch_gaddr;  /* list of fd_block_entry_batch_t */
      27             :   ulong batch_cnt;
      28             :   ulong micros_gaddr; /* ptr to the list of fd_block_micro_t */
      29             :   ulong micros_cnt;
      30             :   ulong txns_gaddr;   /* ptr to the list of fd_block_txn_t */
      31             :   ulong txns_cnt;
      32             :   ulong txns_meta_gaddr; /* ptr to the allocation for txn meta data */
      33             :   ulong txns_meta_sz;
      34             : };
      35             : typedef struct fd_block fd_block_t;
      36             : 
      37             : FD_PROTOTYPES_BEGIN
      38             : 
      39             : /* fd_blockstore_block_data_laddr returns a local pointer to the block's
      40             :    data.  The returned pointer lifetime is until the block is removed. */
      41             : 
      42             : FD_FN_PURE static inline uchar *
      43           0 : fd_blockstore_block_data_laddr( fd_blockstore_t * blockstore, fd_block_t * block ) {
      44           0 :   return fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ), block->data_gaddr );
      45           0 : }
      46             : 
      47             : FD_FN_PURE static inline fd_block_entry_batch_t *
      48           0 : fd_blockstore_block_batch_laddr( fd_blockstore_t * blockstore, fd_block_t * block ) {
      49           0 :   return fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ), block->batch_gaddr );
      50           0 : }
      51             : 
      52             : FD_FN_PURE static inline fd_block_micro_t *
      53           0 : fd_blockstore_block_micro_laddr( fd_blockstore_t * blockstore, fd_block_t * block ) {
      54           0 :   return fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ), block->micros_gaddr );
      55           0 : }
      56             : 
      57             : FD_PROTOTYPES_END
      58             : 
      59             : #if FD_HAS_ROCKSDB
      60             : 
      61             : #include "../../ballet/shred/fd_shred.h"
      62             : #include <rocksdb/c.h>
      63             : 
      64           0 : #define FD_ROCKSDB_CF_CNT (22UL)
      65             : 
      66           0 : #define FD_ROCKSDB_CFIDX_DEFAULT                  (0UL)
      67           0 : #define FD_ROCKSDB_CFIDX_META                     (1UL)
      68           0 : #define FD_ROCKSDB_CFIDX_DEAD_SLOTS               (2UL)
      69           0 : #define FD_ROCKSDB_CFIDX_DUPLICATE_SLOTS          (3UL) /* Usually empty */
      70           0 : #define FD_ROCKSDB_CFIDX_ERASURE_META             (4UL)
      71           0 : #define FD_ROCKSDB_CFIDX_ORPHANS                  (5UL) /* Usually empty */
      72           0 : #define FD_ROCKSDB_CFIDX_BANK_HASHES              (6UL)
      73           0 : #define FD_ROCKSDB_CFIDX_ROOT                     (7UL)
      74           0 : #define FD_ROCKSDB_CFIDX_INDEX                    (8UL)
      75           0 : #define FD_ROCKSDB_CFIDX_DATA_SHRED               (9UL)
      76           0 : #define FD_ROCKSDB_CFIDX_CODE_SHRED               (10UL)
      77           0 : #define FD_ROCKSDB_CFIDX_TRANSACTION_STATUS       (11UL)
      78           0 : #define FD_ROCKSDB_CFIDX_ADDRESS_SIGNATURES       (12UL)
      79           0 : #define FD_ROCKSDB_CFIDX_TRANSACTION_MEMOS        (13UL)
      80           0 : #define FD_ROCKSDB_CFIDX_TRANSACTION_STATUS_INDEX (14UL)
      81           0 : #define FD_ROCKSDB_CFIDX_REWARDS                  (15UL)
      82           0 : #define FD_ROCKSDB_CFIDX_BLOCKTIME                (16UL)
      83           0 : #define FD_ROCKSDB_CFIDX_PERF_SAMPLES             (17UL)
      84           0 : #define FD_ROCKSDB_CFIDX_BLOCK_HEIGHT             (18UL)
      85           0 : #define FD_ROCKSDB_CFIDX_PROGRAM_COSTS            (19UL) /* Usually empty */
      86           0 : #define FD_ROCKSDB_CFIDX_OPTIMISTIC_SLOTS         (20UL)
      87           0 : #define FD_ROCKSDB_CFIDX_MERKLE_ROOT_META         (21UL) /* Usually empty */
      88             : 
      89             : /* Solana rocksdb client */
      90             : struct fd_rocksdb {
      91             :   rocksdb_t *                     db;
      92             :   const char *                    db_name;
      93             :   const char *                    cfgs      [ FD_ROCKSDB_CF_CNT ];
      94             :   rocksdb_column_family_handle_t* cf_handles[ FD_ROCKSDB_CF_CNT ];
      95             :   rocksdb_options_t *             opts;
      96             :   rocksdb_readoptions_t *         ro;
      97             :   rocksdb_writeoptions_t *        wo;
      98             : };
      99             : typedef struct fd_rocksdb fd_rocksdb_t;
     100             : #define FD_ROCKSDB_FOOTPRINT sizeof(fd_rocksdb_t)
     101             : #define FD_ROCKSDB_ALIGN (8UL)
     102             : 
     103             : /* root column iterator */
     104             : struct fd_rocksdb_root_iter {
     105             :   fd_rocksdb_t *                  db;
     106             :   rocksdb_iterator_t*             iter;
     107             : };
     108             : typedef struct fd_rocksdb_root_iter fd_rocksdb_root_iter_t;
     109             : #define FD_ROCKSDB_ROOT_ITER_FOOTPRINT sizeof(fd_rocksdb_root_iter_t)
     110             : #define FD_ROCKSDB_ROOT_ITER_ALIGN (8UL)
     111             : 
     112             : FD_PROTOTYPES_BEGIN
     113             : 
     114             : void *
     115             : fd_rocksdb_root_iter_new( void * shiter );
     116             : 
     117             : fd_rocksdb_root_iter_t *
     118             : fd_rocksdb_root_iter_join( void * iter );
     119             : 
     120             : void *
     121             : fd_rocksdb_root_iter_leave( fd_rocksdb_root_iter_t * iter );
     122             : 
     123             : /* fd_rocksdb_root_iter_seek
     124             : 
     125             :     0 = success
     126             :    -1 = seek for supplied slot failed
     127             :    -2 = seek succeeded but slot did not match what we seeked for
     128             :    -3 = seek succeeded but points at an empty slot */
     129             : 
     130             : int
     131             : fd_rocksdb_root_iter_seek( fd_rocksdb_root_iter_t * iter,
     132             :                            fd_rocksdb_t *           db,
     133             :                            ulong                    slot,
     134             :                            fd_slot_meta_t *         m,
     135             :                            fd_valloc_t              valloc );
     136             : 
     137             : /*  fd_rocksdb_root_iter_next
     138             : 
     139             :     0 = success
     140             :    -1 = not properly initialized with a seek
     141             :    -2 = invalid starting iterator
     142             :    -3 = next returned an invalid iterator state
     143             :    -4 = seek succeeded but points at an empty slot */
     144             : 
     145             : int
     146             : fd_rocksdb_root_iter_next( fd_rocksdb_root_iter_t * iter,
     147             :                            fd_slot_meta_t *         m,
     148             :                            fd_valloc_t              valloc );
     149             : 
     150             : int
     151             : fd_rocksdb_root_iter_slot( fd_rocksdb_root_iter_t * self,
     152             :                            ulong *                  slot );
     153             : 
     154             : void
     155             : fd_rocksdb_root_iter_destroy( fd_rocksdb_root_iter_t * iter );
     156             : 
     157             : /* fd_rocksdb_init: Returns a pointer to a description of the error on failure
     158             : 
     159             :   The provided db_name needs to point at the actual rocksdb directory
     160             :   as apposed to the directory above (like the solana ledger-tool) */
     161             : 
     162             : char *
     163             : fd_rocksdb_init( fd_rocksdb_t * db,
     164             :                  char const *   db_name );
     165             : 
     166             : /* fd_rocksdb_new: Creates a new rocksdb
     167             : 
     168             :    The provided db_name has to the be the full path where the directory
     169             :    will be created. The fd_rocksdb_t object will be initialized */
     170             : 
     171             : void
     172             : fd_rocksdb_new( fd_rocksdb_t * db,
     173             :                 char const *   db_name );
     174             : 
     175             : /* fd_rocksdb_destroy
     176             : 
     177             :    Frees up the internal data structures */
     178             : 
     179             : void
     180             : fd_rocksdb_destroy( fd_rocksdb_t * db );
     181             : 
     182             : /* fd_rocksdb_last_slot:  Returns the last slot in the db
     183             : 
     184             :    This uses the root column to discover the slot of the last root in
     185             :    the db.  If there is an error, this sets *err to a constant string
     186             :    describing the error.  There is no need to free that string. */
     187             : 
     188             : ulong
     189             : fd_rocksdb_last_slot( fd_rocksdb_t * db,
     190             :                       char **        err );
     191             : 
     192             : /* fd_rocksdb_first_slot:  Returns the first slot in the db
     193             : 
     194             :    This uses the root column to discover the slot of the first root in
     195             :    the db.  If there is an error, this sets *err to a constant string
     196             :    describing the error.  There is no need to free that string. */
     197             : 
     198             : ulong
     199             : fd_rocksdb_first_slot( fd_rocksdb_t * db,
     200             :                        char **        err );
     201             : 
     202             : ulong
     203             : fd_rocksdb_find_last_slot( fd_rocksdb_t * db,
     204             :                            char **        err );
     205             : 
     206             : /* fd_rocksdb_get_meta
     207             : 
     208             :    Retrieves the meta structure associated with the supplied slot.  If
     209             :    there is an error, *err is set to a string describing the error.
     210             :    It is expected that you should free() the error once done with it
     211             : 
     212             :    returns a 0 if there is no obvious error */
     213             : int
     214             : fd_rocksdb_get_meta( fd_rocksdb_t *   db,
     215             :                      ulong            slot,
     216             :                      fd_slot_meta_t * m,
     217             :                      fd_valloc_t      valloc );
     218             : 
     219             : /* fd_rocksdb_get_txn_status_raw queries transaction status metadata.
     220             :    slot is the slot number of the block that contains the txn.  sig
     221             :    points to the first signature of the txn.  Returns data==NULL if
     222             :    record not found.  On success, creates a malloc-backed buffer to hold
     223             :    return value, copies raw serialized status into buffer, sets *psz to
     224             :    the byte size of the status and returns pointer to buffer.  Caller
     225             :    must free() non-NULL returned region.  On failure, returns NULL and
     226             :    content of *psz is undefined.  Value is Protobuf-encoded
     227             :    TransactionStatusMeta.  Use fd_solblock nanopb API to deserialize
     228             :    value. */
     229             : 
     230             : void *
     231             : fd_rocksdb_get_txn_status_raw( fd_rocksdb_t * self,
     232             :                                ulong          slot,
     233             :                                void const *   sig,
     234             :                                ulong *        psz );
     235             : 
     236             : /* fd_rocksdb_copy_over_slot_indexed_range copies over all entries for a
     237             :    given column family index into another rocksdb assuming that the key
     238             :    is prefixed with the slot number. This includes column families where
     239             :    the key is just the slot number but also ones where the key starts with
     240             :    the slot number. */
     241             : 
     242             : int
     243             : fd_rocksdb_copy_over_slot_indexed_range( fd_rocksdb_t * src,
     244             :                                          fd_rocksdb_t * dst,
     245             :                                          ulong          cf_idx,
     246             :                                          ulong          start_slot,
     247             :                                          ulong          end_slot );
     248             : 
     249             : /* fd_rocksdb_copy_over_txn_status_range copies over all transaction statuses
     250             :    within a block range assuming the blockstore contains relevant pointers to
     251             :    the transactions within the range. The blockstore object must be populated
     252             :    with the relevant block range. */
     253             : 
     254             : int
     255             : fd_rocksdb_copy_over_txn_status_range( fd_rocksdb_t *    src,
     256             :                                        fd_rocksdb_t *    dst,
     257             :                                        fd_blockstore_t * blockstore,
     258             :                                        ulong             start_slot,
     259             :                                        ulong             end_slot );
     260             : 
     261             : /* fd_rocksdb_copy_over_txn_status constructs a key to query a transaction
     262             :    status and copies over the entry into another rocksdb. The index is used
     263             :    to specify which transaction. */
     264             : 
     265             : void
     266             : fd_rocksdb_copy_over_txn_status( fd_rocksdb_t * src,
     267             :                                  fd_rocksdb_t * dst,
     268             :                                  ulong          slot,
     269             :                                  void const *   sig );
     270             : 
     271             : /* fd_rocksdb_insert_entry inserts a key, value pair into a given rocksdb */
     272             : 
     273             : int
     274             : fd_rocksdb_insert_entry( fd_rocksdb_t * db,
     275             :                          ulong          cf_idx,
     276             :                          const char *   key,
     277             :                          ulong          key_len,
     278             :                          const char *   value,
     279             :                          ulong          value_len );
     280             : 
     281             : /* Import from rocksdb into blockstore */
     282             : 
     283             : int
     284             : fd_rocksdb_import_block_blockstore( fd_rocksdb_t *    db,
     285             :                                     fd_slot_meta_t *  m,
     286             :                                     fd_blockstore_t * blockstore,
     287             :                                     int               txnstatus,
     288             :                                     const uchar *     hash_override,
     289             :                                     fd_valloc_t       valloc );
     290             : 
     291             : int
     292             : fd_rocksdb_import_block_shredcap( fd_rocksdb_t *             db,
     293             :                                   fd_slot_meta_t *           metadata,
     294             :                                   fd_io_buffered_ostream_t * ostream,
     295             :                                   fd_io_buffered_ostream_t * bank_hash_ostream,
     296             :                                   fd_valloc_t                valloc );
     297             : 
     298             : /* fd_blockstore_block_query queries blockstore for block at slot.
     299             :    Returns a pointer to the block or NULL if not in blockstore.  The
     300             :    returned pointer lifetime is until the block is removed.  Check
     301             :    return value for error info.
     302             : 
     303             :    In theory the caller does not need to wrap this function in a
     304             :    start/end read. What is being read lives in the block_info object,
     305             :    and this function does a valid concurrent read for the block_gaddr.
     306             :    The fd_block_t object itself has no such guarantees, and needs a
     307             :    read/write lock to modify. */
     308             : void
     309             : fd_blockstore_block_allocs_remove( fd_blockstore_t * blockstore, ulong slot );
     310             : 
     311             : static inline fd_block_t *
     312           0 : fd_blockstore_block_query(fd_blockstore_t *blockstore, ulong slot){
     313           0 :   int err = FD_MAP_ERR_AGAIN;
     314           0 :   ulong query_block_gaddr = 0;
     315           0 :   while( err == FD_MAP_ERR_AGAIN ){
     316           0 :     fd_block_map_query_t quer[1] = { 0 };
     317           0 :     err = fd_block_map_query_try( blockstore->block_map, &slot, NULL, quer, 0 );
     318           0 :     fd_block_info_t * query = fd_block_map_query_ele( quer );
     319           0 :     if ( err == FD_MAP_ERR_KEY ) return NULL;
     320           0 :     if ( FD_UNLIKELY( err == FD_MAP_ERR_AGAIN ) ) continue;
     321             :     /* later change this to all shreds recieved */
     322           0 :     if( FD_UNLIKELY( query->block_gaddr == 0 ) ) return NULL;
     323           0 :     query_block_gaddr = query->block_gaddr;
     324           0 :     err = fd_block_map_query_test( quer );
     325           0 :   }
     326           0 :   return fd_wksp_laddr_fast( fd_blockstore_wksp( blockstore ), query_block_gaddr );
     327           0 : }
     328             : 
     329             : FD_PROTOTYPES_END
     330             : 
     331             : #endif
     332             : 
     333             : #endif // HEADER_fd_src_flamenco_runtime_fd_rocksdb_h

Generated by: LCOV version 1.14