diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 54008b3b73..9c80e7deb4 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -2365,8 +2365,8 @@ fd_new_target_program_data_account( fd_exec_slot_ctx_t * slot_ctx, /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L118-L125 */ if( config_upgrade_authority_address!=NULL ) { - if( FD_UNLIKELY( state->inner.buffer.authority_address==NULL || - memcmp( config_upgrade_authority_address, state->inner.buffer.authority_address, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !state->inner.buffer.has_authority_address || + !fd_pubkey_eq( config_upgrade_authority_address, &state->inner.buffer.authority_address ) ) ) { return -1; } } @@ -2386,11 +2386,13 @@ fd_new_target_program_data_account( fd_exec_slot_ctx_t * slot_ctx, .discriminant = fd_bpf_upgradeable_loader_state_enum_program_data, .inner = { .program_data = { - .slot = slot_ctx->slot_bank.slot, - .upgrade_authority_address = config_upgrade_authority_address + .slot = slot_ctx->slot_bank.slot } } }; + fd_types_option_flat_from_nullable( + programdata_metadata.inner.program_data, upgrade_authority_address, + config_upgrade_authority_address ); /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L139-L144 */ new_target_program_data_account->vt->set_lamports( new_target_program_data_account, lamports ); diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index 8e1c8b29ce..b556eb015f 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -345,8 +345,8 @@ fd_bpf_loader_v3_program_set_state( fd_borrowed_account_t * borrowed_acct, /* https://github.com/anza-xyz/agave/blob/574bae8fefc0ed256b55340b9d87b7689bcdf222/programs/bpf_loader/src/lib.rs#L1299-L1331 */ static int -common_close_account( fd_pubkey_t * authority_address, - fd_exec_instr_ctx_t * instr_ctx, +common_close_account( fd_pubkey_t const * authority_address, + fd_exec_instr_ctx_t * instr_ctx, fd_bpf_upgradeable_loader_state_t * state ) { int err; @@ -666,8 +666,11 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return err; } - buffer_state->discriminant = fd_bpf_upgradeable_loader_state_enum_buffer; - buffer_state->inner.buffer.authority_address = (fd_pubkey_t*)authority_key; + buffer_state->discriminant = fd_bpf_upgradeable_loader_state_enum_buffer; + buffer_state->inner.buffer = (fd_bpf_upgradeable_loader_state_buffer_t) { + .has_authority_address = 1, + .authority_address = *authority_key, + }; err = fd_bpf_loader_v3_program_set_state( &buffer, buffer_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { @@ -696,7 +699,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } if( fd_bpf_upgradeable_loader_state_is_buffer( loader_state ) ) { - if( FD_UNLIKELY( !loader_state->inner.buffer.authority_address ) ) { + if( FD_UNLIKELY( !loader_state->inner.buffer.has_authority_address ) ) { fd_log_collector_msg_literal( instr_ctx, "Buffer is immutable" ); return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE; } @@ -708,7 +711,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return err; } - if( FD_UNLIKELY( memcmp( loader_state->inner.buffer.authority_address, authority_key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !fd_pubkey_eq( &loader_state->inner.buffer.authority_address, authority_key ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Incorrect buffer authority provided" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -841,8 +844,8 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } if( fd_bpf_upgradeable_loader_state_is_buffer( buffer_state ) ) { - if( FD_UNLIKELY( (authority_key==NULL) != (buffer_state->inner.buffer.authority_address == NULL) || - (authority_key!=NULL && memcmp( buffer_state->inner.buffer.authority_address, authority_key, sizeof(fd_pubkey_t) ) ) ) ) { + if( FD_UNLIKELY( (authority_key==NULL) != (!buffer_state->inner.buffer.has_authority_address) || + (authority_key!=NULL && !fd_pubkey_eq( &buffer_state->inner.buffer.authority_address, authority_key ) ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Buffer and upgrade authority don't match" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -1009,10 +1012,12 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_bpf_upgradeable_loader_state_t programdata_loader_state = { .discriminant = fd_bpf_upgradeable_loader_state_enum_program_data, .inner.program_data = { - .slot = clock->slot, - .upgrade_authority_address = (fd_pubkey_t *)authority_key, + .slot = clock->slot }, }; + fd_types_option_flat_from_nullable( + programdata_loader_state.inner.program_data, upgrade_authority_address, + authority_key ); err = fd_bpf_loader_v3_program_set_state( &programdata, &programdata_loader_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; @@ -1171,8 +1176,8 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return err; } if( fd_bpf_upgradeable_loader_state_is_buffer( buffer_state ) ) { - if( FD_UNLIKELY( (authority_key==NULL) != (buffer_state->inner.buffer.authority_address == NULL) || - (authority_key!=NULL && memcmp( buffer_state->inner.buffer.authority_address, authority_key, sizeof(fd_pubkey_t) ) ) ) ) { + if( FD_UNLIKELY( (authority_key==NULL) != (!buffer_state->inner.buffer.has_authority_address) || + (authority_key!=NULL && !fd_pubkey_eq( &buffer_state->inner.buffer.authority_address, authority_key ) ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Buffer and upgrade authority don't match" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -1234,11 +1239,11 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "Program was deployed in this block already" ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } - if( FD_UNLIKELY( !programdata_state->inner.program_data.upgrade_authority_address ) ) { + if( FD_UNLIKELY( !programdata_state->inner.program_data.has_upgrade_authority_address ) ) { fd_log_collector_msg_literal( instr_ctx, "Prrogram not upgradeable" ); return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE; } - if( FD_UNLIKELY( memcmp( programdata_state->inner.program_data.upgrade_authority_address, authority_key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !fd_pubkey_eq( &programdata_state->inner.program_data.upgrade_authority_address, authority_key ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Incorrect upgrade authority provided" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -1279,9 +1284,11 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/574bae8fefc0ed256b55340b9d87b7689bcdf222/programs/bpf_loader/src/lib.rs#L846-L874 */ /* Update the ProgramData account, record the upgraded data, and zero the rest in a local scope */ do { - programdata_state->discriminant = fd_bpf_upgradeable_loader_state_enum_program_data; - programdata_state->inner.program_data.slot = clock->slot; - programdata_state->inner.program_data.upgrade_authority_address = (fd_pubkey_t *)authority_key; + programdata_state->discriminant = fd_bpf_upgradeable_loader_state_enum_program_data; + programdata_state->inner.program_data.slot = clock->slot; + fd_types_option_flat_from_nullable( + programdata_state->inner.program_data, upgrade_authority_address, + authority_key ); err = fd_bpf_loader_v3_program_set_state( &programdata, programdata_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; @@ -1393,11 +1400,11 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "Buffer authority is not optional" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } - if( FD_UNLIKELY( !account_state->inner.buffer.authority_address ) ) { + if( FD_UNLIKELY( !account_state->inner.buffer.has_authority_address ) ) { fd_log_collector_msg_literal( instr_ctx, "Buffer is immutable" ); return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE; } - if( FD_UNLIKELY( memcmp( account_state->inner.buffer.authority_address, present_authority_key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !fd_pubkey_eq( &account_state->inner.buffer.authority_address, present_authority_key ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Incorrect buffer authority provided" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -1408,18 +1415,18 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* copy in the authority public key into the authority address. https://github.com/anza-xyz/agave/blob/v2.1.14/programs/bpf_loader/src/lib.rs#L926-L928 */ - memcpy( account_state->inner.buffer.authority_address, new_authority, sizeof(fd_pubkey_t) ); + account_state->inner.buffer.authority_address = *new_authority; err = fd_bpf_loader_v3_program_set_state( &account, account_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } } else if( fd_bpf_upgradeable_loader_state_is_program_data( account_state ) ) { - if( FD_UNLIKELY( !account_state->inner.program_data.upgrade_authority_address ) ) { + if( FD_UNLIKELY( !account_state->inner.program_data.has_upgrade_authority_address ) ) { fd_log_collector_msg_literal( instr_ctx, "Program not upgradeable" ); return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE; } - if( FD_UNLIKELY( memcmp( account_state->inner.program_data.upgrade_authority_address, present_authority_key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !fd_pubkey_eq( &account_state->inner.program_data.upgrade_authority_address, present_authority_key ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Incorrect upgrade authority provided" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -1430,11 +1437,9 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* copy in the authority public key into the upgrade authority address. https://github.com/anza-xyz/agave/blob/v2.1.14/programs/bpf_loader/src/lib.rs#L946-L949 */ - if( new_authority ) { - memcpy( account_state->inner.program_data.upgrade_authority_address, new_authority, sizeof(fd_pubkey_t) ); - } else { - account_state->inner.program_data.upgrade_authority_address = NULL; - } + fd_types_option_flat_from_nullable( + account_state->inner.program_data, upgrade_authority_address, + new_authority ); err = fd_bpf_loader_v3_program_set_state( &account, account_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { @@ -1488,11 +1493,11 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } if( fd_bpf_upgradeable_loader_state_is_buffer( account_state ) ) { - if( FD_UNLIKELY( !account_state->inner.buffer.authority_address ) ) { + if( FD_UNLIKELY( !account_state->inner.buffer.has_authority_address ) ) { fd_log_collector_msg_literal( instr_ctx, "Buffer is immutable" ); return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE; } - if( FD_UNLIKELY( memcmp( account_state->inner.buffer.authority_address, present_authority_key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !fd_pubkey_eq( &account_state->inner.buffer.authority_address, present_authority_key ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Incorrect buffer authority provided" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -1504,17 +1509,17 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "New authority did not sign" ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } - account_state->inner.buffer.authority_address = (fd_pubkey_t*)new_authority_key; + account_state->inner.buffer.authority_address = *new_authority_key; err = fd_bpf_loader_v3_program_set_state( &account, account_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } } else if( fd_bpf_upgradeable_loader_state_is_program_data( account_state ) ) { - if( FD_UNLIKELY( !account_state->inner.program_data.upgrade_authority_address ) ) { + if( FD_UNLIKELY( !account_state->inner.program_data.has_upgrade_authority_address ) ) { fd_log_collector_msg_literal( instr_ctx, "Program not upgradeable" ); return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE; } - if( FD_UNLIKELY( memcmp( account_state->inner.program_data.upgrade_authority_address, present_authority_key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !fd_pubkey_eq( &account_state->inner.program_data.upgrade_authority_address, present_authority_key ) ) ) { fd_log_collector_msg_literal( instr_ctx, "Incorrect upgrade authority provided" ); return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY; } @@ -1526,7 +1531,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "New authority did not sign" ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } - account_state->inner.program_data.upgrade_authority_address = (fd_pubkey_t*)new_authority_key; + account_state->inner.program_data.upgrade_authority_address = *new_authority_key; err = fd_bpf_loader_v3_program_set_state( &account, account_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; @@ -1604,7 +1609,8 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS; } - err = common_close_account( close_account_state->inner.buffer.authority_address, instr_ctx, close_account_state ); + fd_pubkey_t const * maybe_authority_address = fd_types_option_flat_to_nullable( close_account_state->inner.buffer, authority_address ); + err = common_close_account( maybe_authority_address, instr_ctx, close_account_state ); if( FD_UNLIKELY( err ) ) { return err; } @@ -1657,9 +1663,9 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L1105 */ fd_borrowed_account_drop( &program_account ); - err = common_close_account( close_account_state->inner.program_data.upgrade_authority_address, - instr_ctx, - close_account_state ); + fd_pubkey_t const * maybe_authority_address = fd_types_option_flat_to_nullable( + close_account_state->inner.program_data, upgrade_authority_address ); + err = common_close_account( maybe_authority_address, instr_ctx, close_account_state ); if( FD_UNLIKELY( err ) ) { return err; } @@ -1773,11 +1779,11 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } - if( FD_UNLIKELY( !programdata_state->inner.program_data.upgrade_authority_address ) ) { + if( FD_UNLIKELY( !programdata_state->inner.program_data.has_upgrade_authority_address ) ) { fd_log_collector_msg_literal( instr_ctx, "Cannot extend ProgramData accounts that are not upgradeable" ); return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE; } - upgrade_authority_address = programdata_state->inner.program_data.upgrade_authority_address; + upgrade_authority_address = &programdata_state->inner.program_data.upgrade_authority_address; } else { fd_log_collector_msg_literal( instr_ctx, "ProgramData state is invalid" ); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; @@ -1881,9 +1887,11 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L1283-L1284 */ FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &programdata_account ); - programdata_state->discriminant = fd_bpf_upgradeable_loader_state_enum_program_data; - programdata_state->inner.program_data.slot = clock->slot; - programdata_state->inner.program_data.upgrade_authority_address = upgrade_authority_address; + programdata_state->discriminant = fd_bpf_upgradeable_loader_state_enum_program_data; + programdata_state->inner.program_data.slot = clock->slot; + fd_types_option_flat_from_nullable( + programdata_state->inner.program_data, upgrade_authority_address, + upgrade_authority_address ); err = fd_bpf_loader_v3_program_set_state( &programdata_account, programdata_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { @@ -1950,8 +1958,8 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1368-L1387 */ - ulong program_len = 0UL; - fd_pubkey_t * upgrade_authority_address = NULL; + ulong program_len = 0UL; + fd_pubkey_t const * upgrade_authority_address = NULL; fd_bpf_upgradeable_loader_state_t * programdata_state = fd_bpf_loader_program_get_state( programdata.acct, spad, &err ); if( FD_LIKELY( err==FD_BINCODE_SUCCESS && fd_bpf_upgradeable_loader_state_is_program_data( programdata_state ) ) ) { @@ -1963,7 +1971,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1378-L1384 */ program_len = fd_ulong_sat_sub( fd_borrowed_account_get_data_len( &programdata ), PROGRAMDATA_METADATA_SIZE ); - upgrade_authority_address = programdata_state->inner.program_data.upgrade_authority_address; + upgrade_authority_address = fd_types_option_flat_to_nullable( programdata_state->inner.program_data, upgrade_authority_address ); } /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1388 */ diff --git a/src/flamenco/runtime/program/fd_bpf_program_util.c b/src/flamenco/runtime/program/fd_bpf_program_util.c index a3c7953288..790c936eb6 100644 --- a/src/flamenco/runtime/program/fd_bpf_program_util.c +++ b/src/flamenco/runtime/program/fd_bpf_program_util.c @@ -82,17 +82,17 @@ static int fd_bpf_get_executable_program_content_for_upgradeable_loader( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * program_acc, uchar const ** program_data, - ulong * program_data_len, - fd_spad_t * runtime_spad ) { + ulong * program_data_len ) { FD_TXN_ACCOUNT_DECL( programdata_acc ); - fd_bpf_upgradeable_loader_state_t * program_account_state = - fd_bincode_decode_spad( - bpf_upgradeable_loader_state, runtime_spad, + fd_bpf_upgradeable_loader_state_t program_account_state[1]; + if( FD_UNLIKELY( !fd_bincode_decode_flat( + program_account_state, + bpf_upgradeable_loader_state, program_acc->vt->get_data( program_acc ), program_acc->vt->get_data_len( program_acc ), - NULL ); - if( FD_UNLIKELY( !program_account_state ) ) { + NULL + ) ) ) { return -1; } if( !fd_bpf_upgradeable_loader_state_is_program( program_account_state ) ) { @@ -182,7 +182,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx, int res; if( !memcmp( program_acc->vt->get_owner( program_acc ), fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) { - res = fd_bpf_get_executable_program_content_for_upgradeable_loader( slot_ctx, program_acc, &program_data, &program_data_len, runtime_spad ); + res = fd_bpf_get_executable_program_content_for_upgradeable_loader( slot_ctx, program_acc, &program_data, &program_data_len ); } else if( !memcmp( program_acc->vt->get_owner( program_acc ), fd_solana_bpf_loader_v4_program_id.key, sizeof(fd_pubkey_t) ) ) { res = fd_bpf_get_executable_program_content_for_v4_loader( program_acc, &program_data, &program_data_len ); } else { diff --git a/src/flamenco/runtime/program/fd_builtin_programs.h b/src/flamenco/runtime/program/fd_builtin_programs.h index 64c00b3f16..355b46dd21 100644 --- a/src/flamenco/runtime/program/fd_builtin_programs.h +++ b/src/flamenco/runtime/program/fd_builtin_programs.h @@ -3,9 +3,6 @@ #include "../../fd_flamenco_base.h" #include "../../runtime/fd_system_ids.h" -#include "../../features/fd_features.h" -#include "../context/fd_exec_epoch_ctx.h" -#include "../context/fd_exec_slot_ctx.h" #include "../fd_system_ids.h" #include "../fd_system_ids_pp.h" diff --git a/src/flamenco/types/fd_bincode.h b/src/flamenco/types/fd_bincode.h index 6c31273cd0..ea5720ad7a 100644 --- a/src/flamenco/types/fd_bincode.h +++ b/src/flamenco/types/fd_bincode.h @@ -2,7 +2,6 @@ #define HEADER_fd_src_util_encoders_fd_bincode_h #include "../../util/fd_util.h" -#include "../../util/valloc/fd_valloc.h" typedef void (* fd_types_walk_fn_t)( void * self, @@ -552,4 +551,58 @@ static inline int fd_archive_decode_check_length( fd_bincode_decode_ctx_t * ctx, #define fd_bincode_decode_scratch( type, buf, buf_sz, perr ) \ fd_bincode_decode1_scratch( type, buf, buf_sz, perr, NULL ) +/* fd_bincode_decode_flat decodes a bincode type without dynamic + allocations. */ + +#define fd_bincode_decode_flat( outp, type, buf, buf_sz, perr ) \ + __extension__({ \ + __typeof__(*outp) * const outp_ = (outp); \ + __typeof__(*outp_) * out = NULL; \ + void const * const buf_ = (buf); \ + ulong const buf_sz_ = (buf_sz); \ + int * perr_ = (perr); \ + fd_bincode_decode_ctx_t ctx = {0}; \ + if( perr_ ) *perr_ = -1; \ + ctx.data = (void const *)( buf_ ); \ + ctx.dataend = (void const *)( (ulong)ctx.data + buf_sz_ ); \ + ulong total_sz = 0UL; \ + int err = fd_##type##_decode_footprint( &ctx, &total_sz ); \ + if( FD_LIKELY( err==FD_BINCODE_SUCCESS ) ) { \ + if( FD_UNLIKELY( sizeof(*out)!=total_sz ) ) { \ + FD_LOG_ERR(( "fd_bincode_" #type "_decode failed: decode requires %lu bytes, but out var is only %lu bytes", sizeof(*out), total_sz )); \ + } \ + out = fd_##type##_decode( outp_, &ctx ); \ + } \ + if( perr_ ) *perr_ = err; \ + out; \ + }) + +#define fd_bincode_decode_scratch( type, buf, buf_sz, perr ) \ + fd_bincode_decode1_scratch( type, buf, buf_sz, perr, NULL ) + +/* Helpers for dealing with option types */ + +/* fd_types_option_flat_from_nullable populates a flat option from a + pointer. Sets target.has_name = 0 if pointer is NULL, otherwise sets + target.has_name = 1, and sets target.name = *pointer */ + +#define fd_types_option_flat_from_nullable( target, name, pointer ) \ + { \ + __typeof__ (pointer) ptr = (pointer); \ + (target . has_##name) = !!ptr; \ + if( ptr ) (target . name) = *ptr; \ + } + +/* fd_types_option_flat_to_nullable creates a nullable pointer to a flat + option. Returns NULL if target.has_name == 0, otherwise returns + &target.name */ + +#define fd_types_option_flat_to_nullable( target, name ) \ + __extension__({ \ + __typeof__( &( (target . name) ) ) ptr; \ + if( (target . has_##name) ) ptr = &(target . name); \ + else ptr = NULL; \ + ptr; \ + }) + #endif /* HEADER_fd_src_util_encoders_fd_bincode_h */ diff --git a/src/flamenco/types/fd_fuzz_types.h b/src/flamenco/types/fd_fuzz_types.h index d0096a59e1..ae95ffec71 100644 --- a/src/flamenco/types/fd_fuzz_types.h +++ b/src/flamenco/types/fd_fuzz_types.h @@ -2748,15 +2748,9 @@ void *fd_bpf_upgradeable_loader_state_buffer_generate( void *mem, void **alloc_m *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_bpf_upgradeable_loader_state_buffer_t); fd_bpf_upgradeable_loader_state_buffer_new(mem); { - uchar is_null = fd_rng_uchar( rng ) % 2; - if( !is_null ) { - self->authority_address = (fd_pubkey_t *) *alloc_mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_pubkey_t); - fd_pubkey_new( self->authority_address ); - fd_pubkey_generate( self->authority_address, alloc_mem, rng ); - } - else { - self->authority_address = NULL; + self->has_authority_address = fd_rng_uchar( rng ) % 2; + if( self->has_authority_address ) { + fd_pubkey_generate( &self->authority_address, alloc_mem, rng ); } } return mem; @@ -2776,15 +2770,9 @@ void *fd_bpf_upgradeable_loader_state_program_data_generate( void *mem, void **a fd_bpf_upgradeable_loader_state_program_data_new(mem); self->slot = fd_rng_ulong( rng ); { - uchar is_null = fd_rng_uchar( rng ) % 2; - if( !is_null ) { - self->upgrade_authority_address = (fd_pubkey_t *) *alloc_mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_pubkey_t); - fd_pubkey_new( self->upgrade_authority_address ); - fd_pubkey_generate( self->upgrade_authority_address, alloc_mem, rng ); - } - else { - self->upgrade_authority_address = NULL; + self->has_upgrade_authority_address = fd_rng_uchar( rng ) % 2; + if( self->has_upgrade_authority_address ) { + fd_pubkey_generate( &self->upgrade_authority_address, alloc_mem, rng ); } } return mem; diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index a614563beb..f2330ac313 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -15651,13 +15651,10 @@ int fd_bpf_upgradeable_loader_program_instruction_encode( fd_bpf_upgradeable_loa int fd_bpf_upgradeable_loader_state_buffer_encode( fd_bpf_upgradeable_loader_state_buffer_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - if( self->authority_address != NULL ) { - err = fd_bincode_bool_encode( 1, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_pubkey_encode( self->authority_address, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } else { - err = fd_bincode_bool_encode( 0, ctx ); + err = fd_bincode_bool_encode( self->has_authority_address, ctx ); + if( FD_UNLIKELY( err ) ) return err; + if( self->has_authority_address ) { + err = fd_pubkey_encode( &self->authority_address, ctx ); if( FD_UNLIKELY( err ) ) return err; } return FD_BINCODE_SUCCESS; @@ -15670,7 +15667,6 @@ static int fd_bpf_upgradeable_loader_state_buffer_decode_footprint_inner( fd_bin err = fd_bincode_bool_decode( &o, ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; if( o ) { - *total_sz += FD_PUBKEY_ALIGN + sizeof(fd_pubkey_t); err = fd_pubkey_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } @@ -15690,14 +15686,10 @@ static void fd_bpf_upgradeable_loader_state_buffer_decode_inner( void * struct_m { uchar o; fd_bincode_bool_decode_unsafe( &o, ctx ); + self->has_authority_address = !!o; if( o ) { - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, FD_PUBKEY_ALIGN ); - self->authority_address = *alloc_mem; - *alloc_mem = (uchar *)*alloc_mem + sizeof(fd_pubkey_t); - fd_pubkey_new( self->authority_address ); - fd_pubkey_decode_inner( self->authority_address, alloc_mem, ctx ); - } else { - self->authority_address = NULL; + fd_pubkey_new( &self->authority_address ); + fd_pubkey_decode_inner( &self->authority_address, alloc_mem, ctx ); } } } @@ -15714,18 +15706,18 @@ void fd_bpf_upgradeable_loader_state_buffer_new(fd_bpf_upgradeable_loader_state_ } void fd_bpf_upgradeable_loader_state_buffer_walk( void * w, fd_bpf_upgradeable_loader_state_buffer_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_bpf_upgradeable_loader_state_buffer", level++ ); - if( !self->authority_address ) { + if( !self->has_authority_address ) { fun( w, NULL, "authority_address", FD_FLAMENCO_TYPE_NULL, "pubkey", level ); } else { - fd_pubkey_walk( w, self->authority_address, fun, "authority_address", level ); + fd_pubkey_walk( w, &self->authority_address, fun, "authority_address", level ); } fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_bpf_upgradeable_loader_state_buffer", level-- ); } ulong fd_bpf_upgradeable_loader_state_buffer_size( fd_bpf_upgradeable_loader_state_buffer_t const * self ) { ulong size = 0; size += sizeof(char); - if( NULL != self->authority_address ) { - size += fd_pubkey_size( self->authority_address ); + if( self->has_authority_address ) { + size += fd_pubkey_size( &self->authority_address ); } return size; } @@ -15768,13 +15760,10 @@ int fd_bpf_upgradeable_loader_state_program_data_encode( fd_bpf_upgradeable_load int err; err = fd_bincode_uint64_encode( self->slot, ctx ); if( FD_UNLIKELY( err ) ) return err; - if( self->upgrade_authority_address != NULL ) { - err = fd_bincode_bool_encode( 1, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_pubkey_encode( self->upgrade_authority_address, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } else { - err = fd_bincode_bool_encode( 0, ctx ); + err = fd_bincode_bool_encode( self->has_upgrade_authority_address, ctx ); + if( FD_UNLIKELY( err ) ) return err; + if( self->has_upgrade_authority_address ) { + err = fd_pubkey_encode( &self->upgrade_authority_address, ctx ); if( FD_UNLIKELY( err ) ) return err; } return FD_BINCODE_SUCCESS; @@ -15789,7 +15778,6 @@ static int fd_bpf_upgradeable_loader_state_program_data_decode_footprint_inner( err = fd_bincode_bool_decode( &o, ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; if( o ) { - *total_sz += FD_PUBKEY_ALIGN + sizeof(fd_pubkey_t); err = fd_pubkey_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } @@ -15810,14 +15798,10 @@ static void fd_bpf_upgradeable_loader_state_program_data_decode_inner( void * st { uchar o; fd_bincode_bool_decode_unsafe( &o, ctx ); + self->has_upgrade_authority_address = !!o; if( o ) { - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, FD_PUBKEY_ALIGN ); - self->upgrade_authority_address = *alloc_mem; - *alloc_mem = (uchar *)*alloc_mem + sizeof(fd_pubkey_t); - fd_pubkey_new( self->upgrade_authority_address ); - fd_pubkey_decode_inner( self->upgrade_authority_address, alloc_mem, ctx ); - } else { - self->upgrade_authority_address = NULL; + fd_pubkey_new( &self->upgrade_authority_address ); + fd_pubkey_decode_inner( &self->upgrade_authority_address, alloc_mem, ctx ); } } } @@ -15835,10 +15819,10 @@ void fd_bpf_upgradeable_loader_state_program_data_new(fd_bpf_upgradeable_loader_ void fd_bpf_upgradeable_loader_state_program_data_walk( void * w, fd_bpf_upgradeable_loader_state_program_data_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_bpf_upgradeable_loader_state_program_data", level++ ); fun( w, &self->slot, "slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - if( !self->upgrade_authority_address ) { + if( !self->has_upgrade_authority_address ) { fun( w, NULL, "upgrade_authority_address", FD_FLAMENCO_TYPE_NULL, "pubkey", level ); } else { - fd_pubkey_walk( w, self->upgrade_authority_address, fun, "upgrade_authority_address", level ); + fd_pubkey_walk( w, &self->upgrade_authority_address, fun, "upgrade_authority_address", level ); } fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_bpf_upgradeable_loader_state_program_data", level-- ); } @@ -15846,8 +15830,8 @@ ulong fd_bpf_upgradeable_loader_state_program_data_size( fd_bpf_upgradeable_load ulong size = 0; size += sizeof(ulong); size += sizeof(char); - if( NULL != self->upgrade_authority_address ) { - size += fd_pubkey_size( self->upgrade_authority_address ); + if( self->has_upgrade_authority_address ) { + size += fd_pubkey_size( &self->upgrade_authority_address ); } return size; } diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index cacd41fc9e..fe50370318 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -2262,7 +2262,8 @@ typedef struct fd_bpf_upgradeable_loader_program_instruction fd_bpf_upgradeable_ /* Encoded Size: Dynamic */ struct fd_bpf_upgradeable_loader_state_buffer { - fd_pubkey_t * authority_address; + fd_pubkey_t authority_address; + uchar has_authority_address; }; typedef struct fd_bpf_upgradeable_loader_state_buffer fd_bpf_upgradeable_loader_state_buffer_t; #define FD_BPF_UPGRADEABLE_LOADER_STATE_BUFFER_ALIGN alignof(fd_bpf_upgradeable_loader_state_buffer_t) @@ -2277,7 +2278,8 @@ typedef struct fd_bpf_upgradeable_loader_state_program fd_bpf_upgradeable_loader /* Encoded Size: Dynamic */ struct fd_bpf_upgradeable_loader_state_program_data { ulong slot; - fd_pubkey_t * upgrade_authority_address; + fd_pubkey_t upgrade_authority_address; + uchar has_upgrade_authority_address; }; typedef struct fd_bpf_upgradeable_loader_state_program_data fd_bpf_upgradeable_loader_state_program_data_t; #define FD_BPF_UPGRADEABLE_LOADER_STATE_PROGRAM_DATA_ALIGN alignof(fd_bpf_upgradeable_loader_state_program_data_t) diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index 0b06b72349..70137fee8f 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -1785,7 +1785,7 @@ "name": "bpf_upgradeable_loader_state_buffer", "type": "struct", "fields": [ - { "name": "authority_address", "type": "option", "element": "pubkey" } + { "name": "authority_address", "type": "option", "element": "pubkey", "flat": true } ] }, { @@ -1800,7 +1800,7 @@ "type": "struct", "fields": [ { "name": "slot", "type": "ulong" }, - { "name": "upgrade_authority_address", "type": "option", "element": "pubkey" } + { "name": "upgrade_authority_address", "type": "option", "element": "pubkey", "flat": true } ] }, {