LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_exec_sol_compat.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 522 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 29 0.0 %

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

Generated by: LCOV version 1.14