Line data Source code
1 : #include "fd_accdb_svm.h"
2 : #include "sysvar/fd_sysvar_rent.h"
3 : #include "program/fd_bpf_loader_program.h"
4 : #include "program/fd_builtin_programs.h"
5 : #include "program/fd_program_util.h"
6 : #include "fd_runtime_stack.h"
7 : #include "fd_pubkey_utils.h"
8 : #include "fd_system_ids.h"
9 : #include "../accdb/fd_accdb_sync.h"
10 : #include "../../ballet/sha256/fd_sha256.h"
11 : #include "../../ballet/sbpf/fd_sbpf_loader.h"
12 : #include "../progcache/fd_prog_load.h"
13 : #include "../vm/fd_vm.h"
14 : #include <assert.h>
15 :
16 : static fd_pubkey_t
17 0 : get_program_data_address( fd_pubkey_t const * program_addr ) {
18 0 : uchar const * seed = program_addr->uc;
19 0 : ulong seed_sz = 32UL;
20 0 : fd_pubkey_t out;
21 0 : uint custom_err;
22 0 : uchar out_bump_seed;
23 0 : int err = fd_pubkey_find_program_address( &fd_solana_bpf_loader_upgradeable_program_id, 1UL, &seed, &seed_sz, &out, &out_bump_seed, &custom_err );
24 0 : if( FD_UNLIKELY( err ) ) {
25 : /* https://github.com/anza-xyz/solana-sdk/blob/address%40v2.1.0/address/src/syscalls.rs#L277-L279 */
26 0 : FD_LOG_ERR(( "Unable to find a viable program address bump seed" ));
27 0 : }
28 0 : return out;
29 0 : }
30 :
31 : fd_tmp_account_t *
32 : tmp_account_new( fd_tmp_account_t * acc,
33 0 : ulong acc_sz ) {
34 0 : acc->data_sz = acc_sz;
35 0 : fd_memset( acc->data, 0, acc_sz );
36 0 : return acc;
37 0 : }
38 :
39 : fd_tmp_account_t *
40 : tmp_account_read( fd_tmp_account_t * acc,
41 : fd_accdb_user_t * accdb,
42 : fd_funk_txn_xid_t const * xid,
43 0 : fd_pubkey_t const * addr ) {
44 0 : fd_accdb_ro_t ro[1];
45 0 : if( FD_LIKELY( !fd_accdb_open_ro( accdb, ro, xid, addr ) ) ) return NULL;
46 0 : tmp_account_new( acc, fd_accdb_ref_data_sz( ro ) );
47 0 : acc->meta = *ro->meta;
48 0 : acc->addr = *addr;
49 0 : fd_memcpy( acc->data, fd_accdb_ref_data_const( ro ), fd_accdb_ref_data_sz( ro ) );
50 0 : acc->data_sz = fd_accdb_ref_data_sz( ro );
51 0 : fd_accdb_close_ro( accdb, ro );
52 0 : return acc;
53 0 : }
54 :
55 : void
56 : tmp_account_store( fd_tmp_account_t * acc,
57 : fd_accdb_user_t * accdb,
58 : fd_funk_txn_xid_t const * xid,
59 : fd_bank_t * bank,
60 0 : fd_capture_ctx_t * capture_ctx ) {
61 0 : if( FD_UNLIKELY( fd_pubkey_eq( &acc->addr, &fd_solana_system_program_id ) ) ) {
62 0 : FD_LOG_ERR(( "Attempted to write to the system program account" ));
63 0 : }
64 :
65 0 : fd_accdb_rw_t rw[1]; fd_accdb_svm_update_t update[1];
66 0 : FD_TEST( fd_accdb_svm_open_rw( accdb, bank, xid, rw, update, &acc->addr, acc->data_sz, FD_ACCDB_FLAG_CREATE ) );
67 :
68 0 : fd_accdb_ref_exec_bit_set( rw, acc->meta.executable );
69 0 : fd_accdb_ref_owner_set ( rw, acc->meta.owner );
70 0 : fd_accdb_ref_lamports_set( rw, acc->meta.lamports );
71 0 : fd_accdb_ref_data_set ( accdb, rw, acc->data, acc->data_sz );
72 :
73 0 : fd_accdb_svm_close_rw( accdb, bank, capture_ctx, rw, update );
74 0 : }
75 :
76 : /* https://github.com/anza-xyz/agave/blob/v3.0.2/runtime/src/bank/builtins/core_bpf_migration/target_core_bpf.rs#L12 */
77 :
78 : struct target_core_bpf {
79 : fd_pubkey_t program_address;
80 : fd_tmp_account_t * program_data_account;
81 : fd_pubkey_t upgrade_authority_address;
82 : uint has_upgrade_authority_address : 1;
83 : };
84 :
85 : typedef struct target_core_bpf target_core_bpf_t;
86 :
87 : /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs#L19 */
88 :
89 : struct target_builtin {
90 : fd_tmp_account_t * program_account;
91 : fd_pubkey_t program_data_address;
92 : ulong program_data_account_lamports;
93 : };
94 :
95 : typedef struct target_builtin target_builtin_t;
96 :
97 : /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs#L25-L91 */
98 :
99 : target_builtin_t *
100 : target_builtin_new_checked( target_builtin_t * target_builtin,
101 : fd_pubkey_t const * program_address,
102 : int migration_target,
103 : int relax_programdata_account_check_migration,
104 : fd_accdb_user_t * accdb,
105 : fd_funk_txn_xid_t const * xid,
106 0 : fd_runtime_stack_t * runtime_stack ) {
107 :
108 : /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs#L31-L53 */
109 :
110 0 : fd_tmp_account_t * program_account = &runtime_stack->bpf_migration.program_account;
111 0 : switch( migration_target ) {
112 0 : case FD_CORE_BPF_MIGRATION_TARGET_BUILTIN:
113 0 : if( FD_UNLIKELY( !tmp_account_read( program_account, accdb, xid, program_address ) ) ) {
114 : /* CoreBpfMigrationError::AccountNotFound(*program_address) */
115 0 : return NULL;
116 0 : }
117 0 : if( FD_UNLIKELY( 0!=memcmp( program_account->meta.owner, &fd_solana_native_loader_id, 32 ) ) ) {
118 : /* CoreBpfMigrationError::IncorrectOwner(*program_address) */
119 0 : return NULL;
120 0 : }
121 0 : break;
122 0 : case FD_CORE_BPF_MIGRATION_TARGET_STATELESS: {
123 : /* Program account should not exist */
124 0 : fd_accdb_ro_t ro[1];
125 0 : int progdata_exists = !!fd_accdb_open_ro( accdb, ro, xid, program_address );
126 0 : if( progdata_exists ) {
127 : /* CoreBpfMigrationError::AccountAlreadyExists(*program_address) */
128 0 : fd_accdb_close_ro( accdb, ro );
129 0 : return NULL;
130 0 : }
131 0 : break;
132 0 : }
133 0 : default:
134 0 : FD_LOG_ERR(( "invalid migration_target %d", migration_target ));
135 0 : }
136 :
137 : /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs#L55 */
138 :
139 0 : fd_pubkey_t program_data_address = get_program_data_address( program_address );
140 :
141 : /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs#L57-L82 */
142 :
143 0 : ulong program_data_account_lamports = 0UL;
144 0 : do {
145 : /* Program data account should not exist */
146 0 : fd_accdb_ro_t ro[1];
147 0 : int progdata_exists = !!fd_accdb_open_ro( accdb, ro, xid, &program_data_address );
148 :
149 : /* SIMD-0444: relax_programdata_account_check_migration
150 : https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs#L57-L70 */
151 0 : if( relax_programdata_account_check_migration ) {
152 : /* The program data account should not exist, but a system
153 : account with funded lamports is acceptable. */
154 0 : if( FD_UNLIKELY( progdata_exists ) ) {
155 0 : if( FD_UNLIKELY( !fd_pubkey_eq( fd_accdb_ref_owner( ro ), &fd_solana_system_program_id ) ) ) {
156 : /* CoreBpfMigrationError::ProgramHasDataAccount(*program_address) */
157 0 : fd_accdb_close_ro( accdb, ro );
158 0 : return NULL;
159 0 : } else {
160 0 : program_data_account_lamports = fd_accdb_ref_lamports( ro );
161 0 : fd_accdb_close_ro( accdb, ro );
162 0 : }
163 0 : }
164 0 : } else {
165 : /* If relax_programdata_account_check_migration is not enabled,
166 : we do not allow the program data account to exist at all. */
167 0 : if( FD_UNLIKELY( progdata_exists ) ) {
168 : /* CoreBpfMigrationError::AccountAlreadyExists(*program_address) */
169 0 : fd_accdb_close_ro( accdb, ro );
170 0 : return NULL;
171 0 : }
172 0 : }
173 0 : } while(0);
174 :
175 : /* https://github.com/anza-xyz/agave/blob/v3.0.2/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs#L63-L67 */
176 :
177 0 : *target_builtin = (target_builtin_t) {
178 0 : .program_account = program_account,
179 0 : .program_data_address = program_data_address,
180 0 : .program_data_account_lamports = program_data_account_lamports
181 0 : };
182 0 : return target_builtin;
183 0 : }
184 :
185 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/target_core_bpf.rs#L26-L93 */
186 : static target_core_bpf_t *
187 : target_core_bpf_new_checked( target_core_bpf_t * target_core_bpf,
188 : fd_pubkey_t const * program_address,
189 : fd_accdb_user_t * accdb,
190 : fd_funk_txn_xid_t const * xid,
191 0 : fd_runtime_stack_t * runtime_stack ) {
192 0 : fd_pubkey_t program_data_address = get_program_data_address( program_address );
193 :
194 : /* The program account should exist */
195 0 : fd_tmp_account_t * program_account = &runtime_stack->bpf_migration.program_account;
196 0 : if( FD_UNLIKELY( !tmp_account_read( program_account, accdb, xid, program_address ) ) ) {
197 0 : return NULL;
198 0 : }
199 :
200 : /* The program account should be owned by the upgradeable loader */
201 0 : if( FD_UNLIKELY( 0!=memcmp( program_account->meta.owner, &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_pubkey_t) ) ) ) {
202 0 : return NULL;
203 0 : }
204 :
205 : /* The program account should be executable */
206 0 : if( FD_UNLIKELY( !program_account->meta.executable ) ) {
207 0 : return NULL;
208 0 : }
209 :
210 : /* Decode and validate program account state */
211 0 : fd_bpf_upgradeable_loader_state_t program_state[1];
212 0 : if( FD_UNLIKELY( FD_EXECUTOR_INSTR_SUCCESS!=fd_bpf_loader_program_get_state( &program_account->meta, program_state ) ) ) {
213 0 : return NULL;
214 0 : }
215 0 : if( FD_UNLIKELY( !fd_bpf_upgradeable_loader_state_is_program( program_state ) ) ) {
216 0 : return NULL;
217 0 : }
218 0 : if( FD_UNLIKELY( 0!=memcmp( &program_state->inner.program.programdata_address, &program_data_address, sizeof(fd_pubkey_t) ) ) ) {
219 0 : return NULL;
220 0 : }
221 :
222 : /* The program data account should exist */
223 0 : fd_tmp_account_t * program_data_account = &runtime_stack->bpf_migration.new_target_program;
224 0 : if( FD_UNLIKELY( !tmp_account_read( program_data_account, accdb, xid, &program_data_address ) ) ) {
225 0 : return NULL;
226 0 : }
227 :
228 : /* The program data account should be owned by the upgradeable loader */
229 0 : if( FD_UNLIKELY( 0!=memcmp( program_data_account->meta.owner, &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_pubkey_t) ) ) ) {
230 0 : return NULL;
231 0 : }
232 :
233 : /* Decode and validate program data account state */
234 0 : fd_bpf_upgradeable_loader_state_t programdata_state[1];
235 0 : if( FD_UNLIKELY( FD_EXECUTOR_INSTR_SUCCESS!=fd_bpf_loader_program_get_state( &program_data_account->meta, programdata_state ) ) ) {
236 0 : return NULL;
237 0 : }
238 0 : if( FD_UNLIKELY( !fd_bpf_upgradeable_loader_state_is_program_data( programdata_state ) ) ) {
239 0 : return NULL;
240 0 : }
241 :
242 : /* Extract upgrade authority from program data state */
243 0 : fd_pubkey_t upgrade_authority_address;
244 0 : if( programdata_state->inner.program_data.has_upgrade_authority_address ) {
245 0 : upgrade_authority_address = programdata_state->inner.program_data.upgrade_authority_address;
246 0 : } else {
247 0 : fd_memset( &upgrade_authority_address, 0, sizeof(fd_pubkey_t) );
248 0 : }
249 :
250 0 : *target_core_bpf = (target_core_bpf_t) {
251 0 : .program_address = *program_address,
252 0 : .program_data_account = program_data_account,
253 0 : .upgrade_authority_address = upgrade_authority_address,
254 0 : .has_upgrade_authority_address = (uint)!!programdata_state->inner.program_data.has_upgrade_authority_address
255 0 : };
256 0 : return target_core_bpf;
257 0 : }
258 :
259 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L25-L82
260 :
261 : Agave uses a separate TargetBpfV2 struct, but it has the
262 : same layout as target_builtin_t so we reuse that. */
263 : static target_builtin_t *
264 : target_bpf_v2_new_checked( target_builtin_t * target_bpf_v2,
265 : fd_pubkey_t const * program_address,
266 : int allow_prefunded,
267 : fd_accdb_user_t * accdb,
268 : fd_funk_txn_xid_t const * xid,
269 0 : fd_runtime_stack_t * runtime_stack ) {
270 :
271 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L30-L33 */
272 0 : fd_tmp_account_t * program_account = &runtime_stack->bpf_migration.program_account;
273 0 : if( FD_UNLIKELY( !tmp_account_read( program_account, accdb, xid, program_address ) ) ) {
274 : /* CoreBpfMigrationError::AccountNotFound(*program_address) */
275 0 : return NULL;
276 0 : }
277 :
278 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L35-L38 */
279 0 : if( FD_UNLIKELY( 0!=memcmp( program_account->meta.owner, &fd_solana_bpf_loader_program_id, FD_PUBKEY_FOOTPRINT ) ) ) {
280 : /* CoreBpfMigrationError::IncorrectOwner(*program_address) */
281 0 : return NULL;
282 0 : }
283 :
284 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L40-L45 */
285 0 : if( FD_UNLIKELY( !program_account->meta.executable ) ) {
286 : /* CoreBpfMigrationError::ProgramAccountNotExecutable(*program_address) */
287 0 : return NULL;
288 0 : }
289 :
290 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L47 */
291 0 : fd_pubkey_t program_data_address = get_program_data_address( program_address );
292 :
293 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L49-L74 */
294 0 : ulong program_data_account_lamports = 0UL;
295 0 : do {
296 0 : fd_accdb_ro_t ro[1];
297 0 : int progdata_exists = !!fd_accdb_open_ro( accdb, ro, xid, &program_data_address );
298 :
299 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L49-L74 */
300 0 : if( FD_LIKELY( allow_prefunded ) ) {
301 : /* The program data account should not exist, but a system
302 : account with funded lamports is acceptable.
303 :
304 : https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L50-L61 */
305 0 : if( FD_UNLIKELY( progdata_exists ) ) {
306 0 : if( FD_UNLIKELY( !fd_pubkey_eq( fd_accdb_ref_owner( ro ), &fd_solana_system_program_id ) ) ) {
307 : /* CoreBpfMigrationError::ProgramHasDataAccount(*program_address) */
308 0 : fd_accdb_close_ro( accdb, ro );
309 0 : return NULL;
310 0 : } else {
311 0 : program_data_account_lamports = fd_accdb_ref_lamports( ro );
312 0 : fd_accdb_close_ro( accdb, ro );
313 0 : }
314 0 : }
315 0 : } else {
316 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/target_bpf_v2.rs#L62-L74 */
317 0 : if( FD_UNLIKELY( progdata_exists ) ) {
318 : /* CoreBpfMigrationError::ProgramHasDataAccount(*program_address) */
319 0 : fd_accdb_close_ro( accdb, ro );
320 0 : return NULL;
321 0 : }
322 0 : }
323 0 : } while(0);
324 :
325 0 : *target_bpf_v2 = (target_builtin_t) {
326 0 : .program_account = program_account,
327 0 : .program_data_address = program_data_address,
328 0 : .program_data_account_lamports = program_data_account_lamports
329 0 : };
330 0 : return target_bpf_v2;
331 0 : }
332 :
333 : /* This function contains the deployment checks that are equivalent to
334 : Agave's directly_invoke_loader_v3_deploy.
335 :
336 : There is no direct equivalent in Agave to this function, because
337 : we are not updating the program cache here. However, we do the same
338 : checks that our program cache does upon deployment.
339 :
340 : This is safe because the bpf migration code runs at the epoch
341 : boundary, before any transaction execution. The program cache
342 : automatically invalidates all programs at the start of an epoch
343 : boundary, so we do not need to explicitly update the cache during the
344 : migration.
345 :
346 : https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L120-L218 */
347 : static int
348 : fd_directly_invoke_loader_v3_deploy_checks( fd_bank_t const * bank,
349 : fd_runtime_stack_t * runtime_stack,
350 : uchar const * elf,
351 0 : ulong elf_sz ) {
352 0 : fd_features_t const * features = &bank->f.features;
353 0 : ulong slot = bank->f.slot;
354 :
355 : /* ELF verification with deploy checks enabled */
356 0 : fd_prog_versions_t versions = fd_prog_versions( features, slot );
357 0 : fd_sbpf_loader_config_t loader_config = {
358 0 : .elf_deploy_checks = 1,
359 0 : .sbpf_min_version = versions.min_sbpf_version,
360 0 : .sbpf_max_version = versions.max_sbpf_version,
361 0 : };
362 0 : fd_sbpf_elf_info_t elf_info[1];
363 0 : if( FD_UNLIKELY( fd_sbpf_elf_peek( elf_info, elf, elf_sz, &loader_config )!=FD_SBPF_ELF_SUCCESS ) ) return 1;
364 :
365 : /* Setup program (includes calldests) */
366 0 : fd_sbpf_program_t * prog = fd_sbpf_program_new(
367 0 : runtime_stack->bpf_migration.progcache_validate.sbpf_footprint,
368 0 : elf_info,
369 0 : runtime_stack->bpf_migration.progcache_validate.rodata );
370 0 : if( FD_UNLIKELY( !prog ) ) return 1;
371 :
372 0 : fd_sbpf_syscalls_t _syscalls[ FD_SBPF_SYSCALLS_SLOT_CNT ];
373 0 : fd_sbpf_syscalls_t * syscalls = fd_sbpf_syscalls_join( fd_sbpf_syscalls_new( _syscalls ) );
374 0 : if( FD_UNLIKELY( !syscalls ) ) return 1;
375 0 : if( FD_UNLIKELY( fd_vm_syscall_register_slot( syscalls, slot, features, /* is_deploy */ 1 )!=FD_VM_SUCCESS ) ) return 1;
376 :
377 : /* fd_sbpf_program_load checks */
378 0 : if( FD_UNLIKELY( fd_sbpf_program_load(
379 0 : prog,
380 0 : elf,
381 0 : elf_sz,
382 0 : syscalls,
383 0 : &loader_config,
384 0 : runtime_stack->bpf_migration.progcache_validate.programdata,
385 0 : sizeof(runtime_stack->bpf_migration.progcache_validate.programdata) ) ) ) return 1;
386 :
387 : /* fd_vm_validate checks */
388 0 : fd_vm_t _vm[1];
389 0 : fd_vm_t * vm = fd_vm_join( fd_vm_new( _vm ) );
390 0 : if( FD_UNLIKELY( !vm ) ) return 1;
391 0 : vm = fd_vm_init( vm,
392 0 : NULL,
393 0 : 0UL,
394 0 : 0UL,
395 0 : prog->rodata,
396 0 : prog->rodata_sz,
397 0 : prog->text,
398 0 : prog->info.text_cnt,
399 0 : prog->info.text_off,
400 0 : prog->info.text_sz,
401 0 : prog->entry_pc,
402 0 : prog->calldests,
403 0 : elf_info->sbpf_version,
404 0 : syscalls,
405 0 : NULL,
406 0 : NULL,
407 0 : NULL,
408 0 : 0U,
409 0 : NULL,
410 0 : 0,
411 0 : FD_FEATURE_ACTIVE( slot, features, account_data_direct_mapping ),
412 0 : FD_FEATURE_ACTIVE( slot, features, syscall_parameter_address_restrictions ),
413 0 : FD_FEATURE_ACTIVE( slot, features, virtual_address_space_adjustments ),
414 0 : 0,
415 0 : 0UL );
416 0 : if( FD_UNLIKELY( !vm ) ) return 1;
417 0 : if( FD_UNLIKELY( fd_vm_validate( vm )!=FD_VM_SUCCESS ) ) return 1;
418 :
419 0 : return FD_EXECUTOR_INSTR_SUCCESS;
420 0 : }
421 :
422 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L51-L75 */
423 :
424 : static fd_tmp_account_t *
425 : source_buffer_new_checked( fd_tmp_account_t * acc,
426 : fd_accdb_user_t * accdb,
427 : fd_funk_txn_xid_t const * xid,
428 : fd_pubkey_t const * pubkey,
429 0 : fd_hash_t const * verified_build_hash ) {
430 :
431 0 : if( FD_UNLIKELY( !tmp_account_read( acc, accdb, xid, pubkey ) ) ) {
432 : /* CoreBpfMigrationError::AccountNotFound(*buffer_address) */
433 0 : return NULL;
434 0 : }
435 :
436 0 : if( FD_UNLIKELY( 0!=memcmp( acc->meta.owner, &fd_solana_bpf_loader_upgradeable_program_id, 32 ) ) ) {
437 : /* CoreBpfMigrationError::IncorrectOwner(*buffer_address) */
438 0 : return NULL;
439 0 : }
440 :
441 0 : if( acc->data_sz < BUFFER_METADATA_SIZE ) {
442 : /* CoreBpfMigrationError::InvalidBufferAccount(*buffer_address) */
443 0 : return NULL;
444 0 : }
445 :
446 0 : fd_bpf_upgradeable_loader_state_t state[1];
447 0 : if( FD_UNLIKELY( !fd_bincode_decode_static(
448 0 : bpf_upgradeable_loader_state, state,
449 0 : acc->data, BUFFER_METADATA_SIZE ) ) ) {
450 0 : return NULL;
451 0 : }
452 :
453 0 : if( FD_UNLIKELY( state->discriminant!=fd_bpf_upgradeable_loader_state_enum_buffer ) ) {
454 : /* CoreBpfMigrationError::InvalidBufferAccount(*buffer_address) */
455 0 : return NULL;
456 0 : }
457 :
458 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L61-L71 */
459 0 : if( verified_build_hash ) {
460 : /* Strip trailing zero-padding before hashing
461 : https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L61-L63 */
462 0 : uchar const * data = (uchar const *)acc->data;
463 0 : ulong offset = BUFFER_METADATA_SIZE;
464 0 : ulong end_offset = acc->data_sz;
465 0 : while( end_offset>offset && data[end_offset-1]==0 ) end_offset--;
466 0 : uchar const * buffer_program_data = data + offset;
467 0 : ulong buffer_program_data_sz = end_offset - offset;
468 :
469 0 : fd_hash_t hash;
470 0 : fd_sha256_hash( buffer_program_data, buffer_program_data_sz, hash.uc );
471 0 : if( FD_UNLIKELY( 0!=memcmp( hash.uc, verified_build_hash->uc, FD_HASH_FOOTPRINT ) ) ) {
472 : /* CoreBpfMigrationError::BuildHashMismatch */
473 0 : return NULL;
474 0 : }
475 0 : }
476 :
477 0 : return acc;
478 0 : }
479 :
480 : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L82-L95 */
481 :
482 : static fd_tmp_account_t *
483 : new_target_program_account( fd_tmp_account_t * acc,
484 : target_builtin_t const * target,
485 0 : fd_rent_t const * rent ) {
486 : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L86-L88 */
487 0 : fd_bpf_upgradeable_loader_state_t state = {
488 0 : .discriminant = fd_bpf_upgradeable_loader_state_enum_program,
489 0 : .inner = {
490 0 : .program = {
491 0 : .programdata_address = target->program_data_address,
492 0 : }
493 0 : }
494 0 : };
495 :
496 0 : ulong state_sz = fd_bpf_upgradeable_loader_state_size( &state );
497 0 : tmp_account_new( acc, state_sz );
498 0 : acc->meta.lamports = fd_rent_exempt_minimum_balance( rent, SIZE_OF_PROGRAM );
499 0 : acc->meta.executable = 1;
500 0 : memcpy( acc->meta.owner, fd_solana_bpf_loader_upgradeable_program_id.uc, sizeof(fd_pubkey_t) );
501 :
502 0 : fd_bincode_encode_ctx_t ctx = { .data=acc->data, .dataend=(uchar *)acc->data+state_sz };
503 0 : if( FD_UNLIKELY( fd_bpf_upgradeable_loader_state_encode( &state, &ctx )!=FD_BINCODE_SUCCESS ) ) {
504 0 : FD_LOG_ERR(( "fd_bpf_upgradeable_loader_state_encode failed" ));
505 0 : }
506 :
507 0 : return acc;
508 0 : }
509 :
510 : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L108-L153 */
511 : static fd_tmp_account_t *
512 : new_target_program_data_account( fd_tmp_account_t * acc,
513 : fd_tmp_account_t const * source,
514 : fd_pubkey_t const * upgrade_authority_address,
515 : fd_rent_t const * rent,
516 0 : ulong slot ) {
517 0 : ulong const buffer_metadata_sz = BUFFER_METADATA_SIZE;
518 :
519 0 : if( FD_UNLIKELY( source->data_sz < buffer_metadata_sz ) )
520 0 : return NULL; /* CoreBpfMigrationError::InvalidBufferAccount */
521 :
522 0 : fd_bpf_upgradeable_loader_state_t state;
523 0 : if( !fd_bincode_decode_static(
524 0 : bpf_upgradeable_loader_state,
525 0 : &state,
526 0 : source->data,
527 0 : buffer_metadata_sz ) )
528 0 : return NULL;
529 :
530 0 : if( FD_UNLIKELY( state.discriminant!=fd_bpf_upgradeable_loader_state_enum_buffer ) )
531 0 : return NULL; /* CoreBpfMigrationError::InvalidBufferAccount */
532 :
533 : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L118-L125 */
534 0 : if( upgrade_authority_address ) {
535 0 : if( FD_UNLIKELY( !state.inner.buffer.has_authority_address ||
536 0 : !fd_pubkey_eq( upgrade_authority_address, &state.inner.buffer.authority_address ) ) ) {
537 0 : return NULL; /* CoreBpfMigrationError::UpgradeAuthorityMismatch */
538 0 : }
539 0 : }
540 :
541 0 : void const * elf = (uchar const *)source->data + buffer_metadata_sz;
542 0 : ulong elf_sz = /* */source->data_sz - buffer_metadata_sz;
543 :
544 0 : ulong space = PROGRAMDATA_METADATA_SIZE + elf_sz;
545 0 : ulong lamports = fd_rent_exempt_minimum_balance( rent, space );
546 0 : fd_pubkey_t owner = fd_solana_bpf_loader_upgradeable_program_id;
547 :
548 0 : fd_bpf_upgradeable_loader_state_t programdata_meta = {
549 0 : .discriminant = fd_bpf_upgradeable_loader_state_enum_program_data,
550 0 : .inner = {
551 0 : .program_data = {
552 0 : .slot = slot,
553 0 : .has_upgrade_authority_address = !!upgrade_authority_address,
554 0 : .upgrade_authority_address = upgrade_authority_address ? *upgrade_authority_address : (fd_pubkey_t){{0}}
555 0 : }
556 0 : }
557 0 : };
558 :
559 0 : tmp_account_new( acc, space );
560 0 : acc->meta.lamports = lamports;
561 0 : memcpy( acc->meta.owner, owner.uc, sizeof(fd_pubkey_t) );
562 0 : fd_bincode_encode_ctx_t ctx = { .data=acc->data, .dataend=(uchar *)acc->data+PROGRAMDATA_METADATA_SIZE };
563 0 : if( FD_UNLIKELY( fd_bpf_upgradeable_loader_state_encode( &programdata_meta, &ctx )!=FD_BINCODE_SUCCESS ) ) {
564 0 : FD_LOG_ERR(( "fd_bpf_upgradeable_loader_state_encode failed" ));
565 0 : }
566 0 : fd_memcpy( (uchar *)acc->data+PROGRAMDATA_METADATA_SIZE, elf, elf_sz );
567 :
568 0 : return acc;
569 0 : }
570 :
571 : void
572 : migrate_builtin_to_core_bpf1( fd_core_bpf_migration_config_t const * config,
573 : fd_accdb_user_t * accdb,
574 : fd_funk_txn_xid_t const * xid,
575 : fd_bank_t * bank,
576 : fd_runtime_stack_t * runtime_stack,
577 : fd_pubkey_t const * builtin_program_id,
578 0 : fd_capture_ctx_t * capture_ctx ) {
579 0 : target_builtin_t target[1];
580 0 : if( FD_UNLIKELY( !target_builtin_new_checked(
581 0 : target,
582 0 : builtin_program_id,
583 0 : config->migration_target,
584 0 : FD_FEATURE_ACTIVE_BANK( bank, relax_programdata_account_check_migration ),
585 0 : accdb,
586 0 : xid,
587 0 : runtime_stack ) ) )
588 0 : return;
589 :
590 0 : fd_tmp_account_t * source = &runtime_stack->bpf_migration.source;
591 0 : if( FD_UNLIKELY( !source_buffer_new_checked(
592 0 : source,
593 0 : accdb,
594 0 : xid,
595 0 : config->source_buffer_address,
596 0 : config->verified_build_hash ) ) )
597 0 : return;
598 :
599 0 : fd_rent_t const * rent = &bank->f.rent;
600 0 : ulong const slot = bank->f.slot;
601 :
602 0 : fd_tmp_account_t * new_target_program = &runtime_stack->bpf_migration.new_target_program;
603 0 : if( FD_UNLIKELY( !new_target_program_account(
604 0 : new_target_program,
605 0 : target,
606 0 : rent ) ) )
607 0 : return;
608 0 : new_target_program->addr = *builtin_program_id;
609 :
610 0 : fd_tmp_account_t * new_target_program_data = &runtime_stack->bpf_migration.new_target_program_data;
611 0 : if( FD_UNLIKELY( !new_target_program_data_account(
612 0 : new_target_program_data,
613 0 : source,
614 0 : config->upgrade_authority_address,
615 0 : rent,
616 0 : slot ) ) )
617 0 : return;
618 0 : new_target_program_data->addr = target->program_data_address;
619 :
620 0 : ulong old_data_sz;
621 0 : if( FD_UNLIKELY( fd_ulong_checked_add( target->program_account->data_sz, source->data_sz, &old_data_sz ) ) ) return;
622 :
623 0 : ulong new_data_sz;
624 0 : if( FD_UNLIKELY( fd_ulong_checked_add( new_target_program->data_sz, new_target_program_data->data_sz, &new_data_sz ) ) ) return;
625 :
626 0 : assert( new_target_program_data->data_sz>=PROGRAMDATA_METADATA_SIZE );
627 : /* FIXME call fd_directly_invoke_loader_v3_deploy */
628 :
629 : /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L267-L281 */
630 0 : ulong lamports_to_burn;
631 0 : if( FD_UNLIKELY( fd_ulong_checked_add( target->program_account->meta.lamports, source->meta.lamports, &lamports_to_burn ) ) ) return;
632 0 : if( FD_UNLIKELY( fd_ulong_checked_add( lamports_to_burn, target->program_data_account_lamports, &lamports_to_burn ) ) ) return;
633 :
634 0 : ulong lamports_to_fund;
635 0 : if( FD_UNLIKELY( fd_ulong_checked_add( new_target_program->meta.lamports, new_target_program_data->meta.lamports, &lamports_to_fund ) ) ) return;
636 :
637 : /* Write back accounts */
638 0 : tmp_account_store( new_target_program, accdb, xid, bank, capture_ctx );
639 0 : tmp_account_store( new_target_program_data, accdb, xid, bank, capture_ctx );
640 0 : fd_tmp_account_t * empty = &runtime_stack->bpf_migration.empty;
641 0 : tmp_account_new( empty, 0UL );
642 0 : empty->addr = source->addr;
643 0 : tmp_account_store( empty, accdb, xid, bank, capture_ctx );
644 :
645 : /* FIXME "remove the built-in program from the bank's list of builtins" */
646 : /* FIXME "update account data size delta" */
647 0 : }
648 :
649 : /* Mimics migrate_builtin_to_core_bpf().
650 : https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#215-303 */
651 : void
652 : fd_migrate_builtin_to_core_bpf( fd_bank_t * bank,
653 : fd_accdb_user_t * accdb,
654 : fd_funk_txn_xid_t const * xid,
655 : fd_runtime_stack_t * runtime_stack,
656 : fd_core_bpf_migration_config_t const * config,
657 0 : fd_capture_ctx_t * capture_ctx ) {
658 0 : migrate_builtin_to_core_bpf1( config, accdb, xid, bank, runtime_stack, config->builtin_program_id, capture_ctx );
659 0 : }
660 :
661 : /* Mimics upgrade_core_bpf_program().
662 : https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L319-L377 */
663 : void
664 : fd_upgrade_core_bpf_program( fd_bank_t * bank,
665 : fd_accdb_user_t * accdb,
666 : fd_funk_txn_xid_t const * xid,
667 : fd_runtime_stack_t * runtime_stack,
668 : fd_pubkey_t const * builtin_program_id,
669 : fd_pubkey_t const * source_buffer_address,
670 0 : fd_capture_ctx_t * capture_ctx ) {
671 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L327 */
672 0 : target_core_bpf_t target[1];
673 0 : if( FD_UNLIKELY( !target_core_bpf_new_checked( target, builtin_program_id, accdb, xid, runtime_stack ) ) ) {
674 0 : return;
675 0 : }
676 :
677 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L328 */
678 0 : fd_tmp_account_t * source = &runtime_stack->bpf_migration.source;
679 0 : if( FD_UNLIKELY( !source_buffer_new_checked( source, accdb, xid, source_buffer_address, NULL ) ) ) {
680 0 : return;
681 0 : }
682 :
683 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L331-L332 */
684 0 : fd_tmp_account_t * new_target_program_data = &runtime_stack->bpf_migration.new_target_program_data;
685 0 : fd_pubkey_t program_data_address = get_program_data_address( builtin_program_id );
686 :
687 0 : ulong program_data_len = source->data_sz - BUFFER_METADATA_SIZE;
688 0 : ulong new_account_size = PROGRAMDATA_METADATA_SIZE + program_data_len;
689 :
690 0 : tmp_account_new( new_target_program_data, new_account_size );
691 0 : new_target_program_data->addr = program_data_address;
692 :
693 0 : fd_rent_t const * rent = &bank->f.rent;
694 0 : new_target_program_data->meta.lamports = fd_rent_exempt_minimum_balance( rent, new_account_size );
695 0 : new_target_program_data->meta.executable = 0;
696 0 : fd_memcpy( new_target_program_data->meta.owner, &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_pubkey_t) );
697 :
698 0 : fd_bpf_upgradeable_loader_state_t programdata_state[1] = {{
699 0 : .discriminant = fd_bpf_upgradeable_loader_state_enum_program_data,
700 0 : .inner = { .program_data = {
701 0 : .slot = bank->f.slot,
702 0 : .upgrade_authority_address = target->upgrade_authority_address,
703 0 : .has_upgrade_authority_address = target->has_upgrade_authority_address
704 0 : }}
705 0 : }};
706 :
707 0 : fd_bincode_encode_ctx_t encode_ctx = {
708 0 : .data = new_target_program_data->data,
709 0 : .dataend = new_target_program_data->data + PROGRAMDATA_METADATA_SIZE
710 0 : };
711 0 : if( FD_UNLIKELY( FD_BINCODE_SUCCESS!=fd_bpf_upgradeable_loader_state_encode( programdata_state, &encode_ctx ) ) ) {
712 0 : return;
713 0 : }
714 :
715 0 : fd_memcpy( new_target_program_data->data + PROGRAMDATA_METADATA_SIZE,
716 0 : source->data + BUFFER_METADATA_SIZE,
717 0 : program_data_len );
718 :
719 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.4/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L339-L346 */
720 0 : ulong old_data_sz;
721 0 : if( FD_UNLIKELY( fd_ulong_checked_add( target->program_data_account->data_sz, source->data_sz, &old_data_sz ) ) ) return;
722 0 : ulong new_data_sz = new_target_program_data->data_sz;
723 :
724 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.4/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L349-L355 */
725 0 : uchar const * elf = new_target_program_data->data + PROGRAMDATA_METADATA_SIZE;
726 0 : ulong elf_sz = program_data_len;
727 0 : if( FD_UNLIKELY( fd_directly_invoke_loader_v3_deploy_checks( bank, runtime_stack, elf, elf_sz ) ) ) return;
728 :
729 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L359-L364 */
730 0 : ulong lamports_to_burn;
731 0 : if( FD_UNLIKELY( fd_ulong_checked_add( target->program_data_account->meta.lamports, source->meta.lamports, &lamports_to_burn ) ) ) return;
732 :
733 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L366-L371 */
734 0 : fd_pubkey_t source_addr = source->addr;
735 0 : tmp_account_store( new_target_program_data, accdb, xid, bank, capture_ctx );
736 :
737 0 : fd_tmp_account_t * empty = &runtime_stack->bpf_migration.empty;
738 0 : tmp_account_new( empty, 0UL );
739 0 : empty->addr = source_addr;
740 0 : tmp_account_store( empty, accdb, xid, bank, capture_ctx );
741 :
742 : /* https://github.com/anza-xyz/agave/blob/v3.1.7/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L374 */
743 : /* FIXME "update account data size delta" */
744 0 : (void)old_data_sz;
745 0 : (void)new_data_sz;
746 :
747 0 : fd_memset( &runtime_stack->bpf_migration, 0, sizeof(runtime_stack->bpf_migration) );
748 0 : }
749 :
750 : /* Mimics upgrade_loader_v2_program_with_loader_v3_program().
751 : https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L402-L474 */
752 : void
753 : fd_upgrade_loader_v2_program_with_loader_v3_program( fd_bank_t * bank,
754 : fd_accdb_user_t * accdb,
755 : fd_funk_txn_xid_t const * xid,
756 : fd_runtime_stack_t * runtime_stack,
757 : fd_pubkey_t const * loader_v2_program_address,
758 : fd_pubkey_t const * source_buffer_address,
759 : int allow_prefunded,
760 0 : fd_capture_ctx_t * capture_ctx ) {
761 :
762 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L411-L412 */
763 0 : target_builtin_t target[1];
764 0 : if( FD_UNLIKELY( !target_bpf_v2_new_checked(
765 0 : target,
766 0 : loader_v2_program_address,
767 0 : allow_prefunded,
768 0 : accdb,
769 0 : xid,
770 0 : runtime_stack ) ) )
771 0 : return;
772 :
773 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L413 */
774 0 : fd_tmp_account_t * source = &runtime_stack->bpf_migration.source;
775 0 : if( FD_UNLIKELY( !source_buffer_new_checked( source, accdb, xid, source_buffer_address, NULL ) ) )
776 0 : return;
777 :
778 0 : fd_rent_t const * rent = &bank->f.rent;
779 0 : ulong slot = bank->f.slot;
780 :
781 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L416-L417 */
782 0 : fd_tmp_account_t * new_target_program = &runtime_stack->bpf_migration.new_target_program;
783 0 : if( FD_UNLIKELY( !new_target_program_account( new_target_program, target, rent ) ) )
784 0 : return;
785 0 : new_target_program->addr = *loader_v2_program_address;
786 :
787 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L419-L421 */
788 0 : fd_tmp_account_t * new_target_program_data = &runtime_stack->bpf_migration.new_target_program_data;
789 0 : if( FD_UNLIKELY( !new_target_program_data_account( new_target_program_data, source, NULL, rent, slot ) ) ) {
790 0 : return;
791 0 : }
792 0 : new_target_program_data->addr = target->program_data_address;
793 :
794 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L427-L435 */
795 0 : ulong old_data_sz;
796 0 : if( FD_UNLIKELY( fd_ulong_checked_add( target->program_account->data_sz, source->data_sz, &old_data_sz ) ) ) return;
797 :
798 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L432-L435 */
799 0 : ulong new_data_sz;
800 0 : if( FD_UNLIKELY( fd_ulong_checked_add( new_target_program->data_sz, new_target_program_data->data_sz, &new_data_sz ) ) ) return;
801 :
802 0 : if( FD_UNLIKELY( new_target_program_data->data_sz<PROGRAMDATA_METADATA_SIZE ) ) {
803 0 : FD_LOG_CRIT(( "invariant violation: new target programdata too small" ));
804 0 : }
805 :
806 : /* Agave calls directly_invoke_loader_v3_deploy to deploy the new
807 : program to the program cache. We don't do that, but instead we
808 : perform the same checks as directly_invoke_loader_v3_deploy
809 : without modifying the program cache. We need to do the checks
810 : at this point so that we can fail the upgrade if the ELF is
811 : invalid.
812 :
813 : This is safe because the bpf migration code runs at the epoch
814 : boundary, before any transaction execution. The program cache
815 : automatically invalidates all programs at the start of an epoch
816 : boundary, so we do not need to explicitly update the cache during the
817 : migration.
818 :
819 : https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L437-L443*/
820 0 : uchar const * elf = (uchar const *)new_target_program_data->data + PROGRAMDATA_METADATA_SIZE;
821 0 : ulong elf_sz = new_target_program_data->data_sz - PROGRAMDATA_METADATA_SIZE;
822 0 : if( FD_UNLIKELY( fd_directly_invoke_loader_v3_deploy_checks( bank, runtime_stack, elf, elf_sz ) ) ) return;
823 :
824 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L451-L459 */
825 0 : ulong lamports_to_burn;
826 0 : if( FD_UNLIKELY( fd_ulong_checked_add( target->program_account->meta.lamports, source->meta.lamports, &lamports_to_burn ) ) ) return;
827 0 : if( FD_UNLIKELY( fd_ulong_checked_add( lamports_to_burn, target->program_data_account_lamports, &lamports_to_burn ) ) ) return;
828 :
829 0 : ulong lamports_to_fund;
830 0 : if( FD_UNLIKELY( fd_ulong_checked_add( new_target_program->meta.lamports, new_target_program_data->meta.lamports, &lamports_to_fund ) ) ) return;
831 :
832 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.2/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L462-L468 */
833 0 : tmp_account_store( new_target_program, accdb, xid, bank, capture_ctx );
834 0 : tmp_account_store( new_target_program_data, accdb, xid, bank, capture_ctx );
835 :
836 0 : fd_tmp_account_t * empty = &runtime_stack->bpf_migration.empty;
837 0 : tmp_account_new( empty, 0UL );
838 0 : empty->addr = source->addr;
839 0 : tmp_account_store( empty, accdb, xid, bank, capture_ctx );
840 :
841 : /* NB: Agave updates "delta_off_chain", using these two fields,
842 : which is not consensus-critical (only used for Agave stats)
843 : so we don't update this in our migration code or store this in
844 : our bank. */
845 0 : (void)old_data_sz;
846 0 : (void)new_data_sz;
847 :
848 0 : fd_memset( &runtime_stack->bpf_migration, 0, sizeof(runtime_stack->bpf_migration) );
849 0 : }
|