From 76eaf37e3f5c9676cff3a4a4cce90cba0362c9cf Mon Sep 17 00:00:00 2001 From: Tom Pointon Date: Wed, 24 Jul 2024 16:33:07 +0000 Subject: [PATCH] flamenco, runtime: re-work partitioned epoch rewards --- src/flamenco/rewards/fd_rewards.c | 1318 ++++--- src/flamenco/rewards/fd_rewards.h | 19 +- src/flamenco/rewards/fd_rewards_types.h | 110 +- .../runtime/context/fd_exec_slot_ctx.c | 3 +- src/flamenco/runtime/fd_executor.c | 2 +- src/flamenco/runtime/fd_runtime.c | 4 +- .../runtime/program/fd_stake_program.c | 2 +- .../runtime/sysvar/fd_sysvar_epoch_rewards.c | 108 +- .../runtime/sysvar/fd_sysvar_epoch_rewards.h | 35 +- .../runtime/sysvar/fd_sysvar_epoch_schedule.c | 11 +- src/flamenco/types/fd_type_names.c | 26 +- src/flamenco/types/fd_types.c | 3180 ++++++++++++----- src/flamenco/types/fd_types.h | 821 ++++- src/flamenco/types/fd_types.json | 241 +- 14 files changed, 3908 insertions(+), 1972 deletions(-) diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index d983db51b3..bb3f535fb5 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -7,24 +7,32 @@ #include "../runtime/context/fd_exec_epoch_ctx.h" #include "../runtime/context/fd_exec_slot_ctx.h" #include "../../ballet/siphash13/fd_siphash13.h" +#include "../runtime/program/fd_program_util.h" #pragma GCC diagnostic ignored "-Wformat" #pragma GCC diagnostic ignored "-Wformat-extra-args" +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/sdk/program/src/native_token.rs#L6 */ +#define LAMPORTS_PER_SOL ( 1000000000UL ) +#define FD_REWARDS_SUCCESS ( 0UL ) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/inflation.rs#L85 */ static double total( fd_inflation_t const * inflation, double year ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/sdk/src/inflation.rs#L84-L93 */ - FD_TEST( year >= 0.0 ); + if ( FD_UNLIKELY( year == 0.0 ) ) { + FD_LOG_ERR(( "inflation year 0" )); + } double tapered = inflation->initial * pow((1.0 - inflation->taper), year); return (tapered > inflation->terminal) ? tapered : inflation->terminal; } +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/inflation.rs#L102 */ static double foundation( fd_inflation_t const * inflation, double year ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/sdk/src/inflation.rs#L100-L108 */ return (year < inflation->foundation_term) ? inflation->foundation * total(inflation, year) : 0.0; } +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/inflation.rs#L97 */ static double validator( fd_inflation_t const * inflation, double year) { /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/sdk/src/inflation.rs#L96-L99 */ @@ -32,11 +40,18 @@ validator( fd_inflation_t const * inflation, double year) { return total( inflation, year ) - foundation( inflation, year ); } +/* Calculates the starting slot for inflation from the activation slot. The activation slot is the earliest + activation slot of the following features: + - devnet_and_testnet + - full_inflation_enable, if full_inflation_vote has been activated + + https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank.rs#L2095 */ static FD_FN_CONST ulong get_inflation_start_slot( fd_exec_slot_ctx_t * slot_ctx ) { ulong devnet_and_testnet = FD_FEATURE_ACTIVE(slot_ctx, devnet_and_testnet) ? slot_ctx->epoch_ctx->features.devnet_and_testnet : ULONG_MAX; + ulong enable = ULONG_MAX; - if (FD_FEATURE_ACTIVE( slot_ctx, full_inflation_vote ) && FD_FEATURE_ACTIVE(slot_ctx, full_inflation_enable)) { + if ( FD_FEATURE_ACTIVE( slot_ctx, full_inflation_vote ) && FD_FEATURE_ACTIVE(slot_ctx, full_inflation_enable ) ) { enable = slot_ctx->epoch_ctx->features.full_inflation_enable; } @@ -51,11 +66,11 @@ get_inflation_start_slot( fd_exec_slot_ctx_t * slot_ctx ) { return min_slot; } +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank.rs#L2110 */ static ulong get_inflation_num_slots( fd_exec_slot_ctx_t * slot_ctx, fd_epoch_schedule_t const * epoch_schedule, ulong slot ) { - /* https://github.com/firedancer-io/solana/blob/de02601d73d626edf98ef63efd772824746f2f33/runtime/src/bank.rs#L2333-L2342 */ ulong inflation_activation_slot = get_inflation_start_slot( slot_ctx ); ulong inflation_start_slot = fd_epoch_slot0( epoch_schedule, @@ -69,18 +84,28 @@ get_inflation_num_slots( fd_exec_slot_ctx_t * slot_ctx, return fd_epoch_slot0(epoch_schedule, epoch) - inflation_start_slot; } +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank.rs#L2121 */ +static double +slot_in_year_for_inflation( fd_exec_slot_ctx_t * slot_ctx ) { + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); + ulong num_slots = get_inflation_num_slots( slot_ctx, &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot ); + return (double)num_slots / (double)epoch_bank->slots_per_year; +} -// for a given stake and vote_state, calculate how many -// points were earned (credits * stake) and new value -// for credits_observed were the points paid +/* For a given stake and vote_state, calculate how many points were earned (credits * stake) and new value + for credits_observed were the points paid + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L109 */ static void calculate_stake_points_and_credits ( - fd_stake_history_t const * stake_history, - fd_stake_state_v2_t * stake_state, - fd_vote_state_versioned_t * vote_state_versioned, - fd_calculate_stake_points_t * result + fd_stake_history_t const * stake_history, + fd_stake_t * stake, + fd_vote_state_versioned_t * vote_state_versioned, + fd_calculated_stake_points_t * result ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/programs/stake/src/stake_state.rs#L249-L351 */ + + ulong credits_in_stake = stake->credits_observed; + fd_vote_epoch_credits_t * epoch_credits; switch (vote_state_versioned->discriminant) { case fd_vote_state_versioned_enum_current: @@ -93,52 +118,65 @@ calculate_stake_points_and_credits ( epoch_credits = vote_state_versioned->inner.v1_14_11.epoch_credits; break; default: - __builtin_unreachable(); + FD_LOG_ERR(( "invalid vote account, should never happen" )); } - ulong credits_in_stake = stake_state->inner.stake.stake.credits_observed; - ulong credits_in_vote = deq_fd_vote_epoch_credits_t_empty( epoch_credits ) ? 0 : deq_fd_vote_epoch_credits_t_peek_tail_const( epoch_credits )->credits; -// FD_LOG_WARNING(("Vote credits: %lu %32J %lu %lu %lu", credits_in_stake, stake_state->inner.stake.stake.delegation.voter_pubkey.key, credits_in_vote, deq_fd_vote_epoch_credits_t_peek_tail_const( epoch_credits )->epoch, deq_fd_vote_epoch_credits_t_peek_tail_const( epoch_credits )->prev_credits )); - - result->points = 0; - result->force_credits_update_with_skipped_reward = credits_in_vote < credits_in_stake; - if (credits_in_vote < credits_in_stake) { - // FD_LOG_WARNING(("Vote credits 2: %lu %32J %lu %lu %lu", credits_in_stake, stake_state->inner.stake.stake.delegation.voter_pubkey.key, credits_in_vote, deq_fd_vote_epoch_credits_t_peek_tail_const( epoch_credits )->epoch, deq_fd_vote_epoch_credits_t_peek_tail_const( epoch_credits )->prev_credits )); - - result->new_credits_observed = credits_in_vote; - return; - } - if (credits_in_vote == credits_in_stake) { - // don't hint caller and return current value if credits remain unchanged (= delinquent) - result->new_credits_observed = credits_in_stake; - return; - } - - uint128 points = 0; - ulong new_credits_observed = credits_in_stake; - - for ( deq_fd_vote_epoch_credits_t_iter_t iter = deq_fd_vote_epoch_credits_t_iter_init( epoch_credits ); !deq_fd_vote_epoch_credits_t_iter_done( epoch_credits, iter ); iter = deq_fd_vote_epoch_credits_t_iter_next( epoch_credits, iter ) ) { - fd_vote_epoch_credits_t * ele = deq_fd_vote_epoch_credits_t_iter_ele(epoch_credits, iter ); - ulong epoch = ele->epoch; - ulong final_epoch_credits = ele->credits; - ulong initial_epoch_credits = ele->prev_credits; - uint128 earned_credits = 0; - if (credits_in_stake < initial_epoch_credits) { - earned_credits = (uint128)(final_epoch_credits - initial_epoch_credits); - } else if (credits_in_stake < final_epoch_credits) { - earned_credits = (uint128)(final_epoch_credits - new_credits_observed); + ulong credits_in_vote = 0UL; + if ( FD_LIKELY( !deq_fd_vote_epoch_credits_t_empty( epoch_credits ) ) ) { + credits_in_vote = deq_fd_vote_epoch_credits_t_peek_tail_const( epoch_credits )->credits; } - new_credits_observed = fd_ulong_max(new_credits_observed, final_epoch_credits); - uint128 stake_amount = (uint128)(fd_stake_activating_and_deactivating(&stake_state->inner.stake.stake.delegation, epoch, stake_history, NULL).effective); - points += stake_amount * earned_credits; - } - result->points = points; - result->new_credits_observed = new_credits_observed; -// FD_LOG_WARNING(("Vote credits 3: %lu", new_credits_observed )); + /* If the Vote account has less credits observed than the Stake account, + something is wrong and we need to force an update. + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L142 */ + if ( FD_UNLIKELY( credits_in_vote < credits_in_stake ) ) { + result->points = 0; + result->new_credits_observed = credits_in_vote; + result->force_credits_update_with_skipped_reward = 1; + return; + } -} + /* If the Vote account has the same amount of credits observed as the Stake account, + then the Vote account hasn't earnt any credits and so there is nothing to update. + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L148 */ + if ( FD_UNLIKELY( credits_in_vote == credits_in_stake ) ) { + result->points = 0; + result->new_credits_observed = credits_in_vote; + result->force_credits_update_with_skipped_reward = 0; + return; + } + + /* Calculate the points for each epoch credit */ + uint128 points = 0; + ulong new_credits_observed = credits_in_stake; + for ( deq_fd_vote_epoch_credits_t_iter_t iter = deq_fd_vote_epoch_credits_t_iter_init( epoch_credits ); + !deq_fd_vote_epoch_credits_t_iter_done( epoch_credits, iter ); + iter = deq_fd_vote_epoch_credits_t_iter_next( epoch_credits, iter ) ) { + + fd_vote_epoch_credits_t * ele = deq_fd_vote_epoch_credits_t_iter_ele( epoch_credits, iter ); + ulong final_epoch_credits = ele->credits; + ulong initial_epoch_credits = ele->prev_credits; + uint128 earned_credits = 0; + if ( FD_LIKELY( credits_in_stake < initial_epoch_credits ) ) { + earned_credits = (uint128)(final_epoch_credits - initial_epoch_credits); + } else if ( FD_UNLIKELY( credits_in_stake < final_epoch_credits ) ) { + earned_credits = (uint128)(final_epoch_credits - new_credits_observed); + } + + new_credits_observed = fd_ulong_max( new_credits_observed, final_epoch_credits ); + ulong stake_amount = fd_stake_activating_and_deactivating( &stake->delegation, ele->epoch, stake_history, NULL ).effective; + points += (uint128)stake_amount * earned_credits; + } + + result->points = points; + result->new_credits_observed = new_credits_observed; + result->force_credits_update_with_skipped_reward = 0; +} + +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/rewards.rs#L127 */ static int calculate_stake_rewards( fd_stake_history_t const * stake_history, @@ -148,19 +186,8 @@ calculate_stake_rewards( fd_point_value_t * point_value, fd_calculated_stake_rewards_t * result ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/programs/stake/src/stake_state.rs#L360-L464 */ - /* - implements the `calculate_stake_rewards` solana function - for a given stake and vote_state, calculate what distributions and what updates should be made - returns a tuple in the case of a payout of: - * staker_rewards to be distributed - * voter_rewards to be distributed - * new value for credits_observed in the stake - returns None if there's no payout or if any deserved payout is < 1 lamport */ - fd_calculate_stake_points_t stake_points_result = {0}; - // TODO - calculate_stake_points_and_credits( stake_history, stake_state, vote_state_versioned, &stake_points_result); - // FD_LOG_WARNING(("CSR: %lu", stake_points_result.new_credits_observed )); + fd_calculated_stake_points_t stake_points_result = {0}; + calculate_stake_points_and_credits( stake_history, &stake_state->inner.stake.stake, vote_state_versioned, &stake_points_result); // Drive credits_observed forward unconditionally when rewards are disabled // or when this is the stake's activation epoch @@ -177,8 +204,8 @@ calculate_stake_rewards( return 1; } - - ulong rewards = (ulong)(stake_points_result.points * (uint128)point_value->rewards / (uint128) point_value->points); + /* FIXME: need to error out if the conversion from uint128 to u64 fails, also use 128 checked mul and div */ + ulong rewards = (ulong)(stake_points_result.points * (uint128)(point_value->rewards) / (uint128) point_value->points); if (rewards == 0) { return 1; } @@ -192,50 +219,27 @@ calculate_stake_rewards( result->staker_rewards = split_result.staker_portion; result->voter_rewards = split_result.voter_portion; result->new_credits_observed = stake_points_result.new_credits_observed; - - /* implements the `redeem_stake_rewards` solana function */ - // stake_state->inner.stake.stake.credits_observed += result->new_credits_observed; - // stake_state->inner.stake.stake.delegation.stake += result->staker_rewards; return 0; } +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/rewards.rs#L33 */ static int -stake_state_redeem_rewards( fd_exec_slot_ctx_t * slot_ctx, - fd_stake_history_t const * stake_history, - fd_pubkey_t const * stake_acc, - fd_vote_state_versioned_t * vote_state, - ulong rewarded_epoch, - fd_point_value_t * point_value, - fd_calculated_stake_rewards_t * result ) { - - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/programs/stake/src/stake_state.rs#L1525-L1571 */ - FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec ); - if( FD_UNLIKELY( err ) ) { - return err; - } - - fd_stake_state_v2_t stake_state = {0}; - int rc = fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; - } - // fd_stake_state_t stake_state; - // read_stake_state( global, stake_acc_rec->const_meta, &stake_state ); - // if (!fd_stake_state_is_stake( &stake_state)) { - // return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; - // } - - rc = calculate_stake_rewards(stake_history, &stake_state, vote_state, rewarded_epoch, point_value, result); - // FD_LOG_WARNING(("SSRR: %32J RES->NCO: %lu, SS->NCO: %lu %lu", stake_acc->key, result->new_credits_observed, stake_state.discriminant, stake_state.inner.stake.stake.credits_observed)); - if (rc != 0) { - // ctx->txn_ctx->custom_err = 0; /* Err(StakeError::NoCreditsToRedeem.into()) */ +redeem_rewards( fd_stake_history_t const * stake_history, + fd_stake_state_v2_t * stake_state, + fd_vote_state_versioned_t * vote_state_versioned, + ulong rewarded_epoch, + fd_point_value_t * point_value, + fd_calculated_stake_rewards_t * calculated_stake_rewards) { + + int rc = calculate_stake_rewards( stake_history, stake_state, vote_state_versioned, rewarded_epoch, point_value, calculated_stake_rewards ); + if ( FD_UNLIKELY( rc != 0 ) ) { return rc; } return FD_EXECUTOR_INSTR_SUCCESS; } +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L70 */ int calculate_points( fd_stake_state_v2_t * stake_state, @@ -243,60 +247,64 @@ calculate_points( fd_stake_history_t const * stake_history, uint128 * result ) { - // TODO - // if (!fd_stake_state_is_stake( stake_state)) { - // return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; - // } - fd_calculate_stake_points_t stake_point_result; - calculate_stake_points_and_credits(stake_history, stake_state, vote_state_versioned, &stake_point_result); + if ( FD_UNLIKELY( !fd_stake_state_v2_is_stake( stake_state ) ) ) { + return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; + } + + fd_calculated_stake_points_t stake_point_result; + calculate_stake_points_and_credits( stake_history, &stake_state->inner.stake.stake, vote_state_versioned, &stake_point_result ); *result = stake_point_result.points; return FD_EXECUTOR_INSTR_SUCCESS; } +/* Returns the length of the given epoch in slots + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/sdk/program/src/epoch_schedule.rs#L103 */ +static ulong +get_slots_in_epoch( + ulong epoch, + fd_epoch_bank_t const * epoch_bank +) { + return (epoch < epoch_bank->epoch_schedule.first_normal_epoch) ? + 1UL << fd_ulong_sat_add(epoch, FD_EPOCH_LEN_MIN_TRAILING_ZERO) : + epoch_bank->epoch_schedule.slots_per_epoch; +} +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank.rs#L2082 */ static double epoch_duration_in_years( fd_epoch_bank_t const * epoch_bank, ulong prev_epoch ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2283-L2288 */ - /* get_slots_in_epoch */ - ulong slots_in_epoch = (prev_epoch < epoch_bank->epoch_schedule.first_normal_epoch) ? - 1UL << fd_ulong_sat_add(prev_epoch, FD_EPOCH_LEN_MIN_TRAILING_ZERO) : - epoch_bank->epoch_schedule.slots_per_epoch; + ulong slots_in_epoch = get_slots_in_epoch( prev_epoch, epoch_bank ); return (double)slots_in_epoch / (double) epoch_bank->slots_per_year; } +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank.rs#L2128 */ static void calculate_previous_epoch_inflation_rewards( fd_exec_slot_ctx_t * slot_ctx, - fd_epoch_bank_t const * epoch_bank, - ulong slot, ulong prev_epoch_capitalization, ulong prev_epoch, fd_prev_epoch_inflation_rewards_t * rewards ) { - /* https://github.com/firedancer-io/solana/blob/de02601d73d626edf98ef63efd772824746f2f33/runtime/src/bank.rs#L2351-L2376 */ - + double slot_in_year = slot_in_year_for_inflation( slot_ctx ); - /* slot_in_year_for_inflation - https://github.com/firedancer-io/solana/blob/de02601d73d626edf98ef63efd772824746f2f33/runtime/src/bank.rs#L2344-L2349 - */ - ulong num_slots = get_inflation_num_slots( slot_ctx, &epoch_bank->epoch_schedule, slot ); - double slot_in_year = (double)num_slots / (double)epoch_bank->slots_per_year; + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); rewards->validator_rate = validator( &epoch_bank->inflation, slot_in_year ); - rewards->foundation_rate = foundation(&epoch_bank->inflation, slot_in_year); + rewards->foundation_rate = foundation( &epoch_bank->inflation, slot_in_year ); rewards->prev_epoch_duration_in_years = epoch_duration_in_years(epoch_bank, prev_epoch); rewards->validator_rewards = (ulong)(rewards->validator_rate * (double)prev_epoch_capitalization * rewards->prev_epoch_duration_in_years); FD_LOG_DEBUG(("Rewards %lu, Rate %.16f, Duration %.18f Capitalization %lu Slot in year %.16f", rewards->validator_rewards, rewards->validator_rate, rewards->prev_epoch_duration_in_years, prev_epoch_capitalization, slot_in_year)); } -// Sum the lamports of the vote accounts and the delegated stake +/* Sum the lamports of the vote accounts and the delegated stake + + https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/stakes.rs#L360 */ static ulong vote_balance_and_staked( fd_exec_slot_ctx_t * slot_ctx, fd_stakes_t const * stakes) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/stakes.rs#L346-L356 */ ulong result = 0; for( fd_vote_accounts_pair_t_mapnode_t const * n = fd_vote_accounts_pair_t_map_minimum_const( stakes->vote_accounts.vote_accounts_pool, stakes->vote_accounts.vote_accounts_root ); n; @@ -323,6 +331,9 @@ vote_balance_and_staked( fd_exec_slot_ctx_t * slot_ctx, fd_stakes_t const * stak if (fd_stake_get_state( stake_acc_rec, &slot_ctx->valloc, &stake_state) != 0) { continue; } + if ( FD_UNLIKELY( !fd_stake_state_v2_is_stake( &stake_state ) ) ) { + continue; + } result += stake_state.inner.stake.stake.delegation.stake; } @@ -332,12 +343,14 @@ vote_balance_and_staked( fd_exec_slot_ctx_t * slot_ctx, fd_stakes_t const * stak n = fd_stake_accounts_pair_t_map_successor_const( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, n ) ) { fd_pubkey_t const * stake_acc = &n->elem.key; FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - if (fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec ) != FD_ACC_MGR_SUCCESS ) { + if ( fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec ) != FD_ACC_MGR_SUCCESS ) { continue; } - // result += stake_acc_rec->const_meta->info.lamports; fd_stake_state_v2_t stake_state; - if (fd_stake_get_state( stake_acc_rec, &slot_ctx->valloc, &stake_state) != 0) { + if ( fd_stake_get_state( stake_acc_rec, &slot_ctx->valloc, &stake_state) != 0 ) { + continue; + } + if ( FD_UNLIKELY( !fd_stake_state_v2_is_stake( &stake_state ) ) ) { continue; } @@ -347,92 +360,23 @@ vote_balance_and_staked( fd_exec_slot_ctx_t * slot_ctx, fd_stakes_t const * stak return result; } -static void -calculate_reward_points_account( - fd_exec_slot_ctx_t * slot_ctx, - fd_stake_history_t const * stake_history, - fd_pubkey_t const * voter_acc, - fd_pubkey_t const * stake_acc, - uint128 * points, - ulong * actual_len - ) { - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong min_stake_delegation = 1000000000; - - FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - if( 0!=fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec) ) { - FD_LOG_DEBUG(("Stake acc not found %32J", stake_acc->uc)); - return; - } - - if (stake_acc_rec->const_meta->info.lamports == 0) { - FD_LOG_DEBUG(("Stake acc not found %32J", stake_acc->uc)); - return; - } - - fd_stake_state_v2_t stake_state = {0}; - int rc = fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - // FD_LOG_ERR(("failed to read")); - return; - } - - if (FD_FEATURE_ACTIVE(slot_ctx, stake_minimum_delegation_for_rewards)) { - if (stake_state.inner.stake.stake.delegation.stake < min_stake_delegation) { - return; - } +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/lib.rs#L29 */ +static ulong +get_minimum_stake_delegation( fd_exec_slot_ctx_t * slot_ctx ) { + if ( !FD_FEATURE_ACTIVE( slot_ctx, stake_minimum_delegation_for_rewards ) ) { + return ULONG_MAX; } - *actual_len += 1; - - fd_vote_accounts_pair_t_mapnode_t key; - fd_memcpy(&key.elem.key, voter_acc, sizeof(fd_pubkey_t)); - if (fd_vote_accounts_pair_t_map_find(epoch_bank->stakes.vote_accounts.vote_accounts_pool, epoch_bank->stakes.vote_accounts.vote_accounts_root, &key) == NULL) { - return; + if ( !FD_FEATURE_ACTIVE( slot_ctx, stake_raise_minimum_delegation_to_1_sol ) ) { + return LAMPORTS_PER_SOL; } - FD_BORROWED_ACCOUNT_DECL(voter_acc_rec); - int read_err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, voter_acc, voter_acc_rec ); - if( read_err!=0 || 0!=memcmp( &voter_acc_rec->const_meta->info.owner, fd_solana_vote_program_id.key, sizeof(fd_pubkey_t) ) ) { - return; - } - - /* Deserialize vote account */ - fd_bincode_decode_ctx_t decode = { - .data = voter_acc_rec->const_data, - .dataend = voter_acc_rec->const_data + voter_acc_rec->const_meta->dlen, - /* TODO: Make this a instruction-scoped allocator */ - .valloc = slot_ctx->valloc, - }; - fd_vote_state_versioned_t vote_state[1] = {0}; - if( FD_UNLIKELY( 0!=fd_vote_state_versioned_decode( vote_state, &decode ) ) ) - FD_LOG_ERR(( "vote_state_versioned_decode failed" )); - - // fd_vote_epoch_credits_t * epoch_credits; - // switch (vote_state->discriminant) { - // case fd_vote_state_versioned_enum_current: - // epoch_credits = vote_state->inner.current.epoch_credits; - // break; - // case fd_vote_state_versioned_enum_v0_23_5: - // epoch_credits = vote_state->inner.v0_23_5.epoch_credits; - // break; - // case fd_vote_state_versioned_enum_v1_14_11: - // epoch_credits = vote_state->inner.v1_14_11.epoch_credits; - // break; - // default: - // __builtin_unreachable(); - // } - - // FD_LOG_WARNING(("VOTE ACCOUNT: %32J, %lu", voter_acc->key, deq_fd_vote_epoch_credits_t_peek_tail_const( epoch_credits )->credits)); - - uint128 result; - *points += (calculate_points(&stake_state, vote_state, stake_history, &result) == FD_EXECUTOR_INSTR_SUCCESS ? result : 0); - // FD_LOG_WARNING(("PER_ACC_POINTS: Acc: %32J, Points: %K", stake_acc->key, &result )); - fd_bincode_destroy_ctx_t destroy = {.valloc = slot_ctx->valloc}; - fd_stake_state_v2_destroy( &stake_state, &destroy ); - fd_vote_state_versioned_destroy( vote_state, &destroy ); + return 1; } +/* Calculates epoch reward points from stake/vote accounts. + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L472 */ static void calculate_reward_points_partitioned( fd_exec_slot_ctx_t * slot_ctx, @@ -440,52 +384,97 @@ calculate_reward_points_partitioned( ulong rewards, fd_point_value_t * result ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2961-L3018 */ + /* There is a cache of vote account keys stored in the slot context */ + /* TODO: check this cache is correct */ + uint128 points = 0; - ulong actual_len = 0; fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - FD_LOG_DEBUG(("Delegations len %lu, slot del len %lu", fd_delegation_pair_t_map_size( epoch_bank->stakes.stake_delegations_pool, epoch_bank->stakes.stake_delegations_root ), fd_stake_accounts_pair_t_map_size( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, slot_ctx->slot_bank.stake_account_keys.stake_accounts_root ))); + + ulong minimum_stake_delegation = get_minimum_stake_delegation( slot_ctx ); + + /* Calculate the points for each stake delegation */ for( fd_delegation_pair_t_mapnode_t const * n = fd_delegation_pair_t_map_minimum_const( epoch_bank->stakes.stake_delegations_pool, epoch_bank->stakes.stake_delegations_root ); n; n = fd_delegation_pair_t_map_successor_const( epoch_bank->stakes.stake_delegations_pool, n ) ) { - fd_pubkey_t const * voter_acc = &n->elem.delegation.voter_pubkey; - fd_pubkey_t const * stake_acc = &n->elem.account; - // FD_LOG_WARNING(("STAKE ACC1: %32J, %32J", stake_acc->key, voter_acc->key)); - calculate_reward_points_account( slot_ctx, stake_history, voter_acc, stake_acc, &points, &actual_len ); - } - // FD_LOG_HEXDUMP_WARNING(( "POINTS 1", &points, 16 )); + FD_SCRATCH_SCOPE_BEGIN { + fd_valloc_t valloc = fd_scratch_virtual(); - for ( fd_stake_accounts_pair_t_mapnode_t const * n = fd_stake_accounts_pair_t_map_minimum_const( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, slot_ctx->slot_bank.stake_account_keys.stake_accounts_root ); - n; - n = fd_stake_accounts_pair_t_map_successor_const( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, n ) ) { - (void) n; - fd_pubkey_t const * stake_acc = &n->elem.key; + /* Fetch the stake account */ + FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); + fd_pubkey_t const * stake_acc = &n->elem.account; + int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec); + if ( err != FD_ACC_MGR_SUCCESS && err != FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) { + FD_LOG_ERR(( "failed to read stake account from funk" )); + continue; + } + if ( err == FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) { + FD_LOG_DEBUG(( "stake account not found %32J", stake_acc->uc )); + continue; + } + if ( stake_acc_rec->const_meta->info.lamports == 0 ) { + FD_LOG_DEBUG(( "stake acc with zero lamports %32J", stake_acc->uc)); + continue; + } - // FD_LOG_WARNING(("STAKE ACC2: %32J", stake_acc->key)); - FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - if( 0!=fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec) ) { - FD_LOG_DEBUG(("Stake acc not found %32J", stake_acc->uc)); - continue; - } + /* Check the minimum stake delegation */ + fd_stake_state_v2_t stake_state[1] = {0}; + err = fd_stake_get_state( stake_acc_rec, &valloc, stake_state ); + if ( err != 0 ) { + FD_LOG_DEBUG(( "get stake state failed" )); + continue; + } + if ( FD_UNLIKELY( stake_state->inner.stake.stake.delegation.stake < minimum_stake_delegation ) ) { + continue; + } - if (stake_acc_rec->const_meta->info.lamports == 0) continue; + /* Check that the vote account is present in our cache */ + fd_vote_accounts_pair_t_mapnode_t key; + fd_pubkey_t const * voter_acc = &n->elem.delegation.voter_pubkey; + fd_memcpy( &key.elem.key, voter_acc, sizeof(fd_pubkey_t) ); + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( + slot_ctx->epoch_ctx ); + if ( FD_UNLIKELY( fd_vote_accounts_pair_t_map_find( + epoch_bank->stakes.vote_accounts.vote_accounts_pool, + epoch_bank->stakes.vote_accounts.vote_accounts_root, + &key ) == NULL ) ) { + FD_LOG_DEBUG(( "vote account missing from cache" )); + continue; + } - fd_stake_state_v2_t stake_state = {0}; - int rc = fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - FD_LOG_WARNING(("Failed to read stake state from stake account %32J", stake_acc)); - continue; - } + /* Check that the vote account is valid and has the correct owner */ + FD_BORROWED_ACCOUNT_DECL(voter_acc_rec); + err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, voter_acc, voter_acc_rec ); + if ( FD_UNLIKELY( err ) ) { + FD_LOG_DEBUG(( "failed to read vote account from funk" )); + continue; + } + if( FD_UNLIKELY( memcmp( &voter_acc_rec->const_meta->info.owner, fd_solana_vote_program_id.key, sizeof(fd_pubkey_t) ) != 0 ) ) { + FD_LOG_DEBUG(( "vote account has wrong owner" )); + continue; + } + fd_bincode_decode_ctx_t decode = { + .data = voter_acc_rec->const_data, + .dataend = voter_acc_rec->const_data + voter_acc_rec->const_meta->dlen, + .valloc = valloc, + }; + fd_vote_state_versioned_t vote_state[1] = {0}; + if( FD_UNLIKELY( 0!=fd_vote_state_versioned_decode( vote_state, &decode ) ) ) { + FD_LOG_DEBUG(( "vote_state_versioned_decode failed" )); + continue; + } + + uint128 account_points; + err = calculate_points( stake_state, vote_state, stake_history, &account_points ); + if ( FD_UNLIKELY( err ) ) { + FD_LOG_DEBUG(( "failed to calculate points" )); + continue; + } - fd_pubkey_t const * voter_acc = &stake_state.inner.stake.stake.delegation.voter_pubkey; - calculate_reward_points_account( slot_ctx, stake_history, voter_acc, stake_acc, &points, &actual_len ); - fd_bincode_destroy_ctx_t destroy = {.valloc = slot_ctx->valloc}; - fd_stake_state_v2_destroy( &stake_state, &destroy ); + points += account_points; + } FD_SCRATCH_SCOPE_END; } - // FD_LOG_HEXDUMP_WARNING(( "POINTS", &points, 16 )); - // FD_LOG_WARNING(("REWARDS 2: %lu TOT POINTS: %llu",rewards, points )); if (points > 0) { result->points = points; result->rewards = rewards; @@ -494,247 +483,221 @@ calculate_reward_points_partitioned( } } +/* Calculate the partitioned stake rewards for a single stake/vote account, + updates result with these. */ static void calculate_stake_vote_rewards_account( - fd_exec_slot_ctx_t * slot_ctx, - fd_stake_history_t const * stake_history, - ulong rewarded_epoch, - fd_point_value_t * point_value, - fd_pubkey_t const * voter_acc, - fd_pubkey_t const * stake_acc, - fd_stake_reward_t * stake_reward_deq, - fd_vote_reward_t_mapnode_t * vote_reward_map, - fd_acc_lamports_t * total_stake_rewards + fd_exec_slot_ctx_t * slot_ctx, + fd_stake_history_t const * stake_history, + ulong rewarded_epoch, + fd_point_value_t * point_value, + fd_pubkey_t const * voter_acc, + fd_pubkey_t const * stake_acc, + fd_borrowed_account_t * stake_acc_rec, + fd_stake_state_v2_t * stake_state, + fd_acc_lamports_t * total_stake_rewards, + fd_calculate_stake_vote_rewards_result_t * result ) { fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong min_stake_delegation = 1000000000; - - FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - int err = fd_acc_mgr_view(slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec); - if (FD_UNLIKELY(err != FD_ACC_MGR_SUCCESS)) { - FD_LOG_DEBUG(("stake_state::stake_state_redeem_rewards() %32J not found", stake_acc )); - return; - } + ulong minimum_stake_delegation = get_minimum_stake_delegation( slot_ctx ); - if (stake_acc_rec->const_meta->info.lamports == 0) return; - - fd_stake_state_v2_t stake_state = {0}; - int rc = fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - // FD_LOG_ERR(("failed to read")); - return; - } - - if (FD_FEATURE_ACTIVE(slot_ctx, stake_minimum_delegation_for_rewards)) { - if (stake_state.inner.stake.stake.delegation.stake < min_stake_delegation) { + if ( FD_FEATURE_ACTIVE(slot_ctx, stake_minimum_delegation_for_rewards )) { + if ( stake_state->inner.stake.stake.delegation.stake < minimum_stake_delegation ) { return; } } fd_vote_accounts_pair_t_mapnode_t key; - fd_memcpy(&key.elem.key, voter_acc, sizeof(fd_pubkey_t)); - - if (fd_vote_accounts_pair_t_map_find(epoch_bank->stakes.vote_accounts.vote_accounts_pool, epoch_bank->stakes.vote_accounts.vote_accounts_root, &key) == NULL - && fd_vote_accounts_pair_t_map_find(slot_ctx->slot_bank.vote_account_keys.vote_accounts_pool, slot_ctx->slot_bank.vote_account_keys.vote_accounts_root, &key) == NULL) { + fd_memcpy( &key.elem.key, voter_acc, sizeof(fd_pubkey_t) ); + if ( fd_vote_accounts_pair_t_map_find( epoch_bank->stakes.vote_accounts.vote_accounts_pool, epoch_bank->stakes.vote_accounts.vote_accounts_root, &key ) == NULL + && fd_vote_accounts_pair_t_map_find( slot_ctx->slot_bank.vote_account_keys.vote_accounts_pool, slot_ctx->slot_bank.vote_account_keys.vote_accounts_root, &key ) == NULL) { return; } - FD_BORROWED_ACCOUNT_DECL(voter_acc_rec); + FD_BORROWED_ACCOUNT_DECL( voter_acc_rec ); int read_err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, voter_acc, voter_acc_rec ); - if( read_err!=0 || 0!=memcmp( &voter_acc_rec->const_meta->info.owner, fd_solana_vote_program_id.key, sizeof(fd_pubkey_t) ) ) { + if( read_err!=0 || memcmp( &voter_acc_rec->const_meta->info.owner, fd_solana_vote_program_id.key, sizeof(fd_pubkey_t) ) != 0 ) { return; } - /* Read vote account */ + fd_valloc_t valloc = fd_scratch_virtual(); fd_bincode_decode_ctx_t decode = { .data = voter_acc_rec->const_data, .dataend = voter_acc_rec->const_data + voter_acc_rec->const_meta->dlen, - /* TODO: Make this a instruction-scoped allocator */ - .valloc = slot_ctx->valloc, + .valloc = valloc, }; - fd_bincode_destroy_ctx_t destroy = {.valloc = slot_ctx->valloc}; fd_vote_state_versioned_t vote_state_versioned[1] = {0}; if( fd_vote_state_versioned_decode( vote_state_versioned, &decode ) != 0 ) { return; } - uchar commission = 0U; + /* Note, this doesn't actually redeem any rewards.. this is a misnomer. */ + fd_calculated_stake_rewards_t calculated_stake_rewards[1] = {0}; + int err = redeem_rewards( stake_history, stake_state, vote_state_versioned, rewarded_epoch, point_value, calculated_stake_rewards ); + if ( err != 0) { + FD_LOG_DEBUG(( "redeem_rewards failed for %32J with error %d", stake_acc->key, err )); + return; + } + + /* Fetch the comission for the vote account */ + ulong * commission = fd_valloc_malloc( slot_ctx->valloc, 1UL, 1UL ); switch (vote_state_versioned->discriminant) { case fd_vote_state_versioned_enum_current: - commission = (uchar)vote_state_versioned->inner.current.commission; + *commission = (uchar)vote_state_versioned->inner.current.commission; break; case fd_vote_state_versioned_enum_v0_23_5: - commission = (uchar)vote_state_versioned->inner.v0_23_5.commission; + *commission = (uchar)vote_state_versioned->inner.v0_23_5.commission; break; case fd_vote_state_versioned_enum_v1_14_11: - commission = (uchar)vote_state_versioned->inner.v1_14_11.commission; + *commission = (uchar)vote_state_versioned->inner.v1_14_11.commission; break; default: - __builtin_unreachable(); - } - - fd_vote_reward_t_mapnode_t * node = fd_vote_reward_t_map_query(vote_reward_map, *voter_acc, NULL); - if (node == NULL) { - node = fd_vote_reward_t_map_insert(vote_reward_map, *voter_acc); - node->vote_rewards = 0; - fd_memcpy(&node->vote_pubkey, voter_acc, sizeof(fd_pubkey_t)); - node->commission = (uchar)commission; - node->needs_store = 0; + FD_LOG_DEBUG(( "unsupported vote account" )); + return; } - fd_calculated_stake_rewards_t redeemed[1] = {0}; - rc = stake_state_redeem_rewards(slot_ctx, stake_history, stake_acc, vote_state_versioned, rewarded_epoch, point_value, redeemed); - if ( rc != 0) { - fd_vote_state_versioned_destroy( vote_state_versioned, &destroy ); - FD_LOG_DEBUG(("stake_state::stake_state_redeem_rewards() failed for %32J with error %d", stake_acc->key, rc )); - return; + /* Update the vote reward in the map */ + fd_vote_reward_t_mapnode_t vote_map_key[1]; + fd_memcpy( &vote_map_key->elem.pubkey, voter_acc, sizeof(fd_pubkey_t) ); + fd_vote_reward_t_mapnode_t * vote_reward_node = fd_vote_reward_t_map_find( result->vote_reward_map_pool, result->vote_reward_map_root, vote_map_key ); + if ( vote_reward_node == NULL ) { + vote_reward_node = fd_vote_reward_t_map_acquire( result->vote_reward_map_pool ); + fd_memcpy( &vote_reward_node->elem.pubkey, voter_acc, sizeof(fd_pubkey_t) ); + vote_reward_node->elem.commission = (uchar)*commission; + vote_reward_node->elem.vote_rewards = calculated_stake_rewards->voter_rewards; + vote_reward_node->elem.needs_store = 1; + fd_vote_reward_t_map_insert( result->vote_reward_map_pool, &result->vote_reward_map_root, vote_reward_node ); + } else { + vote_reward_node->elem.needs_store = 1; + vote_reward_node->elem.vote_rewards = fd_ulong_sat_add( + vote_reward_node->elem.vote_rewards, calculated_stake_rewards->voter_rewards + ); } - fd_acc_lamports_t post_lamports = stake_acc_rec->const_meta->info.lamports; - - // track total_stake_rewards - *total_stake_rewards += redeemed->staker_rewards; + /* Track the total stake rewards */ + *total_stake_rewards += calculated_stake_rewards->staker_rewards; - // add stake_reward to the collection - fd_stake_reward_t stake_reward; - fd_memcpy(&stake_reward.stake_pubkey, stake_acc, sizeof(fd_pubkey_t)); - - stake_reward.reward_info = (fd_reward_info_t) { + /* Add the partitioned stake reward to the partitioned stake reward */ + fd_partitioned_stake_reward_t partitioned_stake_reward; + fd_memcpy( &partitioned_stake_reward.stake_pubkey, stake_acc, sizeof(fd_pubkey_t) ); + partitioned_stake_reward.stake_reward_info = (fd_reward_info_t) { .reward_type = { .discriminant = fd_reward_type_enum_staking }, - .commission = (uchar)commission, - .lamports = redeemed->staker_rewards, - .new_credits_observed = redeemed->new_credits_observed, - .staker_rewards = redeemed->staker_rewards, - .post_balance = post_lamports + .commission = commission, + .lamports = calculated_stake_rewards->staker_rewards, + .post_balance = stake_acc_rec->const_meta->info.lamports + calculated_stake_rewards->staker_rewards, }; + /* TODO: avoid this copy by keeping a reference around? */ + fd_memcpy( &partitioned_stake_reward.stake, &stake_state->inner.stake.stake, FD_STAKE_FOOTPRINT ); - // FD_LOG_WARNING(("STAKE REWARD: %32J %lu", stake_acc->key, redeemed->staker_rewards)); - deq_fd_stake_reward_t_push_tail( stake_reward_deq, stake_reward ); - - // track voter rewards - node->vote_rewards = fd_ulong_sat_add(node->vote_rewards, redeemed->voter_rewards); - node->needs_store = 1; - - fd_stake_state_v2_destroy( &stake_state, &destroy ); - fd_vote_state_versioned_destroy( vote_state_versioned, &destroy ); + /* TODO: use zero-copy API to push to queue */ + deq_fd_partitioned_stake_reward_t_push_tail( result->stake_reward_calculation.stake_reward_deq, partitioned_stake_reward ); } -// return reward info for each vote account -// return account data for each vote account that needs to be stored -// This return value is a little awkward at the moment so that downstream existing code in the non-partitioned rewards code path can be re-used without duplication or modification. -// This function is copied from the existing code path's `store_vote_accounts`. -// The primary differences: -// - we want this fn to have no side effects (such as actually storing vote accounts) so that we -// can compare the expected results with the current code path -// - we want to be able to batch store the vote accounts later for improved performance/cache updating - -/* -Calculates epoch rewards for stake/vote accounts -Returns vote rewards, stake rewards, and the sum of all stake rewards in lamports -*/ +/* Calculates epoch rewards for stake/vote accounts. + Returns vote rewards, stake rewards, and the sum of all stake rewards in lamports. + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L334 */ static void calculate_stake_vote_rewards( - fd_exec_slot_ctx_t * slot_ctx, - fd_stake_history_t const * stake_history, - ulong rewarded_epoch, - fd_point_value_t * point_value, - fd_validator_reward_calculation_t * result + fd_exec_slot_ctx_t * slot_ctx, + fd_stake_history_t const * stake_history, + ulong rewarded_epoch, + fd_point_value_t * point_value, + fd_calculate_stake_vote_rewards_result_t * result ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L3062-L3192 */ fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - fd_acc_lamports_t total_stake_rewards = 0; - fd_stake_reward_t * stake_reward_deq = deq_fd_stake_reward_t_alloc( slot_ctx->valloc ); - fd_vote_reward_t_mapnode_t * vote_reward_map = fd_vote_reward_t_map_alloc( slot_ctx->valloc, 24 ); /* 2^24 slots */ - - for( fd_delegation_pair_t_mapnode_t const * n = fd_delegation_pair_t_map_minimum_const( epoch_bank->stakes.stake_delegations_pool, epoch_bank->stakes.stake_delegations_root ); + /* FIXME: correct value for max */ + /* FIXME: need to clean these up */ + result->stake_reward_calculation.stake_reward_deq = deq_fd_partitioned_stake_reward_t_alloc( slot_ctx->valloc, fd_ulong_pow2( 24 ) ); + result->vote_reward_map_pool = fd_vote_reward_t_map_alloc( slot_ctx->valloc, fd_ulong_pow2( 24 ) ); /* 2^24 slots */ + result->vote_reward_map_root = NULL; + + /* Loop over all the delegations + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L367 */ + for( fd_delegation_pair_t_mapnode_t const * n = fd_delegation_pair_t_map_minimum_const( + epoch_bank->stakes.stake_delegations_pool, epoch_bank->stakes.stake_delegations_root ); n; n = fd_delegation_pair_t_map_successor_const( epoch_bank->stakes.stake_delegations_pool, n ) ) { - // fd_pubkey_t const * voter_acc = &n->elem.delegation.voter_pubkey; fd_pubkey_t const * stake_acc = &n->elem.account; - FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - if( 0!=fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec) ) { - FD_LOG_DEBUG(("Stake acc not found %32J", stake_acc->uc)); - continue; - } - - fd_stake_state_v2_t stake_state = {0}; - int rc = fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - FD_LOG_WARNING(("Failed to read stake state from stake account %32J", stake_acc)); - continue; + FD_BORROWED_ACCOUNT_DECL( stake_acc_rec ); + if( fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec) != 0 ) { + FD_LOG_ERR(( "Stake acc not found %32J", stake_acc->uc )); } - fd_pubkey_t const * voter_acc = &stake_state.inner.stake.stake.delegation.voter_pubkey; - calculate_stake_vote_rewards_account( slot_ctx, stake_history, rewarded_epoch, point_value, voter_acc, stake_acc, stake_reward_deq, vote_reward_map, &total_stake_rewards ); - } - - for ( fd_stake_accounts_pair_t_mapnode_t const * n = fd_stake_accounts_pair_t_map_minimum_const( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, slot_ctx->slot_bank.stake_account_keys.stake_accounts_root ); - n; - n = fd_stake_accounts_pair_t_map_successor_const( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, n) ) { - fd_pubkey_t const * stake_acc = &n->elem.key; - FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - if( 0!=fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, stake_acc_rec) ) { - FD_LOG_DEBUG(("Stake acc not found %32J", stake_acc->uc)); - continue; + fd_stake_state_v2_t stake_state[1] = {0}; + if ( fd_stake_get_state( stake_acc_rec, &slot_ctx->valloc, stake_state ) != 0 ) { + FD_LOG_ERR(( "Failed to read stake state from stake account %32J", stake_acc )); } - - if (stake_acc_rec->const_meta->info.lamports == 0) continue; - - fd_stake_state_v2_t stake_state = {0}; - int rc = fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - FD_LOG_WARNING(("Failed to read stake state from stake account %32J", stake_acc)); - continue; + if ( !fd_stake_state_v2_is_stake( stake_state ) ) { + /* TODO: what is the correct behaviour here? */ + FD_LOG_ERR(( "stake account does not have active delegation" )); } - fd_pubkey_t const * voter_acc = &stake_state.inner.stake.stake.delegation.voter_pubkey; - calculate_stake_vote_rewards_account( slot_ctx, stake_history, rewarded_epoch, point_value, voter_acc, stake_acc, stake_reward_deq, vote_reward_map, &total_stake_rewards ); - - fd_bincode_destroy_ctx_t destroy = {.valloc = slot_ctx->valloc}; - fd_stake_state_v2_destroy( &stake_state, &destroy ); + fd_pubkey_t const * voter_acc = &stake_state->inner.stake.stake.delegation.voter_pubkey; + + calculate_stake_vote_rewards_account( + slot_ctx, + stake_history, + rewarded_epoch, + point_value, + voter_acc, + stake_acc, + stake_acc_rec, + stake_state, + &result->stake_reward_calculation.total_stake_rewards_lamports, + result ); } - // FD_LOG_WARNING(( "TSRL: %lu", total_stake_rewards )); - - *result = (fd_validator_reward_calculation_t) { - .total_stake_rewards_lamports = total_stake_rewards, - .stake_reward_deq = stake_reward_deq, - .vote_reward_map = vote_reward_map - }; + /* TODO: do we also need to loop over the stake accounts in the slot_bank.stake_account_keys.stake_accounts_pool ? I think we probably don't as these only change at epoch boundaries */ } -/* Calculate epoch reward and return vote and stake rewards. */ +/* Calculate epoch reward and return vote and stake rewards. + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L273 */ static void calculate_validator_rewards( fd_exec_slot_ctx_t * slot_ctx, ulong rewarded_epoch, ulong rewards, - fd_validator_reward_calculation_t * result + fd_calculate_validator_rewards_result_t * result ) { /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2759-L2786 */ fd_stake_history_t const * stake_history = fd_sysvar_cache_stake_history( slot_ctx->sysvar_cache ); - if( FD_UNLIKELY( !stake_history ) ) FD_LOG_ERR(( "StakeHistory sysvar is missing from sysvar cache" )); + if( FD_UNLIKELY( !stake_history ) ) { + FD_LOG_ERR(( "StakeHistory sysvar is missing from sysvar cache" )); + } + /* Calculate the epoch reward points from stake/vote accounts */ fd_point_value_t point_value_result[1] = {0}; - calculate_reward_points_partitioned(slot_ctx, stake_history, rewards, point_value_result); - calculate_stake_vote_rewards(slot_ctx, stake_history, rewarded_epoch, point_value_result, result); + calculate_reward_points_partitioned( slot_ctx, stake_history, rewards, point_value_result ); + + /* Calculate the stake and vote rewards for each account */ + calculate_stake_vote_rewards( + slot_ctx, + stake_history, + rewarded_epoch, + point_value_result, + &result->calculate_stake_vote_rewards_result ); } +/* Calculate the number of blocks required to distribute rewards to all stake accounts. -// Calculate the number of blocks required to distribute rewards to all stake accounts. -// fn get_reward_distribution_num_blocks(&self, rewards: &StakeRewards) -> u64 { + https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L214 + */ static ulong get_reward_distribution_num_blocks( fd_epoch_schedule_t const * epoch_schedule, ulong slot, - fd_stake_reward_t * stake_reward_deq + ulong total_stake_accounts ) { /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L1250-L1267 */ - if (epoch_schedule->warmup && fd_slot_to_epoch(epoch_schedule, slot, NULL) < epoch_schedule->first_normal_epoch) { - return 1; + if ( epoch_schedule->warmup && + fd_slot_to_epoch( epoch_schedule, slot, NULL ) < epoch_schedule->first_normal_epoch ) { + return 1UL; } - ulong total_stake_accounts = deq_fd_stake_reward_t_cnt(stake_reward_deq); + ulong num_chunks = total_stake_accounts / (ulong)STAKE_ACCOUNT_STORES_PER_BLOCK + (total_stake_accounts % STAKE_ACCOUNT_STORES_PER_BLOCK != 0); num_chunks = fd_ulong_max(num_chunks, 1); num_chunks = fd_ulong_min( @@ -747,402 +710,337 @@ get_reward_distribution_num_blocks( static void hash_rewards_into_partitions( - fd_slot_bank_t const * bank, - fd_stake_reward_t * stake_reward_deq, + fd_exec_slot_ctx_t * slot_ctx, + fd_partitioned_stake_reward_t * stake_reward_deq, ulong num_partitions, - fd_stake_rewards_vector_t * result + fd_hash_t * parent_blockhash, + fd_partitioned_rewards_calculation_t * result ) { /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/epoch_rewards_hasher.rs#L43C31-L61 */ fd_siphash13_t _sip[1] = {0}; fd_siphash13_t * hasher = fd_siphash13_init( _sip, 0UL, 0UL ); - hasher = fd_siphash13_append( hasher, bank->banks_hash.hash, sizeof(fd_hash_t)); - fd_stake_rewards_vector_new( result ); - for (ulong i = 0; i < num_partitions; ++i) { - fd_stake_rewards_t new_partition; - fd_stake_rewards_new(&new_partition); - fd_stake_rewards_vector_push( result, new_partition); + hasher = fd_siphash13_append( hasher, parent_blockhash->hash, sizeof(fd_hash_t) ); + + result->stake_rewards_by_partition.stake_rewards_by_partition_len = num_partitions; + result->stake_rewards_by_partition.stake_rewards_by_partition = + fd_valloc_malloc( + slot_ctx->valloc, + FD_PARTITIONED_STAKE_REWARDS_ALIGN, + FD_PARTITIONED_STAKE_REWARDS_FOOTPRINT * num_partitions ); + + /* FIXME: remove this large allocation */ + ulong max_partition_size = deq_fd_partitioned_stake_reward_t_cnt( stake_reward_deq ); + for ( ulong i = 0; i < num_partitions; ++i ) { + result->stake_rewards_by_partition.stake_rewards_by_partition[ i ].partition_len = 0UL; + result->stake_rewards_by_partition.stake_rewards_by_partition[ i ].partition = + fd_valloc_malloc( + slot_ctx->valloc, + FD_PARTITIONED_STAKE_REWARD_ALIGN, + FD_PARTITIONED_STAKE_REWARD_FOOTPRINT * max_partition_size ); } for ( - deq_fd_stake_reward_t_iter_t iter = deq_fd_stake_reward_t_iter_init(stake_reward_deq ); - !deq_fd_stake_reward_t_iter_done( stake_reward_deq, iter ); - iter = deq_fd_stake_reward_t_iter_next( stake_reward_deq, iter) + deq_fd_partitioned_stake_reward_t_iter_t iter = deq_fd_partitioned_stake_reward_t_iter_init( + stake_reward_deq ); + !deq_fd_partitioned_stake_reward_t_iter_done( stake_reward_deq, iter ); + iter = deq_fd_partitioned_stake_reward_t_iter_next( stake_reward_deq, iter) ) { - fd_stake_reward_t * ele = deq_fd_stake_reward_t_iter_ele( stake_reward_deq, iter ); + fd_partitioned_stake_reward_t * ele = deq_fd_partitioned_stake_reward_t_iter_ele( stake_reward_deq, iter ); /* hash_address_to_partition: find partition index (0..partitions) by hashing `address` with the `hasher` */ - fd_siphash13_append( hasher, (const uchar *) ele->stake_pubkey.key, sizeof(fd_pubkey_t)); - ulong hash64 = fd_siphash13_fini(hasher); + fd_siphash13_append( hasher, (const uchar *) ele->stake_pubkey.key, sizeof(fd_pubkey_t) ); + ulong hash64 = fd_siphash13_fini( hasher ); /* hash_to_partition */ + /* FIXME: should be saturating add */ ulong partition_index = (ulong)( (uint128) num_partitions * (uint128) hash64 / ((uint128)ULONG_MAX + 1) ); - fd_stake_rewards_push(&result->elems[partition_index], ele); + + /* FIXME: avoid this copy */ + result->stake_rewards_by_partition.stake_rewards_by_partition[ partition_index ].partition[ result->stake_rewards_by_partition.stake_rewards_by_partition[ num_partitions ].partition_len++ ] = *ele; } } -// Calculate rewards from previous epoch to prepare for partitioned distribution. +/* Calculate rewards from previous epoch to prepare for partitioned distribution. + + https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L214 */ static void calculate_rewards_for_partitioning( fd_exec_slot_ctx_t * slot_ctx, ulong prev_epoch, + fd_hash_t * parent_blockhash, fd_partitioned_rewards_calculation_t * result ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2356-L2403 */ + /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L227 */ fd_prev_epoch_inflation_rewards_t rewards; + calculate_previous_epoch_inflation_rewards( slot_ctx, slot_ctx->slot_bank.capitalization, prev_epoch, &rewards ); + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); fd_slot_bank_t const * slot_bank = &slot_ctx->slot_bank; - calculate_previous_epoch_inflation_rewards( slot_ctx, epoch_bank, slot_bank->slot, slot_bank->capitalization, prev_epoch, &rewards ); - - ulong old_vote_balance_and_staked = vote_balance_and_staked(slot_ctx, &epoch_bank->stakes); - - fd_validator_reward_calculation_t validator_result[1] = {0}; - calculate_validator_rewards(slot_ctx, prev_epoch, rewards.validator_rewards, validator_result); + ulong old_vote_balance_and_staked = vote_balance_and_staked( slot_ctx, &epoch_bank->stakes ); - ulong num_partitions = get_reward_distribution_num_blocks(&epoch_bank->epoch_schedule, slot_bank->slot, validator_result->stake_reward_deq); + fd_calculate_validator_rewards_result_t validator_result[1] = {0}; + calculate_validator_rewards( slot_ctx, prev_epoch, rewards.validator_rewards, validator_result ); - fd_stake_rewards_vector_t hash_rewards_result = {0}; - hash_rewards_into_partitions(slot_bank, validator_result->stake_reward_deq, num_partitions, &hash_rewards_result); + /* TODO: pass data structures along */ + ulong num_partitions = get_reward_distribution_num_blocks( + &epoch_bank->epoch_schedule, + slot_bank->slot, + deq_fd_partitioned_stake_reward_t_cnt( validator_result->calculate_stake_vote_rewards_result.stake_reward_calculation.stake_reward_deq ) ); - /* free stake_reward_deq */ - deq_fd_stake_reward_t_delete( validator_result->stake_reward_deq ); - - *result = (fd_partitioned_rewards_calculation_t) { - .vote_account_rewards = validator_result->vote_reward_map, - .stake_rewards_by_partition = { hash_rewards_result }, - .total_stake_rewards_lamports = validator_result->total_stake_rewards_lamports, - .old_vote_balance_and_staked = old_vote_balance_and_staked, - .validator_rewards = rewards.validator_rewards, - .validator_rate = rewards.validator_rate, - .foundation_rate = rewards.foundation_rate, - .prev_epoch_duration_in_years = rewards.prev_epoch_duration_in_years, - .capitalization = slot_bank->capitalization - }; + hash_rewards_into_partitions( + slot_ctx, + validator_result->calculate_stake_vote_rewards_result.stake_reward_calculation.stake_reward_deq, + num_partitions, + parent_blockhash, + result ); + + /* TODO: free stake deque */ + + result->vote_reward_map_pool = validator_result->calculate_stake_vote_rewards_result.vote_reward_map_pool; + result->vote_reward_map_root = validator_result->calculate_stake_vote_rewards_result.vote_reward_map_root; + result->old_vote_balance_and_staked = old_vote_balance_and_staked; + result->validator_rewards = rewards.validator_rewards; + result->validator_rate = rewards.validator_rate; + result->foundation_rate = rewards.foundation_rate; + result->prev_epoch_duration_in_years = rewards.prev_epoch_duration_in_years; + result->capitalization = slot_bank->capitalization; + result->total_points = validator_result->total_points; } -/* (TODO) unclear if we need to implement update_reward_history function on solana side. So far it doesn't do much other than logging / record keeping */ -/* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L3471-L3484 */ -// static void -// update_reward_history( -// ) { -// return; -// } - -// Calculate rewards from previous epoch and distribute vote rewards +/* Calculate rewards from previous epoch and distribute vote rewards + + https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L97 */ static void calculate_rewards_and_distribute_vote_rewards( fd_exec_slot_ctx_t * slot_ctx, ulong prev_epoch, + fd_hash_t * parent_blockhash, fd_calculate_rewards_and_distribute_vote_rewards_result_t * result ) { /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2406-L2492 */ fd_partitioned_rewards_calculation_t rewards_calc_result[1] = {0}; - calculate_rewards_for_partitioning(slot_ctx, prev_epoch, rewards_calc_result); - fd_vote_reward_t_mapnode_t * ref = rewards_calc_result->vote_account_rewards; - for (ulong i = 0; i < fd_vote_reward_t_map_slot_cnt( rewards_calc_result->vote_account_rewards); ++i) { - if (fd_vote_reward_t_map_key_equal( ref[i].vote_pubkey, fd_vote_reward_t_map_key_null() ) ) { - continue; - } - fd_pubkey_t const * vote_pubkey = &ref[i].vote_pubkey; - ulong min_data_sz = 0UL; - FD_BORROWED_ACCOUNT_DECL(vote_rec); - int err = fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, vote_pubkey, 1, min_data_sz, vote_rec); - FD_TEST( err == 0 ); - vote_rec->meta->info.lamports = fd_ulong_sat_add(vote_rec->meta->info.lamports, ref[i].vote_rewards); + calculate_rewards_for_partitioning( slot_ctx, prev_epoch, parent_blockhash, rewards_calc_result ); + + /* Iterate over all the vote reward nodes, deleting as we go */ + fd_vote_reward_t_mapnode_t* next_vote_reward_node; + for ( fd_vote_reward_t_mapnode_t* vote_reward_node = fd_vote_reward_t_map_minimum( + rewards_calc_result->vote_reward_map_pool, + rewards_calc_result->vote_reward_map_root); + vote_reward_node; + vote_reward_node = next_vote_reward_node ) { + + fd_pubkey_t const * vote_pubkey = &vote_reward_node->elem.pubkey; + FD_BORROWED_ACCOUNT_DECL( vote_rec ); + FD_TEST( fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, vote_pubkey, 1, 0UL, vote_rec ) == FD_ACC_MGR_SUCCESS ); + + FD_TEST( fd_borrowed_account_checked_add_lamports( vote_rec, vote_reward_node->elem.vote_rewards ) == 0 ); + + next_vote_reward_node = fd_vote_reward_t_map_successor( rewards_calc_result->vote_reward_map_pool, vote_reward_node ); + + /* TODO: delete vote reward node */ } - /* TODO: update_reward_history (not sure if reward history is ever needed?) */ - // update_reward_history(); // This is for vote rewards only. fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); + + /* TODO: make sure this works for the vote accounts */ ulong new_vote_balance_and_staked = vote_balance_and_staked( slot_ctx, &epoch_bank->stakes ); - ulong validator_rewards_paid = fd_ulong_sat_sub(new_vote_balance_and_staked, rewards_calc_result->old_vote_balance_and_staked); + ulong validator_rewards_paid = fd_ulong_sat_sub( new_vote_balance_and_staked, rewards_calc_result->old_vote_balance_and_staked ); // verify that we didn't pay any more than we expected to - FD_TEST( rewards_calc_result->validator_rewards >= fd_ulong_sat_add(validator_rewards_paid, rewards_calc_result->total_stake_rewards_lamports)); - - FD_LOG_NOTICE(( - "distributed vote rewards: %lu out of %lu, remaining %lu", - validator_rewards_paid, - rewards_calc_result->validator_rewards, - rewards_calc_result->total_stake_rewards_lamports - )); + result->total_rewards = fd_ulong_sat_add( validator_rewards_paid, rewards_calc_result->stake_rewards_by_partition.total_stake_rewards_lamports ); + FD_TEST( rewards_calc_result->validator_rewards >= result->total_rewards ); slot_ctx->slot_bank.capitalization += validator_rewards_paid; - /* - // only useful for logging - ulong active_stake = 0; - for ( fd_stake_history_epochentry_pair_t_mapnode_t * n = fd_stake_history_epochentry_pair_t_map_minimum( bank->stakes.stake_history.entries_pool, bank->stakes.stake_history.entries_root ); n; n = fd_stake_history_epochentry_pair_t_map_successor( bank->stakes.stake_history.entries_pool, n ) ) { - if (bank->stakes.stake_history.entries_pool->elem.epoch == prev_epoch) { - active_stake = bank->stakes.stake_history.entries_pool->elem.entry.effective; - break; - } - } - */ - /* free vote reward map */ - fd_vote_reward_t_map_delete( rewards_calc_result->vote_account_rewards ); - - result->total_rewards = fd_ulong_sat_add(validator_rewards_paid, rewards_calc_result->total_stake_rewards_lamports); result->distributed_rewards = validator_rewards_paid; - *result->stake_rewards_by_partition = *rewards_calc_result->stake_rewards_by_partition; -} -static void -bank_redeem_rewards( - fd_exec_slot_ctx_t * slot_ctx, - ulong rewarded_epoch, - fd_point_value_t * point_value, - fd_stake_history_t const * stake_history, - fd_validator_reward_calculation_t * result -) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L3194-L3288 */ - /* the current implement relies on partitioned version with no thread pool*/ - calculate_stake_vote_rewards( slot_ctx, stake_history, rewarded_epoch, point_value, result ); + result->stake_rewards_by_partition = rewards_calc_result->stake_rewards_by_partition; + result->total_points = rewards_calc_result->total_points; } -static void -calculate_reward_points( - fd_exec_slot_ctx_t * slot_ctx, - fd_stake_history_t const * stake_history, - ulong rewards, - fd_point_value_t * result -) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L3020-L3058 */ - /* the current implement relies on partitioned version with no thread pool*/ - calculate_reward_points_partitioned( slot_ctx, stake_history, rewards, result ); +/* Distributes a single partitioned reward to a single stake account */ +static int +distribute_epoch_reward_to_stake_acc( + fd_exec_slot_ctx_t * slot_ctx, + fd_pubkey_t * stake_pubkey, + ulong reward_lamports + ) { + + FD_BORROWED_ACCOUNT_DECL( stake_acc_rec ); + FD_TEST( fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_pubkey, 0, 0UL, stake_acc_rec ) == FD_ACC_MGR_SUCCESS ); + + fd_stake_state_v2_t stake_state[1] = {0}; + if ( fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, stake_state) != 0 ) { + FD_LOG_DEBUG(( "failed to read stake state for %32J", stake_pubkey )); + return 1; + } + + if ( !fd_stake_state_v2_is_stake( stake_state ) ) { + /* FIXME: can this happen? what if the stake account changes? */ + FD_LOG_ERR(( "non-stake stake account, this should never happen" )); + } + + if( fd_borrowed_account_checked_add_lamports( stake_acc_rec, reward_lamports ) ) { + FD_LOG_DEBUG(( "failed to add lamports to stake account" )); + return 1; + } + + stake_state->inner.stake.stake.delegation.stake = fd_ulong_sat_add( + stake_state->inner.stake.stake.delegation.stake, + reward_lamports + ); + + return 0; } -// pay_validator_rewards_with_thread_pool -/* Load, calculate and payout epoch rewards for stake and vote accounts */ +/* 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 -pay_validator_rewards( - fd_exec_slot_ctx_t * slot_ctx, - ulong rewarded_epoch, - ulong rewards +distribute_epoch_rewards_in_partition( + fd_partitioned_stake_rewards_t * all_stake_rewards, + ulong all_stake_rewards_len, + ulong partition_index, + fd_exec_slot_ctx_t * slot_ctx ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2789-L2839 */ - fd_stake_history_t const * stake_history = fd_sysvar_cache_stake_history( slot_ctx->sysvar_cache ); - if( FD_UNLIKELY( !stake_history ) ) FD_LOG_ERR(( "StakeHistory sysvar is missing from sysvar cache" )); - fd_point_value_t point_value_result[1] = {{0}}; - calculate_reward_points(slot_ctx, stake_history, rewards, point_value_result); - fd_validator_reward_calculation_t rewards_calc_result[1] = {0}; - bank_redeem_rewards( slot_ctx, rewarded_epoch, point_value_result, stake_history, rewards_calc_result ); - - ulong validator_rewards_paid = 0; - - /* store vote accounts */ - fd_vote_reward_t_mapnode_t * ref = rewards_calc_result->vote_reward_map; - FD_LOG_DEBUG(("Num vote rewards %lu", fd_vote_reward_t_map_key_cnt( rewards_calc_result->vote_reward_map))); - for (ulong i = 0; i < fd_vote_reward_t_map_slot_cnt( rewards_calc_result->vote_reward_map); ++i) { - if (fd_vote_reward_t_map_key_equal( ref[i].vote_pubkey, fd_vote_reward_t_map_key_null() ) ) { - continue; - } - fd_pubkey_t const * vote_pubkey = &ref[i].vote_pubkey; - if (ref[i].vote_rewards == 0 && !ref[i].needs_store) { - continue; - } - FD_LOG_DEBUG(("Vote reward for %32J %lu", vote_pubkey->uc, ref[i].vote_rewards)); - ulong min_data_sz = 0UL; - FD_BORROWED_ACCOUNT_DECL(vote_rec); - int err = fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, vote_pubkey, 1, min_data_sz, vote_rec); - FD_TEST( err == 0 ); - vote_rec->meta->info.lamports = fd_ulong_sat_add(vote_rec->meta->info.lamports, ref[i].vote_rewards); - vote_rec->meta->slot = slot_ctx->slot_bank.slot; - validator_rewards_paid = fd_ulong_sat_add(validator_rewards_paid, ref[i].vote_rewards); - } - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - FD_LOG_DEBUG(("Num stake rewards %lu", deq_fd_stake_reward_t_cnt( rewards_calc_result->stake_reward_deq ))); - /* store stake accounts */ - for ( - deq_fd_stake_reward_t_iter_t iter = deq_fd_stake_reward_t_iter_init(rewards_calc_result->stake_reward_deq ); - !deq_fd_stake_reward_t_iter_done( rewards_calc_result->stake_reward_deq, iter ); - iter = deq_fd_stake_reward_t_iter_next( rewards_calc_result->stake_reward_deq, iter) - ) { - fd_stake_reward_t * ele = deq_fd_stake_reward_t_iter_ele( rewards_calc_result->stake_reward_deq, iter ); - fd_pubkey_t const * stake_pubkey = &ele->stake_pubkey; - - ulong min_data_sz = 0UL; - FD_BORROWED_ACCOUNT_DECL(stake_rec); - int err = fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_pubkey, 1, min_data_sz, stake_rec); - FD_TEST( err == 0 ); - FD_LOG_DEBUG(("Stake reward for %32J Existing %lu reward lamps %lu staker reward %lu credits observed %lu", stake_pubkey->uc, stake_rec->meta->info.lamports, ele->reward_info.lamports, ele->reward_info.staker_rewards, ele->reward_info.new_credits_observed)); - stake_rec->meta->info.lamports = fd_ulong_sat_add(stake_rec->meta->info.lamports, ele->reward_info.lamports); - stake_rec->meta->slot = slot_ctx->slot_bank.slot; - validator_rewards_paid = fd_ulong_sat_add(validator_rewards_paid, ele->reward_info.lamports); + FD_TEST( partition_index < all_stake_rewards_len ); + fd_partitioned_stake_rewards_t * this_partition_stake_rewards = &all_stake_rewards[ partition_index ]; - fd_stake_state_v2_t stake_state; - int rc = fd_stake_get_state(stake_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - FD_LOG_ERR(("failed to read stake state for %32J", stake_pubkey )); - } + ulong lamports_distributed = 0UL; + ulong lamports_burned = 0UL; + + for ( ulong i = 0; i < this_partition_stake_rewards->partition_len; i++ ) { + fd_partitioned_stake_reward_t * partitioned_reward = &this_partition_stake_rewards->partition[ i ]; + ulong reward_amount = partitioned_reward->stake_reward_info.lamports; - /* implements the `redeem_stake_rewards` solana function */ - stake_state.inner.stake.stake.credits_observed = ele->reward_info.new_credits_observed; - stake_state.inner.stake.stake.delegation.stake += ele->reward_info.staker_rewards; - fd_delegation_pair_t_mapnode_t query_node; - fd_memcpy(&query_node.elem.account, stake_pubkey, sizeof(fd_pubkey_t)); - fd_delegation_pair_t_mapnode_t * node = fd_delegation_pair_t_map_find(epoch_bank->stakes.stake_delegations_pool, epoch_bank->stakes.stake_delegations_root, &query_node); - if (node != NULL) { - node->elem.delegation.stake += ele->reward_info.staker_rewards; + if ( distribute_epoch_reward_to_stake_acc( slot_ctx, &partitioned_reward->stake_pubkey, reward_amount ) == 0 ) { + lamports_distributed += reward_amount; + } else { + lamports_burned += reward_amount; } - /* write_stake_state */ - err = write_stake_state( slot_ctx, stake_pubkey, &stake_state, 0); - FD_TEST( err == 0 ); - } + FD_BORROWED_ACCOUNT_DECL( stake_acc_rec ); + FD_TEST( fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, &partitioned_reward->stake_pubkey, 0, 0UL, stake_acc_rec ) == FD_ACC_MGR_SUCCESS ); - // FD_LOG_WARNING(("REWARDS PAID: %lu POST_CAP: %lu", validator_rewards_paid, slot_ctx->slot_bank.capitalization )); - slot_ctx->slot_bank.capitalization = fd_ulong_sat_add(slot_ctx->slot_bank.capitalization, validator_rewards_paid); + FD_TEST( fd_borrowed_account_checked_add_lamports( stake_acc_rec, partitioned_reward->stake_reward_info.lamports ) == 0 ); + } - /* free stake_reward_deq and vote_reward_map */ - fd_valloc_free(slot_ctx->valloc, deq_fd_stake_reward_t_delete( deq_fd_stake_reward_t_leave( rewards_calc_result->stake_reward_deq ) ) ); - fd_valloc_free(slot_ctx->valloc, fd_vote_reward_t_map_delete( fd_vote_reward_t_map_leave( rewards_calc_result->vote_reward_map ) ) ); + FD_LOG_DEBUG(( "lamports burned: %lu, lamports distributed: %lu", lamports_burned, lamports_distributed )); - // self.update_reward_history(stake_rewards, vote_rewards); } -// update rewards based on the previous epoch -// non thread pool version below +/* Process reward distribution for the block if it is inside reward interval. + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/distribution.rs#L42 */ void -fd_update_rewards( - fd_exec_slot_ctx_t * slot_ctx, - ulong prev_epoch +fd_distribute_partitioned_epoch_rewards( + fd_exec_slot_ctx_t * slot_ctx ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2515-L2599 */ - /* calculate_previous_epoch_inflation_rewards */ - fd_prev_epoch_inflation_rewards_t rewards; - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); + if ( !fd_epoch_reward_status_is_Active( &slot_ctx->epoch_reward_status ) ) { + return; + } + fd_start_block_height_and_rewards_t * status = &slot_ctx->epoch_reward_status.inner.Active; + fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; - calculate_previous_epoch_inflation_rewards( slot_ctx, epoch_bank, slot_bank->slot, slot_bank->capitalization, prev_epoch, &rewards); - /* pay_validator_rewards_with_thread_pool */ - pay_validator_rewards(slot_ctx, prev_epoch, rewards.validator_rewards); -} + ulong height = slot_bank->block_height; + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank_const( slot_ctx->epoch_ctx ); + + ulong distribution_starting_block_height = status->distribution_starting_block_height; + ulong distribution_end_exclusive = distribution_starting_block_height + status->stake_rewards_by_partition_len; + + /* FIXME: track current epoch in epoch ctx? */ + ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_bank->slot, NULL ); + FD_TEST( get_slots_in_epoch( epoch, epoch_bank ) > status->stake_rewards_by_partition_len ); + + if ( ( height >= distribution_starting_block_height ) && ( height < distribution_end_exclusive ) ) { + ulong partition_index = height - distribution_starting_block_height; + distribute_epoch_rewards_in_partition( + status->stake_rewards_by_partition, + status->stake_rewards_by_partition_len, + partition_index, + slot_ctx + ); + } -/* fd_begin_partitioned_rewards: Begin the process of calculating and - distributing rewards. This process can take multiple slots. */ + /* If we have finished distributing rewards, set the status to inactive */ + if ( fd_ulong_sat_add( height, 1UL ) >= distribution_end_exclusive ) { + slot_ctx->epoch_reward_status.discriminant = fd_epoch_reward_status_enum_Inactive; + fd_sysvar_epoch_rewards_set_inactive( slot_ctx ); + } +} -// https://github.com/anza-xyz/agave/blob/2d722719a2c74ec4e180b255124c7204ef98ee6c/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L35 +/* Non-partitioned epoch rewards entry-point. This uses the same logic as the partitioned epoch rewards code, + but distributes the rewards in one go. */ void -fd_begin_partitioned_rewards( +fd_update_rewards( fd_exec_slot_ctx_t * slot_ctx, + fd_hash_t * blockhash, ulong parent_epoch ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L1613-L1651 */ + + /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L55 */ fd_calculate_rewards_and_distribute_vote_rewards_result_t rewards_result[1] = {0}; calculate_rewards_and_distribute_vote_rewards( slot_ctx, parent_epoch, + blockhash, rewards_result ); - ulong credit_end_exclusive = slot_ctx->slot_bank.block_height + REWARD_CALCULATION_NUM_BLOCK + rewards_result->stake_rewards_by_partition->cnt; - FD_LOG_DEBUG(("self->block_height=%lu, rewards_result->stake_rewards_by_parrition->cnt=%lu", slot_ctx->slot_bank.block_height, rewards_result->stake_rewards_by_partition->cnt)); - - // self.set_epoch_reward_status_active(stake_rewards_by_partition); - slot_ctx->epoch_reward_status = (fd_epoch_reward_status_t){ - .is_active = 1, - .stake_rewards_by_partition = { *rewards_result->stake_rewards_by_partition }, - .start_block_height = slot_ctx->slot_bank.block_height - }; - // create EpochRewards sysvar that holds the balance of undistributed rewards with - // (total_rewards, distributed_rewards, credit_end_exclusive), total capital will increase by (total_rewards - distributed_rewards) - fd_sysvar_epoch_rewards_init( slot_ctx, rewards_result->total_rewards, rewards_result->distributed_rewards, credit_end_exclusive); -} -/* Process reward distribution for the block if it is inside reward interval. */ -void -fd_distribute_partitioned_epoch_rewards( - fd_exec_slot_ctx_t * slot_ctx -) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L1654-L1687 */ - /* make sure we are inside the reward interval */ - if ( !slot_ctx->epoch_reward_status.is_active ) { - return; - } - - ulong validator_rewards_paid = 0; - - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; - - ulong credit_start = slot_ctx->epoch_reward_status.start_block_height + REWARD_CALCULATION_NUM_BLOCK; - ulong credit_end_exclusive = credit_start + slot_ctx->epoch_reward_status.stake_rewards_by_partition->cnt; - if (slot_bank->block_height >= credit_start && slot_bank->block_height < credit_end_exclusive) { - ulong partition_index = slot_bank->block_height - credit_start; - ulong total_rewards_in_lamports = 0UL; - fd_stake_rewards_t this_partition_stake_rewards = slot_ctx->epoch_reward_status.stake_rewards_by_partition->elems[partition_index]; - for (uint i = 0; i < this_partition_stake_rewards.cnt; ++i) { - total_rewards_in_lamports = fd_ulong_sat_add(total_rewards_in_lamports, this_partition_stake_rewards.elems[i]->reward_info.lamports); - // store rewards into accounts - fd_pubkey_t const * stake_acc = &this_partition_stake_rewards.elems[i]->stake_pubkey; - FD_BORROWED_ACCOUNT_DECL(stake_acc_rec); - FD_TEST( 0==fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, stake_acc, 0, 0UL, stake_acc_rec ) ); - stake_acc_rec->meta->info.lamports += this_partition_stake_rewards.elems[i]->reward_info.lamports; - validator_rewards_paid = fd_ulong_sat_add(validator_rewards_paid, this_partition_stake_rewards.elems[i]->reward_info.lamports); - - fd_stake_state_v2_t stake_state = {0}; - int rc = fd_stake_get_state(stake_acc_rec, &slot_ctx->valloc, &stake_state); - if ( rc != 0 ) { - FD_LOG_ERR(("failed to read stake state for %32J", &this_partition_stake_rewards.elems[i]->stake_pubkey )); - } - // fd_stake_state_t stake_state; - // read_stake_state( global, stake_acc_rec->meta, &stake_state ); - // if (!fd_stake_state_is_stake( &stake_state)) { - // FD_LOG_ERR(("failed to read stake state for %32J", &this_partition_stake_rewards.elems[i]->stake_pubkey )); - // } - - /* implements the `redeem_stake_rewards` solana function */ - stake_state.inner.stake.stake.credits_observed = this_partition_stake_rewards.elems[i]->reward_info.new_credits_observed; - stake_state.inner.stake.stake.delegation.stake += this_partition_stake_rewards.elems[i]->reward_info.staker_rewards; - fd_delegation_pair_t_mapnode_t query_node; - fd_memcpy(&query_node.elem.account, stake_acc, sizeof(fd_pubkey_t)); - fd_delegation_pair_t_mapnode_t * node = fd_delegation_pair_t_map_find(epoch_bank->stakes.stake_delegations_pool, epoch_bank->stakes.stake_delegations_root, &query_node); - if (node != NULL) { - node->elem.delegation.stake += this_partition_stake_rewards.elems[i]->reward_info.staker_rewards; - } - - /* write_stake_state */ - int err = write_stake_state( slot_ctx, stake_acc, &stake_state, 0); - FD_TEST( err == 0 ); - - } - - // increase total capitalization by the distributed rewards - slot_bank->capitalization = fd_ulong_sat_add(slot_bank->capitalization, total_rewards_in_lamports); - - // decrease distributed capital from epoch rewards sysvar - fd_sysvar_epoch_rewards_update( slot_ctx, total_rewards_in_lamports ); - - // update reward history for this partitioned distribution - // self.update_reward_history_in_partition(this_partition_stake_rewards); - } - - if ( fd_ulong_sat_add(slot_bank->block_height, 1) >= credit_end_exclusive ) { - // deactivate epoch reward status - slot_ctx->epoch_reward_status.is_active = 0; - // burn and purge EpochRewards sysvar account - fd_sysvar_epoch_rewards_burn_and_purge( slot_ctx ); - // fixing leaks - for ( ulong i = 0; i < slot_ctx->epoch_reward_status.stake_rewards_by_partition->cnt; ++i ) { - fd_stake_rewards_destroy( &slot_ctx->epoch_reward_status.stake_rewards_by_partition->elems[i] ); - } - fd_stake_rewards_vector_destroy( slot_ctx->epoch_reward_status.stake_rewards_by_partition ); + /* Distribute all of the partitioned epoch rewards in one go */ + for ( ulong i = 0UL; i < rewards_result->stake_rewards_by_partition.stake_rewards_by_partition_len; i++ ) { + distribute_epoch_rewards_in_partition( + rewards_result->stake_rewards_by_partition.stake_rewards_by_partition, + rewards_result->stake_rewards_by_partition.stake_rewards_by_partition_len, + i, + slot_ctx + ); } - - slot_ctx->slot_bank.capitalization = fd_ulong_sat_add(slot_ctx->slot_bank.capitalization, validator_rewards_paid); } +/* Partitioned epoch rewards entry-point. + + https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L41 +*/ void -fd_calculate_inflation_rates( fd_exec_slot_ctx_t * slot_ctx, - fd_inflation_rates_t * rates ) { - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong slot_idx = 0; - rates->epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot, &slot_idx ); - ulong num_slots = get_inflation_num_slots( slot_ctx, &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot ); - double slot_in_year = (double)num_slots / epoch_bank->slots_per_year; - rates->validator = validator( &epoch_bank->inflation, slot_in_year ); - rates->foundation = foundation(&epoch_bank->inflation, slot_in_year); - rates->total = total(&epoch_bank->inflation, slot_in_year); +fd_begin_partitioned_rewards( + fd_exec_slot_ctx_t * slot_ctx, + fd_hash_t * blockhash, + ulong parent_epoch +) { + /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L55 */ + fd_calculate_rewards_and_distribute_vote_rewards_result_t rewards_result[1] = {0}; + calculate_rewards_and_distribute_vote_rewards( + slot_ctx, + parent_epoch, + blockhash, + rewards_result + ); + + /* https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L62 */ + ulong distribution_starting_block_height = slot_ctx->slot_bank.block_height + REWARD_CALCULATION_NUM_BLOCKS; + + /* Set the epoch reward status to be 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->epoch_reward_status.inner.Active.stake_rewards_by_partition_len = rewards_result->stake_rewards_by_partition.stake_rewards_by_partition_len; + slot_ctx->epoch_reward_status.inner.Active.stake_rewards_by_partition = rewards_result->stake_rewards_by_partition.stake_rewards_by_partition; + + /* Initialise the epoch rewards sysvar + + https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L78 */ + fd_sysvar_epoch_rewards_init( + slot_ctx, + rewards_result->total_rewards, + rewards_result->distributed_rewards, + distribution_starting_block_height, + rewards_result->stake_rewards_by_partition.stake_rewards_by_partition_len, + rewards_result->total_points, + blockhash + ); } diff --git a/src/flamenco/rewards/fd_rewards.h b/src/flamenco/rewards/fd_rewards.h index 1a83827c10..1df6298fc9 100644 --- a/src/flamenco/rewards/fd_rewards.h +++ b/src/flamenco/rewards/fd_rewards.h @@ -14,27 +14,18 @@ FD_PROTOTYPES_BEGIN void fd_update_rewards( fd_exec_slot_ctx_t * slot_ctx, + fd_hash_t * blockhash, ulong prev_epoch ); void -fd_begin_partitioned_rewards( fd_exec_slot_ctx_t * slot_ctx, - ulong parent_epoch ); +fd_begin_partitioned_rewards( + fd_exec_slot_ctx_t * slot_ctx, + fd_hash_t * blockhash, + ulong parent_epoch ); void fd_distribute_partitioned_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx ); -struct fd_inflation_rates { - ulong epoch; - double foundation; - double total; - double validator; -}; -typedef struct fd_inflation_rates fd_inflation_rates_t; - -void -fd_calculate_inflation_rates( fd_exec_slot_ctx_t * slot_ctx, - fd_inflation_rates_t * rates ); - FD_PROTOTYPES_END #endif diff --git a/src/flamenco/rewards/fd_rewards_types.h b/src/flamenco/rewards/fd_rewards_types.h index 882c8ca87d..e57cf93be7 100644 --- a/src/flamenco/rewards/fd_rewards_types.h +++ b/src/flamenco/rewards/fd_rewards_types.h @@ -16,106 +16,16 @@ #undef VECT_NAME #undef VECT_ELEMENT -/* reward calculation happens synchronously during the first block of the epoch boundary. - So, # blocks for reward calculation is 1. */ -#define REWARD_CALCULATION_NUM_BLOCK 1 -/* stake accounts to store in one block during partitioned reward interval Target to store 64 rewards per entry/tick in a block. A block has a minimum of 64 entries/tick. This gives 4096 total rewards to store in one block. This constant affects consensus. */ -#define STAKE_ACCOUNT_STORES_PER_BLOCK 4096 -#define TEST_ENABLE_PARTITIONED_REWARDS 0 -#define TEST_COMPARE_PARTITIONED_EPOCH_REWARDS 0 -#define MAX_FACTOR_OF_REWARD_BLOCKS_IN_EPOCH 10 - -struct fd_vote_reward_t_mapnode { - fd_pubkey_t vote_pubkey; - ulong vote_rewards; - uchar commission; - uchar needs_store; -}; - -typedef struct fd_vote_reward_t_mapnode fd_vote_reward_t_mapnode_t; - -#define MAP_NAME fd_vote_reward_t_map -#define MAP_T fd_vote_reward_t_mapnode_t -#define MAP_MEMOIZE 0 -#define MAP_KEY vote_pubkey -#define MAP_KEY_T fd_pubkey_t -#define MAP_KEY_NULL (fd_pubkey_t){0} -#define MAP_KEY_INVAL(k) MAP_KEY_EQUAL((k),MAP_KEY_NULL) -#define MAP_KEY_EQUAL(k0,k1) (!memcmp((k0).key, (k1).key, sizeof( fd_pubkey_t ) )) -#define MAP_KEY_EQUAL_IS_SLOW 1 -#define MAP_KEY_HASH(key) ((uint)fd_ulong_hash( fd_ulong_load_8( (key).key ) )) -#define MAP_KEY_MOVE(kd,ks) memcpy( &(kd), &(ks),sizeof(fd_pubkey_t)) -#include "../../util/tmpl/fd_map_dynamic.c" -static inline fd_vote_reward_t_mapnode_t * -fd_vote_reward_t_map_alloc( fd_valloc_t valloc, int lg_slot_cnt ) { - void * mem = fd_valloc_malloc( valloc, fd_vote_reward_t_map_align(), fd_vote_reward_t_map_footprint( lg_slot_cnt )); - return fd_vote_reward_t_map_join(fd_vote_reward_t_map_new(mem, lg_slot_cnt)); -} - - -#define DEQUE_NAME deq_fd_stake_reward_t -#define DEQUE_T fd_stake_reward_t -#define DEQUE_MAX 2000000UL -#include "../../util/tmpl/fd_deque.c" -static inline fd_stake_reward_t * -deq_fd_stake_reward_t_alloc( fd_valloc_t valloc ) { - void * mem = fd_valloc_malloc( valloc, deq_fd_stake_reward_t_align(), deq_fd_stake_reward_t_footprint()); - return deq_fd_stake_reward_t_join( deq_fd_stake_reward_t_new( mem ) ); -} - -struct fd_validator_reward_calculation { - fd_acc_lamports_t total_stake_rewards_lamports; - fd_stake_reward_t * stake_reward_deq; - fd_vote_reward_t_mapnode_t * vote_reward_map; -}; -typedef struct fd_validator_reward_calculation fd_validator_reward_calculation_t; +/* Number of blocks for reward calculation and storing vote accounts. + Distributing rewards to stake accounts begins AFTER this many blocks. + + https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L27 */ +#define REWARD_CALCULATION_NUM_BLOCKS ( 1UL ) -struct fd_partitioned_rewards_calculation { - /* VoteRewardsAccount */ - fd_vote_reward_t_mapnode_t * vote_account_rewards; - fd_stake_rewards_vector_t stake_rewards_by_partition[1]; - ulong total_stake_rewards_lamports; - ulong old_vote_balance_and_staked; - ulong validator_rewards; - double validator_rate; - double foundation_rate; - double prev_epoch_duration_in_years; - ulong capitalization; -}; -typedef struct fd_partitioned_rewards_calculation fd_partitioned_rewards_calculation_t; - -struct fd_point_value { - ulong rewards; - uint128 points; -}; -typedef struct fd_point_value fd_point_value_t; - -struct fd_calculated_stake_rewards{ - ulong staker_rewards; - ulong voter_rewards; - ulong new_credits_observed; -}; -typedef struct fd_calculated_stake_rewards fd_calculated_stake_rewards_t; - -struct fd_calculate_stake_points { - uint128 points; - ulong new_credits_observed; - uint force_credits_update_with_skipped_reward; -}; -typedef struct fd_calculate_stake_points fd_calculate_stake_points_t; - -struct fd_calculate_rewards_and_distribute_vote_rewards_result { - ulong total_rewards; - ulong distributed_rewards; - fd_stake_rewards_vector_t stake_rewards_by_partition[1]; -}; -typedef struct fd_calculate_rewards_and_distribute_vote_rewards_result fd_calculate_rewards_and_distribute_vote_rewards_result_t; - -struct fd_epoch_reward_status { - uint is_active; - ulong start_block_height; - fd_stake_rewards_vector_t stake_rewards_by_partition[1]; -}; -typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; +/* stake accounts to store in one block during partitioned reward interval Target to store 64 rewards per entry/tick in a block. A block has a minimum of 64 entries/tick. This gives 4096 total rewards to store in one block. This constant affects consensus. */ +#define STAKE_ACCOUNT_STORES_PER_BLOCK ( 4096UL ) +#define TEST_ENABLE_PARTITIONED_REWARDS ( 0UL ) +#define TEST_COMPARE_PARTITIONED_EPOCH_REWARDS ( 0UL ) +#define MAX_FACTOR_OF_REWARD_BLOCKS_IN_EPOCH ( 10UL ) #endif /* HEADER_fd_src_flamenco_runtime_program_fd_rewards_types_h */ diff --git a/src/flamenco/runtime/context/fd_exec_slot_ctx.c b/src/flamenco/runtime/context/fd_exec_slot_ctx.c index 0eac608df0..5257a41727 100644 --- a/src/flamenco/runtime/context/fd_exec_slot_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_slot_ctx.c @@ -394,6 +394,7 @@ fd_exec_slot_ctx_free( fd_exec_slot_ctx_t * slot_ctx ) { /* leader points to a caller-allocated leader schedule */ - fd_stake_rewards_vector_destroy( slot_ctx->epoch_reward_status.stake_rewards_by_partition ); + /* FIXME: clean this up */ + // fd_stake_rewards_vector_destroy( slot_ctx->epoch_reward_status.stake_rewards_by_partition ); fd_exec_slot_ctx_delete( fd_exec_slot_ctx_leave( slot_ctx ) ); } diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index d2d9874259..7ea19be298 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -275,7 +275,7 @@ fd_executor_check_txn_accounts( fd_exec_txn_ctx_t * txn_ctx ) { validated_fee_payer = 1; } - if( txn_ctx->slot_ctx->epoch_reward_status.is_active && fd_txn_account_is_writable_idx( txn_ctx, (int)i ) + if( fd_epoch_reward_status_is_Active( &txn_ctx->slot_ctx->epoch_reward_status ) && fd_txn_account_is_writable_idx( txn_ctx, (int)i ) && memcmp( acct->const_meta->info.owner, fd_solana_stake_program_id.uc, sizeof(fd_pubkey_t))==0 ) { return FD_RUNTIME_TXN_ERR_PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED; } diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 3a51c202d9..c02e74e862 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -3709,9 +3709,9 @@ void fd_process_new_epoch( "update_epoch_stakes", ); */ if ( FD_FEATURE_ACTIVE( slot_ctx, enable_partitioned_epoch_reward ) ) { - fd_begin_partitioned_rewards( slot_ctx, parent_epoch ); + fd_begin_partitioned_rewards( slot_ctx, &slot_ctx->slot_bank.banks_hash, parent_epoch ); } else { - fd_update_rewards( slot_ctx, parent_epoch ); + fd_update_rewards( slot_ctx, &slot_ctx->slot_bank.banks_hash, parent_epoch ); } fd_update_stake_delegations( slot_ctx ); diff --git a/src/flamenco/runtime/program/fd_stake_program.c b/src/flamenco/runtime/program/fd_stake_program.c index 2d59918c49..cc1b14b2d1 100644 --- a/src/flamenco/runtime/program/fd_stake_program.c +++ b/src/flamenco/runtime/program/fd_stake_program.c @@ -2399,7 +2399,7 @@ fd_stake_program_execute( fd_exec_instr_ctx_t ctx ) { enable_partitioned_epoch_reward feature is activated. If it exists, check the `active` field */ fd_sysvar_epoch_rewards_t const * rewards = fd_sysvar_cache_epoch_rewards( ctx.slot_ctx->sysvar_cache ); - int epoch_rewards_active = (NULL != rewards) ? rewards->epoch_rewards.active : false; + int epoch_rewards_active = (NULL != rewards) ? rewards->active : false; if (epoch_rewards_active && instruction->discriminant != fd_stake_instruction_enum_get_minimum_delegation) { ctx.txn_ctx->custom_err = FD_STAKE_ERR_EPOCH_REWARDS_ACTIVE; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c index db8364a7d0..c2953ddc8e 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c @@ -4,31 +4,10 @@ #include "../fd_borrowed_account.h" #include "../fd_system_ids.h" #include "../context/fd_exec_slot_ctx.h" - -// THIS IS ALL WRONG... the partitioned epoch rewards code paths have not been finalized with agave -// so these changes are here to support getting the fuzz tests to pass and not actual ledger correctness. -// -// Also, since this feature has not been activated in mainnet or testnet, the account itself does not -// exist which is why they felt free to change the layout outside of a feature flag. -// -// Once the Agave code has stabilized, we will make a proper implementation pass - -void -fd_sysvar_epoch_rewards_burn_and_purge( - fd_exec_slot_ctx_t * slot_ctx -) { - FD_BORROWED_ACCOUNT_DECL(rewards); - - int rc = fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, &fd_sysvar_epoch_rewards_id, 0, 0, rewards); - if ( FD_UNLIKELY( rc ) ) return; // not good... - - fd_memcpy(rewards->meta->info.owner, fd_solana_system_program_id.key, sizeof(fd_pubkey_t)); - rewards->meta->dlen = 0; - rewards->meta->info.lamports = 0; -} +#include "../context/fd_exec_epoch_ctx.h" static void -write_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx, fd_sysvar_epoch_rewards_t * epoch_rewards, fd_acc_lamports_t acc_lamports) { +write_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx, fd_sysvar_epoch_rewards_t * epoch_rewards ) { ulong sz = fd_sysvar_epoch_rewards_size( epoch_rewards ); uchar enc[sz]; fd_memset( enc, 0, sz ); @@ -39,20 +18,19 @@ write_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx, fd_sysvar_epoch_rewards_t * FD_LOG_ERR(("fd_sysvar_epoch_rewards_encode failed")); } - fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_epoch_rewards_id, enc, sz, slot_ctx->slot_bank.slot, acc_lamports ); + fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_epoch_rewards_id, enc, sz, slot_ctx->slot_bank.slot, 0UL ); } - fd_sysvar_epoch_rewards_t * fd_sysvar_epoch_rewards_read( fd_sysvar_epoch_rewards_t * result, - fd_exec_slot_ctx_t * slot_ctx, - fd_acc_lamports_t * acc_lamports + fd_exec_slot_ctx_t * slot_ctx ) { FD_BORROWED_ACCOUNT_DECL(acc); int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, &fd_sysvar_epoch_rewards_id, acc ); - if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) + if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) { return NULL; + } fd_bincode_decode_ctx_t decode = { .data = acc->const_data, @@ -62,56 +40,70 @@ fd_sysvar_epoch_rewards_read( if( FD_UNLIKELY( fd_sysvar_epoch_rewards_decode( result, &decode )!=FD_BINCODE_SUCCESS ) ) return NULL; - if( acc_lamports ) - *acc_lamports = acc->const_meta->info.lamports; - return result; } -/* Update EpochRewards sysvar with distributed rewards */ void -fd_sysvar_epoch_rewards_update( +fd_sysvar_epoch_rewards_distribute( fd_exec_slot_ctx_t * slot_ctx, ulong distributed ) { - fd_sysvar_epoch_rewards_t result; - fd_acc_lamports_t acc_lamports = 0UL; - fd_sysvar_epoch_rewards_read( &result, slot_ctx, &acc_lamports ); - FD_TEST( acc_lamports != 0 ); + FD_TEST( FD_FEATURE_ACTIVE( slot_ctx, enable_partitioned_epoch_reward ) ); + + fd_sysvar_epoch_rewards_t epoch_rewards[1]; + if ( FD_UNLIKELY( fd_sysvar_epoch_rewards_read( epoch_rewards, slot_ctx ) == NULL ) ) { + FD_LOG_ERR(( "failed to read sysvar epoch rewards" )); + } + FD_TEST( epoch_rewards->active ); - FD_TEST( result.epoch_rewards.distributed_rewards + distributed <= result.epoch_rewards.total_rewards ); - result.epoch_rewards.distributed_rewards += distributed; + FD_TEST( fd_ulong_sat_add( epoch_rewards->distributed_rewards, distributed ) <= epoch_rewards->total_rewards ); - acc_lamports -= distributed; + epoch_rewards->distributed_rewards += distributed; - write_epoch_rewards( slot_ctx, &result, acc_lamports); + write_epoch_rewards( slot_ctx, epoch_rewards ); } -/* Create EpochRewards syavar with calculated rewards */ +void +fd_sysvar_epoch_rewards_set_inactive( + fd_exec_slot_ctx_t * slot_ctx +) { + fd_sysvar_epoch_rewards_t epoch_rewards[1]; + if ( FD_UNLIKELY( fd_sysvar_epoch_rewards_read( epoch_rewards, slot_ctx ) == NULL ) ) { + FD_LOG_ERR(( "failed to read sysvar epoch rewards" )); + } + FD_TEST( epoch_rewards->distributed_rewards == epoch_rewards->total_rewards ); + + epoch_rewards->active = 0; + + write_epoch_rewards( slot_ctx, epoch_rewards ); +} + +/* Create EpochRewards syavar with calculated rewards + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L25 */ void fd_sysvar_epoch_rewards_init( fd_exec_slot_ctx_t * slot_ctx, ulong total_rewards, ulong distributed_rewards, - ulong distribution_complete_block_height + ulong distribution_starting_block_height, + ulong num_partitions, + uint128 total_points, + fd_hash_t * last_blockhash ) { + FD_TEST( FD_FEATURE_ACTIVE( slot_ctx, enable_partitioned_epoch_reward ) ); FD_TEST( total_rewards >= distributed_rewards ); fd_sysvar_epoch_rewards_t epoch_rewards = { - .epoch_rewards= { -// .distribution_starting_block_height = distribution_starting_block_height, - .distribution_starting_block_height = distribution_complete_block_height, -// .num_partitions = num_partitions, - .num_partitions = 0, -// .parent_blockhash = parent_blockhash, -// .total_points = total_points, - .total_points = 0, - .total_rewards = total_rewards, - .distributed_rewards = distributed_rewards, - .active = true - } + .distribution_starting_block_height = distribution_starting_block_height, + .num_partitions = num_partitions, + .total_points = total_points, + .total_rewards = total_rewards, + .distributed_rewards = distributed_rewards, + .active = 1 }; - // set the account lamports to the undistributed rewards - fd_acc_lamports_t undistributed_rewards = total_rewards - distributed_rewards; - write_epoch_rewards( slot_ctx, &epoch_rewards, undistributed_rewards); + + fd_memcpy( &epoch_rewards.parent_blockhash, last_blockhash, FD_HASH_FOOTPRINT ); + + write_epoch_rewards( slot_ctx, &epoch_rewards ); } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.h b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.h index ab049a389e..7f9e9348df 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.h @@ -6,31 +6,42 @@ FD_PROTOTYPES_BEGIN -void -fd_sysvar_epoch_rewards_burn_and_purge( - fd_exec_slot_ctx_t * slot_ctx -); - +/* Read the current value of the EpochRewards sysvar from Funk. */ fd_sysvar_epoch_rewards_t * fd_sysvar_epoch_rewards_read( fd_sysvar_epoch_rewards_t * result, - fd_exec_slot_ctx_t * slot_ctx, - fd_acc_lamports_t * acc_lamports + fd_exec_slot_ctx_t * slot_ctx ); -/* Update EpochRewards sysvar with distributed rewards */ +/* Update EpochRewards sysvar with distributed rewards + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/sdk/program/src/epoch_rewards.rs#L44 */ void -fd_sysvar_epoch_rewards_update( +fd_sysvar_epoch_rewards_distribute( fd_exec_slot_ctx_t * slot_ctx, ulong distributed ); -/* Initialize the epoch rewards sysvar account. */ -void fd_sysvar_epoch_rewards_init( +/* Set the EpochRewards sysvar to inactive + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L82 */ +void +fd_sysvar_epoch_rewards_set_inactive( + fd_exec_slot_ctx_t * slot_ctx +); + +/* Initialize the EpochRewards sysvar account + + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L25 */ +void +fd_sysvar_epoch_rewards_init( fd_exec_slot_ctx_t * slot_ctx, ulong total_rewards, ulong distributed_rewards, - ulong distribution_complete_block_height + ulong distribution_starting_block_height, + ulong num_partitions, + uint128 total_points, + fd_hash_t * last_blockhash ); FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c index ac4942b08f..0838b0a86e 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c @@ -98,10 +98,13 @@ fd_epoch_slot0( fd_epoch_schedule_t const * schedule, return fd_ulong_sat_mul( power-1UL, FD_EPOCH_LEN_MIN ); } - ulong n_epoch = epoch - schedule->first_normal_epoch; - ulong n_slot = n_epoch * schedule->slots_per_epoch; - - return schedule->first_normal_slot + n_slot; + return fd_ulong_sat_add( + fd_ulong_sat_mul( + fd_ulong_sat_sub( + epoch, + schedule->first_normal_epoch), + schedule->slots_per_epoch), + schedule->first_normal_slot); } /* https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/sdk/program/src/epoch_schedule.rs#L140 */ diff --git a/src/flamenco/types/fd_type_names.c b/src/flamenco/types/fd_type_names.c index c0dabff136..95c6d1e31b 100644 --- a/src/flamenco/types/fd_type_names.c +++ b/src/flamenco/types/fd_type_names.c @@ -1,5 +1,5 @@ // This is an auto-generated file. To add entries, edit fd_types.json -#define FD_TYPE_NAME_COUNT 210 +#define FD_TYPE_NAME_COUNT 224 static char const * fd_type_names[FD_TYPE_NAME_COUNT] = { "fd_hash", "fd_pubkey", @@ -8,7 +8,6 @@ static char const * fd_type_names[FD_TYPE_NAME_COUNT] = { "fd_gossip_ip6_addr", "fd_feature", "fd_fee_calculator", - "fd_epoch_rewards", "fd_hash_age", "fd_hash_hash_age_pair", "fd_block_hash_vec", @@ -47,12 +46,15 @@ static char const * fd_type_names[FD_TYPE_NAME_COUNT] = { "fd_snapshot_acc_vec", "fd_snapshot_slot_acc_vecs", "fd_reward_type", + "fd_solana_accounts_db_fields", "fd_reward_info", "fd_stake_reward", - "fd_serializable_stake_rewards", + "fd_vote_reward", + "fd_stake", + "fd_partitioned_stake_reward", + "fd_partitioned_stake_rewards", "fd_start_block_height_and_rewards", - "fd_serializable_epoch_reward_status", - "fd_solana_accounts_db_fields", + "fd_epoch_reward_status", "fd_solana_manifest", "fd_rust_duration", "fd_poh_config", @@ -130,7 +132,6 @@ static char const * fd_type_names[FD_TYPE_NAME_COUNT] = { "fd_lockup_args", "fd_stake_instruction", "fd_stake_meta", - "fd_stake", "fd_stake_flags", "fd_stake_state_v2_initialized", "fd_stake_state_v2_stake", @@ -211,4 +212,17 @@ static char const * fd_type_names[FD_TYPE_NAME_COUNT] = { "fd_status_pair", "fd_slot_delta", "fd_bank_slot_deltas", + "fd_pubkey_rewardinfo_pair", + "fd_optional_account", + "fd_vote_rewards_accounts", + "fd_stake_reward_calculation", + "fd_stake_reward_calculation_partitioned", + "fd_partitioned_rewards_calculation", + "fd_calculate_rewards_and_distribute_vote_rewards_result", + "fd_keyed_rewards_and_num_partitions", + "fd_calculated_stake_points", + "fd_point_value", + "fd_calculate_stake_vote_rewards_result", + "fd_calculated_stake_rewards", + "fd_calculate_validator_rewards_result", }; diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index a08b098ca7..32c5706e9d 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -313,122 +313,6 @@ ulong fd_fee_calculator_size( fd_fee_calculator_t const * self ) { return size; } -int fd_epoch_rewards_decode( fd_epoch_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { - void const * data = ctx->data; - int err = fd_epoch_rewards_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - ctx->data = data; - if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_epoch_rewards_new( self ); - } - fd_epoch_rewards_decode_unsafe( self, ctx ); - return FD_BINCODE_SUCCESS; -} -int fd_epoch_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { - int err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_hash_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint128_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_bool_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -void fd_epoch_rewards_decode_unsafe( fd_epoch_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_bincode_uint64_decode_unsafe( &self->distribution_starting_block_height, ctx ); - fd_bincode_uint64_decode_unsafe( &self->num_partitions, ctx ); - fd_hash_decode_unsafe( &self->parent_blockhash, ctx ); - fd_bincode_uint128_decode_unsafe( &self->total_points, ctx ); - fd_bincode_uint64_decode_unsafe( &self->total_rewards, ctx ); - fd_bincode_uint64_decode_unsafe( &self->distributed_rewards, ctx ); - fd_bincode_bool_decode_unsafe( &self->active, ctx ); -} -int fd_epoch_rewards_encode( fd_epoch_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { - int err; - err = fd_bincode_uint64_encode( self->distribution_starting_block_height, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->num_partitions, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_encode( &self->parent_blockhash, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint128_encode( self->total_points, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->total_rewards, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->distributed_rewards, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_bool_encode( (uchar)(self->active), ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -int fd_epoch_rewards_decode_offsets( fd_epoch_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ) { - uchar const * data = ctx->data; - int err; - self->distribution_starting_block_height_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->num_partitions_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->parent_blockhash_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_hash_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - self->total_points_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint128_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - self->total_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->distributed_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->active_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_bool_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -void fd_epoch_rewards_new(fd_epoch_rewards_t * self) { - fd_memset( self, 0, sizeof(fd_epoch_rewards_t) ); - fd_hash_new( &self->parent_blockhash ); -} -void fd_epoch_rewards_destroy( fd_epoch_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ) { - fd_hash_destroy( &self->parent_blockhash, ctx ); -} - -ulong fd_epoch_rewards_footprint( void ){ return FD_EPOCH_REWARDS_FOOTPRINT; } -ulong fd_epoch_rewards_align( void ){ return FD_EPOCH_REWARDS_ALIGN; } - -void fd_epoch_rewards_walk( void * w, fd_epoch_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_epoch_rewards", level++ ); - fun( w, &self->distribution_starting_block_height, "distribution_starting_block_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->num_partitions, "num_partitions", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fd_hash_walk( w, &self->parent_blockhash, fun, "parent_blockhash", level ); - fun( w, &self->total_points, "total_points", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); - fun( w, &self->total_rewards, "total_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->distributed_rewards, "distributed_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->active, "active", FD_FLAMENCO_TYPE_BOOL, "bool", level ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_epoch_rewards", level-- ); -} -ulong fd_epoch_rewards_size( fd_epoch_rewards_t const * self ) { - ulong size = 0; - size += sizeof(ulong); - size += sizeof(ulong); - size += fd_hash_size( &self->parent_blockhash ); - size += sizeof(uint128); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(char); - return size; -} - int fd_hash_age_decode( fd_hash_age_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; int err = fd_hash_age_decode_preflight( ctx ); @@ -6436,99 +6320,348 @@ int fd_reward_type_encode( fd_reward_type_t const * self, fd_bincode_encode_ctx_ return fd_reward_type_inner_encode( &self->inner, self->discriminant, ctx ); } -int fd_reward_info_decode( fd_reward_info_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_solana_accounts_db_fields_decode( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_reward_info_decode_preflight( ctx ); + int err = fd_solana_accounts_db_fields_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_reward_info_new( self ); + fd_solana_accounts_db_fields_new( self ); } - fd_reward_info_decode_unsafe( self, ctx ); + fd_solana_accounts_db_fields_decode_unsafe( self, ctx ); return FD_BINCODE_SUCCESS; } -int fd_reward_info_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { +int fd_solana_accounts_db_fields_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { int err; - err = fd_reward_type_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); + ulong storages_len; + err = fd_bincode_uint64_decode( &storages_len, ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( storages_len ) { + for( ulong i=0; i < storages_len; i++ ) { + err = fd_snapshot_slot_acc_vecs_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); + err = fd_bank_hash_info_decode_preflight( ctx ); if( FD_UNLIKELY( err ) ) return err; + ulong historical_roots_len; + err = fd_bincode_uint64_decode( &historical_roots_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( historical_roots_len ) { + for( ulong i=0; i < historical_roots_len; i++ ) { + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + ulong historical_roots_with_hash_len; + err = fd_bincode_uint64_decode( &historical_roots_with_hash_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( historical_roots_with_hash_len ) { + for( ulong i=0; i < historical_roots_with_hash_len; i++ ) { + err = fd_slot_map_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } return FD_BINCODE_SUCCESS; } -void fd_reward_info_decode_unsafe( fd_reward_info_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_reward_type_decode_unsafe( &self->reward_type, ctx ); - fd_bincode_uint64_decode_unsafe( &self->lamports, ctx ); - fd_bincode_uint64_decode_unsafe( &self->staker_rewards, ctx ); - fd_bincode_uint64_decode_unsafe( &self->new_credits_observed, ctx ); - fd_bincode_uint64_decode_unsafe( &self->post_balance, ctx ); - fd_bincode_uint64_decode_unsafe( (ulong *) &self->commission, ctx ); +void fd_solana_accounts_db_fields_decode_unsafe( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->storages_len, ctx ); + if( self->storages_len ) { + self->storages = (fd_snapshot_slot_acc_vecs_t *)fd_valloc_malloc( ctx->valloc, FD_SNAPSHOT_SLOT_ACC_VECS_ALIGN, FD_SNAPSHOT_SLOT_ACC_VECS_FOOTPRINT*self->storages_len ); + for( ulong i=0; i < self->storages_len; i++ ) { + fd_snapshot_slot_acc_vecs_new( self->storages + i ); + fd_snapshot_slot_acc_vecs_decode_unsafe( self->storages + i, ctx ); + } + } else + self->storages = NULL; + fd_bincode_uint64_decode_unsafe( &self->version, ctx ); + fd_bincode_uint64_decode_unsafe( &self->slot, ctx ); + fd_bank_hash_info_decode_unsafe( &self->bank_hash_info, ctx ); + fd_bincode_uint64_decode_unsafe( &self->historical_roots_len, ctx ); + if( self->historical_roots_len ) { + self->historical_roots = fd_valloc_malloc( ctx->valloc, 8UL, sizeof(ulong)*self->historical_roots_len ); + for( ulong i=0; i < self->historical_roots_len; i++ ) { + fd_bincode_uint64_decode_unsafe( self->historical_roots + i, ctx ); + } + } else + self->historical_roots = NULL; + fd_bincode_uint64_decode_unsafe( &self->historical_roots_with_hash_len, ctx ); + if( self->historical_roots_with_hash_len ) { + self->historical_roots_with_hash = (fd_slot_map_pair_t *)fd_valloc_malloc( ctx->valloc, FD_SLOT_MAP_PAIR_ALIGN, FD_SLOT_MAP_PAIR_FOOTPRINT*self->historical_roots_with_hash_len ); + for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) { + fd_slot_map_pair_new( self->historical_roots_with_hash + i ); + fd_slot_map_pair_decode_unsafe( self->historical_roots_with_hash + i, ctx ); + } + } else + self->historical_roots_with_hash = NULL; } -int fd_reward_info_encode( fd_reward_info_t const * self, fd_bincode_encode_ctx_t * ctx ) { +int fd_solana_accounts_db_fields_encode( fd_solana_accounts_db_fields_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_reward_type_encode( &self->reward_type, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->lamports, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->staker_rewards, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->new_credits_observed, ctx ); + err = fd_bincode_uint64_encode( self->storages_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->storages_len ) { + for( ulong i=0; i < self->storages_len; i++ ) { + err = fd_snapshot_slot_acc_vecs_encode( self->storages + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + err = fd_bincode_uint64_encode( self->version, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->post_balance, ctx ); + err = fd_bincode_uint64_encode( self->slot, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( (ulong)self->commission, ctx ); + err = fd_bank_hash_info_encode( &self->bank_hash_info, ctx ); if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->historical_roots_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->historical_roots_len ) { + for( ulong i=0; i < self->historical_roots_len; i++ ) { + err = fd_bincode_uint64_encode( self->historical_roots[i], ctx ); + } + } + err = fd_bincode_uint64_encode( self->historical_roots_with_hash_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->historical_roots_with_hash_len ) { + for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) { + err = fd_slot_map_pair_encode( self->historical_roots_with_hash + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } return FD_BINCODE_SUCCESS; } -int fd_reward_info_decode_offsets( fd_reward_info_off_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_solana_accounts_db_fields_decode_offsets( fd_solana_accounts_db_fields_off_t * self, fd_bincode_decode_ctx_t * ctx ) { uchar const * data = ctx->data; int err; - self->reward_type_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_reward_type_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - self->lamports_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->staker_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); + self->storages_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong storages_len; + err = fd_bincode_uint64_decode( &storages_len, ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->new_credits_observed_off = (uint)( (ulong)ctx->data - (ulong)data ); + if( storages_len ) { + for( ulong i=0; i < storages_len; i++ ) { + err = fd_snapshot_slot_acc_vecs_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + self->version_off = (uint)( (ulong)ctx->data - (ulong)data ); err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->post_balance_off = (uint)( (ulong)ctx->data - (ulong)data ); + self->slot_off = (uint)( (ulong)ctx->data - (ulong)data ); err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->commission_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); + self->bank_hash_info_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bank_hash_info_decode_preflight( ctx ); if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -void fd_reward_info_new(fd_reward_info_t * self) { - fd_memset( self, 0, sizeof(fd_reward_info_t) ); - fd_reward_type_new( &self->reward_type ); -} -void fd_reward_info_destroy( fd_reward_info_t * self, fd_bincode_destroy_ctx_t * ctx ) { - fd_reward_type_destroy( &self->reward_type, ctx ); -} - -ulong fd_reward_info_footprint( void ){ return FD_REWARD_INFO_FOOTPRINT; } -ulong fd_reward_info_align( void ){ return FD_REWARD_INFO_ALIGN; } - -void fd_reward_info_walk( void * w, fd_reward_info_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_reward_info", level++ ); - fd_reward_type_walk( w, &self->reward_type, fun, "reward_type", level ); - fun( w, &self->lamports, "lamports", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->staker_rewards, "staker_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->new_credits_observed, "new_credits_observed", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + self->historical_roots_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong historical_roots_len; + err = fd_bincode_uint64_decode( &historical_roots_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( historical_roots_len ) { + for( ulong i=0; i < historical_roots_len; i++ ) { + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + self->historical_roots_with_hash_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong historical_roots_with_hash_len; + err = fd_bincode_uint64_decode( &historical_roots_with_hash_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( historical_roots_with_hash_len ) { + for( ulong i=0; i < historical_roots_with_hash_len; i++ ) { + err = fd_slot_map_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_solana_accounts_db_fields_new(fd_solana_accounts_db_fields_t * self) { + fd_memset( self, 0, sizeof(fd_solana_accounts_db_fields_t) ); + fd_bank_hash_info_new( &self->bank_hash_info ); +} +void fd_solana_accounts_db_fields_destroy( fd_solana_accounts_db_fields_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->storages ) { + for( ulong i=0; i < self->storages_len; i++ ) + fd_snapshot_slot_acc_vecs_destroy( self->storages + i, ctx ); + fd_valloc_free( ctx->valloc, self->storages ); + self->storages = NULL; + } + fd_bank_hash_info_destroy( &self->bank_hash_info, ctx ); + if( self->historical_roots ) { + fd_valloc_free( ctx->valloc, self->historical_roots ); + self->historical_roots = NULL; + } + if( self->historical_roots_with_hash ) { + for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) + fd_slot_map_pair_destroy( self->historical_roots_with_hash + i, ctx ); + fd_valloc_free( ctx->valloc, self->historical_roots_with_hash ); + self->historical_roots_with_hash = NULL; + } +} + +ulong fd_solana_accounts_db_fields_footprint( void ){ return FD_SOLANA_ACCOUNTS_DB_FIELDS_FOOTPRINT; } +ulong fd_solana_accounts_db_fields_align( void ){ return FD_SOLANA_ACCOUNTS_DB_FIELDS_ALIGN; } + +void fd_solana_accounts_db_fields_walk( void * w, fd_solana_accounts_db_fields_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_solana_accounts_db_fields", level++ ); + if( self->storages_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "storages", level++ ); + for( ulong i=0; i < self->storages_len; i++ ) + fd_snapshot_slot_acc_vecs_walk(w, self->storages + i, fun, "snapshot_slot_acc_vecs", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "storages", level-- ); + } + fun( w, &self->version, "version", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->slot, "slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fd_bank_hash_info_walk( w, &self->bank_hash_info, fun, "bank_hash_info", level ); + if( self->historical_roots_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "historical_roots", level++ ); + for( ulong i=0; i < self->historical_roots_len; i++ ) + fun( w, self->historical_roots + i, "historical_roots", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "historical_roots", level-- ); + } + if( self->historical_roots_with_hash_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "historical_roots_with_hash", level++ ); + for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) + fd_slot_map_pair_walk(w, self->historical_roots_with_hash + i, fun, "slot_map_pair", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "historical_roots_with_hash", level-- ); + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_solana_accounts_db_fields", level-- ); +} +ulong fd_solana_accounts_db_fields_size( fd_solana_accounts_db_fields_t const * self ) { + ulong size = 0; + do { + size += sizeof(ulong); + for( ulong i=0; i < self->storages_len; i++ ) + size += fd_snapshot_slot_acc_vecs_size( self->storages + i ); + } while(0); + size += sizeof(ulong); + size += sizeof(ulong); + size += fd_bank_hash_info_size( &self->bank_hash_info ); + do { + size += sizeof(ulong); + size += self->historical_roots_len * sizeof(ulong); + } while(0); + do { + size += sizeof(ulong); + for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) + size += fd_slot_map_pair_size( self->historical_roots_with_hash + i ); + } while(0); + return size; +} + +int fd_reward_info_decode( fd_reward_info_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_reward_info_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_reward_info_new( self ); + } + fd_reward_info_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_reward_info_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_reward_type_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_reward_info_decode_unsafe( fd_reward_info_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_reward_type_decode_unsafe( &self->reward_type, ctx ); + fd_bincode_uint64_decode_unsafe( &self->lamports, ctx ); + fd_bincode_uint64_decode_unsafe( &self->post_balance, ctx ); + { + uchar o; + fd_bincode_bool_decode_unsafe( &o, ctx ); + if( o ) { + self->commission = fd_valloc_malloc( ctx->valloc, 8, sizeof(ulong) ); + fd_bincode_uint64_decode_unsafe( self->commission, ctx ); + } else + self->commission = NULL; + } +} +int fd_reward_info_encode( fd_reward_info_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_reward_type_encode( &self->reward_type, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->lamports, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->post_balance, ctx ); + if( FD_UNLIKELY( err ) ) return err; + if( self->commission != NULL ) { + err = fd_bincode_bool_encode( 1, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->commission[0], ctx ); + if( FD_UNLIKELY( err ) ) return err; + } else { + err = fd_bincode_bool_encode( 0, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + return FD_BINCODE_SUCCESS; +} +int fd_reward_info_decode_offsets( fd_reward_info_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->reward_type_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_reward_type_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->lamports_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->post_balance_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->commission_off = (uint)( (ulong)ctx->data - (ulong)data ); + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_reward_info_new(fd_reward_info_t * self) { + fd_memset( self, 0, sizeof(fd_reward_info_t) ); + fd_reward_type_new( &self->reward_type ); +} +void fd_reward_info_destroy( fd_reward_info_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_reward_type_destroy( &self->reward_type, ctx ); + if( self->commission ) { + fd_valloc_free( ctx->valloc, self->commission ); + self->commission = NULL; + } +} + +ulong fd_reward_info_footprint( void ){ return FD_REWARD_INFO_FOOTPRINT; } +ulong fd_reward_info_align( void ){ return FD_REWARD_INFO_ALIGN; } + +void fd_reward_info_walk( void * w, fd_reward_info_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_reward_info", level++ ); + fd_reward_type_walk( w, &self->reward_type, fun, "reward_type", level ); + fun( w, &self->lamports, "lamports", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fun( w, &self->post_balance, "post_balance", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->commission, "commission", FD_FLAMENCO_TYPE_SLONG, "long", level ); + if( !self->commission ) { + fun( w, NULL, "commission", FD_FLAMENCO_TYPE_NULL, "ulong", level ); + } else { + fun( w, self->commission, "commission", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + } fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_reward_info", level-- ); } ulong fd_reward_info_size( fd_reward_info_t const * self ) { @@ -6536,9 +6669,10 @@ ulong fd_reward_info_size( fd_reward_info_t const * self ) { size += fd_reward_type_size( &self->reward_type ); size += sizeof(ulong); size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(long); + size += sizeof(char); + if( NULL != self->commission ) { + size += sizeof(ulong); + } return size; } @@ -6610,106 +6744,338 @@ ulong fd_stake_reward_size( fd_stake_reward_t const * self ) { return size; } -int fd_serializable_stake_rewards_decode( fd_serializable_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_vote_reward_decode( fd_vote_reward_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_serializable_stake_rewards_decode_preflight( ctx ); + int err = fd_vote_reward_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_serializable_stake_rewards_new( self ); + fd_vote_reward_new( self ); } - fd_serializable_stake_rewards_decode_unsafe( self, ctx ); + fd_vote_reward_decode_unsafe( self, ctx ); return FD_BINCODE_SUCCESS; } -int fd_serializable_stake_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { +int fd_vote_reward_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { int err; - ulong body_len; - err = fd_bincode_uint64_decode( &body_len, ctx ); + err = fd_bincode_bytes_decode_preflight( 32, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( body_len ) { - for( ulong i=0; i < body_len; i++ ) { - err = fd_stake_reward_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } + err = fd_bincode_uint8_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint8_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } -void fd_serializable_stake_rewards_decode_unsafe( fd_serializable_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_bincode_uint64_decode_unsafe( &self->body_len, ctx ); - if( self->body_len ) { - self->body = (fd_stake_reward_t *)fd_valloc_malloc( ctx->valloc, FD_STAKE_REWARD_ALIGN, FD_STAKE_REWARD_FOOTPRINT*self->body_len ); - for( ulong i=0; i < self->body_len; i++ ) { - fd_stake_reward_new( self->body + i ); - fd_stake_reward_decode_unsafe( self->body + i, ctx ); - } - } else - self->body = NULL; +void fd_vote_reward_decode_unsafe( fd_vote_reward_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_pubkey_decode_unsafe( &self->pubkey, ctx ); + fd_bincode_uint64_decode_unsafe( &self->vote_rewards, ctx ); + fd_bincode_uint8_decode_unsafe( &self->commission, ctx ); + fd_bincode_uint8_decode_unsafe( &self->needs_store, ctx ); } -int fd_serializable_stake_rewards_encode( fd_serializable_stake_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { +int fd_vote_reward_encode( fd_vote_reward_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_bincode_uint64_encode( self->body_len, ctx ); - if( FD_UNLIKELY(err) ) return err; - if( self->body_len ) { - for( ulong i=0; i < self->body_len; i++ ) { - err = fd_stake_reward_encode( self->body + i, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - } + err = fd_pubkey_encode( &self->pubkey, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->vote_rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint8_encode( (uchar)(self->commission), ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint8_encode( (uchar)(self->needs_store), ctx ); + if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } -int fd_serializable_stake_rewards_decode_offsets( fd_serializable_stake_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_vote_reward_decode_offsets( fd_vote_reward_off_t * self, fd_bincode_decode_ctx_t * ctx ) { uchar const * data = ctx->data; int err; - self->body_off = (uint)( (ulong)ctx->data - (ulong)data ); - ulong body_len; - err = fd_bincode_uint64_decode( &body_len, ctx ); + self->pubkey_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_bytes_decode_preflight( 32, ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->vote_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( body_len ) { - for( ulong i=0; i < body_len; i++ ) { - err = fd_stake_reward_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } + self->commission_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint8_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->needs_store_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint8_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } -void fd_serializable_stake_rewards_new(fd_serializable_stake_rewards_t * self) { - fd_memset( self, 0, sizeof(fd_serializable_stake_rewards_t) ); +void fd_vote_reward_new(fd_vote_reward_t * self) { + fd_memset( self, 0, sizeof(fd_vote_reward_t) ); + fd_pubkey_new( &self->pubkey ); } -void fd_serializable_stake_rewards_destroy( fd_serializable_stake_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ) { - if( self->body ) { - for( ulong i=0; i < self->body_len; i++ ) - fd_stake_reward_destroy( self->body + i, ctx ); - fd_valloc_free( ctx->valloc, self->body ); - self->body = NULL; - } +void fd_vote_reward_destroy( fd_vote_reward_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_pubkey_destroy( &self->pubkey, ctx ); } -ulong fd_serializable_stake_rewards_footprint( void ){ return FD_SERIALIZABLE_STAKE_REWARDS_FOOTPRINT; } -ulong fd_serializable_stake_rewards_align( void ){ return FD_SERIALIZABLE_STAKE_REWARDS_ALIGN; } +ulong fd_vote_reward_footprint( void ){ return FD_VOTE_REWARD_FOOTPRINT; } +ulong fd_vote_reward_align( void ){ return FD_VOTE_REWARD_ALIGN; } -void fd_serializable_stake_rewards_walk( void * w, fd_serializable_stake_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_serializable_stake_rewards", level++ ); - if( self->body_len ) { - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "body", level++ ); - for( ulong i=0; i < self->body_len; i++ ) - fd_stake_reward_walk(w, self->body + i, fun, "stake_reward", level ); - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "body", level-- ); - } - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_serializable_stake_rewards", level-- ); +void fd_vote_reward_walk( void * w, fd_vote_reward_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_vote_reward", level++ ); + fd_pubkey_walk( w, &self->pubkey, fun, "pubkey", level ); + fun( w, &self->vote_rewards, "vote_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->commission, "commission", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); + fun( w, &self->needs_store, "needs_store", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_vote_reward", level-- ); } -ulong fd_serializable_stake_rewards_size( fd_serializable_stake_rewards_t const * self ) { +ulong fd_vote_reward_size( fd_vote_reward_t const * self ) { ulong size = 0; - do { - size += sizeof(ulong); - for( ulong i=0; i < self->body_len; i++ ) - size += fd_stake_reward_size( self->body + i ); - } while(0); + size += fd_pubkey_size( &self->pubkey ); + size += sizeof(ulong); + size += sizeof(char); + size += sizeof(char); return size; } -int fd_start_block_height_and_rewards_decode( fd_start_block_height_and_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_stake_decode( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_start_block_height_and_rewards_decode_preflight( ctx ); + int err = fd_stake_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_stake_new( self ); + } + fd_stake_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_stake_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_delegation_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_stake_decode_unsafe( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_delegation_decode_unsafe( &self->delegation, ctx ); + fd_bincode_uint64_decode_unsafe( &self->credits_observed, ctx ); +} +int fd_stake_encode( fd_stake_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_delegation_encode( &self->delegation, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->credits_observed, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_stake_decode_offsets( fd_stake_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->delegation_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_delegation_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->credits_observed_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_stake_new(fd_stake_t * self) { + fd_memset( self, 0, sizeof(fd_stake_t) ); + fd_delegation_new( &self->delegation ); +} +void fd_stake_destroy( fd_stake_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_delegation_destroy( &self->delegation, ctx ); +} + +ulong fd_stake_footprint( void ){ return FD_STAKE_FOOTPRINT; } +ulong fd_stake_align( void ){ return FD_STAKE_ALIGN; } + +void fd_stake_walk( void * w, fd_stake_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_stake", level++ ); + fd_delegation_walk( w, &self->delegation, fun, "delegation", level ); + fun( w, &self->credits_observed, "credits_observed", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_stake", level-- ); +} +ulong fd_stake_size( fd_stake_t const * self ) { + ulong size = 0; + size += fd_delegation_size( &self->delegation ); + size += sizeof(ulong); + return size; +} + +int fd_partitioned_stake_reward_decode( fd_partitioned_stake_reward_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_partitioned_stake_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_partitioned_stake_reward_new( self ); + } + fd_partitioned_stake_reward_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_partitioned_stake_reward_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_bincode_bytes_decode_preflight( 32, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_stake_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_reward_info_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_partitioned_stake_reward_decode_unsafe( fd_partitioned_stake_reward_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_pubkey_decode_unsafe( &self->stake_pubkey, ctx ); + fd_stake_decode_unsafe( &self->stake, ctx ); + fd_reward_info_decode_unsafe( &self->stake_reward_info, ctx ); +} +int fd_partitioned_stake_reward_encode( fd_partitioned_stake_reward_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_pubkey_encode( &self->stake_pubkey, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_stake_encode( &self->stake, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_reward_info_encode( &self->stake_reward_info, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_partitioned_stake_reward_decode_offsets( fd_partitioned_stake_reward_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->stake_pubkey_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_bytes_decode_preflight( 32, ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->stake_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_stake_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->stake_reward_info_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_reward_info_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_partitioned_stake_reward_new(fd_partitioned_stake_reward_t * self) { + fd_memset( self, 0, sizeof(fd_partitioned_stake_reward_t) ); + fd_pubkey_new( &self->stake_pubkey ); + fd_stake_new( &self->stake ); + fd_reward_info_new( &self->stake_reward_info ); +} +void fd_partitioned_stake_reward_destroy( fd_partitioned_stake_reward_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_pubkey_destroy( &self->stake_pubkey, ctx ); + fd_stake_destroy( &self->stake, ctx ); + fd_reward_info_destroy( &self->stake_reward_info, ctx ); +} + +ulong fd_partitioned_stake_reward_footprint( void ){ return FD_PARTITIONED_STAKE_REWARD_FOOTPRINT; } +ulong fd_partitioned_stake_reward_align( void ){ return FD_PARTITIONED_STAKE_REWARD_ALIGN; } + +void fd_partitioned_stake_reward_walk( void * w, fd_partitioned_stake_reward_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_partitioned_stake_reward", level++ ); + fd_pubkey_walk( w, &self->stake_pubkey, fun, "stake_pubkey", level ); + fd_stake_walk( w, &self->stake, fun, "stake", level ); + fd_reward_info_walk( w, &self->stake_reward_info, fun, "stake_reward_info", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_partitioned_stake_reward", level-- ); +} +ulong fd_partitioned_stake_reward_size( fd_partitioned_stake_reward_t const * self ) { + ulong size = 0; + size += fd_pubkey_size( &self->stake_pubkey ); + size += fd_stake_size( &self->stake ); + size += fd_reward_info_size( &self->stake_reward_info ); + return size; +} + +int fd_partitioned_stake_rewards_decode( fd_partitioned_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_partitioned_stake_rewards_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_partitioned_stake_rewards_new( self ); + } + fd_partitioned_stake_rewards_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_partitioned_stake_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + ulong partition_len; + err = fd_bincode_uint64_decode( &partition_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( partition_len ) { + for( ulong i=0; i < partition_len; i++ ) { + err = fd_partitioned_stake_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_partitioned_stake_rewards_decode_unsafe( fd_partitioned_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->partition_len, ctx ); + if( self->partition_len ) { + self->partition = (fd_partitioned_stake_reward_t *)fd_valloc_malloc( ctx->valloc, FD_PARTITIONED_STAKE_REWARD_ALIGN, FD_PARTITIONED_STAKE_REWARD_FOOTPRINT*self->partition_len ); + for( ulong i=0; i < self->partition_len; i++ ) { + fd_partitioned_stake_reward_new( self->partition + i ); + fd_partitioned_stake_reward_decode_unsafe( self->partition + i, ctx ); + } + } else + self->partition = NULL; +} +int fd_partitioned_stake_rewards_encode( fd_partitioned_stake_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->partition_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->partition_len ) { + for( ulong i=0; i < self->partition_len; i++ ) { + err = fd_partitioned_stake_reward_encode( self->partition + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +int fd_partitioned_stake_rewards_decode_offsets( fd_partitioned_stake_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->partition_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong partition_len; + err = fd_bincode_uint64_decode( &partition_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( partition_len ) { + for( ulong i=0; i < partition_len; i++ ) { + err = fd_partitioned_stake_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_partitioned_stake_rewards_new(fd_partitioned_stake_rewards_t * self) { + fd_memset( self, 0, sizeof(fd_partitioned_stake_rewards_t) ); +} +void fd_partitioned_stake_rewards_destroy( fd_partitioned_stake_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->partition ) { + for( ulong i=0; i < self->partition_len; i++ ) + fd_partitioned_stake_reward_destroy( self->partition + i, ctx ); + fd_valloc_free( ctx->valloc, self->partition ); + self->partition = NULL; + } +} + +ulong fd_partitioned_stake_rewards_footprint( void ){ return FD_PARTITIONED_STAKE_REWARDS_FOOTPRINT; } +ulong fd_partitioned_stake_rewards_align( void ){ return FD_PARTITIONED_STAKE_REWARDS_ALIGN; } + +void fd_partitioned_stake_rewards_walk( void * w, fd_partitioned_stake_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_partitioned_stake_rewards", level++ ); + if( self->partition_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "partition", level++ ); + for( ulong i=0; i < self->partition_len; i++ ) + fd_partitioned_stake_reward_walk(w, self->partition + i, fun, "partitioned_stake_reward", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "partition", level-- ); + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_partitioned_stake_rewards", level-- ); +} +ulong fd_partitioned_stake_rewards_size( fd_partitioned_stake_rewards_t const * self ) { + ulong size = 0; + do { + size += sizeof(ulong); + for( ulong i=0; i < self->partition_len; i++ ) + size += fd_partitioned_stake_reward_size( self->partition + i ); + } while(0); + return size; +} + +int fd_start_block_height_and_rewards_decode( fd_start_block_height_and_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_start_block_height_and_rewards_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { @@ -6727,33 +7093,33 @@ int fd_start_block_height_and_rewards_decode_preflight( fd_bincode_decode_ctx_t if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; if( stake_rewards_by_partition_len ) { for( ulong i=0; i < stake_rewards_by_partition_len; i++ ) { - err = fd_serializable_stake_rewards_decode_preflight( ctx ); + err = fd_partitioned_stake_rewards_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } } return FD_BINCODE_SUCCESS; } void fd_start_block_height_and_rewards_decode_unsafe( fd_start_block_height_and_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_bincode_uint64_decode_unsafe( &self->start_block_height, ctx ); + fd_bincode_uint64_decode_unsafe( &self->distribution_starting_block_height, ctx ); fd_bincode_uint64_decode_unsafe( &self->stake_rewards_by_partition_len, ctx ); if( self->stake_rewards_by_partition_len ) { - self->stake_rewards_by_partition = (fd_serializable_stake_rewards_t *)fd_valloc_malloc( ctx->valloc, FD_SERIALIZABLE_STAKE_REWARDS_ALIGN, FD_SERIALIZABLE_STAKE_REWARDS_FOOTPRINT*self->stake_rewards_by_partition_len ); + self->stake_rewards_by_partition = (fd_partitioned_stake_rewards_t *)fd_valloc_malloc( ctx->valloc, FD_PARTITIONED_STAKE_REWARDS_ALIGN, FD_PARTITIONED_STAKE_REWARDS_FOOTPRINT*self->stake_rewards_by_partition_len ); for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) { - fd_serializable_stake_rewards_new( self->stake_rewards_by_partition + i ); - fd_serializable_stake_rewards_decode_unsafe( self->stake_rewards_by_partition + i, ctx ); + fd_partitioned_stake_rewards_new( self->stake_rewards_by_partition + i ); + fd_partitioned_stake_rewards_decode_unsafe( self->stake_rewards_by_partition + i, ctx ); } } else self->stake_rewards_by_partition = NULL; } int fd_start_block_height_and_rewards_encode( fd_start_block_height_and_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_bincode_uint64_encode( self->start_block_height, ctx ); + err = fd_bincode_uint64_encode( self->distribution_starting_block_height, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_bincode_uint64_encode( self->stake_rewards_by_partition_len, ctx ); if( FD_UNLIKELY(err) ) return err; if( self->stake_rewards_by_partition_len ) { for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) { - err = fd_serializable_stake_rewards_encode( self->stake_rewards_by_partition + i, ctx ); + err = fd_partitioned_stake_rewards_encode( self->stake_rewards_by_partition + i, ctx ); if( FD_UNLIKELY( err ) ) return err; } } @@ -6762,7 +7128,7 @@ int fd_start_block_height_and_rewards_encode( fd_start_block_height_and_rewards_ int fd_start_block_height_and_rewards_decode_offsets( fd_start_block_height_and_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ) { uchar const * data = ctx->data; int err; - self->start_block_height_off = (uint)( (ulong)ctx->data - (ulong)data ); + self->distribution_starting_block_height_off = (uint)( (ulong)ctx->data - (ulong)data ); err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; self->stake_rewards_by_partition_off = (uint)( (ulong)ctx->data - (ulong)data ); @@ -6771,7 +7137,7 @@ int fd_start_block_height_and_rewards_decode_offsets( fd_start_block_height_and_ if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; if( stake_rewards_by_partition_len ) { for( ulong i=0; i < stake_rewards_by_partition_len; i++ ) { - err = fd_serializable_stake_rewards_decode_preflight( ctx ); + err = fd_partitioned_stake_rewards_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } } @@ -6783,7 +7149,7 @@ void fd_start_block_height_and_rewards_new(fd_start_block_height_and_rewards_t * void fd_start_block_height_and_rewards_destroy( fd_start_block_height_and_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ) { if( self->stake_rewards_by_partition ) { for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) - fd_serializable_stake_rewards_destroy( self->stake_rewards_by_partition + i, ctx ); + fd_partitioned_stake_rewards_destroy( self->stake_rewards_by_partition + i, ctx ); fd_valloc_free( ctx->valloc, self->stake_rewards_by_partition ); self->stake_rewards_by_partition = NULL; } @@ -6794,11 +7160,11 @@ ulong fd_start_block_height_and_rewards_align( void ){ return FD_START_BLOCK_HEI void fd_start_block_height_and_rewards_walk( void * w, fd_start_block_height_and_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_start_block_height_and_rewards", level++ ); - fun( w, &self->start_block_height, "start_block_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->distribution_starting_block_height, "distribution_starting_block_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); if( self->stake_rewards_by_partition_len ) { fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "stake_rewards_by_partition", level++ ); for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) - fd_serializable_stake_rewards_walk(w, self->stake_rewards_by_partition + i, fun, "serializable_stake_rewards", level ); + fd_partitioned_stake_rewards_walk(w, self->stake_rewards_by_partition + i, fun, "partitioned_stake_rewards", level ); fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "stake_rewards_by_partition", level-- ); } fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_start_block_height_and_rewards", level-- ); @@ -6809,19 +7175,19 @@ ulong fd_start_block_height_and_rewards_size( fd_start_block_height_and_rewards_ do { size += sizeof(ulong); for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) - size += fd_serializable_stake_rewards_size( self->stake_rewards_by_partition + i ); + size += fd_partitioned_stake_rewards_size( self->stake_rewards_by_partition + i ); } while(0); return size; } -FD_FN_PURE uchar fd_serializable_epoch_reward_status_is_Active(fd_serializable_epoch_reward_status_t const * self) { +FD_FN_PURE uchar fd_epoch_reward_status_is_Active(fd_epoch_reward_status_t const * self) { return self->discriminant == 0; } -FD_FN_PURE uchar fd_serializable_epoch_reward_status_is_Inactive(fd_serializable_epoch_reward_status_t const * self) { +FD_FN_PURE uchar fd_epoch_reward_status_is_Inactive(fd_epoch_reward_status_t const * self) { return self->discriminant == 1; } -void fd_serializable_epoch_reward_status_inner_new( fd_serializable_epoch_reward_status_inner_t * self, uint discriminant ); -int fd_serializable_epoch_reward_status_inner_decode_preflight( uint discriminant, fd_bincode_decode_ctx_t * ctx ) { +void fd_epoch_reward_status_inner_new( fd_epoch_reward_status_inner_t * self, uint discriminant ); +int fd_epoch_reward_status_inner_decode_preflight( uint discriminant, fd_bincode_decode_ctx_t * ctx ) { int err; switch (discriminant) { case 0: { @@ -6835,7 +7201,7 @@ int fd_serializable_epoch_reward_status_inner_decode_preflight( uint discriminan default: return FD_BINCODE_ERR_ENCODING; } } -void fd_serializable_epoch_reward_status_inner_decode_unsafe( fd_serializable_epoch_reward_status_inner_t * self, uint discriminant, fd_bincode_decode_ctx_t * ctx ) { +void fd_epoch_reward_status_inner_decode_unsafe( fd_epoch_reward_status_inner_t * self, uint discriminant, fd_bincode_decode_ctx_t * ctx ) { switch (discriminant) { case 0: { fd_start_block_height_and_rewards_decode_unsafe( &self->Active, ctx ); @@ -6846,28 +7212,28 @@ void fd_serializable_epoch_reward_status_inner_decode_unsafe( fd_serializable_ep } } } -int fd_serializable_epoch_reward_status_decode( fd_serializable_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_epoch_reward_status_decode( fd_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_serializable_epoch_reward_status_decode_preflight( ctx ); + int err = fd_epoch_reward_status_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_serializable_epoch_reward_status_new( self ); + fd_epoch_reward_status_new( self ); } - fd_serializable_epoch_reward_status_decode_unsafe( self, ctx ); + fd_epoch_reward_status_decode_unsafe( self, ctx ); return FD_BINCODE_SUCCESS; } -int fd_serializable_epoch_reward_status_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { +int fd_epoch_reward_status_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { uint discriminant = 0; int err = fd_bincode_uint32_decode( &discriminant, ctx ); if( FD_UNLIKELY( err ) ) return err; - return fd_serializable_epoch_reward_status_inner_decode_preflight( discriminant, ctx ); + return fd_epoch_reward_status_inner_decode_preflight( discriminant, ctx ); } -void fd_serializable_epoch_reward_status_decode_unsafe( fd_serializable_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ) { +void fd_epoch_reward_status_decode_unsafe( fd_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ) { fd_bincode_uint32_decode_unsafe( &self->discriminant, ctx ); - fd_serializable_epoch_reward_status_inner_decode_unsafe( &self->inner, self->discriminant, ctx ); + fd_epoch_reward_status_inner_decode_unsafe( &self->inner, self->discriminant, ctx ); } -void fd_serializable_epoch_reward_status_inner_new( fd_serializable_epoch_reward_status_inner_t * self, uint discriminant ) { +void fd_epoch_reward_status_inner_new( fd_epoch_reward_status_inner_t * self, uint discriminant ) { switch( discriminant ) { case 0: { fd_start_block_height_and_rewards_new( &self->Active ); @@ -6879,15 +7245,15 @@ void fd_serializable_epoch_reward_status_inner_new( fd_serializable_epoch_reward default: break; // FD_LOG_ERR(( "unhandled type")); } } -void fd_serializable_epoch_reward_status_new_disc( fd_serializable_epoch_reward_status_t * self, uint discriminant ) { +void fd_epoch_reward_status_new_disc( fd_epoch_reward_status_t * self, uint discriminant ) { self->discriminant = discriminant; - fd_serializable_epoch_reward_status_inner_new( &self->inner, self->discriminant ); + fd_epoch_reward_status_inner_new( &self->inner, self->discriminant ); } -void fd_serializable_epoch_reward_status_new( fd_serializable_epoch_reward_status_t * self ) { - fd_memset( self, 0, sizeof(fd_serializable_epoch_reward_status_t) ); - fd_serializable_epoch_reward_status_new_disc( self, UINT_MAX ); +void fd_epoch_reward_status_new( fd_epoch_reward_status_t * self ) { + fd_memset( self, 0, sizeof(fd_epoch_reward_status_t) ); + fd_epoch_reward_status_new_disc( self, UINT_MAX ); } -void fd_serializable_epoch_reward_status_inner_destroy( fd_serializable_epoch_reward_status_inner_t * self, uint discriminant, fd_bincode_destroy_ctx_t * ctx ) { +void fd_epoch_reward_status_inner_destroy( fd_epoch_reward_status_inner_t * self, uint discriminant, fd_bincode_destroy_ctx_t * ctx ) { switch( discriminant ) { case 0: { fd_start_block_height_and_rewards_destroy( &self->Active, ctx ); @@ -6896,24 +7262,24 @@ void fd_serializable_epoch_reward_status_inner_destroy( fd_serializable_epoch_re default: break; // FD_LOG_ERR(( "unhandled type" )); } } -void fd_serializable_epoch_reward_status_destroy( fd_serializable_epoch_reward_status_t * self, fd_bincode_destroy_ctx_t * ctx ) { - fd_serializable_epoch_reward_status_inner_destroy( &self->inner, self->discriminant, ctx ); +void fd_epoch_reward_status_destroy( fd_epoch_reward_status_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_epoch_reward_status_inner_destroy( &self->inner, self->discriminant, ctx ); } -ulong fd_serializable_epoch_reward_status_footprint( void ){ return FD_SERIALIZABLE_EPOCH_REWARD_STATUS_FOOTPRINT; } -ulong fd_serializable_epoch_reward_status_align( void ){ return FD_SERIALIZABLE_EPOCH_REWARD_STATUS_ALIGN; } +ulong fd_epoch_reward_status_footprint( void ){ return FD_EPOCH_REWARD_STATUS_FOOTPRINT; } +ulong fd_epoch_reward_status_align( void ){ return FD_EPOCH_REWARD_STATUS_ALIGN; } -void fd_serializable_epoch_reward_status_walk( void * w, fd_serializable_epoch_reward_status_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun(w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_serializable_epoch_reward_status", level++); +void fd_epoch_reward_status_walk( void * w, fd_epoch_reward_status_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun(w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_epoch_reward_status", level++); switch( self->discriminant ) { case 0: { fd_start_block_height_and_rewards_walk( w, &self->inner.Active, fun, "Active", level ); break; } } - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_serializable_epoch_reward_status", level-- ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_epoch_reward_status", level-- ); } -ulong fd_serializable_epoch_reward_status_size( fd_serializable_epoch_reward_status_t const * self ) { +ulong fd_epoch_reward_status_size( fd_epoch_reward_status_t const * self ) { ulong size = 0; size += sizeof(uint); switch (self->discriminant) { @@ -6925,7 +7291,7 @@ ulong fd_serializable_epoch_reward_status_size( fd_serializable_epoch_reward_sta return size; } -int fd_serializable_epoch_reward_status_inner_encode( fd_serializable_epoch_reward_status_inner_t const * self, uint discriminant, fd_bincode_encode_ctx_t * ctx ) { +int fd_epoch_reward_status_inner_encode( fd_epoch_reward_status_inner_t const * self, uint discriminant, fd_bincode_encode_ctx_t * ctx ) { int err; switch (discriminant) { case 0: { @@ -6936,288 +7302,58 @@ int fd_serializable_epoch_reward_status_inner_encode( fd_serializable_epoch_rewa } return FD_BINCODE_SUCCESS; } -int fd_serializable_epoch_reward_status_encode( fd_serializable_epoch_reward_status_t const * self, fd_bincode_encode_ctx_t * ctx ) { +int fd_epoch_reward_status_encode( fd_epoch_reward_status_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err = fd_bincode_uint32_encode( self->discriminant, ctx ); if( FD_UNLIKELY( err ) ) return err; - return fd_serializable_epoch_reward_status_inner_encode( &self->inner, self->discriminant, ctx ); + return fd_epoch_reward_status_inner_encode( &self->inner, self->discriminant, ctx ); } -int fd_solana_accounts_db_fields_decode( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_solana_manifest_decode( fd_solana_manifest_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_solana_accounts_db_fields_decode_preflight( ctx ); + int err = fd_solana_manifest_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_solana_accounts_db_fields_new( self ); + fd_solana_manifest_new( self ); } - fd_solana_accounts_db_fields_decode_unsafe( self, ctx ); + fd_solana_manifest_decode_unsafe( self, ctx ); return FD_BINCODE_SUCCESS; } -int fd_solana_accounts_db_fields_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { +int fd_solana_manifest_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { int err; - ulong storages_len; - err = fd_bincode_uint64_decode( &storages_len, ctx ); + err = fd_deserializable_versioned_bank_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_solana_accounts_db_fields_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( storages_len ) { - for( ulong i=0; i < storages_len; i++ ) { - err = fd_snapshot_slot_acc_vecs_decode_preflight( ctx ); + if( ctx->data == ctx->dataend ) return FD_BINCODE_SUCCESS; + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_bank_incremental_snapshot_persistence_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } } - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bank_hash_info_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - ulong historical_roots_len; - err = fd_bincode_uint64_decode( &historical_roots_len, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( historical_roots_len ) { - for( ulong i=0; i < historical_roots_len; i++ ) { - err = fd_bincode_uint64_decode_preflight( ctx ); + if( ctx->data == ctx->dataend ) return FD_BINCODE_SUCCESS; + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_hash_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } } - ulong historical_roots_with_hash_len; - err = fd_bincode_uint64_decode( &historical_roots_with_hash_len, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( historical_roots_with_hash_len ) { - for( ulong i=0; i < historical_roots_with_hash_len; i++ ) { - err = fd_slot_map_pair_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } - return FD_BINCODE_SUCCESS; -} -void fd_solana_accounts_db_fields_decode_unsafe( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_bincode_uint64_decode_unsafe( &self->storages_len, ctx ); - if( self->storages_len ) { - self->storages = (fd_snapshot_slot_acc_vecs_t *)fd_valloc_malloc( ctx->valloc, FD_SNAPSHOT_SLOT_ACC_VECS_ALIGN, FD_SNAPSHOT_SLOT_ACC_VECS_FOOTPRINT*self->storages_len ); - for( ulong i=0; i < self->storages_len; i++ ) { - fd_snapshot_slot_acc_vecs_new( self->storages + i ); - fd_snapshot_slot_acc_vecs_decode_unsafe( self->storages + i, ctx ); - } - } else - self->storages = NULL; - fd_bincode_uint64_decode_unsafe( &self->version, ctx ); - fd_bincode_uint64_decode_unsafe( &self->slot, ctx ); - fd_bank_hash_info_decode_unsafe( &self->bank_hash_info, ctx ); - fd_bincode_uint64_decode_unsafe( &self->historical_roots_len, ctx ); - if( self->historical_roots_len ) { - self->historical_roots = fd_valloc_malloc( ctx->valloc, 8UL, sizeof(ulong)*self->historical_roots_len ); - for( ulong i=0; i < self->historical_roots_len; i++ ) { - fd_bincode_uint64_decode_unsafe( self->historical_roots + i, ctx ); - } - } else - self->historical_roots = NULL; - fd_bincode_uint64_decode_unsafe( &self->historical_roots_with_hash_len, ctx ); - if( self->historical_roots_with_hash_len ) { - self->historical_roots_with_hash = (fd_slot_map_pair_t *)fd_valloc_malloc( ctx->valloc, FD_SLOT_MAP_PAIR_ALIGN, FD_SLOT_MAP_PAIR_FOOTPRINT*self->historical_roots_with_hash_len ); - for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) { - fd_slot_map_pair_new( self->historical_roots_with_hash + i ); - fd_slot_map_pair_decode_unsafe( self->historical_roots_with_hash + i, ctx ); - } - } else - self->historical_roots_with_hash = NULL; -} -int fd_solana_accounts_db_fields_encode( fd_solana_accounts_db_fields_t const * self, fd_bincode_encode_ctx_t * ctx ) { - int err; - err = fd_bincode_uint64_encode( self->storages_len, ctx ); - if( FD_UNLIKELY(err) ) return err; - if( self->storages_len ) { - for( ulong i=0; i < self->storages_len; i++ ) { - err = fd_snapshot_slot_acc_vecs_encode( self->storages + i, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - } - err = fd_bincode_uint64_encode( self->version, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->slot, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bank_hash_info_encode( &self->bank_hash_info, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->historical_roots_len, ctx ); - if( FD_UNLIKELY(err) ) return err; - if( self->historical_roots_len ) { - for( ulong i=0; i < self->historical_roots_len; i++ ) { - err = fd_bincode_uint64_encode( self->historical_roots[i], ctx ); - } - } - err = fd_bincode_uint64_encode( self->historical_roots_with_hash_len, ctx ); - if( FD_UNLIKELY(err) ) return err; - if( self->historical_roots_with_hash_len ) { - for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) { - err = fd_slot_map_pair_encode( self->historical_roots_with_hash + i, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - } - return FD_BINCODE_SUCCESS; -} -int fd_solana_accounts_db_fields_decode_offsets( fd_solana_accounts_db_fields_off_t * self, fd_bincode_decode_ctx_t * ctx ) { - uchar const * data = ctx->data; - int err; - self->storages_off = (uint)( (ulong)ctx->data - (ulong)data ); - ulong storages_len; - err = fd_bincode_uint64_decode( &storages_len, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( storages_len ) { - for( ulong i=0; i < storages_len; i++ ) { - err = fd_snapshot_slot_acc_vecs_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } - self->version_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->slot_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->bank_hash_info_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bank_hash_info_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - self->historical_roots_off = (uint)( (ulong)ctx->data - (ulong)data ); - ulong historical_roots_len; - err = fd_bincode_uint64_decode( &historical_roots_len, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( historical_roots_len ) { - for( ulong i=0; i < historical_roots_len; i++ ) { - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } - self->historical_roots_with_hash_off = (uint)( (ulong)ctx->data - (ulong)data ); - ulong historical_roots_with_hash_len; - err = fd_bincode_uint64_decode( &historical_roots_with_hash_len, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( historical_roots_with_hash_len ) { - for( ulong i=0; i < historical_roots_with_hash_len; i++ ) { - err = fd_slot_map_pair_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } - return FD_BINCODE_SUCCESS; -} -void fd_solana_accounts_db_fields_new(fd_solana_accounts_db_fields_t * self) { - fd_memset( self, 0, sizeof(fd_solana_accounts_db_fields_t) ); - fd_bank_hash_info_new( &self->bank_hash_info ); -} -void fd_solana_accounts_db_fields_destroy( fd_solana_accounts_db_fields_t * self, fd_bincode_destroy_ctx_t * ctx ) { - if( self->storages ) { - for( ulong i=0; i < self->storages_len; i++ ) - fd_snapshot_slot_acc_vecs_destroy( self->storages + i, ctx ); - fd_valloc_free( ctx->valloc, self->storages ); - self->storages = NULL; - } - fd_bank_hash_info_destroy( &self->bank_hash_info, ctx ); - if( self->historical_roots ) { - fd_valloc_free( ctx->valloc, self->historical_roots ); - self->historical_roots = NULL; - } - if( self->historical_roots_with_hash ) { - for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) - fd_slot_map_pair_destroy( self->historical_roots_with_hash + i, ctx ); - fd_valloc_free( ctx->valloc, self->historical_roots_with_hash ); - self->historical_roots_with_hash = NULL; - } -} - -ulong fd_solana_accounts_db_fields_footprint( void ){ return FD_SOLANA_ACCOUNTS_DB_FIELDS_FOOTPRINT; } -ulong fd_solana_accounts_db_fields_align( void ){ return FD_SOLANA_ACCOUNTS_DB_FIELDS_ALIGN; } - -void fd_solana_accounts_db_fields_walk( void * w, fd_solana_accounts_db_fields_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_solana_accounts_db_fields", level++ ); - if( self->storages_len ) { - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "storages", level++ ); - for( ulong i=0; i < self->storages_len; i++ ) - fd_snapshot_slot_acc_vecs_walk(w, self->storages + i, fun, "snapshot_slot_acc_vecs", level ); - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "storages", level-- ); - } - fun( w, &self->version, "version", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->slot, "slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fd_bank_hash_info_walk( w, &self->bank_hash_info, fun, "bank_hash_info", level ); - if( self->historical_roots_len ) { - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "historical_roots", level++ ); - for( ulong i=0; i < self->historical_roots_len; i++ ) - fun( w, self->historical_roots + i, "historical_roots", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "historical_roots", level-- ); - } - if( self->historical_roots_with_hash_len ) { - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "historical_roots_with_hash", level++ ); - for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) - fd_slot_map_pair_walk(w, self->historical_roots_with_hash + i, fun, "slot_map_pair", level ); - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "historical_roots_with_hash", level-- ); - } - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_solana_accounts_db_fields", level-- ); -} -ulong fd_solana_accounts_db_fields_size( fd_solana_accounts_db_fields_t const * self ) { - ulong size = 0; - do { - size += sizeof(ulong); - for( ulong i=0; i < self->storages_len; i++ ) - size += fd_snapshot_slot_acc_vecs_size( self->storages + i ); - } while(0); - size += sizeof(ulong); - size += sizeof(ulong); - size += fd_bank_hash_info_size( &self->bank_hash_info ); - do { - size += sizeof(ulong); - size += self->historical_roots_len * sizeof(ulong); - } while(0); - do { - size += sizeof(ulong); - for( ulong i=0; i < self->historical_roots_with_hash_len; i++ ) - size += fd_slot_map_pair_size( self->historical_roots_with_hash + i ); - } while(0); - return size; -} - -int fd_solana_manifest_decode( fd_solana_manifest_t * self, fd_bincode_decode_ctx_t * ctx ) { - void const * data = ctx->data; - int err = fd_solana_manifest_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - ctx->data = data; - if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_solana_manifest_new( self ); - } - fd_solana_manifest_decode_unsafe( self, ctx ); - return FD_BINCODE_SUCCESS; -} -int fd_solana_manifest_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { - int err; - err = fd_deserializable_versioned_bank_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_solana_accounts_db_fields_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( ctx->data == ctx->dataend ) return FD_BINCODE_SUCCESS; - { - uchar o; - err = fd_bincode_bool_decode( &o, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( o ) { - err = fd_bank_incremental_snapshot_persistence_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } - if( ctx->data == ctx->dataend ) return FD_BINCODE_SUCCESS; - { - uchar o; - err = fd_bincode_bool_decode( &o, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( o ) { - err = fd_hash_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } - if( ctx->data == ctx->dataend ) return FD_BINCODE_SUCCESS; - { - uchar o; - err = fd_bincode_bool_decode( &o, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( o ) { - err = fd_serializable_epoch_reward_status_decode_preflight( ctx ); + if( ctx->data == ctx->dataend ) return FD_BINCODE_SUCCESS; + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_epoch_reward_status_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } } @@ -7254,9 +7390,9 @@ void fd_solana_manifest_decode_unsafe( fd_solana_manifest_t * self, fd_bincode_d uchar o; fd_bincode_bool_decode_unsafe( &o, ctx ); if( o ) { - self->epoch_reward_status = (fd_serializable_epoch_reward_status_t *)fd_valloc_malloc( ctx->valloc, FD_SERIALIZABLE_EPOCH_REWARD_STATUS_ALIGN, FD_SERIALIZABLE_EPOCH_REWARD_STATUS_FOOTPRINT ); - fd_serializable_epoch_reward_status_new( self->epoch_reward_status ); - fd_serializable_epoch_reward_status_decode_unsafe( self->epoch_reward_status, ctx ); + self->epoch_reward_status = (fd_epoch_reward_status_t *)fd_valloc_malloc( ctx->valloc, FD_EPOCH_REWARD_STATUS_ALIGN, FD_EPOCH_REWARD_STATUS_FOOTPRINT ); + fd_epoch_reward_status_new( self->epoch_reward_status ); + fd_epoch_reward_status_decode_unsafe( self->epoch_reward_status, ctx ); } else self->epoch_reward_status = NULL; } @@ -7290,7 +7426,7 @@ int fd_solana_manifest_encode( fd_solana_manifest_t const * self, fd_bincode_enc if( self->epoch_reward_status != NULL ) { err = fd_bincode_bool_encode( 1, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_serializable_epoch_reward_status_encode( self->epoch_reward_status, ctx ); + err = fd_epoch_reward_status_encode( self->epoch_reward_status, ctx ); if( FD_UNLIKELY( err ) ) return err; } else { err = fd_bincode_bool_encode( 0, ctx ); @@ -7339,7 +7475,7 @@ int fd_solana_manifest_decode_offsets( fd_solana_manifest_off_t * self, fd_binco err = fd_bincode_bool_decode( &o, ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; if( o ) { - err = fd_serializable_epoch_reward_status_decode_preflight( ctx ); + err = fd_epoch_reward_status_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; } } @@ -7364,7 +7500,7 @@ void fd_solana_manifest_destroy( fd_solana_manifest_t * self, fd_bincode_destroy self->epoch_account_hash = NULL; } if( self->epoch_reward_status ) { - fd_serializable_epoch_reward_status_destroy( self->epoch_reward_status, ctx ); + fd_epoch_reward_status_destroy( self->epoch_reward_status, ctx ); fd_valloc_free( ctx->valloc, self->epoch_reward_status ); self->epoch_reward_status = NULL; } @@ -7389,9 +7525,9 @@ void fd_solana_manifest_walk( void * w, fd_solana_manifest_t const * self, fd_ty fd_hash_walk( w, self->epoch_account_hash, fun, "epoch_account_hash", level ); } if( !self->epoch_reward_status ) { - fun( w, NULL, "epoch_reward_status", FD_FLAMENCO_TYPE_NULL, "serializable_epoch_reward_status", level ); + fun( w, NULL, "epoch_reward_status", FD_FLAMENCO_TYPE_NULL, "epoch_reward_status", level ); } else { - fd_serializable_epoch_reward_status_walk( w, self->epoch_reward_status, fun, "epoch_reward_status", level ); + fd_epoch_reward_status_walk( w, self->epoch_reward_status, fun, "epoch_reward_status", level ); } fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_solana_manifest", level-- ); } @@ -7410,7 +7546,7 @@ ulong fd_solana_manifest_size( fd_solana_manifest_t const * self ) { } size += sizeof(char); if( NULL != self->epoch_reward_status ) { - size += fd_serializable_epoch_reward_status_size( self->epoch_reward_status ); + size += fd_epoch_reward_status_size( self->epoch_reward_status ); } return size; } @@ -12525,46 +12661,106 @@ int fd_sysvar_epoch_rewards_decode( fd_sysvar_epoch_rewards_t * self, fd_bincode } int fd_sysvar_epoch_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { int err; - err = fd_epoch_rewards_decode_preflight( ctx ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_hash_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint8_decode_preflight( ctx ); if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } void fd_sysvar_epoch_rewards_decode_unsafe( fd_sysvar_epoch_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_epoch_rewards_decode_unsafe( &self->epoch_rewards, ctx ); + fd_bincode_uint64_decode_unsafe( &self->distribution_starting_block_height, ctx ); + fd_bincode_uint64_decode_unsafe( &self->num_partitions, ctx ); + fd_hash_decode_unsafe( &self->parent_blockhash, ctx ); + fd_bincode_uint128_decode_unsafe( &self->total_points, ctx ); + fd_bincode_uint64_decode_unsafe( &self->total_rewards, ctx ); + fd_bincode_uint64_decode_unsafe( &self->distributed_rewards, ctx ); + fd_bincode_uint8_decode_unsafe( &self->active, ctx ); } int fd_sysvar_epoch_rewards_encode( fd_sysvar_epoch_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_epoch_rewards_encode( &self->epoch_rewards, ctx ); + err = fd_bincode_uint64_encode( self->distribution_starting_block_height, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->num_partitions, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_hash_encode( &self->parent_blockhash, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint128_encode( self->total_points, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->total_rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->distributed_rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint8_encode( (uchar)(self->active), ctx ); if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } int fd_sysvar_epoch_rewards_decode_offsets( fd_sysvar_epoch_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ) { uchar const * data = ctx->data; int err; - self->epoch_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_epoch_rewards_decode_preflight( ctx ); + self->distribution_starting_block_height_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->num_partitions_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->parent_blockhash_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_hash_decode_preflight( ctx ); if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -void fd_sysvar_epoch_rewards_new(fd_sysvar_epoch_rewards_t * self) { - fd_memset( self, 0, sizeof(fd_sysvar_epoch_rewards_t) ); - fd_epoch_rewards_new( &self->epoch_rewards ); -} -void fd_sysvar_epoch_rewards_destroy( fd_sysvar_epoch_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ) { - fd_epoch_rewards_destroy( &self->epoch_rewards, ctx ); -} - -ulong fd_sysvar_epoch_rewards_footprint( void ){ return FD_SYSVAR_EPOCH_REWARDS_FOOTPRINT; } -ulong fd_sysvar_epoch_rewards_align( void ){ return FD_SYSVAR_EPOCH_REWARDS_ALIGN; } - + self->total_points_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->total_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->distributed_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->active_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint8_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_sysvar_epoch_rewards_new(fd_sysvar_epoch_rewards_t * self) { + fd_memset( self, 0, sizeof(fd_sysvar_epoch_rewards_t) ); + fd_hash_new( &self->parent_blockhash ); +} +void fd_sysvar_epoch_rewards_destroy( fd_sysvar_epoch_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_hash_destroy( &self->parent_blockhash, ctx ); +} + +ulong fd_sysvar_epoch_rewards_footprint( void ){ return FD_SYSVAR_EPOCH_REWARDS_FOOTPRINT; } +ulong fd_sysvar_epoch_rewards_align( void ){ return FD_SYSVAR_EPOCH_REWARDS_ALIGN; } + void fd_sysvar_epoch_rewards_walk( void * w, fd_sysvar_epoch_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_sysvar_epoch_rewards", level++ ); - fd_epoch_rewards_walk( w, &self->epoch_rewards, fun, "epoch_rewards", level ); + fun( w, &self->distribution_starting_block_height, "distribution_starting_block_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->num_partitions, "num_partitions", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fd_hash_walk( w, &self->parent_blockhash, fun, "parent_blockhash", level ); + fun( w, &self->total_points, "total_points", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); + fun( w, &self->total_rewards, "total_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->distributed_rewards, "distributed_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->active, "active", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_sysvar_epoch_rewards", level-- ); } ulong fd_sysvar_epoch_rewards_size( fd_sysvar_epoch_rewards_t const * self ) { ulong size = 0; - size += fd_epoch_rewards_size( &self->epoch_rewards ); + size += sizeof(ulong); + size += sizeof(ulong); + size += fd_hash_size( &self->parent_blockhash ); + size += sizeof(uint128); + size += sizeof(ulong); + size += sizeof(ulong); + size += sizeof(char); return size; } @@ -18818,72 +19014,6 @@ ulong fd_stake_meta_size( fd_stake_meta_t const * self ) { return size; } -int fd_stake_decode( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ) { - void const * data = ctx->data; - int err = fd_stake_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - ctx->data = data; - if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_stake_new( self ); - } - fd_stake_decode_unsafe( self, ctx ); - return FD_BINCODE_SUCCESS; -} -int fd_stake_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { - int err; - err = fd_delegation_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - return FD_BINCODE_SUCCESS; -} -void fd_stake_decode_unsafe( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_delegation_decode_unsafe( &self->delegation, ctx ); - fd_bincode_uint64_decode_unsafe( &self->credits_observed, ctx ); -} -int fd_stake_encode( fd_stake_t const * self, fd_bincode_encode_ctx_t * ctx ) { - int err; - err = fd_delegation_encode( &self->delegation, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->credits_observed, ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -int fd_stake_decode_offsets( fd_stake_off_t * self, fd_bincode_decode_ctx_t * ctx ) { - uchar const * data = ctx->data; - int err; - self->delegation_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_delegation_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - self->credits_observed_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_uint64_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - return FD_BINCODE_SUCCESS; -} -void fd_stake_new(fd_stake_t * self) { - fd_memset( self, 0, sizeof(fd_stake_t) ); - fd_delegation_new( &self->delegation ); -} -void fd_stake_destroy( fd_stake_t * self, fd_bincode_destroy_ctx_t * ctx ) { - fd_delegation_destroy( &self->delegation, ctx ); -} - -ulong fd_stake_footprint( void ){ return FD_STAKE_FOOTPRINT; } -ulong fd_stake_align( void ){ return FD_STAKE_ALIGN; } - -void fd_stake_walk( void * w, fd_stake_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_stake", level++ ); - fd_delegation_walk( w, &self->delegation, fun, "delegation", level ); - fun( w, &self->credits_observed, "credits_observed", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_stake", level-- ); -} -ulong fd_stake_size( fd_stake_t const * self ) { - ulong size = 0; - size += fd_delegation_size( &self->delegation ); - size += sizeof(ulong); - return size; -} - int fd_stake_flags_decode( fd_stake_flags_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; int err = fd_stake_flags_decode_preflight( ctx ); @@ -29240,296 +29370,1651 @@ void fd_status_value_walk( void * w, fd_status_value_t const * self, fd_types_wa } fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_status_value", level-- ); } -ulong fd_status_value_size( fd_status_value_t const * self ) { +ulong fd_status_value_size( fd_status_value_t const * self ) { + ulong size = 0; + size += sizeof(ulong); + do { + size += sizeof(ulong); + for( ulong i=0; i < self->statuses_len; i++ ) + size += fd_cache_status_size( self->statuses + i ); + } while(0); + return size; +} + +int fd_status_pair_decode( fd_status_pair_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_status_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_status_pair_new( self ); + } + fd_status_pair_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_status_pair_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_hash_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_status_value_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_status_pair_decode_unsafe( fd_status_pair_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_hash_decode_unsafe( &self->hash, ctx ); + fd_status_value_decode_unsafe( &self->value, ctx ); +} +int fd_status_pair_encode( fd_status_pair_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_hash_encode( &self->hash, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_status_value_encode( &self->value, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_status_pair_decode_offsets( fd_status_pair_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->hash_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_hash_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->value_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_status_value_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_status_pair_new(fd_status_pair_t * self) { + fd_memset( self, 0, sizeof(fd_status_pair_t) ); + fd_hash_new( &self->hash ); + fd_status_value_new( &self->value ); +} +void fd_status_pair_destroy( fd_status_pair_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_hash_destroy( &self->hash, ctx ); + fd_status_value_destroy( &self->value, ctx ); +} + +ulong fd_status_pair_footprint( void ){ return FD_STATUS_PAIR_FOOTPRINT; } +ulong fd_status_pair_align( void ){ return FD_STATUS_PAIR_ALIGN; } + +void fd_status_pair_walk( void * w, fd_status_pair_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_status_pair", level++ ); + fd_hash_walk( w, &self->hash, fun, "hash", level ); + fd_status_value_walk( w, &self->value, fun, "value", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_status_pair", level-- ); +} +ulong fd_status_pair_size( fd_status_pair_t const * self ) { + ulong size = 0; + size += fd_hash_size( &self->hash ); + size += fd_status_value_size( &self->value ); + return size; +} + +int fd_slot_delta_decode( fd_slot_delta_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_slot_delta_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_slot_delta_new( self ); + } + fd_slot_delta_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_slot_delta_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_bool_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + ulong slot_delta_vec_len; + err = fd_bincode_uint64_decode( &slot_delta_vec_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( slot_delta_vec_len ) { + for( ulong i=0; i < slot_delta_vec_len; i++ ) { + err = fd_status_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_slot_delta_decode_unsafe( fd_slot_delta_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->slot, ctx ); + fd_bincode_bool_decode_unsafe( &self->is_root, ctx ); + fd_bincode_uint64_decode_unsafe( &self->slot_delta_vec_len, ctx ); + if( self->slot_delta_vec_len ) { + self->slot_delta_vec = (fd_status_pair_t *)fd_valloc_malloc( ctx->valloc, FD_STATUS_PAIR_ALIGN, FD_STATUS_PAIR_FOOTPRINT*self->slot_delta_vec_len ); + for( ulong i=0; i < self->slot_delta_vec_len; i++ ) { + fd_status_pair_new( self->slot_delta_vec + i ); + fd_status_pair_decode_unsafe( self->slot_delta_vec + i, ctx ); + } + } else + self->slot_delta_vec = NULL; +} +int fd_slot_delta_encode( fd_slot_delta_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->slot, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_bool_encode( (uchar)(self->is_root), ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->slot_delta_vec_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->slot_delta_vec_len ) { + for( ulong i=0; i < self->slot_delta_vec_len; i++ ) { + err = fd_status_pair_encode( self->slot_delta_vec + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +int fd_slot_delta_decode_offsets( fd_slot_delta_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->slot_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->is_root_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_bool_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->slot_delta_vec_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong slot_delta_vec_len; + err = fd_bincode_uint64_decode( &slot_delta_vec_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( slot_delta_vec_len ) { + for( ulong i=0; i < slot_delta_vec_len; i++ ) { + err = fd_status_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_slot_delta_new(fd_slot_delta_t * self) { + fd_memset( self, 0, sizeof(fd_slot_delta_t) ); +} +void fd_slot_delta_destroy( fd_slot_delta_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->slot_delta_vec ) { + for( ulong i=0; i < self->slot_delta_vec_len; i++ ) + fd_status_pair_destroy( self->slot_delta_vec + i, ctx ); + fd_valloc_free( ctx->valloc, self->slot_delta_vec ); + self->slot_delta_vec = NULL; + } +} + +ulong fd_slot_delta_footprint( void ){ return FD_SLOT_DELTA_FOOTPRINT; } +ulong fd_slot_delta_align( void ){ return FD_SLOT_DELTA_ALIGN; } + +void fd_slot_delta_walk( void * w, fd_slot_delta_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_slot_delta", level++ ); + fun( w, &self->slot, "slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->is_root, "is_root", FD_FLAMENCO_TYPE_BOOL, "bool", level ); + if( self->slot_delta_vec_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "slot_delta_vec", level++ ); + for( ulong i=0; i < self->slot_delta_vec_len; i++ ) + fd_status_pair_walk(w, self->slot_delta_vec + i, fun, "status_pair", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "slot_delta_vec", level-- ); + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_slot_delta", level-- ); +} +ulong fd_slot_delta_size( fd_slot_delta_t const * self ) { + ulong size = 0; + size += sizeof(ulong); + size += sizeof(char); + do { + size += sizeof(ulong); + for( ulong i=0; i < self->slot_delta_vec_len; i++ ) + size += fd_status_pair_size( self->slot_delta_vec + i ); + } while(0); + return size; +} + +int fd_bank_slot_deltas_decode( fd_bank_slot_deltas_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_bank_slot_deltas_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_bank_slot_deltas_new( self ); + } + fd_bank_slot_deltas_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_bank_slot_deltas_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + ulong slot_deltas_len; + err = fd_bincode_uint64_decode( &slot_deltas_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( slot_deltas_len ) { + for( ulong i=0; i < slot_deltas_len; i++ ) { + err = fd_slot_delta_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_bank_slot_deltas_decode_unsafe( fd_bank_slot_deltas_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->slot_deltas_len, ctx ); + if( self->slot_deltas_len ) { + self->slot_deltas = (fd_slot_delta_t *)fd_valloc_malloc( ctx->valloc, FD_SLOT_DELTA_ALIGN, FD_SLOT_DELTA_FOOTPRINT*self->slot_deltas_len ); + for( ulong i=0; i < self->slot_deltas_len; i++ ) { + fd_slot_delta_new( self->slot_deltas + i ); + fd_slot_delta_decode_unsafe( self->slot_deltas + i, ctx ); + } + } else + self->slot_deltas = NULL; +} +int fd_bank_slot_deltas_encode( fd_bank_slot_deltas_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->slot_deltas_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->slot_deltas_len ) { + for( ulong i=0; i < self->slot_deltas_len; i++ ) { + err = fd_slot_delta_encode( self->slot_deltas + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +int fd_bank_slot_deltas_decode_offsets( fd_bank_slot_deltas_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->slot_deltas_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong slot_deltas_len; + err = fd_bincode_uint64_decode( &slot_deltas_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( slot_deltas_len ) { + for( ulong i=0; i < slot_deltas_len; i++ ) { + err = fd_slot_delta_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_bank_slot_deltas_new(fd_bank_slot_deltas_t * self) { + fd_memset( self, 0, sizeof(fd_bank_slot_deltas_t) ); +} +void fd_bank_slot_deltas_destroy( fd_bank_slot_deltas_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->slot_deltas ) { + for( ulong i=0; i < self->slot_deltas_len; i++ ) + fd_slot_delta_destroy( self->slot_deltas + i, ctx ); + fd_valloc_free( ctx->valloc, self->slot_deltas ); + self->slot_deltas = NULL; + } +} + +ulong fd_bank_slot_deltas_footprint( void ){ return FD_BANK_SLOT_DELTAS_FOOTPRINT; } +ulong fd_bank_slot_deltas_align( void ){ return FD_BANK_SLOT_DELTAS_ALIGN; } + +void fd_bank_slot_deltas_walk( void * w, fd_bank_slot_deltas_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_bank_slot_deltas", level++ ); + if( self->slot_deltas_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "slot_deltas", level++ ); + for( ulong i=0; i < self->slot_deltas_len; i++ ) + fd_slot_delta_walk(w, self->slot_deltas + i, fun, "slot_delta", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "slot_deltas", level-- ); + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_bank_slot_deltas", level-- ); +} +ulong fd_bank_slot_deltas_size( fd_bank_slot_deltas_t const * self ) { + ulong size = 0; + do { + size += sizeof(ulong); + for( ulong i=0; i < self->slot_deltas_len; i++ ) + size += fd_slot_delta_size( self->slot_deltas + i ); + } while(0); + return size; +} + +int fd_pubkey_rewardinfo_pair_decode( fd_pubkey_rewardinfo_pair_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_pubkey_rewardinfo_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_pubkey_rewardinfo_pair_new( self ); + } + fd_pubkey_rewardinfo_pair_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_pubkey_rewardinfo_pair_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_bincode_bytes_decode_preflight( 32, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_reward_info_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_pubkey_rewardinfo_pair_decode_unsafe( fd_pubkey_rewardinfo_pair_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_pubkey_decode_unsafe( &self->pubkey, ctx ); + fd_reward_info_decode_unsafe( &self->reward_info, ctx ); +} +int fd_pubkey_rewardinfo_pair_encode( fd_pubkey_rewardinfo_pair_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_pubkey_encode( &self->pubkey, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_reward_info_encode( &self->reward_info, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_pubkey_rewardinfo_pair_decode_offsets( fd_pubkey_rewardinfo_pair_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->pubkey_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_bytes_decode_preflight( 32, ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->reward_info_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_reward_info_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_pubkey_rewardinfo_pair_new(fd_pubkey_rewardinfo_pair_t * self) { + fd_memset( self, 0, sizeof(fd_pubkey_rewardinfo_pair_t) ); + fd_pubkey_new( &self->pubkey ); + fd_reward_info_new( &self->reward_info ); +} +void fd_pubkey_rewardinfo_pair_destroy( fd_pubkey_rewardinfo_pair_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_pubkey_destroy( &self->pubkey, ctx ); + fd_reward_info_destroy( &self->reward_info, ctx ); +} + +ulong fd_pubkey_rewardinfo_pair_footprint( void ){ return FD_PUBKEY_REWARDINFO_PAIR_FOOTPRINT; } +ulong fd_pubkey_rewardinfo_pair_align( void ){ return FD_PUBKEY_REWARDINFO_PAIR_ALIGN; } + +void fd_pubkey_rewardinfo_pair_walk( void * w, fd_pubkey_rewardinfo_pair_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_pubkey_rewardinfo_pair", level++ ); + fd_pubkey_walk( w, &self->pubkey, fun, "pubkey", level ); + fd_reward_info_walk( w, &self->reward_info, fun, "reward_info", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_pubkey_rewardinfo_pair", level-- ); +} +ulong fd_pubkey_rewardinfo_pair_size( fd_pubkey_rewardinfo_pair_t const * self ) { + ulong size = 0; + size += fd_pubkey_size( &self->pubkey ); + size += fd_reward_info_size( &self->reward_info ); + return size; +} + +int fd_optional_account_decode( fd_optional_account_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_optional_account_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_optional_account_new( self ); + } + fd_optional_account_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_optional_account_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_solana_account_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_optional_account_decode_unsafe( fd_optional_account_t * self, fd_bincode_decode_ctx_t * ctx ) { + { + uchar o; + fd_bincode_bool_decode_unsafe( &o, ctx ); + if( o ) { + self->account = (fd_solana_account_t *)fd_valloc_malloc( ctx->valloc, FD_SOLANA_ACCOUNT_ALIGN, FD_SOLANA_ACCOUNT_FOOTPRINT ); + fd_solana_account_new( self->account ); + fd_solana_account_decode_unsafe( self->account, ctx ); + } else + self->account = NULL; + } +} +int fd_optional_account_encode( fd_optional_account_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + if( self->account != NULL ) { + err = fd_bincode_bool_encode( 1, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_solana_account_encode( self->account, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } else { + err = fd_bincode_bool_encode( 0, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + return FD_BINCODE_SUCCESS; +} +int fd_optional_account_decode_offsets( fd_optional_account_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->account_off = (uint)( (ulong)ctx->data - (ulong)data ); + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_solana_account_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_optional_account_new(fd_optional_account_t * self) { + fd_memset( self, 0, sizeof(fd_optional_account_t) ); +} +void fd_optional_account_destroy( fd_optional_account_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->account ) { + fd_solana_account_destroy( self->account, ctx ); + fd_valloc_free( ctx->valloc, self->account ); + self->account = NULL; + } +} + +ulong fd_optional_account_footprint( void ){ return FD_OPTIONAL_ACCOUNT_FOOTPRINT; } +ulong fd_optional_account_align( void ){ return FD_OPTIONAL_ACCOUNT_ALIGN; } + +void fd_optional_account_walk( void * w, fd_optional_account_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_optional_account", level++ ); + if( !self->account ) { + fun( w, NULL, "account", FD_FLAMENCO_TYPE_NULL, "solana_account", level ); + } else { + fd_solana_account_walk( w, self->account, fun, "account", level ); + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_optional_account", level-- ); +} +ulong fd_optional_account_size( fd_optional_account_t const * self ) { + ulong size = 0; + size += sizeof(char); + if( NULL != self->account ) { + size += fd_solana_account_size( self->account ); + } + return size; +} + +int fd_vote_rewards_accounts_decode( fd_vote_rewards_accounts_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_vote_rewards_accounts_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_vote_rewards_accounts_new( self ); + } + fd_vote_rewards_accounts_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_vote_rewards_accounts_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + ulong rewards_len; + err = fd_bincode_uint64_decode( &rewards_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( rewards_len ) { + for( ulong i=0; i < rewards_len; i++ ) { + err = fd_pubkey_rewardinfo_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + ulong accounts_to_store_len; + err = fd_bincode_uint64_decode( &accounts_to_store_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( accounts_to_store_len ) { + for( ulong i=0; i < accounts_to_store_len; i++ ) { + err = fd_optional_account_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_vote_rewards_accounts_decode_unsafe( fd_vote_rewards_accounts_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->rewards_len, ctx ); + if( self->rewards_len ) { + self->rewards = (fd_pubkey_rewardinfo_pair_t *)fd_valloc_malloc( ctx->valloc, FD_PUBKEY_REWARDINFO_PAIR_ALIGN, FD_PUBKEY_REWARDINFO_PAIR_FOOTPRINT*self->rewards_len ); + for( ulong i=0; i < self->rewards_len; i++ ) { + fd_pubkey_rewardinfo_pair_new( self->rewards + i ); + fd_pubkey_rewardinfo_pair_decode_unsafe( self->rewards + i, ctx ); + } + } else + self->rewards = NULL; + fd_bincode_uint64_decode_unsafe( &self->accounts_to_store_len, ctx ); + if( self->accounts_to_store_len ) { + self->accounts_to_store = (fd_optional_account_t *)fd_valloc_malloc( ctx->valloc, FD_OPTIONAL_ACCOUNT_ALIGN, FD_OPTIONAL_ACCOUNT_FOOTPRINT*self->accounts_to_store_len ); + for( ulong i=0; i < self->accounts_to_store_len; i++ ) { + fd_optional_account_new( self->accounts_to_store + i ); + fd_optional_account_decode_unsafe( self->accounts_to_store + i, ctx ); + } + } else + self->accounts_to_store = NULL; +} +int fd_vote_rewards_accounts_encode( fd_vote_rewards_accounts_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->rewards_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->rewards_len ) { + for( ulong i=0; i < self->rewards_len; i++ ) { + err = fd_pubkey_rewardinfo_pair_encode( self->rewards + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + err = fd_bincode_uint64_encode( self->accounts_to_store_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->accounts_to_store_len ) { + for( ulong i=0; i < self->accounts_to_store_len; i++ ) { + err = fd_optional_account_encode( self->accounts_to_store + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +int fd_vote_rewards_accounts_decode_offsets( fd_vote_rewards_accounts_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong rewards_len; + err = fd_bincode_uint64_decode( &rewards_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( rewards_len ) { + for( ulong i=0; i < rewards_len; i++ ) { + err = fd_pubkey_rewardinfo_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + self->accounts_to_store_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong accounts_to_store_len; + err = fd_bincode_uint64_decode( &accounts_to_store_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( accounts_to_store_len ) { + for( ulong i=0; i < accounts_to_store_len; i++ ) { + err = fd_optional_account_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_vote_rewards_accounts_new(fd_vote_rewards_accounts_t * self) { + fd_memset( self, 0, sizeof(fd_vote_rewards_accounts_t) ); +} +void fd_vote_rewards_accounts_destroy( fd_vote_rewards_accounts_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->rewards ) { + for( ulong i=0; i < self->rewards_len; i++ ) + fd_pubkey_rewardinfo_pair_destroy( self->rewards + i, ctx ); + fd_valloc_free( ctx->valloc, self->rewards ); + self->rewards = NULL; + } + if( self->accounts_to_store ) { + for( ulong i=0; i < self->accounts_to_store_len; i++ ) + fd_optional_account_destroy( self->accounts_to_store + i, ctx ); + fd_valloc_free( ctx->valloc, self->accounts_to_store ); + self->accounts_to_store = NULL; + } +} + +ulong fd_vote_rewards_accounts_footprint( void ){ return FD_VOTE_REWARDS_ACCOUNTS_FOOTPRINT; } +ulong fd_vote_rewards_accounts_align( void ){ return FD_VOTE_REWARDS_ACCOUNTS_ALIGN; } + +void fd_vote_rewards_accounts_walk( void * w, fd_vote_rewards_accounts_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_vote_rewards_accounts", level++ ); + if( self->rewards_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "rewards", level++ ); + for( ulong i=0; i < self->rewards_len; i++ ) + fd_pubkey_rewardinfo_pair_walk(w, self->rewards + i, fun, "pubkey_rewardinfo_pair", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "rewards", level-- ); + } + if( self->accounts_to_store_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "accounts_to_store", level++ ); + for( ulong i=0; i < self->accounts_to_store_len; i++ ) + fd_optional_account_walk(w, self->accounts_to_store + i, fun, "optional_account", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "accounts_to_store", level-- ); + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_vote_rewards_accounts", level-- ); +} +ulong fd_vote_rewards_accounts_size( fd_vote_rewards_accounts_t const * self ) { + ulong size = 0; + do { + size += sizeof(ulong); + for( ulong i=0; i < self->rewards_len; i++ ) + size += fd_pubkey_rewardinfo_pair_size( self->rewards + i ); + } while(0); + do { + size += sizeof(ulong); + for( ulong i=0; i < self->accounts_to_store_len; i++ ) + size += fd_optional_account_size( self->accounts_to_store + i ); + } while(0); + return size; +} + +int fd_stake_reward_calculation_decode( fd_stake_reward_calculation_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_stake_reward_calculation_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_stake_reward_calculation_new( self ); + } + fd_stake_reward_calculation_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_stake_reward_calculation_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + ulong stake_reward_deq_len; + err = fd_bincode_uint64_decode( &stake_reward_deq_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( ulong i = 0; i < stake_reward_deq_len; ++i ) { + err = fd_partitioned_stake_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_stake_reward_calculation_decode_unsafe( fd_stake_reward_calculation_t * self, fd_bincode_decode_ctx_t * ctx ) { + ulong stake_reward_deq_len; + fd_bincode_uint64_decode_unsafe( &stake_reward_deq_len, ctx ); + ulong stake_reward_deq_max = fd_ulong_max( stake_reward_deq_len, 24 ); + self->stake_reward_deq = deq_fd_partitioned_stake_reward_t_alloc( ctx->valloc, stake_reward_deq_max ); + for( ulong i=0; i < stake_reward_deq_len; i++ ) { + fd_partitioned_stake_reward_t * elem = deq_fd_partitioned_stake_reward_t_push_tail_nocopy( self->stake_reward_deq ); + fd_partitioned_stake_reward_new( elem ); + fd_partitioned_stake_reward_decode_unsafe( elem, ctx ); + } + fd_bincode_uint64_decode_unsafe( &self->total_stake_rewards_lamports, ctx ); +} +int fd_stake_reward_calculation_encode( fd_stake_reward_calculation_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + if( self->stake_reward_deq ) { + ulong stake_reward_deq_len = deq_fd_partitioned_stake_reward_t_cnt( self->stake_reward_deq ); + err = fd_bincode_uint64_encode( stake_reward_deq_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( deq_fd_partitioned_stake_reward_t_iter_t iter = deq_fd_partitioned_stake_reward_t_iter_init( self->stake_reward_deq ); !deq_fd_partitioned_stake_reward_t_iter_done( self->stake_reward_deq, iter ); iter = deq_fd_partitioned_stake_reward_t_iter_next( self->stake_reward_deq, iter ) ) { + fd_partitioned_stake_reward_t const * ele = deq_fd_partitioned_stake_reward_t_iter_ele_const( self->stake_reward_deq, iter ); + err = fd_partitioned_stake_reward_encode( ele, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } else { + ulong stake_reward_deq_len = 0; + err = fd_bincode_uint64_encode( stake_reward_deq_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + err = fd_bincode_uint64_encode( self->total_stake_rewards_lamports, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_stake_reward_calculation_decode_offsets( fd_stake_reward_calculation_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->stake_reward_deq_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong stake_reward_deq_len; + err = fd_bincode_uint64_decode( &stake_reward_deq_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( ulong i = 0; i < stake_reward_deq_len; ++i ) { + err = fd_partitioned_stake_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + self->total_stake_rewards_lamports_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_stake_reward_calculation_new(fd_stake_reward_calculation_t * self) { + fd_memset( self, 0, sizeof(fd_stake_reward_calculation_t) ); +} +void fd_stake_reward_calculation_destroy( fd_stake_reward_calculation_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->stake_reward_deq ) { + for( deq_fd_partitioned_stake_reward_t_iter_t iter = deq_fd_partitioned_stake_reward_t_iter_init( self->stake_reward_deq ); !deq_fd_partitioned_stake_reward_t_iter_done( self->stake_reward_deq, iter ); iter = deq_fd_partitioned_stake_reward_t_iter_next( self->stake_reward_deq, iter ) ) { + fd_partitioned_stake_reward_t * ele = deq_fd_partitioned_stake_reward_t_iter_ele( self->stake_reward_deq, iter ); + fd_partitioned_stake_reward_destroy( ele, ctx ); + } + fd_valloc_free( ctx->valloc, deq_fd_partitioned_stake_reward_t_delete( deq_fd_partitioned_stake_reward_t_leave( self->stake_reward_deq) ) ); + self->stake_reward_deq = NULL; + } +} + +ulong fd_stake_reward_calculation_footprint( void ){ return FD_STAKE_REWARD_CALCULATION_FOOTPRINT; } +ulong fd_stake_reward_calculation_align( void ){ return FD_STAKE_REWARD_CALCULATION_ALIGN; } + +void fd_stake_reward_calculation_walk( void * w, fd_stake_reward_calculation_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_stake_reward_calculation", level++ ); + + /* Walk deque */ + fun( w, self->stake_reward_deq, "stake_reward_deq", FD_FLAMENCO_TYPE_ARR, "stake_reward_deq", level++ ); + if( self->stake_reward_deq ) { + for( deq_fd_partitioned_stake_reward_t_iter_t iter = deq_fd_partitioned_stake_reward_t_iter_init( self->stake_reward_deq ); + !deq_fd_partitioned_stake_reward_t_iter_done( self->stake_reward_deq, iter ); + iter = deq_fd_partitioned_stake_reward_t_iter_next( self->stake_reward_deq, iter ) ) { + fd_partitioned_stake_reward_t * ele = deq_fd_partitioned_stake_reward_t_iter_ele( self->stake_reward_deq, iter ); + fd_partitioned_stake_reward_walk(w, ele, fun, "stake_reward_deq", level ); + } + } + fun( w, self->stake_reward_deq, "stake_reward_deq", FD_FLAMENCO_TYPE_ARR_END, "stake_reward_deq", level-- ); + /* Done walking deque */ + + fun( w, &self->total_stake_rewards_lamports, "total_stake_rewards_lamports", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_stake_reward_calculation", level-- ); +} +ulong fd_stake_reward_calculation_size( fd_stake_reward_calculation_t const * self ) { + ulong size = 0; + if( self->stake_reward_deq ) { + size += sizeof(ulong); + for( deq_fd_partitioned_stake_reward_t_iter_t iter = deq_fd_partitioned_stake_reward_t_iter_init( self->stake_reward_deq ); !deq_fd_partitioned_stake_reward_t_iter_done( self->stake_reward_deq, iter ); iter = deq_fd_partitioned_stake_reward_t_iter_next( self->stake_reward_deq, iter ) ) { + fd_partitioned_stake_reward_t * ele = deq_fd_partitioned_stake_reward_t_iter_ele( self->stake_reward_deq, iter ); + size += fd_partitioned_stake_reward_size( ele ); + } + } else { + size += sizeof(ulong); + } + size += sizeof(ulong); + return size; +} + +int fd_stake_reward_calculation_partitioned_decode( fd_stake_reward_calculation_partitioned_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_stake_reward_calculation_partitioned_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_stake_reward_calculation_partitioned_new( self ); + } + fd_stake_reward_calculation_partitioned_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_stake_reward_calculation_partitioned_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + ulong stake_rewards_by_partition_len; + err = fd_bincode_uint64_decode( &stake_rewards_by_partition_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( stake_rewards_by_partition_len ) { + for( ulong i=0; i < stake_rewards_by_partition_len; i++ ) { + err = fd_partitioned_stake_rewards_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_stake_reward_calculation_partitioned_decode_unsafe( fd_stake_reward_calculation_partitioned_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->stake_rewards_by_partition_len, ctx ); + if( self->stake_rewards_by_partition_len ) { + self->stake_rewards_by_partition = (fd_partitioned_stake_rewards_t *)fd_valloc_malloc( ctx->valloc, FD_PARTITIONED_STAKE_REWARDS_ALIGN, FD_PARTITIONED_STAKE_REWARDS_FOOTPRINT*self->stake_rewards_by_partition_len ); + for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) { + fd_partitioned_stake_rewards_new( self->stake_rewards_by_partition + i ); + fd_partitioned_stake_rewards_decode_unsafe( self->stake_rewards_by_partition + i, ctx ); + } + } else + self->stake_rewards_by_partition = NULL; + fd_bincode_uint64_decode_unsafe( &self->total_stake_rewards_lamports, ctx ); +} +int fd_stake_reward_calculation_partitioned_encode( fd_stake_reward_calculation_partitioned_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->stake_rewards_by_partition_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->stake_rewards_by_partition_len ) { + for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) { + err = fd_partitioned_stake_rewards_encode( self->stake_rewards_by_partition + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + err = fd_bincode_uint64_encode( self->total_stake_rewards_lamports, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_stake_reward_calculation_partitioned_decode_offsets( fd_stake_reward_calculation_partitioned_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->stake_rewards_by_partition_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong stake_rewards_by_partition_len; + err = fd_bincode_uint64_decode( &stake_rewards_by_partition_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( stake_rewards_by_partition_len ) { + for( ulong i=0; i < stake_rewards_by_partition_len; i++ ) { + err = fd_partitioned_stake_rewards_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + self->total_stake_rewards_lamports_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_stake_reward_calculation_partitioned_new(fd_stake_reward_calculation_partitioned_t * self) { + fd_memset( self, 0, sizeof(fd_stake_reward_calculation_partitioned_t) ); +} +void fd_stake_reward_calculation_partitioned_destroy( fd_stake_reward_calculation_partitioned_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->stake_rewards_by_partition ) { + for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) + fd_partitioned_stake_rewards_destroy( self->stake_rewards_by_partition + i, ctx ); + fd_valloc_free( ctx->valloc, self->stake_rewards_by_partition ); + self->stake_rewards_by_partition = NULL; + } +} + +ulong fd_stake_reward_calculation_partitioned_footprint( void ){ return FD_STAKE_REWARD_CALCULATION_PARTITIONED_FOOTPRINT; } +ulong fd_stake_reward_calculation_partitioned_align( void ){ return FD_STAKE_REWARD_CALCULATION_PARTITIONED_ALIGN; } + +void fd_stake_reward_calculation_partitioned_walk( void * w, fd_stake_reward_calculation_partitioned_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_stake_reward_calculation_partitioned", level++ ); + if( self->stake_rewards_by_partition_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "stake_rewards_by_partition", level++ ); + for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) + fd_partitioned_stake_rewards_walk(w, self->stake_rewards_by_partition + i, fun, "partitioned_stake_rewards", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "stake_rewards_by_partition", level-- ); + } + fun( w, &self->total_stake_rewards_lamports, "total_stake_rewards_lamports", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_stake_reward_calculation_partitioned", level-- ); +} +ulong fd_stake_reward_calculation_partitioned_size( fd_stake_reward_calculation_partitioned_t const * self ) { + ulong size = 0; + do { + size += sizeof(ulong); + for( ulong i=0; i < self->stake_rewards_by_partition_len; i++ ) + size += fd_partitioned_stake_rewards_size( self->stake_rewards_by_partition + i ); + } while(0); + size += sizeof(ulong); + return size; +} + +int fd_partitioned_rewards_calculation_decode( fd_partitioned_rewards_calculation_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_partitioned_rewards_calculation_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_partitioned_rewards_calculation_new( self ); + } + fd_partitioned_rewards_calculation_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_partitioned_rewards_calculation_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + ulong vote_reward_map_len; + err = fd_bincode_uint64_decode( &vote_reward_map_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( ulong i=0; i < vote_reward_map_len; i++ ) { + err = fd_vote_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + err = fd_stake_reward_calculation_partitioned_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_double_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_double_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_double_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_partitioned_rewards_calculation_decode_unsafe( fd_partitioned_rewards_calculation_t * self, fd_bincode_decode_ctx_t * ctx ) { + ulong vote_reward_map_len; + fd_bincode_uint64_decode_unsafe( &vote_reward_map_len, ctx ); + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + self->vote_reward_map_pool = fd_vote_reward_t_map_alloc( ctx->valloc, fd_ulong_max(vote_reward_map_len, 24 ) ); + self->vote_reward_map_root = NULL; + } + for( ulong i=0; i < vote_reward_map_len; i++ ) { + fd_vote_reward_t_mapnode_t * node = fd_vote_reward_t_map_acquire( self->vote_reward_map_pool ); + fd_vote_reward_new( &node->elem ); + fd_vote_reward_decode_unsafe( &node->elem, ctx ); + fd_vote_reward_t_map_insert( self->vote_reward_map_pool, &self->vote_reward_map_root, node ); + } + fd_stake_reward_calculation_partitioned_decode_unsafe( &self->stake_rewards_by_partition, ctx ); + fd_bincode_uint64_decode_unsafe( &self->old_vote_balance_and_staked, ctx ); + fd_bincode_uint64_decode_unsafe( &self->validator_rewards, ctx ); + fd_bincode_double_decode_unsafe( &self->validator_rate, ctx ); + fd_bincode_double_decode_unsafe( &self->foundation_rate, ctx ); + fd_bincode_double_decode_unsafe( &self->prev_epoch_duration_in_years, ctx ); + fd_bincode_uint64_decode_unsafe( &self->capitalization, ctx ); + fd_bincode_uint128_decode_unsafe( &self->total_points, ctx ); +} +int fd_partitioned_rewards_calculation_encode( fd_partitioned_rewards_calculation_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + if( self->vote_reward_map_root ) { + ulong vote_reward_map_len = fd_vote_reward_t_map_size( self->vote_reward_map_pool, self->vote_reward_map_root ); + err = fd_bincode_uint64_encode( vote_reward_map_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum( self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor( self->vote_reward_map_pool, n ) ) { + err = fd_vote_reward_encode( &n->elem, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } else { + ulong vote_reward_map_len = 0; + err = fd_bincode_uint64_encode( vote_reward_map_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + err = fd_stake_reward_calculation_partitioned_encode( &self->stake_rewards_by_partition, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->old_vote_balance_and_staked, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->validator_rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_double_encode( self->validator_rate, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_double_encode( self->foundation_rate, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_double_encode( self->prev_epoch_duration_in_years, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->capitalization, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint128_encode( self->total_points, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_partitioned_rewards_calculation_decode_offsets( fd_partitioned_rewards_calculation_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->vote_reward_map_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong vote_reward_map_len; + err = fd_bincode_uint64_decode( &vote_reward_map_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( ulong i=0; i < vote_reward_map_len; i++ ) { + err = fd_vote_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + self->stake_rewards_by_partition_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_stake_reward_calculation_partitioned_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->old_vote_balance_and_staked_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->validator_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->validator_rate_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_double_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->foundation_rate_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_double_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->prev_epoch_duration_in_years_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_double_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->capitalization_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->total_points_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_partitioned_rewards_calculation_new(fd_partitioned_rewards_calculation_t * self) { + fd_memset( self, 0, sizeof(fd_partitioned_rewards_calculation_t) ); + fd_stake_reward_calculation_partitioned_new( &self->stake_rewards_by_partition ); +} +void fd_partitioned_rewards_calculation_destroy( fd_partitioned_rewards_calculation_t * self, fd_bincode_destroy_ctx_t * ctx ) { + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum(self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor(self->vote_reward_map_pool, n) ) { + fd_vote_reward_destroy( &n->elem, ctx ); + } + fd_valloc_free( ctx->valloc, fd_vote_reward_t_map_delete( fd_vote_reward_t_map_leave( self->vote_reward_map_pool ) ) ); + self->vote_reward_map_pool = NULL; + self->vote_reward_map_root = NULL; + fd_stake_reward_calculation_partitioned_destroy( &self->stake_rewards_by_partition, ctx ); +} + +ulong fd_partitioned_rewards_calculation_footprint( void ){ return FD_PARTITIONED_REWARDS_CALCULATION_FOOTPRINT; } +ulong fd_partitioned_rewards_calculation_align( void ){ return FD_PARTITIONED_REWARDS_CALCULATION_ALIGN; } + +void fd_partitioned_rewards_calculation_walk( void * w, fd_partitioned_rewards_calculation_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_partitioned_rewards_calculation", level++ ); + if( self->vote_reward_map_root ) { + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum(self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor( self->vote_reward_map_pool, n ) ) { + fd_vote_reward_walk(w, &n->elem, fun, "vote_reward_map", level ); + } + } + fd_stake_reward_calculation_partitioned_walk( w, &self->stake_rewards_by_partition, fun, "stake_rewards_by_partition", level ); + fun( w, &self->old_vote_balance_and_staked, "old_vote_balance_and_staked", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->validator_rewards, "validator_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->validator_rate, "validator_rate", FD_FLAMENCO_TYPE_DOUBLE, "double", level ); + fun( w, &self->foundation_rate, "foundation_rate", FD_FLAMENCO_TYPE_DOUBLE, "double", level ); + fun( w, &self->prev_epoch_duration_in_years, "prev_epoch_duration_in_years", FD_FLAMENCO_TYPE_DOUBLE, "double", level ); + fun( w, &self->capitalization, "capitalization", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->total_points, "total_points", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_partitioned_rewards_calculation", level-- ); +} +ulong fd_partitioned_rewards_calculation_size( fd_partitioned_rewards_calculation_t const * self ) { + ulong size = 0; + if( self->vote_reward_map_root ) { + size += sizeof(ulong); + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum( self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor( self->vote_reward_map_pool, n ) ) { + size += fd_vote_reward_size( &n->elem ); + } + } else { + size += sizeof(ulong); + } + size += fd_stake_reward_calculation_partitioned_size( &self->stake_rewards_by_partition ); + size += sizeof(ulong); + size += sizeof(ulong); + size += sizeof(double); + size += sizeof(double); + size += sizeof(double); + size += sizeof(ulong); + size += sizeof(uint128); + return size; +} + +int fd_calculate_rewards_and_distribute_vote_rewards_result_decode( fd_calculate_rewards_and_distribute_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_calculate_rewards_and_distribute_vote_rewards_result_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_calculate_rewards_and_distribute_vote_rewards_result_new( self ); + } + fd_calculate_rewards_and_distribute_vote_rewards_result_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_calculate_rewards_and_distribute_vote_rewards_result_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_stake_reward_calculation_partitioned_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_calculate_rewards_and_distribute_vote_rewards_result_decode_unsafe( fd_calculate_rewards_and_distribute_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->total_rewards, ctx ); + fd_bincode_uint64_decode_unsafe( &self->distributed_rewards, ctx ); + fd_bincode_uint128_decode_unsafe( &self->total_points, ctx ); + fd_stake_reward_calculation_partitioned_decode_unsafe( &self->stake_rewards_by_partition, ctx ); +} +int fd_calculate_rewards_and_distribute_vote_rewards_result_encode( fd_calculate_rewards_and_distribute_vote_rewards_result_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->total_rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->distributed_rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint128_encode( self->total_points, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_stake_reward_calculation_partitioned_encode( &self->stake_rewards_by_partition, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_calculate_rewards_and_distribute_vote_rewards_result_decode_offsets( fd_calculate_rewards_and_distribute_vote_rewards_result_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->total_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->distributed_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->total_points_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->stake_rewards_by_partition_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_stake_reward_calculation_partitioned_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_calculate_rewards_and_distribute_vote_rewards_result_new(fd_calculate_rewards_and_distribute_vote_rewards_result_t * self) { + fd_memset( self, 0, sizeof(fd_calculate_rewards_and_distribute_vote_rewards_result_t) ); + fd_stake_reward_calculation_partitioned_new( &self->stake_rewards_by_partition ); +} +void fd_calculate_rewards_and_distribute_vote_rewards_result_destroy( fd_calculate_rewards_and_distribute_vote_rewards_result_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_stake_reward_calculation_partitioned_destroy( &self->stake_rewards_by_partition, ctx ); +} + +ulong fd_calculate_rewards_and_distribute_vote_rewards_result_footprint( void ){ return FD_CALCULATE_REWARDS_AND_DISTRIBUTE_VOTE_REWARDS_RESULT_FOOTPRINT; } +ulong fd_calculate_rewards_and_distribute_vote_rewards_result_align( void ){ return FD_CALCULATE_REWARDS_AND_DISTRIBUTE_VOTE_REWARDS_RESULT_ALIGN; } + +void fd_calculate_rewards_and_distribute_vote_rewards_result_walk( void * w, fd_calculate_rewards_and_distribute_vote_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_calculate_rewards_and_distribute_vote_rewards_result", level++ ); + fun( w, &self->total_rewards, "total_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->distributed_rewards, "distributed_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->total_points, "total_points", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); + fd_stake_reward_calculation_partitioned_walk( w, &self->stake_rewards_by_partition, fun, "stake_rewards_by_partition", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_calculate_rewards_and_distribute_vote_rewards_result", level-- ); +} +ulong fd_calculate_rewards_and_distribute_vote_rewards_result_size( fd_calculate_rewards_and_distribute_vote_rewards_result_t const * self ) { + ulong size = 0; + size += sizeof(ulong); + size += sizeof(ulong); + size += sizeof(uint128); + size += fd_stake_reward_calculation_partitioned_size( &self->stake_rewards_by_partition ); + return size; +} + +int fd_keyed_rewards_and_num_partitions_decode( fd_keyed_rewards_and_num_partitions_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_keyed_rewards_and_num_partitions_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_keyed_rewards_and_num_partitions_new( self ); + } + fd_keyed_rewards_and_num_partitions_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_keyed_rewards_and_num_partitions_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + ulong keyed_rewards_len; + err = fd_bincode_uint64_decode( &keyed_rewards_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( keyed_rewards_len ) { + for( ulong i=0; i < keyed_rewards_len; i++ ) { + err = fd_pubkey_rewardinfo_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_keyed_rewards_and_num_partitions_decode_unsafe( fd_keyed_rewards_and_num_partitions_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->keyed_rewards_len, ctx ); + if( self->keyed_rewards_len ) { + self->keyed_rewards = (fd_pubkey_rewardinfo_pair_t *)fd_valloc_malloc( ctx->valloc, FD_PUBKEY_REWARDINFO_PAIR_ALIGN, FD_PUBKEY_REWARDINFO_PAIR_FOOTPRINT*self->keyed_rewards_len ); + for( ulong i=0; i < self->keyed_rewards_len; i++ ) { + fd_pubkey_rewardinfo_pair_new( self->keyed_rewards + i ); + fd_pubkey_rewardinfo_pair_decode_unsafe( self->keyed_rewards + i, ctx ); + } + } else + self->keyed_rewards = NULL; + { + uchar o; + fd_bincode_bool_decode_unsafe( &o, ctx ); + if( o ) { + self->num_partitions = fd_valloc_malloc( ctx->valloc, 8, sizeof(ulong) ); + fd_bincode_uint64_decode_unsafe( self->num_partitions, ctx ); + } else + self->num_partitions = NULL; + } +} +int fd_keyed_rewards_and_num_partitions_encode( fd_keyed_rewards_and_num_partitions_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->keyed_rewards_len, ctx ); + if( FD_UNLIKELY(err) ) return err; + if( self->keyed_rewards_len ) { + for( ulong i=0; i < self->keyed_rewards_len; i++ ) { + err = fd_pubkey_rewardinfo_pair_encode( self->keyed_rewards + i, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + if( self->num_partitions != NULL ) { + err = fd_bincode_bool_encode( 1, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->num_partitions[0], ctx ); + if( FD_UNLIKELY( err ) ) return err; + } else { + err = fd_bincode_bool_encode( 0, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + return FD_BINCODE_SUCCESS; +} +int fd_keyed_rewards_and_num_partitions_decode_offsets( fd_keyed_rewards_and_num_partitions_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->keyed_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong keyed_rewards_len; + err = fd_bincode_uint64_decode( &keyed_rewards_len, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( keyed_rewards_len ) { + for( ulong i=0; i < keyed_rewards_len; i++ ) { + err = fd_pubkey_rewardinfo_pair_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + self->num_partitions_off = (uint)( (ulong)ctx->data - (ulong)data ); + { + uchar o; + err = fd_bincode_bool_decode( &o, ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + if( o ) { + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} +void fd_keyed_rewards_and_num_partitions_new(fd_keyed_rewards_and_num_partitions_t * self) { + fd_memset( self, 0, sizeof(fd_keyed_rewards_and_num_partitions_t) ); +} +void fd_keyed_rewards_and_num_partitions_destroy( fd_keyed_rewards_and_num_partitions_t * self, fd_bincode_destroy_ctx_t * ctx ) { + if( self->keyed_rewards ) { + for( ulong i=0; i < self->keyed_rewards_len; i++ ) + fd_pubkey_rewardinfo_pair_destroy( self->keyed_rewards + i, ctx ); + fd_valloc_free( ctx->valloc, self->keyed_rewards ); + self->keyed_rewards = NULL; + } + if( self->num_partitions ) { + fd_valloc_free( ctx->valloc, self->num_partitions ); + self->num_partitions = NULL; + } +} + +ulong fd_keyed_rewards_and_num_partitions_footprint( void ){ return FD_KEYED_REWARDS_AND_NUM_PARTITIONS_FOOTPRINT; } +ulong fd_keyed_rewards_and_num_partitions_align( void ){ return FD_KEYED_REWARDS_AND_NUM_PARTITIONS_ALIGN; } + +void fd_keyed_rewards_and_num_partitions_walk( void * w, fd_keyed_rewards_and_num_partitions_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_keyed_rewards_and_num_partitions", level++ ); + if( self->keyed_rewards_len ) { + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "keyed_rewards", level++ ); + for( ulong i=0; i < self->keyed_rewards_len; i++ ) + fd_pubkey_rewardinfo_pair_walk(w, self->keyed_rewards + i, fun, "pubkey_rewardinfo_pair", level ); + fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "keyed_rewards", level-- ); + } + if( !self->num_partitions ) { + fun( w, NULL, "num_partitions", FD_FLAMENCO_TYPE_NULL, "ulong", level ); + } else { + fun( w, self->num_partitions, "num_partitions", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_keyed_rewards_and_num_partitions", level-- ); +} +ulong fd_keyed_rewards_and_num_partitions_size( fd_keyed_rewards_and_num_partitions_t const * self ) { + ulong size = 0; + do { + size += sizeof(ulong); + for( ulong i=0; i < self->keyed_rewards_len; i++ ) + size += fd_pubkey_rewardinfo_pair_size( self->keyed_rewards + i ); + } while(0); + size += sizeof(char); + if( NULL != self->num_partitions ) { + size += sizeof(ulong); + } + return size; +} + +int fd_calculated_stake_points_decode( fd_calculated_stake_points_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_calculated_stake_points_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_calculated_stake_points_new( self ); + } + fd_calculated_stake_points_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_calculated_stake_points_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint8_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_calculated_stake_points_decode_unsafe( fd_calculated_stake_points_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint128_decode_unsafe( &self->points, ctx ); + fd_bincode_uint64_decode_unsafe( &self->new_credits_observed, ctx ); + fd_bincode_uint8_decode_unsafe( &self->force_credits_update_with_skipped_reward, ctx ); +} +int fd_calculated_stake_points_encode( fd_calculated_stake_points_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint128_encode( self->points, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->new_credits_observed, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint8_encode( (uchar)(self->force_credits_update_with_skipped_reward), ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_calculated_stake_points_decode_offsets( fd_calculated_stake_points_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->points_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->new_credits_observed_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->force_credits_update_with_skipped_reward_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint8_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_calculated_stake_points_new(fd_calculated_stake_points_t * self) { + fd_memset( self, 0, sizeof(fd_calculated_stake_points_t) ); +} +void fd_calculated_stake_points_destroy( fd_calculated_stake_points_t * self, fd_bincode_destroy_ctx_t * ctx ) { +} + +ulong fd_calculated_stake_points_footprint( void ){ return FD_CALCULATED_STAKE_POINTS_FOOTPRINT; } +ulong fd_calculated_stake_points_align( void ){ return FD_CALCULATED_STAKE_POINTS_ALIGN; } + +void fd_calculated_stake_points_walk( void * w, fd_calculated_stake_points_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_calculated_stake_points", level++ ); + fun( w, &self->points, "points", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); + fun( w, &self->new_credits_observed, "new_credits_observed", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->force_credits_update_with_skipped_reward, "force_credits_update_with_skipped_reward", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_calculated_stake_points", level-- ); +} +ulong fd_calculated_stake_points_size( fd_calculated_stake_points_t const * self ) { + ulong size = 0; + size += sizeof(uint128); + size += sizeof(ulong); + size += sizeof(char); + return size; +} + +int fd_point_value_decode( fd_point_value_t * self, fd_bincode_decode_ctx_t * ctx ) { + void const * data = ctx->data; + int err = fd_point_value_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + ctx->data = data; + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + fd_point_value_new( self ); + } + fd_point_value_decode_unsafe( self, ctx ); + return FD_BINCODE_SUCCESS; +} +int fd_point_value_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_point_value_decode_unsafe( fd_point_value_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->rewards, ctx ); + fd_bincode_uint128_decode_unsafe( &self->points, ctx ); +} +int fd_point_value_encode( fd_point_value_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint128_encode( self->points, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +int fd_point_value_decode_offsets( fd_point_value_off_t * self, fd_bincode_decode_ctx_t * ctx ) { + uchar const * data = ctx->data; + int err; + self->rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->points_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} +void fd_point_value_new(fd_point_value_t * self) { + fd_memset( self, 0, sizeof(fd_point_value_t) ); +} +void fd_point_value_destroy( fd_point_value_t * self, fd_bincode_destroy_ctx_t * ctx ) { +} + +ulong fd_point_value_footprint( void ){ return FD_POINT_VALUE_FOOTPRINT; } +ulong fd_point_value_align( void ){ return FD_POINT_VALUE_ALIGN; } + +void fd_point_value_walk( void * w, fd_point_value_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_point_value", level++ ); + fun( w, &self->rewards, "rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->points, "points", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_point_value", level-- ); +} +ulong fd_point_value_size( fd_point_value_t const * self ) { ulong size = 0; size += sizeof(ulong); - do { - size += sizeof(ulong); - for( ulong i=0; i < self->statuses_len; i++ ) - size += fd_cache_status_size( self->statuses + i ); - } while(0); + size += sizeof(uint128); return size; } -int fd_status_pair_decode( fd_status_pair_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_calculate_stake_vote_rewards_result_decode( fd_calculate_stake_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_status_pair_decode_preflight( ctx ); + int err = fd_calculate_stake_vote_rewards_result_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_status_pair_new( self ); + fd_calculate_stake_vote_rewards_result_new( self ); } - fd_status_pair_decode_unsafe( self, ctx ); + fd_calculate_stake_vote_rewards_result_decode_unsafe( self, ctx ); return FD_BINCODE_SUCCESS; } -int fd_status_pair_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { +int fd_calculate_stake_vote_rewards_result_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { int err; - err = fd_hash_decode_preflight( ctx ); + err = fd_stake_reward_calculation_decode_preflight( ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_status_value_decode_preflight( ctx ); + ulong vote_reward_map_len; + err = fd_bincode_uint64_decode( &vote_reward_map_len, ctx ); if( FD_UNLIKELY( err ) ) return err; + for( ulong i=0; i < vote_reward_map_len; i++ ) { + err = fd_vote_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + } return FD_BINCODE_SUCCESS; } -void fd_status_pair_decode_unsafe( fd_status_pair_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_hash_decode_unsafe( &self->hash, ctx ); - fd_status_value_decode_unsafe( &self->value, ctx ); +void fd_calculate_stake_vote_rewards_result_decode_unsafe( fd_calculate_stake_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_stake_reward_calculation_decode_unsafe( &self->stake_reward_calculation, ctx ); + ulong vote_reward_map_len; + fd_bincode_uint64_decode_unsafe( &vote_reward_map_len, ctx ); + if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { + self->vote_reward_map_pool = fd_vote_reward_t_map_alloc( ctx->valloc, fd_ulong_max(vote_reward_map_len, 24 ) ); + self->vote_reward_map_root = NULL; + } + for( ulong i=0; i < vote_reward_map_len; i++ ) { + fd_vote_reward_t_mapnode_t * node = fd_vote_reward_t_map_acquire( self->vote_reward_map_pool ); + fd_vote_reward_new( &node->elem ); + fd_vote_reward_decode_unsafe( &node->elem, ctx ); + fd_vote_reward_t_map_insert( self->vote_reward_map_pool, &self->vote_reward_map_root, node ); + } } -int fd_status_pair_encode( fd_status_pair_t const * self, fd_bincode_encode_ctx_t * ctx ) { +int fd_calculate_stake_vote_rewards_result_encode( fd_calculate_stake_vote_rewards_result_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_hash_encode( &self->hash, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_status_value_encode( &self->value, ctx ); + err = fd_stake_reward_calculation_encode( &self->stake_reward_calculation, ctx ); if( FD_UNLIKELY( err ) ) return err; + if( self->vote_reward_map_root ) { + ulong vote_reward_map_len = fd_vote_reward_t_map_size( self->vote_reward_map_pool, self->vote_reward_map_root ); + err = fd_bincode_uint64_encode( vote_reward_map_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum( self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor( self->vote_reward_map_pool, n ) ) { + err = fd_vote_reward_encode( &n->elem, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } else { + ulong vote_reward_map_len = 0; + err = fd_bincode_uint64_encode( vote_reward_map_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } return FD_BINCODE_SUCCESS; } -int fd_status_pair_decode_offsets( fd_status_pair_off_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_calculate_stake_vote_rewards_result_decode_offsets( fd_calculate_stake_vote_rewards_result_off_t * self, fd_bincode_decode_ctx_t * ctx ) { uchar const * data = ctx->data; int err; - self->hash_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_hash_decode_preflight( ctx ); + self->stake_reward_calculation_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_stake_reward_calculation_decode_preflight( ctx ); if( FD_UNLIKELY( err ) ) return err; - self->value_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_status_value_decode_preflight( ctx ); + self->vote_reward_map_off = (uint)( (ulong)ctx->data - (ulong)data ); + ulong vote_reward_map_len; + err = fd_bincode_uint64_decode( &vote_reward_map_len, ctx ); if( FD_UNLIKELY( err ) ) return err; + for( ulong i=0; i < vote_reward_map_len; i++ ) { + err = fd_vote_reward_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + } return FD_BINCODE_SUCCESS; } -void fd_status_pair_new(fd_status_pair_t * self) { - fd_memset( self, 0, sizeof(fd_status_pair_t) ); - fd_hash_new( &self->hash ); - fd_status_value_new( &self->value ); +void fd_calculate_stake_vote_rewards_result_new(fd_calculate_stake_vote_rewards_result_t * self) { + fd_memset( self, 0, sizeof(fd_calculate_stake_vote_rewards_result_t) ); + fd_stake_reward_calculation_new( &self->stake_reward_calculation ); } -void fd_status_pair_destroy( fd_status_pair_t * self, fd_bincode_destroy_ctx_t * ctx ) { - fd_hash_destroy( &self->hash, ctx ); - fd_status_value_destroy( &self->value, ctx ); +void fd_calculate_stake_vote_rewards_result_destroy( fd_calculate_stake_vote_rewards_result_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_stake_reward_calculation_destroy( &self->stake_reward_calculation, ctx ); + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum(self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor(self->vote_reward_map_pool, n) ) { + fd_vote_reward_destroy( &n->elem, ctx ); + } + fd_valloc_free( ctx->valloc, fd_vote_reward_t_map_delete( fd_vote_reward_t_map_leave( self->vote_reward_map_pool ) ) ); + self->vote_reward_map_pool = NULL; + self->vote_reward_map_root = NULL; } -ulong fd_status_pair_footprint( void ){ return FD_STATUS_PAIR_FOOTPRINT; } -ulong fd_status_pair_align( void ){ return FD_STATUS_PAIR_ALIGN; } +ulong fd_calculate_stake_vote_rewards_result_footprint( void ){ return FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_FOOTPRINT; } +ulong fd_calculate_stake_vote_rewards_result_align( void ){ return FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_ALIGN; } -void fd_status_pair_walk( void * w, fd_status_pair_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_status_pair", level++ ); - fd_hash_walk( w, &self->hash, fun, "hash", level ); - fd_status_value_walk( w, &self->value, fun, "value", level ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_status_pair", level-- ); +void fd_calculate_stake_vote_rewards_result_walk( void * w, fd_calculate_stake_vote_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_calculate_stake_vote_rewards_result", level++ ); + fd_stake_reward_calculation_walk( w, &self->stake_reward_calculation, fun, "stake_reward_calculation", level ); + if( self->vote_reward_map_root ) { + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum(self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor( self->vote_reward_map_pool, n ) ) { + fd_vote_reward_walk(w, &n->elem, fun, "vote_reward_map", level ); + } + } + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_calculate_stake_vote_rewards_result", level-- ); } -ulong fd_status_pair_size( fd_status_pair_t const * self ) { +ulong fd_calculate_stake_vote_rewards_result_size( fd_calculate_stake_vote_rewards_result_t const * self ) { ulong size = 0; - size += fd_hash_size( &self->hash ); - size += fd_status_value_size( &self->value ); + size += fd_stake_reward_calculation_size( &self->stake_reward_calculation ); + if( self->vote_reward_map_root ) { + size += sizeof(ulong); + for( fd_vote_reward_t_mapnode_t * n = fd_vote_reward_t_map_minimum( self->vote_reward_map_pool, self->vote_reward_map_root ); n; n = fd_vote_reward_t_map_successor( self->vote_reward_map_pool, n ) ) { + size += fd_vote_reward_size( &n->elem ); + } + } else { + size += sizeof(ulong); + } return size; } -int fd_slot_delta_decode( fd_slot_delta_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_calculated_stake_rewards_decode( fd_calculated_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_slot_delta_decode_preflight( ctx ); + int err = fd_calculated_stake_rewards_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_slot_delta_new( self ); + fd_calculated_stake_rewards_new( self ); } - fd_slot_delta_decode_unsafe( self, ctx ); + fd_calculated_stake_rewards_decode_unsafe( self, ctx ); return FD_BINCODE_SUCCESS; } -int fd_slot_delta_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { +int fd_calculated_stake_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { int err; err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_bool_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - ulong slot_delta_vec_len; - err = fd_bincode_uint64_decode( &slot_delta_vec_len, ctx ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( slot_delta_vec_len ) { - for( ulong i=0; i < slot_delta_vec_len; i++ ) { - err = fd_status_pair_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } return FD_BINCODE_SUCCESS; } -void fd_slot_delta_decode_unsafe( fd_slot_delta_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_bincode_uint64_decode_unsafe( &self->slot, ctx ); - fd_bincode_bool_decode_unsafe( &self->is_root, ctx ); - fd_bincode_uint64_decode_unsafe( &self->slot_delta_vec_len, ctx ); - if( self->slot_delta_vec_len ) { - self->slot_delta_vec = (fd_status_pair_t *)fd_valloc_malloc( ctx->valloc, FD_STATUS_PAIR_ALIGN, FD_STATUS_PAIR_FOOTPRINT*self->slot_delta_vec_len ); - for( ulong i=0; i < self->slot_delta_vec_len; i++ ) { - fd_status_pair_new( self->slot_delta_vec + i ); - fd_status_pair_decode_unsafe( self->slot_delta_vec + i, ctx ); - } - } else - self->slot_delta_vec = NULL; +void fd_calculated_stake_rewards_decode_unsafe( fd_calculated_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_bincode_uint64_decode_unsafe( &self->staker_rewards, ctx ); + fd_bincode_uint64_decode_unsafe( &self->voter_rewards, ctx ); + fd_bincode_uint64_decode_unsafe( &self->new_credits_observed, ctx ); } -int fd_slot_delta_encode( fd_slot_delta_t const * self, fd_bincode_encode_ctx_t * ctx ) { +int fd_calculated_stake_rewards_encode( fd_calculated_stake_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_bincode_uint64_encode( self->slot, ctx ); + err = fd_bincode_uint64_encode( self->staker_rewards, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_bool_encode( (uchar)(self->is_root), ctx ); + err = fd_bincode_uint64_encode( self->voter_rewards, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->new_credits_observed, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->slot_delta_vec_len, ctx ); - if( FD_UNLIKELY(err) ) return err; - if( self->slot_delta_vec_len ) { - for( ulong i=0; i < self->slot_delta_vec_len; i++ ) { - err = fd_status_pair_encode( self->slot_delta_vec + i, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - } return FD_BINCODE_SUCCESS; } -int fd_slot_delta_decode_offsets( fd_slot_delta_off_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_calculated_stake_rewards_decode_offsets( fd_calculated_stake_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ) { uchar const * data = ctx->data; int err; - self->slot_off = (uint)( (ulong)ctx->data - (ulong)data ); + self->staker_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - self->is_root_off = (uint)( (ulong)ctx->data - (ulong)data ); - err = fd_bincode_bool_decode_preflight( ctx ); - if( FD_UNLIKELY( err ) ) return err; - self->slot_delta_vec_off = (uint)( (ulong)ctx->data - (ulong)data ); - ulong slot_delta_vec_len; - err = fd_bincode_uint64_decode( &slot_delta_vec_len, ctx ); + self->voter_rewards_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); + if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; + self->new_credits_observed_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint64_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( slot_delta_vec_len ) { - for( ulong i=0; i < slot_delta_vec_len; i++ ) { - err = fd_status_pair_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } return FD_BINCODE_SUCCESS; } -void fd_slot_delta_new(fd_slot_delta_t * self) { - fd_memset( self, 0, sizeof(fd_slot_delta_t) ); +void fd_calculated_stake_rewards_new(fd_calculated_stake_rewards_t * self) { + fd_memset( self, 0, sizeof(fd_calculated_stake_rewards_t) ); } -void fd_slot_delta_destroy( fd_slot_delta_t * self, fd_bincode_destroy_ctx_t * ctx ) { - if( self->slot_delta_vec ) { - for( ulong i=0; i < self->slot_delta_vec_len; i++ ) - fd_status_pair_destroy( self->slot_delta_vec + i, ctx ); - fd_valloc_free( ctx->valloc, self->slot_delta_vec ); - self->slot_delta_vec = NULL; - } +void fd_calculated_stake_rewards_destroy( fd_calculated_stake_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ) { } -ulong fd_slot_delta_footprint( void ){ return FD_SLOT_DELTA_FOOTPRINT; } -ulong fd_slot_delta_align( void ){ return FD_SLOT_DELTA_ALIGN; } +ulong fd_calculated_stake_rewards_footprint( void ){ return FD_CALCULATED_STAKE_REWARDS_FOOTPRINT; } +ulong fd_calculated_stake_rewards_align( void ){ return FD_CALCULATED_STAKE_REWARDS_ALIGN; } -void fd_slot_delta_walk( void * w, fd_slot_delta_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_slot_delta", level++ ); - fun( w, &self->slot, "slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->is_root, "is_root", FD_FLAMENCO_TYPE_BOOL, "bool", level ); - if( self->slot_delta_vec_len ) { - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "slot_delta_vec", level++ ); - for( ulong i=0; i < self->slot_delta_vec_len; i++ ) - fd_status_pair_walk(w, self->slot_delta_vec + i, fun, "status_pair", level ); - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "slot_delta_vec", level-- ); - } - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_slot_delta", level-- ); +void fd_calculated_stake_rewards_walk( void * w, fd_calculated_stake_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_calculated_stake_rewards", level++ ); + fun( w, &self->staker_rewards, "staker_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->voter_rewards, "voter_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, &self->new_credits_observed, "new_credits_observed", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_calculated_stake_rewards", level-- ); } -ulong fd_slot_delta_size( fd_slot_delta_t const * self ) { +ulong fd_calculated_stake_rewards_size( fd_calculated_stake_rewards_t const * self ) { ulong size = 0; size += sizeof(ulong); - size += sizeof(char); - do { - size += sizeof(ulong); - for( ulong i=0; i < self->slot_delta_vec_len; i++ ) - size += fd_status_pair_size( self->slot_delta_vec + i ); - } while(0); + size += sizeof(ulong); + size += sizeof(ulong); return size; } -int fd_bank_slot_deltas_decode( fd_bank_slot_deltas_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_calculate_validator_rewards_result_decode( fd_calculate_validator_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ) { void const * data = ctx->data; - int err = fd_bank_slot_deltas_decode_preflight( ctx ); + int err = fd_calculate_validator_rewards_result_decode_preflight( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; ctx->data = data; if( !fd_is_null_alloc_virtual( ctx->valloc ) ) { - fd_bank_slot_deltas_new( self ); + fd_calculate_validator_rewards_result_new( self ); } - fd_bank_slot_deltas_decode_unsafe( self, ctx ); + fd_calculate_validator_rewards_result_decode_unsafe( self, ctx ); return FD_BINCODE_SUCCESS; } -int fd_bank_slot_deltas_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { +int fd_calculate_validator_rewards_result_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { int err; - ulong slot_deltas_len; - err = fd_bincode_uint64_decode( &slot_deltas_len, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( slot_deltas_len ) { - for( ulong i=0; i < slot_deltas_len; i++ ) { - err = fd_slot_delta_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } + err = fd_calculate_stake_vote_rewards_result_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } -void fd_bank_slot_deltas_decode_unsafe( fd_bank_slot_deltas_t * self, fd_bincode_decode_ctx_t * ctx ) { - fd_bincode_uint64_decode_unsafe( &self->slot_deltas_len, ctx ); - if( self->slot_deltas_len ) { - self->slot_deltas = (fd_slot_delta_t *)fd_valloc_malloc( ctx->valloc, FD_SLOT_DELTA_ALIGN, FD_SLOT_DELTA_FOOTPRINT*self->slot_deltas_len ); - for( ulong i=0; i < self->slot_deltas_len; i++ ) { - fd_slot_delta_new( self->slot_deltas + i ); - fd_slot_delta_decode_unsafe( self->slot_deltas + i, ctx ); - } - } else - self->slot_deltas = NULL; +void fd_calculate_validator_rewards_result_decode_unsafe( fd_calculate_validator_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ) { + fd_calculate_stake_vote_rewards_result_decode_unsafe( &self->calculate_stake_vote_rewards_result, ctx ); + fd_bincode_uint128_decode_unsafe( &self->total_points, ctx ); } -int fd_bank_slot_deltas_encode( fd_bank_slot_deltas_t const * self, fd_bincode_encode_ctx_t * ctx ) { +int fd_calculate_validator_rewards_result_encode( fd_calculate_validator_rewards_result_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_bincode_uint64_encode( self->slot_deltas_len, ctx ); - if( FD_UNLIKELY(err) ) return err; - if( self->slot_deltas_len ) { - for( ulong i=0; i < self->slot_deltas_len; i++ ) { - err = fd_slot_delta_encode( self->slot_deltas + i, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - } + err = fd_calculate_stake_vote_rewards_result_encode( &self->calculate_stake_vote_rewards_result, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint128_encode( self->total_points, ctx ); + if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } -int fd_bank_slot_deltas_decode_offsets( fd_bank_slot_deltas_off_t * self, fd_bincode_decode_ctx_t * ctx ) { +int fd_calculate_validator_rewards_result_decode_offsets( fd_calculate_validator_rewards_result_off_t * self, fd_bincode_decode_ctx_t * ctx ) { uchar const * data = ctx->data; int err; - self->slot_deltas_off = (uint)( (ulong)ctx->data - (ulong)data ); - ulong slot_deltas_len; - err = fd_bincode_uint64_decode( &slot_deltas_len, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( slot_deltas_len ) { - for( ulong i=0; i < slot_deltas_len; i++ ) { - err = fd_slot_delta_decode_preflight( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } + self->calculate_stake_vote_rewards_result_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_calculate_stake_vote_rewards_result_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; + self->total_points_off = (uint)( (ulong)ctx->data - (ulong)data ); + err = fd_bincode_uint128_decode_preflight( ctx ); + if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } -void fd_bank_slot_deltas_new(fd_bank_slot_deltas_t * self) { - fd_memset( self, 0, sizeof(fd_bank_slot_deltas_t) ); +void fd_calculate_validator_rewards_result_new(fd_calculate_validator_rewards_result_t * self) { + fd_memset( self, 0, sizeof(fd_calculate_validator_rewards_result_t) ); + fd_calculate_stake_vote_rewards_result_new( &self->calculate_stake_vote_rewards_result ); } -void fd_bank_slot_deltas_destroy( fd_bank_slot_deltas_t * self, fd_bincode_destroy_ctx_t * ctx ) { - if( self->slot_deltas ) { - for( ulong i=0; i < self->slot_deltas_len; i++ ) - fd_slot_delta_destroy( self->slot_deltas + i, ctx ); - fd_valloc_free( ctx->valloc, self->slot_deltas ); - self->slot_deltas = NULL; - } +void fd_calculate_validator_rewards_result_destroy( fd_calculate_validator_rewards_result_t * self, fd_bincode_destroy_ctx_t * ctx ) { + fd_calculate_stake_vote_rewards_result_destroy( &self->calculate_stake_vote_rewards_result, ctx ); } -ulong fd_bank_slot_deltas_footprint( void ){ return FD_BANK_SLOT_DELTAS_FOOTPRINT; } -ulong fd_bank_slot_deltas_align( void ){ return FD_BANK_SLOT_DELTAS_ALIGN; } +ulong fd_calculate_validator_rewards_result_footprint( void ){ return FD_CALCULATE_VALIDATOR_REWARDS_RESULT_FOOTPRINT; } +ulong fd_calculate_validator_rewards_result_align( void ){ return FD_CALCULATE_VALIDATOR_REWARDS_RESULT_ALIGN; } -void fd_bank_slot_deltas_walk( void * w, fd_bank_slot_deltas_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_bank_slot_deltas", level++ ); - if( self->slot_deltas_len ) { - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR, "slot_deltas", level++ ); - for( ulong i=0; i < self->slot_deltas_len; i++ ) - fd_slot_delta_walk(w, self->slot_deltas + i, fun, "slot_delta", level ); - fun( w, NULL, NULL, FD_FLAMENCO_TYPE_ARR_END, "slot_deltas", level-- ); - } - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_bank_slot_deltas", level-- ); +void fd_calculate_validator_rewards_result_walk( void * w, fd_calculate_validator_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_calculate_validator_rewards_result", level++ ); + fd_calculate_stake_vote_rewards_result_walk( w, &self->calculate_stake_vote_rewards_result, fun, "calculate_stake_vote_rewards_result", level ); + fun( w, &self->total_points, "total_points", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_calculate_validator_rewards_result", level-- ); } -ulong fd_bank_slot_deltas_size( fd_bank_slot_deltas_t const * self ) { +ulong fd_calculate_validator_rewards_result_size( fd_calculate_validator_rewards_result_t const * self ) { ulong size = 0; - do { - size += sizeof(ulong); - for( ulong i=0; i < self->slot_deltas_len; i++ ) - size += fd_slot_delta_size( self->slot_deltas + i ); - } while(0); + size += fd_calculate_stake_vote_rewards_result_size( &self->calculate_stake_vote_rewards_result ); + size += sizeof(uint128); return size; } @@ -29587,3 +31072,12 @@ long fd_delegation_pair_t_map_compare( fd_delegation_pair_t_mapnode_t * left, fd long fd_clock_timestamp_vote_t_map_compare( fd_clock_timestamp_vote_t_mapnode_t * left, fd_clock_timestamp_vote_t_mapnode_t * right ) { return memcmp( left->elem.pubkey.uc, right->elem.pubkey.uc, sizeof(right->elem.pubkey) ); } +#define REDBLK_T fd_vote_reward_t_mapnode_t +#define REDBLK_NAME fd_vote_reward_t_map +#define REDBLK_IMPL_STYLE 2 +#include "../../util/tmpl/fd_redblack.c" +#undef REDBLK_T +#undef REDBLK_NAME +long fd_vote_reward_t_map_compare( fd_vote_reward_t_mapnode_t * left, fd_vote_reward_t_mapnode_t * right ) { + return memcmp( left->elem.pubkey.uc, right->elem.pubkey.uc, sizeof(right->elem.pubkey) ); +} diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index 167feb4d01..9f64218299 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -39,34 +39,6 @@ typedef struct fd_fee_calculator_off fd_fee_calculator_off_t; #define FD_FEE_CALCULATOR_OFF_FOOTPRINT sizeof(fd_fee_calculator_off_t) #define FD_FEE_CALCULATOR_OFF_ALIGN (8UL) -/* https://github.com/anza-xyz/agave/blob/7fcd8c03fd71418fe49459c8460ab3986a8b608a/sdk/program/src/epoch_rewards.rs#L12 */ -/* Encoded Size: Dynamic */ -struct __attribute__((aligned(8UL))) fd_epoch_rewards { - ulong distribution_starting_block_height; - ulong num_partitions; - fd_hash_t parent_blockhash; - uint128 total_points; - ulong total_rewards; - ulong distributed_rewards; - uchar active; -}; -typedef struct fd_epoch_rewards fd_epoch_rewards_t; -#define FD_EPOCH_REWARDS_FOOTPRINT sizeof(fd_epoch_rewards_t) -#define FD_EPOCH_REWARDS_ALIGN (8UL) - -struct __attribute__((aligned(8UL))) fd_epoch_rewards_off { - uint distribution_starting_block_height_off; - uint num_partitions_off; - uint parent_blockhash_off; - uint total_points_off; - uint total_rewards_off; - uint distributed_rewards_off; - uint active_off; -}; -typedef struct fd_epoch_rewards_off fd_epoch_rewards_off_t; -#define FD_EPOCH_REWARDS_OFF_FOOTPRINT sizeof(fd_epoch_rewards_off_t) -#define FD_EPOCH_REWARDS_OFF_ALIGN (8UL) - /* Encoded Size: Dynamic */ struct __attribute__((aligned(8UL))) fd_hash_age { fd_fee_calculator_t fee_calculator; @@ -1079,7 +1051,7 @@ union fd_reward_type_inner { }; typedef union fd_reward_type_inner fd_reward_type_inner_t; -/* https://github.com/firedancer-io/solana/blob/de02601d73d626edf98ef63efd772824746f2f33/sdk/src/reward_type.rs#L5-L11 */ +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/reward_type.rs#L7 */ struct fd_reward_type { uint discriminant; fd_reward_type_inner_t inner; @@ -1088,14 +1060,42 @@ typedef struct fd_reward_type fd_reward_type_t; #define FD_REWARD_TYPE_FOOTPRINT sizeof(fd_reward_type_t) #define FD_REWARD_TYPE_ALIGN (8UL) +/* Accounts DB related fields in a snapshot */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_solana_accounts_db_fields { + ulong storages_len; + fd_snapshot_slot_acc_vecs_t * storages; + ulong version; + ulong slot; + fd_bank_hash_info_t bank_hash_info; + ulong historical_roots_len; + ulong* historical_roots; + ulong historical_roots_with_hash_len; + fd_slot_map_pair_t * historical_roots_with_hash; +}; +typedef struct fd_solana_accounts_db_fields fd_solana_accounts_db_fields_t; +#define FD_SOLANA_ACCOUNTS_DB_FIELDS_FOOTPRINT sizeof(fd_solana_accounts_db_fields_t) +#define FD_SOLANA_ACCOUNTS_DB_FIELDS_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_solana_accounts_db_fields_off { + uint storages_off; + uint version_off; + uint slot_off; + uint bank_hash_info_off; + uint historical_roots_off; + uint historical_roots_with_hash_off; +}; +typedef struct fd_solana_accounts_db_fields_off fd_solana_accounts_db_fields_off_t; +#define FD_SOLANA_ACCOUNTS_DB_FIELDS_OFF_FOOTPRINT sizeof(fd_solana_accounts_db_fields_off_t) +#define FD_SOLANA_ACCOUNTS_DB_FIELDS_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/reward_info.rs#L5 */ /* Encoded Size: Dynamic */ struct __attribute__((aligned(8UL))) fd_reward_info { fd_reward_type_t reward_type; ulong lamports; - ulong staker_rewards; - ulong new_credits_observed; ulong post_balance; - long commission; + ulong* commission; }; typedef struct fd_reward_info fd_reward_info_t; #define FD_REWARD_INFO_FOOTPRINT sizeof(fd_reward_info_t) @@ -1104,8 +1104,6 @@ typedef struct fd_reward_info fd_reward_info_t; struct __attribute__((aligned(8UL))) fd_reward_info_off { uint reward_type_off; uint lamports_off; - uint staker_rewards_off; - uint new_credits_observed_off; uint post_balance_off; uint commission_off; }; @@ -1130,81 +1128,114 @@ typedef struct fd_stake_reward_off fd_stake_reward_off_t; #define FD_STAKE_REWARD_OFF_FOOTPRINT sizeof(fd_stake_reward_off_t) #define FD_STAKE_REWARD_OFF_ALIGN (8UL) +/* Encoded Size: Fixed (42 bytes) */ +struct __attribute__((aligned(8UL))) fd_vote_reward { + fd_pubkey_t pubkey; + ulong vote_rewards; + uchar commission; + uchar needs_store; +}; +typedef struct fd_vote_reward fd_vote_reward_t; +#define FD_VOTE_REWARD_FOOTPRINT sizeof(fd_vote_reward_t) +#define FD_VOTE_REWARD_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_vote_reward_off { + uint pubkey_off; + uint vote_rewards_off; + uint commission_off; + uint needs_store_off; +}; +typedef struct fd_vote_reward_off fd_vote_reward_off_t; +#define FD_VOTE_REWARD_OFF_FOOTPRINT sizeof(fd_vote_reward_off_t) +#define FD_VOTE_REWARD_OFF_ALIGN (8UL) + +/* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/stake/state.rs#L539 */ /* Encoded Size: Dynamic */ -struct __attribute__((aligned(8UL))) fd_serializable_stake_rewards { - ulong body_len; - fd_stake_reward_t * body; +struct __attribute__((aligned(8UL))) fd_stake { + fd_delegation_t delegation; + ulong credits_observed; }; -typedef struct fd_serializable_stake_rewards fd_serializable_stake_rewards_t; -#define FD_SERIALIZABLE_STAKE_REWARDS_FOOTPRINT sizeof(fd_serializable_stake_rewards_t) -#define FD_SERIALIZABLE_STAKE_REWARDS_ALIGN (8UL) +typedef struct fd_stake fd_stake_t; +#define FD_STAKE_FOOTPRINT sizeof(fd_stake_t) +#define FD_STAKE_ALIGN (8UL) -struct __attribute__((aligned(8UL))) fd_serializable_stake_rewards_off { - uint body_off; +struct __attribute__((aligned(8UL))) fd_stake_off { + uint delegation_off; + uint credits_observed_off; }; -typedef struct fd_serializable_stake_rewards_off fd_serializable_stake_rewards_off_t; -#define FD_SERIALIZABLE_STAKE_REWARDS_OFF_FOOTPRINT sizeof(fd_serializable_stake_rewards_off_t) -#define FD_SERIALIZABLE_STAKE_REWARDS_OFF_ALIGN (8UL) +typedef struct fd_stake_off fd_stake_off_t; +#define FD_STAKE_OFF_FOOTPRINT sizeof(fd_stake_off_t) +#define FD_STAKE_OFF_ALIGN (8UL) +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L31 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_partitioned_stake_reward { + fd_pubkey_t stake_pubkey; + fd_stake_t stake; + fd_reward_info_t stake_reward_info; +}; +typedef struct fd_partitioned_stake_reward fd_partitioned_stake_reward_t; +#define FD_PARTITIONED_STAKE_REWARD_FOOTPRINT sizeof(fd_partitioned_stake_reward_t) +#define FD_PARTITIONED_STAKE_REWARD_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_partitioned_stake_reward_off { + uint stake_pubkey_off; + uint stake_off; + uint stake_reward_info_off; +}; +typedef struct fd_partitioned_stake_reward_off fd_partitioned_stake_reward_off_t; +#define FD_PARTITIONED_STAKE_REWARD_OFF_FOOTPRINT sizeof(fd_partitioned_stake_reward_off_t) +#define FD_PARTITIONED_STAKE_REWARD_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L56 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_partitioned_stake_rewards { + ulong partition_len; + fd_partitioned_stake_reward_t * partition; +}; +typedef struct fd_partitioned_stake_rewards fd_partitioned_stake_rewards_t; +#define FD_PARTITIONED_STAKE_REWARDS_FOOTPRINT sizeof(fd_partitioned_stake_rewards_t) +#define FD_PARTITIONED_STAKE_REWARDS_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_partitioned_stake_rewards_off { + uint partition_off; +}; +typedef struct fd_partitioned_stake_rewards_off fd_partitioned_stake_rewards_off_t; +#define FD_PARTITIONED_STAKE_REWARDS_OFF_FOOTPRINT sizeof(fd_partitioned_stake_rewards_off_t) +#define FD_PARTITIONED_STAKE_REWARDS_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L60 */ /* Encoded Size: Dynamic */ struct __attribute__((aligned(8UL))) fd_start_block_height_and_rewards { - ulong start_block_height; + ulong distribution_starting_block_height; ulong stake_rewards_by_partition_len; - fd_serializable_stake_rewards_t * stake_rewards_by_partition; + fd_partitioned_stake_rewards_t * stake_rewards_by_partition; }; typedef struct fd_start_block_height_and_rewards fd_start_block_height_and_rewards_t; #define FD_START_BLOCK_HEIGHT_AND_REWARDS_FOOTPRINT sizeof(fd_start_block_height_and_rewards_t) #define FD_START_BLOCK_HEIGHT_AND_REWARDS_ALIGN (8UL) struct __attribute__((aligned(8UL))) fd_start_block_height_and_rewards_off { - uint start_block_height_off; + uint distribution_starting_block_height_off; uint stake_rewards_by_partition_off; }; typedef struct fd_start_block_height_and_rewards_off fd_start_block_height_and_rewards_off_t; #define FD_START_BLOCK_HEIGHT_AND_REWARDS_OFF_FOOTPRINT sizeof(fd_start_block_height_and_rewards_off_t) #define FD_START_BLOCK_HEIGHT_AND_REWARDS_OFF_ALIGN (8UL) -union fd_serializable_epoch_reward_status_inner { +union fd_epoch_reward_status_inner { fd_start_block_height_and_rewards_t Active; }; -typedef union fd_serializable_epoch_reward_status_inner fd_serializable_epoch_reward_status_inner_t; +typedef union fd_epoch_reward_status_inner fd_epoch_reward_status_inner_t; -struct fd_serializable_epoch_reward_status { +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L70 */ +struct fd_epoch_reward_status { uint discriminant; - fd_serializable_epoch_reward_status_inner_t inner; -}; -typedef struct fd_serializable_epoch_reward_status fd_serializable_epoch_reward_status_t; -#define FD_SERIALIZABLE_EPOCH_REWARD_STATUS_FOOTPRINT sizeof(fd_serializable_epoch_reward_status_t) -#define FD_SERIALIZABLE_EPOCH_REWARD_STATUS_ALIGN (8UL) - -/* Accounts DB related fields in a snapshot */ -/* Encoded Size: Dynamic */ -struct __attribute__((aligned(8UL))) fd_solana_accounts_db_fields { - ulong storages_len; - fd_snapshot_slot_acc_vecs_t * storages; - ulong version; - ulong slot; - fd_bank_hash_info_t bank_hash_info; - ulong historical_roots_len; - ulong* historical_roots; - ulong historical_roots_with_hash_len; - fd_slot_map_pair_t * historical_roots_with_hash; -}; -typedef struct fd_solana_accounts_db_fields fd_solana_accounts_db_fields_t; -#define FD_SOLANA_ACCOUNTS_DB_FIELDS_FOOTPRINT sizeof(fd_solana_accounts_db_fields_t) -#define FD_SOLANA_ACCOUNTS_DB_FIELDS_ALIGN (8UL) - -struct __attribute__((aligned(8UL))) fd_solana_accounts_db_fields_off { - uint storages_off; - uint version_off; - uint slot_off; - uint bank_hash_info_off; - uint historical_roots_off; - uint historical_roots_with_hash_off; + fd_epoch_reward_status_inner_t inner; }; -typedef struct fd_solana_accounts_db_fields_off fd_solana_accounts_db_fields_off_t; -#define FD_SOLANA_ACCOUNTS_DB_FIELDS_OFF_FOOTPRINT sizeof(fd_solana_accounts_db_fields_off_t) -#define FD_SOLANA_ACCOUNTS_DB_FIELDS_OFF_ALIGN (8UL) +typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; +#define FD_EPOCH_REWARD_STATUS_FOOTPRINT sizeof(fd_epoch_reward_status_t) +#define FD_EPOCH_REWARD_STATUS_ALIGN (8UL) /* Encoded Size: Dynamic */ struct __attribute__((aligned(16UL))) fd_solana_manifest { @@ -1213,7 +1244,7 @@ struct __attribute__((aligned(16UL))) fd_solana_manifest { ulong lamports_per_signature; fd_bank_incremental_snapshot_persistence_t * bank_incremental_snapshot_persistence; fd_hash_t * epoch_account_hash; - fd_serializable_epoch_reward_status_t * epoch_reward_status; + fd_epoch_reward_status_t * epoch_reward_status; }; typedef struct fd_solana_manifest fd_solana_manifest_t; #define FD_SOLANA_MANIFEST_FOOTPRINT sizeof(fd_solana_manifest_t) @@ -2184,17 +2215,29 @@ typedef struct fd_sysvar_fees_off fd_sysvar_fees_off_t; #define FD_SYSVAR_FEES_OFF_FOOTPRINT sizeof(fd_sysvar_fees_off_t) #define FD_SYSVAR_FEES_OFF_ALIGN (8UL) -/* https://github.com/solana-labs/solana/blob/a02aebaa4b3aa0b24e13644cf0ffa5ae8bd47e7b/sdk/program/src/sysvar/epoch_rewards.rs */ +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/sdk/program/src/epoch_rewards.rs#L14 */ /* Encoded Size: Dynamic */ struct __attribute__((aligned(8UL))) fd_sysvar_epoch_rewards { - fd_epoch_rewards_t epoch_rewards; + ulong distribution_starting_block_height; + ulong num_partitions; + fd_hash_t parent_blockhash; + uint128 total_points; + ulong total_rewards; + ulong distributed_rewards; + uchar active; }; typedef struct fd_sysvar_epoch_rewards fd_sysvar_epoch_rewards_t; #define FD_SYSVAR_EPOCH_REWARDS_FOOTPRINT sizeof(fd_sysvar_epoch_rewards_t) #define FD_SYSVAR_EPOCH_REWARDS_ALIGN (8UL) struct __attribute__((aligned(8UL))) fd_sysvar_epoch_rewards_off { - uint epoch_rewards_off; + uint distribution_starting_block_height_off; + uint num_partitions_off; + uint parent_blockhash_off; + uint total_points_off; + uint total_rewards_off; + uint distributed_rewards_off; + uint active_off; }; typedef struct fd_sysvar_epoch_rewards_off fd_sysvar_epoch_rewards_off_t; #define FD_SYSVAR_EPOCH_REWARDS_OFF_FOOTPRINT sizeof(fd_sysvar_epoch_rewards_off_t) @@ -3030,24 +3073,6 @@ typedef struct fd_stake_meta_off fd_stake_meta_off_t; #define FD_STAKE_META_OFF_FOOTPRINT sizeof(fd_stake_meta_off_t) #define FD_STAKE_META_OFF_ALIGN (8UL) -/* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/stake/state.rs#L539 */ -/* Encoded Size: Dynamic */ -struct __attribute__((aligned(8UL))) fd_stake { - fd_delegation_t delegation; - ulong credits_observed; -}; -typedef struct fd_stake fd_stake_t; -#define FD_STAKE_FOOTPRINT sizeof(fd_stake_t) -#define FD_STAKE_ALIGN (8UL) - -struct __attribute__((aligned(8UL))) fd_stake_off { - uint delegation_off; - uint credits_observed_off; -}; -typedef struct fd_stake_off fd_stake_off_t; -#define FD_STAKE_OFF_FOOTPRINT sizeof(fd_stake_off_t) -#define FD_STAKE_OFF_ALIGN (8UL) - /* https://github.com/firedancer-io/solana/blob/v1.17/sdk/program/src/stake/stake_flags.rs#L21 */ /* Encoded Size: Fixed (1 bytes) */ struct __attribute__((aligned(8UL))) fd_stake_flags { @@ -4548,6 +4573,296 @@ typedef struct fd_bank_slot_deltas_off fd_bank_slot_deltas_off_t; #define FD_BANK_SLOT_DELTAS_OFF_FOOTPRINT sizeof(fd_bank_slot_deltas_off_t) #define FD_BANK_SLOT_DELTAS_OFF_ALIGN (8UL) +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L85 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_pubkey_rewardinfo_pair { + fd_pubkey_t pubkey; + fd_reward_info_t reward_info; +}; +typedef struct fd_pubkey_rewardinfo_pair fd_pubkey_rewardinfo_pair_t; +#define FD_PUBKEY_REWARDINFO_PAIR_FOOTPRINT sizeof(fd_pubkey_rewardinfo_pair_t) +#define FD_PUBKEY_REWARDINFO_PAIR_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_pubkey_rewardinfo_pair_off { + uint pubkey_off; + uint reward_info_off; +}; +typedef struct fd_pubkey_rewardinfo_pair_off fd_pubkey_rewardinfo_pair_off_t; +#define FD_PUBKEY_REWARDINFO_PAIR_OFF_FOOTPRINT sizeof(fd_pubkey_rewardinfo_pair_off_t) +#define FD_PUBKEY_REWARDINFO_PAIR_OFF_ALIGN (8UL) + +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_optional_account { + fd_solana_account_t * account; +}; +typedef struct fd_optional_account fd_optional_account_t; +#define FD_OPTIONAL_ACCOUNT_FOOTPRINT sizeof(fd_optional_account_t) +#define FD_OPTIONAL_ACCOUNT_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_optional_account_off { + uint account_off; +}; +typedef struct fd_optional_account_off fd_optional_account_off_t; +#define FD_OPTIONAL_ACCOUNT_OFF_FOOTPRINT sizeof(fd_optional_account_off_t) +#define FD_OPTIONAL_ACCOUNT_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L82 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_vote_rewards_accounts { + ulong rewards_len; + fd_pubkey_rewardinfo_pair_t * rewards; + ulong accounts_to_store_len; + fd_optional_account_t * accounts_to_store; +}; +typedef struct fd_vote_rewards_accounts fd_vote_rewards_accounts_t; +#define FD_VOTE_REWARDS_ACCOUNTS_FOOTPRINT sizeof(fd_vote_rewards_accounts_t) +#define FD_VOTE_REWARDS_ACCOUNTS_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_vote_rewards_accounts_off { + uint rewards_off; + uint accounts_to_store_off; +}; +typedef struct fd_vote_rewards_accounts_off fd_vote_rewards_accounts_off_t; +#define FD_VOTE_REWARDS_ACCOUNTS_OFF_FOOTPRINT sizeof(fd_vote_rewards_accounts_off_t) +#define FD_VOTE_REWARDS_ACCOUNTS_OFF_ALIGN (8UL) + +#define DEQUE_NAME deq_fd_partitioned_stake_reward_t +#define DEQUE_T fd_partitioned_stake_reward_t +#include "../../util/tmpl/fd_deque_dynamic.c" +#undef DEQUE_NAME +#undef DEQUE_T +#undef DEQUE_MAX +static inline fd_partitioned_stake_reward_t * +deq_fd_partitioned_stake_reward_t_alloc( fd_valloc_t valloc, ulong max ) { + if( FD_UNLIKELY( 0 == max ) ) max = 1; // prevent underflow + void * mem = fd_valloc_malloc( valloc, deq_fd_partitioned_stake_reward_t_align(), deq_fd_partitioned_stake_reward_t_footprint( max ) ); + return deq_fd_partitioned_stake_reward_t_join( deq_fd_partitioned_stake_reward_t_new( mem, max ) ); +} +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L94 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_stake_reward_calculation { + fd_partitioned_stake_reward_t * stake_reward_deq; /* fd_deque_dynamic (min cnt 24) */ + ulong total_stake_rewards_lamports; +}; +typedef struct fd_stake_reward_calculation fd_stake_reward_calculation_t; +#define FD_STAKE_REWARD_CALCULATION_FOOTPRINT sizeof(fd_stake_reward_calculation_t) +#define FD_STAKE_REWARD_CALCULATION_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_stake_reward_calculation_off { + uint stake_reward_deq_off; + uint total_stake_rewards_lamports_off; +}; +typedef struct fd_stake_reward_calculation_off fd_stake_reward_calculation_off_t; +#define FD_STAKE_REWARD_CALCULATION_OFF_FOOTPRINT sizeof(fd_stake_reward_calculation_off_t) +#define FD_STAKE_REWARD_CALCULATION_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L131 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_stake_reward_calculation_partitioned { + ulong stake_rewards_by_partition_len; + fd_partitioned_stake_rewards_t * stake_rewards_by_partition; + ulong total_stake_rewards_lamports; +}; +typedef struct fd_stake_reward_calculation_partitioned fd_stake_reward_calculation_partitioned_t; +#define FD_STAKE_REWARD_CALCULATION_PARTITIONED_FOOTPRINT sizeof(fd_stake_reward_calculation_partitioned_t) +#define FD_STAKE_REWARD_CALCULATION_PARTITIONED_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_stake_reward_calculation_partitioned_off { + uint stake_rewards_by_partition_off; + uint total_stake_rewards_lamports_off; +}; +typedef struct fd_stake_reward_calculation_partitioned_off fd_stake_reward_calculation_partitioned_off_t; +#define FD_STAKE_REWARD_CALCULATION_PARTITIONED_OFF_FOOTPRINT sizeof(fd_stake_reward_calculation_partitioned_off_t) +#define FD_STAKE_REWARD_CALCULATION_PARTITIONED_OFF_ALIGN (8UL) + +typedef struct fd_vote_reward_t_mapnode fd_vote_reward_t_mapnode_t; +#define REDBLK_T fd_vote_reward_t_mapnode_t +#define REDBLK_NAME fd_vote_reward_t_map +#define REDBLK_IMPL_STYLE 1 +#include "../../util/tmpl/fd_redblack.c" +#undef REDBLK_T +#undef REDBLK_NAME +struct fd_vote_reward_t_mapnode { + fd_vote_reward_t elem; + ulong redblack_parent; + ulong redblack_left; + ulong redblack_right; + int redblack_color; +}; +static inline fd_vote_reward_t_mapnode_t * +fd_vote_reward_t_map_alloc( fd_valloc_t valloc, ulong len ) { + if( FD_UNLIKELY( 0 == len ) ) len = 1; // prevent underflow + void * mem = fd_valloc_malloc( valloc, fd_vote_reward_t_map_align(), fd_vote_reward_t_map_footprint(len)); + return fd_vote_reward_t_map_join(fd_vote_reward_t_map_new(mem, len)); +} +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L118 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_partitioned_rewards_calculation { + fd_vote_reward_t_mapnode_t * vote_reward_map_pool; + fd_vote_reward_t_mapnode_t * vote_reward_map_root; + fd_stake_reward_calculation_partitioned_t stake_rewards_by_partition; + ulong old_vote_balance_and_staked; + ulong validator_rewards; + double validator_rate; + double foundation_rate; + double prev_epoch_duration_in_years; + ulong capitalization; + uint128 total_points; +}; +typedef struct fd_partitioned_rewards_calculation fd_partitioned_rewards_calculation_t; +#define FD_PARTITIONED_REWARDS_CALCULATION_FOOTPRINT sizeof(fd_partitioned_rewards_calculation_t) +#define FD_PARTITIONED_REWARDS_CALCULATION_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_partitioned_rewards_calculation_off { + uint vote_reward_map_off; + uint stake_rewards_by_partition_off; + uint old_vote_balance_and_staked_off; + uint validator_rewards_off; + uint validator_rate_off; + uint foundation_rate_off; + uint prev_epoch_duration_in_years_off; + uint capitalization_off; + uint total_points_off; +}; +typedef struct fd_partitioned_rewards_calculation_off fd_partitioned_rewards_calculation_off_t; +#define FD_PARTITIONED_REWARDS_CALCULATION_OFF_FOOTPRINT sizeof(fd_partitioned_rewards_calculation_off_t) +#define FD_PARTITIONED_REWARDS_CALCULATION_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L138 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_calculate_rewards_and_distribute_vote_rewards_result { + ulong total_rewards; + ulong distributed_rewards; + uint128 total_points; + fd_stake_reward_calculation_partitioned_t stake_rewards_by_partition; +}; +typedef struct fd_calculate_rewards_and_distribute_vote_rewards_result fd_calculate_rewards_and_distribute_vote_rewards_result_t; +#define FD_CALCULATE_REWARDS_AND_DISTRIBUTE_VOTE_REWARDS_RESULT_FOOTPRINT sizeof(fd_calculate_rewards_and_distribute_vote_rewards_result_t) +#define FD_CALCULATE_REWARDS_AND_DISTRIBUTE_VOTE_REWARDS_RESULT_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_calculate_rewards_and_distribute_vote_rewards_result_off { + uint total_rewards_off; + uint distributed_rewards_off; + uint total_points_off; + uint stake_rewards_by_partition_off; +}; +typedef struct fd_calculate_rewards_and_distribute_vote_rewards_result_off fd_calculate_rewards_and_distribute_vote_rewards_result_off_t; +#define FD_CALCULATE_REWARDS_AND_DISTRIBUTE_VOTE_REWARDS_RESULT_OFF_FOOTPRINT sizeof(fd_calculate_rewards_and_distribute_vote_rewards_result_off_t) +#define FD_CALCULATE_REWARDS_AND_DISTRIBUTE_VOTE_REWARDS_RESULT_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L154 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_keyed_rewards_and_num_partitions { + ulong keyed_rewards_len; + fd_pubkey_rewardinfo_pair_t * keyed_rewards; + ulong* num_partitions; +}; +typedef struct fd_keyed_rewards_and_num_partitions fd_keyed_rewards_and_num_partitions_t; +#define FD_KEYED_REWARDS_AND_NUM_PARTITIONS_FOOTPRINT sizeof(fd_keyed_rewards_and_num_partitions_t) +#define FD_KEYED_REWARDS_AND_NUM_PARTITIONS_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_keyed_rewards_and_num_partitions_off { + uint keyed_rewards_off; + uint num_partitions_off; +}; +typedef struct fd_keyed_rewards_and_num_partitions_off fd_keyed_rewards_and_num_partitions_off_t; +#define FD_KEYED_REWARDS_AND_NUM_PARTITIONS_OFF_FOOTPRINT sizeof(fd_keyed_rewards_and_num_partitions_off_t) +#define FD_KEYED_REWARDS_AND_NUM_PARTITIONS_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L27 */ +/* Encoded Size: Fixed (25 bytes) */ +struct __attribute__((aligned(8UL))) fd_calculated_stake_points { + uint128 points; + ulong new_credits_observed; + uchar force_credits_update_with_skipped_reward; +}; +typedef struct fd_calculated_stake_points fd_calculated_stake_points_t; +#define FD_CALCULATED_STAKE_POINTS_FOOTPRINT sizeof(fd_calculated_stake_points_t) +#define FD_CALCULATED_STAKE_POINTS_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_calculated_stake_points_off { + uint points_off; + uint new_credits_observed_off; + uint force_credits_update_with_skipped_reward_off; +}; +typedef struct fd_calculated_stake_points_off fd_calculated_stake_points_off_t; +#define FD_CALCULATED_STAKE_POINTS_OFF_FOOTPRINT sizeof(fd_calculated_stake_points_off_t) +#define FD_CALCULATED_STAKE_POINTS_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L21 */ +/* Encoded Size: Fixed (24 bytes) */ +struct __attribute__((aligned(8UL))) fd_point_value { + ulong rewards; + uint128 points; +}; +typedef struct fd_point_value fd_point_value_t; +#define FD_POINT_VALUE_FOOTPRINT sizeof(fd_point_value_t) +#define FD_POINT_VALUE_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_point_value_off { + uint rewards_off; + uint points_off; +}; +typedef struct fd_point_value_off fd_point_value_off_t; +#define FD_POINT_VALUE_OFF_FOOTPRINT sizeof(fd_point_value_off_t) +#define FD_POINT_VALUE_OFF_ALIGN (8UL) + +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_calculate_stake_vote_rewards_result { + fd_stake_reward_calculation_t stake_reward_calculation; + fd_vote_reward_t_mapnode_t * vote_reward_map_pool; + fd_vote_reward_t_mapnode_t * vote_reward_map_root; +}; +typedef struct fd_calculate_stake_vote_rewards_result fd_calculate_stake_vote_rewards_result_t; +#define FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_FOOTPRINT sizeof(fd_calculate_stake_vote_rewards_result_t) +#define FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_calculate_stake_vote_rewards_result_off { + uint stake_reward_calculation_off; + uint vote_reward_map_off; +}; +typedef struct fd_calculate_stake_vote_rewards_result_off fd_calculate_stake_vote_rewards_result_off_t; +#define FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_OFF_FOOTPRINT sizeof(fd_calculate_stake_vote_rewards_result_off_t) +#define FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/rewards.rs#L24 */ +/* Encoded Size: Fixed (24 bytes) */ +struct __attribute__((aligned(8UL))) fd_calculated_stake_rewards { + ulong staker_rewards; + ulong voter_rewards; + ulong new_credits_observed; +}; +typedef struct fd_calculated_stake_rewards fd_calculated_stake_rewards_t; +#define FD_CALCULATED_STAKE_REWARDS_FOOTPRINT sizeof(fd_calculated_stake_rewards_t) +#define FD_CALCULATED_STAKE_REWARDS_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_calculated_stake_rewards_off { + uint staker_rewards_off; + uint voter_rewards_off; + uint new_credits_observed_off; +}; +typedef struct fd_calculated_stake_rewards_off fd_calculated_stake_rewards_off_t; +#define FD_CALCULATED_STAKE_REWARDS_OFF_FOOTPRINT sizeof(fd_calculated_stake_rewards_off_t) +#define FD_CALCULATED_STAKE_REWARDS_OFF_ALIGN (8UL) + +/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L102 */ +/* Encoded Size: Dynamic */ +struct __attribute__((aligned(8UL))) fd_calculate_validator_rewards_result { + fd_calculate_stake_vote_rewards_result_t calculate_stake_vote_rewards_result; + uint128 total_points; +}; +typedef struct fd_calculate_validator_rewards_result fd_calculate_validator_rewards_result_t; +#define FD_CALCULATE_VALIDATOR_REWARDS_RESULT_FOOTPRINT sizeof(fd_calculate_validator_rewards_result_t) +#define FD_CALCULATE_VALIDATOR_REWARDS_RESULT_ALIGN (8UL) + +struct __attribute__((aligned(8UL))) fd_calculate_validator_rewards_result_off { + uint calculate_stake_vote_rewards_result_off; + uint total_points_off; +}; +typedef struct fd_calculate_validator_rewards_result_off fd_calculate_validator_rewards_result_off_t; +#define FD_CALCULATE_VALIDATOR_REWARDS_RESULT_OFF_FOOTPRINT sizeof(fd_calculate_validator_rewards_result_off_t) +#define FD_CALCULATE_VALIDATOR_REWARDS_RESULT_OFF_ALIGN (8UL) + FD_PROTOTYPES_BEGIN @@ -4623,18 +4938,6 @@ int fd_fee_calculator_decode_archival_preflight( fd_bincode_decode_ctx_t * ctx ) void fd_fee_calculator_decode_archival_unsafe( fd_fee_calculator_t * self, fd_bincode_decode_ctx_t * ctx ); int fd_fee_calculator_encode_archival( fd_fee_calculator_t const * self, fd_bincode_encode_ctx_t * ctx ); -void fd_epoch_rewards_new( fd_epoch_rewards_t * self ); -int fd_epoch_rewards_decode( fd_epoch_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_epoch_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ); -void fd_epoch_rewards_decode_unsafe( fd_epoch_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_epoch_rewards_decode_offsets( fd_epoch_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_epoch_rewards_encode( fd_epoch_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ); -void fd_epoch_rewards_destroy( fd_epoch_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ); -void fd_epoch_rewards_walk( void * w, fd_epoch_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); -ulong fd_epoch_rewards_size( fd_epoch_rewards_t const * self ); -ulong fd_epoch_rewards_footprint( void ); -ulong fd_epoch_rewards_align( void ); - void fd_hash_age_new( fd_hash_age_t * self ); int fd_hash_age_decode( fd_hash_age_t * self, fd_bincode_decode_ctx_t * ctx ); int fd_hash_age_decode_preflight( fd_bincode_decode_ctx_t * ctx ); @@ -5165,6 +5468,18 @@ fd_reward_type_enum_rent = 1, fd_reward_type_enum_staking = 2, fd_reward_type_enum_voting = 3, }; +void fd_solana_accounts_db_fields_new( fd_solana_accounts_db_fields_t * self ); +int fd_solana_accounts_db_fields_decode( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_solana_accounts_db_fields_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_solana_accounts_db_fields_decode_unsafe( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_solana_accounts_db_fields_decode_offsets( fd_solana_accounts_db_fields_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_solana_accounts_db_fields_encode( fd_solana_accounts_db_fields_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_solana_accounts_db_fields_destroy( fd_solana_accounts_db_fields_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_solana_accounts_db_fields_walk( void * w, fd_solana_accounts_db_fields_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_solana_accounts_db_fields_size( fd_solana_accounts_db_fields_t const * self ); +ulong fd_solana_accounts_db_fields_footprint( void ); +ulong fd_solana_accounts_db_fields_align( void ); + void fd_reward_info_new( fd_reward_info_t * self ); int fd_reward_info_decode( fd_reward_info_t * self, fd_bincode_decode_ctx_t * ctx ); int fd_reward_info_decode_preflight( fd_bincode_decode_ctx_t * ctx ); @@ -5189,17 +5504,53 @@ ulong fd_stake_reward_size( fd_stake_reward_t const * self ); ulong fd_stake_reward_footprint( void ); ulong fd_stake_reward_align( void ); -void fd_serializable_stake_rewards_new( fd_serializable_stake_rewards_t * self ); -int fd_serializable_stake_rewards_decode( fd_serializable_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_serializable_stake_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ); -void fd_serializable_stake_rewards_decode_unsafe( fd_serializable_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_serializable_stake_rewards_decode_offsets( fd_serializable_stake_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_serializable_stake_rewards_encode( fd_serializable_stake_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ); -void fd_serializable_stake_rewards_destroy( fd_serializable_stake_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ); -void fd_serializable_stake_rewards_walk( void * w, fd_serializable_stake_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); -ulong fd_serializable_stake_rewards_size( fd_serializable_stake_rewards_t const * self ); -ulong fd_serializable_stake_rewards_footprint( void ); -ulong fd_serializable_stake_rewards_align( void ); +void fd_vote_reward_new( fd_vote_reward_t * self ); +int fd_vote_reward_decode( fd_vote_reward_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_vote_reward_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_vote_reward_decode_unsafe( fd_vote_reward_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_vote_reward_decode_offsets( fd_vote_reward_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_vote_reward_encode( fd_vote_reward_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_vote_reward_destroy( fd_vote_reward_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_vote_reward_walk( void * w, fd_vote_reward_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_vote_reward_size( fd_vote_reward_t const * self ); +ulong fd_vote_reward_footprint( void ); +ulong fd_vote_reward_align( void ); + +void fd_stake_new( fd_stake_t * self ); +int fd_stake_decode( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_stake_decode_unsafe( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_decode_offsets( fd_stake_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_encode( fd_stake_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_stake_destroy( fd_stake_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_stake_walk( void * w, fd_stake_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_stake_size( fd_stake_t const * self ); +ulong fd_stake_footprint( void ); +ulong fd_stake_align( void ); + +void fd_partitioned_stake_reward_new( fd_partitioned_stake_reward_t * self ); +int fd_partitioned_stake_reward_decode( fd_partitioned_stake_reward_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_stake_reward_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_partitioned_stake_reward_decode_unsafe( fd_partitioned_stake_reward_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_stake_reward_decode_offsets( fd_partitioned_stake_reward_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_stake_reward_encode( fd_partitioned_stake_reward_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_partitioned_stake_reward_destroy( fd_partitioned_stake_reward_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_partitioned_stake_reward_walk( void * w, fd_partitioned_stake_reward_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_partitioned_stake_reward_size( fd_partitioned_stake_reward_t const * self ); +ulong fd_partitioned_stake_reward_footprint( void ); +ulong fd_partitioned_stake_reward_align( void ); + +void fd_partitioned_stake_rewards_new( fd_partitioned_stake_rewards_t * self ); +int fd_partitioned_stake_rewards_decode( fd_partitioned_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_stake_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_partitioned_stake_rewards_decode_unsafe( fd_partitioned_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_stake_rewards_decode_offsets( fd_partitioned_stake_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_stake_rewards_encode( fd_partitioned_stake_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_partitioned_stake_rewards_destroy( fd_partitioned_stake_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_partitioned_stake_rewards_walk( void * w, fd_partitioned_stake_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_partitioned_stake_rewards_size( fd_partitioned_stake_rewards_t const * self ); +ulong fd_partitioned_stake_rewards_footprint( void ); +ulong fd_partitioned_stake_rewards_align( void ); void fd_start_block_height_and_rewards_new( fd_start_block_height_and_rewards_t * self ); int fd_start_block_height_and_rewards_decode( fd_start_block_height_and_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); @@ -5213,36 +5564,24 @@ ulong fd_start_block_height_and_rewards_size( fd_start_block_height_and_rewards_ ulong fd_start_block_height_and_rewards_footprint( void ); ulong fd_start_block_height_and_rewards_align( void ); -void fd_serializable_epoch_reward_status_new_disc( fd_serializable_epoch_reward_status_t * self, uint discriminant ); -void fd_serializable_epoch_reward_status_new( fd_serializable_epoch_reward_status_t * self ); -int fd_serializable_epoch_reward_status_decode( fd_serializable_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_serializable_epoch_reward_status_decode_preflight( fd_bincode_decode_ctx_t * ctx ); -void fd_serializable_epoch_reward_status_decode_unsafe( fd_serializable_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_serializable_epoch_reward_status_encode( fd_serializable_epoch_reward_status_t const * self, fd_bincode_encode_ctx_t * ctx ); -void fd_serializable_epoch_reward_status_destroy( fd_serializable_epoch_reward_status_t * self, fd_bincode_destroy_ctx_t * ctx ); -void fd_serializable_epoch_reward_status_walk( void * w, fd_serializable_epoch_reward_status_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); -ulong fd_serializable_epoch_reward_status_size( fd_serializable_epoch_reward_status_t const * self ); -ulong fd_serializable_epoch_reward_status_footprint( void ); -ulong fd_serializable_epoch_reward_status_align( void ); - -FD_FN_PURE uchar fd_serializable_epoch_reward_status_is_Active( fd_serializable_epoch_reward_status_t const * self ); -FD_FN_PURE uchar fd_serializable_epoch_reward_status_is_Inactive( fd_serializable_epoch_reward_status_t const * self ); +void fd_epoch_reward_status_new_disc( fd_epoch_reward_status_t * self, uint discriminant ); +void fd_epoch_reward_status_new( fd_epoch_reward_status_t * self ); +int fd_epoch_reward_status_decode( fd_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_epoch_reward_status_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_epoch_reward_status_decode_unsafe( fd_epoch_reward_status_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_epoch_reward_status_encode( fd_epoch_reward_status_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_epoch_reward_status_destroy( fd_epoch_reward_status_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_epoch_reward_status_walk( void * w, fd_epoch_reward_status_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_epoch_reward_status_size( fd_epoch_reward_status_t const * self ); +ulong fd_epoch_reward_status_footprint( void ); +ulong fd_epoch_reward_status_align( void ); + +FD_FN_PURE uchar fd_epoch_reward_status_is_Active( fd_epoch_reward_status_t const * self ); +FD_FN_PURE uchar fd_epoch_reward_status_is_Inactive( fd_epoch_reward_status_t const * self ); enum { -fd_serializable_epoch_reward_status_enum_Active = 0, -fd_serializable_epoch_reward_status_enum_Inactive = 1, +fd_epoch_reward_status_enum_Active = 0, +fd_epoch_reward_status_enum_Inactive = 1, }; -void fd_solana_accounts_db_fields_new( fd_solana_accounts_db_fields_t * self ); -int fd_solana_accounts_db_fields_decode( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_solana_accounts_db_fields_decode_preflight( fd_bincode_decode_ctx_t * ctx ); -void fd_solana_accounts_db_fields_decode_unsafe( fd_solana_accounts_db_fields_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_solana_accounts_db_fields_decode_offsets( fd_solana_accounts_db_fields_off_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_solana_accounts_db_fields_encode( fd_solana_accounts_db_fields_t const * self, fd_bincode_encode_ctx_t * ctx ); -void fd_solana_accounts_db_fields_destroy( fd_solana_accounts_db_fields_t * self, fd_bincode_destroy_ctx_t * ctx ); -void fd_solana_accounts_db_fields_walk( void * w, fd_solana_accounts_db_fields_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); -ulong fd_solana_accounts_db_fields_size( fd_solana_accounts_db_fields_t const * self ); -ulong fd_solana_accounts_db_fields_footprint( void ); -ulong fd_solana_accounts_db_fields_align( void ); - void fd_solana_manifest_new( fd_solana_manifest_t * self ); int fd_solana_manifest_decode( fd_solana_manifest_t * self, fd_bincode_decode_ctx_t * ctx ); int fd_solana_manifest_decode_preflight( fd_bincode_decode_ctx_t * ctx ); @@ -6342,18 +6681,6 @@ ulong fd_stake_meta_size( fd_stake_meta_t const * self ); ulong fd_stake_meta_footprint( void ); ulong fd_stake_meta_align( void ); -void fd_stake_new( fd_stake_t * self ); -int fd_stake_decode( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_stake_decode_preflight( fd_bincode_decode_ctx_t * ctx ); -void fd_stake_decode_unsafe( fd_stake_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_stake_decode_offsets( fd_stake_off_t * self, fd_bincode_decode_ctx_t * ctx ); -int fd_stake_encode( fd_stake_t const * self, fd_bincode_encode_ctx_t * ctx ); -void fd_stake_destroy( fd_stake_t * self, fd_bincode_destroy_ctx_t * ctx ); -void fd_stake_walk( void * w, fd_stake_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); -ulong fd_stake_size( fd_stake_t const * self ); -ulong fd_stake_footprint( void ); -ulong fd_stake_align( void ); - void fd_stake_flags_new( fd_stake_flags_t * self ); int fd_stake_flags_decode( fd_stake_flags_t * self, fd_bincode_decode_ctx_t * ctx ); int fd_stake_flags_decode_preflight( fd_bincode_decode_ctx_t * ctx ); @@ -7690,6 +8017,162 @@ ulong fd_bank_slot_deltas_size( fd_bank_slot_deltas_t const * self ); ulong fd_bank_slot_deltas_footprint( void ); ulong fd_bank_slot_deltas_align( void ); +void fd_pubkey_rewardinfo_pair_new( fd_pubkey_rewardinfo_pair_t * self ); +int fd_pubkey_rewardinfo_pair_decode( fd_pubkey_rewardinfo_pair_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_pubkey_rewardinfo_pair_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_pubkey_rewardinfo_pair_decode_unsafe( fd_pubkey_rewardinfo_pair_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_pubkey_rewardinfo_pair_decode_offsets( fd_pubkey_rewardinfo_pair_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_pubkey_rewardinfo_pair_encode( fd_pubkey_rewardinfo_pair_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_pubkey_rewardinfo_pair_destroy( fd_pubkey_rewardinfo_pair_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_pubkey_rewardinfo_pair_walk( void * w, fd_pubkey_rewardinfo_pair_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_pubkey_rewardinfo_pair_size( fd_pubkey_rewardinfo_pair_t const * self ); +ulong fd_pubkey_rewardinfo_pair_footprint( void ); +ulong fd_pubkey_rewardinfo_pair_align( void ); + +void fd_optional_account_new( fd_optional_account_t * self ); +int fd_optional_account_decode( fd_optional_account_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_optional_account_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_optional_account_decode_unsafe( fd_optional_account_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_optional_account_decode_offsets( fd_optional_account_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_optional_account_encode( fd_optional_account_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_optional_account_destroy( fd_optional_account_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_optional_account_walk( void * w, fd_optional_account_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_optional_account_size( fd_optional_account_t const * self ); +ulong fd_optional_account_footprint( void ); +ulong fd_optional_account_align( void ); + +void fd_vote_rewards_accounts_new( fd_vote_rewards_accounts_t * self ); +int fd_vote_rewards_accounts_decode( fd_vote_rewards_accounts_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_vote_rewards_accounts_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_vote_rewards_accounts_decode_unsafe( fd_vote_rewards_accounts_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_vote_rewards_accounts_decode_offsets( fd_vote_rewards_accounts_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_vote_rewards_accounts_encode( fd_vote_rewards_accounts_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_vote_rewards_accounts_destroy( fd_vote_rewards_accounts_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_vote_rewards_accounts_walk( void * w, fd_vote_rewards_accounts_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_vote_rewards_accounts_size( fd_vote_rewards_accounts_t const * self ); +ulong fd_vote_rewards_accounts_footprint( void ); +ulong fd_vote_rewards_accounts_align( void ); + +void fd_stake_reward_calculation_new( fd_stake_reward_calculation_t * self ); +int fd_stake_reward_calculation_decode( fd_stake_reward_calculation_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_reward_calculation_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_stake_reward_calculation_decode_unsafe( fd_stake_reward_calculation_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_reward_calculation_decode_offsets( fd_stake_reward_calculation_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_reward_calculation_encode( fd_stake_reward_calculation_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_stake_reward_calculation_destroy( fd_stake_reward_calculation_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_stake_reward_calculation_walk( void * w, fd_stake_reward_calculation_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_stake_reward_calculation_size( fd_stake_reward_calculation_t const * self ); +ulong fd_stake_reward_calculation_footprint( void ); +ulong fd_stake_reward_calculation_align( void ); + +void fd_stake_reward_calculation_partitioned_new( fd_stake_reward_calculation_partitioned_t * self ); +int fd_stake_reward_calculation_partitioned_decode( fd_stake_reward_calculation_partitioned_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_reward_calculation_partitioned_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_stake_reward_calculation_partitioned_decode_unsafe( fd_stake_reward_calculation_partitioned_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_reward_calculation_partitioned_decode_offsets( fd_stake_reward_calculation_partitioned_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_stake_reward_calculation_partitioned_encode( fd_stake_reward_calculation_partitioned_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_stake_reward_calculation_partitioned_destroy( fd_stake_reward_calculation_partitioned_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_stake_reward_calculation_partitioned_walk( void * w, fd_stake_reward_calculation_partitioned_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_stake_reward_calculation_partitioned_size( fd_stake_reward_calculation_partitioned_t const * self ); +ulong fd_stake_reward_calculation_partitioned_footprint( void ); +ulong fd_stake_reward_calculation_partitioned_align( void ); + +void fd_partitioned_rewards_calculation_new( fd_partitioned_rewards_calculation_t * self ); +int fd_partitioned_rewards_calculation_decode( fd_partitioned_rewards_calculation_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_rewards_calculation_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_partitioned_rewards_calculation_decode_unsafe( fd_partitioned_rewards_calculation_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_rewards_calculation_decode_offsets( fd_partitioned_rewards_calculation_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_partitioned_rewards_calculation_encode( fd_partitioned_rewards_calculation_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_partitioned_rewards_calculation_destroy( fd_partitioned_rewards_calculation_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_partitioned_rewards_calculation_walk( void * w, fd_partitioned_rewards_calculation_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_partitioned_rewards_calculation_size( fd_partitioned_rewards_calculation_t const * self ); +ulong fd_partitioned_rewards_calculation_footprint( void ); +ulong fd_partitioned_rewards_calculation_align( void ); + +void fd_calculate_rewards_and_distribute_vote_rewards_result_new( fd_calculate_rewards_and_distribute_vote_rewards_result_t * self ); +int fd_calculate_rewards_and_distribute_vote_rewards_result_decode( fd_calculate_rewards_and_distribute_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_rewards_and_distribute_vote_rewards_result_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_calculate_rewards_and_distribute_vote_rewards_result_decode_unsafe( fd_calculate_rewards_and_distribute_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_rewards_and_distribute_vote_rewards_result_decode_offsets( fd_calculate_rewards_and_distribute_vote_rewards_result_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_rewards_and_distribute_vote_rewards_result_encode( fd_calculate_rewards_and_distribute_vote_rewards_result_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_calculate_rewards_and_distribute_vote_rewards_result_destroy( fd_calculate_rewards_and_distribute_vote_rewards_result_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_calculate_rewards_and_distribute_vote_rewards_result_walk( void * w, fd_calculate_rewards_and_distribute_vote_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_calculate_rewards_and_distribute_vote_rewards_result_size( fd_calculate_rewards_and_distribute_vote_rewards_result_t const * self ); +ulong fd_calculate_rewards_and_distribute_vote_rewards_result_footprint( void ); +ulong fd_calculate_rewards_and_distribute_vote_rewards_result_align( void ); + +void fd_keyed_rewards_and_num_partitions_new( fd_keyed_rewards_and_num_partitions_t * self ); +int fd_keyed_rewards_and_num_partitions_decode( fd_keyed_rewards_and_num_partitions_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_keyed_rewards_and_num_partitions_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_keyed_rewards_and_num_partitions_decode_unsafe( fd_keyed_rewards_and_num_partitions_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_keyed_rewards_and_num_partitions_decode_offsets( fd_keyed_rewards_and_num_partitions_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_keyed_rewards_and_num_partitions_encode( fd_keyed_rewards_and_num_partitions_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_keyed_rewards_and_num_partitions_destroy( fd_keyed_rewards_and_num_partitions_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_keyed_rewards_and_num_partitions_walk( void * w, fd_keyed_rewards_and_num_partitions_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_keyed_rewards_and_num_partitions_size( fd_keyed_rewards_and_num_partitions_t const * self ); +ulong fd_keyed_rewards_and_num_partitions_footprint( void ); +ulong fd_keyed_rewards_and_num_partitions_align( void ); + +void fd_calculated_stake_points_new( fd_calculated_stake_points_t * self ); +int fd_calculated_stake_points_decode( fd_calculated_stake_points_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculated_stake_points_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_calculated_stake_points_decode_unsafe( fd_calculated_stake_points_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculated_stake_points_decode_offsets( fd_calculated_stake_points_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculated_stake_points_encode( fd_calculated_stake_points_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_calculated_stake_points_destroy( fd_calculated_stake_points_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_calculated_stake_points_walk( void * w, fd_calculated_stake_points_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_calculated_stake_points_size( fd_calculated_stake_points_t const * self ); +ulong fd_calculated_stake_points_footprint( void ); +ulong fd_calculated_stake_points_align( void ); + +void fd_point_value_new( fd_point_value_t * self ); +int fd_point_value_decode( fd_point_value_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_point_value_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_point_value_decode_unsafe( fd_point_value_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_point_value_decode_offsets( fd_point_value_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_point_value_encode( fd_point_value_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_point_value_destroy( fd_point_value_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_point_value_walk( void * w, fd_point_value_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_point_value_size( fd_point_value_t const * self ); +ulong fd_point_value_footprint( void ); +ulong fd_point_value_align( void ); + +void fd_calculate_stake_vote_rewards_result_new( fd_calculate_stake_vote_rewards_result_t * self ); +int fd_calculate_stake_vote_rewards_result_decode( fd_calculate_stake_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_stake_vote_rewards_result_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_calculate_stake_vote_rewards_result_decode_unsafe( fd_calculate_stake_vote_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_stake_vote_rewards_result_decode_offsets( fd_calculate_stake_vote_rewards_result_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_stake_vote_rewards_result_encode( fd_calculate_stake_vote_rewards_result_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_calculate_stake_vote_rewards_result_destroy( fd_calculate_stake_vote_rewards_result_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_calculate_stake_vote_rewards_result_walk( void * w, fd_calculate_stake_vote_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_calculate_stake_vote_rewards_result_size( fd_calculate_stake_vote_rewards_result_t const * self ); +ulong fd_calculate_stake_vote_rewards_result_footprint( void ); +ulong fd_calculate_stake_vote_rewards_result_align( void ); + +void fd_calculated_stake_rewards_new( fd_calculated_stake_rewards_t * self ); +int fd_calculated_stake_rewards_decode( fd_calculated_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculated_stake_rewards_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_calculated_stake_rewards_decode_unsafe( fd_calculated_stake_rewards_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculated_stake_rewards_decode_offsets( fd_calculated_stake_rewards_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculated_stake_rewards_encode( fd_calculated_stake_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_calculated_stake_rewards_destroy( fd_calculated_stake_rewards_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_calculated_stake_rewards_walk( void * w, fd_calculated_stake_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_calculated_stake_rewards_size( fd_calculated_stake_rewards_t const * self ); +ulong fd_calculated_stake_rewards_footprint( void ); +ulong fd_calculated_stake_rewards_align( void ); + +void fd_calculate_validator_rewards_result_new( fd_calculate_validator_rewards_result_t * self ); +int fd_calculate_validator_rewards_result_decode( fd_calculate_validator_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_validator_rewards_result_decode_preflight( fd_bincode_decode_ctx_t * ctx ); +void fd_calculate_validator_rewards_result_decode_unsafe( fd_calculate_validator_rewards_result_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_validator_rewards_result_decode_offsets( fd_calculate_validator_rewards_result_off_t * self, fd_bincode_decode_ctx_t * ctx ); +int fd_calculate_validator_rewards_result_encode( fd_calculate_validator_rewards_result_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_calculate_validator_rewards_result_destroy( fd_calculate_validator_rewards_result_t * self, fd_bincode_destroy_ctx_t * ctx ); +void fd_calculate_validator_rewards_result_walk( void * w, fd_calculate_validator_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_calculate_validator_rewards_result_size( fd_calculate_validator_rewards_result_t const * self ); +ulong fd_calculate_validator_rewards_result_footprint( void ); +ulong fd_calculate_validator_rewards_result_align( void ); + FD_PROTOTYPES_END #endif // HEADER_FD_RUNTIME_TYPES diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index 49cefe2c7c..bd8384c1c1 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -50,20 +50,6 @@ ], "comment": "https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/fee_calculator.rs#L9" }, - { - "name": "epoch_rewards", - "type": "struct", - "fields": [ - { "name": "distribution_starting_block_height", "type": "ulong"}, - { "name": "num_partitions", "type": "ulong" }, - { "name": "parent_blockhash", "type": "hash" }, - { "name": "total_points", "type": "uint128" }, - { "name": "total_rewards", "type": "ulong" }, - { "name": "distributed_rewards", "type": "ulong" }, - { "name": "active", "type": "bool" } - ], - "comment": "https://github.com/anza-xyz/agave/blob/7fcd8c03fd71418fe49459c8460ab3986a8b608a/sdk/program/src/epoch_rewards.rs#L12" - }, { "name": "hash_age", "type": "struct", @@ -492,7 +478,20 @@ { "name": "staking" }, { "name": "voting" } ], - "comment": "https://github.com/firedancer-io/solana/blob/de02601d73d626edf98ef63efd772824746f2f33/sdk/src/reward_type.rs#L5-L11" + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/reward_type.rs#L7" + }, + { + "name": "solana_accounts_db_fields", + "type": "struct", + "fields": [ + { "name": "storages", "type": "vector", "element": "snapshot_slot_acc_vecs" }, + { "name": "version", "type": "ulong" }, + { "name": "slot", "type": "ulong" }, + { "name": "bank_hash_info", "type": "bank_hash_info" }, + { "name": "historical_roots", "type": "vector", "element": "ulong" }, + { "name": "historical_roots_with_hash", "type": "vector", "element": "slot_map_pair" } + ], + "comment": "Accounts DB related fields in a snapshot" }, { "name": "reward_info", @@ -500,11 +499,10 @@ "fields": [ { "name": "reward_type", "type": "reward_type" }, { "name": "lamports", "type": "ulong" }, - { "name": "staker_rewards", "type": "ulong" }, - { "name": "new_credits_observed", "type": "ulong" }, { "name": "post_balance", "type": "ulong" }, - { "name": "commission", "type": "long" } - ] + { "name": "commission", "type": "option", "element": "ulong" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/reward_info.rs#L5" }, { "name": "stake_reward", @@ -515,40 +513,59 @@ ] }, { - "name": "serializable_stake_rewards", + "name": "vote_reward", "type": "struct", "fields": [ - { "name": "body", "type": "vector", "element": "stake_reward" } + { "name": "pubkey", "type": "pubkey" }, + { "name": "vote_rewards", "type": "ulong" }, + { "name": "commission", "type": "uchar" }, + { "name": "needs_store", "type": "uchar" } ] }, { - "name": "start_block_height_and_rewards", + "name": "stake", "type": "struct", "fields": [ - { "name": "start_block_height", "type": "ulong" }, - { "name": "stake_rewards_by_partition", "type": "vector", "element": "serializable_stake_rewards" } - ] + { "name": "delegation", "type": "delegation" }, + { "name": "credits_observed", "type": "ulong" } + ], + "comment": "https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/stake/state.rs#L539" }, { - "name": "serializable_epoch_reward_status", - "type": "enum", - "variants": [ - { "name": "Active", "type": "start_block_height_and_rewards"}, - { "name": "Inactive"} - ] + "name": "partitioned_stake_reward", + "type": "struct", + "fields": [ + { "name": "stake_pubkey", "type": "pubkey" }, + { "name": "stake", "type": "stake" }, + { "name": "stake_reward_info", "type": "reward_info" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L31" }, { - "name": "solana_accounts_db_fields", + "name": "partitioned_stake_rewards", "type": "struct", "fields": [ - { "name": "storages", "type": "vector", "element": "snapshot_slot_acc_vecs" }, - { "name": "version", "type": "ulong" }, - { "name": "slot", "type": "ulong" }, - { "name": "bank_hash_info", "type": "bank_hash_info" }, - { "name": "historical_roots", "type": "vector", "element": "ulong" }, - { "name": "historical_roots_with_hash", "type": "vector", "element": "slot_map_pair" } + { "name": "partition", "type": "vector", "element": "partitioned_stake_reward" } ], - "comment": "Accounts DB related fields in a snapshot" + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L56" + }, + { + "name": "start_block_height_and_rewards", + "type": "struct", + "fields": [ + { "name": "distribution_starting_block_height", "type": "ulong" }, + { "name": "stake_rewards_by_partition", "type": "vector", "element": "partitioned_stake_rewards" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L60" + }, + { + "name": "epoch_reward_status", + "type": "enum", + "variants": [ + { "name": "Active", "type": "start_block_height_and_rewards"}, + { "name": "Inactive" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L70" }, { "name": "solana_manifest", @@ -560,7 +577,7 @@ { "name": "lamports_per_signature", "type": "ulong" }, { "name": "bank_incremental_snapshot_persistence", "type": "option", "element": "bank_incremental_snapshot_persistence", "ignore_underflow": true }, { "name": "epoch_account_hash", "type": "option", "element": "hash", "ignore_underflow": true }, - { "name": "epoch_reward_status", "type": "option", "element": "serializable_epoch_reward_status", "ignore_underflow": true } + { "name": "epoch_reward_status", "type": "option", "element": "epoch_reward_status", "ignore_underflow": true } ] }, { @@ -962,9 +979,15 @@ "name": "sysvar_epoch_rewards", "type": "struct", "fields": [ - { "name": "epoch_rewards", "type": "epoch_rewards" } + { "name": "distribution_starting_block_height", "type": "ulong" }, + { "name": "num_partitions", "type": "ulong" }, + { "name": "parent_blockhash", "type": "hash" }, + { "name": "total_points", "type": "uint128" }, + { "name": "total_rewards", "type": "ulong" }, + { "name": "distributed_rewards", "type": "ulong" }, + { "name": "active", "type": "uchar" } ], - "comment": "https://github.com/solana-labs/solana/blob/a02aebaa4b3aa0b24e13644cf0ffa5ae8bd47e7b/sdk/program/src/sysvar/epoch_rewards.rs" + "comment": "https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/sdk/program/src/epoch_rewards.rs#L14" }, { "name": "config_keys_pair", @@ -1419,15 +1442,6 @@ ], "comment": "https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/stake/state.rs#L248" }, - { - "name": "stake", - "type": "struct", - "fields": [ - { "name": "delegation", "type": "delegation" }, - { "name": "credits_observed", "type": "ulong" } - ], - "comment": "https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/stake/state.rs#L539" - }, { "name": "stake_flags", "type": "struct", @@ -2485,6 +2499,131 @@ "fields": [ { "name": "slot_deltas", "type": "vector", "element": "slot_delta" } ] + }, + { + "name": "pubkey_rewardinfo_pair", + "type": "struct", + "fields": [ + { "name": "pubkey", "type": "pubkey" }, + { "name": "reward_info", "type": "reward_info" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L85" + }, + { + "name": "optional_account", + "type": "struct", + "fields": [ + { "name": "account", "type": "option", "element": "solana_account" } + ] + }, + { + "name": "vote_rewards_accounts", + "type": "struct", + "fields": [ + { "name": "rewards", "type": "vector", "element": "pubkey_rewardinfo_pair" }, + { "name": "accounts_to_store", "type": "vector", "element": "optional_account" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L82" + }, + { + "name": "stake_reward_calculation", + "type": "struct", + "fields": [ + { "name": "stake_reward_deq", "type": "deque", "element": "partitioned_stake_reward", "min": 24 }, + { "name": "total_stake_rewards_lamports", "type": "ulong" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L94" + }, + { + "name": "stake_reward_calculation_partitioned", + "type": "struct", + "fields": [ + { "name": "stake_rewards_by_partition", "type": "vector", "element": "partitioned_stake_rewards" }, + { "name": "total_stake_rewards_lamports", "type": "ulong" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L131" + }, + { + "name": "partitioned_rewards_calculation", + "type": "struct", + "fields": [ + { "name": "vote_reward_map", "type": "map", "element": "vote_reward", "key": "pubkey", "minalloc": 24 }, + { "name": "stake_rewards_by_partition", "type": "stake_reward_calculation_partitioned" }, + { "name": "old_vote_balance_and_staked", "type": "ulong" }, + { "name": "validator_rewards", "type": "ulong" }, + { "name": "validator_rate", "type": "double" }, + { "name": "foundation_rate", "type": "double" }, + { "name": "prev_epoch_duration_in_years", "type": "double" }, + { "name": "capitalization", "type": "ulong" }, + { "name": "total_points", "type": "uint128" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L118" + }, + { + "name": "calculate_rewards_and_distribute_vote_rewards_result", + "type": "struct", + "fields": [ + { "name": "total_rewards", "type": "ulong" }, + { "name": "distributed_rewards", "type": "ulong" }, + { "name": "total_points", "type": "uint128" }, + { "name": "stake_rewards_by_partition", "type": "stake_reward_calculation_partitioned" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L138" + }, + { + "name": "keyed_rewards_and_num_partitions", + "type": "struct", + "fields": [ + { "name": "keyed_rewards", "type": "vector", "element": "pubkey_rewardinfo_pair" }, + { "name": "num_partitions", "type": "option", "element": "ulong" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L154" + }, + { + "name": "calculated_stake_points", + "type": "struct", + "fields": [ + { "name": "points", "type": "uint128" }, + { "name": "new_credits_observed", "type": "ulong" }, + { "name": "force_credits_update_with_skipped_reward", "type": "uchar" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L27" + }, + { + "name": "point_value", + "type": "struct", + "fields": [ + { "name": "rewards", "type": "ulong" }, + { "name": "points", "type": "uint128" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L21" + }, + { + "name": "calculate_stake_vote_rewards_result", + "type": "struct", + "fields": [ + { "name": "stake_reward_calculation", "type": "stake_reward_calculation" }, + { "name": "vote_reward_map", "type": "map", "element": "vote_reward", "key": "vote_pubkey", "minalloc": 24 } + ] + }, + { + "name": "calculated_stake_rewards", + "type": "struct", + "fields": [ + { "name": "staker_rewards", "type": "ulong" }, + { "name": "voter_rewards", "type": "ulong" }, + { "name": "new_credits_observed", "type": "ulong" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/rewards.rs#L24" + }, + { + "name": "calculate_validator_rewards_result", + "type": "struct", + "fields": [ + { "name": "calculate_stake_vote_rewards_result", "type": "calculate_stake_vote_rewards_result" }, + { "name": "total_points", "type": "uint128" } + ], + "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L102" } ] }