LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_bundle_harness.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 266 0.0 %
Date: 2026-07-17 05:22:26 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "fd_bundle_harness.h"
       2             : #include "fd_solfuzz_private.h"
       3             : #include "fd_txn_harness.h"
       4             : #include "fd_dump_pb.h"
       5             : #include "generated/bundle.pb.h"
       6             : #include "../fd_cost_tracker.h"
       7             : #include "../fd_slot_params.h"
       8             : #include "../fd_runtime.h"
       9             : #include "../sysvar/fd_sysvar_cache.h"
      10             : #include "../sysvar/fd_sysvar_epoch_schedule.h"
      11             : #include "../../progcache/fd_progcache_admin.h"
      12             : #include "../../log_collector/fd_log_collector.h"  /* IWYU pragma: keep */
      13             : #include "../../stakes/fd_stakes.h"
      14             : 
      15             : static void
      16           0 : fd_solfuzz_bundle_ctx_destroy( fd_solfuzz_runner_t * runner ) {
      17           0 :   if( runner->bank->new_votes_fork_id!=USHORT_MAX ) {
      18           0 :     fd_new_votes_evict_fork( fd_bank_new_votes( runner->bank ), runner->bank->new_votes_fork_id );
      19           0 :     runner->bank->new_votes_fork_id = USHORT_MAX;
      20           0 :   }
      21           0 :   fd_banks_stake_delegations_evict_bank_fork( runner->banks, runner->bank );
      22             : 
      23           0 :   fd_progcache_reset( runner->progcache->join );
      24             : 
      25             :   /* Purge the fork attached in ctx_create so the accdb fork pool slot
      26             :      is released back for reuse.  Without this, repeated harness
      27             :      invocations (e.g. under a fuzzer) exhaust max_live_slots. */
      28           0 :   fd_accdb_purge( runner->accdb, runner->bank->accdb_fork_id );
      29           0 :   int charge_busy = 0;
      30           0 :   fd_accdb_background( runner->accdb, &charge_busy );
      31             : 
      32             :   /* Keep the runner reusable across many bundle inputs. */
      33           0 :   fd_alloc_compact( runner->progcache->join->alloc );
      34           0 : }
      35             : 
      36             : static fd_txn_p_t *
      37             : fd_solfuzz_pb_bundle_ctx_create( fd_solfuzz_runner_t *                 runner,
      38             :                                  fd_exec_test_bundle_context_t const * test_ctx,
      39           0 :                                  ulong *                               out_txn_cnt ) {
      40           0 :   ulong txn_cnt = (ulong)test_ctx->txns_count;
      41           0 :   FD_TEST( txn_cnt<=FD_PACK_MAX_TXN_PER_BUNDLE );
      42             : 
      43           0 :   fd_accdb_t * accdb = runner->accdb;
      44             : 
      45           0 :   ulong slot = fd_solfuzz_pb_get_slot( test_ctx->account_shared_data, test_ctx->account_shared_data_count );
      46             : 
      47             :   /* Initialize bank from input txn bank */
      48           0 :   fd_banks_clear_bank( runner->banks, runner->bank, 2048UL );
      49             : 
      50           0 :   runner->bank->f.slot = slot;
      51           0 :   runner->bank->bank_seq = runner->bank->idx;
      52             : 
      53           0 :   runner->bank->progcache_fork_id    = fd_progcache_attach_child( runner->progcache->join, fd_progcache_fork_id_initial() );
      54           0 :   runner->bank->accdb_fork_id        = fd_accdb_attach_child( accdb, runner->root_fork_id );
      55           0 :   runner->bank->parent_accdb_fork_id = runner->bank->accdb_fork_id;
      56             : 
      57           0 :   FD_TEST( test_ctx->has_bank );
      58           0 :   fd_exec_test_txn_bank_t const * txn_bank = &test_ctx->bank;
      59             : 
      60           0 :   fd_stake_delegations_t * stake_delegations = fd_banks_stake_delegations_root_query( runner->banks );
      61           0 :   runner->bank->stake_delegations_fork_id = fd_stake_delegations_new_fork( stake_delegations );
      62           0 :   runner->bank->new_votes_fork_id = fd_new_votes_new_fork( fd_bank_new_votes( runner->bank ) );
      63             : 
      64           0 :   fd_solfuzz_pb_restore_blockhash_queue( runner->bank, txn_bank->blockhash_queue, txn_bank->blockhash_queue_count );
      65           0 :   runner->bank->f.rbh_lamports_per_sig = txn_bank->rbh_lamports_per_signature;
      66             : 
      67           0 :   FD_TEST( txn_bank->has_fee_rate_governor );
      68           0 :   fd_solfuzz_pb_restore_fee_rate_governor( runner->bank, &txn_bank->fee_rate_governor );
      69             : 
      70           0 :   runner->bank->f.parent_slot       = slot-1UL;
      71           0 :   runner->bank->f.total_epoch_stake = txn_bank->total_epoch_stake;
      72             : 
      73           0 :   FD_TEST( txn_bank->has_features );
      74           0 :   FD_TEST( fd_solfuzz_pb_restore_features( &runner->bank->f.features, &txn_bank->features ) );
      75             : 
      76           0 :   for( ulong i=0UL; i<test_ctx->account_shared_data_count; i++ ) {
      77           0 :     fd_solfuzz_pb_load_account( runner->runtime, accdb, runner->bank->accdb_fork_id, &test_ctx->account_shared_data[i], i );
      78           0 :   }
      79             : 
      80           0 :   runner->bank->f.ticks_per_slot             = 64;
      81           0 :   runner->bank->f.slot_params                = FD_SLOT_PARAMS_400MS;
      82           0 :   runner->bank->f.slot_params.slots_per_year = SECONDS_PER_YEAR * (1000000000.0 / (double)6250000) / (double)(runner->bank->f.ticks_per_slot);
      83           0 :   runner->bank->f.slot_params_default        = runner->bank->f.slot_params;
      84             : 
      85           0 :   fd_sysvar_cache_restore_fuzz( runner->bank, runner->accdb );
      86             : 
      87           0 :   FD_TEST( fd_sysvar_cache_epoch_schedule_read( &runner->bank->f.sysvar_cache, &runner->bank->f.epoch_schedule ) );
      88           0 :   runner->bank->f.epoch = fd_slot_to_epoch( &runner->bank->f.epoch_schedule, slot, NULL );
      89             : 
      90           0 :   FD_TEST( fd_sysvar_cache_rent_read( &runner->bank->f.sysvar_cache, &runner->bank->f.rent ) );
      91             : 
      92             :   /* Initialize cost tracker */
      93           0 :   fd_cost_tracker_t * cost_tracker = fd_bank_cost_tracker_modify( runner->bank );
      94           0 :   fd_cost_tracker_init( cost_tracker, &runner->bank->f.features, &runner->bank->f.slot_params, slot );
      95             : 
      96           0 :   fd_txn_p_t * txns = fd_spad_alloc( runner->spad, alignof(fd_txn_p_t), txn_cnt*sizeof(fd_txn_p_t) );
      97           0 :   fd_memset( txns, 0, txn_cnt*sizeof(fd_txn_p_t) );
      98             : 
      99           0 :   for( ulong i=0UL; i<txn_cnt; i++ ) {
     100           0 :     ulong msg_sz = fd_solfuzz_pb_txn_serialize( txns[i].payload, &test_ctx->txns[i] );
     101           0 :     if( FD_UNLIKELY( msg_sz==ULONG_MAX ) ) return NULL;
     102           0 :     if( FD_UNLIKELY( !fd_txn_parse( txns[i].payload, msg_sz, TXN( &txns[i] ), NULL ) ) ) return NULL;
     103           0 :     txns[i].payload_sz = msg_sz;
     104           0 :   }
     105             : 
     106           0 :   *out_txn_cnt = txn_cnt;
     107           0 :   return txns;
     108           0 : }
     109             : 
     110             : static void
     111             : fd_solfuzz_bundle_mark_uncommittable( fd_txn_out_t * txn_outs,
     112           0 :                                       ulong          txn_cnt ) {
     113           0 :   for( ulong i=0UL; i<txn_cnt; i++ ) {
     114           0 :     txn_outs[i].err.is_committable = 0;
     115           0 :   }
     116           0 : }
     117             : 
     118             : /* Record the latest stake and vote account updates only. */
     119             : 
     120             : static fd_exec_test_stake_delta_t *
     121             : fd_solfuzz_bundle_stake_delta_upsert( fd_exec_test_bundle_effects_t * effects,
     122           0 :                                       fd_pubkey_t const *             key ) {
     123           0 :   for( ulong i=0UL; i<effects->stake_deltas_count; i++ ) {
     124           0 :     if( fd_memeq( effects->stake_deltas[i].address, key, sizeof(fd_pubkey_t) ) ) return &effects->stake_deltas[i];
     125           0 :   }
     126           0 :   fd_exec_test_stake_delta_t * stake_delta = &effects->stake_deltas[effects->stake_deltas_count++];
     127           0 :   fd_memcpy( stake_delta->address, key, sizeof(fd_pubkey_t) );
     128           0 :   return stake_delta;
     129           0 : }
     130             : 
     131             : static fd_exec_test_vote_update_t *
     132             : fd_solfuzz_bundle_vote_update_upsert( fd_exec_test_bundle_effects_t * effects,
     133           0 :                                       fd_pubkey_t const *             key ) {
     134           0 :   for( ulong i=0UL; i<effects->vote_updates_count; i++ ) {
     135           0 :     if( fd_memeq( effects->vote_updates[i].address, key, sizeof(fd_pubkey_t) ) ) return &effects->vote_updates[i];
     136           0 :   }
     137           0 :   fd_exec_test_vote_update_t * vote_update = &effects->vote_updates[effects->vote_updates_count++];
     138           0 :   fd_memcpy( vote_update->address, key, sizeof(fd_pubkey_t) );
     139           0 :   return vote_update;
     140           0 : }
     141             : 
     142             : static int
     143             : fd_solfuzz_bundle_execute( fd_solfuzz_runner_t *                 runner,
     144             :                            fd_exec_test_bundle_context_t const * input,
     145             :                            int                                   is_bundle,
     146             :                            void *                                output_buf,
     147             :                            ulong                                 output_bufsz,
     148             :                            fd_exec_test_bundle_effects_t **      effects_out,
     149           0 :                            ulong *                               output_used ) {
     150           0 :   ulong txn_cnt = 0UL;
     151           0 :   fd_txn_p_t * txns = fd_solfuzz_pb_bundle_ctx_create( runner, input, &txn_cnt );
     152           0 :   if( FD_UNLIKELY( !txns ) ) {
     153           0 :     fd_solfuzz_bundle_ctx_destroy( runner );
     154           0 :     return 0;
     155           0 :   }
     156             : 
     157           0 :   FD_SCRATCH_ALLOC_INIT( l, output_buf );
     158           0 :   ulong output_end = (ulong)output_buf + output_bufsz;
     159             : 
     160           0 :   fd_exec_test_bundle_effects_t * effects =
     161           0 :     FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_bundle_effects_t),
     162           0 :                                 sizeof(fd_exec_test_bundle_effects_t) );
     163           0 :   if( FD_UNLIKELY( _l>output_end ) ) abort();
     164           0 :   fd_memset( effects, 0, sizeof(fd_exec_test_bundle_effects_t) );
     165             : 
     166           0 :   effects->txn_results_count = (pb_size_t)txn_cnt;
     167           0 :   effects->txn_results = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_txn_result_t),
     168           0 :                                                   txn_cnt*sizeof(fd_exec_test_txn_result_t) );
     169           0 :   if( FD_UNLIKELY( _l>output_end ) ) abort();
     170           0 :   fd_memset( effects->txn_results, 0, txn_cnt*sizeof(fd_exec_test_txn_result_t) );
     171             : 
     172           0 :   ulong update_max = txn_cnt*MAX_TX_ACCOUNT_LOCKS;
     173           0 :   effects->stake_deltas = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_stake_delta_t),
     174           0 :                                                    update_max*sizeof(fd_exec_test_stake_delta_t) );
     175           0 :   if( FD_UNLIKELY( _l>output_end ) ) abort();
     176           0 :   fd_memset( effects->stake_deltas, 0, update_max*sizeof(fd_exec_test_stake_delta_t) );
     177           0 :   effects->stake_deltas_count = 0UL;
     178             : 
     179           0 :   effects->vote_updates = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_vote_update_t),
     180           0 :                                                    update_max*sizeof(fd_exec_test_vote_update_t) );
     181           0 :   if( FD_UNLIKELY( _l>output_end ) ) abort();
     182           0 :   fd_memset( effects->vote_updates, 0, update_max*sizeof(fd_exec_test_vote_update_t) );
     183           0 :   effects->vote_updates_count = 0UL;
     184             : 
     185           0 :   effects->new_votes = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_new_vote_t),
     186           0 :                                                 update_max*sizeof(fd_exec_test_new_vote_t) );
     187           0 :   if( FD_UNLIKELY( _l>output_end ) ) abort();
     188           0 :   fd_memset( effects->new_votes, 0, update_max*sizeof(fd_exec_test_new_vote_t) );
     189           0 :   effects->new_votes_count = 0UL;
     190             : 
     191           0 :   fd_runtime_t *       runtime      = runner->runtime;
     192           0 :   fd_txn_out_t *       txn_outs     = fd_spad_alloc( runner->spad, alignof(fd_txn_out_t), txn_cnt*sizeof(fd_txn_out_t) );
     193           0 :   fd_txn_in_t  *       txn_ins      = fd_spad_alloc( runner->spad, alignof(fd_txn_in_t),  txn_cnt*sizeof(fd_txn_in_t)  );
     194           0 :   fd_log_collector_t * logs         = fd_spad_alloc( runner->spad, alignof(fd_log_collector_t), txn_cnt*sizeof(fd_log_collector_t) );
     195           0 :   ulong                ran_cnt      = 0UL;
     196           0 :   int                  saw_exec_err = 0;
     197             : 
     198             :   /* Set up every txn_in up-front.  For bundles, acquire all of the
     199             :      bundle's accounts in a single acquire_a/acquire_b pair before any
     200             :      txn executes; each txn then binds to this shared pool, which is
     201             :      released once after the bundle is committed or cancelled. */
     202           0 :   for( ulong i=0UL; i<txn_cnt; i++ ) {
     203           0 :     txn_ins[i]                     = (fd_txn_in_t){0};
     204           0 :     txn_ins[i].txn                 = &txns[i];
     205           0 :     txn_ins[i].bundle.is_bundle    = is_bundle;
     206           0 :     txn_ins[i].bundle.prev_txn_cnt = is_bundle ? i : 0UL;
     207           0 :     for( ulong j=0UL; is_bundle && j<i; j++ ) txn_ins[i].bundle.prev_txn_outs[j] = &txn_outs[j];
     208           0 :   }
     209             :   /* Mirror fd_execle_tile: a failed bundle prepare acquires nothing, so
     210             :      every txn fails and fd_runtime_fini_bundle must be skipped.  An
     211             :      empty bundle likewise acquires nothing and must skip fini. */
     212           0 :   int bundle_prep_ok = 1;
     213           0 :   if( is_bundle ) {
     214           0 :     runtime->accdb = runner->accdb;
     215           0 :     if( FD_LIKELY( txn_cnt ) ) {
     216           0 :       int prepare_err = fd_runtime_prepare_bundle_accounts( runtime, runner->bank, txn_ins, txn_outs, txn_cnt );
     217           0 :       if( FD_UNLIKELY( prepare_err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) {
     218           0 :         bundle_prep_ok = 0;
     219           0 :         saw_exec_err   = 1;
     220           0 :       }
     221           0 :     }
     222           0 :   }
     223             : 
     224           0 :   for( ulong i=0UL; bundle_prep_ok && i<txn_cnt; i++ ) {
     225           0 :     fd_txn_in_t * txn_in = &txn_ins[i];
     226             : 
     227           0 :     int exec_res = 0;
     228           0 :     runtime->log.log_collector = &logs[i];
     229           0 :     fd_solfuzz_txn_ctx_exec( runner, runtime, txn_in, &exec_res, &txn_outs[i], 1 );
     230           0 :     ran_cnt = i+1UL;
     231             : 
     232           0 :     if( exec_res!=FD_RUNTIME_EXECUTE_SUCCESS ) {
     233           0 :       saw_exec_err = 1;
     234           0 :       if( is_bundle ) {
     235           0 :         fd_solfuzz_bundle_mark_uncommittable( txn_outs, ran_cnt );
     236           0 :       } else {
     237           0 :         txn_outs[i].err.is_committable = 0;
     238           0 :         fd_runtime_cancel_txn( runtime, NULL, NULL, &txn_outs[i], 0 );
     239           0 :       }
     240           0 :       break;
     241           0 :     }
     242             : 
     243           0 :     fd_exec_test_txn_result_t * txn_result = NULL;
     244           0 :     ulong txn_result_sz = create_txn_result_protobuf_from_txn(
     245           0 :         &txn_result,
     246           0 :         (void *)_l,
     247           0 :         output_end - _l,
     248           0 :         txn_in,
     249           0 :         &txn_outs[i],
     250           0 :         exec_res );
     251           0 :     FD_TEST( txn_result_sz );
     252           0 :     FD_TEST( txn_result );
     253           0 :     effects->txn_results[i] = *txn_result;
     254           0 :     _l += txn_result_sz;
     255             : 
     256           0 :     for( ulong j=0UL; j<txn_outs[i].accounts.cnt; j++ ) {
     257           0 :       if( txn_outs[i].accounts.stake_update[j] ) {
     258           0 :         fd_exec_test_stake_delta_t * stake_delta = fd_solfuzz_bundle_stake_delta_upsert( effects, &txn_outs[i].accounts.keys[j] );
     259           0 :         stake_delta->new_stake = 0UL;
     260             : 
     261           0 :         fd_stake_state_t const * stake_state = fd_stakes_get_state( txn_outs[i].accounts.account[j] );
     262           0 :         if( stake_state && stake_state->stake_type==FD_STAKE_STATE_STAKE ) {
     263           0 :           stake_delta->new_stake = stake_state->stake.stake.delegation.stake;
     264           0 :         }
     265           0 :       }
     266             : 
     267           0 :       if( txn_outs[i].accounts.vote_update[j] ) {
     268           0 :         fd_vote_block_timestamp_t last_vote;
     269           0 :         if( !fd_vote_account_last_timestamp( txn_outs[i].accounts.account[j]->data,
     270           0 :                                              txn_outs[i].accounts.account[j]->data_len,
     271           0 :                                              &last_vote ) ) {
     272           0 :           fd_exec_test_vote_update_t * vote_update = fd_solfuzz_bundle_vote_update_upsert( effects, &txn_outs[i].accounts.keys[j] );
     273           0 :           vote_update->last_vote_slot      = last_vote.slot;
     274           0 :           vote_update->last_vote_timestamp = (ulong)last_vote.timestamp;
     275           0 :         }
     276           0 :       }
     277           0 :     }
     278             : 
     279           0 :     if( !is_bundle ) fd_runtime_commit_txn( runtime, runner->bank, NULL, &txn_outs[i], 0 );
     280           0 :   }
     281             : 
     282           0 :   if( is_bundle && !saw_exec_err ) {
     283           0 :     for( ulong i=0UL; i<txn_cnt; i++ ) {
     284           0 :       fd_runtime_commit_txn( runtime, runner->bank, NULL, &txn_outs[i], 0 );
     285           0 :     }
     286           0 :   }
     287             : 
     288             :   /* Release the bundle's shared account pool exactly once now that all of
     289             :      its txns have been committed or cancelled. */
     290           0 :   if( is_bundle && bundle_prep_ok && txn_cnt ) fd_runtime_fini_bundle( runtime );
     291             : 
     292           0 :   effects->has_error = saw_exec_err;
     293           0 :   if( saw_exec_err ) {
     294           0 :     effects->txn_results_count  = 0UL;
     295           0 :     effects->txn_results        = NULL;
     296           0 :     effects->stake_deltas_count = 0UL;
     297           0 :     effects->stake_deltas       = NULL;
     298           0 :     effects->vote_updates_count = 0UL;
     299           0 :     effects->vote_updates       = NULL;
     300           0 :     effects->new_votes_count    = 0UL;
     301           0 :     effects->new_votes          = NULL;
     302           0 :   } else {
     303           0 :     ushort fork_idx = runner->bank->new_votes_fork_id;
     304           0 :     uchar iter_mem[ FD_NEW_VOTES_ITER_FOOTPRINT ] __attribute__((aligned(FD_NEW_VOTES_ITER_ALIGN)));
     305           0 :     fd_new_votes_iter_t * iter = fd_new_votes_iter_init( fd_bank_new_votes( runner->bank ), &fork_idx, 1UL, iter_mem );
     306           0 :     for( ; !fd_new_votes_iter_done( iter ); fd_new_votes_iter_next( iter ) ) {
     307           0 :       FD_TEST( effects->new_votes_count<update_max );
     308             : 
     309           0 :       fd_exec_test_new_vote_t * new_vote = &effects->new_votes[effects->new_votes_count++];
     310           0 :       int is_tombstone;
     311           0 :       fd_pubkey_t const * pubkey = fd_new_votes_iter_ele( iter, &is_tombstone );
     312           0 :       new_vote->is_tombstone = !!is_tombstone;
     313           0 :       fd_memcpy( new_vote->address, pubkey, sizeof(fd_pubkey_t) );
     314           0 :     }
     315           0 :     fd_new_votes_iter_fini( iter );
     316           0 :   }
     317             : 
     318           0 :   *effects_out = effects;
     319           0 :   *output_used = FD_SCRATCH_ALLOC_FINI( l, 1UL ) - (ulong)output_buf;
     320             : 
     321           0 :   fd_solfuzz_bundle_ctx_destroy( runner );
     322           0 :   return 1;
     323           0 : }
     324             : 
     325             : static void
     326             : fd_solfuzz_bundle_assert_same_success( fd_solfuzz_runner_t *          runner,
     327             :                                        fd_exec_test_bundle_effects_t * regular,
     328           0 :                                        fd_exec_test_bundle_effects_t * bundle ) {
     329           0 :   ulong   buf_sz      = 100000000UL;
     330           0 :   uchar * regular_buf = fd_spad_alloc( runner->spad, 1UL, buf_sz );
     331           0 :   uchar * bundle_buf  = fd_spad_alloc( runner->spad, 1UL, buf_sz );
     332             : 
     333           0 :   ulong regular_sz = buf_sz;
     334           0 :   ulong bundle_sz  = buf_sz;
     335           0 :   FD_TEST( sol_compat_encode( regular_buf, &regular_sz, regular, &fd_exec_test_bundle_effects_t_msg ) );
     336           0 :   FD_TEST( sol_compat_encode( bundle_buf,  &bundle_sz,  bundle,  &fd_exec_test_bundle_effects_t_msg ) );
     337             : 
     338           0 :   if( FD_UNLIKELY( regular_sz!=bundle_sz || !fd_memeq( regular_buf, bundle_buf, regular_sz ) ) ) {
     339           0 :     FD_LOG_ERR(( "bundle transaction effects mismatch" ));
     340           0 :   }
     341           0 : }
     342             : 
     343             : ulong
     344             : fd_solfuzz_pb_bundle_run( fd_solfuzz_runner_t * runner,
     345             :                           void const *          input_,
     346             :                           void **               output_,
     347             :                           void *                output_buf,
     348           0 :                           ulong                 output_bufsz ) {
     349           0 :   fd_exec_test_bundle_context_t const * input  = fd_type_pun_const( input_ );
     350           0 :   fd_exec_test_bundle_effects_t **      output = fd_type_pun( output_ );
     351             : 
     352           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     353           0 :     void * regular_buf = fd_spad_alloc( runner->spad, 1UL, output_bufsz );
     354             : 
     355           0 :     fd_exec_test_bundle_effects_t * regular_effects = NULL;
     356           0 :     fd_exec_test_bundle_effects_t * bundle_effects  = NULL;
     357           0 :     ulong                           regular_sz      = 0UL;
     358           0 :     ulong                           bundle_sz       = 0UL;
     359             : 
     360           0 :     int regular_ok = fd_solfuzz_bundle_execute( runner, input, 0, regular_buf, output_bufsz, &regular_effects, &regular_sz );
     361           0 :     int bundle_ok  = fd_solfuzz_bundle_execute( runner, input, 1, output_buf,  output_bufsz, &bundle_effects,  &bundle_sz  );
     362             : 
     363           0 :     if( FD_UNLIKELY( regular_ok!=bundle_ok ) ) {
     364           0 :       FD_LOG_ERR(( "bundle harness setup parity mismatch: regular_ok=%d bundle_ok=%d", regular_ok, bundle_ok ));
     365           0 :     }
     366           0 :     if( FD_UNLIKELY( !regular_ok ) ) {
     367           0 :       return 0UL;
     368           0 :     }
     369             : 
     370           0 :     (void)regular_sz;
     371           0 :     if( FD_UNLIKELY( regular_effects->has_error!=bundle_effects->has_error ) ) {
     372           0 :       FD_LOG_ERR(( "bundle success parity mismatch: regular_has_error=%d bundle_has_error=%d",
     373           0 :                    regular_effects->has_error, bundle_effects->has_error ));
     374           0 :     }
     375             : 
     376           0 :     if( !regular_effects->has_error ) {
     377           0 :       fd_solfuzz_bundle_assert_same_success( runner, regular_effects, bundle_effects );
     378           0 :     }
     379             : 
     380           0 :     *output = bundle_effects;
     381           0 :     return bundle_sz;
     382           0 :   } FD_SPAD_FRAME_END;
     383           0 : }

Generated by: LCOV version 1.14