diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index 821ed88f9c..c6d9f0df37 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -315,6 +315,8 @@ struct fd_replay_tile { TODO: Should be replaced by tile-level allocations. */ fd_spad_t * runtime_spad; + fd_runtime_mem_t runtime_mem; + /* Buffer to store vote towers that need to be published to the Tower tile. */ ulong vote_tower_out_idx; /* index of vote tower to publish next */ @@ -648,10 +650,11 @@ replay_block_start( fd_replay_tile_t * ctx, &xid, ctx->capture_ctx, ctx->runtime_spad, + &ctx->runtime_mem, &is_epoch_boundary ); if( FD_UNLIKELY( is_epoch_boundary ) ) publish_stake_weights( ctx, stem, bank, 1 ); - int res = fd_runtime_block_execute_prepare( bank, ctx->funk, &xid, ctx->capture_ctx, ctx->runtime_spad ); + int res = fd_runtime_block_execute_prepare( bank, ctx->funk, &xid, ctx->capture_ctx, &ctx->runtime_mem ); if( FD_UNLIKELY( res!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { FD_LOG_CRIT(( "block prep execute failed" )); } @@ -762,10 +765,10 @@ replay_block_finalize( fd_replay_tile_t * ctx, break; } int rc = fd_bank_hash_cmp_check( bank_hash_cmp, cmp_slot ); - switch ( rc ) { + switch( rc ) { case -1: /* Mismatch */ - FD_LOG_WARNING(( "Bank hash mismatch on slot: %lu. Halting.", cmp_slot )); + FD_LOG_WARNING(( "Bank hash mismatch on slot: %lu.", cmp_slot )); break; case 0: /* Not ready */ @@ -849,10 +852,11 @@ prepare_leader_bank( fd_replay_tile_t * ctx, &xid, ctx->capture_ctx, ctx->runtime_spad, + &ctx->runtime_mem, &is_epoch_boundary ); if( FD_UNLIKELY( is_epoch_boundary ) ) publish_stake_weights( ctx, stem, ctx->leader_bank, 1 ); - int res = fd_runtime_block_execute_prepare( ctx->leader_bank, ctx->funk, &xid, ctx->capture_ctx, ctx->runtime_spad ); + int res = fd_runtime_block_execute_prepare( ctx->leader_bank, ctx->funk, &xid, ctx->capture_ctx, &ctx->runtime_mem ); if( FD_UNLIKELY( res!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { FD_LOG_CRIT(( "block prep execute failed" )); } @@ -947,7 +951,7 @@ init_after_snapshot( fd_replay_tile_t * ctx ) { /* After both snapshots have been loaded in, we can determine if we should start distributing rewards. */ - fd_rewards_recalculate_partitioned_rewards( ctx->banks, bank, ctx->funk, &xid, ctx->capture_ctx, ctx->runtime_spad ); + fd_rewards_recalculate_partitioned_rewards( ctx->banks, bank, ctx->funk, &xid, ctx->capture_ctx, ctx->runtime_spad, &ctx->runtime_mem ); ulong snapshot_slot = fd_bank_slot_get( bank ); if( FD_UNLIKELY( !snapshot_slot ) ) { @@ -955,7 +959,7 @@ init_after_snapshot( fd_replay_tile_t * ctx ) { /* FIXME: This branch does not set up a new block exec ctx properly. Needs to do whatever prepare_new_block_execution does, but just hacking that in breaks stuff. */ - fd_runtime_update_leaders( bank, ctx->runtime_spad ); + fd_runtime_update_leaders( bank, ctx->runtime_mem.epoch_weights_mem ); ulong hashcnt_per_slot = fd_bank_hashes_per_tick_get( bank ) * fd_bank_ticks_per_slot_get( bank ); fd_hash_t * poh = fd_bank_poh_modify( bank ); @@ -963,7 +967,7 @@ init_after_snapshot( fd_replay_tile_t * ctx ) { fd_sha256_hash( poh->hash, 32UL, poh->hash ); } - FD_TEST( fd_runtime_block_execute_prepare( bank, ctx->funk, &xid, ctx->capture_ctx, ctx->runtime_spad ) == 0 ); + FD_TEST( fd_runtime_block_execute_prepare( bank, ctx->funk, &xid, ctx->capture_ctx, &ctx->runtime_mem ) == 0 ); fd_runtime_block_execute_finalize( bank, ctx->funk, &xid, ctx->capture_ctx, 1 ); snapshot_slot = 0UL; @@ -1166,7 +1170,7 @@ boot_genesis( fd_replay_tile_t * ctx, } fd_funk_txn_xid_t xid = { .ul = { 0UL, 0UL } }; - fd_runtime_read_genesis( ctx->banks, bank, ctx->funk, &xid, NULL, fd_type_pun_const( genesis_hash ), fd_type_pun_const( lthash ), genesis, ctx->runtime_spad ); + fd_runtime_read_genesis( ctx->banks, bank, ctx->funk, &xid, NULL, fd_type_pun_const( genesis_hash ), fd_type_pun_const( lthash ), genesis, ctx->runtime_spad, &ctx->runtime_mem ); static const fd_txncache_fork_id_t txncache_root = { .val = USHORT_MAX }; bank->txncache_fork_id = fd_txncache_attach_child( ctx->txncache, txncache_root ); @@ -1285,7 +1289,7 @@ on_snapshot_message( fd_replay_tile_t * ctx, fd_features_restore( bank, ctx->funk, &xid ); - fd_runtime_update_leaders( bank, ctx->runtime_spad ); + fd_runtime_update_leaders( bank, ctx->runtime_mem.epoch_weights_mem ); fd_block_id_ele_t * block_id_ele = &ctx->block_id_arr[ 0 ]; FD_TEST( block_id_ele ); @@ -1390,7 +1394,7 @@ replay( fd_replay_tile_t * ctx, fd_funk_txn_xid_t xid = { .ul = { ready_txn->slot, ready_txn->slot } }; - fd_runtime_update_program_cache( bank, ctx->funk, &xid, txn_p, ctx->runtime_spad ); + fd_runtime_update_program_cache( bank, ctx->funk, &xid, txn_p, &ctx->runtime_mem ); /* At this point, we are going to send the txn down the execution pipeline. Increment the refcnt so we don't prematurely prune a @@ -1526,7 +1530,6 @@ process_fec_set( fd_replay_tile_t * ctx, fd_funk_txn_xid_copy( sched_fec->alut_ctx->xid, fd_funk_last_publish( ctx->funk ) ); sched_fec->alut_ctx->funk = ctx->funk; sched_fec->alut_ctx->els = ctx->published_root_slot; - sched_fec->alut_ctx->runtime_spad = ctx->runtime_spad; if( FD_UNLIKELY( !fd_sched_fec_ingest( ctx->sched, sched_fec ) ) ) { fd_banks_mark_bank_dead( ctx->banks, fd_banks_bank_query( ctx->banks, sched_fec->bank_idx ) ); diff --git a/src/discof/replay/fd_sched.c b/src/discof/replay/fd_sched.c index b31d323009..83d0d940e7 100644 --- a/src/discof/replay/fd_sched.c +++ b/src/discof/replay/fd_sched.c @@ -1114,9 +1114,7 @@ fd_sched_parse_txn( fd_sched_t * sched, fd_sched_block_t * block, fd_sched_alut_ int has_aluts = txn->transaction_version==FD_TXN_V0 && txn->addr_table_adtl_cnt>0; int serializing = 0; if( has_aluts ) { - /* FIXME: statically size out slot hashes decode footprint. */ - FD_SPAD_FRAME_BEGIN( alut_ctx->runtime_spad ) { - fd_slot_hashes_global_t const * slot_hashes_global = fd_sysvar_slot_hashes_read( alut_ctx->funk, alut_ctx->xid, alut_ctx->runtime_spad ); + fd_slot_hashes_global_t const * slot_hashes_global = fd_sysvar_slot_hashes_read( alut_ctx->funk, alut_ctx->xid, alut_ctx->slot_hashes_mem ); if( FD_LIKELY( slot_hashes_global ) ) { fd_slot_hash_t * slot_hash = deq_fd_slot_hash_t_join( (uchar *)slot_hashes_global + slot_hashes_global->hashes_offset ); serializing = !!fd_runtime_load_txn_address_lookup_tables( txn, block->fec_buf+block->fec_buf_soff, alut_ctx->funk, alut_ctx->xid, alut_ctx->els, slot_hash, block->aluts ); @@ -1124,7 +1122,6 @@ fd_sched_parse_txn( fd_sched_t * sched, fd_sched_block_t * block, fd_sched_alut_ } else { serializing = 1; } - } FD_SPAD_FRAME_END; } ulong bank_idx = (ulong)(block-sched->block_pool); diff --git a/src/discof/replay/fd_sched.h b/src/discof/replay/fd_sched.h index 689b49d83a..9d5283ea21 100644 --- a/src/discof/replay/fd_sched.h +++ b/src/discof/replay/fd_sched.h @@ -2,11 +2,12 @@ #define HEADER_fd_src_discof_replay_fd_sched_h #include "fd_rdisp.h" -#include "../../disco/store/fd_store.h" /* for fd_store_fec_t */ +#include "../../disco/store/fd_store.h" /* for fd_store_fec_t */ #include "../../disco/pack/fd_microblock.h" /* for fd_txn_p_t */ -#include "../../funk/fd_funk_base.h" /* for ALUTs */ -#include "../../util/spad/fd_spad.h" /* for ALUTs */ +#include "../../funk/fd_funk_base.h" /* for ALUTs */ +#include "../../util/spad/fd_spad.h" /* for ALUTs */ +#include "../../flamenco/runtime/sysvar/fd_sysvar_slot_hashes.h" /* for ALUTs*/ /* fd_sched wraps all the smarts and mechanical chores around scheduling transactions for replay execution. It is built on top of the @@ -58,7 +59,7 @@ struct fd_sched_alut_ctx { fd_funk_t * funk; fd_funk_txn_xid_t xid[1]; ulong els; /* Effective lookup slot. */ - fd_spad_t * runtime_spad; + uchar slot_hashes_mem[ FD_SYSVAR_SLOT_HASHES_DECODE_FOOTPRINT ]; }; typedef struct fd_sched_alut_ctx fd_sched_alut_ctx_t; diff --git a/src/flamenco/fd_flamenco_base.h b/src/flamenco/fd_flamenco_base.h index 1b27f18474..3156561b8e 100644 --- a/src/flamenco/fd_flamenco_base.h +++ b/src/flamenco/fd_flamenco_base.h @@ -96,6 +96,9 @@ typedef struct fd_borrowed_account fd_borrowed_account_t; struct fd_txn_account; typedef struct fd_txn_account fd_txn_account_t; +struct fd_runtime_mem; +typedef struct fd_runtime_mem fd_runtime_mem_t; + struct fd_account_meta { uchar owner[32]; ulong lamports; diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index 0cd00aac06..9fa7270e1b 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -662,9 +662,10 @@ calculate_validator_rewards( fd_bank_t * bank, ulong rewarded_epoch, ulong rewards, fd_calculate_validator_rewards_result_t * result, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2759-L2786 */ - fd_stake_history_t const * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + fd_stake_history_t const * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_mem->stake_history_mem ); if( FD_UNLIKELY( !stake_history ) ) { FD_LOG_ERR(( "Unable to read and decode stake history sysvar" )); } @@ -774,7 +775,8 @@ calculate_rewards_for_partitioning( fd_bank_t * bank, ulong prev_epoch, const fd_hash_t * parent_blockhash, fd_partitioned_rewards_calculation_t * result, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L227 */ fd_prev_epoch_inflation_rewards_t rewards; @@ -792,7 +794,8 @@ calculate_rewards_for_partitioning( fd_bank_t * bank, prev_epoch, rewards.validator_rewards, validator_result, - runtime_spad ); + runtime_spad, + runtime_mem ); fd_stake_reward_calculation_t * stake_reward_calculation = &validator_result->calculate_stake_vote_rewards_result.stake_reward_calculation; fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank ); @@ -831,7 +834,8 @@ calculate_rewards_and_distribute_vote_rewards( fd_bank_t * ba fd_capture_ctx_t * capture_ctx, ulong prev_epoch, fd_hash_t const * parent_blockhash, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2406-L2492 */ fd_partitioned_rewards_calculation_t rewards_calc_result[1] = {0}; @@ -843,7 +847,8 @@ calculate_rewards_and_distribute_vote_rewards( fd_bank_t * ba prev_epoch, parent_blockhash, rewards_calc_result, - runtime_spad ); + runtime_spad, + runtime_mem ); /* Iterate over all the vote reward nodes */ ulong distributed_rewards = 0UL; @@ -1137,7 +1142,8 @@ fd_begin_partitioned_rewards( fd_bank_t * bank, fd_stake_delegations_t const * stake_delegations, fd_hash_t const * parent_blockhash, ulong parent_epoch, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L55 */ calculate_rewards_and_distribute_vote_rewards( @@ -1148,7 +1154,8 @@ fd_begin_partitioned_rewards( fd_bank_t * bank, capture_ctx, parent_epoch, parent_blockhash, - runtime_spad ); + runtime_spad, + runtime_mem ); /* https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L62 */ ulong distribution_starting_block_height = fd_bank_block_height_get( bank ) + REWARD_CALCULATION_NUM_BLOCKS; @@ -1184,7 +1191,8 @@ fd_rewards_recalculate_partitioned_rewards( fd_banks_t * banks, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { FD_SPAD_FRAME_BEGIN( runtime_spad ) { fd_sysvar_epoch_rewards_t epoch_rewards[1]; @@ -1221,7 +1229,7 @@ fd_rewards_recalculate_partitioned_rewards( fd_banks_t * banks, new_warmup_cooldown_rate_epoch = NULL; } - fd_stake_history_t const * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + fd_stake_history_t const * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_mem->stake_history_mem ); if( FD_UNLIKELY( !stake_history ) ) { FD_LOG_ERR(( "Unable to read and decode stake history sysvar" )); } diff --git a/src/flamenco/rewards/fd_rewards.h b/src/flamenco/rewards/fd_rewards.h index 4deac6f38c..575b9cf53e 100644 --- a/src/flamenco/rewards/fd_rewards.h +++ b/src/flamenco/rewards/fd_rewards.h @@ -35,7 +35,8 @@ fd_begin_partitioned_rewards( fd_bank_t * bank, fd_stake_delegations_t const * stake_delegations, fd_hash_t const * parent_blockhash, ulong parent_epoch, - fd_spad_t * runtime_spad ); + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ); /* fd_rewards_recalculate_partitioned_rewards restores epoch bank stake and account reward calculations. Does not update accounts. Called @@ -54,7 +55,8 @@ fd_rewards_recalculate_partitioned_rewards( fd_banks_t * banks, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ); + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ); /* fd_distribute_partitioned_epoch_rewards pays out rewards to stake accounts. Called at the beginning of a few slots per epoch. diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 77cdab4b56..ab5fa823e9 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -116,9 +116,7 @@ fd_runtime_update_slots_per_epoch( fd_bank_t * bank, void fd_runtime_update_leaders( fd_bank_t * bank, - fd_spad_t * runtime_spad ) { - - FD_SPAD_FRAME_BEGIN( runtime_spad ) { + uchar * epoch_weights_mem ) { fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank ); @@ -127,8 +125,7 @@ fd_runtime_update_leaders( fd_bank_t * bank, ulong slot_cnt = fd_epoch_slot_cnt( epoch_schedule, epoch ); fd_vote_states_t const * vote_states_prev_prev = fd_bank_vote_states_prev_prev_locking_query( bank ); - ulong vote_acc_cnt = fd_vote_states_cnt( vote_states_prev_prev ) ; - fd_vote_stake_weight_t * epoch_weights = fd_spad_alloc_check( runtime_spad, alignof(fd_vote_stake_weight_t), vote_acc_cnt * sizeof(fd_vote_stake_weight_t) ); + fd_vote_stake_weight_t * epoch_weights = fd_type_pun( epoch_weights_mem ); ulong stake_weight_cnt = fd_stake_weights_by_node( vote_states_prev_prev, epoch_weights ); fd_bank_vote_states_prev_prev_end_locking_query( bank ); @@ -146,9 +143,8 @@ fd_runtime_update_leaders( fd_bank_t * bank, } ulong vote_keyed_lsched = (ulong)fd_runtime_should_use_vote_keyed_leader_schedule( bank ); - void * epoch_leaders_mem = fd_bank_epoch_leaders_locking_modify( bank ); fd_epoch_leaders_t * leaders = fd_epoch_leaders_join( fd_epoch_leaders_new( - epoch_leaders_mem, + fd_bank_epoch_leaders_locking_modify( bank ), epoch, slot0, slot_cnt, @@ -161,7 +157,6 @@ fd_runtime_update_leaders( fd_bank_t * bank, } fd_bank_epoch_leaders_end_locking_modify( bank ); } - } FD_SPAD_FRAME_END; } /******************************************************************************/ @@ -436,28 +431,24 @@ fd_runtime_block_sysvar_update_pre_execute( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ) { + fd_runtime_mem_t * runtime_mem ) { // let (fee_rate_governor, fee_components_time_us) = measure_us!( // FeeRateGovernor::new_derived(&parent.fee_rate_governor, parent.signature_count()) // ); /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L1312-L1314 */ - FD_SPAD_FRAME_BEGIN( runtime_spad ) { - fd_runtime_new_fee_rate_governor_derived( bank, fd_bank_parent_signature_cnt_get( bank ) ); fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank ); ulong parent_epoch = fd_slot_to_epoch( epoch_schedule, fd_bank_parent_slot_get( bank ), NULL ); - fd_sysvar_clock_update( bank, funk, xid, capture_ctx, runtime_spad, &parent_epoch ); + fd_sysvar_clock_update( bank, funk, xid, capture_ctx, runtime_mem->clock_ts_pool_mem, &parent_epoch ); // It has to go into the current txn previous info but is not in slot 0 if( fd_bank_slot_get( bank ) != 0 ) { - fd_sysvar_slot_hashes_update( bank, funk, xid, capture_ctx, runtime_spad ); + fd_sysvar_slot_hashes_update( bank, funk, xid, capture_ctx, runtime_mem->slot_hashes_mem ); } fd_sysvar_last_restart_slot_update( bank, funk, xid, capture_ctx, fd_bank_last_restart_slot_get( bank ).slot ); - } FD_SPAD_FRAME_END; - return 0; } @@ -696,7 +687,7 @@ fd_runtime_block_execute_prepare( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ) { + fd_runtime_mem_t * runtime_mem ) { fd_bank_execution_fees_set( bank, 0UL ); fd_bank_priority_fees_set( bank, 0UL ); @@ -716,7 +707,7 @@ fd_runtime_block_execute_prepare( fd_bank_t * bank, } fd_bank_cost_tracker_end_locking_modify( bank ); - int result = fd_runtime_block_sysvar_update_pre_execute( bank, funk, xid, capture_ctx, runtime_spad ); + int result = fd_runtime_block_sysvar_update_pre_execute( bank, funk, xid, capture_ctx, runtime_mem ); if( FD_UNLIKELY( result != 0 ) ) { FD_LOG_WARNING(("updating sysvars failed")); return result; @@ -1488,7 +1479,8 @@ fd_runtime_process_new_epoch( fd_banks_t * banks, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, ulong parent_epoch, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { FD_LOG_NOTICE(( "fd_process_new_epoch start, epoch: %lu, slot: %lu", fd_bank_epoch_get( bank ), fd_bank_slot_get( bank ) )); FD_SPAD_FRAME_BEGIN( runtime_spad ) { @@ -1526,11 +1518,11 @@ fd_runtime_process_new_epoch( fd_banks_t * banks, } /* Updates stake history sysvar accumulated values. */ - fd_stakes_activate_epoch( bank, funk, xid, capture_ctx, stake_delegations, new_rate_activation_epoch, runtime_spad ); + fd_stakes_activate_epoch( bank, funk, xid, capture_ctx, stake_delegations, new_rate_activation_epoch, runtime_mem->stake_history_mem ); /* Refresh vote accounts in stakes cache using updated stake weights, and merges slot bank vote accounts with the epoch bank vote accounts. https://github.com/anza-xyz/agave/blob/v2.1.6/runtime/src/stakes.rs#L363-L370 */ - fd_stake_history_t const * history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + fd_stake_history_t const * history = fd_sysvar_stake_history_read( funk, xid, runtime_mem->stake_history_mem ); if( FD_UNLIKELY( !history ) ) { FD_LOG_ERR(( "StakeHistory sysvar could not be read and decoded" )); } @@ -1561,7 +1553,8 @@ fd_runtime_process_new_epoch( fd_banks_t * banks, stake_delegations, &parent_blockhash, parent_epoch, - runtime_spad ); + runtime_spad, + runtime_mem ); /* Update vote_states_prev_prev with vote_states_prev */ @@ -1574,7 +1567,7 @@ fd_runtime_process_new_epoch( fd_banks_t * banks, /* Update current leaders using epoch_stakes (new T-2 stakes) */ - fd_runtime_update_leaders( bank, runtime_spad ); + fd_runtime_update_leaders( bank, runtime_mem->epoch_weights_mem ); FD_LOG_NOTICE(( "fd_process_new_epoch end" )); @@ -1601,23 +1594,21 @@ fd_runtime_update_program_cache( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_txn_p_t const * txn_p, - fd_spad_t * runtime_spad ) { + fd_runtime_mem_t * runtime_mem ) { fd_txn_t const * txn_descriptor = TXN( txn_p ); - FD_SPAD_FRAME_BEGIN( runtime_spad ) { - /* Iterate over account keys referenced directly in the transaction first */ fd_acct_addr_t const * acc_addrs = fd_txn_get_acct_addrs( txn_descriptor, txn_p ); for( ushort acc_idx=0; acc_idxacct_addr_cnt; acc_idx++ ) { fd_pubkey_t const * account = fd_type_pun_const( &acc_addrs[acc_idx] ); - fd_program_cache_update_program( bank, funk, xid, account, runtime_spad ); + fd_program_cache_update_program( bank, funk, xid, account, runtime_mem ); } if( txn_descriptor->transaction_version==FD_TXN_V0 ) { /* Iterate over account keys referenced in ALUTs */ fd_acct_addr_t alut_accounts[256]; - fd_slot_hashes_global_t const * slot_hashes_global = fd_sysvar_slot_hashes_read( funk, xid, runtime_spad ); + fd_slot_hashes_global_t const * slot_hashes_global = fd_sysvar_slot_hashes_read( funk, xid, runtime_mem->slot_hashes_mem ); if( FD_UNLIKELY( !slot_hashes_global ) ) { return; } @@ -1642,11 +1633,9 @@ fd_runtime_update_program_cache( fd_bank_t * bank, for( ushort alut_idx=0; alut_idxaddr_table_adtl_cnt; alut_idx++ ) { fd_pubkey_t const * account = fd_type_pun_const( &alut_accounts[alut_idx] ); - fd_program_cache_update_program( bank, funk, xid, account, runtime_spad ); + fd_program_cache_update_program( bank, funk, xid, account, runtime_mem ); } } - - } FD_SPAD_FRAME_END; } /******************************************************************************/ @@ -1680,7 +1669,8 @@ fd_runtime_init_bank_from_genesis( fd_banks_t * banks, fd_funk_txn_xid_t const * xid, fd_genesis_solana_global_t const * genesis_block, fd_hash_t const * genesis_hash, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { fd_bank_poh_set( bank, *genesis_hash ); @@ -1826,7 +1816,7 @@ fd_runtime_init_bank_from_genesis( fd_banks_t * banks, the amount of stake that is delegated to each vote account. */ ulong new_rate_activation_epoch = 0UL; - fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_mem->stake_history_mem ); fd_refresh_vote_accounts( bank, stake_delegations, @@ -1878,7 +1868,8 @@ fd_runtime_process_genesis_block( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { fd_hash_t * poh = fd_bank_poh_modify( bank ); ulong hashcnt_per_slot = fd_bank_hashes_per_tick_get( bank ) * fd_bank_ticks_per_slot_get( bank ); @@ -1904,7 +1895,7 @@ fd_runtime_process_genesis_block( fd_bank_t * bank, fd_sysvar_slot_history_update( bank, funk, xid, capture_ctx ); - fd_runtime_update_leaders( bank, runtime_spad ); + fd_runtime_update_leaders( bank, runtime_mem->epoch_weights_mem ); fd_runtime_freeze( bank, funk, xid, capture_ctx ); @@ -1934,7 +1925,8 @@ fd_runtime_read_genesis( fd_banks_t * banks, fd_hash_t const * genesis_hash, fd_lthash_value_t const * genesis_lthash, fd_genesis_solana_global_t const * genesis_block, - fd_spad_t * runtime_spad ) { + fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem ) { FD_SPAD_FRAME_BEGIN( runtime_spad ) { fd_lthash_value_t * lthash = fd_bank_lthash_locking_modify( bank ); @@ -1946,7 +1938,7 @@ fd_runtime_read_genesis( fd_banks_t * banks, setting some fields, and notably setting up the vote and stake caches which are used for leader scheduling/rewards. */ - fd_runtime_init_bank_from_genesis( banks, bank, funk, xid, genesis_block, genesis_hash, runtime_spad ); + fd_runtime_init_bank_from_genesis( banks, bank, funk, xid, genesis_block, genesis_hash, runtime_spad, runtime_mem ); /* Write the native programs to the accounts db. */ @@ -1966,7 +1958,7 @@ fd_runtime_read_genesis( fd_banks_t * banks, block. In practice, this updates some bank fields (notably the poh and bank hash). */ - int err = fd_runtime_process_genesis_block( bank, funk, xid, capture_ctx, runtime_spad ); + int err = fd_runtime_process_genesis_block( bank, funk, xid, capture_ctx, runtime_spad, runtime_mem ); if( FD_UNLIKELY( err ) ) FD_LOG_CRIT(( "genesis slot 0 execute failed with error %d", err )); } FD_SPAD_FRAME_END; @@ -1987,6 +1979,7 @@ fd_runtime_block_pre_execute_process_new_epoch( fd_banks_t * banks, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, fd_spad_t * runtime_spad, + fd_runtime_mem_t * runtime_mem, int * is_epoch_boundary ) { ulong const slot = fd_bank_slot_get( bank ); @@ -2003,7 +1996,7 @@ fd_runtime_block_pre_execute_process_new_epoch( fd_banks_t * banks, if( FD_UNLIKELY( prev_epochsbpf_program_mem, fd_sbpf_program_align() ) ); + fd_sbpf_program_t * prog = fd_sbpf_program_new( runtime_mem->sbpf_program_mem, elf_info, fd_program_cache_get_rodata( cache_entry ) ); if( FD_UNLIKELY( !prog ) ) { FD_LOG_DEBUG(( "fd_sbpf_program_new() failed" )); cache_entry->failed_verification = 1; @@ -268,9 +266,8 @@ fd_program_cache_validate_sbpf_program( fd_bank_t * bank, } /* Allocate syscalls */ - - void * syscalls_mem = fd_spad_alloc_check( runtime_spad, fd_sbpf_syscalls_align(), fd_sbpf_syscalls_footprint() ); - fd_sbpf_syscalls_t * syscalls = fd_sbpf_syscalls_join( fd_sbpf_syscalls_new( syscalls_mem ) ); + FD_TEST( fd_ulong_is_aligned( (ulong)runtime_mem->syscalls_mem, fd_sbpf_syscalls_align() ) ); + fd_sbpf_syscalls_t * syscalls = fd_sbpf_syscalls_join( fd_sbpf_syscalls_new( runtime_mem->syscalls_mem ) ); if( FD_UNLIKELY( !syscalls ) ) { FD_LOG_CRIT(( "Call to fd_sbpf_syscalls_new() failed" )); } @@ -382,73 +379,71 @@ fd_program_cache_create_cache_entry( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_txn_account_t const * program_acc, - fd_spad_t * runtime_spad ) { - FD_SPAD_FRAME_BEGIN( runtime_spad ) { - ulong current_slot = fd_bank_slot_get( bank ); - - /* Prepare the funk record for the program cache. */ - fd_pubkey_t const * program_pubkey = program_acc->pubkey; - fd_funk_rec_key_t id = fd_program_cache_key( program_pubkey ); - - /* Try to get the programdata for the account. If it doesn't exist, - simply return without publishing anything. The program could have - been closed, but we do not want to touch the cache in this case. */ - ulong program_data_len = 0UL; - uchar const * program_data = fd_program_cache_get_account_programdata( funk, xid, program_acc, &program_data_len ); - - /* This prepare should never fail. */ - int funk_err = FD_FUNK_SUCCESS; - fd_funk_rec_prepare_t prepare[1]; - fd_funk_rec_t * rec = fd_funk_rec_prepare( funk, xid, &id, prepare, &funk_err ); - if( rec == NULL || funk_err != FD_FUNK_SUCCESS ) { - FD_LOG_CRIT(( "fd_funk_rec_prepare() failed: %i-%s", funk_err, fd_funk_strerror( funk_err ) )); - } + fd_runtime_mem_t * runtime_mem ) { + ulong current_slot = fd_bank_slot_get( bank ); - /* In Agave's load_program_with_pubkey(), if program data cannot be - obtained, a tombstone cache entry of type Closed or - FailedVerification is created. For correctness, we could just - not insert a cache entry when there is no valid program data. - Nonetheless, for purely conformance on instruction error log - messages reasons, specifically "Program is not deployed" vs - "Program is not cached", we would like to have a cache entry - precisely when Agave does, such that we match Agave exactly on - this error log. So, we insert a cache entry here. */ - if( FD_UNLIKELY( program_data==NULL ) ) { - fd_program_cache_publish_failed_verification_rec( funk, prepare, rec, current_slot ); - return; - } + /* Prepare the funk record for the program cache. */ + fd_pubkey_t const * program_pubkey = program_acc->pubkey; + fd_funk_rec_key_t id = fd_program_cache_key( program_pubkey ); - fd_sbpf_elf_info_t elf_info = {0}; - if( FD_UNLIKELY( fd_program_cache_parse_elf_info( bank, &elf_info, program_data, program_data_len ) ) ) { - fd_program_cache_publish_failed_verification_rec( funk, prepare, rec, current_slot ); - return; - } + /* Try to get the programdata for the account. If it doesn't exist, + simply return without publishing anything. The program could have + been closed, but we do not want to touch the cache in this case. */ + ulong program_data_len = 0UL; + uchar const * program_data = fd_program_cache_get_account_programdata( funk, xid, program_acc, &program_data_len ); + + /* This prepare should never fail. */ + int funk_err = FD_FUNK_SUCCESS; + fd_funk_rec_prepare_t prepare[1]; + fd_funk_rec_t * rec = fd_funk_rec_prepare( funk, xid, &id, prepare, &funk_err ); + if( rec == NULL || funk_err != FD_FUNK_SUCCESS ) { + FD_LOG_CRIT(( "fd_funk_rec_prepare() failed: %i-%s", funk_err, fd_funk_strerror( funk_err ) )); + } - ulong val_sz = fd_program_cache_entry_footprint( &elf_info ); - void * val = fd_funk_val_truncate( - rec, - fd_funk_alloc( funk ), - fd_funk_wksp( funk ), - 0UL, - val_sz, - &funk_err ); - if( FD_UNLIKELY( funk_err ) ) { - FD_LOG_ERR(( "fd_funk_val_truncate(sz=%lu) for account failed (%i-%s)", val_sz, funk_err, fd_funk_strerror( funk_err ) )); - } + /* In Agave's load_program_with_pubkey(), if program data cannot be + obtained, a tombstone cache entry of type Closed or + FailedVerification is created. For correctness, we could just + not insert a cache entry when there is no valid program data. + Nonetheless, for purely conformance on instruction error log + messages reasons, specifically "Program is not deployed" vs + "Program is not cached", we would like to have a cache entry + precisely when Agave does, such that we match Agave exactly on + this error log. So, we insert a cache entry here. */ + if( FD_UNLIKELY( program_data==NULL ) ) { + fd_program_cache_publish_failed_verification_rec( funk, prepare, rec, current_slot ); + return; + } - /* Note that the cache entry points to the funk record data - and writes into the record directly to avoid an expensive memcpy. - Since this record is fresh, we should set the last slot modified - to 0. */ - fd_program_cache_entry_t * cache_entry = fd_program_cache_entry_new( val, &elf_info, 0UL, current_slot ); - int res = fd_program_cache_validate_sbpf_program( bank, &elf_info, program_data, program_data_len, runtime_spad, cache_entry ); - if( FD_UNLIKELY( res ) ) { - fd_program_cache_publish_failed_verification_rec( funk, prepare, rec, current_slot ); - return; - } + fd_sbpf_elf_info_t elf_info = {0}; + if( FD_UNLIKELY( fd_program_cache_parse_elf_info( bank, &elf_info, program_data, program_data_len ) ) ) { + fd_program_cache_publish_failed_verification_rec( funk, prepare, rec, current_slot ); + return; + } - fd_funk_rec_publish( funk, prepare ); - } FD_SPAD_FRAME_END; + ulong val_sz = fd_program_cache_entry_footprint( &elf_info ); + void * val = fd_funk_val_truncate( + rec, + fd_funk_alloc( funk ), + fd_funk_wksp( funk ), + 0UL, + val_sz, + &funk_err ); + if( FD_UNLIKELY( funk_err ) ) { + FD_LOG_ERR(( "fd_funk_val_truncate(sz=%lu) for account failed (%i-%s)", val_sz, funk_err, fd_funk_strerror( funk_err ) )); + } + + /* Note that the cache entry points to the funk record data + and writes into the record directly to avoid an expensive memcpy. + Since this record is fresh, we should set the last slot modified + to 0. */ + fd_program_cache_entry_t * cache_entry = fd_program_cache_entry_new( val, &elf_info, 0UL, current_slot ); + int res = fd_program_cache_validate_sbpf_program( bank, &elf_info, program_data, program_data_len, runtime_mem, cache_entry ); + if( FD_UNLIKELY( res ) ) { + fd_program_cache_publish_failed_verification_rec( funk, prepare, rec, current_slot ); + return; + } + + fd_funk_rec_publish( funk, prepare ); } int @@ -499,8 +494,7 @@ fd_program_cache_update_program( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_pubkey_t const * program_key, - fd_spad_t * runtime_spad ) { -FD_SPAD_FRAME_BEGIN( runtime_spad ) { + fd_runtime_mem_t * runtime_mem ) { FD_TXN_ACCOUNT_DECL( exec_rec ); fd_funk_rec_key_t id = fd_program_cache_key( program_key ); @@ -525,7 +519,7 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) { fd_program_cache_entry_t const * existing_entry = NULL; int err = fd_program_cache_load_entry( funk, xid, program_key, &existing_entry ); if( FD_UNLIKELY( err ) ) { - fd_program_cache_create_cache_entry( bank, funk, xid, exec_rec, runtime_spad ); + fd_program_cache_create_cache_entry( bank, funk, xid, exec_rec, runtime_mem ); return; } @@ -600,7 +594,7 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) { accordingly. We publish the funk record regardless of the return code. */ writable_entry = fd_program_cache_entry_new( data, &elf_info, last_slot_modified, current_slot ); - int res = fd_program_cache_validate_sbpf_program( bank, &elf_info, program_data, program_data_len, runtime_spad, writable_entry ); + int res = fd_program_cache_validate_sbpf_program( bank, &elf_info, program_data, program_data_len, runtime_mem, writable_entry ); if( FD_UNLIKELY( res ) ) { FD_LOG_DEBUG(( "fd_program_cache_validate_sbpf_program() failed" )); } @@ -608,7 +602,6 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) { fd_funk_rec_insert_para( funk, xid, &id, alignof(fd_program_cache_entry_t), record_sz, writable_entry ); -} FD_SPAD_FRAME_END; } void diff --git a/src/flamenco/runtime/program/fd_program_cache.h b/src/flamenco/runtime/program/fd_program_cache.h index 3e4b63bd59..8658e66cfd 100644 --- a/src/flamenco/runtime/program/fd_program_cache.h +++ b/src/flamenco/runtime/program/fd_program_cache.h @@ -282,7 +282,7 @@ fd_program_cache_update_program( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_pubkey_t const * program_key, - fd_spad_t * runtime_spad ); + fd_runtime_mem_t * runtime_mem ); /* Queues a single program account for reverification. This function queries the cache for an existing entry and queues it for diff --git a/src/flamenco/runtime/program/test_program_cache.c b/src/flamenco/runtime/program/test_program_cache.c index 069f895efd..ad2cd0f29b 100644 --- a/src/flamenco/runtime/program/test_program_cache.c +++ b/src/flamenco/runtime/program/test_program_cache.c @@ -20,12 +20,13 @@ static fd_pubkey_t const test_program_pubkey = { static ulong const SPAD_MEM_MAX = 100UL << 20; /* 100MB */ /* Test setup and teardown helpers */ -static fd_wksp_t * test_wksp = NULL; -static fd_funk_t * test_funk = NULL; -static fd_spad_t * test_spad = NULL; -static fd_bank_t * test_bank = NULL; -static fd_banks_t * test_banks = NULL; -static fd_funk_txn_xid_t test_xid = {0}; +static fd_wksp_t * test_wksp = NULL; +static fd_funk_t * test_funk = NULL; +static fd_spad_t * test_spad = NULL; +static fd_bank_t * test_bank = NULL; +static fd_banks_t * test_banks = NULL; +static fd_runtime_mem_t * test_runtime_mem = NULL; +static fd_funk_txn_xid_t test_xid = {0}; static void test_teardown( void ) { @@ -117,7 +118,7 @@ test_account_does_not_exist( void ) { fd_pubkey_t const non_existent_pubkey = {0}; /* This should return early without doing anything */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &non_existent_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &non_existent_pubkey, test_runtime_mem ); /* Verify no cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -142,7 +143,7 @@ test_account_not_bpf_loader_owner( void ) { 1 ); /* This should return early without doing anything */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify no cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -167,7 +168,7 @@ test_invalid_program_not_in_cache_first_time( void ) { 1 ); /* This should create a cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -196,7 +197,7 @@ test_valid_program_not_in_cache_first_time( void ) { 1 ); /* This should create a cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -226,7 +227,7 @@ test_program_in_cache_needs_reverification( void ) { 1 ); /* First call to create cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -242,7 +243,7 @@ test_program_in_cache_needs_reverification( void ) { fd_bank_slot_set( test_bank, fd_bank_slot_get( test_bank ) + 432000UL ); /* This should trigger reverification */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify the cache entry was updated */ err = fd_program_cache_load_entry( test_funk, &test_xid, &test_program_pubkey, &valid_prog ); @@ -272,7 +273,7 @@ test_program_in_cache_queued_for_reverification( void ) { 1 ); /* First call to create cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -308,7 +309,7 @@ test_program_in_cache_queued_for_reverification( void ) { FD_TEST( valid_prog->last_slot_modified>original_slot ); /* Reverify the cache entry at the future slot */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify the cache entry was updated */ err = fd_program_cache_load_entry( test_funk, &test_xid, &test_program_pubkey, &valid_prog ); @@ -376,7 +377,7 @@ test_program_in_cache_queued_for_reverification_and_processed( void ) { 1 ); /* First call to create cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -417,7 +418,7 @@ test_program_in_cache_queued_for_reverification_and_processed( void ) { FD_TEST( future_update_slot>future_slot ); /* Now update the cache entry at the future slot */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify the cache entry was updated */ err = fd_program_cache_load_entry( test_funk, &test_xid, &test_program_pubkey, &valid_prog ); @@ -447,7 +448,7 @@ test_invalid_genesis_program_reverified_after_genesis( void ) { 1 ); /* First call to create cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -466,7 +467,7 @@ test_invalid_genesis_program_reverified_after_genesis( void ) { FD_TEST( future_slot>original_slot ); /* Program invoked, update cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify the cache entry was updated */ err = fd_program_cache_load_entry( test_funk, &test_xid, &test_program_pubkey, &valid_prog ); @@ -497,7 +498,7 @@ test_valid_genesis_program_reverified_after_genesis( void ) { 1 ); /* First call to create cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -516,7 +517,7 @@ test_valid_genesis_program_reverified_after_genesis( void ) { FD_TEST( future_slot>original_slot ); /* Program invoked, update cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify the cache entry was updated */ err = fd_program_cache_load_entry( test_funk, &test_xid, &test_program_pubkey, &valid_prog ); @@ -546,7 +547,7 @@ test_program_upgraded_with_larger_programdata( void ) { 1 ); /* First call to create cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Verify cache entry was created */ fd_program_cache_entry_t const * valid_prog = NULL; @@ -589,7 +590,7 @@ test_program_upgraded_with_larger_programdata( void ) { FD_TEST( !fd_funk_rec_query_test( query ) ); /* Program invoked, update cache entry */ - fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_spad ); + fd_program_cache_update_program( test_bank, test_funk, &test_xid, &test_program_pubkey, test_runtime_mem ); /* Get the new program cache funk record size, and make sure it's larger */ @@ -641,6 +642,9 @@ main( int argc, void * spad_mem = fd_wksp_alloc_laddr( test_wksp, spad_align, spad_footprint, TEST_WKSP_TAG ); FD_TEST( spad_mem ); + test_runtime_mem = fd_wksp_alloc_laddr( test_wksp, alignof(fd_runtime_mem_t), sizeof(fd_runtime_mem_t), TEST_WKSP_TAG ); + FD_TEST( test_runtime_mem ); + test_spad = fd_spad_join( fd_spad_new( spad_mem, SPAD_MEM_MAX ) ); FD_TEST( test_spad ); diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_clock.c b/src/flamenco/runtime/sysvar/fd_sysvar_clock.c index 4b5d5783d8..60074e3298 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_clock.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_clock.c @@ -137,8 +137,7 @@ FD_FN_CONST static inline int valcmp (VAL_T a, VAL_T b) { long get_timestamp_estimate( fd_bank_t * bank, fd_sol_sysvar_clock_t * clock, - fd_spad_t * spad ) { - FD_SPAD_FRAME_BEGIN( spad ) { + uchar * pool_mem ) { fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank ); ulong slot_duration = (ulong)fd_bank_ns_per_slot_get( bank ); @@ -148,13 +147,12 @@ get_timestamp_estimate( fd_bank_t * bank, This is to establish a mapping between each vote timestamp and the amount of stake associated with each timestamp. */ stake_ts_treap_t _treap[1]; - stake_ts_treap_t * treap = stake_ts_treap_join( stake_ts_treap_new( _treap, FD_RUNTIME_MAX_VOTE_ACCOUNTS ) ); - uchar * pool_mem = fd_spad_alloc( spad, stake_ts_pool_align(), stake_ts_pool_footprint( FD_RUNTIME_MAX_VOTE_ACCOUNTS ) ); - stake_ts_ele_t * pool = stake_ts_pool_join( stake_ts_pool_new( pool_mem, FD_RUNTIME_MAX_VOTE_ACCOUNTS ) ); - uint txn_cnt = (uint)fd_bank_transaction_count_get( bank ); + stake_ts_treap_t * treap = stake_ts_treap_join( stake_ts_treap_new( _treap, FD_RUNTIME_MAX_VOTE_ACCOUNTS ) ); + stake_ts_ele_t * pool = stake_ts_pool_join( stake_ts_pool_new( pool_mem, FD_RUNTIME_MAX_VOTE_ACCOUNTS ) ); + uint txn_cnt = (uint)fd_bank_transaction_count_get( bank ); fd_rng_t _rng[1]; - fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, txn_cnt, 0UL ) ); + fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, txn_cnt, 0UL ) ); /* https://github.com/anza-xyz/agave/blob/v2.3.7/runtime/src/stake_weighted_timestamp.rs#L41 */ uint128 total_stake = 0UL; @@ -279,8 +277,6 @@ get_timestamp_estimate( fd_bank_t * bank, } return estimate; - - } FD_SPAD_FRAME_END; } /* TODO: This function should be called from genesis bootup as well with @@ -291,7 +287,7 @@ fd_sysvar_clock_update( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * spad, + uchar * ts_pool_mem, ulong const * parent_epoch ) { fd_sol_sysvar_clock_t clock_[1]; fd_sol_sysvar_clock_t * clock = fd_sysvar_clock_read( funk, xid, clock_ ); @@ -309,7 +305,7 @@ fd_sysvar_clock_update( fd_bank_t * bank, /* TODO: Are we handling slot 0 correctly? https://github.com/anza-xyz/agave/blob/v2.3.7/runtime/src/bank.rs#L2176-L2183 */ - long timestamp_estimate = get_timestamp_estimate( bank, clock, spad ); + long timestamp_estimate = get_timestamp_estimate( bank, clock, ts_pool_mem ); /* If the timestamp was successfully calculated, use it. It not keep the old one. */ if( FD_LIKELY( timestamp_estimate!=0L ) ) { diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_clock.h b/src/flamenco/runtime/sysvar/fd_sysvar_clock.h index 1448a59e32..ca49d62528 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_clock.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_clock.h @@ -39,7 +39,7 @@ fd_sysvar_clock_update( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * spad, + uchar * ts_pool_mem, ulong const * parent_epoch ); /* Writes the current value of the clock sysvar to funk. */ diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c index bd03d245b2..c0fe1f7d9e 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c @@ -100,52 +100,49 @@ fd_sysvar_slot_hashes_update( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ) { - FD_SPAD_FRAME_BEGIN( runtime_spad ) { - fd_slot_hashes_global_t * slot_hashes_global = fd_sysvar_slot_hashes_read( funk, xid, runtime_spad ); - fd_slot_hash_t * hashes = NULL; - if( FD_UNLIKELY( !slot_hashes_global ) ) { - /* Note: Agave's implementation initializes a new slot_hashes if it doesn't already exist (refer to above URL). */ - void * mem = fd_spad_alloc( runtime_spad, FD_SYSVAR_SLOT_HASHES_ALIGN, fd_sysvar_slot_hashes_footprint( FD_SYSVAR_SLOT_HASHES_CAP ) ); - slot_hashes_global = fd_sysvar_slot_hashes_new( mem, FD_SYSVAR_SLOT_HASHES_CAP ); - } - slot_hashes_global = fd_sysvar_slot_hashes_join( slot_hashes_global, &hashes ); - - uchar found = 0; - for( deq_fd_slot_hash_t_iter_t iter = deq_fd_slot_hash_t_iter_init( hashes ); - !deq_fd_slot_hash_t_iter_done( hashes, iter ); - iter = deq_fd_slot_hash_t_iter_next( hashes, iter ) ) { - fd_slot_hash_t * ele = deq_fd_slot_hash_t_iter_ele( hashes, iter ); - if( ele->slot == fd_bank_parent_slot_get( bank ) ) { - fd_hash_t const * bank_hash = fd_bank_bank_hash_query( bank ); - memcpy( &ele->hash, bank_hash, sizeof(fd_hash_t) ); - found = 1; - } + uchar * slot_hashes_mem ) { + fd_slot_hashes_global_t * slot_hashes_global = fd_sysvar_slot_hashes_read( funk, xid, slot_hashes_mem ); + fd_slot_hash_t * hashes = NULL; + if( FD_UNLIKELY( !slot_hashes_global ) ) { + /* Note: Agave's implementation initializes a new slot_hashes if it doesn't already exist (refer to above URL). */ + slot_hashes_global = fd_sysvar_slot_hashes_new( slot_hashes_mem, FD_SYSVAR_SLOT_HASHES_CAP ); + } + slot_hashes_global = fd_sysvar_slot_hashes_join( slot_hashes_global, &hashes ); + + uchar found = 0; + for( deq_fd_slot_hash_t_iter_t iter = deq_fd_slot_hash_t_iter_init( hashes ); + !deq_fd_slot_hash_t_iter_done( hashes, iter ); + iter = deq_fd_slot_hash_t_iter_next( hashes, iter ) ) { + fd_slot_hash_t * ele = deq_fd_slot_hash_t_iter_ele( hashes, iter ); + if( ele->slot == fd_bank_parent_slot_get( bank ) ) { + fd_hash_t const * bank_hash = fd_bank_bank_hash_query( bank ); + memcpy( &ele->hash, bank_hash, sizeof(fd_hash_t) ); + found = 1; } + } - if( !found ) { - // https://github.com/firedancer-io/solana/blob/08a1ef5d785fe58af442b791df6c4e83fe2e7c74/runtime/src/bank.rs#L2371 - fd_slot_hash_t slot_hash = { - .hash = fd_bank_bank_hash_get( bank ), // parent hash? - .slot = fd_bank_parent_slot_get( bank ), // parent_slot - }; - FD_LOG_DEBUG(( "fd_sysvar_slot_hash_update: slot %lu, hash %s", slot_hash.slot, FD_BASE58_ENC_32_ALLOCA( slot_hash.hash.key ) )); + if( !found ) { + // https://github.com/firedancer-io/solana/blob/08a1ef5d785fe58af442b791df6c4e83fe2e7c74/runtime/src/bank.rs#L2371 + fd_slot_hash_t slot_hash = { + .hash = fd_bank_bank_hash_get( bank ), // parent hash? + .slot = fd_bank_parent_slot_get( bank ), // parent_slot + }; + FD_LOG_DEBUG(( "fd_sysvar_slot_hash_update: slot %lu, hash %s", slot_hash.slot, FD_BASE58_ENC_32_ALLOCA( slot_hash.hash.key ) )); - if( deq_fd_slot_hash_t_full( hashes ) ) - memset( deq_fd_slot_hash_t_pop_tail_nocopy( hashes ), 0, sizeof(fd_slot_hash_t) ); + if( deq_fd_slot_hash_t_full( hashes ) ) + memset( deq_fd_slot_hash_t_pop_tail_nocopy( hashes ), 0, sizeof(fd_slot_hash_t) ); - deq_fd_slot_hash_t_push_head( hashes, slot_hash ); - } + deq_fd_slot_hash_t_push_head( hashes, slot_hash ); + } - fd_sysvar_slot_hashes_write( bank, funk, xid, capture_ctx, slot_hashes_global ); - fd_sysvar_slot_hashes_leave( slot_hashes_global, hashes ); - } FD_SPAD_FRAME_END; + fd_sysvar_slot_hashes_write( bank, funk, xid, capture_ctx, slot_hashes_global ); + fd_sysvar_slot_hashes_leave( slot_hashes_global, hashes ); } fd_slot_hashes_global_t * fd_sysvar_slot_hashes_read( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_spad_t * spad ) { + uchar * slot_hashes_mem ) { FD_TXN_ACCOUNT_DECL( rec ); int err = fd_txn_account_init_from_funk_readonly( rec, (fd_pubkey_t const *)&fd_sysvar_slot_hashes_id, funk, xid ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { @@ -171,11 +168,9 @@ fd_sysvar_slot_hashes_read( fd_funk_t * funk, return NULL; } - uchar * mem = fd_spad_alloc( spad, fd_slot_hashes_align(), total_sz ); - - if( FD_UNLIKELY( !mem ) ) { - FD_LOG_ERR(( "Unable to allocate memory for slot hashes" )); + if( FD_UNLIKELY( total_sz!=FD_SYSVAR_SLOT_HASHES_DECODE_FOOTPRINT ) ) { + FD_LOG_ERR(( "Invalid slot hashes account size: %lu", total_sz )); } - return fd_slot_hashes_decode_global( mem, &decode ); + return fd_slot_hashes_decode_global( slot_hashes_mem, &decode ); } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.h b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.h index 5a0c5e6e1f..02ea0ff7f7 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.h @@ -14,6 +14,8 @@ #define FD_SYSVAR_SLOT_HASHES_CAP (512UL) +#define FD_SYSVAR_SLOT_HASHES_DECODE_FOOTPRINT (20528UL) + FD_PROTOTYPES_BEGIN ulong @@ -55,7 +57,7 @@ fd_sysvar_slot_hashes_update( fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ); + uchar * slot_hashes_mem ); /* fd_sysvar_slot_hashes_read reads the slot hashes sysvar from funk. If the account doesn't exist in funk or if the account has zero @@ -63,7 +65,7 @@ fd_sysvar_slot_hashes_update( fd_bank_t * bank, fd_slot_hashes_global_t * fd_sysvar_slot_hashes_read( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_spad_t * spad ); + uchar * slot_hashes_mem ); FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c index 0a37742fe7..a768b1d8f9 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c @@ -28,7 +28,7 @@ write_stake_history( fd_bank_t * bank, fd_stake_history_t * fd_sysvar_stake_history_read( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_spad_t * spad ) { + uchar * stake_history_mem ) { FD_TXN_ACCOUNT_DECL( stake_rec ); int err = fd_txn_account_init_from_funk_readonly( stake_rec, &fd_sysvar_stake_history_id, funk, xid ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { @@ -43,8 +43,9 @@ fd_sysvar_stake_history_read( fd_funk_t * funk, return NULL; } - return fd_bincode_decode_spad( - stake_history, spad, + return fd_bincode_decode_static( + stake_history, + stake_history_mem, fd_txn_account_get_data( stake_rec ), fd_txn_account_get_data_len( stake_rec ), &err ); @@ -66,11 +67,10 @@ fd_sysvar_stake_history_update( fd_bank_t * bank fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, fd_epoch_stake_history_entry_pair_t const * pair, - fd_spad_t * runtime_spad ) { - FD_SPAD_FRAME_BEGIN( runtime_spad ) { + uchar * stake_history_mem ) { // Need to make this maybe zero copies of map... - fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, xid, stake_history_mem ); if( stake_history->fd_stake_history_offset == 0 ) { stake_history->fd_stake_history_offset = stake_history->fd_stake_history_size - 1; @@ -92,5 +92,4 @@ fd_sysvar_stake_history_update( fd_bank_t * bank write_stake_history( bank, funk, xid, capture_ctx, stake_history ); - } FD_SPAD_FRAME_END; } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h index d5f68f8856..1f5c7184d3 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h @@ -30,7 +30,7 @@ fd_sysvar_stake_history_init( fd_bank_t * bank, fd_stake_history_t * fd_sysvar_stake_history_read( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_spad_t * spad ); + uchar * stake_history_mem ); /* Update the stake history sysvar account - called during epoch boundary */ void @@ -39,7 +39,7 @@ fd_sysvar_stake_history_update( fd_bank_t * bank fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, fd_epoch_stake_history_entry_pair_t const * pair, - fd_spad_t * runtime_spad ); + uchar * stake_history_mem ); FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c b/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c index a2d1ace237..f64cb3d4ce 100644 --- a/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c +++ b/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c @@ -43,9 +43,7 @@ test_sysvar_stake_history_update( fd_wksp_t * wksp ) { fd_bank_epoch_schedule_set( env->bank, schedule ); /* Update should be a no-op if not at the epoch boundary */ - static uchar spad_mem[ FD_SPAD_FOOTPRINT( 1<<17 ) ] __attribute__((aligned(FD_SPAD_ALIGN))); - fd_spad_t * spad = fd_spad_join( fd_spad_new( spad_mem, 1<<17 ) ); - fd_spad_push( spad ); + static uchar stake_history_mem[ FD_SYSVAR_STAKE_HISTORY_FOOTPRINT ] __attribute__((aligned(FD_SYSVAR_STAKE_HISTORY_ALIGN))); fd_bank_slot_set( env->bank, 3UL ); fd_bank_parent_slot_set( env->bank, 2UL ); fd_epoch_stake_history_entry_pair_t const entry0 = { @@ -56,13 +54,13 @@ test_sysvar_stake_history_update( fd_wksp_t * wksp ) { } }; fd_sysvar_stake_history_init( env->bank, env->funk, &env->xid, NULL ); - fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0, spad ); + fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0, stake_history_mem ); fd_sysvar_cache_restore( env->bank, env->funk, &env->xid ); FD_TEST( fd_sysvar_cache_stake_history_is_valid( env->sysvar_cache )==1 ); fd_bank_slot_set( env->bank, 432000UL ); fd_bank_parent_slot_set( env->bank, 431999UL ); - fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0, spad ); + fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0, stake_history_mem ); fd_sysvar_cache_restore( env->bank, env->funk, &env->xid ); FD_TEST( fd_sysvar_cache_stake_history_is_valid( env->sysvar_cache )==1 ); @@ -73,8 +71,6 @@ test_sysvar_stake_history_update( fd_wksp_t * wksp ) { } test_sysvar_cache_env_destroy( env ); - fd_spad_pop( spad ); - fd_spad_delete( fd_spad_leave( spad ) ); } static void diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index dae99f73df..4546b0cd2c 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -168,6 +168,7 @@ fd_runtime_fuzz_block_ctx_destroy( fd_solfuzz_runner_t * runner ) { Returns block_info on success and NULL on failure. */ static fd_runtime_block_info_t * fd_runtime_fuzz_block_ctx_create( fd_solfuzz_runner_t * runner, + fd_runtime_mem_t * runtime_mem, fd_exec_test_block_context_t const * test_ctx ) { fd_funk_t * funk = runner->funk; fd_bank_t * bank = runner->bank; @@ -301,7 +302,7 @@ fd_runtime_fuzz_block_ctx_create( fd_solfuzz_runner_t * runner, /* Refresh the program cache */ - fd_runtime_fuzz_refresh_program_cache( bank, funk, xid, test_ctx->acct_states, test_ctx->acct_states_count, runner->spad ); + fd_runtime_fuzz_refresh_program_cache( bank, funk, xid, test_ctx->acct_states, test_ctx->acct_states_count, runner->runtime_mem ); /* Update vote cache for epoch T-1 */ vote_states_prev = fd_bank_vote_states_prev_locking_modify( bank ); @@ -320,7 +321,7 @@ fd_runtime_fuzz_block_ctx_create( fd_solfuzz_runner_t * runner, fd_bank_vote_states_prev_prev_end_locking_modify( bank ); /* Update leader schedule */ - fd_runtime_update_leaders( bank, runner->spad ); + fd_runtime_update_leaders( bank, runtime_mem->epoch_weights_mem ); /* Initialize the blockhash queue and recent blockhashes sysvar from the input blockhash queue */ ulong blockhash_seed; FD_TEST( fd_rng_secure( &blockhash_seed, sizeof(ulong) ) ); @@ -438,6 +439,7 @@ fd_runtime_fuzz_block_ctx_create( fd_solfuzz_runner_t * runner, and executes it against the runtime. Returns the execution result. */ static int fd_runtime_fuzz_block_ctx_exec( fd_solfuzz_runner_t * runner, + fd_runtime_mem_t * runtime_mem, fd_funk_txn_xid_t const * xid, fd_runtime_block_info_t * block_info ) { int res = 0; @@ -456,14 +458,14 @@ fd_runtime_fuzz_block_ctx_exec( fd_solfuzz_runner_t * runner, fd_solcap_writer_set_slot( capture_ctx->capture, fd_bank_slot_get( runner->bank ) ); } - fd_rewards_recalculate_partitioned_rewards( runner->banks, runner->bank, runner->funk, xid, capture_ctx, runner->spad ); + fd_rewards_recalculate_partitioned_rewards( runner->banks, runner->bank, runner->funk, xid, capture_ctx, runner->spad, runner->runtime_mem ); /* Process new epoch may push a new spad frame onto the runtime spad. We should make sure this frame gets cleared (if it was allocated) before executing the block. */ int is_epoch_boundary = 0; - fd_runtime_block_pre_execute_process_new_epoch( runner->banks, runner->bank, runner->funk, xid, capture_ctx, runner->spad, &is_epoch_boundary ); + fd_runtime_block_pre_execute_process_new_epoch( runner->banks, runner->bank, runner->funk, xid, capture_ctx, runner->spad, runtime_mem, &is_epoch_boundary ); - res = fd_runtime_block_execute_prepare( runner->bank, runner->funk, xid, capture_ctx, runner->spad ); + res = fd_runtime_block_execute_prepare( runner->bank, runner->funk, xid, capture_ctx, runner->runtime_mem ); if( FD_UNLIKELY( res ) ) { return res; } @@ -476,7 +478,7 @@ fd_runtime_fuzz_block_ctx_exec( fd_solfuzz_runner_t * runner, fd_txn_p_t * txn = &txn_ptrs[i]; /* Update the program cache */ - fd_runtime_update_program_cache( runner->bank, runner->funk, xid, txn, runner->spad ); + fd_runtime_update_program_cache( runner->bank, runner->funk, xid, txn, runner->runtime_mem ); /* Execute the transaction against the runtime */ res = FD_RUNTIME_EXECUTE_SUCCESS; @@ -520,8 +522,9 @@ fd_solfuzz_block_run( fd_solfuzz_runner_t * runner, fd_exec_test_block_effects_t ** output = fd_type_pun( output_ ); FD_SPAD_FRAME_BEGIN( runner->spad ) { + /* Set up the block execution context */ - fd_runtime_block_info_t * block_info = fd_runtime_fuzz_block_ctx_create( runner, input ); + fd_runtime_block_info_t * block_info = fd_runtime_fuzz_block_ctx_create( runner, runner->runtime_mem, input ); if( block_info==NULL ) { fd_runtime_fuzz_block_ctx_destroy( runner ); return 0; @@ -530,7 +533,7 @@ fd_solfuzz_block_run( fd_solfuzz_runner_t * runner, fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( runner->bank ), fd_bank_slot_get( runner->bank ) } }; /* Execute the constructed block against the runtime. */ - int res = fd_runtime_fuzz_block_ctx_exec( runner, &xid, block_info ); + int res = fd_runtime_fuzz_block_ctx_exec( runner, runner->runtime_mem, &xid, block_info ); /* Start saving block exec results */ FD_SCRATCH_ALLOC_INIT( l, output_buf ); diff --git a/src/flamenco/runtime/tests/fd_harness_common.c b/src/flamenco/runtime/tests/fd_harness_common.c index bc65069ba3..7ad1312242 100644 --- a/src/flamenco/runtime/tests/fd_harness_common.c +++ b/src/flamenco/runtime/tests/fd_harness_common.c @@ -77,10 +77,10 @@ fd_runtime_fuzz_refresh_program_cache( fd_bank_t * bank, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * acct_states, ulong acct_states_count, - fd_spad_t * runtime_spad ) { + fd_runtime_mem_t * runtime_mem ) { for( ushort i=0; ibank, funk, xid, test_ctx->accounts, test_ctx->accounts_count, runner->spad ); + fd_runtime_fuzz_refresh_program_cache( runner->bank, funk, xid, test_ctx->accounts, test_ctx->accounts_count, runner->runtime_mem ); /* Load instruction accounts */ diff --git a/src/flamenco/runtime/tests/fd_solfuzz.c b/src/flamenco/runtime/tests/fd_solfuzz.c index bf409032b4..cf0d46c7b8 100644 --- a/src/flamenco/runtime/tests/fd_solfuzz.c +++ b/src/flamenco/runtime/tests/fd_solfuzz.c @@ -82,10 +82,11 @@ fd_solfuzz_runner_new( fd_wksp_t * wksp, ulong const spad_max = FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_FUZZ; ulong const bank_max = 1UL; ulong const fork_max = 1UL; - fd_solfuzz_runner_t * runner = fd_wksp_alloc_laddr( wksp, alignof(fd_solfuzz_runner_t), sizeof(fd_solfuzz_runner_t), wksp_tag ); - void * funk_mem = fd_wksp_alloc_laddr( wksp, fd_funk_align(), fd_funk_footprint( txn_max, rec_max ), wksp_tag ); - void * spad_mem = fd_wksp_alloc_laddr( wksp, fd_spad_align(), fd_spad_footprint( spad_max ), wksp_tag ); - void * banks_mem = fd_wksp_alloc_laddr( wksp, fd_banks_align(), fd_banks_footprint( bank_max, fork_max ), wksp_tag ); + fd_solfuzz_runner_t * runner = fd_wksp_alloc_laddr( wksp, alignof(fd_solfuzz_runner_t), sizeof(fd_solfuzz_runner_t), wksp_tag ); + void * funk_mem = fd_wksp_alloc_laddr( wksp, fd_funk_align(), fd_funk_footprint( txn_max, rec_max ), wksp_tag ); + void * spad_mem = fd_wksp_alloc_laddr( wksp, fd_spad_align(), fd_spad_footprint( spad_max ), wksp_tag ); + void * banks_mem = fd_wksp_alloc_laddr( wksp, fd_banks_align(), fd_banks_footprint( bank_max, fork_max ), wksp_tag ); + void * runtime_mem = fd_wksp_alloc_laddr( wksp, alignof(fd_runtime_mem_t), sizeof(fd_runtime_mem_t), wksp_tag ); if( FD_UNLIKELY( !runner ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(solfuzz_runner) failed" )); goto bail1; } if( FD_UNLIKELY( !funk_mem ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(funk) failed" )); goto bail1; } if( FD_UNLIKELY( !spad_mem ) ) { FD_LOG_WARNING(( "fd_wksp_alloc(spad) failed (spad_max=%g)", (double)spad_max )); goto bail1; } @@ -102,10 +103,9 @@ fd_solfuzz_runner_new( fd_wksp_t * wksp, runner->banks = fd_banks_join( fd_banks_new( banks_mem, bank_max, fork_max ) ); if( FD_UNLIKELY( !runner->banks ) ) goto bail2; runner->bank = fd_banks_init_bank( runner->banks ); - if( FD_UNLIKELY( !runner->bank ) ) { - FD_LOG_WARNING(( "fd_banks_init_bank failed" )); - goto bail2; - } + if( FD_UNLIKELY( !runner->bank ) ) goto bail2; + runner->runtime_mem = runtime_mem; + if( FD_UNLIKELY( !runner->runtime_mem ) ) goto bail2; fd_bank_slot_set( runner->bank, 0UL ); runner->enable_vm_tracing = options->enable_vm_tracing; @@ -119,6 +119,7 @@ fd_solfuzz_runner_new( fd_wksp_t * wksp, fd_wksp_free_laddr( funk_mem ); fd_wksp_free_laddr( spad_mem ); fd_wksp_free_laddr( banks_mem ); + fd_wksp_free_laddr( runtime_mem ); fd_wksp_free_laddr( runner ); FD_LOG_WARNING(( "fd_solfuzz_runner_new failed" )); return NULL; diff --git a/src/flamenco/runtime/tests/fd_solfuzz.h b/src/flamenco/runtime/tests/fd_solfuzz.h index b429508bdc..73793a8331 100644 --- a/src/flamenco/runtime/tests/fd_solfuzz.h +++ b/src/flamenco/runtime/tests/fd_solfuzz.h @@ -12,6 +12,7 @@ #include "../../capture/fd_solcap_writer.h" #include "../../../funk/fd_funk.h" +#include "../fd_runtime_const.h" /* A fd_solfuzz_runner_t object processes solfuzz inputs. Can be reused for different inputs, even of different types. Single-thread per @@ -21,11 +22,12 @@ each other (or any other allocations) just fine. */ struct fd_solfuzz_runner { - fd_funk_t funk[1]; - fd_wksp_t * wksp; - fd_spad_t * spad; - fd_banks_t * banks; - fd_bank_t * bank; + fd_funk_t funk[1]; + fd_wksp_t * wksp; + fd_spad_t * spad; + fd_banks_t * banks; + fd_bank_t * bank; + fd_runtime_mem_t * runtime_mem; fd_solcap_writer_t * solcap; void * solcap_file; /* FILE * */ diff --git a/src/flamenco/runtime/tests/fd_solfuzz_private.h b/src/flamenco/runtime/tests/fd_solfuzz_private.h index 9a41cfd97e..3f49ff6cca 100644 --- a/src/flamenco/runtime/tests/fd_solfuzz_private.h +++ b/src/flamenco/runtime/tests/fd_solfuzz_private.h @@ -34,7 +34,7 @@ fd_runtime_fuzz_refresh_program_cache( fd_bank_t * bank, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * acct_states, ulong acct_states_count, - fd_spad_t * runtime_spad ); + fd_runtime_mem_t * runtime_mem ); typedef ulong( exec_test_run_fn_t )( fd_solfuzz_runner_t *, void const *, diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 152ab59323..315f22c0bd 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -112,10 +112,10 @@ fd_runtime_fuzz_txn_ctx_create( fd_solfuzz_runner_t * runner, FD_TEST( rent ); fd_bank_rent_set( runner->bank, *rent ); - fd_slot_hashes_global_t * slot_hashes = fd_sysvar_slot_hashes_read( funk, &xid, runner->spad ); + fd_slot_hashes_global_t * slot_hashes = fd_sysvar_slot_hashes_read( funk, &xid, runner->runtime_mem->slot_hashes_mem ); FD_TEST( slot_hashes ); - fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, &xid, runner->spad ); + fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, &xid, runner->runtime_mem->stake_history_mem ); FD_TEST( stake_history ); fd_sol_sysvar_clock_t clock_[1]; @@ -203,7 +203,7 @@ fd_runtime_fuzz_txn_ctx_create( fd_solfuzz_runner_t * runner, fd_sysvar_cache_restore_fuzz( runner->bank, runner->funk, &xid ); /* Refresh the program cache */ - fd_runtime_fuzz_refresh_program_cache( runner->bank, runner->funk, &xid, test_ctx->account_shared_data, test_ctx->account_shared_data_count, runner->spad ); + fd_runtime_fuzz_refresh_program_cache( runner->bank, runner->funk, &xid, test_ctx->account_shared_data, test_ctx->account_shared_data_count, runner->runtime_mem ); /* Create the raw txn (https://solana.com/docs/core/transactions#transaction-size) */ fd_txn_p_t * txn = fd_spad_alloc( runner->spad, alignof(fd_txn_p_t), sizeof(fd_txn_p_t) ); diff --git a/src/flamenco/stakes/fd_stakes.c b/src/flamenco/stakes/fd_stakes.c index d59bc31ed5..fb4d6c18bb 100644 --- a/src/flamenco/stakes/fd_stakes.c +++ b/src/flamenco/stakes/fd_stakes.c @@ -166,14 +166,14 @@ fd_stakes_activate_epoch( fd_bank_t * bank, fd_capture_ctx_t * capture_ctx, fd_stake_delegations_t const * stake_delegations, ulong * new_rate_activation_epoch, - fd_spad_t * runtime_spad ) { + uchar * stake_history_mem ) { /* Current stake delegations: list of all current delegations in stake_delegations https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/runtime/src/stakes.rs#L180 */ /* Add a new entry to the Stake History sysvar for the previous epoch https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/runtime/src/stakes.rs#L181-L192 */ - fd_stake_history_t const * history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + fd_stake_history_t const * history = fd_sysvar_stake_history_read( funk, xid, stake_history_mem ); if( FD_UNLIKELY( !history ) ) FD_LOG_ERR(( "StakeHistory sysvar is missing from sysvar cache" )); fd_stake_history_entry_t accumulator = { @@ -200,7 +200,7 @@ fd_stakes_activate_epoch( fd_bank_t * bank, } }; - fd_sysvar_stake_history_update( bank, funk, xid, capture_ctx, &new_elem, runtime_spad ); + fd_sysvar_stake_history_update( bank, funk, xid, capture_ctx, &new_elem, stake_history_mem ); } diff --git a/src/flamenco/stakes/fd_stakes.h b/src/flamenco/stakes/fd_stakes.h index fba1bc5be8..e8400a3dad 100644 --- a/src/flamenco/stakes/fd_stakes.h +++ b/src/flamenco/stakes/fd_stakes.h @@ -33,7 +33,7 @@ fd_stakes_activate_epoch( fd_bank_t * bank, fd_capture_ctx_t * capture_ctx, fd_stake_delegations_t const * stake_delegations, ulong * new_rate_activation_epoch, - fd_spad_t * runtime_spad ); + uchar * stake_history_mem ); fd_stake_history_entry_t stake_and_activating( fd_delegation_t const * delegation,