LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_svm_mini.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 29 29 100.0 %
Date: 2026-07-17 05:22:26 Functions: 35 46 76.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_tests_fd_svm_mini_h
       2             : #define HEADER_fd_src_flamenco_runtime_tests_fd_svm_mini_h
       3             : 
       4             : /* fd_svm_mini.h is an API for creating Solana runtime test
       5             :    environments.
       6             : 
       7             :    Structurally, the API works as follows:
       8             :    - svm_mini provides an environment for block/transaction execution,
       9             :      including a fork-aware accounts DB, program cache, etc.
      10             :    - svm_mini_limits configures memory limits for the above
      11             :    - svm_mini_params fine-tunes default state to reduce setup
      12             :      boilerplate (e.g. set up vote/stake accounts, builtin programs)
      13             :    - forks are identified by the "bank index".  some care is required to
      14             :      handle bank indexes, as they are reused after invalidation.
      15             : 
      16             :    This API optimizes for testing, not useful for production:
      17             :    - smaller runtime defaults (aims for 2 GiB memory reservations)
      18             :    - memory lazy paged / not pinned by default
      19             :    - memory 4K paged by default (simplify startup)
      20             :    - avoids use of privileged kernel calls */
      21             : 
      22             : #include "../../progcache/fd_progcache_user.h"
      23             : #include "../../log_collector/fd_log_collector_base.h"
      24             : #include "../fd_runtime.h"
      25             : #include "../fd_runtime_stack.h"
      26             : #include "../fd_txncache.h"
      27             : #include "../../vm/fd_vm.h"
      28             : 
      29             : /* fd_svm_mini_t holds handles to all relevant Firedancer runtime
      30             :    components for test environments. */
      31             : 
      32             : struct fd_svm_mini {
      33             :   fd_wksp_t *           wksp;
      34             :   fd_banks_t *          banks;
      35             :   fd_runtime_t *        runtime;
      36             :   fd_runtime_stack_t *  runtime_stack;
      37             :   fd_txncache_shmem_t * txncache_shmem;
      38             :   fd_txncache_t *       txncache;
      39             :   fd_vm_t *             vm;
      40             : 
      41             :   fd_progcache_t     progcache[1];
      42             :   fd_log_collector_t log_collector[1];
      43             :   fd_features_t      features[1];
      44             :   fd_sha256_t        sha256[1]; /* FIXME this should not be separate */
      45             : 
      46             :   /* Saved accdb init params for reset */
      47             :   int                  accdb_fd;
      48             :   void *               accdb_shmem_mem;
      49             :   void *               accdb_join_mem;
      50             :   ulong                accdb_max_accounts;
      51             :   ulong                accdb_max_live_slots;
      52             :   ulong                accdb_joiner_cnt;
      53             : };
      54             : 
      55             : typedef struct fd_svm_mini fd_svm_mini_t;
      56             : 
      57             : /* fd_svm_mini_limits_t specifies memory allocation limits for runtime
      58             :    components. */
      59             : 
      60             : struct fd_svm_mini_limits {
      61             :   /* fork management */
      62             :   ulong max_live_slots;
      63             :   ulong max_fork_width;
      64             : 
      65             :   /* consensus */
      66             :   ulong max_vote_accounts;
      67             :   ulong max_stake_accounts;
      68             : 
      69             :   /* accdb */
      70             :   ulong max_accounts;
      71             :   ulong max_account_space_bytes;
      72             : 
      73             :   /* Number of accdb joiners (writer joins) the shmem must support.  0
      74             :      means 1 (just the mini's own runtime join).  Tests that join the
      75             :      accdb a second time (e.g. an exec tile sharing mini's accounts DB)
      76             :      must set this to at least 2. */
      77             :   ulong accdb_joiner_cnt;
      78             : 
      79             :   /* progcache */
      80             :   ulong max_progcache_recs;
      81             :   ulong max_progcache_heap_bytes;
      82             : 
      83             :   /* txn executor */
      84             :   ulong max_txn_write_locks;
      85             :   ulong max_txn_per_slot;
      86             : 
      87             :   /* wksp alloc tag (0 uses default) */
      88             :   ulong wksp_tag;
      89             : 
      90             :   /* additional wksp partitions / data size */
      91             :   ulong wksp_addl_part_cnt;
      92             :   ulong wksp_addl_sz;
      93             : };
      94             : 
      95             : typedef struct fd_svm_mini_limits fd_svm_mini_limits_t;
      96             : 
      97             : /* fd_svm_mini_params_t specifies defaults for initialization of an
      98             :    svm_mini object. */
      99             : 
     100             : struct fd_svm_mini_params {
     101             :   ulong hash_seed;
     102             :   ulong root_slot;
     103             :   ulong slots_per_epoch;
     104             : 
     105             :   ulong init_sysvars          : 1;
     106             :   ulong init_feature_accounts : 1;
     107             :   ulong init_builtins         : 1;
     108             : 
     109             :   /* If non-zero, creates mock_validator_cnt validators with uniform
     110             :      stake and populates the epoch leader schedule.  For each validator,
     111             :      creates identity, vote, and stake accounts in the accounts DB. */
     112             :   ulong mock_validator_cnt;
     113             : 
     114             :   /* Sysvar overrides */
     115             :   fd_sol_sysvar_clock_t const * clock;
     116             :   fd_epoch_schedule_t const *   epoch_schedule;
     117             :   fd_rent_t const *             rent;
     118             : };
     119             : 
     120             : typedef struct fd_svm_mini_params fd_svm_mini_params_t;
     121             : 
     122             : FD_PROTOTYPES_BEGIN
     123             : 
     124             : /* fd_svm_test_{boot,halt} do all-in-one setup for test executables.
     125             :    An important goal is rootless operation on a default Linux config for
     126             :    easy development.
     127             : 
     128             :    fd_svm_test_boot does the following steps:
     129             :    - standard command-line handling
     130             :    - creates an anonymous wksp / attaches to an existing wksp
     131             :    - creates various runtime objects
     132             : 
     133             :    Parses and strips the following arguments from pargc/pargv, or
     134             :    chooses sane defaults in the absence of these options.
     135             : 
     136             :    --page-sz <size>     memory page size ("normal", "huge", "gigantic")
     137             :                         if unspecified, uses lazy anonymous normal pages
     138             :                         if specified, implies pinned/mlock() pages
     139             :    --page-cnt <count>   number of memory pages to reserve (default derived from limits)
     140             :    --wksp <name>        use existing wksp instead of allocating one
     141             :    --near-cpu <number>  NUMA affinity hint for memory allocations
     142             :                         (default: let kernel decide on first use/mlock)
     143             : 
     144             :    Terminates the process with FD_LOG_ERR (exit code 1) if svm_mini
     145             :    fails to boot.
     146             : 
     147             :    fd_svm_test_halt destroys the mini object and halts fd.  Wksp
     148             :    cleanup is left to process termination. */
     149             : 
     150             : fd_svm_mini_t *
     151             : fd_svm_test_boot( int *    pargc,
     152             :                   char *** pargv,
     153             :                   fd_svm_mini_limits_t const * limits );
     154             : 
     155             : void
     156             : fd_svm_test_halt( fd_svm_mini_t * mini );
     157             : 
     158             : /* fd_svm_mini_limits_default populates minimal single-fork execution
     159             :    limits. */
     160             : 
     161             : FD_FN_UNUSED static fd_svm_mini_limits_t *
     162          57 : fd_svm_mini_limits_default( fd_svm_mini_limits_t * limits ) {
     163          57 :   *limits = (fd_svm_mini_limits_t) {
     164          57 :     .max_live_slots           = 16UL,
     165          57 :     .max_fork_width           = 4UL,
     166          57 :     .max_vote_accounts        = 256UL,
     167          57 :     .max_stake_accounts       = 256UL,
     168          57 :     .max_accounts             = 128UL,
     169          57 :     .max_account_space_bytes  = 32UL<<20,
     170          57 :     .max_progcache_recs       = 256UL,
     171          57 :     .max_progcache_heap_bytes = 65536UL,
     172          57 :     .max_txn_write_locks      = 0UL,
     173          57 :     .max_txn_per_slot         = 128UL
     174          57 :   };
     175          57 :   return limits;
     176          57 : }
     177             : 
     178             : /* fd_svm_mini_wksp_data_max returns the recommended heap space in bytes
     179             :    for a given limits config. */
     180             : 
     181             : ulong
     182             : fd_svm_mini_wksp_data_max( fd_svm_mini_limits_t const * limits );
     183             : 
     184             : /* fd_svm_mini_create allocates and constructs various Solana runtime
     185             :    environment objects and packs them into an svm_mini handle.  The
     186             :    newly created svm_mini object is reset using default params.  On
     187             :    failure terminates the app with FD_LOG_ERR (exit code 1). */
     188             : 
     189             : fd_svm_mini_t *
     190             : fd_svm_mini_create( fd_wksp_t *                  wksp,
     191             :                     fd_svm_mini_limits_t const * limits );
     192             : 
     193             : /* fd_svm_mini_destroy destroys all Solana runtime environment objects,
     194             :    accounts, blocks, etc, and frees them back to the wksp heap. */
     195             : 
     196             : void
     197             : fd_svm_mini_destroy( fd_svm_mini_t * mini );
     198             : 
     199             : /* fd_svm_mini_params_default populates default execution state. */
     200             : 
     201             : FD_FN_UNUSED static fd_svm_mini_params_t *
     202        3651 : fd_svm_mini_params_default( fd_svm_mini_params_t * params ) {
     203        3651 :   *params = (fd_svm_mini_params_t) {
     204        3651 :     .hash_seed              = 1UL,
     205        3651 :     .root_slot              = 1UL,
     206        3651 :     .slots_per_epoch        = 16UL,
     207        3651 :     .init_sysvars           = 1,
     208        3651 :     .init_feature_accounts  = 0,
     209        3651 :     .init_builtins          = 1,
     210        3651 :     .mock_validator_cnt     = 1UL,
     211        3651 :     .clock                  = NULL,
     212        3651 :     .epoch_schedule         = NULL,
     213             :     .rent                   = NULL,
     214        3651 :   };
     215        3651 :   return params;
     216        3651 : }
     217             : 
     218             : /* fd_svm_mini_reset destroys all existing runtime state (banks, accdb,
     219             :    etc), and initializes them according to params.  This operation
     220             :    invalidates any handle previously acquired through svm_mini.  Returns
     221             :    the initial bank index (rooted). */
     222             : 
     223             : ulong
     224             : fd_svm_mini_reset( fd_svm_mini_t *        mini,
     225             :                    fd_svm_mini_params_t * params );
     226             : 
     227             : /* Fork management API */
     228             : 
     229             : /* fd_svm_mini_attach_child creates a fork node as a descendant of the
     230             :    node identified by parent_bank_idx.  child_slot is the slot number of
     231             :    this node.  Terminates the app with FD_LOG_ERR on failure. */
     232             : 
     233             : ulong
     234             : fd_svm_mini_attach_child( fd_svm_mini_t * mini,
     235             :                           ulong           parent_bank_idx,
     236             :                           ulong           child_slot );
     237             : 
     238             : /* fd_svm_mini_freeze freezes the bank identified by bank_idx.  Runs
     239             :    slot boundary logic (registers POH hash into blockhash queue, updates
     240             :    sysvars, settles fees, etc). */
     241             : 
     242             : void
     243             : fd_svm_mini_freeze( fd_svm_mini_t * mini,
     244             :                     ulong           bank_idx );
     245             : 
     246             : /* fd_svm_mini_register_blockhash makes blockhash resolvable by the
     247             :    status cache when executing transactions on the bank identified by
     248             :    bank_idx (otherwise the fd_txncache_query/insert FD_TEST(blockcache)
     249             :    in the executor's pre-execute checks fails).  It registers blockhash
     250             :    on bank_idx's PARENT txncache fork, because a fork can only query
     251             :    blockhashes registered on a fork it descends from (a fork's
     252             :    descends-set holds its ancestors, not itself).  bank_idx must
     253             :    therefore have a parent, and that parent fork must not already be
     254             :    finalized (each txncache fork carries at most one blockhash). */
     255             : 
     256             : void
     257             : fd_svm_mini_register_blockhash( fd_svm_mini_t *   mini,
     258             :                                 ulong             bank_idx,
     259             :                                 fd_hash_t const * blockhash );
     260             : 
     261             : /* fd_svm_mini_cancel_fork cancels the subtree of the fork graph
     262             :    identified by bank_idx (i.e. the bank_idx node and all its children,
     263             :    transitively). */
     264             : 
     265             : void
     266             : fd_svm_mini_cancel_fork( fd_svm_mini_t * mini,
     267             :                          ulong           bank_idx );
     268             : 
     269             : /* fd_svm_mini_advance_root advances the fork graph root to the node
     270             :    identified by bank_idx.  Cancels all siblings and uncles
     271             :    (transitively) of the rooted nodes. */
     272             : 
     273             : void
     274             : fd_svm_mini_advance_root( fd_svm_mini_t * mini,
     275             :                           ulong           bank_idx );
     276             : 
     277             : fd_bank_t *
     278             : fd_svm_mini_bank( fd_svm_mini_t * mini,
     279             :                   ulong           bank_idx );
     280             : 
     281             : fd_accdb_fork_id_t
     282             : fd_svm_mini_fork_id( fd_svm_mini_t * mini,
     283             :                      ulong           bank_idx );
     284             : 
     285             : /* Mock/inject API */
     286             : 
     287             : /* fd_svm_mini_put_account_rooted injects a copy of the account at ro
     288             :    into the rooted state. */
     289             : 
     290             : void
     291             : fd_svm_mini_put_account_rooted( fd_svm_mini_t *  mini,
     292             :                                 fd_acc_t const * ro );
     293             : 
     294             : /* fd_svm_mini_add_lamports_rooted increases the lamport balance of a
     295             :    rooted accounts. */
     296             : 
     297             : void
     298             : fd_svm_mini_add_lamports_rooted( fd_svm_mini_t *     mini,
     299             :                                  fd_pubkey_t const * pubkey,
     300             :                                  ulong               lamports );
     301             : 
     302             : /* fd_svm_mini_add_lamports increases the lamport balance of an account. */
     303             : 
     304             : void
     305             : fd_svm_mini_add_lamports( fd_svm_mini_t *     mini,
     306             :                           fd_accdb_fork_id_t  fork_id,
     307             :                           fd_pubkey_t const * pubkey,
     308             :                           ulong               lamports );
     309             : 
     310             : FD_PROTOTYPES_END
     311             : 
     312             : #endif /* HEADER_fd_src_flamenco_runtime_tests_fd_svm_mini_h */

Generated by: LCOV version 1.14