LCOV - code coverage report
Current view: top level - discof/restore - fd_snapin_tile_private.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 56 0.0 %
Date: 2026-02-13 06:06:24 Functions: 0 48 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_discof_restore_fd_snapin_tile_private_h
       2             : #define HEADER_fd_discof_restore_fd_snapin_tile_private_h
       3             : 
       4             : /* fd_snapin_tile_private.h contains private APIs for the "snapin" tile,
       5             :    which is the tile responsible for parsing a snapshot, and directing
       6             :    database writes. */
       7             : 
       8             : #include "utils/fd_ssparse.h"
       9             : #include "utils/fd_ssmanifest_parser.h"
      10             : #include "utils/fd_slot_delta_parser.h"
      11             : #include "utils/fd_ssctrl.h"
      12             : #include "../../flamenco/accdb/fd_accdb_admin.h"
      13             : #include "../../flamenco/accdb/fd_accdb_user.h"
      14             : #include "../../flamenco/runtime/fd_runtime_const.h"
      15             : #include "../../flamenco/runtime/fd_txncache.h"
      16             : #include "../../disco/stem/fd_stem.h"
      17             : #include "../../disco/topo/fd_topo.h"
      18             : #include "../../vinyl/io/fd_vinyl_io.h"
      19             : #include "../../vinyl/meta/fd_vinyl_meta.h"
      20             : 
      21             : /* 300 here is from status_cache.rs::MAX_CACHE_ENTRIES which is the most
      22             :    root slots Agave could possibly serve in a snapshot. */
      23           0 : #define FD_SNAPIN_TXNCACHE_MAX_ENTRIES (300UL*FD_PACK_MAX_TXNCACHE_TXN_PER_SLOT)
      24             : 
      25             : struct blockhash_group {
      26             :   uchar blockhash[ 32UL ];
      27             :   ulong txnhash_offset;
      28             : };
      29             : 
      30             : typedef struct blockhash_group blockhash_group_t;
      31             : 
      32             : struct fd_snapin_out_link {
      33             :   ulong       idx;
      34             :   fd_wksp_t * mem;
      35             :   ulong       chunk0;
      36             :   ulong       wmark;
      37             :   ulong       chunk;
      38             :   ulong       mtu;
      39             : };
      40             : typedef struct fd_snapin_out_link fd_snapin_out_link_t;
      41             : 
      42             : struct buffered_account_batch {
      43             :   uchar const * batch[ FD_SSPARSE_ACC_BATCH_MAX ];
      44             :   ulong         batch_cnt;
      45             :   ulong         slot;
      46             :   /* index at which to start processing a buffered account batch */
      47             :   ulong         remaining_idx;
      48             : };
      49             : 
      50             : typedef struct buffered_account_batch buffered_account_batch_t;
      51             : 
      52             : struct fd_snapin_tile {
      53             :   int  state;
      54             :   uint full      : 1;       /* loading a full snapshot? */
      55             :   uint use_vinyl : 1;       /* using vinyl-backed accdb? */
      56             :   uint lthash_disabled : 1; /* disable lthash checking? */
      57             : 
      58             :   ulong seed;
      59             :   long boot_timestamp;
      60             : 
      61             :   fd_accdb_admin_t accdb_admin[1];
      62             :   fd_accdb_user_t  accdb[1];
      63             :   fd_funk_t *      funk;
      64             : 
      65             :   fd_txncache_t * txncache;
      66             :   uchar *         acc_data;
      67             : 
      68             :   fd_funk_txn_xid_t xid[1]; /* txn XID */
      69             : 
      70             :   fd_stem_context_t *      stem;
      71             : 
      72             :   fd_ssparse_t *           ssparse;
      73             :   fd_ssmanifest_parser_t * manifest_parser;
      74             :   fd_slot_delta_parser_t * slot_delta_parser;
      75             : 
      76             :   buffered_account_batch_t buffered_batch;
      77             : 
      78             :   struct {
      79             :     int manifest_done;
      80             :     int status_cache_done;
      81             :     int manifest_processed;
      82             :   } flags;
      83             : 
      84             :   ulong advertised_slot;
      85             :   ulong bank_slot;
      86             : 
      87             :   ulong blockhash_offsets_len;
      88             :   blockhash_group_t * blockhash_offsets;
      89             : 
      90             :   ulong   txncache_entries_len;
      91             :   ulong * txncache_entries_len_vinyl_ptr;
      92             :   fd_sstxncache_entry_t * txncache_entries;
      93             : 
      94             :   fd_txncache_fork_id_t txncache_root_fork_id;
      95             : 
      96             :   struct {
      97             :     ulong full_bytes_read;
      98             :     ulong incremental_bytes_read;
      99             : 
     100             :     /* Account counters (full + incremental) */
     101             :     ulong accounts_loaded;
     102             :     ulong accounts_replaced;
     103             :     ulong accounts_ignored;
     104             : 
     105             :     /* Account counters (snapshot taken for full snapshot only) */
     106             :     ulong full_accounts_loaded;
     107             :     ulong full_accounts_replaced;
     108             :     ulong full_accounts_ignored;
     109             :   } metrics;
     110             : 
     111             :   struct {
     112             :     fd_wksp_t * wksp;
     113             :     ulong       chunk0;
     114             :     ulong       wmark;
     115             :     ulong       mtu;
     116             :     ulong       pos;
     117             :   } in;
     118             : 
     119             :   ulong                out_ct_idx;
     120             :   fd_snapin_out_link_t manifest_out;
     121             :   fd_snapin_out_link_t gui_out;
     122             :   fd_snapin_out_link_t hash_out;
     123             : 
     124             :   struct {
     125             :     uchar * pair;
     126             :     ulong   pair_sz;
     127             : 
     128             :     uchar * dst;
     129             :     ulong   dst_rem;
     130             :     ulong   data_rem;
     131             : 
     132             :     fd_vinyl_meta_ele_t * meta_ele;
     133             :   } vinyl_op;
     134             : };
     135             : 
     136             : typedef struct fd_snapin_tile fd_snapin_tile_t;
     137             : 
     138             : /* Funk APIs **********************************************************/
     139             : 
     140             : FD_PROTOTYPES_BEGIN
     141             : 
     142             : int fd_snapin_process_account_header_funk( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     143             : int fd_snapin_process_account_data_funk  ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     144             : int fd_snapin_process_account_batch_funk ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result, buffered_account_batch_t * buffered_batch );
     145             : 
     146             : void
     147             : fd_snapin_read_account_funk( fd_snapin_tile_t *  ctx,
     148             :                              void const *        acct_addr,
     149             :                              fd_account_meta_t * meta,
     150             :                              uchar *             data,
     151             :                              ulong               data_max );
     152             : 
     153             : FD_PROTOTYPES_END
     154             : 
     155             : /* Vinyl APIs *********************************************************/
     156             : 
     157             : FD_PROTOTYPES_BEGIN
     158             : 
     159             : #define FD_SNAPIN_IO_SPAD_MAX (64UL<<20) /* 64 MiB of I/O scratch space */
     160             : 
     161             : /* fd_snapin_vinyl_unprivileged_init performs setup tasks after being
     162             :    sandboxed.  (anything that might be exposed to untrusted data) */
     163             : 
     164             : void
     165             : fd_snapin_vinyl_unprivileged_init( fd_snapin_tile_t * ctx,
     166             :                                    fd_topo_t *        topo,
     167             :                                    fd_topo_tile_t *   tile,
     168             :                                    void *             io_mm_mem,
     169             :                                    void *             io_wd_mem );
     170             : 
     171             : /* fd_snapin_vinyl_seccomp returns a seccomp sandbox policy suitable
     172             :    for vinyl operation. */
     173             : 
     174             : ulong
     175             : fd_snapin_vinyl_seccomp( ulong                out_cnt,
     176             :                          struct sock_filter * out );
     177             : 
     178             : /* fd_snapin_vinyl_reset pauses the snapwr tile (waits for the snapwr
     179             :    tile to ack) and formats a bstream file to be empty.  THIS IS A
     180             :    DESTRUCTIVE ACTION. */
     181             : 
     182             : void
     183             : fd_snapin_vinyl_reset( fd_snapin_tile_t * ctx );
     184             : 
     185             : /* fd_snapin_vinyl_txn_begin starts a transactional burst write.
     186             :    Assumes vinyl uses the io_mm backend.  The write can then either be
     187             :    committed or cancelled.  There is no practical limit on the size of
     188             :    this burst. */
     189             : 
     190             : void
     191             : fd_snapin_vinyl_txn_begin( fd_snapin_tile_t * ctx );
     192             : 
     193             : /* fd_snapin_vinyl_txn_commit finishes a transactional burst write.
     194             :    Assumes vinyl uses the io_mm backend.  Reads through bstream records
     195             :    written since txn_begin was called and updates the vinyl_meta index. */
     196             : 
     197             : void
     198             : fd_snapin_vinyl_txn_commit( fd_snapin_tile_t * ctx );
     199             : 
     200             : /* fd_snapin_vinyl_txn_cancel abandons a transactional burst write.
     201             :    Assumes vinyl uses the io_mm backend.  Reverts the bstream state to
     202             :    when txn_begin was called. */
     203             : 
     204             : void
     205             : fd_snapin_vinyl_txn_cancel( fd_snapin_tile_t * ctx );
     206             : 
     207             : /* fd_snapin_vinyl_wd_init transitions the vinyl backend from generic
     208             :    vinyl accessor (io_mm) to fast dumb direct account insertion (io_wd).
     209             :    This must be called before calling fd_snapin_process_account_*.
     210             :    Starts the snapwr tile (waits for the snapwr tile to ack). */
     211             : 
     212             : void
     213             : fd_snapin_vinyl_wd_init( fd_snapin_tile_t * ctx );
     214             : 
     215             : /* fd_snapin_vinyl_wd_fini transitions the vinyl backend from fast dumb
     216             :    direct account insertion (io_wd) back to generic mode (io_mm).
     217             :    Pauses the snapwr tile (waits for the snapwr to ack). */
     218             : 
     219             : void
     220             : fd_snapin_vinyl_wd_fini( fd_snapin_tile_t * ctx );
     221             : 
     222             : /* fd_snapin_vinyl_shutdown instructs vinyl-related tiles of the loader
     223             :    to shut down.  Blocks until all affected tiles have acknowledged the
     224             :    shutdown signal. */
     225             : 
     226             : void
     227             : fd_snapin_vinyl_shutdown( fd_snapin_tile_t * ctx );
     228             : 
     229             : /* Internal APIs for inserting accounts */
     230             : 
     231             : int fd_snapin_process_account_header_vinyl( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     232             : int fd_snapin_process_account_data_vinyl  ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     233             : int fd_snapin_process_account_batch_vinyl ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     234             : 
     235             : FD_PROTOTYPES_END
     236             : 
     237             : /* Generic APIs *******************************************************/
     238             : 
     239             : FD_PROTOTYPES_BEGIN
     240             : 
     241             : /* int return value for fd_snapin_process_account_header,
     242             : fd_snapin_process_account_data, and fd_snapin_process_account_batch
     243             : indicates whether to yield to stem for credit return */
     244             : 
     245             : static inline int
     246             : fd_snapin_process_account_header( fd_snapin_tile_t *            ctx,
     247           0 :                                   fd_ssparse_advance_result_t * result ) {
     248           0 :   if( ctx->use_vinyl ) {
     249           0 :     return fd_snapin_process_account_header_vinyl( ctx, result );
     250           0 :   } else {
     251           0 :     return fd_snapin_process_account_header_funk( ctx, result );
     252           0 :   }
     253           0 :   return 0;
     254           0 : }
     255             : 
     256             : static inline int
     257             : fd_snapin_process_account_data( fd_snapin_tile_t *            ctx,
     258           0 :                                 fd_ssparse_advance_result_t * result ) {
     259           0 :   if( ctx->use_vinyl ) {
     260           0 :     return fd_snapin_process_account_data_vinyl( ctx, result );
     261           0 :   } else {
     262           0 :     return fd_snapin_process_account_data_funk( ctx, result );
     263           0 :   }
     264           0 :   return 0;
     265           0 : }
     266             : 
     267             : static inline int
     268             : fd_snapin_process_account_batch( fd_snapin_tile_t *            ctx,
     269             :                                  fd_ssparse_advance_result_t * result,
     270           0 :                                  buffered_account_batch_t *    buffered_batch ) {
     271           0 :   if( ctx->use_vinyl ) {
     272           0 :     return fd_snapin_process_account_batch_vinyl( ctx, result );
     273           0 :   } else {
     274           0 :     return fd_snapin_process_account_batch_funk( ctx, result, buffered_batch );
     275           0 :   }
     276           0 :   return 0;
     277           0 : }
     278             : 
     279             : static inline void
     280             : fd_snapin_read_account( fd_snapin_tile_t *  ctx,
     281             :                         void const *        acct_addr,
     282             :                         fd_account_meta_t * meta,
     283             :                         uchar *             data,
     284           0 :                         ulong               data_max ) {
     285             :   /* fd_snapin_read_account will no longer be required in the snapin
     286             :      tile once funk is deprecated from the snapshot load pipeline.
     287             :      Under vinyl, this is implemented in the snapwm tile. */
     288           0 :   if( ctx->use_vinyl ) {
     289           0 :     FD_LOG_ERR(( "read account is not supported under vinyl" ));
     290           0 :   } else {
     291           0 :     fd_snapin_read_account_funk( ctx, acct_addr, meta, data, data_max );
     292           0 :   }
     293           0 : }
     294             : 
     295             : /* fd_snapin_send_duplicate_account sends a duplicate account message
     296             :    with the signature FD_SNAPSHOT_HASH_MSG_SUB or
     297             :    FD_SNAPSHOT_HASH_MSG_SUB_HDR, depending on if this duplicate account
     298             :    contains valid account data. The message is only
     299             :    sent if lthash verification is enabled in the snapshot loader.
     300             : 
     301             :    lamports is account's lamports value.  data is the account's data,
     302             :    which can be optionally null.  data_len is the length of the account
     303             :    data.  executable is the account's executable flag. owner points to
     304             :    the account's owner (32 bytes).  pubkey points to the account's
     305             :    pubkey (32 bytes).  early_exit is an optional pointer to an int flag
     306             :    that is set to 1 if the caller should yield to stem following this
     307             :    call. */
     308             : static inline void
     309             : fd_snapin_send_duplicate_account( fd_snapin_tile_t * ctx,
     310             :                                   ulong              lamports,
     311             :                                   uchar const *      data,
     312             :                                   ulong              data_len,
     313             :                                   uchar              executable,
     314             :                                   uchar const *      owner,
     315             :                                   uchar const *      pubkey,
     316             :                                   int                has_data,
     317           0 :                                   int *              early_exit ) {
     318           0 :   if( FD_UNLIKELY( ctx->lthash_disabled ) ) return;
     319             : 
     320           0 :   if( FD_LIKELY( has_data ) ) {
     321           0 :     fd_snapshot_full_account_t * existing_account = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
     322           0 :     fd_snapshot_account_hdr_init( &existing_account->hdr, pubkey, owner, lamports, executable, data_len );
     323           0 :     fd_memcpy( existing_account->data, data, data_len );
     324           0 :     fd_stem_publish( ctx->stem, ctx->out_ct_idx, FD_SNAPSHOT_HASH_MSG_SUB, ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t)+data_len, 0UL, 0UL, 0UL );
     325           0 :     ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t)+data_len, ctx->hash_out.chunk0, ctx->hash_out.wmark );
     326           0 :   } else {
     327           0 :     fd_snapshot_account_hdr_t * acc_hdr = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
     328           0 :     fd_snapshot_account_hdr_init( acc_hdr, pubkey, owner, lamports, executable, data_len );
     329           0 :     fd_stem_publish( ctx->stem, ctx->out_ct_idx, FD_SNAPSHOT_HASH_MSG_SUB_HDR, ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t), 0UL, 0UL, 0UL );
     330           0 :     ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t), ctx->hash_out.chunk0, ctx->hash_out.wmark );
     331           0 :   }
     332           0 :   if( FD_LIKELY( early_exit ) ) *early_exit = 1;
     333           0 : }
     334             : 
     335             : /* fd_snapin_send_duplicate_account_data sends a duplicate account
     336             :    message with the signature FD_SNAPSHOT_HASH_MSG_SUB_DATA.  The
     337             :    message is only sent if lthash verification is enabled in the
     338             :    snapshot loader.
     339             : 
     340             :    data is the account's data, which cannot be null.  data_len is the
     341             :    length of the account data.  early_exit is an optional pointer to an
     342             :    int flag that is set to 1 if the caller should yield to stem
     343             :    following this call. */
     344             : static inline void
     345             : fd_snapin_send_duplicate_account_data( fd_snapin_tile_t * ctx,
     346             :                                        uchar const *      data,
     347             :                                        ulong              data_sz,
     348           0 :                                        int *              early_exit ) {
     349           0 :   if( FD_UNLIKELY( ctx->lthash_disabled ) ) return;
     350             : 
     351           0 :   uchar * drop_account_data = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
     352           0 :   fd_memcpy( drop_account_data, data, data_sz );
     353           0 :   fd_stem_publish( ctx->stem, ctx->out_ct_idx, FD_SNAPSHOT_HASH_MSG_SUB_DATA, ctx->hash_out.chunk, data_sz, 0UL, 0UL, 0UL );
     354           0 :   ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, data_sz, ctx->hash_out.chunk0, ctx->hash_out.wmark );
     355           0 :   if( FD_LIKELY( early_exit ) ) *early_exit = 1;
     356           0 : }
     357             : 
     358             : FD_PROTOTYPES_END
     359             : 
     360             : #endif /* HEADER_fd_discof_restore_fd_snapin_tile_private_h */

Generated by: LCOV version 1.14