diff --git a/src/discof/bank/fd_bank_tile.c b/src/discof/bank/fd_bank_tile.c index dd93193580..90ef6c1282 100644 --- a/src/discof/bank/fd_bank_tile.c +++ b/src/discof/bank/fd_bank_tile.c @@ -274,7 +274,7 @@ handle_microblock( fd_bank_ctx_t * ctx, that first the non-alt accounts are laid out, then the writable alt accounts, and finally the read-only alt accounts. */ fd_txn_t * txn_descriptor = TXN( txn_in->txn ); - fd_acct_addr_t const * writable_alt = fd_type_pun_const( txn_out->accounts.account_keys+txn_descriptor->acct_addr_cnt ); + fd_acct_addr_t const * writable_alt = fd_type_pun_const( txn_out->accounts.keys+txn_descriptor->acct_addr_cnt ); if( FD_LIKELY( ctx->enable_rebates ) ) fd_pack_rebate_sum_add_txn( ctx->rebater, txn, &writable_alt, 1UL ); /* The VM will stop executing and fail an instruction immediately if @@ -390,7 +390,7 @@ handle_bundle( fd_bank_ctx_t * ctx, continue; } - writable_alt[i] = fd_type_pun_const( txn_out->accounts.account_keys+TXN( txn_in->txn )->acct_addr_cnt ); + writable_alt[i] = fd_type_pun_const( txn_out->accounts.keys+TXN( txn_in->txn )->acct_addr_cnt ); } /* If all of the transactions in the bundle executed successfully, we @@ -596,12 +596,13 @@ unprivileged_init( fd_topo_t * topo, } } - ctx->runtime->accdb = accdb; - ctx->runtime->funk = fd_accdb_user_v1_funk( accdb ); - ctx->runtime->progcache = progcache; - ctx->runtime->status_cache = txncache; - ctx->runtime->log.log_collector = ctx->log_collector; + ctx->runtime->accdb = accdb; + ctx->runtime->funk = fd_accdb_user_v1_funk( accdb ); + ctx->runtime->progcache = progcache; + ctx->runtime->status_cache = txncache; + ctx->runtime->log.log_collector = ctx->log_collector; ctx->runtime->log.enable_log_collector = 0; + ctx->runtime->log.capture_ctx = NULL; ulong banks_obj_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "banks" ); FD_TEST( banks_obj_id!=ULONG_MAX ); diff --git a/src/discof/exec/fd_exec_tile.c b/src/discof/exec/fd_exec_tile.c index 384c3bccd7..084a89e83e 100644 --- a/src/discof/exec/fd_exec_tile.c +++ b/src/discof/exec/fd_exec_tile.c @@ -311,6 +311,8 @@ unprivileged_init( fd_topo_t * topo, ctx->runtime->log.enable_log_collector = 0; ctx->runtime->log.dumping_mem = ctx->dumping_mem; ctx->runtime->log.tracing_mem = &ctx->tracing_mem[0][0]; + ctx->runtime->log.capture_ctx = ctx->capture_ctx; + ctx->runtime->log.enable_vm_tracing = 0; } /* Publish the next account update event buffered in the capture tile to the replay tile diff --git a/src/flamenco/fd_flamenco_base.h b/src/flamenco/fd_flamenco_base.h index 87ac0713ae..38ed53872b 100644 --- a/src/flamenco/fd_flamenco_base.h +++ b/src/flamenco/fd_flamenco_base.h @@ -116,6 +116,11 @@ struct fd_account_meta { }; typedef struct fd_account_meta fd_account_meta_t; +FD_FN_PURE static inline uchar * +fd_account_data( fd_account_meta_t const * acc ) { + return (uchar *)( acc+1 ); +} + FD_PROTOTYPES_BEGIN /* fd_acct_addr_cstr converts the given Solana address into a base58- diff --git a/src/flamenco/log_collector/fd_log_collector.h b/src/flamenco/log_collector/fd_log_collector.h index d59645c0df..1fc1b45242 100644 --- a/src/flamenco/log_collector/fd_log_collector.h +++ b/src/flamenco/log_collector/fd_log_collector.h @@ -387,7 +387,7 @@ fd_log_collector_program_invoke( fd_exec_instr_ctx_t * ctx ) { return; } - fd_pubkey_t const * program_id_pubkey = &ctx->txn_out->accounts.account_keys[ ctx->instr->program_id ]; + fd_pubkey_t const * program_id_pubkey = &ctx->txn_out->accounts.keys[ ctx->instr->program_id ]; /* Cache ctx->program_id_base58 */ fd_base58_encode_32( program_id_pubkey->uc, NULL, ctx->program_id_base58 ); /* Max msg_sz: 22 - 4 + 44 + 10 = 72 < 127 => we can use printf */ diff --git a/src/flamenco/progcache/fd_prog_load.c b/src/flamenco/progcache/fd_prog_load.c index fa17e0c980..04e8f599f0 100644 --- a/src/flamenco/progcache/fd_prog_load.c +++ b/src/flamenco/progcache/fd_prog_load.c @@ -18,7 +18,7 @@ fd_get_executable_program_content_for_v4_loader( fd_txn_account_t const * progra int err; /* Get the current loader v4 state. This implicitly also checks the dlen. */ - fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program_acc, &err ); + fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program_acc->meta, &err ); if( FD_UNLIKELY( err ) ) { return NULL; } diff --git a/src/flamenco/progcache/test_progcache_common.c b/src/flamenco/progcache/test_progcache_common.c index 09242e41d2..a661a17756 100644 --- a/src/flamenco/progcache/test_progcache_common.c +++ b/src/flamenco/progcache/test_progcache_common.c @@ -140,8 +140,6 @@ create_test_account( test_env_t * env, fd_txn_account_set_data( acc, data, data_len ); } - acc->starting_lamports = 1UL; - acc->starting_dlen = data_len; fd_txn_account_set_lamports( acc, 1UL ); fd_txn_account_set_executable( acc, executable ); fd_txn_account_set_owner( acc, &owner ); diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index 41c993dcf9..0f3ec14394 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -819,7 +819,7 @@ calculate_rewards_and_distribute_vote_rewards( fd_bank_t * ba FD_LOG_ERR(( "Adding lamports to vote account would cause overflow" )); } - fd_hashes_update_lthash( vote_rec, prev_hash,bank, capture_ctx ); + fd_hashes_update_lthash( vote_rec->pubkey, vote_rec->meta, prev_hash,bank, capture_ctx ); fd_txn_account_mutable_fini( vote_rec, accdb, &prepare ); distributed_rewards = fd_ulong_sat_add( distributed_rewards, rewards ); @@ -882,7 +882,7 @@ distribute_epoch_reward_to_stake_acc( fd_bank_t * bank, fd_txn_account_set_slot( stake_acc_rec, fd_bank_slot_get( bank ) ); fd_stake_state_v2_t stake_state[1] = {0}; - if( fd_stake_get_state( stake_acc_rec, stake_state ) != 0 ) { + if( fd_stake_get_state( stake_acc_rec->meta, stake_state ) != 0 ) { FD_LOG_DEBUG(( "failed to read stake state for %s", FD_BASE58_ENC_32_ALLOCA( stake_pubkey ) )); return 1; } @@ -932,7 +932,7 @@ distribute_epoch_reward_to_stake_acc( fd_bank_t * bank, FD_LOG_ERR(( "write_stake_state failed" )); } - fd_hashes_update_lthash( stake_acc_rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( stake_acc_rec->pubkey, stake_acc_rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( stake_acc_rec, accdb, &prepare ); return 0; diff --git a/src/flamenco/runtime/context/fd_exec_instr_ctx.c b/src/flamenco/runtime/context/fd_exec_instr_ctx.c index 9f8087d712..ceb0f84035 100644 --- a/src/flamenco/runtime/context/fd_exec_instr_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_instr_ctx.c @@ -7,7 +7,7 @@ fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx, fd_pubkey_t const * pubkey ) { for( int i=0; iinstr->acct_cnt; i++ ) { ushort idx_in_txn = ctx->instr->accounts[ i ].index_in_transaction; - if( memcmp( pubkey->uc, ctx->txn_out->accounts.account_keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { + if( memcmp( pubkey->uc, ctx->txn_out->accounts.keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { return i; } } @@ -46,11 +46,9 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, fd_borrowed_account_t * account ) { /* Get the account from the transaction context using idx_in_txn. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L600-L602 */ - fd_txn_account_t * txn_account = NULL; int err = fd_runtime_get_account_at_index( ctx->txn_in, ctx->txn_out, idx_in_txn, - &txn_account, NULL ); if( FD_UNLIKELY( err ) ) { /* Return a MissingAccount error if the account is not found. @@ -59,19 +57,23 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } + fd_account_meta_t * meta = ctx->txn_out->accounts.metas[idx_in_txn]; + /* Return an AccountBorrowFailed error if the write is not acquirable. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L605 */ - int borrow_res = fd_txn_account_try_borrow_mut( txn_account ); - if( FD_UNLIKELY( !borrow_res ) ) { + if( FD_UNLIKELY( ctx->runtime->accounts.refcnt[idx_in_txn]!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED; } + ctx->runtime->accounts.refcnt[idx_in_txn]++; /* Create a BorrowedAccount upon success. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */ fd_borrowed_account_init( account, - txn_account, + &ctx->txn_out->accounts.keys[idx_in_txn], + meta, ctx, - idx_in_instr ); + idx_in_instr, + &ctx->runtime->accounts.refcnt[idx_in_txn] ); return FD_EXECUTOR_INSTR_SUCCESS; } @@ -101,7 +103,7 @@ fd_exec_instr_ctx_try_borrow_instr_account_with_key( fd_exec_instr_ctx_t const * fd_borrowed_account_t * account ) { for( ushort i=0; iinstr->acct_cnt; i++ ) { ushort idx_in_txn = ctx->instr->accounts[ i ].index_in_transaction; - if( memcmp( pubkey->uc, ctx->txn_out->accounts.account_keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { + if( memcmp( pubkey->uc, ctx->txn_out->accounts.keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { return fd_exec_instr_ctx_try_borrow_instr_account( ctx, i, account ); } } @@ -148,7 +150,7 @@ fd_exec_instr_ctx_any_signed( fd_exec_instr_ctx_t const * ctx, ushort idx_in_txn = ctx->instr->accounts[ j ].index_in_transaction; is_signer |= ( ( !!fd_instr_acc_is_signer_idx( ctx->instr, j, NULL ) ) & - ( 0==memcmp( pubkey->key, ctx->txn_out->accounts.account_keys[ idx_in_txn ].key, sizeof(fd_pubkey_t) ) ) ); + ( 0==memcmp( pubkey->key, ctx->txn_out->accounts.keys[ idx_in_txn ].key, sizeof(fd_pubkey_t) ) ) ); } return is_signer; } diff --git a/src/flamenco/runtime/fd_borrowed_account.c b/src/flamenco/runtime/fd_borrowed_account.c index 870a9076f4..1a2c671558 100644 --- a/src/flamenco/runtime/fd_borrowed_account.c +++ b/src/flamenco/runtime/fd_borrowed_account.c @@ -4,7 +4,6 @@ int fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, uchar * * data_out, ulong * dlen_out ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L824 */ int err; @@ -14,9 +13,9 @@ fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, } if ( data_out != NULL ) - *data_out = fd_txn_account_get_data_mut( acct ); + *data_out = fd_account_data( borrowed_acct->meta ); if ( dlen_out != NULL ) - *dlen_out = fd_txn_account_get_data_len( acct ); + *dlen_out = borrowed_acct->meta->dlen; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -24,7 +23,6 @@ fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, fd_pubkey_t const * owner ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* Only the owner can assign a new owner https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L741 */ @@ -52,7 +50,7 @@ fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, /* Don't copy the account if the owner does not change https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L757 */ - if( !memcmp( fd_txn_account_get_owner( acct ), owner, sizeof( fd_pubkey_t ) ) ) { + if( !memcmp( borrowed_acct->meta->owner, owner, sizeof(fd_pubkey_t) ) ) { return FD_EXECUTOR_INSTR_SUCCESS; } @@ -60,7 +58,7 @@ fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, /* Copy into owner https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L761 */ - fd_txn_account_set_owner( acct, owner ); + fd_memcpy( borrowed_acct->meta->owner, owner, sizeof(fd_pubkey_t) ); return FD_EXECUTOR_INSTR_SUCCESS; } @@ -69,12 +67,11 @@ fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_set_lamports( fd_borrowed_account_t * borrowed_acct, ulong lamports ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* An account not owned by the program cannot have its blanace decrease https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L775 */ if( FD_UNLIKELY( (!fd_borrowed_account_is_owned_by_current_program( borrowed_acct )) && - (lamportsmeta->lamports) ) ) { return FD_EXECUTOR_INSTR_ERR_EXTERNAL_ACCOUNT_LAMPORT_SPEND; } @@ -92,13 +89,13 @@ fd_borrowed_account_set_lamports( fd_borrowed_account_t * borrowed_acct, /* Don't copy the account if the lamports do not change https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L787 */ - if( fd_txn_account_get_lamports( acct )==lamports ) { + if( borrowed_acct->meta->lamports==lamports ) { return FD_EXECUTOR_INSTR_SUCCESS; } /* Agave self.touch() is a no-op */ - fd_txn_account_set_lamports( acct, lamports ); + borrowed_acct->meta->lamports = lamports; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -106,7 +103,6 @@ int fd_borrowed_account_set_data_from_slice( fd_borrowed_account_t * borrowed_acct, uchar const * data, ulong data_sz ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L865 */ int err; @@ -127,7 +123,8 @@ fd_borrowed_account_set_data_from_slice( fd_borrowed_account_t * borrowed_acct, } /* AccountSharedData::set_data_from_slice() */ - fd_txn_account_set_data( acct, data, data_sz ); + borrowed_acct->meta->dlen = (uint)data_sz; + fd_memcpy( fd_account_data( borrowed_acct->meta ), data, data_sz ); return FD_EXECUTOR_INSTR_SUCCESS; } @@ -135,8 +132,7 @@ fd_borrowed_account_set_data_from_slice( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_set_data_length( fd_borrowed_account_t * borrowed_acct, ulong new_len ) { - fd_txn_account_t * acct = borrowed_acct->acct; - int err = FD_EXECUTOR_INSTR_SUCCESS; + int err = FD_EXECUTOR_INSTR_SUCCESS; /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L883 */ if( FD_UNLIKELY( !fd_borrowed_account_can_data_be_resized( borrowed_acct, new_len, &err ) ) ) { @@ -148,7 +144,7 @@ fd_borrowed_account_set_data_length( fd_borrowed_account_t * borrowed_acct, return err; } - ulong old_len = fd_txn_account_get_data_len( acct ); + ulong old_len = borrowed_acct->meta->dlen; /* Don't copy the account if the length does not change https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L886 */ @@ -165,19 +161,18 @@ fd_borrowed_account_set_data_length( fd_borrowed_account_t * borrowed_acct, /* Resize the account https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L891 */ - fd_txn_account_resize( acct, new_len ); + fd_account_meta_resize( borrowed_acct->meta, new_len ); + return FD_EXECUTOR_INSTR_SUCCESS; } int fd_borrowed_account_set_executable( fd_borrowed_account_t * borrowed_acct, int is_executable ) { - fd_txn_account_t * acct = borrowed_acct->acct; - /* To become executable an account must be rent exempt https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1003-L1006 */ fd_rent_t const * rent = fd_bank_rent_query( borrowed_acct->instr_ctx->bank ); - if( FD_UNLIKELY( fd_txn_account_get_lamports( acct )meta->lamportsmeta->dlen ) ) ) { return FD_EXECUTOR_INSTR_ERR_EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT; } @@ -208,7 +203,7 @@ fd_borrowed_account_set_executable( fd_borrowed_account_t * borrowed_acct, /* Agave self.touch() is a no-op */ /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1027 */ - fd_txn_account_set_executable( acct, is_executable ); + borrowed_acct->meta->executable = !!is_executable; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -218,8 +213,7 @@ fd_borrowed_account_update_accounts_resize_delta( fd_borrowed_account_t * borrow ulong new_len, int * err ) { fd_exec_instr_ctx_t const * instr_ctx = borrowed_acct->instr_ctx; - fd_txn_account_t * acct = borrowed_acct->acct; - ulong size_delta = fd_ulong_sat_sub( new_len, fd_txn_account_get_data_len( acct ) ); + ulong size_delta = fd_ulong_sat_sub( new_len, borrowed_acct->meta->dlen ); /* TODO: The size delta should never exceed the value of ULONG_MAX so this could be replaced with a normal addition. However to match execution with @@ -233,11 +227,10 @@ int fd_borrowed_account_can_data_be_resized( fd_borrowed_account_t const * borrowed_acct, ulong new_length, int * err ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* Only the owner can change the length of the data https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1095 */ - if( FD_UNLIKELY( (fd_txn_account_get_data_len( acct )!=new_length) & + if( FD_UNLIKELY( (borrowed_acct->meta->dlen!=new_length) & (!fd_borrowed_account_is_owned_by_current_program( borrowed_acct )) ) ) { *err = FD_EXECUTOR_INSTR_ERR_ACC_DATA_SIZE_CHANGED; return 0; @@ -252,7 +245,7 @@ fd_borrowed_account_can_data_be_resized( fd_borrowed_account_t const * borrowed_ /* The resize can not exceed the per-transaction maximum https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1104-L1108 */ - ulong length_delta = fd_ulong_sat_sub( new_length, fd_txn_account_get_data_len( acct ) ); + ulong length_delta = fd_ulong_sat_sub( new_length, borrowed_acct->meta->dlen ); ulong new_accounts_resize_delta = fd_ulong_sat_add( borrowed_acct->instr_ctx->txn_out->details.accounts_resize_delta, length_delta ); if( FD_UNLIKELY( new_accounts_resize_delta > MAX_PERMITTED_ACCOUNT_DATA_ALLOCS_PER_TXN ) ) { *err = FD_EXECUTOR_INSTR_ERR_MAX_ACCS_DATA_ALLOCS_EXCEEDED; diff --git a/src/flamenco/runtime/fd_borrowed_account.h b/src/flamenco/runtime/fd_borrowed_account.h index 9a8f2e5fdb..290c4ed977 100644 --- a/src/flamenco/runtime/fd_borrowed_account.h +++ b/src/flamenco/runtime/fd_borrowed_account.h @@ -16,12 +16,15 @@ struct fd_borrowed_account { ulong magic; - fd_txn_account_t * acct; + fd_pubkey_t const * pubkey; + fd_account_meta_t * meta; fd_exec_instr_ctx_t const * instr_ctx; /* index_in_instruction will be USHORT_MAX for borrowed program accounts because they are not stored in the list of instruction accounts in the instruction context */ ushort index_in_instruction; + + ulong * refcnt; }; typedef struct fd_borrowed_account fd_borrowed_account_t; @@ -35,12 +38,16 @@ FD_PROTOTYPES_BEGIN static inline void fd_borrowed_account_init( fd_borrowed_account_t * borrowed_acct, - fd_txn_account_t * acct, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, fd_exec_instr_ctx_t const * instr_ctx, - ushort index_in_instruction ) { - borrowed_acct->acct = acct; + ushort index_in_instruction, + ulong * refcnt ) { + borrowed_acct->pubkey = pubkey; + borrowed_acct->meta = meta; borrowed_acct->instr_ctx = instr_ctx; borrowed_acct->index_in_instruction = index_in_instruction; + borrowed_acct->refcnt = refcnt; FD_COMPILER_MFENCE(); borrowed_acct->magic = FD_BORROWED_ACCOUNT_MAGIC; @@ -52,7 +59,7 @@ fd_borrowed_account_init( fd_borrowed_account_t * borrowed_acct, static inline void fd_borrowed_account_drop( fd_borrowed_account_t * borrowed_acct ) { - fd_txn_account_drop( borrowed_acct->acct ); + (*borrowed_acct->refcnt) = 0; } /* Destructor */ @@ -79,12 +86,12 @@ fd_borrowed_account_destroy( fd_borrowed_account_t * borrowed_acct ) { static inline uchar const * fd_borrowed_account_get_data( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_data( borrowed_acct->acct ); + return fd_account_data( borrowed_acct->meta ); } static inline ulong fd_borrowed_account_get_data_len( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_data_len( borrowed_acct->acct ); + return borrowed_acct->meta->dlen; } /* fd_borrowed_account_get_data_mut mirrors Agave function @@ -103,7 +110,7 @@ fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, static inline fd_pubkey_t const * fd_borrowed_account_get_owner( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_owner( borrowed_acct->acct ); + return (fd_pubkey_t const *)borrowed_acct->meta->owner; } /* fd_borrowed_account_get_lamports mirrors Agave function @@ -116,22 +123,12 @@ fd_borrowed_account_get_owner( fd_borrowed_account_t const * borrowed_acct ) { static inline ulong fd_borrowed_account_get_lamports( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_lamports( borrowed_acct->acct ); -} - -/* fd_borrowed_account_get_rent_epoch mirrors Agave function - solana_sdk::transaction_context::BorrowedAccount::get_rent_epoch. - - https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1034 */ - -static inline ulong -fd_borrowed_account_get_rent_epoch( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_rent_epoch( borrowed_acct->acct ); + return borrowed_acct->meta->lamports; } static inline fd_account_meta_t const * fd_borrowed_account_get_acc_meta( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_meta( borrowed_acct->acct ); + return borrowed_acct->meta; } /* Setters */ @@ -210,7 +207,7 @@ static inline int fd_borrowed_account_checked_add_lamports( fd_borrowed_account_t * borrowed_acct, ulong lamports ) { ulong balance_post = 0UL; - int err = fd_ulong_checked_add( fd_txn_account_get_lamports( borrowed_acct->acct ), + int err = fd_ulong_checked_add( borrowed_acct->meta->lamports, lamports, &balance_post ); if( FD_UNLIKELY( err ) ) { @@ -233,7 +230,7 @@ static inline int fd_borrowed_account_checked_sub_lamports( fd_borrowed_account_t * borrowed_acct, ulong lamports ) { ulong balance_post = 0UL; - int err = fd_ulong_checked_sub( fd_txn_account_get_lamports( borrowed_acct->acct ), + int err = fd_ulong_checked_sub( borrowed_acct->meta->lamports, lamports, &balance_post ); if( FD_UNLIKELY( err ) ) { @@ -250,8 +247,8 @@ fd_borrowed_account_checked_sub_lamports( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_update_accounts_resize_delta( fd_borrowed_account_t * borrowed_acct, - ulong new_len, - int * err ); + ulong new_len, + int * err ); /* Accessors */ @@ -264,14 +261,13 @@ fd_borrowed_account_update_accounts_resize_delta( fd_borrowed_account_t * borrow static inline int fd_borrowed_account_is_rent_exempt_at_data_length( fd_borrowed_account_t const * borrowed_acct ) { - fd_txn_account_t * acct = borrowed_acct->acct; - if( FD_UNLIKELY( !fd_txn_account_get_meta( acct ) ) ) FD_LOG_ERR(( "account is not setup" )); + if( FD_UNLIKELY( !borrowed_acct->meta ) ) FD_LOG_ERR(( "account is not setup" )); /* TODO: Add an is_exempt rent API to better match Agave and clean up code https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L990 */ fd_rent_t const * rent = fd_bank_rent_query( borrowed_acct->instr_ctx->bank ); - ulong min_balance = fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( acct ) ); - return fd_txn_account_get_lamports( acct )>=min_balance; + ulong min_balance = fd_rent_exempt_minimum_balance( rent, borrowed_acct->meta->dlen ); + return borrowed_acct->meta->lamports>=min_balance; } /* fd_borrowed_account_is_executable mirrors Agave function @@ -284,7 +280,7 @@ fd_borrowed_account_is_rent_exempt_at_data_length( fd_borrowed_account_t const * FD_FN_PURE static inline int fd_borrowed_account_is_executable( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_is_executable( borrowed_acct->acct ); + return borrowed_acct->meta->executable; } /* fd_borrowed_account_is_executable_internal is a private function for deprecating the `is_executable` flag. @@ -300,11 +296,6 @@ fd_borrowed_account_is_executable_internal( fd_borrowed_account_t const * borrow fd_borrowed_account_is_executable( borrowed_acct ); } -FD_FN_PURE static inline int -fd_borrowed_account_is_mutable( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_is_mutable( borrowed_acct->acct ); -} - /* fd_borrowed_account_is_signer mirrors the Agave function solana_sdk::transaction_context::BorrowedAccount::is_signer. Returns 1 if the account is a signer or is writable and 0 otherwise. @@ -358,8 +349,7 @@ fd_borrowed_account_is_owned_by_current_program( fd_borrowed_account_t const * b return 0; } - return !memcmp( program_id_pubkey->key, - fd_txn_account_get_owner( borrowed_acct->acct ), sizeof(fd_pubkey_t) ); + return !memcmp( program_id_pubkey->key, borrowed_acct->meta->owner, sizeof(fd_pubkey_t) ); } /* fd_borrowed_account_can_data_be changed mirrors Agave function @@ -407,10 +397,9 @@ fd_borrowed_account_can_data_be_resized( fd_borrowed_account_t const * borrowed_ FD_FN_PURE static inline int fd_borrowed_account_is_zeroed( fd_borrowed_account_t const * borrowed_acct ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* TODO: optimize this */ - uchar const * data = fd_txn_account_get_data( acct ); - for( ulong i=0UL; imeta ); + for( ulong i=0UL; imeta->dlen; i++ ) { if( data[i] != 0 ) { return 0; } diff --git a/src/flamenco/runtime/fd_core_bpf_migration.c b/src/flamenco/runtime/fd_core_bpf_migration.c index 90e7354fff..49488e938b 100644 --- a/src/flamenco/runtime/fd_core_bpf_migration.c +++ b/src/flamenco/runtime/fd_core_bpf_migration.c @@ -86,7 +86,7 @@ tmp_account_store( fd_tmp_account_t * acc, fd_txn_account_set_lamports ( rec, acc->meta.lamports ); fd_txn_account_set_data ( rec, acc->data, acc->data_sz ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); } diff --git a/src/flamenco/runtime/fd_cost_tracker.c b/src/flamenco/runtime/fd_cost_tracker.c index 716eaff231..33eb29caf0 100644 --- a/src/flamenco/runtime/fd_cost_tracker.c +++ b/src/flamenco/runtime/fd_cost_tracker.c @@ -389,10 +389,10 @@ would_fit( fd_cost_tracker_t const * cost_tracker, account_cost_map_t const * map = fd_type_pun_const(((cost_tracker_outer_t const *)cost_tracker)+1UL); account_cost_t const * pool = fd_type_pun_const( (void*)((ulong)cost_tracker + ((cost_tracker_outer_t const *)cost_tracker)->pool_offset) ); - for( ulong i=0UL; iaccounts.accounts_cnt; i++ ) { + for( ulong i=0UL; iaccounts.cnt; i++ ) { if( !fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, (ushort)i ) ) continue; - fd_pubkey_t const * writable_acc = &txn_out->accounts.account_keys[i]; + fd_pubkey_t const * writable_acc = &txn_out->accounts.keys[i]; account_cost_t const * chained_cost = account_cost_map_ele_query_const( map, writable_acc, NULL, pool ); if( FD_UNLIKELY( chained_cost && fd_ulong_sat_add( chained_cost->cost, cost )>cost_tracker->account_cost_limit ) ) { @@ -415,10 +415,10 @@ add_transaction_execution_cost( fd_cost_tracker_t * _cost_tracker, account_cost_map_t * map = fd_type_pun( cost_tracker+1UL ); account_cost_t * pool = fd_type_pun( (void*)((ulong)cost_tracker+cost_tracker->pool_offset) ); - for( ulong i=0UL; iaccounts.accounts_cnt; i++ ) { + for( ulong i=0UL; iaccounts.cnt; i++ ) { if( FD_LIKELY( !fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, (ushort)i ) ) ) continue; - fd_pubkey_t const * writable_acc = &txn_out->accounts.account_keys[i]; + fd_pubkey_t const * writable_acc = &txn_out->accounts.keys[i]; account_cost_t * account_cost = account_cost_map_ele_query( map, writable_acc, NULL, pool ); if( FD_UNLIKELY( !account_cost ) ) { diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 89ec1a9641..4e213dee5f 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -102,8 +102,7 @@ typedef struct fd_native_prog_info fd_native_prog_info_t; #undef PERFECT_HASH fd_exec_instr_fn_t -fd_executor_lookup_native_precompile_program( fd_txn_account_t const * prog_acc ) { - fd_pubkey_t const * pubkey = prog_acc->pubkey; +fd_executor_lookup_native_precompile_program( fd_pubkey_t const * pubkey ) { const fd_native_prog_info_t null_function = {0}; return fd_native_precompile_program_fn_lookup_tbl_query( pubkey, &null_function )->fn; } @@ -128,20 +127,20 @@ fd_executor_program_is_active( fd_bank_t * bank, native program ID. Returns NULL if given ID is not a recognized native program. https://github.com/anza-xyz/agave/blob/v2.2.6/program-runtime/src/invoke_context.rs#L520-L544 */ static int -fd_executor_lookup_native_program( fd_txn_account_t const * prog_acc, - fd_bank_t * bank, - fd_exec_instr_fn_t * native_prog_fn, - uchar * is_precompile ) { +fd_executor_lookup_native_program( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank, + fd_exec_instr_fn_t * native_prog_fn, + uchar * is_precompile ) { /* First lookup to see if the program key is a precompile */ *is_precompile = 0; - *native_prog_fn = fd_executor_lookup_native_precompile_program( prog_acc ); + *native_prog_fn = fd_executor_lookup_native_precompile_program( pubkey ); if( FD_UNLIKELY( *native_prog_fn!=NULL ) ) { *is_precompile = 1; return 0; } - fd_pubkey_t const * pubkey = prog_acc->pubkey; - fd_pubkey_t const * owner = fd_txn_account_get_owner( prog_acc ); + fd_pubkey_t const * owner = (fd_pubkey_t const *)meta->owner; /* Native programs should be owned by the native loader... This will not be the case though once core programs are migrated to BPF. */ @@ -212,10 +211,10 @@ fd_executor_rent_transition_allowed( fd_rent_state_t const * pre_rent_state, /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L61-L77 */ static int -fd_executor_check_rent_state_with_account( fd_txn_account_t const * account, - fd_rent_state_t const * pre_rent_state, - fd_rent_state_t const * post_rent_state ) { - if( FD_UNLIKELY( memcmp( account->pubkey->key, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) && +fd_executor_check_rent_state_with_account( fd_pubkey_t const * pubkey, + fd_rent_state_t const * pre_rent_state, + fd_rent_state_t const * post_rent_state ) { + if( FD_UNLIKELY( memcmp( pubkey, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) && !fd_executor_rent_transition_allowed( pre_rent_state, post_rent_state ) ) ) { return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; } @@ -224,16 +223,16 @@ fd_executor_check_rent_state_with_account( fd_txn_account_t const * account, /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L87-L101 */ fd_rent_state_t -fd_executor_get_account_rent_state( fd_txn_account_t const * account, fd_rent_t const * rent ) { +fd_executor_get_account_rent_state( fd_account_meta_t const * meta, fd_rent_t const * rent ) { /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L88-L89 */ - if( fd_txn_account_get_lamports( account )==0UL ) { + if( meta->lamports==0UL ) { return (fd_rent_state_t){ .discriminant = fd_rent_state_enum_uninitialized }; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L90-L94 */ - if( fd_txn_account_get_lamports( account )>=fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( account ) ) ) { + if( meta->lamports>=fd_rent_exempt_minimum_balance( rent, meta->dlen ) ) { return (fd_rent_state_t){ .discriminant = fd_rent_state_enum_rent_exempt }; @@ -244,8 +243,8 @@ fd_executor_get_account_rent_state( fd_txn_account_t const * account, fd_rent_t .discriminant = fd_rent_state_enum_rent_paying, .inner = { .rent_paying = { - .lamports = fd_txn_account_get_lamports( account ), - .data_size = fd_txn_account_get_data_len( account ) + .lamports = meta->lamports, + .data_size = meta->dlen } } }; @@ -253,17 +252,19 @@ fd_executor_get_account_rent_state( fd_txn_account_t const * account, fd_rent_t /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L293-L342 */ static int -fd_validate_fee_payer( fd_txn_account_t * account, - fd_rent_t const * rent, - ulong fee ) { +fd_validate_fee_payer( fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, + fd_rent_t const * rent, + ulong fee ) { + /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L301-L304 */ - if( FD_UNLIKELY( fd_txn_account_get_lamports( account )==0UL ) ) { - FD_LOG_DEBUG(( "Fee payer doesn't exist %s", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) )); + if( FD_UNLIKELY( meta->lamports==0UL ) ) { + FD_LOG_DEBUG(( "Fee payer doesn't exist %s", FD_BASE58_ENC_32_ALLOCA( pubkey ) )); return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L305-L308 */ - int system_account_kind = fd_get_system_account_kind( account ); + int system_account_kind = fd_get_system_account_kind( meta ); if( FD_UNLIKELY( system_account_kind==FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN ) ) { return FD_RUNTIME_TXN_ERR_INVALID_ACCOUNT_FOR_FEE; } @@ -275,25 +276,24 @@ fd_validate_fee_payer( fd_txn_account_t * account, } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L320-L327 */ - if( FD_UNLIKELY( min_balance>fd_txn_account_get_lamports( account ) || - fee>fd_txn_account_get_lamports( account )-min_balance ) ) { + if( FD_UNLIKELY( min_balance>meta->lamports || fee>meta->lamports-min_balance ) ) { return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_FEE; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L329 */ - fd_rent_state_t payer_pre_rent_state = fd_executor_get_account_rent_state( account, rent ); + fd_rent_state_t payer_pre_rent_state = fd_executor_get_account_rent_state( meta, rent ); /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L330-L332 */ - int err = fd_txn_account_checked_sub_lamports( account, fee ); + int err = fd_account_meta_checked_sub_lamports( meta, fee ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_FEE; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L334 */ - fd_rent_state_t payer_post_rent_state = fd_executor_get_account_rent_state( account, rent ); + fd_rent_state_t payer_post_rent_state = fd_executor_get_account_rent_state( meta, rent ); /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L335-L342 */ - return fd_executor_check_rent_state_with_account( account, &payer_pre_rent_state, &payer_post_rent_state ); + return fd_executor_check_rent_state_with_account( pubkey, &payer_pre_rent_state, &payer_post_rent_state ); } static int @@ -460,19 +460,19 @@ load_transaction_account( fd_runtime_t * runtime, fd_bank_t * bank, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, - fd_txn_account_t * acct, - uchar is_writable, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, uchar unknown_acc, ulong txn_idx ) { /* Handling the sysvar instructions account explictly. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L817-L824 */ - if( FD_UNLIKELY( !memcmp( acct->pubkey->key, fd_sysvar_instructions_id.key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !memcmp( pubkey, fd_sysvar_instructions_id.key, sizeof(fd_pubkey_t) ) ) ) { /* The sysvar instructions account cannot be "loaded" since it's constructed by the SVM and modified within each transaction's instruction execution only, so it incurs a loaded size cost of 0. */ - fd_sysvar_instructions_serialize_account( txn_in, txn_out, (fd_instr_info_t const *)runtime->instr.infos, TXN( txn_in->txn )->instr_cnt, txn_idx ); + fd_sysvar_instructions_serialize_account( runtime, txn_in, txn_out, (fd_instr_info_t const *)runtime->instr.infos, TXN( txn_in->txn )->instr_cnt, txn_idx ); return 0UL; } @@ -490,10 +490,7 @@ load_transaction_account( fd_runtime_t * runtime, ulong base_account_size = FD_FEATURE_ACTIVE_BANK( bank, formalize_loaded_transaction_data_size ) ? FD_TRANSACTION_ACCOUNT_BASE_SIZE : 0UL; /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L828-L835 */ - if( is_writable ) { - acct->starting_lamports = fd_txn_account_get_lamports( acct ); /* TODO: why do we do this everywhere? */ - } - return fd_ulong_sat_add( base_account_size, fd_txn_account_get_data_len( acct ) ); + return fd_ulong_sat_add( base_account_size, meta->dlen ); } /* The rest of this function is a no-op for us since we already set up @@ -523,11 +520,10 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, ulong requested_loaded_accounts_data_size = txn_out->details.compute_budget.loaded_accounts_data_size_limit; /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L429-L443 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_txn_account_t * acct = &txn_out->accounts.accounts[i]; - uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, &acct, fd_runtime_account_check_exists ) || - fd_txn_account_get_lamports( acct )==0UL); - uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); + for( ushort i=0; iaccounts.cnt; i++ ) { + fd_account_meta_t * meta = txn_out->accounts.metas[i]; + uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || + meta->lamports==0UL); /* Collect the fee payer account separately (since it was already) loaded during fee payer validation. @@ -539,7 +535,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, We also don't need to add a base account size to this value because this branch would only be taken BEFORE SIMD-0186 is enabled. */ - int err = accumulate_and_check_loaded_account_data_size( fd_txn_account_get_data_len( acct ), + int err = accumulate_and_check_loaded_account_data_size( meta->dlen, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { @@ -549,7 +545,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L733-L740 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, unknown_acc, i ); int err = accumulate_and_check_loaded_account_data_size( loaded_acc_size, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); @@ -571,37 +567,36 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, fd_txn_instr_t const * instr = &TXN( txn_in->txn )->instr[i]; /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L449-L451 */ - if( FD_UNLIKELY( !memcmp( txn_out->accounts.account_keys[ instr->program_id ].key, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !memcmp( txn_out->accounts.keys[ instr->program_id ].key, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) ) { continue; } /* Mimicking `load_account()` here with 0-lamport check as well. https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L455-L462 */ - fd_txn_account_t * program_account = NULL; + fd_account_meta_t * program_meta = txn_out->accounts.metas[instr->program_id]; int err = fd_runtime_get_account_at_index( txn_in, txn_out, instr->program_id, - &program_account, fd_runtime_account_check_exists ); - if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || fd_txn_account_get_lamports( program_account )==0UL ) ) { + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || program_meta->lamports==0UL ) ) { return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; } /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L464-L471 */ if( FD_UNLIKELY( !FD_FEATURE_ACTIVE_BANK( bank, remove_accounts_executable_flag_checks ) && - !fd_txn_account_is_executable( program_account ) ) ) { + !program_meta->executable ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; } /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L474-L477 */ - if( !memcmp( fd_txn_account_get_owner( program_account ), fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) { + if( !memcmp( program_meta->owner, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) { continue; } /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L479-L522 */ uchar loader_seen = 0; for( ushort j=0; jowner, sizeof(fd_pubkey_t) ) ) { /* If the owner account has already been seen, skip the owner checks and do not acccumulate the account size. */ loader_seen = 1; @@ -615,35 +610,32 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, total size of accounts and their owners are accumulated: duplicate owners should be avoided. https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L496-L517 */ - fd_txn_account_t owner_account[1]; - err = fd_txn_account_init_from_funk_readonly( owner_account, - fd_txn_account_get_owner( program_account ), - runtime->funk, - &xid ); + + fd_pubkey_t const * owner_pubkey = (fd_pubkey_t const *)program_meta->owner; + fd_account_meta_t const * owner_account = fd_funk_get_acc_meta_readonly( runtime->funk, &xid, owner_pubkey, NULL, &err, NULL ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L520 */ return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; } - /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L502-L510 */ - if( FD_UNLIKELY( memcmp( fd_txn_account_get_owner( owner_account ), fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) || + if( FD_UNLIKELY( memcmp( owner_account->owner, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) || ( !FD_FEATURE_ACTIVE_BANK( bank, remove_accounts_executable_flag_checks ) && - !fd_txn_account_is_executable( owner_account ) ) ) ) { + !owner_account->executable ) ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; } /* Count the owner's data in the loaded account size for program accounts. However, it is important to not double count repeated owners. https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L511-L517 */ - err = accumulate_and_check_loaded_account_data_size( fd_txn_account_get_data_len( owner_account ), + err = accumulate_and_check_loaded_account_data_size( owner_account->dlen, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { return err; } - fd_memcpy( validated_loaders[ validated_loaders_cnt++ ].key, owner_account->pubkey, sizeof(fd_pubkey_t) ); + fd_memcpy( validated_loaders[ validated_loaders_cnt++ ].key, owner_pubkey, sizeof(fd_pubkey_t) ); } return FD_RUNTIME_EXECUTE_SUCCESS; @@ -671,13 +663,13 @@ fd_increase_calculated_data_size( fd_txn_out_t * txn_out, /* This function is represented as a closure in Agave. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L578-L640 */ static int -fd_collect_loaded_account( fd_runtime_t * runtime, - fd_txn_out_t * txn_out, - fd_bank_t * bank, - fd_txn_account_t const * account, - ulong loaded_acc_size, - fd_pubkey_t * additional_loaded_account_keys, - ulong * additional_loaded_account_keys_cnt ) { +fd_collect_loaded_account( fd_runtime_t * runtime, + fd_txn_out_t * txn_out, + fd_bank_t * bank, + fd_account_meta_t const * account_meta, + ulong loaded_acc_size, + fd_pubkey_t * additional_loaded_account_keys, + ulong * additional_loaded_account_keys_cnt ) { /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L586-L590 */ int err = fd_increase_calculated_data_size( txn_out, loaded_acc_size ); @@ -692,14 +684,14 @@ fd_collect_loaded_account( fd_runtime_t * runtime, loading logic. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L611 */ - if( FD_LIKELY( memcmp( fd_txn_account_get_owner( account ), fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_LIKELY( memcmp( account_meta->owner, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } /* Try to read the program state https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L612-L634 */ fd_bpf_upgradeable_loader_state_t loader_state[1]; - err = fd_bpf_loader_program_get_state( account, loader_state ); + err = fd_bpf_loader_program_get_state( account_meta, loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -712,8 +704,8 @@ fd_collect_loaded_account( fd_runtime_t * runtime, /* Iterate through the account keys and make sure the programdata account is not present so it doesn't get loaded twice. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L617 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - if( FD_UNLIKELY( !memcmp( &txn_out->accounts.account_keys[i], &loader_state->inner.program.programdata_address, sizeof(fd_pubkey_t) ) ) ) { + for( ushort i=0; iaccounts.cnt; i++ ) { + if( FD_UNLIKELY( !memcmp( &txn_out->accounts.keys[i], &loader_state->inner.program.programdata_address, sizeof(fd_pubkey_t) ) ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } } @@ -727,20 +719,23 @@ fd_collect_loaded_account( fd_runtime_t * runtime, } /* Load the programdata account from Funk to read the programdata length */ - fd_txn_account_t programdata_account[1]; fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - err = fd_txn_account_init_from_funk_readonly( programdata_account, - &loader_state->inner.program.programdata_address, - runtime->funk, - &xid ); + + fd_account_meta_t const * programdata_meta = fd_funk_get_acc_meta_readonly( + runtime->funk, + &xid, + &loader_state->inner.program.programdata_address, + NULL, + &err, + NULL ); + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } /* Try to accumulate the programdata's data size https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L625-L630 */ - ulong programdata_size_delta = fd_ulong_sat_add( FD_TRANSACTION_ACCOUNT_BASE_SIZE, - fd_txn_account_get_data_len( programdata_account ) ); + ulong programdata_size_delta = fd_ulong_sat_add( FD_TRANSACTION_ACCOUNT_BASE_SIZE, programdata_meta->dlen ); err = fd_increase_calculated_data_size( txn_out, programdata_size_delta ); if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { return err; @@ -790,11 +785,11 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L642-L660 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_txn_account_t * acct = &txn_out->accounts.accounts[i]; - uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, &acct, fd_runtime_account_check_exists ) || - fd_txn_account_get_lamports( acct )==0UL); - uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); + for( ushort i=0; iaccounts.cnt; i++ ) { + fd_account_meta_t * meta = txn_out->accounts.metas[i]; + + uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || + meta->lamports==0UL); /* Collect the fee payer account separately (since it was already) loaded during fee payer validation. @@ -807,12 +802,12 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, because this branch would only be taken AFTER SIMD-0186 is enabled. */ ulong loaded_acc_size = fd_ulong_sat_add( FD_TRANSACTION_ACCOUNT_BASE_SIZE, - fd_txn_account_get_data_len( acct ) ); + meta->dlen ); int err = fd_collect_loaded_account( runtime, txn_out, bank, - acct, + meta, loaded_acc_size, additional_loaded_account_keys, &additional_loaded_account_keys_cnt ); @@ -824,12 +819,12 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Load and collect any remaining accounts https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L652-L659 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, unknown_acc, i ); int err = fd_collect_loaded_account( runtime, txn_out, bank, - acct, + meta, loaded_acc_size, additional_loaded_account_keys, &additional_loaded_account_keys_cnt ); @@ -845,24 +840,23 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Mimicking `load_account()` here with 0-lamport check as well. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L663-L666 */ - fd_txn_account_t * program_account; + fd_account_meta_t * program_meta = txn_out->accounts.metas[ instr->program_id ]; int err = fd_runtime_get_account_at_index( txn_in, txn_out, instr->program_id, - &program_account, fd_runtime_account_check_exists ); - if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || fd_txn_account_get_lamports( program_account )==0UL ) ) { + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || program_meta->lamports==0UL ) ) { return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L668-L675 */ if( FD_UNLIKELY( !FD_FEATURE_ACTIVE_BANK( bank, remove_accounts_executable_flag_checks ) && - !fd_txn_account_is_executable( program_account ) ) ) { + !program_meta->executable ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L677-L681 */ - fd_pubkey_t const * owner_id = fd_txn_account_get_owner( program_account ); + fd_pubkey_t const * owner_id = (fd_pubkey_t const *)program_meta->owner; if( FD_UNLIKELY( memcmp( owner_id->key, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) && !fd_executor_pubkey_is_bpf_loader( owner_id ) ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; @@ -892,15 +886,15 @@ fd_executor_validate_account_locks( fd_bank_t * bank, /* Ensure the number of account keys does not exceed the transaction lock limit https://github.com/anza-xyz/agave/blob/v2.2.17/accounts-db/src/account_locks.rs#L121 */ ulong tx_account_lock_limit = get_transaction_account_lock_limit( bank ); - if( FD_UNLIKELY( txn_out->accounts.accounts_cnt>tx_account_lock_limit ) ) { + if( FD_UNLIKELY( txn_out->accounts.cnt>tx_account_lock_limit ) ) { return FD_RUNTIME_TXN_ERR_TOO_MANY_ACCOUNT_LOCKS; } /* Duplicate account check https://github.com/anza-xyz/agave/blob/v2.2.17/accounts-db/src/account_locks.rs#L123 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - for( ushort j=(ushort)(i+1U); jaccounts.accounts_cnt; j++ ) { - if( FD_UNLIKELY( !memcmp( &txn_out->accounts.account_keys[i], &txn_out->accounts.account_keys[j], sizeof(fd_pubkey_t) ) ) ) { + for( ushort i=0; iaccounts.cnt; i++ ) { + for( ushort j=(ushort)(i+1U); jaccounts.cnt; j++ ) { + if( FD_UNLIKELY( !memcmp( &txn_out->accounts.keys[i], &txn_out->accounts.keys[j], sizeof(fd_pubkey_t) ) ) ) { return FD_RUNTIME_TXN_ERR_ACCOUNT_LOADED_TWICE; } } @@ -933,7 +927,7 @@ fd_executor_calculate_fee( fd_bank_t * bank, ulong num_signatures = txn_descriptor->signature_cnt; for (ushort i=0; iinstr_cnt; ++i ) { fd_txn_instr_t const * txn_instr = &txn_descriptor->instr[i]; - fd_pubkey_t * program_id = &txn_out->accounts.account_keys[txn_instr->program_id]; + fd_pubkey_t * program_id = &txn_out->accounts.keys[txn_instr->program_id]; if( !memcmp(program_id->uc, fd_solana_keccak_secp_256k_program_id.key, sizeof(fd_pubkey_t)) || !memcmp(program_id->uc, fd_solana_ed25519_sig_verify_program_id.key, sizeof(fd_pubkey_t)) || (!memcmp(program_id->uc, fd_solana_secp256r1_program_id.key, sizeof(fd_pubkey_t)) && FD_FEATURE_ACTIVE_BANK( bank, enable_secp256r1_precompile )) ) { @@ -970,15 +964,14 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ulong total_fee ) { - fd_pubkey_t * fee_payer_key = &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX]; - fd_txn_account_t * rollback_fee_payer_acc; + fd_pubkey_t * fee_payer_key = &txn_out->accounts.keys[FD_FEE_PAYER_TXN_IDX]; /* When setting the data of the rollback fee payer, there is an edge case where the fee payer is the nonce account. In this case, we can just deduct fees from the nonce account and return, because we save the nonce account in the commit phase anyways. */ if( FD_UNLIKELY( txn_out->accounts.nonce_idx_in_txn==FD_FEE_PAYER_TXN_IDX ) ) { - rollback_fee_payer_acc = txn_out->accounts.rollback_nonce; + txn_out->accounts.rollback_fee_payer = txn_out->accounts.rollback_nonce; } else { fd_account_meta_t const * meta = NULL; if( FD_UNLIKELY( txn_in->bundle.is_bundle ) ) { @@ -986,11 +979,11 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, for( ulong i=txn_in->bundle.prev_txn_cnt; i>0UL && !is_found; i-- ) {; fd_txn_in_t const * prev_txn_in = txn_in->bundle.prev_txn_ins[ i-1 ]; fd_txn_out_t const * prev_txn_out = txn_in->bundle.prev_txn_outs[ i-1 ]; - for( ushort j=0UL; jaccounts.accounts_cnt; j++ ) { - if( !memcmp( &prev_txn_out->accounts.account_keys[ j ], fee_payer_key, sizeof(fd_pubkey_t) ) && + for( ushort j=0UL; jaccounts.cnt; j++ ) { + if( !memcmp( &prev_txn_out->accounts.keys[ j ], fee_payer_key, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { /* Found the account in a previous transaction */ - meta = prev_txn_out->accounts.accounts[ j ].meta; + meta = prev_txn_out->accounts.metas[ j ]; is_found = 1; break; } @@ -1012,19 +1005,11 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, uchar * fee_payer_data = txn_in->exec_accounts->rollback_fee_payer_mem; fd_memcpy( fee_payer_data, (uchar *)meta, sizeof(fd_account_meta_t) + meta->dlen ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( - txn_out->accounts.rollback_fee_payer, - fee_payer_key, - (fd_account_meta_t *)fee_payer_data, - 1 ) ) ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } - - rollback_fee_payer_acc = txn_out->accounts.rollback_fee_payer; + txn_out->accounts.rollback_fee_payer = fd_type_pun( fee_payer_data ); } /* Deduct the transaction fees from the rollback account. Because of prior checks, this should never fail. */ - if( FD_UNLIKELY( fd_txn_account_checked_sub_lamports( rollback_fee_payer_acc, total_fee ) ) ) { + if( FD_UNLIKELY( fd_account_meta_checked_sub_lamports( txn_out->accounts.rollback_fee_payer, total_fee ) ) ) { FD_LOG_ERR(( "fd_executor_create_rollback_fee_payer_account(): failed to deduct fees from rollback account" )); } } @@ -1036,17 +1021,17 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out ) { /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L574-L580 */ - fd_txn_account_t * fee_payer_rec = NULL; int err = fd_runtime_get_account_at_index( txn_in, txn_out, FD_FEE_PAYER_TXN_IDX, - &fee_payer_rec, fd_runtime_account_check_fee_payer_writable ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { - FD_LOG_DEBUG(( "Fee payer isn't writable %s", FD_BASE58_ENC_32_ALLOCA( fee_payer_rec->pubkey ) )); + FD_LOG_DEBUG(( "Fee payer isn't writable %s", FD_BASE58_ENC_32_ALLOCA( &txn_out->accounts.keys[FD_FEE_PAYER_TXN_IDX] ) )); return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } + fd_pubkey_t * fee_payer_key = &txn_out->accounts.keys[FD_FEE_PAYER_TXN_IDX]; + fd_account_meta_t * fee_payer_meta = txn_out->accounts.metas[FD_FEE_PAYER_TXN_IDX]; /* Calculate transaction fees https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L597-L606 */ @@ -1061,7 +1046,7 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L609-L616 */ - err = fd_validate_fee_payer( fee_payer_rec, fd_bank_rent_query( bank ), total_fee ); + err = fd_validate_fee_payer( fee_payer_key, fee_payer_meta, fd_bank_rent_query( bank ), total_fee ); if( FD_UNLIKELY( err ) ) { return err; } @@ -1071,7 +1056,7 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, fd_executor_create_rollback_fee_payer_account( runtime, bank, txn_in, txn_out, total_fee ); /* Set the starting lamports (to avoid unbalanced lamports issues in instruction execution) */ - fee_payer_rec->starting_lamports = fd_txn_account_get_lamports( fee_payer_rec ); /* TODO: why do we do this everywhere? */ + runtime->accounts.starting_lamports[FD_FEE_PAYER_TXN_IDX] = fee_payer_meta->lamports; txn_out->details.execution_fee = execution_fee; txn_out->details.priority_fee = priority_fee; @@ -1084,12 +1069,12 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, void fd_executor_setup_txn_account_keys( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out ) { - txn_out->accounts.accounts_cnt = (uchar)TXN( txn_in->txn )->acct_addr_cnt; + txn_out->accounts.cnt = (uchar)TXN( txn_in->txn )->acct_addr_cnt; fd_pubkey_t * tx_accs = (fd_pubkey_t *)((uchar *)txn_in->txn->payload + TXN( txn_in->txn )->acct_addr_off); // Set up accounts in the transaction body and perform checks for( ulong i = 0UL; i < TXN( txn_in->txn )->acct_addr_cnt; i++ ) { - txn_out->accounts.account_keys[i] = tx_accs[i]; + txn_out->accounts.keys[i] = tx_accs[i]; } } @@ -1110,7 +1095,7 @@ fd_executor_setup_txn_alut_account_keys( fd_runtime_t * runtime, return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - fd_acct_addr_t * accts_alt = (fd_acct_addr_t *) fd_type_pun( &txn_out->accounts.account_keys[txn_out->accounts.accounts_cnt] ); + fd_acct_addr_t * accts_alt = (fd_acct_addr_t *) fd_type_pun( &txn_out->accounts.keys[txn_out->accounts.cnt] ); int err = fd_runtime_load_txn_address_lookup_tables( TXN( txn_in->txn ), txn_in->txn->payload, runtime->funk, @@ -1119,7 +1104,7 @@ fd_executor_setup_txn_alut_account_keys( fd_runtime_t * runtime, slot_hashes, accts_alt ); fd_sysvar_cache_slot_hashes_leave_const( sysvar_cache, slot_hashes ); - txn_out->accounts.accounts_cnt += TXN( txn_in->txn )->addr_table_adtl_cnt; + txn_out->accounts.cnt += TXN( txn_in->txn )->addr_table_adtl_cnt; if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) return err; } @@ -1191,20 +1176,21 @@ fd_txn_ctx_push( fd_runtime_t * runtime, int idx = fd_runtime_find_index_of_account( txn_out, &fd_sysvar_instructions_id ); if( FD_UNLIKELY( idx!=-1 ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L397-L400 */ - fd_txn_account_t * sysvar_instructions_account = NULL; - err = fd_runtime_get_account_at_index( txn_in, txn_out, (ushort)idx, &sysvar_instructions_account, NULL ); + err = fd_runtime_get_account_at_index( txn_in, txn_out, (ushort)idx, NULL ); if( FD_UNLIKELY( err ) ) { return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } + ulong refcnt = runtime->accounts.refcnt[idx]; /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L401-L402 */ - if( FD_UNLIKELY( !fd_txn_account_try_borrow_mut( sysvar_instructions_account ) ) ) { + if( FD_UNLIKELY( refcnt!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED; } + refcnt++; /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L403-L406 */ - fd_sysvar_instructions_update_current_instr_idx( sysvar_instructions_account, (ushort)runtime->instr.current_idx ); - fd_txn_account_drop( sysvar_instructions_account ); + fd_sysvar_instructions_update_current_instr_idx( txn_out->accounts.metas[idx], (ushort)runtime->instr.current_idx ); + refcnt--; } return FD_EXECUTOR_INSTR_SUCCESS; @@ -1285,9 +1271,9 @@ fd_instr_stack_pop( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L367-L371 */ for( ushort i=0; iacct_cnt; i++ ) { ushort idx_in_txn = instr->accounts[i].index_in_transaction; - fd_txn_account_t * account = &txn_out->accounts.accounts[ idx_in_txn ]; - if( FD_UNLIKELY( fd_txn_account_is_executable( account ) && - fd_txn_account_is_borrowed( account ) ) ) { + fd_account_meta_t const * meta = txn_out->accounts.metas[ idx_in_txn ]; + ulong refcnt = runtime->accounts.refcnt[idx_in_txn]; + if( FD_UNLIKELY( meta->executable && refcnt!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_OUTSTANDING; } } @@ -1354,7 +1340,7 @@ fd_execute_instr( fd_runtime_t * runtime, .txn_out = txn_out, .bank = bank, }; - fd_base58_encode_32( txn_out->accounts.accounts[ instr->program_id ].pubkey->uc, NULL, ctx->program_id_base58 ); + fd_base58_encode_32( txn_out->accounts.keys[ instr->program_id ].uc, NULL, ctx->program_id_base58 ); runtime->instr.trace[ runtime->instr.trace_length - 1 ] = (fd_exec_instr_trace_entry_t) { .instr_info = instr, @@ -1365,7 +1351,8 @@ fd_execute_instr( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.1.6/svm/src/message_processor.rs#L88 */ fd_exec_instr_fn_t native_prog_fn; uchar is_precompile; - int err = fd_executor_lookup_native_program( &txn_out->accounts.accounts[ instr->program_id ], + int err = fd_executor_lookup_native_program( &txn_out->accounts.keys[ instr->program_id ], + txn_out->accounts.metas[ instr->program_id ], bank, &native_prog_fn, &is_precompile ); @@ -1424,26 +1411,25 @@ fd_execute_instr( fd_runtime_t * runtime, } void -fd_executor_reclaim_account( fd_txn_account_t * account, +fd_executor_reclaim_account( fd_account_meta_t * meta, ulong slot ) { - fd_txn_account_set_slot( account, slot ); - if( FD_UNLIKELY( fd_txn_account_get_lamports( account )==0UL ) ) { - fd_txn_account_set_data_len( account, 0UL ); - fd_txn_account_clear_owner( account ); + meta->slot = slot; + if( FD_UNLIKELY( meta->lamports==0UL ) ) { + meta->dlen = 0UL; + memset( meta->owner, 0, sizeof(fd_pubkey_t) ); } } -static fd_txn_account_t * +static void fd_executor_setup_txn_account( fd_runtime_t * runtime, fd_bank_t * bank, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ) { - /* To setup a transaction account, we need to first retrieve a read-only handle to the account from the database. */ - fd_pubkey_t * acc = &txn_out->accounts.account_keys[ idx ]; + fd_pubkey_t * acc = &txn_out->accounts.keys[ idx ]; fd_account_meta_t const * meta = NULL; @@ -1464,10 +1450,10 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, for( ulong i=txn_in->bundle.prev_txn_cnt; i>0UL && !is_found; i-- ) { fd_txn_in_t const * prev_txn_in = txn_in->bundle.prev_txn_ins[ i-1 ]; fd_txn_out_t const * prev_txn_out = txn_in->bundle.prev_txn_outs[ i-1 ]; - for( ushort j=0UL; jaccounts.accounts_cnt; j++ ) { - if( !memcmp( &prev_txn_out->accounts.account_keys[ j ], acc, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { + for( ushort j=0UL; jaccounts.cnt; j++ ) { + if( !memcmp( &prev_txn_out->accounts.keys[ j ], acc, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { /* Found the account in a previous transaction */ - meta = prev_txn_out->accounts.accounts[ j ].meta; + meta = prev_txn_out->accounts.metas[ j ]; is_found = 1; break; } @@ -1492,7 +1478,6 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, FD_LOG_CRIT(( "fd_txn_account_init_from_funk_readonly err=%d", err )); } - fd_txn_account_t * txn_account = &txn_out->accounts.accounts[ idx ]; int is_writable = fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, idx ) || idx==FD_FEE_PAYER_TXN_IDX; fd_account_meta_t * account_meta = NULL; @@ -1530,24 +1515,19 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, } } - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( - txn_account, - acc, - account_meta, - is_writable ) ) ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } - - return txn_account; + runtime->accounts.starting_lamports[idx] = account_meta->lamports; + runtime->accounts.starting_dlen[idx] = account_meta->dlen; + runtime->accounts.refcnt[idx] = 0UL; + txn_out->accounts.metas[idx] = account_meta; } static void -fd_executor_setup_executable_account( fd_runtime_t * runtime, - fd_bank_t * bank, - fd_txn_account_t const * account, - ushort * executable_idx ) { +fd_executor_setup_executable_account( fd_runtime_t * runtime, + fd_bank_t * bank, + fd_account_meta_t const * program_meta, + ushort * executable_idx ) { fd_bpf_upgradeable_loader_state_t program_loader_state[1]; - int err = fd_bpf_loader_program_get_state( account, program_loader_state ); + int err = fd_bpf_loader_program_get_state( program_meta, program_loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return; } @@ -1562,10 +1542,17 @@ fd_executor_setup_executable_account( fd_runtime_t * runtime, account will not exist within the executable accounts list. */ fd_pubkey_t * programdata_acc = &program_loader_state->inner.program.programdata_address; fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - if( FD_LIKELY( fd_txn_account_init_from_funk_readonly( &runtime->executable.accounts[ *executable_idx ], - programdata_acc, - runtime->funk, - &xid )==0 ) ) { + + fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( + runtime->funk, + &xid, + programdata_acc, + NULL, + &err, + NULL ); + if( FD_LIKELY( err==FD_ACC_MGR_SUCCESS ) ) { + runtime->accounts.executable_pubkeys[*executable_idx] = *programdata_acc; + runtime->accounts.executables_meta[*executable_idx] = (fd_account_meta_t *)meta; (*executable_idx)++; } } @@ -1577,14 +1564,13 @@ fd_executor_setup_accounts_for_txn( fd_runtime_t * runtime, fd_txn_out_t * txn_out ) { ushort executable_idx = 0U; - fd_memset( txn_out->accounts.accounts, 0, sizeof(fd_txn_account_t) * txn_out->accounts.accounts_cnt ); - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_txn_account_t * txn_account = fd_executor_setup_txn_account( runtime, bank, txn_in, txn_out, i ); + for( ushort i=0; iaccounts.cnt; i++ ) { + fd_executor_setup_txn_account( runtime, bank, txn_in, txn_out, i ); + fd_account_meta_t * meta = txn_out->accounts.metas[ i ]; - if( FD_UNLIKELY( txn_account && - memcmp( fd_txn_account_get_owner( txn_account ), fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) == 0 ) ) { - fd_executor_setup_executable_account( runtime, bank, txn_account, &executable_idx ); + if( FD_UNLIKELY( meta && memcmp( meta->owner, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) == 0 ) ) { + fd_executor_setup_executable_account( runtime, bank, meta, &executable_idx ); } } @@ -1594,14 +1580,17 @@ fd_executor_setup_accounts_for_txn( fd_runtime_t * runtime, fd_bank_slot_get( bank ) >= runtime->log.capture_ctx->dump_proto_start_slot && runtime->log.capture_ctx->dump_elf_to_pb; if( FD_UNLIKELY( dump_elf_to_pb ) ) { - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_dump_elf_to_protobuf( runtime, bank, txn_in, &txn_out->accounts.accounts[i] ); + for( ushort i=0; iaccounts.cnt; i++ ) { + fd_txn_account_t txn_account[1]; + txn_account->meta = txn_out->accounts.metas[i]; + fd_memcpy( txn_account->pubkey, &txn_out->accounts.keys[i], sizeof(fd_pubkey_t) ); + fd_dump_elf_to_protobuf( runtime, bank, txn_in, txn_account ); } } # endif txn_out->accounts.nonce_idx_in_txn = ULONG_MAX; - runtime->executable.cnt = executable_idx; + runtime->accounts.executable_cnt = executable_idx; /* Set up instr infos from the txn descriptor. No Agave equivalent to this function. */ fd_executor_setup_instr_infos_from_txn_instrs( runtime, bank, txn_in, txn_out ); @@ -1625,43 +1614,9 @@ fd_executor_txn_verify( fd_txn_p_t * txn_p, return FD_RUNTIME_EXECUTE_SUCCESS; } -int -fd_execute_txn( fd_runtime_t * runtime, - fd_bank_t * bank, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out ) { - - bool dump_insn = runtime->log.capture_ctx && fd_bank_slot_get( bank ) >= runtime->log.capture_ctx->dump_proto_start_slot && runtime->log.capture_ctx->dump_instr_to_pb; - (void)dump_insn; - - /* Initialize log collection. */ - fd_log_collector_init( runtime->log.log_collector, runtime->log.enable_log_collector ); - - for( ushort i=0; itxn )->instr_cnt; i++ ) { - runtime->instr.current_idx = i; -# if FD_HAS_FLATCC - if( FD_UNLIKELY( dump_insn ) ) { - // Capture the input and convert it into a Protobuf message - fd_dump_instr_to_protobuf( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i], i ); - } -# endif - - int instr_exec_result = fd_execute_instr( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i] ); - if( FD_UNLIKELY( instr_exec_result!=FD_EXECUTOR_INSTR_SUCCESS ) ) { - if( txn_out->err.exec_err_idx==INT_MAX ) { - txn_out->err.exec_err_idx = i; - } - return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR; - } - } - - /* TODO: This function needs to be split out of fd_execute_txn and be placed - into the replay tile once it is implemented. */ - return fd_executor_txn_check( bank, txn_out ); -} - -int -fd_executor_txn_check( fd_bank_t * bank, +static int +fd_executor_txn_check( fd_runtime_t * runtime, + fd_bank_t * bank, fd_txn_out_t * txn_out ) { fd_rent_t const * rent = fd_bank_rent_query( bank ); @@ -1672,66 +1627,54 @@ fd_executor_txn_check( fd_bank_t * bank, ulong ending_lamports_h = 0; /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L63 */ - for( ulong idx = 0; idx < txn_out->accounts.accounts_cnt; idx++ ) { - fd_txn_account_t * b = &txn_out->accounts.accounts[idx]; + for( ulong idx = 0; idx < txn_out->accounts.cnt; idx++ ) { + ulong starting_lamports = runtime->accounts.starting_lamports[idx]; + ulong starting_dlen = runtime->accounts.starting_dlen[idx]; + fd_account_meta_t * meta = txn_out->accounts.metas[idx]; + fd_pubkey_t * pubkey = &txn_out->accounts.keys[idx]; // Was this account written to? /* TODO: Clean this logic up... lots of redundant checks with our newer account loading model. We should be using the rent transition checking logic instead, along with a small refactor to keep check ordering consistent. */ - if( fd_txn_account_get_meta( b )!=NULL ) { - fd_uwide_inc( &ending_lamports_h, &ending_lamports_l, ending_lamports_h, ending_lamports_l, fd_txn_account_get_lamports( b ) ); + if( meta!=NULL ) { + + fd_uwide_inc( &ending_lamports_h, &ending_lamports_l, ending_lamports_h, ending_lamports_l, meta->lamports ); /* Rent states are defined as followed: - lamports == 0 -> Uninitialized - 0 < lamports < rent_exempt_minimum -> RentPaying - lamports >= rent_exempt_minimum -> RentExempt In Agave, 'self' refers to our 'after' state. */ - uchar after_uninitialized = fd_txn_account_get_lamports( b ) == 0; - uchar after_rent_exempt = fd_txn_account_get_lamports( b ) >= fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( b ) ); + uchar after_uninitialized = meta->lamports == 0; + uchar after_rent_exempt = meta->lamports >= fd_rent_exempt_minimum_balance( rent, meta->dlen ); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L96 */ - if( FD_LIKELY( memcmp( b->pubkey->key, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) != 0 ) ) { + if( FD_LIKELY( memcmp( pubkey, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) != 0 ) ) { /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L44 */ if( after_uninitialized || after_rent_exempt ) { // no-op } else { /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L45-L59 */ - uchar before_uninitialized = b->starting_dlen == ULONG_MAX || b->starting_lamports == 0; - uchar before_rent_exempt = b->starting_dlen != ULONG_MAX && b->starting_lamports >= fd_rent_exempt_minimum_balance( rent, b->starting_dlen ); + uchar before_uninitialized = starting_dlen == ULONG_MAX || starting_lamports == 0; + uchar before_rent_exempt = starting_dlen != ULONG_MAX && starting_lamports >= fd_rent_exempt_minimum_balance( rent, starting_dlen ); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L50 */ if( before_uninitialized || before_rent_exempt ) { - FD_LOG_DEBUG(( "Rent exempt error for %s Curr len %lu Starting len %lu Curr lamports %lu Starting lamports %lu Curr exempt %lu Starting exempt %lu", - FD_BASE58_ENC_32_ALLOCA( b->pubkey->uc ), - fd_txn_account_get_data_len( b ), - b->starting_dlen, - fd_txn_account_get_lamports( b ), - b->starting_lamports, - fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( b ) ), - fd_rent_exempt_minimum_balance( rent, b->starting_dlen ) )); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L56 */ - } else if( (fd_txn_account_get_data_len( b ) == b->starting_dlen) && fd_txn_account_get_lamports( b ) <= b->starting_lamports ) { + } else if( (meta->dlen == starting_dlen) && meta->lamports <= starting_lamports ) { // no-op } else { - FD_LOG_DEBUG(( "Rent exempt error for %s Curr len %lu Starting len %lu Curr lamports %lu Starting lamports %lu Curr exempt %lu Starting exempt %lu", - FD_BASE58_ENC_32_ALLOCA( b->pubkey->uc ), - fd_txn_account_get_data_len( b ), - b->starting_dlen, - fd_txn_account_get_lamports( b ), - b->starting_lamports, - fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( b ) ), - fd_rent_exempt_minimum_balance( rent, b->starting_dlen ) )); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; } } } - if( b->starting_lamports != ULONG_MAX ) { - fd_uwide_inc( &starting_lamports_h, &starting_lamports_l, starting_lamports_h, starting_lamports_l, b->starting_lamports ); + if( starting_lamports != ULONG_MAX ) { + fd_uwide_inc( &starting_lamports_h, &starting_lamports_l, starting_lamports_h, starting_lamports_l, starting_lamports ); } } } @@ -1745,6 +1688,42 @@ fd_executor_txn_check( fd_bank_t * bank, return FD_RUNTIME_EXECUTE_SUCCESS; } + +int +fd_execute_txn( fd_runtime_t * runtime, + fd_bank_t * bank, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out ) { + + bool dump_insn = runtime->log.capture_ctx && fd_bank_slot_get( bank ) >= runtime->log.capture_ctx->dump_proto_start_slot && runtime->log.capture_ctx->dump_instr_to_pb; + (void)dump_insn; + + /* Initialize log collection. */ + fd_log_collector_init( runtime->log.log_collector, runtime->log.enable_log_collector ); + + for( ushort i=0; itxn )->instr_cnt; i++ ) { + runtime->instr.current_idx = i; +# if FD_HAS_FLATCC + if( FD_UNLIKELY( dump_insn ) ) { + // Capture the input and convert it into a Protobuf message + fd_dump_instr_to_protobuf( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i], i ); + } +# endif + + int instr_exec_result = fd_execute_instr( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i] ); + if( FD_UNLIKELY( instr_exec_result!=FD_EXECUTOR_INSTR_SUCCESS ) ) { + if( txn_out->err.exec_err_idx==INT_MAX ) { + txn_out->err.exec_err_idx = i; + } + return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR; + } + } + + /* TODO: This function needs to be split out of fd_execute_txn and be placed + into the replay tile once it is implemented. */ + return fd_executor_txn_check( runtime, bank, txn_out ); +} + int fd_executor_consume_cus( fd_txn_out_t * txn_out, ulong cus ) { diff --git a/src/flamenco/runtime/fd_executor.h b/src/flamenco/runtime/fd_executor.h index dd9e5216d0..b2a8d1ab8c 100644 --- a/src/flamenco/runtime/fd_executor.h +++ b/src/flamenco/runtime/fd_executor.h @@ -32,7 +32,7 @@ FD_PROTOTYPES_BEGIN typedef int (* fd_exec_instr_fn_t)( fd_exec_instr_ctx_t * ctx ); fd_exec_instr_fn_t -fd_executor_lookup_native_precompile_program( fd_txn_account_t const * prog_acc ); +fd_executor_lookup_native_precompile_program( fd_pubkey_t const * pubkey ); /* Returns 1 if the given pubkey matches one of the BPF loader v1/v2/v3/v4 program IDs, and 0 otherwise. */ @@ -100,17 +100,9 @@ fd_executor_setup_txn_alut_account_keys( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out ); -/* - Validate the txn after execution for violations of various lamport balance and size rules - */ - -int -fd_executor_txn_check( fd_bank_t * bank, - fd_txn_out_t * txn_out ); - void -fd_executor_reclaim_account( fd_txn_account_t * account, - ulong slot ); +fd_executor_reclaim_account( fd_account_meta_t * meta, + ulong slot ); /* fd_io_strerror converts an FD_EXECUTOR_INSTR_ERR_{...} code into a human readable cstr. The lifetime of the returned pointer is diff --git a/src/flamenco/runtime/fd_hashes.c b/src/flamenco/runtime/fd_hashes.c index ce2515d3b1..863d12e19e 100644 --- a/src/flamenco/runtime/fd_hashes.c +++ b/src/flamenco/runtime/fd_hashes.c @@ -76,15 +76,15 @@ fd_hashes_hash_bank( fd_lthash_value_t const * lthash, } void -fd_hashes_update_lthash( fd_txn_account_t const * account, +fd_hashes_update_lthash( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, fd_lthash_value_t const * prev_account_hash, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ) { /* Hash the new version of the account */ fd_lthash_value_t new_hash[1]; - fd_account_meta_t const * meta = fd_txn_account_get_meta( account ); - fd_hashes_account_lthash( account->pubkey, meta, fd_txn_account_get_data( account ), new_hash ); + fd_hashes_account_lthash( pubkey, meta, fd_account_data( meta ), new_hash ); /* Subtract the old hash of the account from the bank lthash */ fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) ); @@ -99,19 +99,20 @@ fd_hashes_update_lthash( fd_txn_account_t const * account, if( capture_ctx && capture_ctx->capture && fd_bank_slot_get( bank )>=capture_ctx->solcap_start_slot && memcmp( prev_account_hash->bytes, new_hash->bytes, sizeof(fd_lthash_value_t))!=0 ) { - fd_solana_account_meta_t meta[1]; + fd_solana_account_meta_t solana_meta[1]; fd_solana_account_meta_init( - meta, - fd_txn_account_get_lamports ( account ), - fd_txn_account_get_owner ( account ), - fd_txn_account_is_executable( account ) + solana_meta, + meta->lamports, + meta->owner, + meta->executable ); int err = fd_solcap_write_account( capture_ctx->capture, - account->pubkey, - meta, - fd_txn_account_get_data( account ), - fd_txn_account_get_data_len( account ) ); + pubkey, + solana_meta, + fd_account_data( meta ), + meta->dlen + ); if( FD_UNLIKELY( err ) ) { FD_LOG_ERR(( "Failed to write account to capture file" )); } diff --git a/src/flamenco/runtime/fd_hashes.h b/src/flamenco/runtime/fd_hashes.h index 55e6179f6d..3829b6f53f 100644 --- a/src/flamenco/runtime/fd_hashes.h +++ b/src/flamenco/runtime/fd_hashes.h @@ -84,7 +84,7 @@ fd_hashes_account_lthash_simple( uchar const pubkey[ static FD_HASH_FOOT maintained incrementally by subtracting the old account hash and adding the new account hash. - account is the modified account (via fd_txn_account_t interface). + meta is a pointer to the modified account's metadata and data. prev_hash contains the lthash of the account before modification (or zero for newly created accounts). bank is the bank whose lthash should be updated. capture_ctx is an optional capture context for @@ -106,7 +106,8 @@ fd_hashes_account_lthash_simple( uchar const pubkey[ static FD_HASH_FOOT execution. This includes sysvar accounts. */ void -fd_hashes_update_lthash( fd_txn_account_t const * account, +fd_hashes_update_lthash( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, fd_lthash_value_t const * prev_account_hash, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ); diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 4854c58ec4..f6e9859dc6 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -22,6 +22,7 @@ #include "program/fd_stake_program.h" #include "program/fd_builtin_programs.h" +#include "program/fd_program_util.h" #include "sysvar/fd_sysvar_clock.h" #include "sysvar/fd_sysvar_last_restart_slot.h" @@ -236,7 +237,7 @@ fd_runtime_run_incinerator( fd_bank_t * bank, fd_bank_capitalization_set( bank, new_capitalization ); fd_txn_account_set_lamports( rec, 0UL ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); return 0; @@ -320,7 +321,7 @@ fd_runtime_freeze( fd_bank_t * bank, fd_txn_account_checked_add_lamports( rec, fees ); fd_txn_account_set_slot( rec, fd_bank_slot_get( bank ) ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); } while(0); @@ -538,7 +539,7 @@ fd_feature_activate( fd_bank_t * bank, FD_LOG_ERR(( "Failed to encode feature account %s (%d)", addr_b58, decode_err )); } - fd_hashes_update_lthash( modify_acct_rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( modify_acct_rec->pubkey, modify_acct_rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( modify_acct_rec, accdb, &modify_acct_prepare ); } } @@ -977,14 +978,14 @@ fd_runtime_pre_execute_check( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.1.14/runtime/src/bank.rs#L4116 In any case, we should always add the dlen of the fee payer. */ - txn_out->details.loaded_accounts_data_size = fd_txn_account_get_data_len( &txn_out->accounts.accounts[FD_FEE_PAYER_TXN_IDX] ); + txn_out->details.loaded_accounts_data_size = txn_out->accounts.metas[ FD_FEE_PAYER_TXN_IDX ]->dlen; /* Special case handling for if a nonce account is present in the transaction. */ if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { /* If the nonce account is not the fee payer, then we separately add the dlen of the nonce account. Otherwise, we would be double counting the dlen of the fee payer. */ if( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) { - txn_out->details.loaded_accounts_data_size += fd_txn_account_get_data_len( txn_out->accounts.rollback_nonce ); + txn_out->details.loaded_accounts_data_size += txn_out->accounts.rollback_nonce->dlen; } } } @@ -1012,21 +1013,18 @@ fd_runtime_pre_execute_check( fd_runtime_t * runtime, static void fd_runtime_finalize_account( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_txn_account_t * acc, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, fd_funk_rec_t * prev_rec ) { - if( FD_UNLIKELY( !fd_txn_account_is_mutable( acc ) ) ) { - FD_LOG_CRIT(( "fd_runtime_finalize_account: account is not mutable" )); - } - fd_pubkey_t const * key = acc->pubkey; - uchar const * record_data = (uchar *)fd_txn_account_get_meta( acc ); - ulong record_sz = fd_account_meta_get_record_sz( acc->meta ); + uchar const * record_data = (uchar *)meta; + ulong record_sz = fd_account_meta_get_record_sz( meta ); int err = FD_FUNK_SUCCESS; if( !prev_rec || !fd_funk_txn_xid_eq( prev_rec->pair.xid, xid ) ) { - fd_funk_rec_key_t funk_key = fd_funk_acc_key( key ); + fd_funk_rec_key_t funk_key = fd_funk_acc_key( pubkey ); fd_funk_rec_prepare_t prepare[1]; fd_funk_rec_t * rec = fd_funk_rec_prepare( funk, xid, &funk_key, prepare, &err ); if( FD_UNLIKELY( !rec || err!=FD_FUNK_SUCCESS ) ) { @@ -1072,7 +1070,8 @@ fd_runtime_finalize_account( fd_funk_t * funk, TODO: remove this when solcap v2 is here. */ static void -fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, +fd_runtime_buffer_solcap_account_update( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ) { @@ -1082,12 +1081,11 @@ fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, } /* Get account data */ - fd_account_meta_t const * meta = fd_txn_account_get_meta( account ); - void const * data = fd_txn_account_get_data( account ); + void const * data = fd_account_data( meta ); /* Calculate account hash using lthash */ fd_lthash_value_t lthash[1]; - fd_hashes_account_lthash( account->pubkey, meta, data, lthash ); + fd_hashes_account_lthash( pubkey, meta, data, lthash ); /* Calculate message size */ if( FD_UNLIKELY( capture_ctx->account_updates_len >= FD_CAPTURE_CTX_MAX_ACCOUNT_UPDATES ) ) { @@ -1097,15 +1095,14 @@ fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, /* Write the message to the buffer */ fd_capture_ctx_account_update_msg_t * account_update_msg = (fd_capture_ctx_account_update_msg_t *)(capture_ctx->account_updates_buffer_ptr); - account_update_msg->pubkey = *account->pubkey; + account_update_msg->pubkey = *pubkey; account_update_msg->data_sz = meta->dlen; account_update_msg->bank_idx = bank->idx; fd_solana_account_meta_init( &account_update_msg->info, - fd_txn_account_get_lamports ( account ), - fd_txn_account_get_owner ( account ), - fd_txn_account_is_executable( account ) - ); + meta->lamports, + meta->owner, + meta->executable ); memcpy( account_update_msg->hash.uc, lthash->bytes, sizeof(fd_hash_t) ); capture_ctx->account_updates_buffer_ptr += sizeof(fd_capture_ctx_account_update_msg_t); @@ -1144,7 +1141,8 @@ fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, static void fd_runtime_save_account( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_txn_account_t * account, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ) { /* Look up the previous version of the account from Funk */ @@ -1153,7 +1151,7 @@ fd_runtime_save_account( fd_funk_t * funk, fd_account_meta_t const * prev_meta = fd_funk_get_acc_meta_readonly( funk, xid, - account->pubkey, + pubkey, fd_type_pun( &funk_prev_rec ), &err, NULL ); @@ -1164,21 +1162,22 @@ fd_runtime_save_account( fd_funk_t * funk, fd_lthash_zero( prev_hash ); if( err != FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) { fd_hashes_account_lthash( - account->pubkey, + pubkey, prev_meta, prev_data, prev_hash ); } /* Mix in the account hash into the bank hash */ - fd_hashes_update_lthash( account, prev_hash, bank, NULL ); + fd_hashes_update_lthash( pubkey, meta, prev_hash, bank, NULL ); /* Publish account update to replay tile for solcap writing TODO: write in the exec tile with solcap v2 */ - fd_runtime_buffer_solcap_account_update( account, bank, capture_ctx ); + + fd_runtime_buffer_solcap_account_update( pubkey, meta, bank, capture_ctx ); /* Save the new version of the account to Funk */ - fd_runtime_finalize_account( funk, xid, account, funk_prev_rec ); + fd_runtime_finalize_account( funk, xid, pubkey, meta, funk_prev_rec ); } /* fd_runtime_commit_txn is a helper used by the non-tpool transaction @@ -1212,48 +1211,56 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, We should always rollback the nonce account first. Note that the nonce account may be the fee payer (case 2). */ if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { - fd_runtime_save_account( runtime->funk, &xid, txn_out->accounts.rollback_nonce, bank, runtime->log.capture_ctx ); + fd_runtime_save_account( runtime->funk, + &xid, + &txn_out->accounts.keys[txn_out->accounts.nonce_idx_in_txn], + txn_out->accounts.rollback_nonce, + bank, + runtime->log.capture_ctx ); } /* Now, we must only save the fee payer if the nonce account was not the fee payer (because that was already saved above) */ if( FD_LIKELY( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { - fd_runtime_save_account( runtime->funk, &xid, txn_out->accounts.rollback_fee_payer, bank, runtime->log.capture_ctx ); + fd_runtime_save_account( runtime->funk, + &xid, + &txn_out->accounts.keys[FD_FEE_PAYER_TXN_IDX], + txn_out->accounts.rollback_fee_payer, + bank, + runtime->log.capture_ctx ); } } else { - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { + for( ushort i=0; iaccounts.cnt; i++ ) { /* We are only interested in saving writable accounts and the fee payer account. */ if( !fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i ) && i!=FD_FEE_PAYER_TXN_IDX ) { continue; } - fd_txn_account_t * acc_rec = fd_txn_account_join( &txn_out->accounts.accounts[i] ); - if( FD_UNLIKELY( !acc_rec ) ) { - FD_LOG_CRIT(( "fd_runtime_commit_txn: failed to join account at idx %u", i )); - } + fd_pubkey_t const * pubkey = &txn_out->accounts.keys[i]; + fd_account_meta_t * meta = txn_out->accounts.metas[i]; /* Tips for bundles are collected in the bank: a user submitting a bundle must include a instruction that transfers lamports to a specific tip account. Tips accumulated through the slot. */ - if( fd_pack_tip_is_tip_account( fd_type_pun( acc_rec->pubkey->uc ) ) ) { - txn_out->details.tips += fd_ulong_sat_sub( acc_rec->meta->lamports, acc_rec->starting_lamports ); + if( fd_pack_tip_is_tip_account( fd_type_pun_const( pubkey->uc ) ) ) { + txn_out->details.tips += fd_ulong_sat_sub( meta->lamports, runtime->accounts.starting_lamports[i] ); FD_ATOMIC_FETCH_AND_ADD( fd_bank_tips_modify( bank ), txn_out->details.tips ); } - if( 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_vote_program_id, sizeof(fd_pubkey_t) ) ) { - fd_stakes_update_vote_state( acc_rec, bank ); + if( 0==memcmp( meta->owner, &fd_solana_vote_program_id, sizeof(fd_pubkey_t) ) ) { + fd_stakes_update_vote_state( pubkey, meta, bank ); } - if( 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_stake_program_id, sizeof(fd_pubkey_t) ) ) { - fd_stakes_update_stake_delegation( acc_rec, bank ); + if( 0==memcmp( meta->owner, &fd_solana_stake_program_id, sizeof(fd_pubkey_t) ) ) { + fd_stakes_update_stake_delegation( pubkey, meta, bank ); } /* Reclaim any accounts that have 0-lamports, now that any related cache updates have been applied. */ - fd_executor_reclaim_account( &txn_out->accounts.accounts[i], fd_bank_slot_get( bank ) ); + fd_executor_reclaim_account( txn_out->accounts.metas[i], fd_bank_slot_get( bank ) ); - fd_runtime_save_account( runtime->funk, &xid, &txn_out->accounts.accounts[i], bank, runtime->log.capture_ctx ); + fd_runtime_save_account( runtime->funk, &xid, pubkey, meta, bank, runtime->log.capture_ctx ); } /* We need to queue any existing program accounts that may have @@ -1325,7 +1332,7 @@ fd_runtime_prepare_and_execute_txn( fd_runtime_t * runtime, txn_out->details.exec_start_timestamp = LONG_MAX; txn_out->details.commit_start_timestamp = LONG_MAX; - txn_out->accounts.accounts_cnt = 0UL; + txn_out->accounts.cnt = 0UL; txn_out->details.programs_to_reverify_cnt = 0UL; txn_out->details.loaded_accounts_data_size = 0UL; @@ -1339,7 +1346,7 @@ fd_runtime_prepare_and_execute_txn( fd_runtime_t * runtime, memset( txn_out->details.return_data.program_id.key, 0, sizeof(fd_pubkey_t) ); fd_compute_budget_details_new( &txn_out->details.compute_budget ); - runtime->executable.cnt = 0UL; + runtime->accounts.executable_cnt = 0UL; runtime->log.enable_log_collector = 0; runtime->instr.info_cnt = 0UL; runtime->instr.trace_length = 0UL; @@ -1731,8 +1738,8 @@ fd_runtime_block_execute_finalize( fd_bank_t * bank, int fd_runtime_find_index_of_account( fd_txn_out_t const * txn_out, fd_pubkey_t const * pubkey ) { - for( ulong i=txn_out->accounts.accounts_cnt; i>0UL; i-- ) { - if( 0==memcmp( pubkey, &txn_out->accounts.account_keys[ i-1UL ], sizeof(fd_pubkey_t) ) ) { + for( ulong i=txn_out->accounts.cnt; i>0UL; i-- ) { + if( 0==memcmp( pubkey, &txn_out->accounts.keys[ i-1UL ], sizeof(fd_pubkey_t) ) ) { return (int)(i-1UL); } } @@ -1743,17 +1750,13 @@ int fd_runtime_get_account_at_index( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx, - fd_txn_account_t * * account, fd_txn_account_condition_fn_t * condition ) { - if( FD_UNLIKELY( idx>=txn_out->accounts.accounts_cnt ) ) { + if( FD_UNLIKELY( idx>=txn_out->accounts.cnt ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } - fd_txn_account_t * txn_account = &txn_out->accounts.accounts[idx]; - *account = txn_account; - if( FD_LIKELY( condition != NULL ) ) { - if( FD_UNLIKELY( !condition( *account, txn_in, txn_out, idx ) ) ) { + if( FD_UNLIKELY( !condition( txn_in, txn_out, idx ) ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } } @@ -1765,52 +1768,54 @@ int fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, + int * index_out, fd_txn_account_condition_fn_t * condition ) { int index = fd_runtime_find_index_of_account( txn_out, pubkey ); if( FD_UNLIKELY( index==-1 ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } + *index_out = index; + return fd_runtime_get_account_at_index( txn_in, txn_out, (uchar)index, - account, condition ); } int -fd_runtime_get_executable_account( fd_runtime_t * runtime, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out, - fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, - fd_txn_account_condition_fn_t * condition ) { - /* First try to fetch the executable account from the existing borrowed accounts. - If the pubkey is in the account keys, then we want to re-use that - borrowed account since it reflects changes from prior instructions. Referencing the - read-only executable accounts list is incorrect behavior when the program - data account is written to in a prior instruction (e.g. program upgrade + invoke within the same txn) */ +fd_runtime_get_executable_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out, + fd_pubkey_t const * pubkey, + fd_account_meta_t const * * meta ) { + /* First try to fetch the executable account from the existing + borrowed accounts. If the pubkey is in the account keys, then we + want to re-use that borrowed account since it reflects changes from + prior instructions. Referencing the read-only executable accounts + list is incorrect behavior when the program data account is written + to in a prior instruction (e.g. program upgrade + invoke within the + same txn) */ + + fd_txn_account_condition_fn_t * condition = fd_runtime_account_check_exists; + + int index; int err = fd_runtime_get_account_with_key( txn_in, txn_out, pubkey, - account, + &index, condition ); if( FD_UNLIKELY( err==FD_ACC_MGR_SUCCESS ) ) { + *meta = txn_out->accounts.metas[index]; return FD_ACC_MGR_SUCCESS; } - for( ushort i=0; iexecutable.cnt; i++ ) { - if( memcmp( pubkey->uc, runtime->executable.accounts[i].pubkey->uc, sizeof(fd_pubkey_t) )==0 ) { - fd_txn_account_t * txn_account = &runtime->executable.accounts[i]; - *account = txn_account; - - if( FD_LIKELY( condition != NULL ) ) { - if( FD_UNLIKELY( !condition( *account, txn_in, txn_out, i ) ) ) { - return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; - } + for( ushort i=0; iaccounts.executable_cnt; i++ ) { + if( memcmp( pubkey->uc, runtime->accounts.executable_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) { + *meta = runtime->accounts.executables_meta[i]; + if( FD_UNLIKELY( !fd_account_meta_exists( *meta ) ) ) { + return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } - return FD_ACC_MGR_SUCCESS; } } @@ -1824,11 +1829,11 @@ fd_runtime_get_key_of_account_at_index( fd_txn_out_t * txn_out, fd_pubkey_t const * * key ) { /* Return a NotEnoughAccountKeys error if idx is out of bounds. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L218 */ - if( FD_UNLIKELY( idx>=txn_out->accounts.accounts_cnt ) ) { + if( FD_UNLIKELY( idx>=txn_out->accounts.cnt ) ) { return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } - *key = &txn_out->accounts.account_keys[ idx ]; + *key = &txn_out->accounts.keys[ idx ]; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -1899,10 +1904,10 @@ fd_runtime_account_is_writable_idx( fd_txn_in_t const * txn_in, fd_txn_out_t const * txn_out, fd_bank_t * bank, ushort idx ) { - uint bpf_upgradeable = fd_txn_account_has_bpf_loader_upgradeable( txn_out->accounts.account_keys, txn_out->accounts.accounts_cnt ); + uint bpf_upgradeable = fd_txn_account_has_bpf_loader_upgradeable( txn_out->accounts.keys, txn_out->accounts.cnt ); return fd_runtime_account_is_writable_idx_flat( fd_bank_slot_get( bank ), idx, - &txn_out->accounts.account_keys[idx], + &txn_out->accounts.keys[idx], TXN( txn_in->txn ), fd_bank_features_query( bank ), bpf_upgradeable ); @@ -1911,22 +1916,42 @@ fd_runtime_account_is_writable_idx( fd_txn_in_t const * txn_in, /* Account pre-condition filtering functions */ int -fd_runtime_account_check_exists( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_exists( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ) { (void) txn_in; - (void) txn_out; - (void) idx; - return fd_account_meta_exists( fd_txn_account_get_meta( acc ) ); + return fd_account_meta_exists( txn_out->accounts.metas[idx] ); } int -fd_runtime_account_check_fee_payer_writable( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_fee_payer_writable( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ) { (void) txn_out; - (void) acc; return fd_txn_is_writable( TXN( txn_in->txn ), idx ); } + + +int +fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, ulong lamports ) { + ulong balance_post = 0UL; + int err = fd_ulong_checked_sub( meta->lamports, + lamports, + &balance_post ); + if( FD_UNLIKELY( err ) ) { + return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; + } + + meta->lamports = balance_post; + return FD_EXECUTOR_INSTR_SUCCESS; +} + +void +fd_account_meta_resize( fd_account_meta_t * meta, + ulong dlen ) { + ulong old_sz = meta->dlen; + ulong new_sz = dlen; + ulong memset_sz = fd_ulong_sat_sub( new_sz, old_sz ); + fd_memset( fd_account_data( meta ) + old_sz, 0, memset_sz ); + meta->dlen = (uint)dlen; +} diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 0d89225d70..b859c29c10 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -128,9 +128,14 @@ struct fd_runtime { } stake_program; struct { - ulong cnt; /* Number of BPF upgradeable loader accounts. */ - fd_txn_account_t accounts[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ - } executable; + ulong executable_cnt; /* Number of BPF upgradeable loader accounts. */ + fd_account_meta_t const * executables_meta[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + fd_pubkey_t executable_pubkeys[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + + ulong starting_lamports[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting lamports for each account */ + ulong starting_dlen[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting data length for each account */ + ulong refcnt[ MAX_TX_ACCOUNT_LOCKS ]; /* Reference count for each account */ + } accounts; }; typedef struct fd_runtime fd_runtime_t; @@ -196,28 +201,24 @@ struct fd_txn_out { https://github.com/anza-xyz/agave/blob/838c1952595809a31520ff1603a13f2c9123aa51/accounts-db/src/account_locks.rs#L118 That is the limit we are going to use here. */ struct { - /* TODO: These fd_txn_account_t arrays should be replaced with an - array of fd_account_meta_t pointers. Currently, the - fd_txn_account_t is just a wrapper around uchar data pointers. */ - ulong accounts_cnt; - fd_txn_account_t accounts[ MAX_TX_ACCOUNT_LOCKS ]; - /* The account keys are used by the CU rebating mechanism in the - bank tile (leader pipeline). */ - fd_pubkey_t account_keys[ MAX_TX_ACCOUNT_LOCKS ]; - - /* The rollback accounts are special cased accounts that are still - committed to the accounts database even if a transaction fails - to execute (but still lands on chain). The state of both the - nonce and fee payer account is saved after the nonce is advanced - and the fee payer is debited. If the transaction fails to - execute, the state must be rolled back to when the accounts were - in this state and then they are free to be committed to the - accounts database. */ - ulong nonce_idx_in_txn; - fd_txn_account_t rollback_nonce[ 1 ]; + ulong cnt; + fd_pubkey_t keys[ MAX_TX_ACCOUNT_LOCKS ]; + fd_account_meta_t * metas[ MAX_TX_ACCOUNT_LOCKS ]; + + /* The fee payer and nonce accounts are treated differently than + other accounts: if an on-transaction fails they are still + committed to the accounts database. However, they are saved at + the point where they were before the transaction was executed + because the failed transaction could have potentially modified + these accounts. The rollback fee payer and nonce are used to + store the state of these accounts after fees have been debited + and the nonce has been advanced, but before the transaction is + executed. */ + fd_account_meta_t * rollback_fee_payer; /* If the transaction has a nonce account that must be advanced, this would be !=ULONG_MAX. */ - fd_txn_account_t rollback_fee_payer[ 1 ]; + ulong nonce_idx_in_txn; + fd_account_meta_t * rollback_nonce; } accounts; }; typedef struct fd_txn_out fd_txn_out_t; diff --git a/src/flamenco/runtime/fd_runtime_helpers.h b/src/flamenco/runtime/fd_runtime_helpers.h index 7e7a9d4971..a45d948d42 100644 --- a/src/flamenco/runtime/fd_runtime_helpers.h +++ b/src/flamenco/runtime/fd_runtime_helpers.h @@ -134,8 +134,7 @@ int fd_runtime_find_index_of_account( fd_txn_out_t const * txn_out, fd_pubkey_t const * pubkey ); -typedef int fd_txn_account_condition_fn_t ( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +typedef int fd_txn_account_condition_fn_t ( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ); @@ -151,7 +150,6 @@ int fd_runtime_get_account_at_index( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx, - fd_txn_account_t * * account, fd_txn_account_condition_fn_t * condition ); /* A wrapper around fd_exec_txn_ctx_get_account_at_index that obtains an @@ -161,18 +159,17 @@ int fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, + int * index_out, fd_txn_account_condition_fn_t * condition ); /* Gets an executable (program data) account via its pubkey. */ int -fd_runtime_get_executable_account( fd_runtime_t * runtime, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out, - fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, - fd_txn_account_condition_fn_t * condition ); +fd_runtime_get_executable_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out, + fd_pubkey_t const * pubkey, + fd_account_meta_t const * * meta ); /* Mirrors Agave function solana_sdk::transaction_context::get_key_of_account_at_index @@ -208,8 +205,7 @@ fd_runtime_account_is_writable_idx( fd_txn_in_t const * txn_in, when obtaining accounts from the transaction context. Passed as a function pointer. */ int -fd_runtime_account_check_exists( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_exists( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ); @@ -220,11 +216,18 @@ fd_runtime_account_check_exists( fd_txn_account_t * acc, doesn't have a writable signature. */ int -fd_runtime_account_check_fee_payer_writable( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_fee_payer_writable( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ); +int +fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, + ulong lamports ); + +void +fd_account_meta_resize( fd_account_meta_t * meta, + ulong dlen ); + FD_PROTOTYPES_END #endif /* HEADER_fd_src_flamenco_runtime_fd_runtime_helpers_h */ diff --git a/src/flamenco/runtime/fd_txn_account.c b/src/flamenco/runtime/fd_txn_account.c index 635eaf9432..25d8f7a477 100644 --- a/src/flamenco/runtime/fd_txn_account.c +++ b/src/flamenco/runtime/fd_txn_account.c @@ -33,10 +33,7 @@ fd_txn_account_new( void * mem, fd_memcpy( txn_account->pubkey, pubkey, sizeof(fd_pubkey_t) ); - txn_account->magic = FD_TXN_ACCOUNT_MAGIC; - - txn_account->starting_dlen = meta->dlen; - txn_account->starting_lamports = meta->lamports; + txn_account->magic = FD_TXN_ACCOUNT_MAGIC; uchar * data = (uchar *)meta + sizeof(fd_account_meta_t); @@ -222,46 +219,6 @@ fd_txn_account_mutable_fini( fd_txn_account_t * acct, } } -/* read/write mutual exclusion */ - -FD_FN_PURE int -fd_txn_account_acquire_write_is_safe( fd_txn_account_t const * acct ) { - return !acct->refcnt_excl; -} - -/* fd_txn_account_acquire_write acquires write/exclusive access. - Causes all other write or read acquire attempts will fail. Returns 1 - on success, 0 on failure. - - Mirrors a try_borrow_mut() call in Agave. */ -int -fd_txn_account_acquire_write( fd_txn_account_t * acct ) { - if( FD_UNLIKELY( !fd_txn_account_acquire_write_is_safe( acct ) ) ) { - return 0; - } - acct->refcnt_excl = (ushort)1; - return 1; -} - -/* fd_txn_account_release_write{_private} releases a write/exclusive - access handle. The private version should only be used by fd_borrowed_account_drop - and fd_borrowed_account_destroy. */ -void -fd_txn_account_release_write( fd_txn_account_t * acct ) { - if( FD_UNLIKELY( acct->refcnt_excl!=1 ) ) { - FD_LOG_CRIT(( "refcnt_excl is %d, expected 1", acct->refcnt_excl )); - } - acct->refcnt_excl = (ushort)0; -} - -void -fd_txn_account_release_write_private( fd_txn_account_t * acct ) { - /* Only release if it is not yet released */ - if( !fd_txn_account_acquire_write_is_safe( acct ) ) { - fd_txn_account_release_write( acct ); - } -} - fd_pubkey_t const * fd_txn_account_get_owner( fd_txn_account_t const * acct ) { if( FD_UNLIKELY( !acct->meta ) ) { @@ -452,11 +409,6 @@ fd_txn_account_resize( fd_txn_account_t * acct, acct->meta->dlen = (uint)dlen; } -ushort -fd_txn_account_is_borrowed( fd_txn_account_t const * acct ) { - return !!acct->refcnt_excl; -} - int fd_txn_account_is_mutable( fd_txn_account_t const * acct ) { /* A txn account is mutable if meta is non NULL */ @@ -469,16 +421,6 @@ fd_txn_account_is_readonly( fd_txn_account_t const * acct ) { return !acct->is_mutable; } -int -fd_txn_account_try_borrow_mut( fd_txn_account_t * acct ) { - return fd_txn_account_acquire_write( acct ); -} - -void -fd_txn_account_drop( fd_txn_account_t * acct ) { - fd_txn_account_release_write_private( acct ); -} - void fd_txn_account_set_readonly( fd_txn_account_t * acct ) { acct->is_mutable = 0; diff --git a/src/flamenco/runtime/fd_txn_account.h b/src/flamenco/runtime/fd_txn_account.h index 271caa55ce..5a48a20825 100644 --- a/src/flamenco/runtime/fd_txn_account.h +++ b/src/flamenco/runtime/fd_txn_account.h @@ -34,14 +34,6 @@ struct __attribute__((aligned(8UL))) fd_txn_account { int is_mutable; long meta_soff; - - ulong starting_dlen; - ulong starting_lamports; - - /* Provide borrowing semantics. Used for single-threaded logic only, - thus not comparable to a data synchronization lock. */ - ushort refcnt_excl; - }; typedef struct fd_txn_account fd_txn_account_t; #define FD_TXN_ACCOUNT_FOOTPRINT (sizeof(fd_txn_account_t)) @@ -199,21 +191,12 @@ fd_txn_account_clear_owner( fd_txn_account_t * acct ); void fd_txn_account_resize( fd_txn_account_t * acct, ulong dlen ); -ushort -fd_txn_account_is_borrowed( fd_txn_account_t const * acct ); - int fd_txn_account_is_mutable( fd_txn_account_t const * acct ); int fd_txn_account_is_readonly( fd_txn_account_t const * acct ); -int -fd_txn_account_try_borrow_mut( fd_txn_account_t * acct ); - -void -fd_txn_account_drop( fd_txn_account_t * acct ); - void fd_txn_account_set_readonly( fd_txn_account_t * acct ); diff --git a/src/flamenco/runtime/info/fd_instr_info.c b/src/flamenco/runtime/info/fd_instr_info.c index 61fe017017..b07555940f 100644 --- a/src/flamenco/runtime/info/fd_instr_info.c +++ b/src/flamenco/runtime/info/fd_instr_info.c @@ -8,12 +8,13 @@ fd_instr_info_accumulate_starting_lamports( fd_instr_info_t * instr, ushort idx_in_callee, ushort idx_in_txn ) { if( FD_LIKELY( !instr->is_duplicate[ idx_in_callee ] ) ) { - fd_txn_account_t const * account = &txn_out->accounts.accounts[ idx_in_txn ]; - if( fd_txn_account_get_meta( account ) ) { + + fd_account_meta_t const * meta = txn_out->accounts.metas[ idx_in_txn ]; + if( meta ) { fd_uwide_inc( &instr->starting_lamports_h, &instr->starting_lamports_l, instr->starting_lamports_h, instr->starting_lamports_l, - fd_txn_account_get_lamports( account ) ); + meta->lamports ); } } } @@ -65,9 +66,9 @@ fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, *total_lamports_l = 0UL; for( ulong i=0UL; iacct_cnt; ++i ) { ushort idx_in_txn = instr->accounts[i].index_in_transaction; - fd_txn_account_t const * account = &txn_out->accounts.accounts[ idx_in_txn ]; + fd_account_meta_t const * meta = txn_out->accounts.metas[ idx_in_txn ]; - if( !fd_txn_account_get_meta( account ) || + if( !meta || instr->is_duplicate[i] ) { continue; } @@ -76,8 +77,7 @@ fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, ulong tmp_total_lamports_h = 0UL; ulong tmp_total_lamports_l = 0UL; - fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, *total_lamports_h, *total_lamports_l, - fd_txn_account_get_lamports( account ) ); + fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, *total_lamports_h, *total_lamports_l, meta->lamports ); if( tmp_total_lamports_h < *total_lamports_h ) { return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; diff --git a/src/flamenco/runtime/program/fd_address_lookup_table_program.c b/src/flamenco/runtime/program/fd_address_lookup_table_program.c index ff8222d8ce..6dc042a0d5 100644 --- a/src/flamenco/runtime/program/fd_address_lookup_table_program.c +++ b/src/flamenco/runtime/program/fd_address_lookup_table_program.c @@ -211,7 +211,7 @@ create_lookup_table( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L60-L62 */ lut_lamports = fd_borrowed_account_get_lamports( &lut_acct ); - lut_key = lut_acct.acct->pubkey; + lut_key = lut_acct.pubkey; lut_owner = fd_borrowed_account_get_owner( &lut_acct ); /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L63-L70 */ @@ -232,7 +232,7 @@ create_lookup_table( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L75 */ - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L76-L83 */ if( !FD_FEATURE_ACTIVE_BANK( ctx->bank, relax_authority_signer_check_for_lookup_table_creation ) @@ -250,7 +250,7 @@ create_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t payer_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_PAYER, &payer_acct ); - payer_key = payer_acct.acct->pubkey; + payer_key = payer_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L89-L92 */ if( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_PAYER, NULL ) ) { @@ -494,7 +494,7 @@ freeze_lookup_table( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L186-L189 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { @@ -585,7 +585,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t lut_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct ); - lut_key = lut_acct.acct->pubkey; + lut_key = lut_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L233-235 */ if( FD_UNLIKELY( 0!=memcmp( fd_borrowed_account_get_owner( &lut_acct ), fd_solana_address_lookup_table_program_id.key, sizeof(fd_pubkey_t) ) ) ) @@ -602,7 +602,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L241-L244 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { @@ -697,7 +697,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( err ) ) { return err; } - fd_txn_account_resize( lut_acct.acct, new_table_data_sz ); + fd_account_meta_resize( lut_acct.meta, new_table_data_sz ); /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L307-L310 */ err = fd_addrlut_serialize_meta( &lut->state, lut_data_mut, lut_data_mut_len ); @@ -732,7 +732,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t payer_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_PAYER, &payer_acct ); - payer_key = payer_acct.acct->pubkey; + payer_key = payer_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L327-L330 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_PAYER, NULL ) ) ) { fd_log_collector_msg_literal( ctx, "Payer account must be a signer" ); @@ -822,7 +822,7 @@ deactivate_lookup_table( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L356-L359 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { @@ -930,7 +930,7 @@ close_lookup_table( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L405-L408 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index 115b87555c..41b3c3e181 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -262,14 +262,14 @@ write_program_data( fd_exec_instr_ctx_t * instr_ctx, } int -fd_bpf_loader_program_get_state( fd_txn_account_t const * acct, +fd_bpf_loader_program_get_state( fd_account_meta_t const * meta, fd_bpf_upgradeable_loader_state_t * state ) { int err = 0; fd_bincode_decode_static( bpf_upgradeable_loader_state, state, - fd_txn_account_get_data( acct ), - fd_txn_account_get_data_len( acct ), + fd_account_data( meta ), + meta->dlen, &err ); if( FD_UNLIKELY( err ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; @@ -655,7 +655,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1379-L1381 */ fd_guarded_borrowed_account_t programdata_account = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, PROGRAM_DATA_ACCOUNT_INDEX, &programdata_account ); - fd_pubkey_t * programdata_key = programdata_account.acct->pubkey; + fd_pubkey_t const * programdata_key = programdata_account.pubkey; /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1383-L1386 */ if( FD_UNLIKELY( memcmp( program_id, fd_borrowed_account_get_owner( &programdata_account ), sizeof(fd_pubkey_t) ) ) ) { @@ -687,7 +687,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1403-L1419 */ fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program_account.acct, program_state ); + err = fd_bpf_loader_program_get_state( program_account.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -725,7 +725,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1439-L1478 */ fd_pubkey_t * upgrade_authority_address = NULL; fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state( programdata_account.acct, programdata_state ); + err = fd_bpf_loader_program_get_state( programdata_account.meta, programdata_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -857,7 +857,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, ulong programdata_size = new_len - PROGRAMDATA_METADATA_SIZE; /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1512-L1522 */ - err = fd_deploy_program( instr_ctx, program_account.acct->pubkey, programdata_data, programdata_size ); + err = fd_deploy_program( instr_ctx, program_account.pubkey, programdata_data, programdata_size ); if( FD_UNLIKELY( err ) ) { return err; } @@ -933,7 +933,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, buffer_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -974,7 +974,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &buffer ); fd_bpf_upgradeable_loader_state_t loader_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, loader_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1074,15 +1074,15 @@ 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#L542-L560 */ /* Verify Program account */ - fd_pubkey_t * new_program_id = NULL; - fd_rent_t const * rent = fd_bank_rent_query( instr_ctx->bank ); + fd_pubkey_t const * new_program_id = NULL; + fd_rent_t const * rent = fd_bank_rent_query( instr_ctx->bank ); /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L545 */ fd_guarded_borrowed_account_t program = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 2UL, &program ); fd_bpf_upgradeable_loader_state_t loader_state[1]; - int err = fd_bpf_loader_program_get_state( program.acct, loader_state ); + int err = fd_bpf_loader_program_get_state( program.meta, loader_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -1099,7 +1099,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "Program account not rent-exempt" ); return FD_EXECUTOR_INSTR_ERR_EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT; } - new_program_id = program.acct->pubkey; + new_program_id = program.pubkey; /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L560 */ fd_borrowed_account_drop( &program ); @@ -1107,17 +1107,17 @@ 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#L561-L600 */ /* Verify Buffer account */ - fd_pubkey_t * buffer_key = NULL; - ulong buffer_data_offset = 0UL; - ulong buffer_data_len = 0UL; - ulong programdata_len = 0UL; + fd_pubkey_t const* buffer_key = NULL; + ulong buffer_data_offset = 0UL; + ulong buffer_data_len = 0UL; + ulong programdata_len = 0UL; /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L564-L565 */ fd_guarded_borrowed_account_t buffer = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 3UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, buffer_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1138,7 +1138,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "Invalid Buffer account" ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } - buffer_key = buffer.acct->pubkey; + buffer_key = buffer.pubkey; buffer_data_offset = BUFFER_METADATA_SIZE; buffer_data_len = fd_ulong_sat_sub( fd_borrowed_account_get_data_len( &buffer ), buffer_data_offset ); /* UpgradeableLoaderState::size_of_program_data( max_data_len ) */ @@ -1272,7 +1272,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { const uchar * buffer_data = fd_borrowed_account_get_data( &buffer ) + buffer_data_offset; - err = fd_deploy_program( instr_ctx, program.acct->pubkey, buffer_data, buffer_data_len ); + err = fd_deploy_program( instr_ctx, program.pubkey, buffer_data, buffer_data_len ); if( FD_UNLIKELY( err ) ) { return err; } @@ -1355,7 +1355,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return err; } - FD_LOG_INFO(( "Program deployed %s", FD_BASE58_ENC_32_ALLOCA( program.acct->pubkey ) )); + FD_LOG_INFO(( "Program deployed %s", FD_BASE58_ENC_32_ALLOCA( program.pubkey ) )); /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L700 */ fd_borrowed_account_drop( &program ); @@ -1419,7 +1419,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; } fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program.acct, program_state ); + err = fd_bpf_loader_program_get_state( program.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1448,7 +1448,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 2UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, buffer_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1503,7 +1503,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state( programdata.acct, programdata_state ); + err = fd_bpf_loader_program_get_state( programdata.meta, programdata_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1552,7 +1552,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } const uchar * buffer_data = fd_borrowed_account_get_data( &buffer ) + buffer_data_offset; - err = fd_deploy_program( instr_ctx, program.acct->pubkey, buffer_data, buffer_data_len ); + err = fd_deploy_program( instr_ctx, program.pubkey, buffer_data, buffer_data_len ); if( FD_UNLIKELY( err ) ) { return err; } @@ -1670,7 +1670,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_exec_instr_ctx_get_key_of_account_at_index( instr_ctx, 2UL, &new_authority ); fd_bpf_upgradeable_loader_state_t account_state[1]; - err = fd_bpf_loader_program_get_state( account.acct, account_state ); + err = fd_bpf_loader_program_get_state( account.meta, account_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -1775,7 +1775,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { if( FD_UNLIKELY( err ) ) return err; fd_bpf_upgradeable_loader_state_t account_state[1]; - err = fd_bpf_loader_program_get_state( account.acct, account_state ); + err = fd_bpf_loader_program_get_state( account.meta, account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1871,9 +1871,9 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_guarded_borrowed_account_t close_account = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &close_account ); - fd_pubkey_t * close_key = close_account.acct->pubkey; + fd_pubkey_t const * close_key = close_account.pubkey; fd_bpf_upgradeable_loader_state_t close_account_state[1]; - err = fd_bpf_loader_program_get_state( close_account.acct, close_account_state ); + err = fd_bpf_loader_program_get_state( close_account.meta, close_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1956,7 +1956,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program_account.acct, program_state ); + err = fd_bpf_loader_program_get_state( program_account.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -2084,7 +2084,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { ulong program_len = 0UL; fd_pubkey_t * upgrade_authority_address = NULL; fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state( programdata.acct, programdata_state ); + err = fd_bpf_loader_program_get_state( programdata.meta, programdata_state ); if( FD_LIKELY( err==FD_EXECUTOR_INSTR_SUCCESS && fd_bpf_upgradeable_loader_state_is_program_data( programdata_state ) ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1374-L1377 */ @@ -2139,7 +2139,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#L1415-L1426 */ fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program.acct, program_state ); + err = fd_bpf_loader_program_get_state( program.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -2488,7 +2488,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { if( !memcmp( metadata->owner, &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_pubkey_t) ) ) { fd_bpf_upgradeable_loader_state_t program_account_state[1]; - err = fd_bpf_loader_program_get_state( program_account.acct, program_account_state ); + err = fd_bpf_loader_program_get_state( program_account.meta, program_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { @@ -2515,14 +2515,13 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } - fd_txn_account_t * program_data_account = NULL; - fd_pubkey_t * programdata_pubkey = (fd_pubkey_t *)&program_account_state->inner.program.programdata_address; + fd_account_meta_t const * programdata_meta = NULL; + fd_pubkey_t * programdata_pubkey = (fd_pubkey_t *)&program_account_state->inner.program.programdata_address; err = fd_runtime_get_executable_account( ctx->runtime, ctx->txn_in, ctx->txn_out, programdata_pubkey, - &program_data_account, - fd_runtime_account_check_exists ); + &programdata_meta ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { @@ -2531,7 +2530,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } - if( FD_UNLIKELY( fd_txn_account_get_data_len( program_data_account )dlenbank, remove_accounts_executable_flag_checks ) ) { return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_PROGRAM_ID; @@ -2540,7 +2539,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { } fd_bpf_upgradeable_loader_state_t program_data_account_state[1]; - err = fd_bpf_loader_program_get_state( program_data_account, program_data_account_state ); + err = fd_bpf_loader_program_get_state( programdata_meta, program_data_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.h b/src/flamenco/runtime/program/fd_bpf_loader_program.h index 817a93d722..107ef3a48f 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.h +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.h @@ -56,13 +56,10 @@ FD_PROTOTYPES_BEGIN /* Mirrors solana_sdk::transaction_context::BorrowedAccount::get_state() - - Acts on a fd_txn_account_t for ease of API use. - https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L965-L969 */ int -fd_bpf_loader_program_get_state( fd_txn_account_t const * acct, +fd_bpf_loader_program_get_state( fd_account_meta_t const * meta, fd_bpf_upgradeable_loader_state_t * state ); int @@ -92,6 +89,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * instr_ctx ); documentation for our `fd_deploy_program` for more information. https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L155-L233 */ + int fd_directly_invoke_loader_v3_deploy( fd_bank_t * bank, fd_funk_t * funk, diff --git a/src/flamenco/runtime/program/fd_bpf_loader_serialization.c b/src/flamenco/runtime/program/fd_bpf_loader_serialization.c index 8a0c0076ed..238252dd3f 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_serialization.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_serialization.c @@ -162,7 +162,7 @@ write_account( fd_borrowed_account_t * account, ulong dlen = account ? fd_borrowed_account_get_data_len( account ) : 0UL; acc_region_metas[instr_acc_idx].original_data_len = dlen; - acc_region_metas[instr_acc_idx].acct = account->acct; + acc_region_metas[instr_acc_idx].meta = account->meta; /* Legacy behavior: no stricter_abi_and_runtime_constraints (also implies no direct mapping) https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L131-L140 */ @@ -263,7 +263,7 @@ fd_bpf_loader_input_serialize_aligned( fd_exec_instr_ctx_t * ctx, fd_vm_acc_region_meta_t * acc_region_metas, int stricter_abi_and_runtime_constraints, int direct_mapping ) { - fd_pubkey_t * txn_accs = ctx->txn_out->accounts.account_keys; + fd_pubkey_t * txn_accs = ctx->txn_out->accounts.keys; uchar acc_idx_seen[ FD_INSTR_ACCT_MAX ] = {0}; ushort dup_acc_idx[ FD_INSTR_ACCT_MAX ] = {0}; @@ -539,7 +539,7 @@ fd_bpf_loader_input_serialize_unaligned( fd_exec_instr_ctx_t * ctx, fd_vm_acc_region_meta_t * acc_region_metas, int stricter_abi_and_runtime_constraints, int direct_mapping ) { - fd_pubkey_t const * txn_accs = ctx->txn_out->accounts.account_keys; + fd_pubkey_t const * txn_accs = ctx->txn_out->accounts.keys; uchar acc_idx_seen[FD_INSTR_ACCT_MAX] = {0}; ushort dup_acc_idx[FD_INSTR_ACCT_MAX] = {0}; diff --git a/src/flamenco/runtime/program/fd_builtin_programs.c b/src/flamenco/runtime/program/fd_builtin_programs.c index b2813aff5c..a00fed3f33 100644 --- a/src/flamenco/runtime/program/fd_builtin_programs.c +++ b/src/flamenco/runtime/program/fd_builtin_programs.c @@ -229,7 +229,7 @@ fd_write_builtin_account( fd_bank_t * bank, fd_txn_account_set_executable( rec, 1 ); fd_txn_account_set_owner( rec, &fd_solana_native_loader_id ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); diff --git a/src/flamenco/runtime/program/fd_config_program.c b/src/flamenco/runtime/program/fd_config_program.c index 090527e1ed..31ba1d5c3b 100644 --- a/src/flamenco/runtime/program/fd_config_program.c +++ b/src/flamenco/runtime/program/fd_config_program.c @@ -57,7 +57,7 @@ _process_config_instr( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t config_acc_rec = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_CONFIG, &config_acc_rec ); - config_account_key = config_acc_rec.acct->pubkey; + config_account_key = config_acc_rec.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.17/programs/config/src/config_processor.rs#L27 */ @@ -148,7 +148,7 @@ _process_config_instr( fd_exec_instr_ctx_t * ctx ) { /* https://github.com/solana-labs/solana/blob/v1.17.17/programs/config/src/config_processor.rs#L80-L87 */ - if( FD_UNLIKELY( 0!=memcmp( signer_account.acct->pubkey, signer, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( 0!=memcmp( signer_account.pubkey, signer, sizeof(fd_pubkey_t) ) ) ) { /* Max msg_sz: 53 - 3 + 20 = 70 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, "account[%lu].signer_key() does not match Config data)", counter+1 ); diff --git a/src/flamenco/runtime/program/fd_loader_v4_program.c b/src/flamenco/runtime/program/fd_loader_v4_program.c index 314a486898..2052f859aa 100644 --- a/src/flamenco/runtime/program/fd_loader_v4_program.c +++ b/src/flamenco/runtime/program/fd_loader_v4_program.c @@ -62,17 +62,17 @@ fd_loader_v4_get_state_mut( uchar * data, https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L32-L44 */ fd_loader_v4_state_t const * -fd_loader_v4_get_state( fd_txn_account_t const * program, - int * err ) { +fd_loader_v4_get_state( fd_account_meta_t const * meta, + int * err ) { *err = FD_EXECUTOR_INSTR_SUCCESS; /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L35-L36 */ - if( FD_UNLIKELY( fd_txn_account_get_data_len( program )dlenacct, err ); + fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program->meta, err ); if( FD_UNLIKELY( *err ) ) { return NULL; } @@ -528,7 +528,7 @@ fd_loader_v4_program_instruction_deploy( fd_exec_instr_ctx_t * instr_ctx ) { invoked until the next slot anyways, doing this is okay. https://github.com/anza-xyz/agave/blob/v2.2.13/programs/loader-v4/src/lib.rs#L309-L316 */ - err = fd_deploy_program( instr_ctx, program.acct->pubkey, programdata, buffer_dlen - LOADER_V4_PROGRAM_DATA_OFFSET ); + err = fd_deploy_program( instr_ctx, program.pubkey, programdata, buffer_dlen - LOADER_V4_PROGRAM_DATA_OFFSET ); if( FD_UNLIKELY( err ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -752,7 +752,7 @@ fd_loader_v4_program_instruction_finalize( fd_exec_instr_ctx_t * instr_ctx ) { } /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L454 */ - fd_loader_v4_state_t const * state_of_next_version = fd_loader_v4_get_state( next_version.acct, &err ); + fd_loader_v4_state_t const * state_of_next_version = fd_loader_v4_get_state( next_version.meta, &err ); if( FD_UNLIKELY( err ) ) { return err; } @@ -770,7 +770,7 @@ fd_loader_v4_program_instruction_finalize( fd_exec_instr_ctx_t * instr_ctx ) { } /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L463 */ - fd_pubkey_t * address_of_next_version = next_version.acct->pubkey; + fd_pubkey_t const * address_of_next_version = next_version.pubkey; /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L464 */ fd_borrowed_account_drop( &next_version ); @@ -890,7 +890,7 @@ fd_loader_v4_program_execute( fd_exec_instr_ctx_t * instr_ctx ) { Therefore, Firedancer recovers the DelayVisibility and Closed states on-the-fly before querying cahce. */ - fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program.acct, &rc ); + fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program.meta, &rc ); if( FD_UNLIKELY( rc ) ) { fd_log_collector_msg_literal( instr_ctx, "Program is not deployed" ); return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_PROGRAM_ID; diff --git a/src/flamenco/runtime/program/fd_loader_v4_program.h b/src/flamenco/runtime/program/fd_loader_v4_program.h index beac9cee52..f80a6bc19c 100644 --- a/src/flamenco/runtime/program/fd_loader_v4_program.h +++ b/src/flamenco/runtime/program/fd_loader_v4_program.h @@ -69,8 +69,8 @@ FD_FN_PURE uchar fd_loader_v4_status_is_finalized( fd_loader_v4_state_t const * state ); fd_loader_v4_state_t const * -fd_loader_v4_get_state( fd_txn_account_t const * program, - int * err ); +fd_loader_v4_get_state( fd_account_meta_t const * meta, + int * err ); int fd_loader_v4_program_execute( fd_exec_instr_ctx_t * instr_ctx ); diff --git a/src/flamenco/runtime/program/fd_stake_program.c b/src/flamenco/runtime/program/fd_stake_program.c index 5c9c9e7dc0..0770da27d4 100644 --- a/src/flamenco/runtime/program/fd_stake_program.c +++ b/src/flamenco/runtime/program/fd_stake_program.c @@ -142,13 +142,13 @@ typedef struct effective_activating effective_activating_t; /**********************************************************************/ static int -get_state( fd_txn_account_t const * self, - fd_stake_state_v2_t * out ) { +get_state( fd_account_meta_t const * meta, + fd_stake_state_v2_t * out ) { int rc; fd_bincode_decode_ctx_t bincode_ctx = { - .data = fd_txn_account_get_data( self ), - .dataend = fd_txn_account_get_data( self ) + fd_txn_account_get_data_len( self ), + .data = fd_account_data( meta ), + .dataend = fd_account_data( meta ) + meta->dlen, }; ulong total_sz = 0UL; @@ -1277,7 +1277,7 @@ initialize( fd_borrowed_account_t * stake_account, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L224 fd_stake_state_v2_t stake_state = {0}; do { - int rc = get_state( stake_account->acct, &stake_state ); + int rc = get_state( stake_account->meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; } while(0); @@ -1318,7 +1318,7 @@ authorize( fd_borrowed_account_t * stake_account, int rc; fd_stake_state_v2_t stake_state = {0}; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L251 - rc = get_state( stake_account->acct, &stake_state ); + rc = get_state( stake_account->meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; switch( stake_state.discriminant ) { /* FIXME check if the compiler can optimize away branching (given the layout of `meta` in both @@ -1426,9 +1426,9 @@ delegate( fd_exec_instr_ctx_t const * ctx, if( FD_UNLIKELY( memcmp( fd_borrowed_account_get_owner( &vote_account ), fd_solana_vote_program_id.key, 32UL ) ) ) return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L3326 - vote_pubkey = vote_account.acct->pubkey; + vote_pubkey = vote_account.pubkey; // https://github.com/anza-xyz/agave/blob/a60fbc2288d626a4f1846052c8fcb98d3f9ea58d/programs/stake/src/stake_state.rs#L327 - vote_state = fd_vote_get_state( vote_account.acct, ctx->runtime->stake_program.delegate.vote_state_mem ); + vote_state = fd_vote_get_state( vote_account.meta, ctx->runtime->stake_program.delegate.vote_state_mem ); /* https://github.com/anza-xyz/agave/blob/v2.1.14/programs/stake/src/stake_state.rs#L328 */ fd_borrowed_account_drop( &vote_account ); @@ -1438,7 +1438,7 @@ delegate( fd_exec_instr_ctx_t const * ctx, fd_guarded_borrowed_account_t stake_account = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, stake_account_index, &stake_account ); - rc = get_state( stake_account.acct, &stake_state ); + rc = get_state( stake_account.meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L332 @@ -1533,7 +1533,7 @@ deactivate( fd_borrowed_account_t * stake_account, int rc; fd_stake_state_v2_t state = {0}; - rc = get_state( stake_account->acct, &state ); + rc = get_state( stake_account->meta, &state ); if( FD_UNLIKELY( rc ) ) return rc; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L370 @@ -1565,7 +1565,7 @@ set_lockup( fd_borrowed_account_t * stake_account, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L385 fd_stake_state_v2_t state = {0}; - rc = get_state( stake_account->acct, &state ); + rc = get_state( stake_account->meta, &state ); if( FD_UNLIKELY( rc ) ) return rc; switch( state.discriminant ) { @@ -1613,7 +1613,7 @@ split( fd_exec_instr_ctx_t const * ctx, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L415 fd_stake_state_v2_t split_get_state = {0}; - rc = get_state( split.acct, &split_get_state ); + rc = get_state( split.meta, &split_get_state ); if( FD_UNLIKELY( rc ) ) return rc; if( FD_UNLIKELY( split_get_state.discriminant!=fd_stake_state_v2_enum_uninitialized ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; @@ -1633,7 +1633,7 @@ split( fd_exec_instr_ctx_t const * ctx, if( FD_UNLIKELY( lamports>fd_borrowed_account_get_lamports( &stake_account ) ) ) return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS; - rc = get_state( stake_account.acct, &stake_state ); + rc = get_state( stake_account.meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; /* https://github.com/anza-xyz/agave/blob/v2.1.14/programs/stake/src/stake_state.rs#L426 */ @@ -1870,7 +1870,7 @@ merge( fd_exec_instr_ctx_t * ctx, // not const to log FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, stake_account_index, &stake_account ); fd_stake_state_v2_t stake_account_state = {0}; - rc = get_state( stake_account.acct, &stake_account_state ); + rc = get_state( stake_account.meta, &stake_account_state ); if( FD_UNLIKELY( rc ) ) return rc; merge_kind_t stake_merge_kind = {0}; @@ -1892,7 +1892,7 @@ merge( fd_exec_instr_ctx_t * ctx, // not const to log return rc; fd_stake_state_v2_t source_account_state = {0}; - rc = get_state( source_account.acct, &source_account_state ); + rc = get_state( source_account.meta, &source_account_state ); if( FD_UNLIKELY( rc ) ) return rc; merge_kind_t source_merge_kind = {0}; @@ -1971,7 +1971,7 @@ move_stake_or_lamports_shared_checks( fd_exec_instr_ctx_t * invoke_context, // return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L163 - if( FD_UNLIKELY( !memcmp( &source_account->acct->pubkey, &destination_account->acct->pubkey, sizeof(fd_pubkey_t) ) ) ) + if( FD_UNLIKELY( !memcmp( source_account->pubkey, destination_account->pubkey, sizeof(fd_pubkey_t) ) ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA; // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L168 @@ -1993,7 +1993,7 @@ move_stake_or_lamports_shared_checks( fd_exec_instr_ctx_t * invoke_context, // // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L182 fd_stake_state_v2_t source_account_state = {0}; - rc = get_state( source_account->acct, &source_account_state ); + rc = get_state( source_account->meta, &source_account_state ); if( FD_UNLIKELY( rc ) ) return rc; rc = get_if_mergeable( invoke_context, @@ -2011,7 +2011,7 @@ move_stake_or_lamports_shared_checks( fd_exec_instr_ctx_t * invoke_context, // // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L197 fd_stake_state_v2_t destination_account_state = {0}; - rc = get_state( destination_account->acct, &destination_account_state ); + rc = get_state( destination_account->meta, &destination_account_state ); if( FD_UNLIKELY( rc ) ) return rc; rc = get_if_mergeable( invoke_context, @@ -2283,7 +2283,7 @@ withdraw( fd_exec_instr_ctx_t const * ctx, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L821 fd_stake_state_v2_t stake_state = {0}; - rc = get_state( stake_account.acct, &stake_state ); + rc = get_state( stake_account.meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; fd_stake_lockup_t lockup; @@ -2334,7 +2334,7 @@ withdraw( fd_exec_instr_ctx_t const * ctx, } case fd_stake_state_v2_enum_uninitialized: { // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L846 - if( FD_UNLIKELY( !fd_signers_contains( signers, stake_account.acct->pubkey ) ) ) { + if( FD_UNLIKELY( !fd_signers_contains( signers, stake_account.pubkey ) ) ) { return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L850 @@ -2438,7 +2438,7 @@ deactivate_delinquent( fd_exec_instr_ctx_t * ctx, return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L920-L922 - fd_vote_state_versioned_t * delinquent_vote_state_versioned = fd_vote_get_state( delinquent_vote_account.acct, ctx->runtime->stake_program.deactivate_delinquent.delinquent_vote_state_mem ); + fd_vote_state_versioned_t * delinquent_vote_state_versioned = fd_vote_get_state( delinquent_vote_account.meta, ctx->runtime->stake_program.deactivate_delinquent.delinquent_vote_state_mem ); if( FD_UNLIKELY( !delinquent_vote_state_versioned ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; fd_vote_convert_to_current( delinquent_vote_state_versioned, ctx->runtime->stake_program.deactivate_delinquent.delinquent_authorized_voters_mem, @@ -2454,7 +2454,7 @@ deactivate_delinquent( fd_exec_instr_ctx_t * ctx, return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L929-L932 - fd_vote_state_versioned_t * reference_vote_state_versioned = fd_vote_get_state( reference_vote_account.acct, ctx->runtime->stake_program.deactivate_delinquent.reference_vote_state_mem ); + fd_vote_state_versioned_t * reference_vote_state_versioned = fd_vote_get_state( reference_vote_account.meta, ctx->runtime->stake_program.deactivate_delinquent.reference_vote_state_mem ); if( FD_UNLIKELY( !reference_vote_state_versioned ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; fd_vote_convert_to_current( reference_vote_state_versioned, ctx->runtime->stake_program.deactivate_delinquent.reference_authorized_voters_mem, @@ -2468,7 +2468,7 @@ deactivate_delinquent( fd_exec_instr_ctx_t * ctx, } fd_stake_state_v2_t stake_state = {0}; - rc = get_state( stake_account->acct, &stake_state ); + rc = get_state( stake_account->meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L937 if( FD_LIKELY( stake_state.discriminant==fd_stake_state_v2_enum_stake ) ) { @@ -3288,9 +3288,9 @@ fd_stake_program_config_init( fd_accdb_user_t * accdb, } int -fd_stake_get_state( fd_txn_account_t const * self, - fd_stake_state_v2_t * out ) { - return get_state( self, out ); +fd_stake_get_state( fd_account_meta_t const * meta, + fd_stake_state_v2_t * out ) { + return get_state( meta, out ); } fd_stake_history_entry_t diff --git a/src/flamenco/runtime/program/fd_stake_program.h b/src/flamenco/runtime/program/fd_stake_program.h index cf213e014e..d254ee3038 100644 --- a/src/flamenco/runtime/program/fd_stake_program.h +++ b/src/flamenco/runtime/program/fd_stake_program.h @@ -39,8 +39,8 @@ fd_stake_program_config_init( fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid ); int -fd_stake_get_state( fd_txn_account_t const * self, - fd_stake_state_v2_t * out ); +fd_stake_get_state( fd_account_meta_t const * meta, + fd_stake_state_v2_t * out ); fd_stake_history_entry_t fd_stake_activating_and_deactivating( fd_delegation_t const * self, diff --git a/src/flamenco/runtime/program/fd_system_program.c b/src/flamenco/runtime/program/fd_system_program.c index ea6b303c67..ca77c00c41 100644 --- a/src/flamenco/runtime/program/fd_system_program.c +++ b/src/flamenco/runtime/program/fd_system_program.c @@ -128,7 +128,7 @@ fd_system_program_transfer( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 37 - 2 + 45 = 80 < 127 => we can use printf */ ushort idx_in_txn = ctx->instr->accounts[ from_acct_idx ].index_in_transaction; fd_log_collector_printf_dangerous_max_127( ctx, - "Transfer: `from` account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.account_keys[ idx_in_txn ] ) ); + "Transfer: `from` account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.keys[ idx_in_txn ] ) ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } @@ -158,7 +158,7 @@ fd_system_program_allocate( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 35 - 2 + 125 = 158 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: 'to' (account %s, base %s) must sign", - FD_BASE58_ENC_32_ALLOCA( &account->acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &account->pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } @@ -170,7 +170,7 @@ fd_system_program_allocate( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 35 - 2 + 125 = 158 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: account (account %s, base %s) already in use", - FD_BASE58_ENC_32_ALLOCA( &account->acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &account->pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); ctx->txn_out->err.custom_err = FD_SYSTEM_PROGRAM_ERR_ACCT_ALREADY_IN_USE; return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR; @@ -220,7 +220,7 @@ fd_system_program_assign( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 28 - 2 + 125 = 151 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: 'to' (account %s, base %s) must sign", - FD_BASE58_ENC_32_ALLOCA( &account->acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &account->pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } @@ -279,7 +279,7 @@ fd_system_program_create_account( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 41 - 2 + 125 = 164 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: 'to' (account %s, base %s) already in use", - FD_BASE58_ENC_32_ALLOCA( &to.acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &to.pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); ctx->txn_out->err.custom_err = FD_SYSTEM_PROGRAM_ERR_ACCT_ALREADY_IN_USE; return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR; @@ -358,7 +358,7 @@ fd_system_program_exec_assign( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L392 */ - err = fd_system_program_assign( ctx, &account, owner, account.acct->pubkey, NULL ); + err = fd_system_program_assign( ctx, &account, owner, account.pubkey, NULL ); if( FD_UNLIKELY( err ) ) return err; /* Implicit drop */ @@ -453,7 +453,7 @@ fd_system_program_exec_allocate( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L515 Authorization check is lifted out from 'allocate' to here. */ - err = fd_system_program_allocate( ctx, &account, space, account.acct->pubkey, NULL ); + err = fd_system_program_allocate( ctx, &account, space, account.pubkey, NULL ); if( FD_UNLIKELY( err ) ) return err; /* Implicit drop */ @@ -484,7 +484,7 @@ fd_system_program_exec_allocate_with_seed( fd_exec_instr_ctx_t * err = verify_seed_address( ctx, - account.acct->pubkey, + account.pubkey, &args->base, (char const *)args->seed, args->seed_len, @@ -531,7 +531,7 @@ fd_system_program_exec_assign_with_seed( fd_exec_instr_ctx_t * err = verify_seed_address( ctx, - account.acct->pubkey, + account.pubkey, &args->base, (char const *)args->seed, args->seed_len, @@ -576,7 +576,7 @@ fd_system_program_exec_transfer_with_seed( fd_exec_instr_ctx_t * /* Max msg_sz: 37 - 2 + 45 = 80 < 127 => we can use printf */ ushort idx_in_txn = ctx->instr->accounts[ from_base_idx ].index_in_transaction; fd_log_collector_printf_dangerous_max_127( ctx, - "Transfer: 'from' account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.account_keys[ idx_in_txn ] ) ); + "Transfer: 'from' account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.keys[ idx_in_txn ] ) ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } @@ -724,19 +724,19 @@ fd_system_program_execute( fd_exec_instr_ctx_t * ctx ) { /**********************************************************************/ int -fd_get_system_account_kind( fd_txn_account_t * account ) { +fd_get_system_account_kind( fd_account_meta_t const * meta ) { /* https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L56 */ - if( FD_UNLIKELY( memcmp( fd_txn_account_get_owner( account ), fd_solana_system_program_id.uc, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( memcmp( meta->owner, fd_solana_system_program_id.uc, sizeof(fd_pubkey_t) ) ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN; } /* https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L57-L58 */ - if( FD_LIKELY( !fd_txn_account_get_data_len( account ) ) ) { + if( FD_LIKELY( !meta->dlen ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_SYSTEM; } /* https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L59 */ - if( FD_UNLIKELY( fd_txn_account_get_data_len( account )!=FD_SYSTEM_PROGRAM_NONCE_DLEN ) ) { + if( FD_UNLIKELY( meta->dlen!=FD_SYSTEM_PROGRAM_NONCE_DLEN ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN; } @@ -744,8 +744,8 @@ fd_get_system_account_kind( fd_txn_account_t * account ) { fd_nonce_state_versions_t versions[1]; if( FD_UNLIKELY( !fd_bincode_decode_static( nonce_state_versions, versions, - fd_txn_account_get_data( account ), - fd_txn_account_get_data_len( account ), + fd_account_data( meta ), + meta->dlen, NULL ) ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN; } diff --git a/src/flamenco/runtime/program/fd_system_program.h b/src/flamenco/runtime/program/fd_system_program.h index 54a8f88d32..b88b24c4c6 100644 --- a/src/flamenco/runtime/program/fd_system_program.h +++ b/src/flamenco/runtime/program/fd_system_program.h @@ -68,7 +68,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L55-L71 */ int -fd_get_system_account_kind( fd_txn_account_t * account ); +fd_get_system_account_kind( fd_account_meta_t const * meta ); FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/program/fd_system_program_nonce.c b/src/flamenco/runtime/program/fd_system_program_nonce.c index 54fba071fe..18d47f082a 100644 --- a/src/flamenco/runtime/program/fd_system_program_nonce.c +++ b/src/flamenco/runtime/program/fd_system_program_nonce.c @@ -135,7 +135,7 @@ fd_system_program_advance_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_instr_acc_is_writable_idx( ctx->instr, instr_acc_idx ) ) ) { /* Max msg_sz: 50 - 2 + 45 = 93 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Advance nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey) ); + "Advance nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->pubkey) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -226,7 +226,7 @@ fd_system_program_advance_nonce_account( fd_exec_instr_ctx_t * ctx, case fd_nonce_state_enum_uninitialized: { /* Max msg_sz: 50 - 2 + 45 = 93 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Advance nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Advance nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -305,7 +305,7 @@ fd_system_program_withdraw_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_instr_acc_is_writable_idx( ctx->instr, from_acct_idx ) ) ) { /* Max msg_sz: 51 - 2 + 45 = 94 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Withdraw nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( from.acct->pubkey ) ); + "Withdraw nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( from.pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -349,7 +349,7 @@ fd_system_program_withdraw_nonce_account( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.23/programs/system/src/system_instruction.rs#L105 */ - *signer = *from.acct->pubkey; + *signer = *from.pubkey; break; } @@ -506,7 +506,7 @@ fd_system_program_initialize_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_borrowed_account_is_writable( account ) ) ) { /* Max msg_sz: 53 - 2 + 45 = 96 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Initialize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Initialize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -593,7 +593,7 @@ fd_system_program_initialize_nonce_account( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 53 - 2 + 45 = 96 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Initialize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Initialize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -677,7 +677,7 @@ fd_system_program_authorize_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_instr_acc_is_writable_idx( ctx->instr, instr_acc_idx ) ) ) { /* Max msg_sz: 52 - 2 + 45 = 95 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Authorize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Authorize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -716,7 +716,7 @@ fd_system_program_authorize_nonce_account( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 52 - 2 + 45 = 95 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Authorize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Authorize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -949,7 +949,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, fd_txn_account_t durable_nonce_rec[1]; fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; int err = fd_txn_account_init_from_funk_readonly( durable_nonce_rec, - &txn_out->accounts.account_keys[ nonce_idx ], + &txn_out->accounts.keys[ nonce_idx ], runtime->funk, &xid ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { @@ -993,7 +993,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, the nonce instruction are signers. This is a successful exit case. */ for( ushort i=0; iacct_cnt; ++i ) { if( fd_txn_is_signer( TXN( txn_in->txn ), (int)instr_accts[i] ) ) { - if( !memcmp( &txn_out->accounts.account_keys[ instr_accts[i] ], &state->inner.current.inner.initialized.authority, sizeof(fd_pubkey_t) ) ) { + if( !memcmp( &txn_out->accounts.keys[ instr_accts[i] ], &state->inner.current.inner.initialized.authority, sizeof(fd_pubkey_t) ) ) { /* Mark nonce account to make sure that we modify and hash the account even if the transaction failed to execute @@ -1007,7 +1007,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( runtime->funk, &xid, - &txn_out->accounts.account_keys[ instr_accts[ 0UL ] ], + &txn_out->accounts.keys[ instr_accts[ 0UL ] ], NULL, &err, NULL ); @@ -1044,21 +1044,15 @@ fd_check_transaction_age( fd_runtime_t * runtime, } fd_memcpy( borrowed_account_data, meta, sizeof(fd_account_meta_t)+acc_data_len ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( - txn_out->accounts.rollback_nonce, - &txn_out->accounts.account_keys[ instr_accts[ 0UL ] ], - (fd_account_meta_t *)borrowed_account_data, - 1 ) ) ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } + txn_out->accounts.rollback_nonce = (fd_account_meta_t *)borrowed_account_data; - if( FD_UNLIKELY( fd_nonce_state_versions_size( &new_state )>fd_txn_account_get_data_len( txn_out->accounts.rollback_nonce ) ) ) { + if( FD_UNLIKELY( fd_nonce_state_versions_size( &new_state )>txn_out->accounts.rollback_nonce->dlen ) ) { return FD_RUNTIME_TXN_ERR_BLOCKHASH_FAIL_ADVANCE_NONCE_INSTR; } do { fd_bincode_encode_ctx_t encode_ctx = - { .data = fd_txn_account_get_data_mut( txn_out->accounts.rollback_nonce ), - .dataend = fd_txn_account_get_data_mut( txn_out->accounts.rollback_nonce ) + fd_txn_account_get_data_len( txn_out->accounts.rollback_nonce ) }; + { .data = fd_account_data( txn_out->accounts.rollback_nonce ), + .dataend = fd_account_data( txn_out->accounts.rollback_nonce ) + txn_out->accounts.rollback_nonce->dlen }; int err = fd_nonce_state_versions_encode( &new_state, &encode_ctx ); if( FD_UNLIKELY( err ) ) { return FD_RUNTIME_TXN_ERR_BLOCKHASH_FAIL_ADVANCE_NONCE_INSTR; diff --git a/src/flamenco/runtime/program/fd_vote_program.c b/src/flamenco/runtime/program/fd_vote_program.c index 2ff36f0a80..e117c82772 100644 --- a/src/flamenco/runtime/program/fd_vote_program.c +++ b/src/flamenco/runtime/program/fd_vote_program.c @@ -145,12 +145,12 @@ from_vote_state_1_14_11( fd_vote_state_t * vote_state, /* https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1074 */ static int -get_state( fd_txn_account_t const * self, - uchar * res ) { +get_state( fd_account_meta_t const * meta, + uchar * res ) { fd_bincode_decode_ctx_t decode = { - .data = fd_txn_account_get_data( self ), - .dataend = fd_txn_account_get_data( self ) + fd_txn_account_get_data_len( self ), + .data = fd_account_data( meta ), + .dataend = fd_account_data( meta ) + meta->dlen, }; ulong total_sz = 0UL; @@ -1462,7 +1462,7 @@ authorize( fd_borrowed_account_t * vote_account, // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L857 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.authorize.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.authorize.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.authorize.vote_state_mem; @@ -1525,7 +1525,7 @@ update_validator_identity( fd_borrowed_account_t * vote_account, int rc = 0; // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L900 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.update_validator_identity.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.update_validator_identity.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.update_validator_identity.vote_state_mem; convert_to_current( vote_state_versioned, @@ -1577,7 +1577,7 @@ update_commission( fd_borrowed_account_t * vote_account, // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L927 int enforce_commission_update_rule = 1; - rc = get_state( vote_account->acct, ctx->runtime->vote_program.update_commission.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.update_commission.vote_state_mem ); if( FD_LIKELY( rc==FD_EXECUTOR_INSTR_SUCCESS ) ) { vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.update_commission.vote_state_mem; convert_to_current( vote_state_versioned, @@ -1597,7 +1597,7 @@ update_commission( fd_borrowed_account_t * vote_account, // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L949 if( !vote_state ) { - rc = get_state( vote_account->acct, ctx->runtime->vote_program.update_commission.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.update_commission.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.update_commission.vote_state_mem; convert_to_current( vote_state_versioned, @@ -1629,7 +1629,7 @@ withdraw( fd_exec_instr_ctx_t const * ctx, int rc = 0; // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1010 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.withdraw.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.withdraw.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.withdraw.vote_state_mem; @@ -1804,7 +1804,7 @@ initialize_account( fd_borrowed_account_t * vote_account, } // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1074 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.init_account.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.init_account.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.init_account.vote_state_mem; @@ -1849,7 +1849,7 @@ verify_and_get_vote_state( fd_borrowed_account_t * vote_account, int rc = 0; // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1091 - rc = get_state( vote_account->acct, vote_state_mem ); + rc = get_state( vote_account->meta, vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * versioned = (fd_vote_state_versioned_t *)vote_state_mem; @@ -2721,30 +2721,30 @@ fd_vote_program_execute( fd_exec_instr_ctx_t * ctx ) { /**********************************************************************/ uint -fd_vote_state_versions_is_correct_and_initialized( fd_txn_account_t * vote_account ) { +fd_vote_state_versions_is_correct_and_initialized( fd_account_meta_t const * meta ) { // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L885 - uint data_len_check = fd_txn_account_get_data_len( vote_account )==FD_VOTE_STATE_V3_SZ; + uint data_len_check = meta->dlen==FD_VOTE_STATE_V3_SZ; uchar test_data[DEFAULT_PRIOR_VOTERS_OFFSET] = {0}; uint data_check = memcmp(( - fd_txn_account_get_data( vote_account )+VERSION_OFFSET), test_data, DEFAULT_PRIOR_VOTERS_OFFSET)!=0; + fd_account_data( meta )+VERSION_OFFSET), test_data, DEFAULT_PRIOR_VOTERS_OFFSET)!=0; if (data_check && data_len_check) { return 1; } // VoteState1_14_11::is_correct_size_and_initialized // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/vote_state_1_14_11.rs#L58 - data_len_check = fd_txn_account_get_data_len( vote_account )==FD_VOTE_STATE_V2_SZ; + data_len_check = meta->dlen==FD_VOTE_STATE_V2_SZ; uchar test_data_1_14_11[DEFAULT_PRIOR_VOTERS_OFFSET_1_14_11] = {0}; data_check = memcmp( ( - fd_txn_account_get_data( vote_account )+VERSION_OFFSET), test_data_1_14_11, DEFAULT_PRIOR_VOTERS_OFFSET_1_14_11)!=0; + fd_account_data( meta )+VERSION_OFFSET), test_data_1_14_11, DEFAULT_PRIOR_VOTERS_OFFSET_1_14_11)!=0; return data_check && data_len_check; } fd_vote_state_versioned_t * -fd_vote_get_state( fd_txn_account_t const * self, - uchar * mem /* out */ ) { +fd_vote_get_state( fd_account_meta_t const * meta, + uchar * mem /* out */ ) { - int err = get_state( self, mem ); + int err = get_state( meta, mem ); return err ? NULL : (fd_vote_state_versioned_t *)mem; } @@ -2754,28 +2754,3 @@ fd_vote_convert_to_current( fd_vote_state_versioned_t * self, uchar * landed_votes_mem ) { convert_to_current( self, authorized_voters_mem, landed_votes_mem ); } - -void -fd_vote_store_account( fd_txn_account_t * vote_account, - fd_bank_t * bank ) { - - fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); - - if( fd_txn_account_get_lamports( vote_account )==0UL ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); - fd_bank_vote_states_end_locking_modify( bank ); - return; - } - - if( !fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); - fd_bank_vote_states_end_locking_modify( bank ); - return; - } - - fd_vote_states_update_from_account( vote_states, - vote_account->pubkey, - fd_txn_account_get_data( vote_account ), - fd_txn_account_get_data_len( vote_account ) ); - fd_bank_vote_states_end_locking_modify( bank ); -} diff --git a/src/flamenco/runtime/program/fd_vote_program.h b/src/flamenco/runtime/program/fd_vote_program.h index a8d5a618d3..f062ddc8ac 100644 --- a/src/flamenco/runtime/program/fd_vote_program.h +++ b/src/flamenco/runtime/program/fd_vote_program.h @@ -48,25 +48,21 @@ fd_vote_program_execute( fd_exec_instr_ctx_t * ctx ); /* https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/vote_state_versions.rs#L90 */ uint -fd_vote_state_versions_is_correct_and_initialized( fd_txn_account_t * vote_account ); +fd_vote_state_versions_is_correct_and_initialized( fd_account_meta_t const * meta ); /* An implementation of solana_sdk::transaction_context::BorrowedAccount::get_state for setting the vote state. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L965 */ fd_vote_state_versioned_t * -fd_vote_get_state( fd_txn_account_t const * self, - uchar * mem ); +fd_vote_get_state( fd_account_meta_t const * meta, + uchar * mem ); void fd_vote_convert_to_current( fd_vote_state_versioned_t * self, uchar * authorized_voters_mem, uchar * landed_votes_mem ); -void -fd_vote_store_account( fd_txn_account_t * vote_account, - fd_bank_t * bank ); - FD_PROTOTYPES_END #endif /* HEADER_fd_src_flamenco_runtime_program_fd_vote_program_h */ diff --git a/src/flamenco/runtime/program/zksdk/fd_zksdk.c b/src/flamenco/runtime/program/zksdk/fd_zksdk.c index cb7bbfa62c..e327e35305 100644 --- a/src/flamenco/runtime/program/zksdk/fd_zksdk.c +++ b/src/flamenco/runtime/program/zksdk/fd_zksdk.c @@ -26,7 +26,7 @@ fd_zksdk_process_close_context_state( fd_exec_instr_ctx_t * ctx ) { } FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_OWNER, &owner_acc ); - *owner_pubkey = *owner_acc.acct->pubkey; + *owner_pubkey = *owner_acc.pubkey; /* implicit drop of borrowed owner_acc */ } while (0); @@ -37,13 +37,13 @@ fd_zksdk_process_close_context_state( fd_exec_instr_ctx_t * ctx ) { /* Obtain the proof account pubkey by borrowing the proof account. https://github.com/anza-xyz/agave/blob/master/programs/zk-elgamal-proof/src/lib.rs#L143-L145 */ FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK(ctx, ACC_IDX_PROOF, &proof_acc ); - *proof_pubkey = *proof_acc.acct->pubkey; + *proof_pubkey = *proof_acc.pubkey; fd_borrowed_account_drop( &proof_acc ); /* Obtain the dest account pubkey by borrowing the dest account. https://github.com/anza-xyz/agave/blob/master/programs/zk-elgamal-proof/src/lib.rs#L146-L148*/ FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_DEST, &dest_acc ); - *dest_pubkey = *dest_acc.acct->pubkey; + *dest_pubkey = *dest_acc.pubkey; fd_borrowed_account_drop( &dest_acc ); if( FD_UNLIKELY( fd_memeq( proof_pubkey, dest_pubkey, sizeof(fd_pubkey_t) ) ) ) { @@ -237,7 +237,7 @@ fd_zksdk_process_verify_proof( fd_exec_instr_ctx_t * ctx ) { do { fd_guarded_borrowed_account_t _acc = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, (ushort)(accessed_accounts+1), &_acc ); - *context_state_authority = *_acc.acct->pubkey; + *context_state_authority = *_acc.pubkey; } while(0); /* Borrow the proof context account diff --git a/src/flamenco/runtime/sysvar/fd_sysvar.c b/src/flamenco/runtime/sysvar/fd_sysvar.c index 4eb6df193a..26333a4d02 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar.c @@ -47,7 +47,7 @@ fd_sysvar_account_update( fd_bank_t * bank, __builtin_unreachable(); } - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); if( FD_UNLIKELY( fd_log_level_logfile()<=0 || fd_log_level_stderr()<=0 ) ) { @@ -67,7 +67,7 @@ fd_sysvar_instr_acct_check( fd_exec_instr_ctx_t const * ctx, } ushort idx_in_txn = ctx->instr->accounts[idx].index_in_transaction; - fd_pubkey_t const * addr_have = &ctx->txn_out->accounts.account_keys[ idx_in_txn ]; + fd_pubkey_t const * addr_have = &ctx->txn_out->accounts.keys[ idx_in_txn ]; if( FD_UNLIKELY( 0!=memcmp( addr_have, addr_want, sizeof(fd_pubkey_t) ) ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index 1fa56730bc..f693a608c9 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -33,54 +33,40 @@ instructions_serialized_size( fd_instr_info_t const * instrs, /* https://github.com/anza-xyz/agave/blob/v2.1.1/svm/src/account_loader.rs#L547-L576 */ void -fd_sysvar_instructions_serialize_account( fd_txn_in_t const * txn_in, +fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_instr_info_t const * instrs, ushort instrs_cnt, ulong txn_idx ) { ulong serialized_sz = instructions_serialized_size( instrs, instrs_cnt ); - fd_txn_account_t * rec = NULL; + int index; int err = fd_runtime_get_account_with_key( txn_in, txn_out, &fd_sysvar_instructions_id, - &rec, + &index, fd_runtime_account_check_exists ); - if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS && rec==NULL ) ) { + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS && index==-1 ) ) { /* The way we use this, this should NEVER hit since the borrowed accounts should be set up before this is called, and this is only called if the sysvar instructions account is in the borrowed accounts list. */ FD_LOG_ERR(( "Failed to view sysvar instructions borrowed account. It may not be included in the txn account keys." )); } - /* This stays within the FD spad allocation bounds because... - 1. Case 1: rec->meta!=NULL - - rec->meta was set up in `fd_executor_setup_accounts_for_txn()` and data was allocated from the spad - - No need to allocate meta and data here - 2. Case 2: rec->meta==NULL - - `fd_executor_setup_accounts_for_txn()` did not make an spad allocation for this account - - spad memory is sized out for allocations for 128 (max number) accounts - - sizeof(fd_account_meta_t) + serialized_sz will always be less than FD_ACC_TOT_SZ_MAX - - at most 127 accounts could be using spad memory right now, so this allocation is safe */ - if( !fd_txn_account_is_mutable( rec ) ) { - uchar const * mem = txn_in->exec_accounts->accounts_mem[ txn_idx ]; - fd_account_meta_t * meta = (fd_account_meta_t *)mem; - fd_txn_account_t * acc = fd_txn_account_join( fd_txn_account_new( rec, &fd_sysvar_instructions_id, meta, 1 ) ); - if( FD_UNLIKELY( !acc ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } - } - + fd_account_meta_t * meta = txn_out->accounts.metas[ txn_idx ]; /* Agave sets up the borrowed account for the instructions sysvar to contain default values except for the data which is serialized into the account. */ - fd_txn_account_set_owner( rec, &fd_sysvar_owner_id ); - fd_txn_account_set_lamports( rec, 0UL ); - fd_txn_account_set_executable( rec, 0 ); - fd_txn_account_set_data_len( rec, serialized_sz ); - rec->starting_lamports = 0UL; + fd_memcpy( meta->owner, &fd_sysvar_owner_id, sizeof(fd_pubkey_t) ); + meta->lamports = 0UL; + meta->executable = 0; + meta->dlen = (uint)serialized_sz; + + runtime->accounts.starting_lamports[txn_idx] = 0UL; + runtime->accounts.starting_dlen[txn_idx] = serialized_sz; - uchar * serialized_instructions = fd_txn_account_get_data_mut( rec ); + uchar * serialized_instructions = fd_account_data( meta ); ulong offset = 0; // TODO: do we needs bounds checking? @@ -111,12 +97,12 @@ fd_sysvar_instructions_serialize_account( fd_txn_in_t const * txn_in, // pubkey ushort idx_in_txn = instr->accounts[j].index_in_transaction; - FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.account_keys[ idx_in_txn ] ); + FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.keys[ idx_in_txn ] ); offset += sizeof(fd_pubkey_t); } // program_id_pubkey - FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.account_keys[ instr->program_id ] ); + FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.keys[ instr->program_id ] ); offset += sizeof(fd_pubkey_t); // instr_data_len @@ -136,13 +122,13 @@ fd_sysvar_instructions_serialize_account( fd_txn_in_t const * txn_in, /* Stores the current instruction index in the instructions sysvar account. https://github.com/anza-xyz/solana-sdk/blob/instructions-sysvar%40v2.2.1/instructions-sysvar/src/lib.rs#L164-L167 */ void -fd_sysvar_instructions_update_current_instr_idx( fd_txn_account_t * rec, - ushort current_instr_idx ) { +fd_sysvar_instructions_update_current_instr_idx( fd_account_meta_t * meta, + ushort current_instr_idx ) { /* Extra safety checks */ - if( FD_UNLIKELY( fd_txn_account_get_data_len( rec )dlendlen - sizeof(ushort)); FD_STORE( ushort, serialized_current_instr_idx, current_instr_idx ); } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h index 60428b3d26..609d925773 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h @@ -8,15 +8,16 @@ FD_PROTOTYPES_BEGIN void -fd_sysvar_instructions_serialize_account( fd_txn_in_t const * txn_in, +fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_instr_info_t const * instrs, ushort instrs_cnt, ulong txn_idx ); void -fd_sysvar_instructions_update_current_instr_idx( fd_txn_account_t * rec, - ushort current_instr_idx ); +fd_sysvar_instructions_update_current_instr_idx( fd_account_meta_t * meta, + ushort current_instr_idx ); FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/test_runtime_alut.c b/src/flamenco/runtime/test_runtime_alut.c index bab701a19b..1ee5ab3010 100644 --- a/src/flamenco/runtime/test_runtime_alut.c +++ b/src/flamenco/runtime/test_runtime_alut.c @@ -113,8 +113,6 @@ create_test_account( test_ctx_t * ctx, fd_txn_account_set_data( acc, data, data_len ); } - acc->starting_lamports = lamports; - acc->starting_dlen = data_len; fd_txn_account_set_lamports( acc, lamports ); fd_txn_account_set_executable( acc, executable ); fd_txn_account_set_owner( acc, &owner ); diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index 513e1cf938..1d9ed0ce71 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -111,7 +111,7 @@ fd_solfuzz_block_register_vote_account( fd_funk_t * funk, } /* Account must be initialized correctly */ - if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc ) ) ) { + if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc->meta ) ) ) { return; } @@ -147,7 +147,7 @@ fd_solfuzz_block_register_stake_delegation( fd_funk_t * funk, /* Stake state must exist and be initialized correctly */ fd_stake_state_v2_t stake_state; - if( FD_UNLIKELY( fd_stake_get_state( acc, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { + if( FD_UNLIKELY( fd_stake_get_state( acc->meta, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { return; } @@ -344,8 +344,7 @@ fd_solfuzz_pb_block_ctx_create( fd_solfuzz_runner_t * runner, /* Load in all accounts with > 0 lamports provided in the context. The input expects unique account pubkeys. */ vote_states = fd_bank_vote_states_locking_modify( bank ); for( ushort i=0; iacct_states_count; i++ ) { - fd_txn_account_t acc[1]; - fd_solfuzz_pb_load_account( acc, accdb, xid, &test_ctx->acct_states[i], 1 ); + fd_solfuzz_pb_load_account( runner->runtime, accdb, xid, &test_ctx->acct_states[i], 1, i, NULL ); /* Update vote accounts cache for epoch T */ fd_pubkey_t pubkey; diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index 4a23a6b5f1..490687350e 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -104,25 +104,26 @@ dump_sorted_features( fd_features_t const * features, /** ACCOUNT DUMPING **/ static void -dump_account_state( fd_txn_account_t const * txn_account, +dump_account_state( fd_pubkey_t const * account_key, + fd_account_meta_t const * account_meta, fd_exec_test_acct_state_t * output_account, fd_spad_t * spad ) { // Address - fd_memcpy(output_account->address, txn_account->pubkey, sizeof(fd_pubkey_t)); + fd_memcpy(output_account->address, account_key, sizeof(fd_pubkey_t)); // Lamports - output_account->lamports = (uint64_t)fd_txn_account_get_lamports( txn_account ); + output_account->lamports = (uint64_t)account_meta->lamports; // Data - output_account->data = fd_spad_alloc( spad, alignof(pb_bytes_array_t), PB_BYTES_ARRAY_T_ALLOCSIZE( fd_txn_account_get_data_len( txn_account ) ) ); - output_account->data->size = (pb_size_t) fd_txn_account_get_data_len( txn_account ); - fd_memcpy(output_account->data->bytes, fd_txn_account_get_data( txn_account ), fd_txn_account_get_data_len( txn_account ) ); + output_account->data = fd_spad_alloc( spad, alignof(pb_bytes_array_t), PB_BYTES_ARRAY_T_ALLOCSIZE( account_meta->dlen ) ); + output_account->data->size = (pb_size_t) account_meta->dlen; + fd_memcpy(output_account->data->bytes, fd_account_data( account_meta ), account_meta->dlen ); // Executable - output_account->executable = (bool)fd_txn_account_is_executable( txn_account ); + output_account->executable = (bool)account_meta->executable; // Owner - fd_memcpy(output_account->owner, fd_txn_account_get_owner( txn_account ), sizeof(fd_pubkey_t)); + fd_memcpy(output_account->owner, account_meta->owner, sizeof(fd_pubkey_t)); } static uchar @@ -155,7 +156,7 @@ dump_account_if_not_already_dumped( fd_funk_t const * funk, } if( !account_already_dumped( out_acct_states, *out_acct_states_cnt, account_key ) ) { - dump_account_state( account, &out_acct_states[*out_acct_states_cnt], spad ); + dump_account_state( account_key, account->meta, &out_acct_states[*out_acct_states_cnt], spad ); (*out_acct_states_cnt)++; } @@ -689,7 +690,7 @@ create_block_context_protobuf_from_block( fd_block_dump_ctx_t * dump_ctx, if( FD_UNLIKELY( ret ) ) { continue; } - dump_account_state( txn_account, &block_context->acct_states[block_context->acct_states_count++], spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, &block_context->acct_states[block_context->acct_states_count++], spad ); } /* BlockContext -> blockhash_queue */ @@ -774,16 +775,16 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m alignof(fd_exec_test_acct_state_t), (256UL*2UL + txn_descriptor->addr_table_lookup_cnt + num_sysvar_entries) * sizeof(fd_exec_test_acct_state_t) ); fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - for( ulong i = 0; i < txn_out->accounts.accounts_cnt; ++i ) { + for( ulong i = 0; i < txn_out->accounts.cnt; ++i ) { fd_txn_account_t txn_account[1]; - int ret = fd_txn_account_init_from_funk_readonly( txn_account, &txn_out->accounts.account_keys[i], runtime->funk, &xid ); + int ret = fd_txn_account_init_from_funk_readonly( txn_account, &txn_out->accounts.keys[i], runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) { continue; } // Make sure account is not a non-migrating builtin - if( !is_builtin_account( &txn_out->accounts.account_keys[i] ) ) { - dump_account_state( txn_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + if( !is_builtin_account( &txn_out->accounts.keys[i] ) ) { + dump_account_state( txn_account->pubkey, txn_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } } @@ -796,7 +797,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m int ret = fd_txn_account_init_from_funk_readonly( txn_account, alut_key, runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) continue; - dump_account_state( txn_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); fd_acct_addr_t * lookup_addrs = (fd_acct_addr_t *)&fd_txn_account_get_data( txn_account )[FD_LOOKUP_TABLE_META_SIZE]; ulong lookup_addrs_cnt = (fd_txn_account_get_data_len( txn_account ) - FD_LOOKUP_TABLE_META_SIZE) >> 5UL; // = (dlen - 56) / 32 @@ -813,7 +814,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m fd_txn_account_t referenced_account[1]; ret = fd_txn_account_init_from_funk_readonly( referenced_account, referenced_addr, runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) continue; - dump_account_state( referenced_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( referenced_account->pubkey, referenced_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } uchar const * readonly_lut_idxs = txn_payload + addr_lut->readonly_off; @@ -827,7 +828,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m fd_txn_account_t referenced_account[1]; ret = fd_txn_account_init_from_funk_readonly( referenced_account, referenced_addr, runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) continue; - dump_account_state( referenced_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( referenced_account->pubkey, referenced_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } } @@ -848,15 +849,15 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m // Make sure the account doesn't exist in the output accounts yet int account_exists = 0; - for( ulong j = 0; j < txn_out->accounts.accounts_cnt; j++ ) { - if ( 0 == memcmp( txn_out->accounts.account_keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { + for( ulong j = 0; j < txn_out->accounts.cnt; j++ ) { + if ( 0 == memcmp( txn_out->accounts.keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { account_exists = true; break; } } // Copy it into output if (!account_exists) { - dump_account_state( txn_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } } @@ -895,18 +896,18 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * fd_instr_info_t const * instr, fd_spad_t * spad ) { /* Program ID */ - fd_memcpy( instr_context->program_id, txn_out->accounts.account_keys[ instr->program_id ].uc, sizeof(fd_pubkey_t) ); + fd_memcpy( instr_context->program_id, txn_out->accounts.keys[ instr->program_id ].uc, sizeof(fd_pubkey_t) ); fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; /* Accounts */ - instr_context->accounts_count = (pb_size_t) txn_out->accounts.accounts_cnt; - instr_context->accounts = fd_spad_alloc( spad, alignof(fd_exec_test_acct_state_t), (instr_context->accounts_count + num_sysvar_entries + runtime->executable.cnt) * sizeof(fd_exec_test_acct_state_t)); - for( ulong i = 0; i < txn_out->accounts.accounts_cnt; i++ ) { + instr_context->accounts_count = (pb_size_t) txn_out->accounts.cnt; + instr_context->accounts = fd_spad_alloc( spad, alignof(fd_exec_test_acct_state_t), (instr_context->accounts_count + num_sysvar_entries + runtime->accounts.executable_cnt) * sizeof(fd_exec_test_acct_state_t)); + for( ulong i = 0; i < txn_out->accounts.cnt; i++ ) { // Copy account information over - fd_txn_account_t const * txn_account = &txn_out->accounts.accounts[i]; + fd_account_meta_t * account_meta = txn_out->accounts.metas[i]; fd_exec_test_acct_state_t * output_account = &instr_context->accounts[i]; - dump_account_state( txn_account, output_account, spad ); + dump_account_state( &txn_out->accounts.keys[i], account_meta, output_account, spad ); } /* Add sysvar cache variables */ @@ -918,8 +919,8 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * } // Make sure the account doesn't exist in the output accounts yet int account_exists = 0; - for( ulong j = 0; j < txn_out->accounts.accounts_cnt; j++ ) { - if ( 0 == memcmp( txn_out->accounts.account_keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { + for( ulong j = 0; j < txn_out->accounts.cnt; j++ ) { + if ( 0 == memcmp( txn_out->accounts.keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { account_exists = true; break; } @@ -928,21 +929,21 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * // Copy it into output if (!account_exists) { fd_exec_test_acct_state_t * output_account = &instr_context->accounts[instr_context->accounts_count++]; - dump_account_state( txn_account, output_account, spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, output_account, spad ); } } /* Add executable accounts */ - for( ulong i = 0; i < runtime->executable.cnt; i++ ) { + for( ulong i = 0; i < runtime->accounts.executable_cnt; i++ ) { fd_txn_account_t txn_account[1]; - int ret = fd_txn_account_init_from_funk_readonly( txn_account, runtime->executable.accounts[i].pubkey, runtime->funk, &xid ); + int ret = fd_txn_account_init_from_funk_readonly( txn_account, &runtime->accounts.executable_pubkeys[i], runtime->funk, &xid ); if( ret != FD_ACC_MGR_SUCCESS ) { continue; } // Make sure the account doesn't exist in the output accounts yet bool account_exists = false; for( ulong j = 0; j < instr_context->accounts_count; j++ ) { - if( 0 == memcmp( instr_context->accounts[j].address, runtime->executable.accounts[i].pubkey->uc, sizeof(fd_pubkey_t) ) ) { + if( 0 == memcmp( instr_context->accounts[j].address, runtime->accounts.executable_pubkeys[i].uc, sizeof(fd_pubkey_t) ) ) { account_exists = true; break; } @@ -950,7 +951,7 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * // Copy it into output if( !account_exists ) { fd_exec_test_acct_state_t * output_account = &instr_context->accounts[instr_context->accounts_count++]; - dump_account_state( txn_account, output_account, spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, output_account, spad ); } } diff --git a/src/flamenco/runtime/tests/fd_harness_common.c b/src/flamenco/runtime/tests/fd_harness_common.c index d912164881..2489631623 100644 --- a/src/flamenco/runtime/tests/fd_harness_common.c +++ b/src/flamenco/runtime/tests/fd_harness_common.c @@ -1,16 +1,19 @@ #include "fd_solfuzz_private.h" #include "generated/context.pb.h" #include "../fd_acc_mgr.h" +#include "../fd_runtime.h" #include "../../features/fd_features.h" #include "../../accdb/fd_accdb_impl_v1.h" #include int -fd_solfuzz_pb_load_account( fd_txn_account_t * acc, +fd_solfuzz_pb_load_account( fd_runtime_t * runtime, fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * state, - uchar reject_zero_lamports ) { + uchar reject_zero_lamports, + ulong acc_idx, + fd_account_meta_t * * meta_out ) { if( reject_zero_lamports && state->lamports==0UL ) { return 0; } @@ -26,8 +29,13 @@ fd_solfuzz_pb_load_account( fd_txn_account_t * acc, return 0; } + /* TODO: break the txn account dependency completely from the + harnesses. */ + fd_funk_rec_prepare_t prepare = {0}; + fd_txn_account_t acc[1]; + int ok = !!fd_txn_account_init_from_funk_mutable( /* acc */ acc, /* pubkey */ pubkey, /* funk */ accdb, @@ -36,13 +44,16 @@ fd_solfuzz_pb_load_account( fd_txn_account_t * acc, /* min_data_sz */ size, /* prepare */ &prepare ); assert( ok ); + if( meta_out ) { + *meta_out = acc->meta; + } if( state->data ) { fd_txn_account_set_data( acc, state->data->bytes, size ); } - acc->starting_lamports = state->lamports; - acc->starting_dlen = size; + runtime->accounts.starting_lamports[acc_idx] = state->lamports; + runtime->accounts.starting_dlen[acc_idx] = size; fd_txn_account_set_lamports( acc, state->lamports ); fd_txn_account_set_executable( acc, state->executable ); fd_txn_account_set_owner( acc, (fd_pubkey_t const *)state->owner ); diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index 4cb6eb19d5..5b98b8f147 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -51,6 +51,8 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, txn_in->exec_accounts = runner->exec_accounts; + memset( txn_out->accounts.metas, 0, sizeof(fd_account_meta_t) * MAX_TX_ACCOUNT_LOCKS ); + /* Bank manager */ fd_banks_clear_bank( runner->banks, runner->bank ); @@ -91,8 +93,8 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, fd_compute_budget_details_new( &txn_out->details.compute_budget ); runtime->instr.stack_sz = 0; - txn_out->accounts.accounts_cnt = 0UL; - runtime->executable.cnt = 0UL; + txn_out->accounts.cnt = 0UL; + runtime->accounts.executable_cnt = 0UL; txn_out->details.programs_to_reverify_cnt = 0UL; txn_out->details.loaded_accounts_data_size = 0UL; @@ -142,19 +144,19 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, /* Load accounts into database */ - fd_txn_account_t * accts = txn_out->accounts.accounts; - fd_memset( accts, 0, test_ctx->accounts_count * sizeof(fd_txn_account_t) ); - txn_out->accounts.accounts_cnt = test_ctx->accounts_count; + fd_txn_account_t accts[MAX_TX_ACCOUNT_LOCKS] = {0}; + txn_out->accounts.cnt = test_ctx->accounts_count; int has_program_id = 0; for( ulong j=0UL; j < test_ctx->accounts_count; j++ ) { fd_pubkey_t * acc_key = (fd_pubkey_t *)test_ctx->accounts[j].address; - memcpy( &(txn_out->accounts.account_keys[j]), test_ctx->accounts[j].address, sizeof(fd_pubkey_t) ); - if( !fd_solfuzz_pb_load_account( &accts[j], runner->accdb, xid, &test_ctx->accounts[j], 0 ) ) { + memcpy( &(txn_out->accounts.keys[j]), test_ctx->accounts[j].address, sizeof(fd_pubkey_t) ); + if( !fd_solfuzz_pb_load_account( runtime, runner->accdb, xid, &test_ctx->accounts[j], 0, j, &accts[j].meta ) ) { return 0; } + runtime->accounts.refcnt[j] = 0UL; fd_txn_account_t * acc = &accts[j]; if( fd_txn_account_get_meta( acc ) ) { @@ -166,10 +168,11 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, FD_LOG_CRIT(( "Failed to join and new a txn account" )); } } + txn_out->accounts.metas[j] = accts[j].meta; if( !memcmp( accts[j].pubkey, test_ctx->program_id, sizeof(fd_pubkey_t) ) ) { has_program_id = 1; - info->program_id = (uchar)txn_out->accounts.accounts_cnt; + info->program_id = (uchar)txn_out->accounts.cnt; } /* Since the instructions sysvar is set as mutable at the txn level, we need to make it mutable here as well. */ @@ -181,7 +184,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, /* If the program id is not in the set of accounts it must be added to the set of accounts. */ if( FD_UNLIKELY( !has_program_id ) ) { fd_txn_account_t * program_acc = &accts[ test_ctx->accounts_count ]; - fd_pubkey_t * program_key = &txn_out->accounts.account_keys[ txn_out->accounts.accounts_cnt ]; + fd_pubkey_t * program_key = &txn_out->accounts.keys[ txn_out->accounts.cnt ]; memcpy( program_key, test_ctx->program_id, sizeof(fd_pubkey_t) ); fd_account_meta_t * meta = fd_spad_alloc( runner->spad, alignof(fd_account_meta_t), sizeof(fd_account_meta_t) ); @@ -195,12 +198,14 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, FD_LOG_CRIT(( "Failed to join and new a txn account" )); } - info->program_id = (uchar)txn_out->accounts.accounts_cnt; - txn_out->accounts.accounts_cnt++; + txn_out->accounts.metas[test_ctx->accounts_count] = meta; + + info->program_id = (uchar)txn_out->accounts.cnt; + txn_out->accounts.cnt++; } /* Load in executable accounts */ - for( ulong i = 0; i < txn_out->accounts.accounts_cnt; i++ ) { + for( ulong i = 0; i < txn_out->accounts.cnt; i++ ) { fd_pubkey_t * acc_key = (fd_pubkey_t *)test_ctx->accounts[i].address; fd_txn_account_t * acc = &accts[i]; @@ -221,7 +226,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, if( FD_UNLIKELY( !memcmp( meta->owner, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) ) { fd_bpf_upgradeable_loader_state_t program_loader_state[1]; - int err = fd_bpf_loader_program_get_state( acc, program_loader_state ); + int err = fd_bpf_loader_program_get_state( meta, program_loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { continue; } @@ -231,13 +236,21 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, } fd_pubkey_t * programdata_acc = &program_loader_state->inner.program.programdata_address; - if( FD_UNLIKELY( fd_txn_account_init_from_funk_readonly( &runtime->executable.accounts[runtime->executable.cnt], - programdata_acc, - runtime->funk, - xid ) ) ) { + + fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( + runtime->funk, + xid, + programdata_acc, + NULL, + &err, + NULL ); + + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { continue; } - runtime->executable.cnt++; + runtime->accounts.executable_pubkeys[runtime->accounts.executable_cnt] = *programdata_acc; + runtime->accounts.executables_meta[runtime->accounts.executable_cnt] = (fd_account_meta_t *)meta; + runtime->accounts.executable_cnt++; } } @@ -340,7 +353,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, runtime->log.enable_log_collector = 0; fd_log_collector_init( ctx->runtime->log.log_collector, 1 ); - fd_base58_encode_32( txn_out->accounts.account_keys[ ctx->instr->program_id ].uc, NULL, ctx->program_id_base58 ); + fd_base58_encode_32( txn_out->accounts.keys[ ctx->instr->program_id ].uc, NULL, ctx->program_id_base58 ); return 1; } @@ -397,13 +410,13 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, if( FD_LIKELY( effects->result ) ) { int program_id_idx = ctx->instr[ 0UL ].program_id; if( exec_result==FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && - fd_executor_lookup_native_precompile_program( &ctx->txn_out->accounts.accounts[ program_id_idx ] )==NULL ) { + fd_executor_lookup_native_precompile_program( &ctx->txn_out->accounts.keys[ program_id_idx ] )==NULL ) { effects->custom_err = ctx->txn_out->err.custom_err; } } /* Allocate space for captured accounts */ - ulong modified_acct_cnt = ctx->txn_out->accounts.accounts_cnt; + ulong modified_acct_cnt = ctx->txn_out->accounts.cnt; fd_exec_test_acct_state_t * modified_accts = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_acct_state_t), @@ -417,9 +430,10 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, /* Capture borrowed accounts */ - for( ulong j=0UL; j < ctx->txn_out->accounts.accounts_cnt; j++ ) { - fd_txn_account_t * acc = &ctx->txn_out->accounts.accounts[j]; - if( !fd_txn_account_get_meta( acc ) ) { + for( ulong j=0UL; j < ctx->txn_out->accounts.cnt; j++ ) { + fd_pubkey_t * acc_key = &ctx->txn_out->accounts.keys[j]; + fd_account_meta_t * acc = ctx->txn_out->accounts.metas[j]; + if( !acc ) { continue; } @@ -430,22 +444,22 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, memset( out_acct, 0, sizeof(fd_exec_test_acct_state_t) ); /* Copy over account content */ - memcpy( out_acct->address, acc->pubkey, sizeof(fd_pubkey_t) ); - out_acct->lamports = fd_txn_account_get_lamports( acc ); - if( fd_txn_account_get_data_len( acc )>0UL ) { + memcpy( out_acct->address, acc_key, sizeof(fd_pubkey_t) ); + out_acct->lamports = acc->lamports; + if( acc->dlen>0UL ) { out_acct->data = FD_SCRATCH_ALLOC_APPEND( l, alignof(pb_bytes_array_t), - PB_BYTES_ARRAY_T_ALLOCSIZE( fd_txn_account_get_data_len( acc ) ) ); + PB_BYTES_ARRAY_T_ALLOCSIZE( acc->dlen ) ); if( FD_UNLIKELY( _l > output_end ) ) { fd_solfuzz_pb_instr_ctx_destroy( runner, ctx ); return 0UL; } - out_acct->data->size = (pb_size_t)fd_txn_account_get_data_len( acc ); - fd_memcpy( out_acct->data->bytes, fd_txn_account_get_data( acc ), fd_txn_account_get_data_len( acc ) ); + out_acct->data->size = (pb_size_t)acc->dlen; + fd_memcpy( out_acct->data->bytes, fd_account_data( acc ), acc->dlen ); } - out_acct->executable = fd_txn_account_is_executable( acc ); - memcpy( out_acct->owner, fd_txn_account_get_owner( acc ), sizeof(fd_pubkey_t) ); + out_acct->executable = acc->executable; + memcpy( out_acct->owner, acc->owner, sizeof(fd_pubkey_t) ); effects->modified_accounts_count++; } diff --git a/src/flamenco/runtime/tests/fd_solfuzz_private.h b/src/flamenco/runtime/tests/fd_solfuzz_private.h index 5b9d78f3b1..6a7044954b 100644 --- a/src/flamenco/runtime/tests/fd_solfuzz_private.h +++ b/src/flamenco/runtime/tests/fd_solfuzz_private.h @@ -27,11 +27,13 @@ FD_PROTOTYPES_BEGIN On success, loads the account into acc. Optionally, reject any zero-lamport accounts from being loaded in. */ int -fd_solfuzz_pb_load_account( fd_txn_account_t * acc, +fd_solfuzz_pb_load_account( fd_runtime_t * runtime, fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * state, - uchar reject_zero_lamports ); + uchar reject_zero_lamports, + ulong acc_idx, + fd_account_meta_t * * meta_out ); /* Activates features in the runtime given an input feature set. Fails if a passed-in feature is unknown / not supported. */ diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 59754d3e9c..1134c13b31 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -81,8 +81,7 @@ fd_solfuzz_pb_txn_ctx_create( fd_solfuzz_runner_t * runner, for( ulong i = 0; i < test_ctx->account_shared_data_count; i++ ) { /* Load the accounts into the account manager Borrowed accounts get reset anyways - we just need to load the account somewhere */ - fd_txn_account_t acc[1]; - fd_solfuzz_pb_load_account( acc, accdb, &xid, &test_ctx->account_shared_data[i], 1 ); + fd_solfuzz_pb_load_account( runner->runtime, accdb, &xid, &test_ctx->account_shared_data[i], 1, i, NULL ); } /* Setup Bank manager */ @@ -452,7 +451,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, /* If the exec err was a custom instr error and came from a precompile instruction, don't capture the custom error code. */ if( txn_out->err.exec_err==FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && - fd_executor_lookup_native_precompile_program( &txn_out->accounts.accounts[ program_id_idx ] )==NULL ) { + fd_executor_lookup_native_precompile_program( &txn_out->accounts.keys[ program_id_idx ] )==NULL ) { txn_result->custom_error = txn_out->err.custom_err; } } @@ -479,7 +478,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, } /* Allocate space for captured accounts */ - ulong modified_acct_cnt = txn_out->accounts.accounts_cnt; + ulong modified_acct_cnt = txn_out->accounts.cnt; txn_result->has_resulting_state = true; txn_result->resulting_state.acct_states = @@ -490,27 +489,27 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, } /* If the transaction is a fees-only transaction, we have to create rollback accounts to iterate over and save. */ - fd_txn_account_t * accounts_to_save = txn_out->accounts.accounts; - ulong accounts_cnt = txn_out->accounts.accounts_cnt; + fd_account_meta_t * * accounts_to_save = txn_out->accounts.metas; + ulong accounts_cnt = txn_out->accounts.cnt; if( txn_out->err.is_fees_only ) { accounts_to_save = fd_spad_alloc( runner->spad, alignof(fd_txn_account_t), sizeof(fd_txn_account_t) * 2 ); accounts_cnt = 0UL; if( FD_LIKELY( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { - accounts_to_save[accounts_cnt++] = *txn_out->accounts.rollback_fee_payer; + accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_fee_payer; } if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { - accounts_to_save[accounts_cnt++] = *txn_out->accounts.rollback_nonce; + accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_nonce; } } /* Capture borrowed accounts */ for( ulong j=0UL; jaccounts.keys[j]; if( !( fd_runtime_account_is_writable_idx( txn_in, txn_out, runner->bank, (ushort)j ) || j==FD_FEE_PAYER_TXN_IDX ) ) continue; - assert( fd_txn_account_is_mutable( acc ) ); ulong modified_idx = txn_result->resulting_state.acct_states_count; assert( modified_idx < modified_acct_cnt ); @@ -519,23 +518,23 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, memset( out_acct, 0, sizeof(fd_exec_test_acct_state_t) ); /* Copy over account content */ - memcpy( out_acct->address, acc->pubkey, sizeof(fd_pubkey_t) ); + memcpy( out_acct->address, pubkey, sizeof(fd_pubkey_t) ); - out_acct->lamports = fd_txn_account_get_lamports( acc ); + out_acct->lamports = meta->lamports; - if( fd_txn_account_get_data_len( acc )>0UL ) { + if( meta->dlen>0UL ) { out_acct->data = FD_SCRATCH_ALLOC_APPEND( l, alignof(pb_bytes_array_t), - PB_BYTES_ARRAY_T_ALLOCSIZE( fd_txn_account_get_data_len( acc ) ) ); + PB_BYTES_ARRAY_T_ALLOCSIZE( meta->dlen ) ); if( FD_UNLIKELY( _l > output_end ) ) { abort(); } - out_acct->data->size = (pb_size_t)fd_txn_account_get_data_len( acc ); - fd_memcpy( out_acct->data->bytes, fd_txn_account_get_data( acc ), fd_txn_account_get_data_len( acc ) ); + out_acct->data->size = (pb_size_t)meta->dlen; + fd_memcpy( out_acct->data->bytes, fd_account_data( meta ), meta->dlen ); } - out_acct->executable = fd_txn_account_is_executable( acc ); - memcpy( out_acct->owner, fd_txn_account_get_owner( acc ), sizeof(fd_pubkey_t) ); + out_acct->executable = meta->executable; + memcpy( out_acct->owner, meta->owner, sizeof(fd_pubkey_t) ); txn_result->resulting_state.acct_states_count++; } diff --git a/src/flamenco/runtime/tests/fd_vm_harness.c b/src/flamenco/runtime/tests/fd_vm_harness.c index 2f5bd36dea..03bfaab67b 100644 --- a/src/flamenco/runtime/tests/fd_vm_harness.c +++ b/src/flamenco/runtime/tests/fd_vm_harness.c @@ -148,19 +148,19 @@ do{ memcpy( rodata, input->vm_ctx.rodata->bytes, rodata_sz ); /* Setup input region */ - ulong input_sz = 0UL; - ulong pre_lens[256] = {0}; - fd_vm_input_region_t input_mem_regions[1000] = {0}; /* We can have a max of (3 * num accounts + 1) regions */ - fd_vm_acc_region_meta_t acc_region_metas[256] = {0}; /* instr acc idx to idx */ - uint input_mem_regions_cnt = 0UL; - int direct_mapping = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, account_data_direct_mapping ); - int stricter_abi_and_runtime_constraints = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, stricter_abi_and_runtime_constraints ); - - uchar * input_ptr = NULL; - uchar program_id_idx = instr_ctx->instr->program_id; - fd_txn_account_t const * program_acc = &instr_ctx->txn_out->accounts.accounts[program_id_idx]; - uchar is_deprecated = ( program_id_idx < instr_ctx->txn_out->accounts.accounts_cnt ) && - ( !memcmp( fd_txn_account_get_owner( program_acc ), fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); + ulong input_sz = 0UL; + ulong pre_lens[256] = {0}; + fd_vm_input_region_t input_mem_regions[1000] = {0}; /* We can have a max of (3 * num accounts + 1) regions */ + fd_vm_acc_region_meta_t acc_region_metas[256] = {0}; /* instr acc idx to idx */ + uint input_mem_regions_cnt = 0UL; + int direct_mapping = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, account_data_direct_mapping ); + int stricter_abi_and_runtime_constraints = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, stricter_abi_and_runtime_constraints ); + + uchar * input_ptr = NULL; + uchar program_id_idx = instr_ctx->instr->program_id; + fd_account_meta_t const * program_acc = instr_ctx->txn_out->accounts.metas[program_id_idx]; + uchar is_deprecated = ( program_id_idx < instr_ctx->txn_out->accounts.cnt ) && + ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); /* Push the instruction onto the stack. This may also modify the sysvar instructions account, if its present. */ int stack_push_err = fd_instr_stack_push( instr_ctx->runtime, instr_ctx->txn_in, instr_ctx->txn_out, (fd_instr_info_t *)instr_ctx->instr ); @@ -468,11 +468,11 @@ fd_solfuzz_pb_syscall_run( fd_solfuzz_runner_t * runner, int direct_mapping = FD_FEATURE_ACTIVE_BANK( ctx->bank, account_data_direct_mapping ); int stricter_abi_and_runtime_constraints = FD_FEATURE_ACTIVE_BANK( ctx->bank, stricter_abi_and_runtime_constraints ); - uchar * input_ptr = NULL; - uchar program_id_idx = ctx->instr->program_id; - fd_txn_account_t * program_acc = &ctx->txn_out->accounts.accounts[program_id_idx]; - uchar is_deprecated = ( program_id_idx < ctx->txn_out->accounts.accounts_cnt ) && - ( !memcmp( fd_txn_account_get_owner( program_acc ), fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); + uchar * input_ptr = NULL; + uchar program_id_idx = ctx->instr->program_id; + fd_account_meta_t * program_acc = ctx->txn_out->accounts.metas[program_id_idx]; + uchar is_deprecated = ( program_id_idx < ctx->txn_out->accounts.cnt ) && + ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); /* Push the instruction onto the stack. This may also modify the sysvar instructions account, if its present. */ int stack_push_err = fd_instr_stack_push( ctx->runtime, ctx->txn_in, ctx->txn_out, (fd_instr_info_t *)ctx->instr ); diff --git a/src/flamenco/runtime/tests/test_dump_block.c b/src/flamenco/runtime/tests/test_dump_block.c index 6cdac32ff9..a3c33db653 100644 --- a/src/flamenco/runtime/tests/test_dump_block.c +++ b/src/flamenco/runtime/tests/test_dump_block.c @@ -237,7 +237,7 @@ register_vote_account_from_funk( fd_funk_t * funk, } /* Account must be initialized correctly */ - if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc ) ) ) { + if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc->meta ) ) ) { return; } @@ -271,7 +271,7 @@ register_stake_delegation_from_funk( fd_funk_t * funk, /* Stake state must exist and be initialized correctly */ fd_stake_state_v2_t stake_state; - if( FD_UNLIKELY( fd_stake_get_state( acc, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { + if( FD_UNLIKELY( fd_stake_get_state( acc->meta, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { return; } @@ -323,8 +323,6 @@ load_accounts_from_proto( fd_accdb_user_t * accdb, } /* Set account metadata */ - acc->starting_lamports = state->lamports; - acc->starting_dlen = size; fd_txn_account_set_lamports( acc, state->lamports ); fd_txn_account_set_executable( acc, state->executable ); fd_txn_account_set_owner( acc, (fd_pubkey_t const *)state->owner ); diff --git a/src/flamenco/stakes/fd_stake_delegations.c b/src/flamenco/stakes/fd_stake_delegations.c index 045dfe129b..806ae51d28 100644 --- a/src/flamenco/stakes/fd_stake_delegations.c +++ b/src/flamenco/stakes/fd_stake_delegations.c @@ -1,6 +1,7 @@ #include "fd_stake_delegations.h" #include "../../funk/fd_funk_base.h" #include "../runtime/fd_txn_account.h" +#include "../runtime/fd_acc_mgr.h" #include "../runtime/program/fd_stake_program.h" #define POOL_NAME fd_stake_delegation_pool @@ -355,21 +356,16 @@ fd_stake_delegations_refresh( fd_stake_delegations_t * stake_delegations, continue; } - fd_txn_account_t acct_rec[1]; - int err = fd_txn_account_init_from_funk_readonly( - acct_rec, - &stake_delegation->stake_account, - funk, - xid ); - - if( FD_UNLIKELY( err || fd_txn_account_get_lamports( acct_rec )==0UL ) ) { + int err = 0; + fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( funk, xid, &stake_delegation->stake_account, NULL, &err, NULL ); + if( FD_UNLIKELY( err || meta->lamports==0UL ) ) { fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool ); fd_stake_delegation_pool_idx_release( stake_delegation_pool, i ); continue; } fd_stake_state_v2_t stake_state; - err = fd_stake_get_state( acct_rec, &stake_state ); + err = fd_stake_get_state( meta, &stake_state ); if( FD_UNLIKELY( err ) ) { fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool ); fd_stake_delegation_pool_idx_release( stake_delegation_pool, i ); diff --git a/src/flamenco/stakes/fd_stakes.c b/src/flamenco/stakes/fd_stakes.c index 621d3b96e0..b1d390b3c9 100644 --- a/src/flamenco/stakes/fd_stakes.c +++ b/src/flamenco/stakes/fd_stakes.c @@ -172,50 +172,49 @@ write_stake_state( fd_txn_account_t * stake_acc_rec, } void -fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ) { - - if( !stake_account->is_mutable ) return; +fd_stakes_update_stake_delegation( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ) { fd_stake_delegations_t * stake_delegations_delta = fd_bank_stake_delegations_delta_locking_modify( bank ); if( FD_UNLIKELY( !stake_delegations_delta ) ) { FD_LOG_CRIT(( "unable to retrieve join to stake delegation delta" )); } - if( fd_txn_account_get_lamports( stake_account )==0UL ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + if( meta->lamports==0UL ) { + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } fd_stake_state_v2_t stake_state; - int err = fd_stake_get_state( stake_account, &stake_state ); + int err = fd_stake_get_state( meta, &stake_state ); if( FD_UNLIKELY( err!=0 ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( !fd_stake_state_v2_is_stake( &stake_state ) ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( fd_stake_state_v2_is_uninitialized( &stake_state ) ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( stake_state.inner.stake.stake.delegation.stake==0UL ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } fd_stake_delegations_update( stake_delegations_delta, - stake_account->pubkey, + pubkey, &stake_state.inner.stake.stake.delegation.voter_pubkey, stake_state.inner.stake.stake.delegation.stake, stake_state.inner.stake.stake.delegation.activation_epoch, @@ -227,28 +226,27 @@ fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, } void -fd_stakes_update_vote_state( fd_txn_account_t * vote_account, - fd_bank_t * bank ) { - - if( !vote_account->is_mutable ) return; +fd_stakes_update_vote_state( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ) { fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); - if( fd_txn_account_get_lamports( vote_account )==0UL ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); + if( meta->lamports==0UL ) { + fd_vote_states_remove( vote_states, pubkey ); fd_bank_vote_states_end_locking_modify( bank ); return; } - if( !fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); + if( !fd_vote_state_versions_is_correct_and_initialized( meta ) ) { + fd_vote_states_remove( vote_states, pubkey ); fd_bank_vote_states_end_locking_modify( bank ); return; } fd_vote_states_update_from_account( vote_states, - vote_account->pubkey, - fd_txn_account_get_data( vote_account ), - fd_txn_account_get_data_len( vote_account ) ); + pubkey, + fd_account_data( meta ), + meta->dlen ); fd_bank_vote_states_end_locking_modify( bank ); } diff --git a/src/flamenco/stakes/fd_stakes.h b/src/flamenco/stakes/fd_stakes.h index 9ad42096f5..9163027289 100644 --- a/src/flamenco/stakes/fd_stakes.h +++ b/src/flamenco/stakes/fd_stakes.h @@ -62,8 +62,9 @@ fd_refresh_vote_accounts( fd_bank_t * bank, the stake account. */ void -fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ); +fd_stakes_update_stake_delegation( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ); /* fd_stakes_update_vote_state is used to maintain the in-memory cache of the vote states that is used at the epoch boundary. Entries in @@ -71,8 +72,9 @@ fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, the vote account. */ void -fd_stakes_update_vote_state( fd_txn_account_t * vote_account, - fd_bank_t * bank ); +fd_stakes_update_vote_state( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ); FD_PROTOTYPES_END diff --git a/src/flamenco/vm/fd_vm.h b/src/flamenco/vm/fd_vm.h index c6a1026ded..348bb27e20 100644 --- a/src/flamenco/vm/fd_vm.h +++ b/src/flamenco/vm/fd_vm.h @@ -37,21 +37,21 @@ typedef struct fd_vm_input_region fd_vm_input_region_t; region location. */ struct __attribute((aligned(8UL))) fd_vm_acc_region_meta { - uint region_idx; + uint region_idx; /* FIXME: We can get rid of this field once DM is activated. This is only a hack to make the non-DM code path happy. When DM is activated, we could query the input_mem_region array for the original data len. */ - ulong original_data_len; + ulong original_data_len; /* The transaction account corresponding to this account. */ - fd_txn_account_t * acct; + fd_account_meta_t * meta; /* The expected virtual offsets of the serialized pubkey, lamports and owner for the account corresponding to this region. Relative to the start of the account's input region vaddr. Used for CPI security checks. */ - uint expected_pubkey_offset; - uint expected_lamports_offset; - uint expected_owner_offset; + uint expected_pubkey_offset; + uint expected_lamports_offset; + uint expected_owner_offset; }; typedef struct fd_vm_acc_region_meta fd_vm_acc_region_meta_t; diff --git a/src/flamenco/vm/fd_vm_private.h b/src/flamenco/vm/fd_vm_private.h index 64c54e3675..c93192f487 100644 --- a/src/flamenco/vm/fd_vm_private.h +++ b/src/flamenco/vm/fd_vm_private.h @@ -370,7 +370,7 @@ fd_vm_handle_input_mem_region_oob( fd_vm_t const * vm, fd_ulong_sat_add( vm->instr_ctx->txn_out->details.accounts_resize_delta, new_region_sz ), region->region_sz ); - fd_txn_account_resize( vm->acc_region_metas[ region->acc_region_meta_idx ].acct, new_region_sz ); + fd_account_meta_resize( vm->acc_region_metas[ region->acc_region_meta_idx ].meta, new_region_sz ); region->region_sz = (uint)new_region_sz; } } diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c b/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c index d69d26c6ac..4773afed5f 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c @@ -141,15 +141,15 @@ fd_vm_prepare_instruction( fd_instr_info_t * callee_instr, /* Check that the account is not read-only in the caller but writable in the callee */ if( FD_UNLIKELY( instruction_account->is_writable && !fd_borrowed_account_is_writable( &borrowed_caller_acct ) ) ) { - FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.acct->pubkey->uc, id_b58 ); + FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.pubkey->uc, id_b58 ); fd_log_collector_msg_many( instr_ctx, 2, id_b58, id_b58_len, "'s writable privilege escalated", 31UL ); FD_TXN_ERR_FOR_LOG_INSTR( instr_ctx->txn_out, FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION, instr_ctx->txn_out->err.exec_err_idx ); return FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION; } /* If the account is signed in the callee, it must be signed by the caller or the program */ - if ( FD_UNLIKELY( instruction_account->is_signer && !( fd_borrowed_account_is_signer( &borrowed_caller_acct ) || fd_vm_syscall_cpi_is_signer( borrowed_caller_acct.acct->pubkey, signers, signers_cnt) ) ) ) { - FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.acct->pubkey->uc, id_b58 ); + if ( FD_UNLIKELY( instruction_account->is_signer && !( fd_borrowed_account_is_signer( &borrowed_caller_acct ) || fd_vm_syscall_cpi_is_signer( borrowed_caller_acct.pubkey, signers, signers_cnt) ) ) ) { + FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.pubkey->uc, id_b58 ); fd_log_collector_msg_many( instr_ctx, 2, id_b58, id_b58_len, "'s signer privilege escalated", 29UL ); FD_TXN_ERR_FOR_LOG_INSTR( instr_ctx->txn_out, FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION, instr_ctx->txn_out->err.exec_err_idx ); return FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION; diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c b/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c index 0d07044206..d6d33c8cef 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c @@ -286,7 +286,7 @@ VM_SYSCALL_CPI_TRANSLATE_AND_UPDATE_ACCOUNTS_FUNC( fd_guarded_borrowed_account_t callee_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( vm->instr_ctx, instruction_accounts[i].index_in_caller, &callee_acct ); - fd_pubkey_t const * account_key = callee_acct.acct->pubkey; + fd_pubkey_t const * account_key = callee_acct.pubkey; fd_account_meta_t const * acc_meta = fd_borrowed_account_get_acc_meta( &callee_acct ); /* If the account is known and executable, we only need to consume the compute units. @@ -540,21 +540,21 @@ VM_SYSCALL_CPI_UPDATE_CALLER_ACC_FUNC( fd_vm_t * vm, return 1; } - fd_txn_account_t * callee_acc = borrowed_callee_acc.acct; + fd_account_meta_t * callee_meta = borrowed_callee_acc.meta; /* Update the caller account lamports with the value from the callee https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1191 */ - *(caller_account->lamports) = fd_txn_account_get_lamports( callee_acc ); + *(caller_account->lamports) = callee_meta->lamports; /* Update the caller account owner with the value from the callee https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1192 */ - fd_pubkey_t const * updated_owner = fd_txn_account_get_owner( callee_acc ); + fd_pubkey_t const * updated_owner = (fd_pubkey_t const *)callee_meta->owner; if( updated_owner ) *caller_account->owner = *updated_owner; else fd_memset( caller_account->owner, 0, sizeof(fd_pubkey_t) ); /* Update the caller account data with the value from the callee https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1194-L1195 */ ulong prev_len = *caller_account->ref_to_len_in_vm; - ulong post_len = fd_txn_account_get_data_len( callee_acc ); + ulong post_len = callee_meta->dlen; /* Calculate the address space reserved for the account. With stricter_abi_and_runtime_constraints and deprecated loader, the reserved space equals original length (no realloc space). @@ -637,7 +637,7 @@ VM_SYSCALL_CPI_UPDATE_CALLER_ACC_FUNC( fd_vm_t * vm, https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1254-L1265 */ if( !(vm->stricter_abi_and_runtime_constraints && vm->direct_mapping) ) { - fd_memcpy( caller_account->serialized_data, fd_txn_account_get_data( callee_acc ), post_len ); + fd_memcpy( caller_account->serialized_data, fd_account_data( callee_meta ), post_len ); } @@ -739,7 +739,7 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm, /* Derive PDA signers ************************************************/ fd_pubkey_t signers[ FD_CPI_MAX_SIGNER_CNT ] = {0}; - fd_pubkey_t * caller_program_id = &vm->instr_ctx->txn_out->accounts.account_keys[ vm->instr_ctx->instr->program_id ]; + fd_pubkey_t * caller_program_id = &vm->instr_ctx->txn_out->accounts.keys[ vm->instr_ctx->instr->program_id ]; /* This is the equivalent of translate_slice in translate_signers: https://github.com/solana-labs/solana/blob/dbf06e258ae418097049e845035d7d5502fe1327/programs/bpf_loader/src/syscalls/cpi.rs#L595 */ if( FD_LIKELY( signers_seeds_cnt > 0UL ) ) { @@ -904,7 +904,7 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm, caller accounts can't be changed during a CPI execution. */ if( fd_instr_acc_is_writable_idx( vm->instr_ctx->instr, callee_account_keys[i] ) ) { ushort idx_in_txn = vm->instr_ctx->instr->accounts[ callee_account_keys[i] ].index_in_transaction; - fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.account_keys[ idx_in_txn ]; + fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.keys[ idx_in_txn ]; err = VM_SYSCALL_CPI_UPDATE_CALLER_ACC_FUNC(vm, &acc_infos[ caller_accounts_to_update[i] ], caller_accounts + i, (uchar)callee_account_keys[i], callee); if( FD_UNLIKELY( err ) ) { return err; @@ -921,7 +921,7 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm, /* https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1033-L1034 */ fd_guarded_borrowed_account_t borrowed_callee_acc = {0}; ushort idx_in_txn = vm->instr_ctx->instr->accounts[ callee_account_keys[i] ].index_in_transaction; - fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.account_keys[ idx_in_txn ]; + fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.keys[ idx_in_txn ]; err = fd_exec_instr_ctx_try_borrow_instr_account_with_key( vm->instr_ctx, callee, &borrowed_callee_acc ); if( FD_UNLIKELY( err && ( err != FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) ) ) { return 1;