Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_tests_fd_solfuzz_private_h
2 : #define HEADER_fd_src_flamenco_runtime_tests_fd_solfuzz_private_h
3 :
4 : /* fd_solfuzz_private.h contains internal components for the solfuzz
5 : Protobuf shim. */
6 :
7 : #include "fd_solfuzz.h"
8 : #include "../../features/fd_features.h"
9 : #include "../../../third_party/nanopb/pb_encode.h"
10 : #include "../../../third_party/nanopb/pb_decode.h"
11 : #include "generated/context.pb.h"
12 :
13 : FD_PROTOTYPES_BEGIN
14 :
15 : static inline ulong
16 : fd_solfuzz_hash( void const * data,
17 0 : ulong data_sz ) {
18 0 : return data_sz ? fd_hash( 0UL, data, data_sz ) : 0UL;
19 0 : }
20 :
21 : /* Returns the account data carried by an input account state, or NULL if
22 : the account state carries a hash of its data instead. */
23 : static inline pb_bytes_array_t const *
24 0 : fd_solfuzz_acct_data( fd_exec_test_acct_state_t const * acct ) {
25 0 : if( acct->which_data_repr!=FD_EXEC_TEST_ACCT_STATE_DATA_TAG ) return NULL;
26 0 : return acct->data_repr.data;
27 0 : }
28 :
29 : /* Stores the hash of the given account data in an effects account
30 : state. */
31 : static inline void
32 : fd_solfuzz_acct_set_data_hash( fd_exec_test_acct_state_t * acct,
33 : void const * data,
34 0 : ulong data_sz ) {
35 0 : acct->which_data_repr = FD_EXEC_TEST_ACCT_STATE_DATA_HASH_TAG;
36 0 : acct->data_repr.data_hash = fd_solfuzz_hash( data, data_sz );
37 0 : }
38 :
39 : /* Creates / overwrites an account in the accdb given an input account
40 : state. On success, loads the account into acc. Optionally, reject
41 : any zero-lamport accounts from being loaded in. */
42 : int
43 : fd_solfuzz_pb_load_account( fd_runtime_t * runtime,
44 : fd_accdb_t * accdb,
45 : fd_accdb_fork_id_t fork_id,
46 : fd_exec_test_acct_state_t const * state,
47 : ulong acc_idx );
48 :
49 : /* Restores the fee rate governor in the bank from the given protobuf
50 : fee rate governor. */
51 : void
52 : fd_solfuzz_pb_restore_fee_rate_governor( fd_bank_t * bank,
53 : fd_exec_test_fee_rate_governor_t const * fee_rate_governor );
54 :
55 : /* Initializes the blockhash queue in the bank from the given protobuf
56 : blockhash queue entries. */
57 : void
58 : fd_solfuzz_pb_restore_blockhash_queue( fd_bank_t * bank,
59 : fd_exec_test_blockhash_queue_entry_t const * entries,
60 : ulong entries_cnt );
61 :
62 : /* Retrieves the slot number from the clock sysvar account within the
63 : given account states list. Throws FD_LOG_ERR if the clock sysvar
64 : is not found or is malformed. */
65 : ulong
66 : fd_solfuzz_pb_get_slot( fd_exec_test_acct_state_t const * acct_states,
67 : ulong acct_states_cnt );
68 :
69 : /* Activates features in the runtime given an input feature set. Fails
70 : if a passed-in feature is unknown / not supported. */
71 : int
72 : fd_solfuzz_pb_restore_features( fd_features_t * features,
73 : fd_exec_test_feature_set_t const * feature_set );
74 :
75 : /* Due to how Firedancer's VM CU accounting works, when
76 : virtual_address_space_adjustments is enabled and execution
77 : fails with the CU meter exhausted, we cannot compare the data
78 : region of the accounts with Agave. This function clears the
79 : data field on each captured account in this case. */
80 : void
81 : fd_solfuzz_direct_mapping_handle_cu_exhaustion( fd_solfuzz_runner_t * runner,
82 : ulong cu_avail,
83 : int has_err,
84 : fd_exec_test_acct_state_t * accounts,
85 : pb_size_t accounts_cnt );
86 :
87 : /* Create feature accounts for all active features in the given feature
88 : set, with an activation slot of 0. Skip any feature whose pubkey
89 : already appears in acct_states so the caller-supplied state wins
90 : (matches solfuzz-agave's accounts_to_store filter). */
91 : void
92 : fd_solfuzz_pb_create_feature_accounts( fd_accdb_t * accdb,
93 : fd_accdb_fork_id_t fork_id,
94 : fd_exec_test_feature_set_t const * feature_set,
95 : fd_exec_test_acct_state_t const * acct_states,
96 : pb_size_t acct_states_count );
97 :
98 : typedef ulong( exec_test_run_pb_fn_t )( fd_solfuzz_runner_t *,
99 : void const *,
100 : void **,
101 : void *,
102 : ulong );
103 :
104 : static inline void
105 : fd_solfuzz_pb_execute_wrapper( fd_solfuzz_runner_t * runner,
106 : void const * input,
107 : void ** output,
108 0 : exec_test_run_pb_fn_t * exec_test_run_fn ) {
109 0 : ulong out_bufsz = 100000000; /* 100 MB */
110 0 : void * out0 = fd_spad_alloc( runner->spad, 1UL, out_bufsz );
111 0 : FD_TEST( out_bufsz <= fd_spad_alloc_max( runner->spad, 1UL ) );
112 :
113 0 : ulong out_used = exec_test_run_fn( runner, input, output, out0, out_bufsz );
114 0 : if( FD_UNLIKELY( !out_used ) ) {
115 0 : *output = NULL;
116 0 : }
117 0 : }
118 :
119 : /* Utils */
120 :
121 : static FD_FN_UNUSED void *
122 : sol_compat_decode_lenient( void * decoded,
123 : uchar const * in,
124 : ulong in_sz,
125 0 : pb_msgdesc_t const * decode_type ) {
126 0 : pb_istream_t istream = pb_istream_from_buffer( in, in_sz );
127 0 : int decode_ok = pb_decode_ex( &istream, decode_type, decoded, PB_DECODE_NOINIT );
128 0 : if( !decode_ok ) {
129 0 : pb_release( decode_type, decoded );
130 0 : return NULL;
131 0 : }
132 0 : return decoded;
133 0 : }
134 :
135 : static FD_FN_UNUSED void *
136 : sol_compat_decode( void * decoded,
137 : uchar const * in,
138 : ulong in_sz,
139 0 : pb_msgdesc_t const * decode_type ) {
140 0 : pb_istream_t istream = pb_istream_from_buffer( in, in_sz );
141 0 : int decode_ok = pb_decode_ex( &istream, decode_type, decoded, PB_DECODE_NOINIT );
142 0 : if( !decode_ok ) {
143 0 : pb_release( decode_type, decoded );
144 0 : return NULL;
145 0 : }
146 0 : ulong size;
147 0 : if( FD_UNLIKELY( !pb_get_encoded_size( &size, decode_type, decoded ) ) ) {
148 0 : pb_release( decode_type, decoded );
149 0 : return NULL;
150 0 : }
151 0 : if( FD_UNLIKELY( size != in_sz ) ) {
152 0 : pb_release( decode_type, decoded );
153 0 : return NULL;
154 0 : }
155 0 : return decoded;
156 0 : }
157 :
158 : static FD_FN_UNUSED void const *
159 : sol_compat_encode( uchar * out,
160 : ulong * out_sz,
161 : void const * to_encode,
162 0 : pb_msgdesc_t const * encode_type ) {
163 0 : pb_ostream_t ostream = pb_ostream_from_buffer( out, *out_sz );
164 0 : int encode_ok = pb_encode( &ostream, encode_type, to_encode );
165 0 : if( !encode_ok ) {
166 0 : return NULL;
167 0 : }
168 0 : *out_sz = ostream.bytes_written;
169 0 : return to_encode;
170 0 : }
171 :
172 : FD_PROTOTYPES_END
173 :
174 : #endif /* HEADER_fd_src_flamenco_runtime_tests_fd_solfuzz_private_h */
|