LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_svm_mini.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 30 30 100.0 %
Date: 2026-09-01 04:28:17 Functions: 35 44 79.5 %

          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             :   ulong max_fallback_stake_accounts;
      69             : 
      70             :   /* accdb */
      71             :   ulong max_accounts;
      72             :   ulong max_account_space_bytes;
      73             : 
      74             :   /* Number of accdb joiners (writer joins) the shmem must support.  0
      75             :      means 1 (just the mini's own runtime join).  Tests that join the
      76             :      accdb a second time (e.g. an exec tile sharing mini's accounts DB)
      77             :      must set this to at least 2. */
      78             :   ulong accdb_joiner_cnt;
      79             : 
      80             :   /* progcache */
      81             :   ulong max_progcache_recs;
      82             :   ulong max_progcache_heap_bytes;
      83             : 
      84             :   /* txn executor */
      85             :   ulong max_txn_write_locks;
      86             :   ulong max_txn_per_slot;
      87             : 
      88             :   /* wksp alloc tag (0 uses default) */
      89             :   ulong wksp_tag;
      90             : 
      91             :   /* additional wksp partitions / data size */
      92             :   ulong wksp_addl_part_cnt;
      93             :   ulong wksp_addl_sz;
      94             : };
      95             : 
      96             : typedef struct fd_svm_mini_limits fd_svm_mini_limits_t;
      97             : 
      98             : /* fd_svm_mini_params_t specifies defaults for initialization of an
      99             :    svm_mini object. */
     100             : 
     101             : struct fd_svm_mini_params {
     102             :   ulong hash_seed;
     103             :   ulong root_slot;
     104             :   ulong slots_per_epoch;
     105             : 
     106             :   ulong init_sysvars          : 1;
     107             :   ulong init_feature_accounts : 1;
     108             :   ulong init_builtins         : 1;
     109             : 
     110             :   /* If non-zero, creates mock_validator_cnt validators with uniform
     111             :      stake and populates the epoch leader schedule.  For each validator,
     112             :      creates identity, vote, and stake accounts in the accounts DB. */
     113             :   ulong mock_validator_cnt;
     114             : 
     115             :   /* Sysvar overrides */
     116             :   fd_sol_sysvar_clock_t const * clock;
     117             :   fd_epoch_schedule_t const *   epoch_schedule;
     118             :   fd_rent_t const *             rent;
     119             : };
     120             : 
     121             : typedef struct fd_svm_mini_params fd_svm_mini_params_t;
     122             : 
     123             : FD_PROTOTYPES_BEGIN
     124             : 
     125             : /* fd_svm_test_{boot,halt} do all-in-one setup for test executables.
     126             :    An important goal is rootless operation on a default Linux config for
     127             :    easy development.
     128             : 
     129             :    fd_svm_test_boot does the following steps:
     130             :    - standard command-line handling
     131             :    - creates an anonymous wksp / attaches to an existing wksp
     132             :    - creates various runtime objects
     133             : 
     134             :    Parses and strips the following arguments from pargc/pargv, or
     135             :    chooses sane defaults in the absence of these options.
     136             : 
     137             :    --page-sz <size>     memory page size ("normal", "huge", "gigantic")
     138             :                         if unspecified, uses lazy anonymous normal pages
     139             :                         if specified, implies pinned/mlock() pages
     140             :    --page-cnt <count>   number of memory pages to reserve (default derived from limits)
     141             :    --wksp <name>        use existing wksp instead of allocating one
     142             :    --near-cpu <number>  NUMA affinity hint for memory allocations
     143             :                         (default: let kernel decide on first use/mlock)
     144             : 
     145             :    Terminates the process with FD_LOG_ERR (exit code 1) if svm_mini
     146             :    fails to boot.
     147             : 
     148             :    fd_svm_test_halt destroys the mini object and halts fd.  Wksp
     149             :    cleanup is left to process termination. */
     150             : 
     151             : fd_svm_mini_t *
     152             : fd_svm_test_boot( int *    pargc,
     153             :                   char *** pargv,
     154             :                   fd_svm_mini_limits_t const * limits );
     155             : 
     156             : void
     157             : fd_svm_test_halt( fd_svm_mini_t * mini );
     158             : 
     159             : /* fd_svm_mini_limits_default populates minimal single-fork execution
     160             :    limits. */
     161             : 
     162             : FD_FN_UNUSED static fd_svm_mini_limits_t *
     163          57 : fd_svm_mini_limits_default( fd_svm_mini_limits_t * limits ) {
     164          57 :   *limits = (fd_svm_mini_limits_t) {
     165          57 :     .max_live_slots           = 16UL,
     166          57 :     .max_fork_width           = 4UL,
     167          57 :     .max_vote_accounts        = 256UL,
     168          57 :     .max_stake_accounts       = 256UL,
     169          57 :     .max_fallback_stake_accounts = 4096UL,
     170          57 :     .max_accounts             = 128UL,
     171          57 :     .max_account_space_bytes  = 32UL<<20,
     172          57 :     .max_progcache_recs       = 256UL,
     173          57 :     .max_progcache_heap_bytes = 65536UL,
     174          57 :     .max_txn_write_locks      = 0UL,
     175          57 :     .max_txn_per_slot         = 128UL
     176          57 :   };
     177          57 :   return limits;
     178          57 : }
     179             : 
     180             : /* fd_svm_mini_wksp_data_max returns the recommended heap space in bytes
     181             :    for a given limits config. */
     182             : 
     183             : ulong
     184             : fd_svm_mini_wksp_data_max( fd_svm_mini_limits_t const * limits );
     185             : 
     186             : /* fd_svm_mini_create allocates and constructs various Solana runtime
     187             :    environment objects and packs them into an svm_mini handle.  The
     188             :    newly created svm_mini object is reset using default params.  On
     189             :    failure terminates the app with FD_LOG_ERR (exit code 1). */
     190             : 
     191             : fd_svm_mini_t *
     192             : fd_svm_mini_create( fd_wksp_t *                  wksp,
     193             :                     fd_svm_mini_limits_t const * limits );
     194             : 
     195             : /* fd_svm_mini_destroy destroys all Solana runtime environment objects,
     196             :    accounts, blocks, etc, and frees them back to the wksp heap. */
     197             : 
     198             : void
     199             : fd_svm_mini_destroy( fd_svm_mini_t * mini );
     200             : 
     201             : /* fd_svm_mini_params_default populates default execution state. */
     202             : 
     203             : FD_FN_UNUSED static fd_svm_mini_params_t *
     204        3909 : fd_svm_mini_params_default( fd_svm_mini_params_t * params ) {
     205        3909 :   *params = (fd_svm_mini_params_t) {
     206        3909 :     .hash_seed              = 1UL,
     207        3909 :     .root_slot              = 1UL,
     208        3909 :     .slots_per_epoch        = 16UL,
     209        3909 :     .init_sysvars           = 1,
     210        3909 :     .init_feature_accounts  = 0,
     211        3909 :     .init_builtins          = 1,
     212        3909 :     .mock_validator_cnt     = 1UL,
     213        3909 :     .clock                  = NULL,
     214        3909 :     .epoch_schedule         = NULL,
     215             :     .rent                   = NULL,
     216        3909 :   };
     217        3909 :   return params;
     218        3909 : }
     219             : 
     220             : /* fd_svm_mini_reset destroys all existing runtime state (banks, accdb,
     221             :    etc), and initializes them according to params.  This operation
     222             :    invalidates any handle previously acquired through svm_mini.  Returns
     223             :    the initial bank index (rooted), or ULONG_MAX if mock_validator_cnt
     224             :    exceeds the configured vote-account capacity. */
     225             : 
     226             : ulong
     227             : fd_svm_mini_reset( fd_svm_mini_t *        mini,
     228             :                    fd_svm_mini_params_t * params );
     229             : 
     230             : /* Fork management API */
     231             : 
     232             : /* fd_svm_mini_attach_child creates a fork node as a descendant of the
     233             :    node identified by parent_bank_idx.  child_slot is the slot number of
     234             :    this node.  Terminates the app with FD_LOG_ERR on failure. */
     235             : 
     236             : ulong
     237             : fd_svm_mini_attach_child( fd_svm_mini_t * mini,
     238             :                           ulong           parent_bank_idx,
     239             :                           ulong           child_slot );
     240             : 
     241             : /* fd_svm_mini_freeze freezes the bank identified by bank_idx.  Runs
     242             :    slot boundary logic (registers POH hash into blockhash queue, updates
     243             :    sysvars, settles fees, etc). */
     244             : 
     245             : void
     246             : fd_svm_mini_freeze( fd_svm_mini_t * mini,
     247             :                     ulong           bank_idx );
     248             : 
     249             : /* fd_svm_mini_register_blockhash makes blockhash resolvable by the
     250             :    status cache when executing transactions on the bank identified by
     251             :    bank_idx (otherwise the fd_txncache_query/insert FD_TEST(blockcache)
     252             :    in the executor's pre-execute checks fails).  It registers blockhash
     253             :    on bank_idx's PARENT txncache fork, because a fork can only query
     254             :    blockhashes registered on a fork it descends from (a fork's
     255             :    descends-set holds its ancestors, not itself).  bank_idx must
     256             :    therefore have a parent, and that parent fork must not already be
     257             :    finalized (each txncache fork carries at most one blockhash). */
     258             : 
     259             : void
     260             : fd_svm_mini_register_blockhash( fd_svm_mini_t *   mini,
     261             :                                 ulong             bank_idx,
     262             :                                 fd_hash_t const * blockhash );
     263             : 
     264             : /* fd_svm_mini_cancel_fork cancels the subtree of the fork graph
     265             :    identified by bank_idx (i.e. the bank_idx node and all its children,
     266             :    transitively). */
     267             : 
     268             : void
     269             : fd_svm_mini_cancel_fork( fd_svm_mini_t * mini,
     270             :                          ulong           bank_idx );
     271             : 
     272             : /* fd_svm_mini_advance_root advances the fork graph root to the node
     273             :    identified by bank_idx.  Cancels all siblings and uncles
     274             :    (transitively) of the rooted nodes. */
     275             : 
     276             : void
     277             : fd_svm_mini_advance_root( fd_svm_mini_t * mini,
     278             :                           ulong           bank_idx );
     279             : 
     280             : fd_bank_t *
     281             : fd_svm_mini_bank( fd_svm_mini_t * mini,
     282             :                   ulong           bank_idx );
     283             : 
     284             : fd_accdb_fork_id_t
     285             : fd_svm_mini_fork_id( fd_svm_mini_t * mini,
     286             :                      ulong           bank_idx );
     287             : 
     288             : /* Mock/inject API */
     289             : 
     290             : /* fd_svm_mini_put_account_rooted injects a copy of the account at ro
     291             :    into the rooted state. */
     292             : 
     293             : void
     294             : fd_svm_mini_put_account_rooted( fd_svm_mini_t *  mini,
     295             :                                 fd_acc_t const * ro );
     296             : 
     297             : /* fd_svm_mini_add_lamports_rooted increases the lamport balance of a
     298             :    rooted accounts. */
     299             : 
     300             : void
     301             : fd_svm_mini_add_lamports_rooted( fd_svm_mini_t *     mini,
     302             :                                  fd_pubkey_t const * pubkey,
     303             :                                  ulong               lamports );
     304             : 
     305             : /* fd_svm_mini_add_lamports increases the lamport balance of an account. */
     306             : 
     307             : void
     308             : fd_svm_mini_add_lamports( fd_svm_mini_t *     mini,
     309             :                           fd_accdb_fork_id_t  fork_id,
     310             :                           fd_pubkey_t const * pubkey,
     311             :                           ulong               lamports );
     312             : 
     313             : FD_PROTOTYPES_END
     314             : 
     315             : #endif /* HEADER_fd_src_flamenco_runtime_tests_fd_svm_mini_h */

Generated by: LCOV version 1.14