Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] flamenco: move epoch reward status to slot_bank #4402

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 39 additions & 32 deletions src/flamenco/rewards/fd_rewards.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ calculate_stake_vote_rewards_account_tpool( void *tpool,

/* Add the stake reward to list of all stake rewards. The update is thread-safe because each index in the dlist
is only ever accessed / written to once among all threads. */
fd_stake_reward_t * stake_reward = fd_stake_reward_pool_ele( result->stake_reward_calculation.pool, i );
fd_stake_reward_t * stake_reward = fd_stake_reward_calculation_pool_ele( result->stake_reward_calculation.pool, i );
if( FD_UNLIKELY( stake_reward==NULL ) ) {
FD_LOG_WARNING(( "could not find stake reward node in pool" ));
continue;
Expand Down Expand Up @@ -578,12 +578,17 @@ calculate_stake_vote_rewards( fd_exec_slot_ctx_t * slot_ct
ulong rewards_max_count = temp_info->stake_infos_len;

/* Create the stake rewards pool and dlist. The pool will be destoyed after the stake rewards have been distributed. */
result->stake_reward_calculation.pool = fd_stake_reward_pool_join( fd_stake_reward_pool_new( fd_spad_alloc( runtime_spad,
fd_stake_reward_pool_align(),
fd_stake_reward_pool_footprint( rewards_max_count ) ),
rewards_max_count ) );
fd_stake_reward_dlist_new( &result->stake_reward_calculation.stake_rewards );
result->stake_reward_calculation.stake_rewards_len = 0UL;
result->stake_reward_calculation.pool = fd_stake_reward_calculation_pool_join( fd_stake_reward_calculation_pool_new( fd_spad_alloc( runtime_spad,
fd_stake_reward_calculation_pool_align(),
fd_stake_reward_calculation_pool_footprint( rewards_max_count ) ),
rewards_max_count ) );
result->stake_reward_calculation.stake_rewards = fd_spad_alloc( runtime_spad,
fd_stake_reward_calculation_dlist_align(),
fd_stake_reward_calculation_dlist_footprint() );

fd_stake_reward_calculation_dlist_new( result->stake_reward_calculation.stake_rewards );
result->stake_reward_calculation.stake_rewards_len = 1UL;
result->stake_reward_calculation.stake_rewards_lengths[0] = 0;

/* Create the vote rewards map. This will be destroyed after the vote rewards have been distributed. */
ulong vote_account_cnt = fd_vote_info_pair_t_map_size( temp_info->vote_states_pool, temp_info->vote_states_root );
Expand All @@ -610,13 +615,13 @@ calculate_stake_vote_rewards( fd_exec_slot_ctx_t * slot_ct

/* Pre-allocate the dlist stake reward elements */
for( ulong i=0UL; i<temp_info->stake_infos_len; i++ ) {
fd_stake_reward_t * stake_reward = fd_stake_reward_pool_ele_acquire( result->stake_reward_calculation.pool );
fd_stake_reward_t * stake_reward = fd_stake_reward_calculation_pool_ele_acquire( result->stake_reward_calculation.pool );
if( FD_UNLIKELY( stake_reward==NULL ) ) {
FD_LOG_ERR(( "insufficient space allocated for stake reward calculation pool" ));
return;
}
stake_reward->valid = 0;
fd_stake_reward_dlist_ele_push_tail( &result->stake_reward_calculation.stake_rewards, stake_reward, result->stake_reward_calculation.pool );
fd_stake_reward_calculation_dlist_ele_push_tail( result->stake_reward_calculation.stake_rewards, stake_reward, result->stake_reward_calculation.pool );
}

fd_calculate_stake_vote_rewards_task_args_t task_args = {
Expand Down Expand Up @@ -711,25 +716,25 @@ hash_rewards_into_partitions( fd_exec_slot_ctx_t * slot_c
slot_ctx->slot_bank.slot,
stake_reward_calculation->stake_rewards_len );
result->partitioned_stake_rewards.partitions_len = num_partitions;
result->partitioned_stake_rewards.partitions = fd_spad_alloc( runtime_spad,
fd_stake_reward_dlist_align(),
fd_stake_reward_dlist_footprint() * num_partitions );
result->partitioned_stake_rewards.partitions = fd_spad_alloc( runtime_spad,
fd_partitioned_stake_rewards_dlist_align(),
fd_partitioned_stake_rewards_dlist_footprint() * num_partitions );

/* Ownership of these dlist's and the pool gets transferred to stake_rewards_by_partition, which then gets transferred to epoch_reward_status.
These are eventually cleaned up when epoch_reward_status_inactive is called. */
for( ulong i = 0; i < num_partitions; ++i ) {
fd_stake_reward_dlist_new( &result->partitioned_stake_rewards.partitions[ i ] );
fd_partitioned_stake_rewards_dlist_new( &result->partitioned_stake_rewards.partitions[ i ] );
}

/* Iterate over all the stake rewards, moving references to them into the appropiate partitions.
IMPORTANT: after this, we cannot use the original stake rewards dlist anymore. */
fd_stake_reward_dlist_iter_t next_iter;
for( fd_stake_reward_dlist_iter_t iter = fd_stake_reward_dlist_iter_fwd_init( &stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );
!fd_stake_reward_dlist_iter_done( iter, &stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );
fd_stake_reward_calculation_dlist_iter_t next_iter;
for( fd_stake_reward_calculation_dlist_iter_t iter = fd_stake_reward_calculation_dlist_iter_fwd_init( stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );
!fd_stake_reward_calculation_dlist_iter_done( iter, stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );
iter = next_iter ) {
fd_stake_reward_t * stake_reward = fd_stake_reward_dlist_iter_ele( iter, &stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );
fd_stake_reward_t * stake_reward = fd_stake_reward_calculation_dlist_iter_ele( iter, stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );
/* Cache the next iter here, as we will overwrite the DLIST_NEXT value further down in the loop iteration. */
next_iter = fd_stake_reward_dlist_iter_fwd_next( iter, &stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );
next_iter = fd_stake_reward_calculation_dlist_iter_fwd_next( iter, stake_reward_calculation->stake_rewards, stake_reward_calculation->pool );

if( FD_UNLIKELY( !stake_reward->valid ) ) {
continue;
Expand All @@ -750,8 +755,9 @@ hash_rewards_into_partitions( fd_exec_slot_ctx_t * slot_c
((uint128)ULONG_MAX + 1));

/* Move the stake reward to the partition's dlist */
fd_stake_reward_dlist_t * partition = &result->partitioned_stake_rewards.partitions[ partition_index ];
fd_stake_reward_dlist_ele_push_tail( partition, stake_reward, stake_reward_calculation->pool );
fd_partitioned_stake_rewards_dlist_t * partition = &result->partitioned_stake_rewards.partitions[ partition_index ];
fd_partitioned_stake_rewards_dlist_ele_push_tail( partition, stake_reward, stake_reward_calculation->pool );
result->partitioned_stake_rewards.partitions_lengths[ partition_index ]++;
}
}

Expand Down Expand Up @@ -916,11 +922,11 @@ distribute_epoch_reward_to_stake_acc( fd_exec_slot_ctx_t * slot_ctx,
static void
set_epoch_reward_status_inactive( fd_exec_slot_ctx_t * slot_ctx,
fd_spad_t * runtime_spad ) {
if( slot_ctx->epoch_reward_status.discriminant == fd_epoch_reward_status_enum_Active ) {
if( slot_ctx->slot_bank.epoch_reward_status.discriminant == fd_epoch_reward_status_enum_Active ) {
FD_LOG_NOTICE(( "Done partitioning rewards for current epoch" ));
fd_spad_pop( runtime_spad );
}
slot_ctx->epoch_reward_status.discriminant = fd_epoch_reward_status_enum_Inactive;
slot_ctx->slot_bank.epoch_reward_status.discriminant = fd_epoch_reward_status_enum_Inactive;
}

/* Sets the epoch reward status to active.
Expand All @@ -933,28 +939,28 @@ set_epoch_reward_status_active( fd_exec_slot_ctx_t * slot_ctx,
fd_partitioned_stake_rewards_t * partitioned_rewards ) {

FD_LOG_NOTICE(( "Setting epoch reward status as active" ));
slot_ctx->epoch_reward_status.discriminant = fd_epoch_reward_status_enum_Active;
slot_ctx->epoch_reward_status.inner.Active.distribution_starting_block_height = distribution_starting_block_height;
slot_ctx->slot_bank.epoch_reward_status.discriminant = fd_epoch_reward_status_enum_Active;
slot_ctx->slot_bank.epoch_reward_status.inner.Active.distribution_starting_block_height = distribution_starting_block_height;

fd_memcpy( &slot_ctx->epoch_reward_status.inner.Active.partitioned_stake_rewards, partitioned_rewards, FD_PARTITIONED_STAKE_REWARDS_FOOTPRINT );
fd_memcpy( &slot_ctx->slot_bank.epoch_reward_status.inner.Active.partitioned_stake_rewards, partitioned_rewards, FD_PARTITIONED_STAKE_REWARDS_FOOTPRINT );
}

/* Process reward credits for a partition of rewards.
Store the rewards to AccountsDB, update reward history record and total capitalization

https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/distribution.rs#L88 */
static void
distribute_epoch_rewards_in_partition( fd_stake_reward_dlist_t * partition,
distribute_epoch_rewards_in_partition( fd_partitioned_stake_rewards_dlist_t * partition,
fd_stake_reward_t * pool,
fd_exec_slot_ctx_t * slot_ctx ) {

ulong lamports_distributed = 0UL;
ulong lamports_burned = 0UL;

for( fd_stake_reward_dlist_iter_t iter = fd_stake_reward_dlist_iter_fwd_init( partition, pool );
!fd_stake_reward_dlist_iter_done( iter, partition, pool );
iter = fd_stake_reward_dlist_iter_fwd_next( iter, partition, pool ) ) {
fd_stake_reward_t * stake_reward = fd_stake_reward_dlist_iter_ele( iter, partition, pool );
for( fd_partitioned_stake_rewards_dlist_iter_t iter = fd_partitioned_stake_rewards_dlist_iter_fwd_init( partition, pool );
!fd_partitioned_stake_rewards_dlist_iter_done( iter, partition, pool );
iter = fd_partitioned_stake_rewards_dlist_iter_fwd_next( iter, partition, pool ) ) {
fd_stake_reward_t * stake_reward = fd_partitioned_stake_rewards_dlist_iter_ele( iter, partition, pool );

if( distribute_epoch_reward_to_stake_acc( slot_ctx,
&stake_reward->stake_pubkey,
Expand Down Expand Up @@ -991,11 +997,11 @@ fd_distribute_partitioned_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx,
(void)exec_spads;
(void)exec_spad_cnt;

if( slot_ctx->epoch_reward_status.discriminant == fd_epoch_reward_status_enum_Inactive ) {
if( slot_ctx->slot_bank.epoch_reward_status.discriminant == fd_epoch_reward_status_enum_Inactive ) {
return;
}

fd_start_block_height_and_rewards_t * status = &slot_ctx->epoch_reward_status.inner.Active;
fd_start_block_height_and_rewards_t * status = &slot_ctx->slot_bank.epoch_reward_status.inner.Active;

fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank;
ulong height = slot_bank->block_height;
Expand All @@ -1012,6 +1018,7 @@ fd_distribute_partitioned_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx,

if( (height>=distribution_starting_block_height) && (height < distribution_end_exclusive) ) {
ulong partition_index = height - distribution_starting_block_height;
FD_LOG_WARNING(( "Distributing rewards for partition %lu", partition_index ));
distribute_epoch_rewards_in_partition( &status->partitioned_stake_rewards.partitions[ partition_index ],
status->partitioned_stake_rewards.pool,
slot_ctx );
Expand Down
3 changes: 0 additions & 3 deletions src/flamenco/runtime/context/fd_exec_slot_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ fd_exec_slot_ctx_new( void * mem,

self->sysvar_cache = fd_sysvar_cache_new( fd_spad_alloc( runtime_spad, fd_sysvar_cache_align(), fd_sysvar_cache_footprint() ), runtime_spad );

/* This is inactive by default */
self->epoch_reward_status.discriminant = fd_epoch_reward_status_enum_Inactive;

FD_COMPILER_MFENCE();
self->magic = FD_EXEC_SLOT_CTX_MAGIC;
FD_COMPILER_MFENCE();
Expand Down
3 changes: 0 additions & 3 deletions src/flamenco/runtime/context/fd_exec_slot_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ struct __attribute__((aligned(8UL))) fd_exec_slot_ctx {

ulong total_compute_units_requested;

/* TODO figure out what to do with this */
fd_epoch_reward_status_t epoch_reward_status;

/* TODO remove this stuff */
ulong signature_cnt;
fd_hash_t account_delta_hash;
Expand Down
15 changes: 14 additions & 1 deletion src/flamenco/types/fd_type_names.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This is an auto-generated file. To add entries, edit fd_types.json
#define FD_TYPE_NAME_COUNT 238
#define FD_TYPE_NAME_COUNT 251
static char const * fd_type_names[FD_TYPE_NAME_COUNT] = {
"fd_hash",
"fd_pubkey",
Expand Down Expand Up @@ -107,6 +107,19 @@ static char const * fd_type_names[FD_TYPE_NAME_COUNT] = {
"fd_firedancer_bank",
"fd_cluster_type",
"fd_epoch_bank",
"fd_stake_reward",
"fd_vote_reward",
"fd_point_value",
"fd_partitioned_stake_rewards",
"fd_stake_reward_calculation_partitioned",
"fd_stake_reward_calculation",
"fd_calculate_stake_vote_rewards_result",
"fd_calculate_validator_rewards_result",
"fd_calculate_rewards_and_distribute_vote_rewards_result",
"fd_partitioned_rewards_calculation",
"fd_start_block_height_and_rewards",
"fd_fd_epoch_reward_status_inner",
"fd_epoch_reward_status",
"fd_slot_bank",
"fd_prev_epoch_inflation_rewards",
"fd_vote",
Expand Down
Loading