LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_solfuzz.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 134 0.0 %
Date: 2025-11-25 04:50:41 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /* fd_solfuzz.c contains support routines */
       2             : 
       3             : #define _GNU_SOURCE
       4             : #include "fd_solfuzz.h"
       5             : #include "../fd_bank.h"
       6             : #include "../fd_runtime_stack.h"
       7             : #include "../fd_runtime.h"
       8             : #include "../../accdb/fd_accdb_impl_v1.h"
       9             : #include <errno.h>
      10             : #include <sys/mman.h>
      11             : #include "../../../util/shmem/fd_shmem_private.h"
      12             : 
      13             : fd_wksp_t *
      14             : fd_wksp_demand_paged_new( char const * name,
      15             :                           uint         seed,
      16             :                           ulong        part_max,
      17           0 :                           ulong        data_max ) {
      18           0 :   ulong footprint = fd_wksp_footprint( part_max, data_max );
      19           0 :   if( FD_UNLIKELY( !footprint ) ) {
      20           0 :     FD_LOG_WARNING(( "invalid workspace params (part_max=%lu data_max=%lu)", part_max, data_max ));
      21           0 :     return NULL;
      22           0 :   }
      23             : 
      24             :   /* Round up footprint to nearest huge page size */
      25           0 :   footprint = fd_ulong_align_up( footprint, FD_SHMEM_HUGE_PAGE_SZ );
      26             : 
      27             :   /* Acquire anonymous demand-paged memory */
      28           0 :   void * mem = fd_shmem_private_map_rand( footprint, FD_SHMEM_HUGE_PAGE_SZ, PROT_READ|PROT_WRITE );
      29           0 :   if( FD_UNLIKELY( mem==MAP_FAILED ) ) {
      30           0 :     FD_LOG_WARNING(( "fd_shmem_private_map_rand() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      31           0 :     return NULL;
      32           0 :   }
      33             : 
      34             :   /* Indicate to kernel that hugepages are a fine backing store
      35             :      (Transparent Huge Pages) */
      36           0 :   if( FD_UNLIKELY( 0!=madvise( mem, footprint, MADV_HUGEPAGE ) ) ) {
      37           0 :     FD_LOG_WARNING(( "madvise() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      38           0 :     munmap( mem, footprint );
      39           0 :     return NULL;
      40           0 :   }
      41             : 
      42             :   /* Create workspace */
      43           0 :   fd_wksp_t * wksp = fd_wksp_join( fd_wksp_new( mem, name, seed, part_max, data_max ) );
      44           0 :   if( FD_UNLIKELY( !wksp ) ) {
      45           0 :     FD_LOG_WARNING(( "fd_wksp_new() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      46           0 :     munmap( mem, footprint );
      47           0 :     return NULL;
      48           0 :   }
      49             : 
      50             :   /* Register shared memory region */
      51           0 :   ulong fake_page_cnt = footprint>>FD_SHMEM_HUGE_LG_PAGE_SZ;
      52           0 :   int join_err = fd_shmem_join_anonymous(
      53           0 :       name,
      54           0 :       FD_SHMEM_JOIN_MODE_READ_WRITE,
      55           0 :       wksp,
      56           0 :       mem,
      57           0 :       FD_SHMEM_HUGE_PAGE_SZ,
      58           0 :       fake_page_cnt
      59           0 :   );
      60           0 :   if( FD_UNLIKELY( join_err ) ) {
      61           0 :     FD_LOG_WARNING(( "fd_shmem_join_anonymous() failed (%i-%s)", join_err, fd_io_strerror( join_err ) ));
      62           0 :     fd_wksp_delete( fd_wksp_leave( wksp ) );
      63           0 :     munmap( mem, footprint );
      64           0 :     return NULL;
      65           0 :   }
      66             : 
      67           0 :   return wksp;
      68           0 : }
      69             : 
      70             : void
      71           0 : fd_wksp_demand_paged_delete( fd_wksp_t * wksp ) {
      72           0 :   fd_shmem_leave_anonymous( wksp, NULL );
      73           0 :   FD_TEST( fd_wksp_delete( fd_wksp_leave( wksp ) ) );
      74           0 : }
      75             : 
      76             : fd_solfuzz_runner_t *
      77             : fd_solfuzz_runner_new( fd_wksp_t *                         wksp,
      78             :                        ulong                               wksp_tag,
      79           0 :                        fd_solfuzz_runner_options_t const * options ) {
      80             : 
      81             :   /* Allocate objects */
      82           0 :   ulong const txn_max  = 16UL;
      83           0 :   ulong const rec_max  = 1024UL;
      84           0 :   ulong const spad_max = 1500000000UL; /* 1.5GB to accommodate 128 accounts 10MB each */
      85           0 :   ulong const bank_max = 1UL;
      86           0 :   ulong const fork_max = 1UL;
      87           0 :   fd_solfuzz_runner_t * runner     = fd_wksp_alloc_laddr( wksp, alignof(fd_solfuzz_runner_t), sizeof(fd_solfuzz_runner_t),              wksp_tag );
      88           0 :   void *                funk_mem   = fd_wksp_alloc_laddr( wksp, fd_funk_align(),              fd_funk_footprint( txn_max, rec_max ),    wksp_tag );
      89           0 :   void *                pcache_mem = fd_wksp_alloc_laddr( wksp, fd_funk_align(),              fd_funk_footprint( txn_max, rec_max ),    wksp_tag );
      90           0 :   uchar *               scratch    = fd_wksp_alloc_laddr( wksp, FD_PROGCACHE_SCRATCH_ALIGN,   FD_PROGCACHE_SCRATCH_FOOTPRINT,           wksp_tag );
      91           0 :   void *                spad_mem   = fd_wksp_alloc_laddr( wksp, fd_spad_align(),              fd_spad_footprint( spad_max ),            wksp_tag );
      92           0 :   void *                banks_mem  = fd_wksp_alloc_laddr( wksp, fd_banks_align(),             fd_banks_footprint( bank_max, fork_max ), wksp_tag );
      93           0 :   if( FD_UNLIKELY( !runner     ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(solfuzz_runner) failed" )); goto bail1; }
      94           0 :   if( FD_UNLIKELY( !funk_mem   ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(funk) failed"           )); goto bail1; }
      95           0 :   if( FD_UNLIKELY( !pcache_mem ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(funk) failed"           )); goto bail1; }
      96           0 :   if( FD_UNLIKELY( !scratch    ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(scratch) failed"        )); goto bail1; }
      97           0 :   if( FD_UNLIKELY( !spad_mem   ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(spad) failed (spad_max=%g)", (double)spad_max )); goto bail1; }
      98           0 :   if( FD_UNLIKELY( !banks_mem  ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(banks) failed (bank_max=%lu fork_max=%lu)", bank_max, fork_max )); goto bail1; }
      99             : 
     100             :   /* Create objects */
     101           0 :   fd_memset( runner, 0, sizeof(fd_solfuzz_runner_t) );
     102           0 :   runner->wksp = wksp;
     103             : 
     104           0 :   void * shfunk   = fd_funk_new( funk_mem,   wksp_tag, 1UL, txn_max, rec_max );
     105           0 :   void * shpcache = fd_funk_new( pcache_mem, wksp_tag, 1UL, txn_max, rec_max );
     106           0 :   if( FD_UNLIKELY( !shfunk   ) ) goto bail1;
     107           0 :   if( FD_UNLIKELY( !shpcache ) ) goto bail1;
     108             : 
     109           0 :   if( FD_UNLIKELY( !fd_accdb_admin_join  ( runner->accdb_admin, funk_mem ) ) ) goto bail2;
     110           0 :   if( FD_UNLIKELY( !fd_accdb_user_v1_init( runner->accdb,       funk_mem ) ) ) goto bail2;
     111           0 :   if( FD_UNLIKELY( !fd_progcache_join( runner->progcache, pcache_mem, scratch, FD_PROGCACHE_SCRATCH_FOOTPRINT ) ) ) goto bail2;
     112           0 :   if( FD_UNLIKELY( !fd_progcache_admin_join( runner->progcache_admin, pcache_mem ) ) ) goto bail2;
     113             : 
     114           0 :   runner->runtime = fd_wksp_alloc_laddr( wksp, alignof(fd_runtime_t), sizeof(fd_runtime_t), wksp_tag );
     115           0 :   if( FD_UNLIKELY( !runner->runtime ) ) goto bail2;
     116           0 :   runner->exec_accounts = fd_wksp_alloc_laddr( wksp, alignof(fd_exec_accounts_t), sizeof(fd_exec_accounts_t), wksp_tag );
     117           0 :   if( FD_UNLIKELY( !runner->exec_accounts ) ) goto bail2;
     118           0 :   runner->runtime_stack = fd_wksp_alloc_laddr( wksp, alignof(fd_runtime_stack_t), sizeof(fd_runtime_stack_t), wksp_tag );
     119           0 :   if( FD_UNLIKELY( !runner->runtime_stack ) ) goto bail2;
     120             : 
     121           0 : # if FD_HAS_FLATCC
     122             :   /* TODO: Consider implementing custom allocators and emitters.
     123             :      The default builder / emitter uses libc allocators */
     124           0 :   int builder_err = flatcc_builder_init( runner->fb_builder );
     125           0 :   if( FD_UNLIKELY( builder_err ) ) goto bail2;
     126           0 : # endif
     127             : 
     128           0 :   runner->spad = fd_spad_join( fd_spad_new( spad_mem, spad_max ) );
     129           0 :   if( FD_UNLIKELY( !runner->spad ) ) goto bail2;
     130           0 :   runner->banks = fd_banks_join( fd_banks_new( banks_mem, bank_max, fork_max, 0, 8888UL ) );
     131           0 :   if( FD_UNLIKELY( !runner->banks ) ) goto bail2;
     132           0 :   runner->bank = fd_banks_init_bank( runner->banks );
     133           0 :   if( FD_UNLIKELY( !runner->bank ) ) {
     134           0 :     FD_LOG_WARNING(( "fd_banks_init_bank failed" ));
     135           0 :     goto bail2;
     136           0 :   }
     137           0 :   fd_bank_slot_set( runner->bank, 0UL );
     138             : 
     139           0 :   runner->enable_vm_tracing = options->enable_vm_tracing;
     140           0 :   FD_TEST( runner->progcache->funk->shmem );
     141           0 :   return runner;
     142             : 
     143           0 : bail2:
     144           0 :   if( runner->spad      ) fd_spad_delete( fd_spad_leave( runner->spad ) );
     145           0 :   if( shfunk            ) fd_funk_delete( shfunk ); /* free underlying fd_alloc instance */
     146           0 :   if( shpcache          ) fd_funk_delete( shpcache );
     147           0 :   if( runner->banks     ) fd_banks_delete( fd_banks_leave( runner->banks ) );
     148           0 : bail1:
     149           0 :   fd_wksp_free_laddr( scratch    );
     150           0 :   fd_wksp_free_laddr( pcache_mem );
     151           0 :   fd_wksp_free_laddr( funk_mem   );
     152           0 :   fd_wksp_free_laddr( spad_mem   );
     153           0 :   fd_wksp_free_laddr( banks_mem  );
     154           0 :   fd_wksp_free_laddr( runner     );
     155           0 :   FD_LOG_WARNING(( "fd_solfuzz_runner_new failed" ));
     156           0 :   return NULL;
     157           0 : }
     158             : 
     159             : void
     160           0 : fd_solfuzz_runner_delete( fd_solfuzz_runner_t * runner ) {
     161             : 
     162           0 :   fd_accdb_user_fini( runner->accdb );
     163           0 :   void * shfunk = NULL;
     164           0 :   fd_accdb_admin_leave( runner->accdb_admin, &shfunk );
     165           0 :   if( shfunk ) fd_wksp_free_laddr( fd_funk_delete( shfunk ) );
     166             : 
     167           0 :   fd_progcache_leave( runner->progcache, NULL );
     168           0 :   void * shpcache = NULL;
     169           0 :   fd_progcache_admin_leave( runner->progcache_admin, &shpcache );
     170           0 :   if( shpcache ) fd_wksp_free_laddr( fd_funk_delete( shpcache ) );
     171             : 
     172           0 : # if FD_HAS_FLATCC
     173           0 :   flatcc_builder_clear( runner->fb_builder );
     174           0 : # endif
     175             : 
     176           0 :   if( runner->spad  ) fd_wksp_free_laddr( fd_spad_delete( fd_spad_leave( runner->spad ) ) );
     177           0 :   if( runner->banks ) fd_wksp_free_laddr( fd_banks_delete( fd_banks_leave( runner->banks ) ) );
     178           0 :   fd_wksp_free_laddr( runner );
     179           0 : }
     180             : 
     181             : void
     182           0 : fd_solfuzz_runner_leak_check( fd_solfuzz_runner_t * runner ) {
     183           0 :   if( FD_UNLIKELY( fd_spad_frame_used( runner->spad ) ) ) {
     184           0 :     FD_LOG_CRIT(( "solfuzz leaked a spad frame (bump allocator)" ));
     185           0 :   }
     186             : 
     187           0 :   if( FD_UNLIKELY( !fd_funk_txn_idx_is_null( fd_funk_txn_idx( runner->accdb_admin->funk->shmem->child_head_cidx ) ) ) ) {
     188           0 :     FD_LOG_CRIT(( "solfuzz leaked a funk txn" ));
     189           0 :   }
     190           0 : }

Generated by: LCOV version 1.14