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

Generated by: LCOV version 1.14