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-01-23 05:02:40 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 bank_slot;
      85             : 
      86             :   ulong blockhash_offsets_len;
      87             :   blockhash_group_t * blockhash_offsets;
      88             : 
      89             :   ulong   txncache_entries_len;
      90             :   ulong * txncache_entries_len_vinyl_ptr;
      91             :   fd_sstxncache_entry_t * txncache_entries;
      92             : 
      93             :   fd_txncache_fork_id_t txncache_root_fork_id;
      94             : 
      95             :   struct {
      96             :     ulong full_bytes_read;
      97             :     ulong incremental_bytes_read;
      98             : 
      99             :     /* Account counters (full + incremental) */
     100             :     ulong accounts_loaded;
     101             :     ulong accounts_replaced;
     102             :     ulong accounts_ignored;
     103             : 
     104             :     /* Account counters (snapshot taken for full snapshot only) */
     105             :     ulong full_accounts_loaded;
     106             :     ulong full_accounts_replaced;
     107             :     ulong full_accounts_ignored;
     108             :   } metrics;
     109             : 
     110             :   struct {
     111             :     fd_wksp_t * wksp;
     112             :     ulong       chunk0;
     113             :     ulong       wmark;
     114             :     ulong       mtu;
     115             :     ulong       pos;
     116             :   } in;
     117             : 
     118             :   ulong                out_ct_idx;
     119             :   fd_snapin_out_link_t manifest_out;
     120             :   fd_snapin_out_link_t gui_out;
     121             :   fd_snapin_out_link_t hash_out;
     122             : 
     123             :   struct {
     124             :     uchar * pair;
     125             :     ulong   pair_sz;
     126             : 
     127             :     uchar * dst;
     128             :     ulong   dst_rem;
     129             :     ulong   data_rem;
     130             : 
     131             :     fd_vinyl_meta_ele_t * meta_ele;
     132             :   } vinyl_op;
     133             : };
     134             : 
     135             : typedef struct fd_snapin_tile fd_snapin_tile_t;
     136             : 
     137             : /* Funk APIs **********************************************************/
     138             : 
     139             : FD_PROTOTYPES_BEGIN
     140             : 
     141             : int fd_snapin_process_account_header_funk( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     142             : int fd_snapin_process_account_data_funk  ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     143             : int fd_snapin_process_account_batch_funk ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result, buffered_account_batch_t * buffered_batch );
     144             : 
     145             : void
     146             : fd_snapin_read_account_funk( fd_snapin_tile_t *  ctx,
     147             :                              void const *        acct_addr,
     148             :                              fd_account_meta_t * meta,
     149             :                              uchar *             data,
     150             :                              ulong               data_max );
     151             : 
     152             : FD_PROTOTYPES_END
     153             : 
     154             : /* Vinyl APIs *********************************************************/
     155             : 
     156             : FD_PROTOTYPES_BEGIN
     157             : 
     158             : #define FD_SNAPIN_IO_SPAD_MAX (64UL<<20) /* 64 MiB of I/O scratch space */
     159             : 
     160             : /* fd_snapin_vinyl_unprivileged_init performs setup tasks after being
     161             :    sandboxed.  (anything that might be exposed to untrusted data) */
     162             : 
     163             : void
     164             : fd_snapin_vinyl_unprivileged_init( fd_snapin_tile_t * ctx,
     165             :                                    fd_topo_t *        topo,
     166             :                                    fd_topo_tile_t *   tile,
     167             :                                    void *             io_mm_mem,
     168             :                                    void *             io_wd_mem );
     169             : 
     170             : /* fd_snapin_vinyl_seccomp returns a seccomp sandbox policy suitable
     171             :    for vinyl operation. */
     172             : 
     173             : ulong
     174             : fd_snapin_vinyl_seccomp( ulong                out_cnt,
     175             :                          struct sock_filter * out );
     176             : 
     177             : /* fd_snapin_vinyl_reset pauses the snapwr tile (waits for the snapwr
     178             :    tile to ack) and formats a bstream file to be empty.  THIS IS A
     179             :    DESTRUCTIVE ACTION. */
     180             : 
     181             : void
     182             : fd_snapin_vinyl_reset( fd_snapin_tile_t * ctx );
     183             : 
     184             : /* fd_snapin_vinyl_txn_begin starts a transactional burst write.
     185             :    Assumes vinyl uses the io_mm backend.  The write can then either be
     186             :    committed or cancelled.  There is no practical limit on the size of
     187             :    this burst. */
     188             : 
     189             : void
     190             : fd_snapin_vinyl_txn_begin( fd_snapin_tile_t * ctx );
     191             : 
     192             : /* fd_snapin_vinyl_txn_commit finishes a transactional burst write.
     193             :    Assumes vinyl uses the io_mm backend.  Reads through bstream records
     194             :    written since txn_begin was called and updates the vinyl_meta index. */
     195             : 
     196             : void
     197             : fd_snapin_vinyl_txn_commit( fd_snapin_tile_t * ctx );
     198             : 
     199             : /* fd_snapin_vinyl_txn_cancel abandons a transactional burst write.
     200             :    Assumes vinyl uses the io_mm backend.  Reverts the bstream state to
     201             :    when txn_begin was called. */
     202             : 
     203             : void
     204             : fd_snapin_vinyl_txn_cancel( fd_snapin_tile_t * ctx );
     205             : 
     206             : /* fd_snapin_vinyl_wd_init transitions the vinyl backend from generic
     207             :    vinyl accessor (io_mm) to fast dumb direct account insertion (io_wd).
     208             :    This must be called before calling fd_snapin_process_account_*.
     209             :    Starts the snapwr tile (waits for the snapwr tile to ack). */
     210             : 
     211             : void
     212             : fd_snapin_vinyl_wd_init( fd_snapin_tile_t * ctx );
     213             : 
     214             : /* fd_snapin_vinyl_wd_fini transitions the vinyl backend from fast dumb
     215             :    direct account insertion (io_wd) back to generic mode (io_mm).
     216             :    Pauses the snapwr tile (waits for the snapwr to ack). */
     217             : 
     218             : void
     219             : fd_snapin_vinyl_wd_fini( fd_snapin_tile_t * ctx );
     220             : 
     221             : /* fd_snapin_vinyl_shutdown instructs vinyl-related tiles of the loader
     222             :    to shut down.  Blocks until all affected tiles have acknowledged the
     223             :    shutdown signal. */
     224             : 
     225             : void
     226             : fd_snapin_vinyl_shutdown( fd_snapin_tile_t * ctx );
     227             : 
     228             : /* Internal APIs for inserting accounts */
     229             : 
     230             : int fd_snapin_process_account_header_vinyl( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     231             : int fd_snapin_process_account_data_vinyl  ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     232             : int fd_snapin_process_account_batch_vinyl ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
     233             : 
     234             : FD_PROTOTYPES_END
     235             : 
     236             : /* Generic APIs *******************************************************/
     237             : 
     238             : FD_PROTOTYPES_BEGIN
     239             : 
     240             : /* int return value for fd_snapin_process_account_header,
     241             : fd_snapin_process_account_data, and fd_snapin_process_account_batch
     242             : indicates whether to yield to stem for credit return */
     243             : 
     244             : static inline int
     245             : fd_snapin_process_account_header( fd_snapin_tile_t *            ctx,
     246           0 :                                   fd_ssparse_advance_result_t * result ) {
     247           0 :   if( ctx->use_vinyl ) {
     248           0 :     return fd_snapin_process_account_header_vinyl( ctx, result );
     249           0 :   } else {
     250           0 :     return fd_snapin_process_account_header_funk( ctx, result );
     251           0 :   }
     252           0 :   return 0;
     253           0 : }
     254             : 
     255             : static inline int
     256             : fd_snapin_process_account_data( fd_snapin_tile_t *            ctx,
     257           0 :                                 fd_ssparse_advance_result_t * result ) {
     258           0 :   if( ctx->use_vinyl ) {
     259           0 :     return fd_snapin_process_account_data_vinyl( ctx, result );
     260           0 :   } else {
     261           0 :     return fd_snapin_process_account_data_funk( ctx, result );
     262           0 :   }
     263           0 :   return 0;
     264           0 : }
     265             : 
     266             : static inline int
     267             : fd_snapin_process_account_batch( fd_snapin_tile_t *            ctx,
     268             :                                  fd_ssparse_advance_result_t * result,
     269           0 :                                  buffered_account_batch_t *    buffered_batch ) {
     270           0 :   if( ctx->use_vinyl ) {
     271           0 :     return fd_snapin_process_account_batch_vinyl( ctx, result );
     272           0 :   } else {
     273           0 :     return fd_snapin_process_account_batch_funk( ctx, result, buffered_batch );
     274           0 :   }
     275           0 :   return 0;
     276           0 : }
     277             : 
     278             : static inline void
     279             : fd_snapin_read_account( fd_snapin_tile_t *  ctx,
     280             :                         void const *        acct_addr,
     281             :                         fd_account_meta_t * meta,
     282             :                         uchar *             data,
     283           0 :                         ulong               data_max ) {
     284             :   /* fd_snapin_read_account will no longer be required in the snapin
     285             :      tile once funk is deprecated from the snapshot load pipeline.
     286             :      Under vinyl, this is implemented in the snapwm tile. */
     287           0 :   if( ctx->use_vinyl ) {
     288           0 :     FD_LOG_ERR(( "read account is not supported under vinyl" ));
     289           0 :   } else {
     290           0 :     fd_snapin_read_account_funk( ctx, acct_addr, meta, data, data_max );
     291           0 :   }
     292           0 : }
     293             : 
     294             : /* fd_snapin_send_duplicate_account sends a duplicate account message
     295             :    with the signature FD_SNAPSHOT_HASH_MSG_SUB or
     296             :    FD_SNAPSHOT_HASH_MSG_SUB_HDR, depending on if this duplicate account
     297             :    contains valid account data. The message is only
     298             :    sent if lthash verification is enabled in the snapshot loader.
     299             : 
     300             :    lamports is account's lamports value.  data is the account's data,
     301             :    which can be optionally null.  data_len is the length of the account
     302             :    data.  executable is the account's executable flag. owner points to
     303             :    the account's owner (32 bytes).  pubkey points to the account's
     304             :    pubkey (32 bytes).  early_exit is an optional pointer to an int flag
     305             :    that is set to 1 if the caller should yield to stem following this
     306             :    call. */
     307             : static inline void
     308             : fd_snapin_send_duplicate_account( fd_snapin_tile_t * ctx,
     309             :                                   ulong              lamports,
     310             :                                   uchar const *      data,
     311             :                                   ulong              data_len,
     312             :                                   uchar              executable,
     313             :                                   uchar const *      owner,
     314             :                                   uchar const *      pubkey,
     315             :                                   int                has_data,
     316           0 :                                   int *              early_exit ) {
     317           0 :   if( FD_UNLIKELY( ctx->lthash_disabled ) ) return;
     318             : 
     319           0 :   if( FD_LIKELY( has_data ) ) {
     320           0 :     fd_snapshot_full_account_t * existing_account = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
     321           0 :     fd_snapshot_account_hdr_init( &existing_account->hdr, pubkey, owner, lamports, executable, data_len );
     322           0 :     fd_memcpy( existing_account->data, data, data_len );
     323           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 );
     324           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 );
     325           0 :   } else {
     326           0 :     fd_snapshot_account_hdr_t * acc_hdr = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
     327           0 :     fd_snapshot_account_hdr_init( acc_hdr, pubkey, owner, lamports, executable, data_len );
     328           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 );
     329           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 );
     330           0 :   }
     331           0 :   if( FD_LIKELY( early_exit ) ) *early_exit = 1;
     332           0 : }
     333             : 
     334             : /* fd_snapin_send_duplicate_account_data sends a duplicate account
     335             :    message with the signature FD_SNAPSHOT_HASH_MSG_SUB_DATA.  The
     336             :    message is only sent if lthash verification is enabled in the
     337             :    snapshot loader.
     338             : 
     339             :    data is the account's data, which cannot be null.  data_len is the
     340             :    length of the account data.  early_exit is an optional pointer to an
     341             :    int flag that is set to 1 if the caller should yield to stem
     342             :    following this call. */
     343             : static inline void
     344             : fd_snapin_send_duplicate_account_data( fd_snapin_tile_t * ctx,
     345             :                                        uchar const *      data,
     346             :                                        ulong              data_sz,
     347           0 :                                        int *              early_exit ) {
     348           0 :   if( FD_UNLIKELY( ctx->lthash_disabled ) ) return;
     349             : 
     350           0 :   uchar * drop_account_data = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
     351           0 :   fd_memcpy( drop_account_data, data, data_sz );
     352           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 );
     353           0 :   ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, data_sz, ctx->hash_out.chunk0, ctx->hash_out.wmark );
     354           0 :   if( FD_LIKELY( early_exit ) ) *early_exit = 1;
     355           0 : }
     356             : 
     357             : FD_PROTOTYPES_END
     358             : 
     359             : #endif /* HEADER_fd_discof_restore_fd_snapin_tile_private_h */

Generated by: LCOV version 1.14