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