LCOV - code coverage report
Current view: top level - flamenco/runtime/tests/harness - fd_exec_sol_compat.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 576 0.0 %
Date: 2025-08-05 05:04:49 Functions: 0 29 0.0 %

          Line data    Source code
       1             : #define _GNU_SOURCE
       2             : #include "fd_exec_sol_compat.h"
       3             : 
       4             : #include "../../../../ballet/nanopb/pb_encode.h"
       5             : #include "../../../../ballet/nanopb/pb_decode.h"
       6             : 
       7             : #include "../../fd_executor_err.h"
       8             : #include "../../../capture/fd_solcap_writer.h"
       9             : #include "../../../features/fd_features.h"
      10             : #include "../../../../ballet/shred/fd_shred.h"
      11             : 
      12             : #include "fd_instr_harness.h"
      13             : #include "fd_txn_harness.h"
      14             : #include "fd_block_harness.h"
      15             : #include "fd_types_harness.h"
      16             : #include "fd_vm_harness.h"
      17             : #include "fd_pack_harness.h"
      18             : #include "fd_elf_harness.h"
      19             : 
      20             : #include "generated/elf.pb.h"
      21             : #include "generated/invoke.pb.h"
      22             : #include "generated/shred.pb.h"
      23             : #include "generated/vm.pb.h"
      24             : #include "generated/type.pb.h"
      25             : 
      26             : #include <errno.h>
      27             : #include <stdio.h>
      28             : 
      29             : /* FIXME: Spad isn't properly sized out or cleaned up */
      30             : 
      31             : /* This file defines stable APIs for compatibility testing.
      32             : 
      33             :    For the "compat" shared library used by the differential fuzzer,
      34             :    ideally the symbols defined in this file would be the only visible
      35             :    globals.  Unfortunately, we currently export all symbols, which leads
      36             :    to great symbol table bloat from fd_types.c. */
      37             : 
      38             : typedef struct {
      39             :   ulong   struct_size;
      40             :   ulong * hardcoded_features;
      41             :   ulong   hardcoded_features_cnt;
      42             :   ulong * supported_features;
      43             :   ulong   supported_feature_cnt;
      44             : } sol_compat_features_t;
      45             : 
      46             : static sol_compat_features_t features;
      47             : static uchar *               spad_mem;
      48             : static fd_wksp_t *           wksp  = NULL;
      49             : static fd_banks_t *          banks = NULL;
      50             : static fd_bank_t *           bank  = NULL;
      51             : 
      52           0 : #define WKSP_EXECUTE_ALLOC_TAG (2UL)
      53           0 : #define WKSP_INIT_ALLOC_TAG    (3UL)
      54             : 
      55             : void
      56           0 : sol_compat_init( int log_level ) {
      57           0 :   int argc = 1;
      58           0 :   char * argv[2] = { (char *)"fd_exec_sol_compat", NULL };
      59           0 :   char ** argv_ = argv;
      60           0 :   if( !getenv( "FD_LOG_PATH" ) ) {
      61           0 :     setenv( "FD_LOG_PATH", "", 1 );
      62           0 :   }
      63           0 :   fd_log_enable_unclean_exit();
      64           0 :   fd_boot( &argc, &argv_ );
      65           0 :   fd_log_level_logfile_set( log_level );
      66           0 :   fd_log_level_core_set(4);  /* abort on FD_LOG_ERR */
      67             : 
      68           0 :   sol_compat_wksp_init( FD_SHMEM_NORMAL_PAGE_SZ );
      69           0 : }
      70             : 
      71             : fd_wksp_t *
      72           0 : sol_compat_wksp_init( ulong wksp_page_sz ) {
      73           0 :   ulong cpu_idx = fd_tile_cpu_id( fd_tile_idx() );
      74           0 :   if( cpu_idx>=fd_shmem_cpu_cnt() ) cpu_idx = 0UL;
      75           0 :   switch( wksp_page_sz )
      76           0 :   {
      77           0 :   case FD_SHMEM_GIGANTIC_PAGE_SZ:
      78           0 :     wksp = fd_wksp_new_anonymous( FD_SHMEM_GIGANTIC_PAGE_SZ, 6UL, fd_shmem_cpu_idx( fd_shmem_numa_idx( cpu_idx ) ), "wksp", 0UL );
      79           0 :     break;
      80           0 :   case FD_SHMEM_NORMAL_PAGE_SZ:
      81           0 :     wksp = fd_wksp_new_anonymous( FD_SHMEM_NORMAL_PAGE_SZ, 512UL * 512UL * 6UL, fd_shmem_cpu_idx( fd_shmem_numa_idx( cpu_idx ) ), "wksp", 0UL );
      82           0 :     break;
      83           0 :   default:
      84           0 :     FD_LOG_ERR(( "Unsupported page size %lu", wksp_page_sz ));
      85           0 :   }
      86           0 :   FD_TEST( wksp );
      87             : 
      88           0 :   spad_mem = fd_wksp_alloc_laddr( wksp, FD_SPAD_ALIGN, FD_SPAD_FOOTPRINT( FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_FUZZ ), WKSP_INIT_ALLOC_TAG ); /* 4738713960 B */
      89           0 :   FD_TEST( spad_mem );
      90             : 
      91           0 :   ulong        banks_footprint = fd_banks_footprint( 1UL, 1UL );
      92           0 :   uchar *      banks_mem       = fd_wksp_alloc_laddr( wksp, fd_banks_align(), banks_footprint, WKSP_INIT_ALLOC_TAG );
      93           0 :   if( FD_UNLIKELY( !banks_mem ) ) {
      94           0 :     FD_LOG_CRIT(( "Unable to allocate memory for banks" ));
      95           0 :   }
      96             : 
      97           0 :   banks = fd_banks_join( fd_banks_new( banks_mem, 1UL, 1UL ) );
      98           0 :   if( FD_UNLIKELY( !banks ) ) {
      99           0 :     FD_LOG_CRIT(( "Unable to create and join banks" ));
     100           0 :   }
     101           0 :   bank = fd_banks_init_bank( banks, 0UL );
     102           0 :   if( FD_UNLIKELY( !bank ) ) {
     103           0 :     FD_LOG_CRIT(( "Unable to initialize bank" ));
     104           0 :   }
     105             : 
     106           0 :   features.struct_size        = sizeof(sol_compat_features_t);
     107           0 :   features.hardcoded_features = fd_wksp_alloc_laddr( wksp, 8UL, FD_FEATURE_ID_CNT * sizeof(ulong), WKSP_INIT_ALLOC_TAG );
     108           0 :   features.supported_features = fd_wksp_alloc_laddr( wksp, 8UL, FD_FEATURE_ID_CNT * sizeof(ulong), WKSP_INIT_ALLOC_TAG );
     109             : 
     110           0 :   for( const fd_feature_id_t * current_feature = fd_feature_iter_init(); !fd_feature_iter_done( current_feature ); current_feature = fd_feature_iter_next( current_feature ) ) {
     111             :     // Skip reverted features
     112           0 :     if( current_feature->reverted ) continue;
     113             : 
     114             :     // Only hardcode features that are activated on all clusters
     115           0 :     if( current_feature->activated_on_all_clusters ) {
     116           0 :       memcpy( &features.hardcoded_features[features.hardcoded_features_cnt++], &current_feature->id, sizeof(ulong) );
     117           0 :     } else {
     118           0 :       memcpy( &features.supported_features[features.supported_feature_cnt++], &current_feature->id, sizeof(ulong) );
     119           0 :     }
     120           0 :   }
     121             : 
     122           0 :   return wksp;
     123           0 : }
     124             : 
     125             : void
     126           0 : sol_compat_fini( void ) {
     127           0 :   fd_wksp_free_laddr( spad_mem );
     128           0 :   fd_wksp_free_laddr( features.hardcoded_features );
     129           0 :   fd_wksp_free_laddr( features.supported_features );
     130           0 :   fd_wksp_delete_anonymous( wksp );
     131           0 :   wksp     = NULL;
     132           0 :   spad_mem = NULL;
     133           0 : }
     134             : 
     135             : void
     136           0 : sol_compat_check_wksp_usage( void ) {
     137           0 :   fd_wksp_usage_t usage[1];
     138           0 :   ulong tags[1] = { WKSP_EXECUTE_ALLOC_TAG };
     139           0 :   fd_wksp_usage( wksp, tags, 1, usage );
     140           0 :   if( usage->used_sz ) {
     141           0 :     FD_LOG_ERR(( "%lu bytes leaked in %lu allocations", usage->used_sz, usage->used_cnt ));
     142           0 :   }
     143           0 : }
     144             : 
     145             : sol_compat_features_t const *
     146           0 : sol_compat_get_features_v1( void ) {
     147           0 :   return &features;
     148           0 : }
     149             : 
     150             : fd_runtime_fuzz_runner_t *
     151           0 : sol_compat_setup_runner( void ) {
     152             : 
     153             :   // Setup test runner
     154           0 :   void * runner_mem = fd_wksp_alloc_laddr( wksp, fd_runtime_fuzz_runner_align(), fd_runtime_fuzz_runner_footprint(), WKSP_EXECUTE_ALLOC_TAG );
     155           0 :   fd_runtime_fuzz_runner_t * runner = fd_runtime_fuzz_runner_new( runner_mem, spad_mem, banks, bank, WKSP_EXECUTE_ALLOC_TAG );
     156             : 
     157           0 :   char const * solcap_path = getenv( "FD_SOLCAP" );
     158           0 :   if( solcap_path ) {
     159           0 :     runner->solcap_file = fopen( solcap_path, "w" );
     160           0 :     if( FD_UNLIKELY( !runner->solcap_file ) ) {
     161           0 :       FD_LOG_ERR(( "fopen($FD_SOLCAP=%s) failed (%i-%s)", solcap_path, errno, fd_io_strerror( errno ) ));
     162           0 :     }
     163           0 :     FD_LOG_NOTICE(( "Logging to solcap file %s", solcap_path ));
     164             : 
     165           0 :     void * solcap_mem = fd_wksp_alloc_laddr( runner->wksp, fd_solcap_writer_align(), fd_solcap_writer_footprint(), 1UL );
     166           0 :     runner->solcap = fd_solcap_writer_new( solcap_mem );
     167           0 :     FD_TEST( runner->solcap );
     168           0 :     FD_TEST( fd_solcap_writer_init( solcap_mem, runner->solcap_file ) );
     169           0 :   }
     170             : 
     171           0 :   return runner;
     172           0 : }
     173             : 
     174             : void
     175           0 : sol_compat_cleanup_runner( fd_runtime_fuzz_runner_t * runner ) {
     176             :   /* Cleanup test runner */
     177           0 :   if( runner->solcap ) {
     178           0 :     fd_solcap_writer_flush( runner->solcap );
     179           0 :     fd_wksp_free_laddr( fd_solcap_writer_delete( runner->solcap ) );
     180           0 :     runner->solcap = NULL;
     181           0 :     fclose( runner->solcap_file );
     182           0 :     runner->solcap_file = NULL;
     183           0 :   }
     184           0 :   fd_wksp_free_laddr( fd_runtime_fuzz_runner_delete( runner ) );
     185           0 : }
     186             : 
     187             : void *
     188             : sol_compat_decode( void *               decoded,
     189             :                    uchar const *        in,
     190             :                    ulong                in_sz,
     191           0 :                    pb_msgdesc_t const * decode_type ) {
     192           0 :   pb_istream_t istream = pb_istream_from_buffer( in, in_sz );
     193           0 :   int decode_ok = pb_decode_ex( &istream, decode_type, decoded, PB_DECODE_NOINIT );
     194           0 :   if( !decode_ok ) {
     195           0 :     pb_release( decode_type, decoded );
     196           0 :     return NULL;
     197           0 :   }
     198           0 :   return decoded;
     199           0 : }
     200             : 
     201             : void const *
     202             : sol_compat_encode( uchar *              out,
     203             :                    ulong *              out_sz,
     204             :                    void const *         to_encode,
     205           0 :                    pb_msgdesc_t const * encode_type ) {
     206           0 :   pb_ostream_t ostream = pb_ostream_from_buffer( out, *out_sz );
     207           0 :   int encode_ok = pb_encode( &ostream, encode_type, to_encode );
     208           0 :   if( !encode_ok ) {
     209           0 :     return NULL;
     210           0 :   }
     211           0 :   *out_sz = ostream.bytes_written;
     212           0 :   return to_encode;
     213           0 : }
     214             : 
     215             : typedef ulong( exec_test_run_fn_t )( fd_runtime_fuzz_runner_t *,
     216             :                                      void const *,
     217             :                                      void **,
     218             :                                      void *,
     219             :                                      ulong );
     220             : 
     221             : void
     222             : sol_compat_execute_wrapper( fd_runtime_fuzz_runner_t * runner,
     223             :                             void * input,
     224             :                             void ** output,
     225           0 :                             exec_test_run_fn_t * exec_test_run_fn ) {
     226             : 
     227           0 :   ulong out_bufsz = 100000000;  /* 100 MB */
     228           0 :   void * out0 = fd_spad_alloc( runner->spad, 1UL, out_bufsz );
     229           0 :   FD_TEST( out_bufsz <= fd_spad_alloc_max( runner->spad, 1UL ) );
     230             : 
     231           0 :   ulong out_used = exec_test_run_fn( runner, input, output, out0, out_bufsz );
     232           0 :   if( FD_UNLIKELY( !out_used ) ) {
     233           0 :     *output = NULL;
     234           0 :   }
     235             : 
     236           0 : }
     237             : 
     238             : /*
     239             :  * fixtures
     240             :  */
     241             : 
     242             : int
     243             : sol_compat_cmp_binary_strict( void const * effects,
     244             :                               void const * expected,
     245             :                               pb_msgdesc_t const * encode_type,
     246           0 :                               fd_spad_t * spad ) {
     247           0 : #define MAX_SZ 32*1024*1024
     248           0 : FD_SPAD_FRAME_BEGIN( spad ) {
     249           0 :   if( effects==NULL ) {
     250           0 :     FD_LOG_WARNING(( "No output effects" ));
     251           0 :     return 0;
     252           0 :   }
     253             : 
     254             :   /* Note: Most likely this spad allocation won't fail. If it does, you may need to bump
     255             :      the allocated spad memory amount in fd_exec_sol_compat.c. */
     256           0 :   ulong out_sz = MAX_SZ;
     257           0 :   uchar * out = fd_spad_alloc( spad, 1UL, out_sz );
     258           0 :   if( !sol_compat_encode( out, &out_sz, effects, encode_type ) ) {
     259           0 :     FD_LOG_WARNING(( "Error encoding effects" ));
     260           0 :     return 0;
     261           0 :   }
     262             : 
     263           0 :   ulong exp_sz = MAX_SZ;
     264           0 :   uchar * exp = fd_spad_alloc( spad, 1UL, exp_sz );
     265           0 :   if( !sol_compat_encode( exp, &exp_sz, expected, encode_type ) ) {
     266           0 :     FD_LOG_WARNING(( "Error encoding expected" ));
     267           0 :     return 0;
     268           0 :   }
     269             : 
     270           0 :   if( out_sz!=exp_sz ) {
     271           0 :     FD_LOG_WARNING(( "Binary cmp failed: different size. out_sz=%lu exp_sz=%lu", out_sz, exp_sz  ));
     272           0 :     return 0;
     273           0 :   }
     274           0 :   if( !fd_memeq( out, exp, out_sz ) ) {
     275           0 :     FD_LOG_WARNING(( "Binary cmp failed: different values." ));
     276           0 :     return 0;
     277           0 :   }
     278             : 
     279           0 :   return 1;
     280           0 : } FD_SPAD_FRAME_END;
     281           0 : #undef MAX_SIZE
     282           0 : }
     283             : 
     284             : static int
     285             : _diff_txn_acct( fd_exec_test_acct_state_t * expected,
     286           0 :                 fd_exec_test_acct_state_t * actual ) {
     287             :   /* AcctState -> address (This must hold true when calling this function!) */
     288           0 :   assert( fd_memeq( expected->address, actual->address, sizeof(fd_pubkey_t) ) );
     289             : 
     290             :   /* AcctState -> lamports */
     291           0 :   if( expected->lamports != actual->lamports ) {
     292           0 :     FD_LOG_WARNING(( "Lamports mismatch: expected=%lu actual=%lu", expected->lamports, actual->lamports ));
     293           0 :     return 0;
     294           0 :   }
     295             : 
     296             :   /* AcctState -> data */
     297           0 :   if( expected->data != NULL || actual->data != NULL ) {
     298           0 :     if( expected->data == NULL ) {
     299           0 :       FD_LOG_WARNING(( "Expected account data is NULL, actual is non-NULL" ));
     300           0 :       return 0;
     301           0 :     }
     302             : 
     303           0 :     if( actual->data == NULL ) {
     304           0 :       FD_LOG_WARNING(( "Expected account data is NULL, actual is non-NULL" ));
     305           0 :       return 0;
     306           0 :     }
     307             : 
     308           0 :     if( expected->data->size != actual->data->size ) {
     309           0 :       FD_LOG_WARNING(( "Account data size mismatch: expected=%u actual=%u", expected->data->size, actual->data->size ));
     310           0 :       return 0;
     311           0 :     }
     312             : 
     313           0 :     if( !fd_memeq( expected->data->bytes, actual->data->bytes, expected->data->size ) ) {
     314           0 :       FD_LOG_WARNING(( "Account data mismatch" ));
     315           0 :       return 0;
     316           0 :     }
     317           0 :   }
     318             : 
     319             :   /* AcctState -> executable */
     320           0 :   if( expected->executable != actual->executable ) {
     321           0 :     FD_LOG_WARNING(( "Executable mismatch: expected=%d actual=%d", expected->executable, actual->executable ));
     322           0 :     return 0;
     323           0 :   }
     324             : 
     325             :   /* AcctState -> rent_epoch */
     326           0 :   if( expected->rent_epoch != actual->rent_epoch ) {
     327           0 :     FD_LOG_WARNING(( "Rent epoch mismatch: expected=%lu actual=%lu", expected->rent_epoch, actual->rent_epoch ));
     328           0 :     return 0;
     329           0 :   }
     330             : 
     331             :   /* AcctState -> owner */
     332           0 :   if( !fd_memeq( expected->owner, actual->owner, sizeof(fd_pubkey_t) ) ) {
     333           0 :     char a[ FD_BASE58_ENCODED_32_SZ ];
     334           0 :     char b[ FD_BASE58_ENCODED_32_SZ ];
     335           0 :     FD_LOG_WARNING(( "Owner mismatch: expected=%s, actual=%s", fd_acct_addr_cstr( a, expected->owner ), fd_acct_addr_cstr( b, actual->owner ) ));
     336           0 :     return 0;
     337           0 :   }
     338             : 
     339           0 :   return 1;
     340           0 : }
     341             : 
     342             : 
     343             : static int
     344             : _diff_resulting_states( fd_exec_test_resulting_state_t *  expected,
     345           0 :                         fd_exec_test_resulting_state_t *  actual ) {
     346             :   // Verify that the number of accounts are the same
     347           0 :   if( expected->acct_states_count != actual->acct_states_count ) {
     348           0 :     FD_LOG_WARNING(( "Account states count mismatch: expected=%u actual=%u", expected->acct_states_count, actual->acct_states_count ));
     349           0 :     return 0;
     350           0 :   }
     351             : 
     352             :   // Verify that the account states are the same
     353           0 :   for( ulong i = 0; i < expected->acct_states_count; ++i ) {
     354           0 :     for( ulong j = 0; j < actual->acct_states_count; ++j ) {
     355           0 :       if( fd_memeq( expected->acct_states[i].address, actual->acct_states[j].address, sizeof(fd_pubkey_t) ) ) {
     356           0 :         if( !_diff_txn_acct( &expected->acct_states[i], &actual->acct_states[j] ) ) {
     357           0 :           return 0;
     358           0 :         }
     359           0 :       }
     360           0 :     }
     361           0 :   }
     362             : 
     363             :   // TODO: resulting_state -> rent_debits, resulting_state->transaction_rent
     364           0 :   return 1;
     365           0 : }
     366             : 
     367             : int
     368             : sol_compat_cmp_txn( fd_exec_test_txn_result_t *  expected,
     369           0 :                     fd_exec_test_txn_result_t *  actual ) {
     370             :   /* TxnResult -> executed */
     371           0 :   if( expected->executed != actual->executed ) {
     372           0 :     FD_LOG_WARNING(( "Executed mismatch: expected=%d actual=%d", expected->executed, actual->executed ));
     373           0 :     return 0;
     374           0 :   }
     375             : 
     376             :   /* TxnResult -> sanitization_error */
     377           0 :   if( expected->sanitization_error != actual->sanitization_error ) {
     378           0 :     FD_LOG_WARNING(( "Sanitization error mismatch: expected=%d actual=%d", expected->sanitization_error, actual->sanitization_error ));
     379           0 :     return 0;
     380           0 :   }
     381             : 
     382             :   /* TxnResult -> resulting_state */
     383           0 :   if( !_diff_resulting_states( &expected->resulting_state, &actual->resulting_state ) ) {
     384           0 :     return 0;
     385           0 :   }
     386             : 
     387             :   /* TxnResult -> rent */
     388           0 :   if( expected->rent != actual->rent ) {
     389           0 :     FD_LOG_WARNING(( "Rent mismatch: expected=%lu actual=%lu", expected->rent, actual->rent ));
     390           0 :     return 0;
     391           0 :   }
     392             : 
     393             :   /* TxnResult -> is_ok */
     394           0 :   if( expected->is_ok != actual->is_ok ) {
     395           0 :     FD_LOG_WARNING(( "Is ok mismatch: expected=%d actual=%d", expected->is_ok, actual->is_ok ));
     396           0 :     return 0;
     397           0 :   }
     398             : 
     399             :   /* TxnResult -> status */
     400           0 :   if( expected->status != actual->status ) {
     401           0 :     FD_LOG_WARNING(( "Status mismatch: expected=%u actual=%u", expected->status, actual->status ));
     402           0 :     return 0;
     403           0 :   }
     404             : 
     405             :   /* TxnResult -> instruction_error */
     406           0 :   if( expected->instruction_error != actual->instruction_error ) {
     407           0 :     FD_LOG_WARNING(( "Instruction error mismatch: expected=%u actual=%u", expected->instruction_error, actual->instruction_error ));
     408           0 :     return 0;
     409           0 :   }
     410             : 
     411           0 :   if( expected->instruction_error ) {
     412             :     /* TxnResult -> instruction_error_index */
     413           0 :     if( expected->instruction_error_index != actual->instruction_error_index ) {
     414           0 :       FD_LOG_WARNING(( "Instruction error index mismatch: expected=%u actual=%u", expected->instruction_error_index, actual->instruction_error_index ));
     415           0 :       return 0;
     416           0 :     }
     417             : 
     418             :     /* TxnResult -> custom_error */
     419           0 :     if( expected->instruction_error == (ulong) -FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && expected->custom_error != actual->custom_error ) {
     420           0 :       FD_LOG_WARNING(( "Custom error mismatch: expected=%u actual=%u", expected->custom_error, actual->custom_error ));
     421           0 :       return 0;
     422           0 :     }
     423           0 :   }
     424             : 
     425             :   /* TxnResult -> return_data */
     426           0 :   if( expected->return_data != NULL || actual->return_data != NULL ) {
     427           0 :     if( expected->return_data == NULL ) {
     428           0 :       FD_LOG_WARNING(( "Expected return data is NULL, actual is non-NULL" ));
     429           0 :       return 0;
     430           0 :     }
     431             : 
     432           0 :     if( actual->return_data == NULL ) {
     433           0 :       FD_LOG_WARNING(( "Expected return data is NULL, actual is non-NULL" ));
     434           0 :       return 0;
     435           0 :     }
     436             : 
     437           0 :     if( expected->return_data->size != actual->return_data->size ) {
     438           0 :       FD_LOG_WARNING(( "Return data size mismatch: expected=%u actual=%u", expected->return_data->size, actual->return_data->size ));
     439           0 :       return 0;
     440           0 :     }
     441             : 
     442           0 :     if( !fd_memeq( expected->return_data->bytes, actual->return_data->bytes, expected->return_data->size ) ) {
     443           0 :       FD_LOG_WARNING(( "Return data mismatch" ));
     444           0 :       return 0;
     445           0 :     }
     446           0 :   }
     447             : 
     448             :   /* TxnResult -> executed_units */
     449           0 :   if( expected->executed_units != actual->executed_units ) {
     450           0 :     FD_LOG_WARNING(( "Executed units mismatch: expected=%lu actual=%lu", expected->executed_units, actual->executed_units ));
     451           0 :     return 0;
     452           0 :   }
     453             : 
     454             :   /* TxnResult -> fee_details */
     455           0 :   if( expected->has_fee_details != actual->has_fee_details ) {
     456           0 :     FD_LOG_WARNING(( "Has fee details mismatch: expected=%d actual=%d", expected->has_fee_details, actual->has_fee_details ));
     457           0 :     return 0;
     458           0 :   }
     459             : 
     460           0 :   if( expected->has_fee_details ) {
     461           0 :     if( expected->fee_details.transaction_fee != actual->fee_details.transaction_fee ) {
     462           0 :       FD_LOG_WARNING(( "Transaction fee mismatch: expected=%lu actual=%lu", expected->fee_details.transaction_fee, actual->fee_details.transaction_fee ));
     463           0 :       return 0;
     464           0 :     }
     465             : 
     466           0 :     if( expected->fee_details.prioritization_fee != actual->fee_details.prioritization_fee ) {
     467           0 :       FD_LOG_WARNING(( "Priority fee mismatch: expected=%lu actual=%lu", expected->fee_details.prioritization_fee, actual->fee_details.prioritization_fee ));
     468           0 :       return 0;
     469           0 :     }
     470           0 :   }
     471             : 
     472             :   /* TxnResult -> loaded_accounts_data_size */
     473           0 :   if( expected->loaded_accounts_data_size != actual->loaded_accounts_data_size ) {
     474           0 :     FD_LOG_WARNING(( "Loaded accounts data size mismatch: expected=%lu actual=%lu", expected->loaded_accounts_data_size, actual->loaded_accounts_data_size ));
     475           0 :     return 0;
     476           0 :   }
     477             : 
     478           0 :   return 1;
     479           0 : }
     480             : 
     481             : int
     482             : sol_compat_instr_fixture( fd_runtime_fuzz_runner_t * runner,
     483             :                           uchar const *              in,
     484           0 :                           ulong                      in_sz ) {
     485             :   // Decode fixture
     486           0 :   fd_exec_test_instr_fixture_t fixture[1] = {0};
     487           0 :   void * res = sol_compat_decode( &fixture, in, in_sz, &fd_exec_test_instr_fixture_t_msg );
     488           0 :   if ( res==NULL ) {
     489           0 :     FD_LOG_WARNING(( "Invalid instr fixture." ));
     490           0 :     return 0;
     491           0 :   }
     492             : 
     493           0 :   int ok = 0;
     494             :   // Execute
     495           0 :   void * output = NULL;
     496           0 :   sol_compat_execute_wrapper( runner, &fixture->input, &output, fd_runtime_fuzz_instr_run );
     497             : 
     498             :   // Compare effects
     499           0 :   ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_instr_effects_t_msg, runner->spad );
     500             : 
     501             :   // Cleanup
     502           0 :   pb_release( &fd_exec_test_instr_fixture_t_msg, fixture );
     503           0 :   return ok;
     504           0 : }
     505             : 
     506             : int
     507             : sol_compat_txn_fixture( fd_runtime_fuzz_runner_t * runner,
     508             :                         uchar const *              in,
     509           0 :                         ulong                      in_sz ) {
     510             :   // Decode fixture
     511           0 :   fd_exec_test_txn_fixture_t fixture[1] = {0};
     512           0 :   void * res = sol_compat_decode( &fixture, in, in_sz, &fd_exec_test_txn_fixture_t_msg );
     513           0 :   if ( res==NULL ) {
     514           0 :     FD_LOG_WARNING(( "Invalid txn fixture." ));
     515           0 :     return 0;
     516           0 :   }
     517             : 
     518           0 :   int ok = 0;
     519           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     520             :     // Execute
     521           0 :     void * output = NULL;
     522           0 :     sol_compat_execute_wrapper( runner, &fixture->input, &output, fd_runtime_fuzz_txn_run );
     523           0 :     if( FD_LIKELY( output ) ) {
     524             :       // Compare effects
     525           0 :       fd_exec_test_txn_result_t * effects = output;
     526           0 :       ok = sol_compat_cmp_txn( &fixture->output, effects );
     527           0 :     }
     528           0 :   } FD_SPAD_FRAME_END;
     529             : 
     530             :   // Cleanup
     531           0 :   pb_release( &fd_exec_test_txn_fixture_t_msg, fixture );
     532           0 :   return ok;
     533           0 : }
     534             : 
     535             : int
     536             : sol_compat_block_fixture( fd_runtime_fuzz_runner_t * runner,
     537             :                           uchar const *              in,
     538           0 :                           ulong                      in_sz ) {
     539             :   // Decode fixture
     540           0 :   fd_exec_test_block_fixture_t fixture[1] = {0};
     541           0 :   void * res = sol_compat_decode( &fixture, in, in_sz, &fd_exec_test_block_fixture_t_msg );
     542           0 :   if ( res==NULL ) {
     543           0 :     FD_LOG_WARNING(( "Invalid block fixture." ));
     544           0 :     return 0;
     545           0 :   }
     546             : 
     547           0 :   int ok = 0;
     548           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     549             :   // Execute
     550           0 :   void * output = NULL;
     551           0 :   sol_compat_execute_wrapper( runner, &fixture->input, &output, fd_runtime_fuzz_block_run );
     552             : 
     553             :   // Compare effects
     554           0 :   ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_block_effects_t_msg, runner->spad );
     555           0 :   } FD_SPAD_FRAME_END;
     556             : 
     557             :   // Cleanup
     558           0 :   pb_release( &fd_exec_test_block_fixture_t_msg, fixture );
     559           0 :   return ok;
     560           0 : }
     561             : 
     562             : int
     563             : sol_compat_elf_loader_fixture( fd_runtime_fuzz_runner_t * runner,
     564             :                                uchar const *              in,
     565           0 :                                ulong                      in_sz ) {
     566             :   // Decode fixture
     567           0 :   fd_exec_test_elf_loader_fixture_t fixture[1] = {0};
     568           0 :   void * res = sol_compat_decode( &fixture, in, in_sz, &fd_exec_test_elf_loader_fixture_t_msg );
     569           0 :   if ( res==NULL ) {
     570           0 :     FD_LOG_WARNING(( "Invalid elf_loader fixture." ));
     571           0 :     return 0;
     572           0 :   }
     573           0 :   int ok = 0;
     574           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     575             :   // Execute
     576           0 :   void * output = NULL;
     577           0 :   sol_compat_execute_wrapper( runner, &fixture->input, &output, fd_runtime_fuzz_sbpf_load_run );
     578             : 
     579             :   // Compare effects
     580           0 :   ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_elf_loader_effects_t_msg, runner->spad );
     581           0 :   } FD_SPAD_FRAME_END;
     582             : 
     583             :   // Cleanup
     584           0 :   pb_release( &fd_exec_test_elf_loader_fixture_t_msg, fixture );
     585           0 :   return ok;
     586           0 : }
     587             : 
     588             : int
     589             : sol_compat_syscall_fixture( fd_runtime_fuzz_runner_t * runner,
     590             :                             uchar const *              in,
     591           0 :                             ulong                      in_sz ) {
     592             :   // Decode fixture
     593           0 :   fd_exec_test_syscall_fixture_t fixture[1] = {0};
     594           0 :   if ( !sol_compat_decode( &fixture, in, in_sz, &fd_exec_test_syscall_fixture_t_msg ) ) {
     595           0 :     FD_LOG_WARNING(( "Invalid syscall fixture." ));
     596           0 :     return 0;
     597           0 :   }
     598             : 
     599           0 :   int ok = 0;
     600           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     601             :   // Execute
     602           0 :   void * output = NULL;
     603           0 :   sol_compat_execute_wrapper( runner, &fixture->input, &output, fd_runtime_fuzz_vm_syscall_run );
     604             : 
     605             :   // Compare effects
     606           0 :   ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_syscall_effects_t_msg, runner->spad );
     607           0 :   } FD_SPAD_FRAME_END;
     608             : 
     609             :   // Cleanup
     610           0 :   pb_release( &fd_exec_test_syscall_fixture_t_msg, fixture );
     611           0 :   return ok;
     612           0 : }
     613             : 
     614             : int
     615             : sol_compat_vm_interp_fixture( fd_runtime_fuzz_runner_t * runner,
     616             :                               uchar const *              in,
     617           0 :                               ulong                      in_sz ) {
     618             :   // Decode fixture
     619           0 :   fd_exec_test_syscall_fixture_t fixture[1] = {0};
     620           0 :   if ( !sol_compat_decode( &fixture, in, in_sz, &fd_exec_test_syscall_fixture_t_msg ) ) {
     621           0 :     FD_LOG_WARNING(( "Invalid syscall fixture." ));
     622           0 :     return 0;
     623           0 :   }
     624             : 
     625           0 :   int ok = 0;
     626           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     627             :   // Execute
     628           0 :   void * output = NULL;
     629           0 :   sol_compat_execute_wrapper( runner, &fixture->input, &output, (exec_test_run_fn_t *)fd_runtime_fuzz_vm_interp_run );
     630             : 
     631             :   // Compare effects
     632           0 :   ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_syscall_effects_t_msg, runner->spad );
     633           0 :   } FD_SPAD_FRAME_END;
     634             : 
     635             :   // Cleanup
     636           0 :   pb_release( &fd_exec_test_syscall_fixture_t_msg, fixture );
     637           0 :   return ok;
     638           0 : }
     639             : 
     640             : /*
     641             :  * execute_v1
     642             :  */
     643             : 
     644             : int
     645             : sol_compat_instr_execute_v1( uchar *       out,
     646             :                              ulong *       out_sz,
     647             :                              uchar const * in,
     648           0 :                              ulong         in_sz ) {
     649             :   // Setup
     650           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner();
     651             : 
     652             :   // Decode context
     653           0 :   fd_exec_test_instr_context_t input[1] = {0};
     654           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_instr_context_t_msg );
     655           0 :   if ( res==NULL ) {
     656           0 :     sol_compat_cleanup_runner( runner );
     657           0 :     return 0;
     658           0 :   }
     659             : 
     660           0 :   int ok = 0;
     661           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     662             :   // Execute
     663           0 :   void * output = NULL;
     664           0 :   sol_compat_execute_wrapper( runner, input, &output, fd_runtime_fuzz_instr_run );
     665             : 
     666             :   // Encode effects
     667           0 :   if( output ) {
     668           0 :     ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_instr_effects_t_msg );
     669           0 :   }
     670           0 :   } FD_SPAD_FRAME_END;
     671             : 
     672             :   // Cleanup
     673           0 :   pb_release( &fd_exec_test_instr_context_t_msg, input );
     674           0 :   sol_compat_cleanup_runner( runner );
     675             : 
     676             :   // Check wksp usage is 0
     677           0 :   sol_compat_check_wksp_usage();
     678             : 
     679           0 :   return ok;
     680           0 : }
     681             : 
     682             : int
     683             : sol_compat_txn_execute_v1( uchar *       out,
     684             :                            ulong *       out_sz,
     685             :                            uchar const * in,
     686           0 :                            ulong         in_sz ) {
     687             :   // Setup
     688           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner();
     689             : 
     690             :   // Decode context
     691           0 :   fd_exec_test_txn_context_t input[1] = {0};
     692           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_txn_context_t_msg );
     693           0 :   if ( res==NULL ) {
     694           0 :     sol_compat_cleanup_runner( runner );
     695           0 :     return 0;
     696           0 :   }
     697             : 
     698           0 :   int ok = 0;
     699           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     700             :   // Execute
     701           0 :   void * output = NULL;
     702           0 :   sol_compat_execute_wrapper( runner, input, &output, fd_runtime_fuzz_txn_run );
     703             : 
     704             :   // Encode effects
     705           0 :   if( output ) {
     706           0 :     ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_txn_result_t_msg );
     707           0 :   }
     708           0 :   } FD_SPAD_FRAME_END;
     709             : 
     710             :   // Cleanup
     711           0 :   pb_release( &fd_exec_test_txn_context_t_msg, input );
     712           0 :   sol_compat_cleanup_runner( runner );
     713             : 
     714             :   // Check wksp usage is 0
     715           0 :   sol_compat_check_wksp_usage();
     716           0 :   return ok;
     717           0 : }
     718             : 
     719             : int
     720             : sol_compat_block_execute_v1( uchar *       out,
     721             :                              ulong *       out_sz,
     722             :                              uchar const * in,
     723           0 :                              ulong         in_sz ) {
     724             :   // Setup
     725           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner();
     726             : 
     727             :   // Decode context
     728           0 :   fd_exec_test_block_context_t input[1] = {0};
     729           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_block_context_t_msg );
     730           0 :   if ( res==NULL ) {
     731           0 :     sol_compat_cleanup_runner( runner );
     732           0 :     return 0;
     733           0 :   }
     734             : 
     735           0 :   int ok = 0;
     736           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     737           0 :     void * output = NULL;
     738             : 
     739             :     // Execute
     740           0 :     sol_compat_execute_wrapper( runner, input, &output, fd_runtime_fuzz_block_run );
     741             : 
     742             :     // Encode effects
     743           0 :     if( output ) {
     744           0 :       ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_block_effects_t_msg );
     745           0 :     }
     746           0 :   } FD_SPAD_FRAME_END;
     747             : 
     748             :   // Cleanup
     749           0 :   pb_release( &fd_exec_test_block_context_t_msg, input );
     750           0 :   sol_compat_cleanup_runner( runner );
     751             : 
     752             :   // Check wksp usage is 0
     753           0 :   sol_compat_check_wksp_usage();
     754             : 
     755           0 :   return ok;
     756           0 : }
     757             : 
     758             : int
     759             : sol_compat_elf_loader_v1( uchar *       out,
     760             :                           ulong *       out_sz,
     761             :                           uchar const * in,
     762           0 :                           ulong         in_sz ) {
     763             :   // Setup
     764           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner();
     765             : 
     766             :   // Decode context
     767           0 :   fd_exec_test_elf_loader_ctx_t input[1] = {0};
     768           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_elf_loader_ctx_t_msg );
     769           0 :   if ( res==NULL ) {
     770           0 :     sol_compat_cleanup_runner( runner );
     771           0 :     return 0;
     772           0 :   }
     773             : 
     774           0 :   int ok = 0;
     775           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     776           0 :     void * output = NULL;
     777             : 
     778             :     // Execute
     779           0 :     sol_compat_execute_wrapper( runner, input, &output, fd_runtime_fuzz_sbpf_load_run );
     780             : 
     781             :     // Encode effects
     782           0 :     if( output ) {
     783           0 :       ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_elf_loader_effects_t_msg );
     784           0 :     }
     785           0 :   } FD_SPAD_FRAME_END;
     786             : 
     787             :   // Cleanup
     788           0 :   pb_release( &fd_exec_test_elf_loader_ctx_t_msg, input );
     789           0 :   sol_compat_cleanup_runner( runner );
     790             : 
     791             :   // Check wksp usage is 0
     792           0 :   sol_compat_check_wksp_usage();
     793             : 
     794           0 :   return ok;
     795           0 : }
     796             : 
     797             : int
     798             : sol_compat_vm_syscall_execute_v1( uchar *       out,
     799             :                                   ulong *       out_sz,
     800             :                                   uchar const * in,
     801           0 :                                   ulong         in_sz ) {
     802             :   // Setup
     803           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner();
     804             : 
     805             :   // Decode context
     806           0 :   fd_exec_test_syscall_context_t input[1] = {0};
     807           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_syscall_context_t_msg );
     808           0 :   if ( res==NULL ) {
     809           0 :     sol_compat_cleanup_runner( runner );
     810           0 :     return 0;
     811           0 :   }
     812             : 
     813           0 :   int ok = 0;
     814           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     815             :   // Execute
     816           0 :   void * output = NULL;
     817           0 :   sol_compat_execute_wrapper( runner, input, &output, fd_runtime_fuzz_vm_syscall_run );
     818             : 
     819             :   // Encode effects
     820           0 :   if( output ) {
     821           0 :     ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_syscall_effects_t_msg );
     822           0 :   }
     823           0 :   } FD_SPAD_FRAME_END;
     824             : 
     825             :   // Cleanup
     826           0 :   pb_release( &fd_exec_test_syscall_context_t_msg, input );
     827           0 :   sol_compat_cleanup_runner( runner );
     828             : 
     829             :   // Check wksp usage is 0
     830           0 :   sol_compat_check_wksp_usage();
     831             : 
     832           0 :   return ok;
     833           0 : }
     834             : 
     835             : int
     836             : sol_compat_vm_interp_v1( uchar *       out,
     837             :                          ulong *       out_sz,
     838             :                          uchar const * in,
     839           0 :                          ulong         in_sz ) {
     840             :   // Setup
     841           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner();
     842             : 
     843             :   // Decode context
     844           0 :   fd_exec_test_syscall_context_t input[1] = {0};
     845           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_syscall_context_t_msg );
     846           0 :   if ( res==NULL ) {
     847           0 :     sol_compat_cleanup_runner( runner );
     848           0 :     return 0;
     849           0 :   }
     850             : 
     851           0 :   int ok = 0;
     852             : 
     853           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     854             :   // Execute
     855           0 :   void * output = NULL;
     856           0 :   sol_compat_execute_wrapper( runner, input, &output, (exec_test_run_fn_t *)fd_runtime_fuzz_vm_interp_run );
     857             : 
     858             :   // Encode effects
     859           0 :   if( output ) {
     860           0 :     ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_syscall_effects_t_msg );
     861           0 :   }
     862           0 :   } FD_SPAD_FRAME_END;
     863             : 
     864             :   // Cleanup
     865           0 :   pb_release( &fd_exec_test_syscall_context_t_msg, input );
     866           0 :   sol_compat_cleanup_runner( runner );
     867             : 
     868             :   // Check wksp usage is 0
     869           0 :   sol_compat_check_wksp_usage();
     870             : 
     871           0 :   return ok;
     872           0 : }
     873             : 
     874             : int sol_compat_shred_parse_v1( uchar *       out,
     875             :                                ulong *       out_sz,
     876             :                                uchar const * in,
     877           0 :                                ulong         in_sz ) {
     878           0 :     fd_exec_test_shred_binary_t input[1] = {0};
     879           0 :     void                      * res      = sol_compat_decode( &input, in, in_sz, &fd_exec_test_shred_binary_t_msg );
     880           0 :     if( FD_UNLIKELY( res==NULL ) ) {
     881           0 :         return 0;
     882           0 :     }
     883           0 :     if( FD_UNLIKELY( input[0].data==NULL ) ) {
     884           0 :         pb_release( &fd_exec_test_shred_binary_t_msg, input );
     885           0 :         return 0;
     886           0 :     }
     887           0 :     fd_exec_test_accepts_shred_t output[1] = {0};
     888           0 :     output[0].valid                        = !!fd_shred_parse( input[0].data->bytes, input[0].data->size );
     889           0 :     pb_release( &fd_exec_test_shred_binary_t_msg, input );
     890           0 :     return !!sol_compat_encode( out, out_sz, output, &fd_exec_test_accepts_shred_t_msg );
     891           0 : }
     892             : 
     893             : int
     894             : sol_compat_pack_compute_budget_v1( uchar *       out,
     895             :                                    ulong *       out_sz,
     896             :                                    uchar const * in,
     897           0 :                                    ulong         in_sz ) {
     898           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner( );
     899             : 
     900           0 :   fd_exec_test_pack_compute_budget_context_t input[1] = {0};
     901           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_pack_compute_budget_context_t_msg );
     902           0 :   if( res==NULL ) {
     903           0 :     sol_compat_cleanup_runner( runner );
     904           0 :     return 0;
     905           0 :   }
     906             : 
     907           0 :   int ok = 0;
     908           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     909           0 :   void * output = NULL;
     910           0 :   sol_compat_execute_wrapper( runner, input, &output, fd_runtime_fuzz_pack_cpb_run );
     911             : 
     912           0 :   if( output ) {
     913           0 :     ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_pack_compute_budget_effects_t_msg );
     914           0 :   }
     915           0 :   } FD_SPAD_FRAME_END;
     916             : 
     917           0 :   pb_release( &fd_exec_test_pack_compute_budget_context_t_msg, input );
     918           0 :   sol_compat_cleanup_runner( runner );
     919             : 
     920             :   // Check wksp usage is 0
     921           0 :   sol_compat_check_wksp_usage();
     922           0 :   return ok;
     923           0 : }
     924             : 
     925             : int
     926             : sol_compat_type_execute_v1( uchar *       out,
     927             :                             ulong *       out_sz,
     928             :                             uchar const * in,
     929           0 :                             ulong         in_sz ) {
     930             :   // Setup
     931           0 :   fd_runtime_fuzz_runner_t * runner = sol_compat_setup_runner();
     932             :   // Decode context
     933           0 :   fd_exec_test_type_context_t input[1] = {0};
     934           0 :   void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_type_context_t_msg );
     935           0 :   if( res==NULL ) {
     936           0 :     sol_compat_cleanup_runner( runner );
     937           0 :     return 0;
     938           0 :   }
     939             : 
     940           0 :   int ok = 0;
     941           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     942             : 
     943           0 :     void * output = NULL;
     944           0 :     sol_compat_execute_wrapper( runner, input, &output, fd_runtime_fuzz_type_run );
     945           0 :     if( output ) {
     946           0 :       ok = !!sol_compat_encode( out, out_sz, output, &fd_exec_test_type_effects_t_msg );
     947           0 :     }
     948             : 
     949           0 :   } FD_SPAD_FRAME_END;
     950             : 
     951           0 :   pb_release( &fd_exec_test_type_context_t_msg, input );
     952           0 :   sol_compat_cleanup_runner( runner );
     953             : 
     954           0 :   sol_compat_check_wksp_usage();
     955             : 
     956           0 :   return ok;
     957           0 : }

Generated by: LCOV version 1.14