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: 186 503 37.0 %
Date: 2025-01-08 12:08:44 Functions: 17 28 60.7 %

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

Generated by: LCOV version 1.14