From bebdef2ae8c83b5cf390b759cd7e4439927fe4e7 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 14 Oct 2025 13:16:59 +0000 Subject: [PATCH] runtime: cleanup around epoch rewards and stakes --- src/discof/replay/fd_replay_tile.c | 2 +- src/discof/restore/utils/fd_ssload.c | 3 + src/flamenco/rewards/fd_epoch_rewards.c | 201 ++-- src/flamenco/rewards/fd_epoch_rewards.h | 173 ++- src/flamenco/rewards/fd_rewards.c | 834 +++++--------- src/flamenco/rewards/fd_rewards.h | 6 +- src/flamenco/rewards/test_epoch_rewards.c | 94 +- .../runtime/context/fd_exec_txn_ctx.c | 7 +- .../runtime/context/fd_exec_txn_ctx.h | 2 - src/flamenco/runtime/fd_runtime.c | 68 +- .../runtime/program/fd_vote_program.c | 60 +- .../runtime/program/fd_vote_program.h | 3 +- .../runtime/sysvar/fd_sysvar_stake_history.c | 19 +- .../runtime/sysvar/fd_sysvar_stake_history.h | 5 +- .../sysvar/test_sysvar_stake_history.c | 4 +- src/flamenco/runtime/tests/fd_block_harness.c | 2 +- src/flamenco/runtime/tests/fd_txn_harness.c | 3 +- src/flamenco/stakes/fd_stake_delegations.c | 1 - src/flamenco/stakes/fd_stakes.c | 242 ++-- src/flamenco/stakes/fd_stakes.h | 26 +- src/flamenco/stakes/fd_vote_states.c | 3 +- src/flamenco/stakes/fd_vote_states.h | 11 +- src/flamenco/types/fd_fuzz_types.h | 150 +-- src/flamenco/types/fd_types.c | 1021 +---------------- src/flamenco/types/fd_types.h | 328 +----- src/flamenco/types/fd_types.json | 103 +- .../types/fd_types_reflect_generated.c | 13 +- 27 files changed, 689 insertions(+), 2695 deletions(-) diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index 0acfc45da61..83113017347 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -1084,7 +1084,7 @@ init_after_snapshot( fd_replay_tile_t * ctx ) { /* After both snapshots have been loaded in, we can determine if we should start distributing rewards. */ - fd_rewards_recalculate_partitioned_rewards( ctx->banks, bank, ctx->funk, &xid, ctx->capture_ctx, ctx->runtime_spad ); + fd_rewards_recalculate_partitioned_rewards( ctx->banks, bank, ctx->funk, &xid, ctx->capture_ctx ); ulong snapshot_slot = fd_bank_slot_get( bank ); if( FD_UNLIKELY( !snapshot_slot ) ) { diff --git a/src/discof/restore/utils/fd_ssload.c b/src/discof/restore/utils/fd_ssload.c index 5ef7b1f10fc..2300a089e44 100644 --- a/src/discof/restore/utils/fd_ssload.c +++ b/src/discof/restore/utils/fd_ssload.c @@ -166,6 +166,9 @@ fd_ssload_recover( fd_snapshot_manifest_t * manifest, fd_stake_delegations_t * stake_delegations = fd_banks_stake_delegations_root_query( banks ); for( ulong i=0UL; istake_delegations_len; i++ ) { fd_snapshot_manifest_stake_delegation_t const * elem = &manifest->stake_delegations[ i ]; + if( FD_UNLIKELY( elem->stake_delegation==0UL ) ) { + continue; + } fd_stake_delegations_update( stake_delegations, (fd_pubkey_t *)elem->stake_pubkey, diff --git a/src/flamenco/rewards/fd_epoch_rewards.c b/src/flamenco/rewards/fd_epoch_rewards.c index 51ba5639dd3..7d59a500906 100644 --- a/src/flamenco/rewards/fd_epoch_rewards.c +++ b/src/flamenco/rewards/fd_epoch_rewards.c @@ -1,6 +1,19 @@ #include "fd_epoch_rewards.h" #include "../../ballet/siphash13/fd_siphash13.h" +#define POOL_NAME fd_epoch_stake_reward_pool +#define POOL_T fd_epoch_stake_reward_t +#include "../../util/tmpl/fd_pool.c" + +#define MAP_NAME fd_epoch_stake_reward_map +#define MAP_KEY_T fd_pubkey_t +#define MAP_ELE_T fd_epoch_stake_reward_t +#define MAP_KEY stake_pubkey +#define MAP_KEY_EQ(k0,k1) (fd_pubkey_eq( k0, k1 )) +#define MAP_KEY_HASH(key,seed) (fd_hash( seed, key, sizeof(fd_pubkey_t) )) +#define MAP_NEXT next_map +#include "../../util/tmpl/fd_map_chain.c" + ulong fd_epoch_rewards_align( void ) { return FD_EPOCH_REWARDS_ALIGN; @@ -8,9 +21,12 @@ fd_epoch_rewards_align( void ) { ulong fd_epoch_rewards_footprint( ulong stake_account_max ) { + ulong chain_cnt_est = fd_epoch_stake_reward_map_chain_cnt_est( stake_account_max ); + ulong l = FD_LAYOUT_INIT; l = FD_LAYOUT_APPEND( l, fd_epoch_rewards_align(), sizeof(fd_epoch_rewards_t) ); l = FD_LAYOUT_APPEND( l, fd_epoch_stake_reward_pool_align(), fd_epoch_stake_reward_pool_footprint( stake_account_max ) ); + l = FD_LAYOUT_APPEND( l, fd_epoch_stake_reward_map_align(), fd_epoch_stake_reward_map_footprint( chain_cnt_est ) ); l = FD_LAYOUT_APPEND( l, fd_epoch_stake_reward_dlist_align(), fd_epoch_stake_reward_dlist_footprint() * FD_REWARDS_MAX_PARTITIONS ); return FD_LAYOUT_FINI( l, fd_epoch_rewards_align() ); } @@ -30,15 +46,26 @@ fd_epoch_rewards_new( void * shmem, ulong stake_account_max ) { FD_SCRATCH_ALLOC_INIT( l, shmem ); fd_epoch_rewards_t * epoch_rewards = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_rewards_align(), sizeof(fd_epoch_rewards_t) ); + memset( epoch_rewards, 0, sizeof(fd_epoch_rewards_t) ); void * pool = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_stake_reward_pool_align(), fd_epoch_stake_reward_pool_footprint( stake_account_max ) ); + epoch_rewards->pool_offset = (ulong)pool - (ulong)shmem; if( FD_UNLIKELY( !fd_epoch_stake_reward_pool_new( pool, stake_account_max ) ) ) { FD_LOG_WARNING(( "bad pool" )); return NULL; } + ulong chain_cnt_est = fd_epoch_stake_reward_map_chain_cnt_est( stake_account_max ); + void * map = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_stake_reward_map_align(), fd_epoch_stake_reward_map_footprint( chain_cnt_est ) ); + epoch_rewards->map_offset = (ulong)map - (ulong)shmem; + if( FD_UNLIKELY( !fd_epoch_stake_reward_map_new( map, chain_cnt_est, 0UL ) ) ) { + FD_LOG_WARNING(( "bad map" )); + return NULL; + } + for( ulong i=0UL; idlists_offset = (ulong)dlist - (ulong)shmem; if( FD_UNLIKELY( !fd_epoch_stake_reward_dlist_new( dlist ) ) ) { FD_LOG_WARNING(( "bad dlist at idx %lu", i )); return NULL; @@ -50,10 +77,12 @@ fd_epoch_rewards_new( void * shmem, ulong stake_account_max ) { return NULL; } - memset( epoch_rewards, 0, sizeof(fd_epoch_rewards_t) ); - epoch_rewards->magic = FD_EPOCH_REWARDS_MAGIC; - epoch_rewards->stake_account_max_ = stake_account_max; + FD_COMPILER_MFENCE(); + epoch_rewards->magic = FD_EPOCH_REWARDS_MAGIC; + FD_COMPILER_MFENCE(); + + epoch_rewards->stake_account_max = stake_account_max; return shmem; } @@ -72,7 +101,7 @@ fd_epoch_rewards_join( void * shmem ) { FD_SCRATCH_ALLOC_INIT( l, shmem ); fd_epoch_rewards_t * epoch_rewards = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_rewards_align(), sizeof(fd_epoch_rewards_t) ); - ulong stake_account_max = epoch_rewards->stake_account_max_; + ulong stake_account_max = epoch_rewards->stake_account_max; void * pool = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_stake_reward_pool_align(), fd_epoch_stake_reward_pool_footprint( stake_account_max ) ); if( FD_UNLIKELY( !fd_epoch_stake_reward_pool_join( pool ) ) ) { @@ -80,6 +109,13 @@ fd_epoch_rewards_join( void * shmem ) { return NULL; } + ulong chain_cnt_est = fd_epoch_stake_reward_map_chain_cnt_est( stake_account_max ); + void * map = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_stake_reward_map_align(), fd_epoch_stake_reward_map_footprint( chain_cnt_est ) ); + if( FD_UNLIKELY( !fd_epoch_stake_reward_map_join( map ) ) ) { + FD_LOG_WARNING(( "bad map" )); + return NULL; + } + for( ulong i=0UL; i= epoch_rewards->num_partitions_ ) ) { - FD_LOG_WARNING(( "idx: %lu is greater than num_partitions: %lu", idx, epoch_rewards->num_partitions_ )); + if( FD_UNLIKELY( idx>=epoch_rewards->num_partitions ) ) { + FD_LOG_WARNING(( "idx: %lu is greater than num_partitions: %lu", idx, epoch_rewards->num_partitions )); return NULL; } - FD_SCRATCH_ALLOC_INIT( l, epoch_rewards ); - FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_rewards_align(), sizeof(fd_epoch_rewards_t) ); - FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_stake_reward_pool_align(), fd_epoch_stake_reward_pool_footprint( epoch_rewards->stake_account_max_ ) ); - for( ulong i=0UL; idlists_offset); + fd_epoch_stake_reward_dlist_t * partition_dlist = fd_epoch_stake_reward_dlist_join( dlist_idx_zero + idx ); return partition_dlist; } -fd_epoch_stake_reward_t * +static inline fd_epoch_stake_reward_t * fd_epoch_rewards_get_stake_reward_pool( fd_epoch_rewards_t const * epoch_rewards ) { - if( FD_UNLIKELY( !epoch_rewards ) ) { - FD_LOG_WARNING(( "NULL epoch_rewards" )); - return NULL; - } + return fd_epoch_stake_reward_pool_join( (uchar *)epoch_rewards + epoch_rewards->pool_offset ); +} - FD_SCRATCH_ALLOC_INIT( l, epoch_rewards ); - FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_rewards_align(), sizeof(fd_epoch_rewards_t) ); - void * pool = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_stake_reward_pool_align(), fd_epoch_stake_reward_pool_footprint( epoch_rewards->stake_account_max_ ) ); - fd_epoch_stake_reward_t * stake_reward_pool = fd_epoch_stake_reward_pool_join( pool ); - if( FD_UNLIKELY( !stake_reward_pool ) ) { - FD_LOG_WARNING(( "bad stake_reward_pool" )); - return NULL; - } - return stake_reward_pool; +static inline fd_epoch_stake_reward_map_t * +fd_epoch_rewards_get_stake_reward_map( fd_epoch_rewards_t const * epoch_rewards ) { + return fd_epoch_stake_reward_map_join( (uchar *)epoch_rewards + epoch_rewards->map_offset ); } -int -fd_epoch_rewards_hash_and_insert( fd_epoch_rewards_t * epoch_rewards, - fd_hash_t const * parent_blockhash, - fd_pubkey_t const * pubkey, - ulong credits, - ulong lamports ) { +void +fd_epoch_rewards_insert( fd_epoch_rewards_t * epoch_rewards, + fd_pubkey_t const * pubkey, + ulong credits, + ulong lamports ) { + fd_epoch_stake_reward_t * stake_reward_pool = fd_epoch_rewards_get_stake_reward_pool( epoch_rewards ); + fd_epoch_stake_reward_map_t * stake_reward_map = fd_epoch_rewards_get_stake_reward_map( epoch_rewards ); - if( FD_UNLIKELY( !epoch_rewards ) ) { - FD_LOG_WARNING(( "NULL epoch_rewards" )); - return 1; + if( FD_UNLIKELY( fd_epoch_stake_reward_map_ele_query( stake_reward_map, pubkey, NULL, stake_reward_pool ) ) ) { + FD_LOG_CRIT(( "invariant violation: stake reward entry already exists" )); } - if( FD_UNLIKELY( !parent_blockhash ) ) { - FD_LOG_WARNING(( "NULL parent_blockhash" )); - return 1; - } + fd_epoch_stake_reward_t * stake_reward = fd_epoch_stake_reward_pool_ele_acquire( stake_reward_pool ); - if( FD_UNLIKELY( !pubkey ) ) { - FD_LOG_WARNING(( "NULL pubkey" )); - return 1; - } + stake_reward->stake_pubkey = *pubkey; + stake_reward->credits_observed = credits; + stake_reward->lamports = lamports; - /* First figure out which partition the pubkey belongs to. */ - fd_siphash13_t sip[1] = {0}; - fd_siphash13_t * hasher = fd_siphash13_init( sip, 0UL, 0UL ); + fd_epoch_stake_reward_map_ele_insert( stake_reward_map, stake_reward, stake_reward_pool ); - hasher = fd_siphash13_append( hasher, parent_blockhash->hash, sizeof(fd_hash_t) ); - fd_siphash13_append( hasher, (uchar const *)pubkey, sizeof(fd_pubkey_t) ); - ulong hash64 = fd_siphash13_fini( hasher ); + epoch_rewards->total_stake_rewards += lamports; + epoch_rewards->stake_rewards_cnt++; - /* Now get the correct dlist based on the hash. */ - ulong partition_index = (ulong)((uint128)epoch_rewards->num_partitions_ * (uint128) hash64 / ((uint128)ULONG_MAX + 1)); +} - fd_epoch_stake_reward_dlist_t * partition_dlist = fd_epoch_rewards_get_partition_index( epoch_rewards, partition_index ); - if( FD_UNLIKELY( !partition_dlist ) ) { - FD_LOG_WARNING(( "bad partition_dlist" )); - return 1; - } +void +fd_epoch_rewards_hash_into_partitions( fd_epoch_rewards_t * epoch_rewards, + fd_hash_t const * parent_blockhash, + ulong num_partitions ) { - /* Acquire a stake reward from the pool's free list and add it to - the tail of the dlist. */ - fd_epoch_stake_reward_t * stake_reward_pool = fd_epoch_rewards_get_stake_reward_pool( epoch_rewards ); - if( FD_UNLIKELY( !stake_reward_pool ) ) { - FD_LOG_WARNING(( "bad stake_reward_pool" )); - return 1; - } + fd_epoch_stake_reward_t * stake_reward_pool = fd_epoch_rewards_get_stake_reward_pool( epoch_rewards ); + fd_epoch_stake_reward_map_t * stake_reward_map = fd_epoch_rewards_get_stake_reward_map( epoch_rewards ); - if( FD_UNLIKELY( !fd_epoch_stake_reward_pool_free( stake_reward_pool ) ) ) { - FD_LOG_WARNING(( "stake_reward_pool is full" )); - return 1; - } + epoch_rewards->num_partitions = num_partitions; - fd_epoch_stake_reward_t * stake_reward = fd_epoch_stake_reward_pool_ele_acquire( stake_reward_pool ); - if( FD_UNLIKELY( !stake_reward ) ) { - FD_LOG_WARNING(( "bad stake_reward" )); - return 1; + for( fd_epoch_stake_reward_map_iter_t iter = fd_epoch_stake_reward_map_iter_init( stake_reward_map, stake_reward_pool ); + !fd_epoch_stake_reward_map_iter_done( iter, stake_reward_map, stake_reward_pool ); + iter = fd_epoch_stake_reward_map_iter_next( iter, stake_reward_map, stake_reward_pool ) ) { + + fd_epoch_stake_reward_t * stake_reward = fd_epoch_stake_reward_map_iter_ele( iter, stake_reward_map, stake_reward_pool ); + + fd_siphash13_t sip[1] = {0}; + fd_siphash13_t * hasher = fd_siphash13_init( sip, 0UL, 0UL ); + hasher = fd_siphash13_append( hasher, parent_blockhash->hash, sizeof(fd_hash_t) ); + fd_siphash13_append( hasher, (uchar const *)stake_reward->stake_pubkey.uc, sizeof(fd_pubkey_t) ); + ulong hash64 = fd_siphash13_fini( hasher ); + + /* Now get the correct dlist based on the hash. */ + ulong partition_index = (ulong)((uint128)num_partitions * (uint128) hash64 / ((uint128)ULONG_MAX + 1)); + + fd_epoch_stake_reward_dlist_t * partition_dlist = fd_epoch_rewards_get_partition_index( epoch_rewards, partition_index ); + + fd_epoch_stake_reward_dlist_ele_push_tail( partition_dlist, stake_reward, stake_reward_pool ); } +} - stake_reward->stake_pubkey = *pubkey; - stake_reward->credits_observed = credits; - stake_reward->lamports = lamports; +fd_epoch_stake_reward_t * +fd_epoch_rewards_iter_ele( fd_epoch_rewards_iter_t * iter ) { + return fd_epoch_stake_reward_dlist_iter_ele( iter->iter, iter->dlist, iter->pool ); +} + +fd_epoch_rewards_iter_t * +fd_epoch_rewards_iter_init( fd_epoch_rewards_iter_t * iter, + fd_epoch_rewards_t const * epoch_rewards, + ulong partition_idx ) { + iter->pool = fd_epoch_rewards_get_stake_reward_pool( epoch_rewards ); + iter->dlist = fd_epoch_rewards_get_partition_index( epoch_rewards, partition_idx ); + iter->iter = fd_epoch_stake_reward_dlist_iter_fwd_init( iter->dlist, iter->pool ); + return iter; +} - fd_epoch_stake_reward_dlist_ele_push_tail( partition_dlist, stake_reward, stake_reward_pool ); - return 0; +int +fd_epoch_rewards_iter_done( fd_epoch_rewards_iter_t * iter ) { + return fd_epoch_stake_reward_dlist_iter_done( iter->iter, iter->dlist, iter->pool ); } +void +fd_epoch_rewards_iter_next( fd_epoch_rewards_iter_t * iter ) { + iter->iter = fd_epoch_stake_reward_dlist_iter_fwd_next( iter->iter, iter->dlist, iter->pool ); +} diff --git a/src/flamenco/rewards/fd_epoch_rewards.h b/src/flamenco/rewards/fd_epoch_rewards.h index 69342f5d770..91de74b0685 100644 --- a/src/flamenco/rewards/fd_epoch_rewards.h +++ b/src/flamenco/rewards/fd_epoch_rewards.h @@ -63,45 +63,66 @@ FD_STATIC_ASSERT( FD_REWARDS_MAX_PARTITIONS <= FD_RUNTIME_SLOTS_PER_EPOCH / MAX_ #define FD_EPOCH_REWARDS_MAGIC (0x122400081001UL) struct fd_epoch_stake_reward { - ulong prev; - ulong next; - ulong parent; fd_pubkey_t stake_pubkey; ulong credits_observed; ulong lamports; + /* Internal pointers for pool, dlist, and map. */ + ulong prev; + ulong next; + ulong parent; + ulong next_map; }; typedef struct fd_epoch_stake_reward fd_epoch_stake_reward_t; -#define POOL_NAME fd_epoch_stake_reward_pool -#define POOL_T fd_epoch_stake_reward_t -#include "../../util/tmpl/fd_pool.c" +/* TODO: Need to move the dlist into the .c file. There needs to be a + way to forward declare the iterator (see fd_map.h). */ #define DLIST_NAME fd_epoch_stake_reward_dlist #define DLIST_ELE_T fd_epoch_stake_reward_t #include "../../util/tmpl/fd_dlist.c" +struct fd_epoch_rewards_iter { + fd_epoch_stake_reward_t * pool; + void * dlist; + fd_epoch_stake_reward_dlist_iter_t iter; +}; +typedef struct fd_epoch_rewards_iter fd_epoch_rewards_iter_t; + struct fd_epoch_rewards { ulong magic; /* Data representing the partitioned stake rewards */ - int is_active_; - ulong stake_account_max_; - ulong starting_block_height_; - ulong num_partitions_; - ulong partitions_lengths_[FD_REWARDS_MAX_PARTITIONS]; + ulong stake_account_max; + ulong starting_block_height; + ulong num_partitions; + ulong partitions_lengths[FD_REWARDS_MAX_PARTITIONS]; /* Result of total rewards distribution */ /* Total rewards for the epoch (including both vote rewards and stake rewards) */ - ulong total_rewards_; + ulong total_rewards; + /* total rewards points calculated for the current epoch, where points equals the sum of (delegated stake * credits observed) for all delegations */ - ulong distributed_rewards_; + ulong distributed_rewards; + /* Stake rewards that still need to be distributed, grouped by partition */ - uint128 total_points_; + uint128 total_points; + + /* Total stake rewards to distribute as calculated during the epoch + boundary */ + ulong total_stake_rewards; + + /* Total number of stake accounts that have rewards to distribute */ + ulong stake_rewards_cnt; + + /* Internal pointers for pool, dlist, and map. */ + ulong pool_offset; + ulong map_offset; + ulong dlists_offset; /* This will be followed by a pool of fd_epoch_stake_reward_t. This pool will be sized out to FD_BANKS_MAX_STAKE_ACCOUNTS. */ @@ -147,107 +168,63 @@ fd_epoch_rewards_leave( fd_epoch_rewards_t const * epoch_rewards ); void * fd_epoch_rewards_delete( void * epoch_rewards ); -/* fd_epoch_rewards_get_partition_index returns a pointer to the dlist - of stake rewards for the given partition index. */ - -fd_epoch_stake_reward_dlist_t * -fd_epoch_rewards_get_partition_index( fd_epoch_rewards_t const * epoch_rewards, ulong idx ); +/* fd_epoch_rewards_insert stores the rewards for a given stake account + into the data structure. */ -/* fd_epoch_rewards_get_stake_reward_pool returns a pointer to the pool - of stake rewards. */ - -fd_epoch_stake_reward_t * -fd_epoch_rewards_get_stake_reward_pool( fd_epoch_rewards_t const * epoch_rewards ); +void +fd_epoch_rewards_insert( fd_epoch_rewards_t * epoch_rewards, + fd_pubkey_t const * pubkey, + ulong credits, + ulong lamports ); -/* fd_epoch_rewards_hash_and_insert determines the hash partition that - the stake pubkey belongs in and stores the pubkey along with the - total amount of credits and lamports. */ +/* fd_epoch_rewards_hash_into_partitions hashes all of the stake + accounts into the appropriate partitions. */ -int -fd_epoch_rewards_hash_and_insert( fd_epoch_rewards_t * epoch_rewards, - fd_hash_t const * parent_blockhash, - fd_pubkey_t const * pubkey, - ulong credits, - ulong lamports ); +void +fd_epoch_rewards_hash_into_partitions( fd_epoch_rewards_t * epoch_rewards, + fd_hash_t const * parent_blockhash, + ulong num_partitions ); /* fd_epoch_rewards_get_distribution_partition_index determines the hash partition that the current block belongs in. */ ulong -fd_epoch_rewards_get_distribution_partition_index( fd_epoch_rewards_t const * epoch_rewards, ulong curr_block_height ); - -/* Simple inline mutator functions */ +fd_epoch_rewards_get_distribution_partition_index( fd_epoch_rewards_t const * epoch_rewards, + ulong curr_block_height ); -static void FD_FN_UNUSED -fd_epoch_rewards_set_active( fd_epoch_rewards_t * epoch_rewards, int is_active ) { - epoch_rewards->is_active_ = is_active; -} - -static void FD_FN_UNUSED -fd_epoch_rewards_set_starting_block_height( fd_epoch_rewards_t * epoch_rewards, ulong block_height ) { - epoch_rewards->starting_block_height_ = block_height; -} +/* fd_epoch_rewards_get_exclusive_ending_block_height returns the + block height that the last partition ends at. */ -static void FD_FN_UNUSED -fd_epoch_rewards_set_num_partitions( fd_epoch_rewards_t * epoch_rewards, ulong num_partitions ) { - if( FD_UNLIKELY( num_partitions>FD_REWARDS_MAX_PARTITIONS ) ) { - FD_LOG_WARNING(( "num_partitions: %lu is greater than FD_REWARDS_MAX_PARTITIONS: %lu", num_partitions, FD_REWARDS_MAX_PARTITIONS )); - return; - } - epoch_rewards->num_partitions_ = num_partitions; -} - -static void FD_FN_UNUSED -fd_epoch_rewards_set_distributed_rewards( fd_epoch_rewards_t * epoch_rewards, ulong distributed_rewards ) { - epoch_rewards->distributed_rewards_ = distributed_rewards; -} - -static void FD_FN_UNUSED -fd_epoch_rewards_set_total_rewards( fd_epoch_rewards_t * epoch_rewards, ulong total_rewards ) { - epoch_rewards->total_rewards_ = total_rewards; -} - -static void FD_FN_UNUSED -fd_epoch_rewards_set_total_points( fd_epoch_rewards_t * epoch_rewards, uint128 total_points ) { - epoch_rewards->total_points_ = total_points; -} - -/* Simple inline accessor functions */ - -static int FD_FN_UNUSED -fd_epoch_rewards_is_active( fd_epoch_rewards_t const * epoch_rewards ) { - return epoch_rewards->is_active_; +static inline ulong +fd_epoch_rewards_get_exclusive_ending_block_height( fd_epoch_rewards_t const * epoch_rewards ) { + return epoch_rewards->starting_block_height + epoch_rewards->num_partitions; } -static ulong FD_FN_UNUSED -fd_epoch_rewards_get_num_partitions( fd_epoch_rewards_t const * epoch_rewards ) { - return epoch_rewards->num_partitions_; -} +/* Iterator API for epoch rewards. The iterator is initialized with a + call to fd_epoch_rewards_iter_init. The caller is responsible for + managing the memory for the iterator. It is safe to call + fd_epoch_rewards_iter_next if the result of + fd_epoch_rewards_iter_done() ==0. It is safe to call + fd_epoch_rewards_iter_ele() to get the current epoch reward. + Elements that are iterated over are not safe to modify. -static ulong FD_FN_UNUSED -fd_epoch_rewards_get_starting_block_height( fd_epoch_rewards_t const * epoch_rewards ) { - return epoch_rewards->starting_block_height_; -} + Under the hood, the iterator is just a wrapper over the iterator used + by the underlying dlist. +*/ -static ulong FD_FN_UNUSED -fd_epoch_rewards_get_exclusive_ending_block_height( fd_epoch_rewards_t const * epoch_rewards ) { - return epoch_rewards->starting_block_height_ + epoch_rewards->num_partitions_; -} +fd_epoch_stake_reward_t * +fd_epoch_rewards_iter_ele( fd_epoch_rewards_iter_t * iter ); -static ulong FD_FN_UNUSED -fd_epoch_rewards_get_distributed_rewards( fd_epoch_rewards_t const * epoch_rewards ) { - return epoch_rewards->distributed_rewards_; -} +fd_epoch_rewards_iter_t * +fd_epoch_rewards_iter_init( fd_epoch_rewards_iter_t * iter, + fd_epoch_rewards_t const * epoch_rewards, + ulong partition_idx ); -static uint128 FD_FN_UNUSED -fd_epoch_rewards_get_total_points( fd_epoch_rewards_t const * epoch_rewards ) { - return epoch_rewards->total_points_; -} +int +fd_epoch_rewards_iter_done( fd_epoch_rewards_iter_t * iter ); -static ulong FD_FN_UNUSED -fd_epoch_rewards_get_total_rewards( fd_epoch_rewards_t const * epoch_rewards ) { - return epoch_rewards->total_rewards_; -} +void +fd_epoch_rewards_iter_next( fd_epoch_rewards_iter_t * iter ); FD_PROTOTYPES_END diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index 6405ca6b26b..6efadbfa8b2 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -11,6 +11,7 @@ #include "../runtime/sysvar/fd_sysvar_stake_history.h" #include "../runtime/context/fd_capture_ctx.h" #include "../runtime/fd_runtime.h" +#include "fd_epoch_rewards.h" /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/inflation.rs#L85 */ static double @@ -168,43 +169,48 @@ calculate_stake_points_and_credits( fd_stake_history_t const * stake_history result->force_credits_update_with_skipped_reward = 0; } -/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/rewards.rs#L127 */ +/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/rewards.rs#L33 */ static int -calculate_stake_rewards( fd_stake_history_t const * stake_history, - fd_stake_delegation_t const * stake, - fd_vote_state_ele_t const * vote_state, - ulong rewarded_epoch, - fd_point_value_t * point_value, - ulong * new_rate_activation_epoch, - fd_calculated_stake_rewards_t * result ) { - fd_calculated_stake_points_t stake_points_result = {0}; +redeem_rewards( fd_stake_history_t const * stake_history, + fd_stake_delegation_t const * stake, + fd_vote_state_ele_t const * vote_state, + ulong rewarded_epoch, + ulong total_rewards, + uint128 total_points, + ulong * new_rate_activation_epoch, + fd_calculated_stake_rewards_t * result ) { + + /* The firedancer implementation of redeem_rewards inlines a lot of + the helper functions that the Agave implementation uses. + In Agave: redeem_rewards calls redeem_stake_rewards which calls + calculate_stake_rewards. */ + fd_calculated_stake_points_t stake_points_result = {0}; calculate_stake_points_and_credits( stake_history, stake, vote_state, new_rate_activation_epoch, - &stake_points_result); + &stake_points_result ); // Drive credits_observed forward unconditionally when rewards are disabled // or when this is the stake's activation epoch - if( ( point_value->rewards==0UL ) || - ( stake->activation_epoch==rewarded_epoch ) ) { - stake_points_result.force_credits_update_with_skipped_reward |= 1; + if( total_rewards==0UL || stake->activation_epoch==rewarded_epoch ) { + stake_points_result.force_credits_update_with_skipped_reward = 1; } if( stake_points_result.force_credits_update_with_skipped_reward ) { - result->staker_rewards = 0; - result->voter_rewards = 0; + result->staker_rewards = 0; + result->voter_rewards = 0; result->new_credits_observed = stake_points_result.new_credits_observed; return 0; } - if( stake_points_result.points == 0 || point_value->points == 0 ) { + if( stake_points_result.points==0 || total_points==0 ) { return 1; } /* 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); + ulong rewards = (ulong)(stake_points_result.points * (uint128)(total_rewards) / (uint128) total_points); if( rewards == 0 ) { return 1; } @@ -215,37 +221,12 @@ calculate_stake_rewards( fd_stake_history_t const * stake_history, return 1; } - result->staker_rewards = split_result.staker_portion; - result->voter_rewards = split_result.voter_portion; + result->staker_rewards = split_result.staker_portion; + result->voter_rewards = split_result.voter_portion; result->new_credits_observed = stake_points_result.new_credits_observed; return 0; } -/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/rewards.rs#L33 */ -static int -redeem_rewards( fd_stake_history_t const * stake_history, - fd_stake_delegation_t const * stake, - fd_vote_state_ele_t const * vote_state, - ulong rewarded_epoch, - fd_point_value_t * point_value, - ulong * new_rate_activation_epoch, - fd_calculated_stake_rewards_t * calculated_stake_rewards ) { - - int rc = calculate_stake_rewards( - stake_history, - stake, - vote_state, - rewarded_epoch, - point_value, - new_rate_activation_epoch, - 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 */ static int calculate_points( fd_stake_delegation_t const * stake, @@ -312,12 +293,27 @@ get_minimum_stake_delegation( fd_bank_t * bank ) { return 1; } +/* Calculates epoch reward points from stake/vote accounts. + https://github.com/anza-xyz/agave/blob/v2.3.1/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L445 */ static uint128 -calculate_points_all( fd_bank_t * bank, - fd_stake_delegations_t const * stake_delegations, - fd_stake_history_t const * stake_history, - ulong * new_warmup_cooldown_rate_epoch, - ulong minimum_stake_delegation ) { +calculate_reward_points_partitioned( fd_bank_t * bank, + fd_stake_delegations_t const * stake_delegations, + fd_stake_history_t const * stake_history ) { + ulong minimum_stake_delegation = get_minimum_stake_delegation( bank ); + + /* Calculate the points for each stake delegation */ + int _err[1]; + ulong new_warmup_cooldown_rate_epoch_val = 0UL; + ulong * new_warmup_cooldown_rate_epoch = &new_warmup_cooldown_rate_epoch_val; + int is_some = fd_new_warmup_cooldown_rate_epoch( + fd_bank_epoch_schedule_query( bank ), + fd_bank_features_query( bank ), + fd_bank_slot_get( bank ), + new_warmup_cooldown_rate_epoch, + _err ); + if( FD_UNLIKELY( !is_some ) ) { + new_warmup_cooldown_rate_epoch = NULL; + } uint128 total_points = 0; @@ -357,17 +353,32 @@ calculate_points_all( fd_bank_t * bank, return total_points; } -/* 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 */ +/* Calculates epoch rewards for stake/vote accounts. + Returns vote rewards, stake rewards, and the sum of all stake rewards + in lamports. + + In the future, the calculation will be cached in the snapshot, but + for now we just re-calculate it (as Agave does). + calculate_stake_vote_rewards is responsible for calculating + stake account rewards based off of a combination of the + stake delegation state as well as the vote account. If this + calculation is done at the end of an epoch, we can just use the + vote states at the end of the current epoch. However, because we + are presumably booting up a node in the middle of rewards + distribution, we need to make sure that we are using the vote + states from the end of the previous epoch. + + https://github.com/anza-xyz/agave/blob/v2.3.1/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L323 */ static void -calculate_reward_points_partitioned( fd_bank_t * bank, - fd_stake_delegations_t const * stake_delegations, - fd_stake_history_t const * stake_history, - ulong rewards, - fd_point_value_t * result ) { - ulong minimum_stake_delegation = get_minimum_stake_delegation( bank ); +calculate_stake_vote_rewards( fd_bank_t * bank, + fd_stake_delegations_t const * stake_delegations, + fd_capture_ctx_t * capture_ctx, + fd_stake_history_t const * stake_history, + ulong rewarded_epoch, + ulong total_rewards, + uint128 total_points, + int is_recalculation ) { - /* Calculate the points for each stake delegation */ int _err[1]; ulong new_warmup_cooldown_rate_epoch_val = 0UL; ulong * new_warmup_cooldown_rate_epoch = &new_warmup_cooldown_rate_epoch_val; @@ -381,52 +392,13 @@ calculate_reward_points_partitioned( fd_bank_t * bank, new_warmup_cooldown_rate_epoch = NULL; } - uint128 points = calculate_points_all( - bank, - stake_delegations, - stake_history, - new_warmup_cooldown_rate_epoch, - minimum_stake_delegation ); - - if( points > 0 ) { - result->points = points; - result->rewards = rewards; - } -} - -static void -calculate_stake_vote_rewards_account( fd_bank_t * bank, - fd_stake_delegations_t const * stake_delegations, - fd_capture_ctx_t const * capture_ctx, - fd_stake_history_t const * stake_history, - ulong const rewarded_epoch, - ulong * new_warmup_cooldown_rate_epoch, - fd_point_value_t * point_value, - fd_calculate_stake_vote_rewards_result_t * result, - fd_spad_t * spad, - int is_recalculation ) { - - FD_SPAD_FRAME_BEGIN( spad ) { ulong minimum_stake_delegation = get_minimum_stake_delegation( bank ); - ulong total_stake_rewards = 0UL; - ulong dlist_additional_cnt = 0UL; ulong stake_delegation_cnt = fd_stake_delegations_cnt( stake_delegations ); - /* Build a local vote reward map */ - fd_vote_reward_t_mapnode_t * vote_reward_map_pool = fd_vote_reward_t_map_join( fd_vote_reward_t_map_new( fd_spad_alloc( - spad, fd_vote_reward_t_map_align(), fd_vote_reward_t_map_footprint( stake_delegation_cnt ) ), stake_delegation_cnt ) ); - fd_vote_reward_t_mapnode_t * vote_reward_map_root = NULL; + fd_vote_states_t * vote_states = !!is_recalculation ? fd_bank_vote_states_prev_locking_modify( bank ) : fd_bank_vote_states_locking_modify( bank ); - fd_vote_states_t const * vote_states = NULL; - if( !is_recalculation ) { - vote_states = fd_bank_vote_states_locking_query( bank ); - } else { - vote_states = fd_bank_vote_states_prev_locking_query( bank ); - } - if( FD_UNLIKELY( !vote_states ) ) { - FD_LOG_CRIT(( "vote_states is NULL" )); - } + fd_epoch_rewards_t * epoch_rewards = fd_epoch_rewards_join( fd_epoch_rewards_new( fd_bank_epoch_rewards_locking_modify( bank ), stake_delegation_cnt ) ); fd_stake_delegations_iter_t iter_[1]; for( fd_stake_delegations_iter_t * iter = fd_stake_delegations_iter_init( iter_, stake_delegations ); @@ -443,19 +415,20 @@ calculate_stake_vote_rewards_account( fd_bank_t * fd_pubkey_t const * voter_acc = &stake_delegation->vote_account; fd_vote_state_ele_t * vote_state_ele = fd_vote_states_query( vote_states, voter_acc ); if( FD_UNLIKELY( !vote_state_ele ) ) { - FD_LOG_DEBUG(( "failed to query vote state" )); continue; } - /* Note, this doesn't actually redeem any rewards.. this is a misnomer. */ + /* redeem_rewards is actually just responisble for calculating the + vote and stake rewards for each stake account. It does not do + rewards redemption: it is a misnomer. */ fd_calculated_stake_rewards_t calculated_stake_rewards[1] = {0}; - int err = redeem_rewards( stake_history, stake_delegation, vote_state_ele, rewarded_epoch, - point_value, + total_rewards, + total_points, new_warmup_cooldown_rate_epoch, calculated_stake_rewards ); @@ -474,216 +447,49 @@ calculate_stake_vote_rewards_account( fd_bank_t * (long)calculated_stake_rewards->new_credits_observed ); } - // Find and update the vote reward node in the local map - fd_vote_reward_t_mapnode_t vote_map_key[1]; - vote_map_key->elem.pubkey = *voter_acc; - 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( FD_UNLIKELY( vote_reward_node==NULL ) ) { - FD_LOG_WARNING(( "vote account is missing from the vote rewards pool" )); - continue; - } - - vote_reward_node = fd_vote_reward_t_map_find( vote_reward_map_pool, vote_reward_map_root, vote_map_key ); - - if( vote_reward_node==NULL ) { - vote_reward_node = fd_vote_reward_t_map_acquire( vote_reward_map_pool ); - vote_reward_node->elem.pubkey = *voter_acc; - vote_reward_node->elem.commission = vote_state_ele->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( vote_reward_map_pool, &vote_reward_map_root, vote_reward_node ); - } else { - vote_reward_node->elem.vote_rewards += calculated_stake_rewards->voter_rewards; - } - - /* Add the stake reward to list of all stake rewards. The update is - thread-safe because each index in the dlist is only ever accessed - / written to once among all threads. */ - - - if( FD_UNLIKELY( !fd_stake_reward_calculation_pool_free( result->stake_reward_calculation.pool ) ) ) { - FD_LOG_CRIT(( "insufficient space allocated for stake reward calculation pool" )); - } - fd_stake_reward_t * stake_reward = fd_stake_reward_calculation_pool_ele_acquire( result->stake_reward_calculation.pool ); - - fd_memcpy( stake_reward->stake_pubkey.uc, &stake_delegation->stake_account, sizeof(fd_pubkey_t) ); - stake_reward->lamports = calculated_stake_rewards->staker_rewards; - stake_reward->credits_observed = calculated_stake_rewards->new_credits_observed; - stake_reward->valid = 1; - - /* Update the total stake rewards */ - total_stake_rewards += calculated_stake_rewards->staker_rewards; - dlist_additional_cnt++; - - fd_stake_reward_calculation_dlist_ele_push_tail( result->stake_reward_calculation.stake_rewards, stake_reward, result->stake_reward_calculation.pool ); - } - - if( !is_recalculation ) { - fd_bank_vote_states_end_locking_query( bank ); - } else { - fd_bank_vote_states_prev_end_locking_query( bank ); - } - - /* Merge vote rewards with result after */ - for( fd_vote_reward_t_mapnode_t * vote_reward_node = fd_vote_reward_t_map_minimum( vote_reward_map_pool, vote_reward_map_root ); - vote_reward_node; - vote_reward_node = fd_vote_reward_t_map_successor( vote_reward_map_pool, vote_reward_node ) ) { - - fd_vote_reward_t_mapnode_t * result_reward_node = fd_vote_reward_t_map_find( result->vote_reward_map_pool, result->vote_reward_map_root, vote_reward_node ); - result_reward_node->elem.commission = vote_reward_node->elem.commission; - result_reward_node->elem.vote_rewards += vote_reward_node->elem.vote_rewards; - result_reward_node->elem.needs_store = 1; - } - - result->stake_reward_calculation.total_stake_rewards_lamports += total_stake_rewards; - result->stake_reward_calculation.stake_rewards_len += dlist_additional_cnt; - - } FD_SPAD_FRAME_END; - - -} - -/* Calculates epoch rewards for stake/vote accounts. - Returns vote rewards, stake rewards, and the sum of all stake rewards - in lamports. - - In future, the calculation will be cached in the snapshot, but - for now we just re-calculate it (as Agave does). - calculate_stake_vote_rewards is responsible for calculating - stake account rewards based off of a combination of the - stake delegation state as well as the vote account. If this - calculation is done at the end of an epoch, we can just use the - vote states at the end of the current epoch. However, because we - are presumably booting up a node in the middle of rewards - distribution, we need to make sure that we are using the vote - states from the end of the previous epoch. - - https://github.com/anza-xyz/agave/blob/v2.3.1/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L323 */ -static void -calculate_stake_vote_rewards( fd_bank_t * bank, - fd_stake_delegations_t const * stake_delegations, - fd_capture_ctx_t * capture_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, - fd_spad_t * runtime_spad, - int is_recalculation ) { - - int _err[1]; - ulong new_warmup_cooldown_rate_epoch_val = 0UL; - ulong * new_warmup_cooldown_rate_epoch = &new_warmup_cooldown_rate_epoch_val; - int is_some = fd_new_warmup_cooldown_rate_epoch( - fd_bank_epoch_schedule_query( bank ), - fd_bank_features_query( bank ), - fd_bank_slot_get( bank ), - new_warmup_cooldown_rate_epoch, - _err ); - if( FD_UNLIKELY( !is_some ) ) { - new_warmup_cooldown_rate_epoch = NULL; - } - - ulong rewards_max_count = fd_stake_delegations_cnt( stake_delegations ); - - /* Create the stake rewards pool and dlist. The pool will be destoyed after the stake rewards have been distributed. */ - result->stake_reward_calculation.pool = fd_stake_reward_calculation_pool_join( fd_stake_reward_calculation_pool_new( fd_spad_alloc( runtime_spad, - fd_stake_reward_calculation_pool_align(), - fd_stake_reward_calculation_pool_footprint( rewards_max_count ) ), - rewards_max_count ) ); - result->stake_reward_calculation.stake_rewards = fd_spad_alloc( runtime_spad, - fd_stake_reward_calculation_dlist_align(), - fd_stake_reward_calculation_dlist_footprint() ); - - fd_stake_reward_calculation_dlist_new( result->stake_reward_calculation.stake_rewards ); - result->stake_reward_calculation.stake_rewards_len = 0UL; - - fd_vote_states_t const * vote_states = NULL; - if( !is_recalculation ) { - vote_states = fd_bank_vote_states_locking_query( bank ); - } else { - vote_states = fd_bank_vote_states_prev_locking_query( bank ); - } - if( FD_UNLIKELY( !vote_states ) ) { - FD_LOG_CRIT(( "vote_states is NULL" )); - } - - /* Create the vote rewards map. This will be destroyed after the vote rewards have been distributed. */ - ulong vote_account_cnt = fd_vote_states_cnt( vote_states ); - result->vote_reward_map_pool = fd_vote_reward_t_map_join( fd_vote_reward_t_map_new( fd_spad_alloc( runtime_spad, - fd_vote_reward_t_map_align(), - fd_vote_reward_t_map_footprint( vote_account_cnt )), - vote_account_cnt ) ); - result->vote_reward_map_root = NULL; - - /* Pre-fill the vote pubkeys in the vote rewards map pool */ - fd_vote_states_iter_t iter_[1]; - for( fd_vote_states_iter_t * iter = fd_vote_states_iter_init( iter_, vote_states ); !fd_vote_states_iter_done( iter ); fd_vote_states_iter_next( iter ) ) { - fd_vote_state_ele_t const * vote_state = fd_vote_states_iter_ele( iter ); - - fd_vote_reward_t_mapnode_t * vote_reward_node = fd_vote_reward_t_map_acquire( result->vote_reward_map_pool ); + vote_state_ele->rewards += calculated_stake_rewards->voter_rewards; - vote_reward_node->elem.pubkey = vote_state->vote_account; - vote_reward_node->elem.vote_rewards = 0UL; - vote_reward_node->elem.needs_store = 0; - - fd_vote_reward_t_map_insert( result->vote_reward_map_pool, &result->vote_reward_map_root, vote_reward_node ); + fd_epoch_rewards_insert( epoch_rewards, &stake_delegation->stake_account, calculated_stake_rewards->new_credits_observed, calculated_stake_rewards->staker_rewards ); } - if( !is_recalculation ) { - fd_bank_vote_states_end_locking_query( bank ); - } else { - fd_bank_vote_states_prev_end_locking_query( bank ); - } + fd_bank_epoch_rewards_end_locking_modify( bank ); - /* Loop over all the delegations - https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L367 */ - calculate_stake_vote_rewards_account( - bank, - stake_delegations, - capture_ctx, - stake_history, - rewarded_epoch, - new_warmup_cooldown_rate_epoch, - point_value, - result, - runtime_spad, - is_recalculation ); + !!is_recalculation ? fd_bank_vote_states_prev_end_locking_modify( bank ) : fd_bank_vote_states_end_locking_modify( bank ); } /* 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_bank_t * bank, - fd_funk_t * funk, - fd_funk_txn_xid_t const * xid, - fd_stake_delegations_t const * stake_delegations, - fd_capture_ctx_t * capture_ctx, - ulong rewarded_epoch, - ulong rewards, - fd_calculate_validator_rewards_result_t * result, - fd_spad_t * runtime_spad ) { - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L2759-L2786 */ - fd_stake_history_t const * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); - if( FD_UNLIKELY( !stake_history ) ) { +static uint128 +calculate_validator_rewards( fd_bank_t * bank, + fd_funk_t * funk, + fd_funk_txn_xid_t const * xid, + fd_stake_delegations_t const * stake_delegations, + fd_capture_ctx_t * capture_ctx, + ulong rewarded_epoch, + ulong * rewards_out ) { + + fd_stake_history_t stake_history[1]; + if( FD_UNLIKELY( !fd_sysvar_stake_history_read( funk, xid, stake_history ) ) ) { FD_LOG_ERR(( "Unable to read and decode stake history sysvar" )); } /* Calculate the epoch reward points from stake/vote accounts */ - calculate_reward_points_partitioned( + uint128 points = calculate_reward_points_partitioned( bank, stake_delegations, - stake_history, - rewards, - &result->point_value ); + stake_history ); + + /* If there are no points, then we set the rewards to 0. */ + *rewards_out = points>0UL ? *rewards_out: 0UL; if( capture_ctx ) { ulong const epoch = fd_bank_epoch_get( bank ); fd_solcap_writer_stake_rewards_begin( capture_ctx->capture, epoch, - epoch-1, /* FIXME this is not strictly correct */ - result->point_value.rewards, - result->point_value.points ); + epoch-1UL, /* FIXME: this is not strictly correct */ + *rewards_out, + points ); } /* Calculate the stake and vote rewards for each account. We want to @@ -694,10 +500,11 @@ calculate_validator_rewards( fd_bank_t * bank, capture_ctx, stake_history, rewarded_epoch, - &result->point_value, - &result->calculate_stake_vote_rewards_result, - runtime_spad, + *rewards_out, + points, 0 ); + + return points; } /* Calculate the number of blocks required to distribute rewards to all stake accounts. @@ -721,50 +528,9 @@ get_reward_distribution_num_blocks( fd_epoch_schedule_t const * epoch_schedule, return num_chunks; } -static void -hash_rewards_into_partitions( fd_bank_t * bank, - fd_stake_reward_calculation_t * stake_reward_calculation, - fd_hash_t const * parent_blockhash, - ulong num_partitions ) { - - fd_epoch_rewards_t * epoch_rewards = fd_epoch_rewards_join( fd_epoch_rewards_new( fd_bank_epoch_rewards_locking_modify( bank ), FD_RUNTIME_MAX_STAKE_ACCOUNTS ) ); - if( FD_UNLIKELY( !epoch_rewards ) ) { - FD_LOG_CRIT(( "failed to join epoch rewards" )); - } - fd_epoch_rewards_set_num_partitions( epoch_rewards, num_partitions ); - - /* Iterate over all the stake rewards, moving references to them into the appropiate partitions. - IMPORTANT: after this, we cannot use the original stake rewards dlist anymore. */ - fd_stake_reward_calculation_dlist_iter_t next_iter; - for( fd_stake_reward_calculation_dlist_iter_t iter = fd_stake_reward_calculation_dlist_iter_fwd_init( stake_reward_calculation->stake_rewards, stake_reward_calculation->pool ); - !fd_stake_reward_calculation_dlist_iter_done( iter, stake_reward_calculation->stake_rewards, stake_reward_calculation->pool ); - iter = next_iter ) { - fd_stake_reward_t * stake_reward = fd_stake_reward_calculation_dlist_iter_ele( iter, stake_reward_calculation->stake_rewards, stake_reward_calculation->pool ); - /* Cache the next iter here, as we will overwrite the DLIST_NEXT value further down in the loop iteration. */ - next_iter = fd_stake_reward_calculation_dlist_iter_fwd_next( iter, stake_reward_calculation->stake_rewards, stake_reward_calculation->pool ); - - if( FD_UNLIKELY( !stake_reward->valid ) ) { - continue; - } - - /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/epoch_rewards_hasher.rs#L43C31-L61 */ - int err = fd_epoch_rewards_hash_and_insert( - epoch_rewards, - parent_blockhash, - &stake_reward->stake_pubkey, - stake_reward->credits_observed, - stake_reward->lamports ); - if( FD_UNLIKELY( err ) ) { - FD_LOG_CRIT(( "failed to hash and insert stake reward" )); - } - } - - fd_bank_epoch_rewards_end_locking_modify( bank ); -} - /* 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 */ + https://github.com/anza-xyz/agave/blob/v3.0.4/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L277 */ static void calculate_rewards_for_partitioning( fd_bank_t * bank, fd_funk_t * funk, @@ -772,10 +538,7 @@ calculate_rewards_for_partitioning( fd_bank_t * bank, fd_stake_delegations_t const * stake_delegations, fd_capture_ctx_t * capture_ctx, ulong prev_epoch, - const fd_hash_t * parent_blockhash, - fd_partitioned_rewards_calculation_t * result, - fd_spad_t * runtime_spad ) { - /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L227 */ + fd_partitioned_rewards_calculation_t * result ) { fd_prev_epoch_inflation_rewards_t rewards; calculate_previous_epoch_inflation_rewards( bank, @@ -783,46 +546,29 @@ calculate_rewards_for_partitioning( fd_bank_t * bank, prev_epoch, &rewards ); - fd_calculate_validator_rewards_result_t validator_result[1] = {0}; - calculate_validator_rewards( bank, - funk, - xid, - stake_delegations, - capture_ctx, - prev_epoch, - rewards.validator_rewards, - validator_result, - runtime_spad ); - - fd_stake_reward_calculation_t * stake_reward_calculation = &validator_result->calculate_stake_vote_rewards_result.stake_reward_calculation; - fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank ); - - ulong num_partitions = get_reward_distribution_num_blocks( - epoch_schedule, - fd_bank_slot_get( bank ), - stake_reward_calculation->stake_rewards_len ); - hash_rewards_into_partitions( - bank, - stake_reward_calculation, - parent_blockhash, - num_partitions ); - - result->stake_rewards_by_partition.total_stake_rewards_lamports = - validator_result->calculate_stake_vote_rewards_result.stake_reward_calculation.total_stake_rewards_lamports; - - 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->validator_rewards = rewards.validator_rewards; + ulong total_rewards = rewards.validator_rewards; + + uint128 points = calculate_validator_rewards( bank, + funk, + xid, + stake_delegations, + capture_ctx, + prev_epoch, + &total_rewards ); + + /* The agave client does not partition the stake rewards until the + first distribution block. We calculate the partitions during the + boundary. */ + result->validator_points = points; + result->validator_rewards = total_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 = fd_bank_capitalization_get( bank ); - result->point_value = validator_result->point_value; } /* 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 */ + https://github.com/anza-xyz/agave/blob/v3.0.4/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L148 */ static void calculate_rewards_and_distribute_vote_rewards( fd_bank_t * bank, fd_funk_t * funk, @@ -830,10 +576,12 @@ calculate_rewards_and_distribute_vote_rewards( fd_bank_t * ba fd_stake_delegations_t const * stake_delegations, fd_capture_ctx_t * capture_ctx, ulong prev_epoch, - fd_hash_t const * parent_blockhash, - fd_spad_t * runtime_spad ) { + int is_recalculation ) { + + /* First we must compute the stake and vote rewards for the just + completed epoch. We store the stake account rewards and vote + states rewards in the bank */ - /* 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( bank, funk, @@ -841,21 +589,25 @@ calculate_rewards_and_distribute_vote_rewards( fd_bank_t * ba stake_delegations, capture_ctx, prev_epoch, - parent_blockhash, - rewards_calc_result, - runtime_spad ); + rewards_calc_result ); + + fd_vote_states_t const * vote_states = !!is_recalculation ? fd_bank_vote_states_prev_locking_query( bank ) : fd_bank_vote_states_locking_query( bank ); - /* Iterate over all the vote reward nodes */ + /* Iterate over all the vote reward nodes and distribute the rewards + to the vote accounts. After each reward has been paid out, + calcualte the lthash for each vote account. */ ulong distributed_rewards = 0UL; - 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 = fd_vote_reward_t_map_successor( rewards_calc_result->vote_reward_map_pool, vote_reward_node ) ) { + fd_vote_states_iter_t iter_[1]; + for( fd_vote_states_iter_t * iter = fd_vote_states_iter_init( iter_, vote_states ); + !fd_vote_states_iter_done( iter ); + fd_vote_states_iter_next( iter ) ) { + fd_vote_state_ele_t * vote_state = fd_vote_states_iter_ele( iter ); - if( FD_UNLIKELY( !vote_reward_node->elem.needs_store ) ) { + if( vote_state->rewards==0UL ) { continue; } - fd_pubkey_t const * vote_pubkey = &vote_reward_node->elem.pubkey; + fd_pubkey_t const * vote_pubkey = &vote_state->vote_account; fd_txn_account_t vote_rec[1]; fd_funk_rec_prepare_t prepare = {0}; @@ -878,38 +630,39 @@ calculate_rewards_and_distribute_vote_rewards( fd_bank_t * ba fd_txn_account_set_slot( vote_rec, fd_bank_slot_get( bank ) ); - if( FD_UNLIKELY( fd_txn_account_checked_add_lamports( vote_rec, vote_reward_node->elem.vote_rewards ) ) ) { + if( FD_UNLIKELY( fd_txn_account_checked_add_lamports( vote_rec, vote_state->rewards ) ) ) { FD_LOG_ERR(( "Adding lamports to vote account would cause overflow" )); } fd_hashes_update_lthash( vote_rec, prev_hash,bank, capture_ctx ); fd_txn_account_mutable_fini( vote_rec, funk, &prepare ); - distributed_rewards = fd_ulong_sat_add( distributed_rewards, vote_reward_node->elem.vote_rewards ); + distributed_rewards = fd_ulong_sat_add( distributed_rewards, vote_state->rewards ); if( capture_ctx ) { fd_solcap_write_vote_account_payout( capture_ctx->capture, vote_pubkey, fd_bank_slot_get( bank ), fd_txn_account_get_lamports( vote_rec ), - (long)vote_reward_node->elem.vote_rewards ); + (long)vote_state->rewards ); } } - /* There is no need to free the vote reward map since it was spad*/ + !!is_recalculation ? fd_bank_vote_states_prev_end_locking_query( bank ) : fd_bank_vote_states_end_locking_query( bank ); /* Verify that we didn't pay any more than we expected to */ - ulong total_rewards = fd_ulong_sat_add( distributed_rewards, rewards_calc_result->stake_rewards_by_partition.total_stake_rewards_lamports ); + fd_epoch_rewards_t * epoch_rewards = fd_bank_epoch_rewards_locking_modify( bank ); + + ulong total_rewards = fd_ulong_sat_add( distributed_rewards, epoch_rewards->total_stake_rewards ); if( FD_UNLIKELY( rewards_calc_result->validator_rewardspoint_value.rewards ); - fd_epoch_rewards_set_total_points( epoch_rewards, rewards_calc_result->point_value.points ); + epoch_rewards->distributed_rewards = distributed_rewards; + epoch_rewards->total_rewards = rewards_calc_result->validator_rewards; + epoch_rewards->total_points = rewards_calc_result->validator_points; fd_bank_epoch_rewards_end_locking_modify( bank ); } @@ -1000,60 +753,33 @@ distribute_epoch_reward_to_stake_acc( fd_bank_t * bank, return 0; } -/* Sets the epoch reward status to inactive, and destroys any allocated state associated with the active state. */ -static void -set_epoch_reward_status_inactive( fd_bank_t * bank ) { - fd_epoch_rewards_t * epoch_rewards = fd_bank_epoch_rewards_locking_modify( bank ); - if( fd_epoch_rewards_is_active( epoch_rewards ) ) { - FD_LOG_NOTICE(( "Done partitioning rewards for current epoch" )); - } - fd_epoch_rewards_set_active( epoch_rewards, 0 ); - fd_bank_epoch_rewards_end_locking_modify( bank ); -} - -/* Sets the epoch reward status to active. - - Takes ownership of the given stake_rewards_by_partition data structure, - which will be destroyed when set_epoch_reward_status_inactive is called. */ -static void -set_epoch_reward_status_active( fd_bank_t * bank, - ulong distribution_starting_block_height ) { - FD_LOG_NOTICE(( "Setting epoch reward status as active" )); - - fd_epoch_rewards_t * epoch_rewards = fd_bank_epoch_rewards_locking_modify( bank ); - - fd_epoch_rewards_set_active( epoch_rewards, 1 ); - fd_epoch_rewards_set_starting_block_height( epoch_rewards, distribution_starting_block_height ); - fd_bank_epoch_rewards_end_locking_modify( bank ); -} - -/* 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 */ +/* Process reward credits for a partition of rewards. Store the rewards + to AccountsDB, update reward history record and total capitalization + https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/distribution.rs#L88 */ static void -distribute_epoch_rewards_in_partition( fd_epoch_stake_reward_dlist_t * stake_reward_dlist, - fd_epoch_stake_reward_t * stake_reward_pool, - fd_bank_t * bank, - fd_funk_t * funk, - fd_funk_txn_xid_t const * xid, - fd_capture_ctx_t * capture_ctx ) { +distribute_epoch_rewards_in_partition( fd_epoch_rewards_t const * epoch_rewards, + ulong partition_idx, + fd_bank_t * bank, + fd_funk_t * funk, + fd_funk_txn_xid_t const * xid, + fd_capture_ctx_t * capture_ctx ) { ulong lamports_distributed = 0UL; ulong lamports_burned = 0UL; - for( fd_epoch_stake_reward_dlist_iter_t iter = fd_epoch_stake_reward_dlist_iter_fwd_init( stake_reward_dlist, stake_reward_pool ); - !fd_epoch_stake_reward_dlist_iter_done( iter, stake_reward_dlist, stake_reward_pool ); - iter = fd_epoch_stake_reward_dlist_iter_fwd_next( iter, stake_reward_dlist, stake_reward_pool ) ) { - fd_epoch_stake_reward_t * stake_reward = fd_epoch_stake_reward_dlist_iter_ele( iter, stake_reward_dlist, stake_reward_pool ); - if( FD_LIKELY( !distribute_epoch_reward_to_stake_acc( - bank, - funk, - xid, - capture_ctx, - &stake_reward->stake_pubkey, - stake_reward->lamports, - stake_reward->credits_observed ) ) ) { + fd_epoch_rewards_iter_t iter_[1]; + for( fd_epoch_rewards_iter_t * iter = fd_epoch_rewards_iter_init( iter_, epoch_rewards, partition_idx ); + !fd_epoch_rewards_iter_done( iter ); + fd_epoch_rewards_iter_next( iter ) ) { + fd_epoch_stake_reward_t * stake_reward = fd_epoch_rewards_iter_ele( iter ); + + if( FD_LIKELY( !distribute_epoch_reward_to_stake_acc( bank, + funk, + xid, + capture_ctx, + &stake_reward->stake_pubkey, + stake_reward->lamports, + stake_reward->credits_observed ) ) ) { lamports_distributed += stake_reward->lamports; } else { lamports_burned += stake_reward->lamports; @@ -1078,56 +804,40 @@ fd_distribute_partitioned_epoch_rewards( fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ) { fd_epoch_rewards_t const * epoch_rewards = fd_bank_epoch_rewards_locking_query( bank ); - - if( !fd_epoch_rewards_is_active( epoch_rewards ) ) { + if( FD_LIKELY( !epoch_rewards ) ) { fd_bank_epoch_rewards_end_locking_query( bank ); return; } - ulong height = fd_bank_block_height_get( bank ); - ulong distribution_starting_block_height = fd_epoch_rewards_get_starting_block_height( epoch_rewards ); + ulong block_height = fd_bank_block_height_get( bank ); + ulong distribution_starting_block_height = epoch_rewards->starting_block_height; ulong distribution_end_exclusive = fd_epoch_rewards_get_exclusive_ending_block_height( epoch_rewards ); fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank ); ulong epoch = fd_bank_epoch_get( bank ); - if( FD_UNLIKELY( get_slots_in_epoch( epoch, epoch_schedule ) <= fd_epoch_rewards_get_num_partitions( epoch_rewards ) ) ) { + if( FD_UNLIKELY( get_slots_in_epoch( epoch, epoch_schedule ) <= epoch_rewards->num_partitions ) ) { FD_LOG_CRIT(( "Should not be distributing rewards" )); } - if( (height>=distribution_starting_block_height) && (height < distribution_end_exclusive) ) { + if( FD_UNLIKELY( block_height>=distribution_starting_block_height && block_height=distribution_end_exclusive ) { + fd_sysvar_epoch_rewards_set_inactive( bank, funk, xid, capture_ctx ); } - - distribute_epoch_rewards_in_partition( stake_reward_dlist, - stake_reward_pool, - bank, - funk, - xid, - capture_ctx ); } fd_bank_epoch_rewards_end_locking_query( bank ); - /* If we have finished distributing rewards, set the status to inactive */ - if( fd_ulong_sat_add( height, 1UL ) >= distribution_end_exclusive ) { - set_epoch_reward_status_inactive( bank ); - fd_sysvar_epoch_rewards_set_inactive( bank, funk, xid, capture_ctx ); - } } /* Partitioned epoch rewards entry-point. - https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L41 + https://github.com/anza-xyz/agave/blob/v3.0.4/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L102 */ void fd_begin_partitioned_rewards( fd_bank_t * bank, @@ -1136,10 +846,8 @@ fd_begin_partitioned_rewards( fd_bank_t * bank, fd_capture_ctx_t * capture_ctx, fd_stake_delegations_t const * stake_delegations, fd_hash_t const * parent_blockhash, - ulong parent_epoch, - fd_spad_t * runtime_spad ) { + ulong parent_epoch ) { - /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L55 */ calculate_rewards_and_distribute_vote_rewards( bank, funk, @@ -1147,30 +855,45 @@ fd_begin_partitioned_rewards( fd_bank_t * bank, stake_delegations, capture_ctx, parent_epoch, - parent_blockhash, - runtime_spad ); + 0 ); + + /* Once the rewards for vote accounts have been distributed and stake + account rewards have been calculated, we can now set our epoch + reward status to be active and we can initialize the epoch rewards + sysvar. This sysvar is then deleted once all of the partitioned + stake rewards have been distributed. + + The Agave client calculates the partitions for each stake reward + when the first distribution block is reached. The Firedancer + client differs here since we hash the partitions during the epoch + boundary. */ + + fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank ); + fd_epoch_rewards_t * epoch_rewards = fd_epoch_rewards_join( fd_bank_epoch_rewards_locking_modify( bank ) ); + + ulong num_partitions = get_reward_distribution_num_blocks( + epoch_schedule, + fd_bank_slot_get( bank ), + epoch_rewards->stake_rewards_cnt ); + + fd_epoch_rewards_hash_into_partitions( epoch_rewards, parent_blockhash, num_partitions ); - /* https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L62 */ ulong distribution_starting_block_height = fd_bank_block_height_get( bank ) + REWARD_CALCULATION_NUM_BLOCKS; - /* Set the epoch reward status to be active */ - set_epoch_reward_status_active( bank, distribution_starting_block_height ); + epoch_rewards->starting_block_height = distribution_starting_block_height; - /* Initialize the epoch rewards sysvar - https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L78 */ - fd_epoch_rewards_t const * epoch_rewards = fd_bank_epoch_rewards_locking_query( bank ); fd_sysvar_epoch_rewards_init( bank, funk, xid, capture_ctx, - fd_epoch_rewards_get_distributed_rewards( epoch_rewards ), + epoch_rewards->distributed_rewards, distribution_starting_block_height, - fd_epoch_rewards_get_num_partitions( epoch_rewards ), - fd_epoch_rewards_get_total_rewards( epoch_rewards ), - fd_epoch_rewards_get_total_points( epoch_rewards ), + epoch_rewards->num_partitions, + epoch_rewards->total_rewards, + epoch_rewards->total_points, parent_blockhash ); - fd_bank_epoch_rewards_end_locking_query( bank ); + fd_bank_epoch_rewards_end_locking_modify( bank ); } /* @@ -1183,103 +906,72 @@ fd_rewards_recalculate_partitioned_rewards( fd_banks_t * banks, fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ) { - FD_SPAD_FRAME_BEGIN( runtime_spad ) { + fd_capture_ctx_t * capture_ctx ) { - fd_sysvar_epoch_rewards_t epoch_rewards[1]; - if( FD_UNLIKELY( !fd_sysvar_epoch_rewards_read( funk, xid, epoch_rewards ) ) ) { + fd_sysvar_epoch_rewards_t epoch_rewards_sysvar[1]; + if( FD_UNLIKELY( !fd_sysvar_epoch_rewards_read( funk, xid, epoch_rewards_sysvar ) ) ) { FD_LOG_DEBUG(( "Failed to read or decode epoch rewards sysvar - may not have been created yet" )); - set_epoch_reward_status_inactive( bank ); return; } FD_LOG_DEBUG(( "recalculating partitioned rewards" )); - if( FD_UNLIKELY( epoch_rewards->active ) ) { - - /* If partitioned rewards are active, the rewarded epoch is always the immediately - preceeding epoch. + if( FD_UNLIKELY( !epoch_rewards_sysvar->active ) ) { + FD_LOG_DEBUG(( "epoch rewards is inactive" )); + return; + } - https://github.com/anza-xyz/agave/blob/2316fea4c0852e59c071f72d72db020017ffd7d0/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L566 */ - FD_LOG_DEBUG(( "epoch rewards is active" )); + /* If partitioned rewards are active, the rewarded epoch is always the immediately + preceeding epoch. - ulong const slot = fd_bank_slot_get( bank ); - ulong const epoch = fd_bank_epoch_get( bank ); - ulong const rewarded_epoch = fd_ulong_sat_sub( epoch, 1UL ); + https://github.com/anza-xyz/agave/blob/2316fea4c0852e59c071f72d72db020017ffd7d0/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L566 */ + FD_LOG_DEBUG(( "epoch rewards is active" )); - int _err[1] = {0}; - ulong new_warmup_cooldown_rate_epoch_; - ulong * new_warmup_cooldown_rate_epoch = &new_warmup_cooldown_rate_epoch_; - int is_some = fd_new_warmup_cooldown_rate_epoch( - fd_bank_epoch_schedule_query( bank ), - fd_bank_features_query( bank ), - slot, - new_warmup_cooldown_rate_epoch, - _err ); - if( FD_UNLIKELY( !is_some ) ) { - new_warmup_cooldown_rate_epoch = NULL; - } + ulong const slot = fd_bank_slot_get( bank ); + ulong const epoch = fd_bank_epoch_get( bank ); + ulong const rewarded_epoch = fd_ulong_sat_sub( epoch, 1UL ); - fd_stake_history_t const * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); - if( FD_UNLIKELY( !stake_history ) ) { - FD_LOG_ERR(( "Unable to read and decode stake history sysvar" )); - } + int _err[1] = {0}; + ulong new_warmup_cooldown_rate_epoch_; + ulong * new_warmup_cooldown_rate_epoch = &new_warmup_cooldown_rate_epoch_; + int is_some = fd_new_warmup_cooldown_rate_epoch( + fd_bank_epoch_schedule_query( bank ), + fd_bank_features_query( bank ), + slot, + new_warmup_cooldown_rate_epoch, + _err ); + if( FD_UNLIKELY( !is_some ) ) { + new_warmup_cooldown_rate_epoch = NULL; + } - fd_point_value_t point_value = { .points = epoch_rewards->total_points, - .rewards = epoch_rewards->total_rewards }; + fd_stake_history_t stake_history[1]; + if( FD_UNLIKELY( !fd_sysvar_stake_history_read( funk, xid, stake_history ) ) ) { + FD_LOG_ERR(( "Unable to read and decode stake history sysvar" )); + } - fd_stake_history_entry_t _accumulator = { - .effective = 0UL, - .activating = 0UL, - .deactivating = 0UL - }; + fd_stake_delegations_t const * stake_delegations = fd_bank_stake_delegations_frontier_query( banks, bank ); + if( FD_UNLIKELY( !stake_delegations ) ) { + FD_LOG_CRIT(( "stake_delegations is NULL" )); + } - fd_stake_delegations_t const * stake_delegations = fd_bank_stake_delegations_frontier_query( banks, bank ); - if( FD_UNLIKELY( !stake_delegations ) ) { - FD_LOG_CRIT(( "stake_delegations is NULL" )); - } + /* Make sure is_recalculation is ==1 since we are booting up in the + middle of rewards distribution (so we should use the epoch + stakes for the end of epoch E-1 since we are still distributing + rewards for the previous epoch). */ + calculate_stake_vote_rewards( + bank, + stake_delegations, + capture_ctx, + stake_history, + rewarded_epoch, + epoch_rewards_sysvar->total_rewards, + epoch_rewards_sysvar->total_points, + 1 /* is_recalculation */ ); - fd_accumulate_stake_infos( - epoch, - stake_delegations, - stake_history, - new_warmup_cooldown_rate_epoch, - &_accumulator ); - - /* Make sure is_recalculation is ==1 since we are booting up in the - middle of rewards distribution (so we should use the epoch - stakes for the end of epoch E-1 since we are still distributing - rewards for the previous epoch). */ - fd_calculate_stake_vote_rewards_result_t calculate_stake_vote_rewards_result[1]; - calculate_stake_vote_rewards( - bank, - stake_delegations, - capture_ctx, - stake_history, - rewarded_epoch, - &point_value, - calculate_stake_vote_rewards_result, - runtime_spad, - 1 /* is_recalculation */ ); - - /* The vote reward map isn't actually used in this code path and - will only be freed after rewards have been distributed. */ - - - /* Use the epoch rewards sysvar parent_blockhash and num_partitions. - https://github.com/anza-xyz/agave/blob/v2.2.14/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L579 */ - hash_rewards_into_partitions( - bank, - &calculate_stake_vote_rewards_result->stake_reward_calculation, - &epoch_rewards->parent_blockhash, - epoch_rewards->num_partitions ); - - /* Update the epoch reward status with the newly re-calculated partitions. */ - set_epoch_reward_status_active( bank, epoch_rewards->distribution_starting_block_height ); - } else { - set_epoch_reward_status_inactive( bank ); - } + fd_epoch_rewards_t * epoch_rewards = fd_epoch_rewards_join( fd_bank_epoch_rewards_locking_modify( bank ) ); + fd_epoch_rewards_hash_into_partitions( epoch_rewards, &epoch_rewards_sysvar->parent_blockhash, epoch_rewards_sysvar->num_partitions ); - } FD_SPAD_FRAME_END; + /* Update the epoch reward status with the newly re-calculated partitions. */ + epoch_rewards->starting_block_height = epoch_rewards_sysvar->distribution_starting_block_height; + fd_bank_epoch_rewards_end_locking_modify( bank ); } diff --git a/src/flamenco/rewards/fd_rewards.h b/src/flamenco/rewards/fd_rewards.h index 4deac6f38ca..8ec90ad8783 100644 --- a/src/flamenco/rewards/fd_rewards.h +++ b/src/flamenco/rewards/fd_rewards.h @@ -34,8 +34,7 @@ fd_begin_partitioned_rewards( fd_bank_t * bank, fd_capture_ctx_t * capture_ctx, fd_stake_delegations_t const * stake_delegations, fd_hash_t const * parent_blockhash, - ulong parent_epoch, - fd_spad_t * runtime_spad ); + ulong parent_epoch ); /* fd_rewards_recalculate_partitioned_rewards restores epoch bank stake and account reward calculations. Does not update accounts. Called @@ -53,8 +52,7 @@ fd_rewards_recalculate_partitioned_rewards( fd_banks_t * banks, fd_bank_t * bank, fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_capture_ctx_t * capture_ctx, - fd_spad_t * runtime_spad ); + fd_capture_ctx_t * capture_ctx ); /* fd_distribute_partitioned_epoch_rewards pays out rewards to stake accounts. Called at the beginning of a few slots per epoch. diff --git a/src/flamenco/rewards/test_epoch_rewards.c b/src/flamenco/rewards/test_epoch_rewards.c index b1c0d2cf83f..eea63bd40b2 100644 --- a/src/flamenco/rewards/test_epoch_rewards.c +++ b/src/flamenco/rewards/test_epoch_rewards.c @@ -19,7 +19,6 @@ int main( int argc, char * * argv ) { than or equal to the align of its underlying members. */ FD_TEST( fd_epoch_rewards_align() >= alignof(fd_epoch_rewards_t) ); - FD_TEST( fd_epoch_rewards_align() >= fd_epoch_stake_reward_pool_align() ); FD_TEST( fd_epoch_rewards_align() >= fd_epoch_stake_reward_dlist_align() ); /* Make sure that the static footprint is at least as large as the @@ -59,45 +58,16 @@ int main( int argc, char * * argv ) { epoch_rewards = fd_epoch_rewards_join( epoch_rewards_mem ); FD_TEST( epoch_rewards ); - FD_TEST( fd_epoch_rewards_get_num_partitions( epoch_rewards ) == 0UL ); - FD_TEST( fd_epoch_rewards_is_active( epoch_rewards ) == 0 ); - FD_TEST( fd_epoch_rewards_get_starting_block_height( epoch_rewards ) == 0UL ); - FD_TEST( fd_epoch_rewards_get_exclusive_ending_block_height( epoch_rewards ) == 0UL ); - FD_TEST( fd_epoch_rewards_get_distributed_rewards( epoch_rewards ) == 0UL ); - FD_TEST( fd_epoch_rewards_get_total_points( epoch_rewards ) == 0 ); - FD_TEST( fd_epoch_rewards_get_total_rewards( epoch_rewards ) == 0UL ); - FD_TEST( epoch_rewards->stake_account_max_ == STAKE_ACC_MAX ); - - /* Try to get partition index before setting any. */ - - FD_TEST( !fd_epoch_rewards_get_partition_index( epoch_rewards, 0UL ) ); + FD_TEST( epoch_rewards->num_partitions == 0UL ); + FD_TEST( epoch_rewards->starting_block_height == 0UL ); + FD_TEST( epoch_rewards->distributed_rewards == 0UL ); + FD_TEST( epoch_rewards->total_points == 0 ); + FD_TEST( epoch_rewards->total_rewards == 0UL ); + FD_TEST( epoch_rewards->stake_account_max == STAKE_ACC_MAX ); /* Set num partitions. */ - fd_epoch_rewards_set_num_partitions( epoch_rewards, FD_REWARDS_MAX_PARTITIONS * 2 ); - FD_TEST( fd_epoch_rewards_get_num_partitions( epoch_rewards ) == 0UL ); - - fd_epoch_rewards_set_num_partitions( epoch_rewards, 100UL ); - FD_TEST( fd_epoch_rewards_get_num_partitions( epoch_rewards ) == 100UL ); - - /* Try to get partition index after setting num partitions. */ - - FD_TEST( fd_epoch_rewards_get_partition_index( epoch_rewards, 0UL ) ); - FD_TEST( fd_epoch_rewards_get_partition_index( epoch_rewards, 50UL ) ); - - /* Try to get partition index with idx greater than num partitions. */ - - FD_TEST( !fd_epoch_rewards_get_partition_index( epoch_rewards, 100UL ) ); - FD_TEST( !fd_epoch_rewards_get_partition_index( epoch_rewards, 101UL ) ); - - /* Getting stake reward pool should always be successful. */ - - fd_epoch_stake_reward_t * stake_reward_pool = fd_epoch_rewards_get_stake_reward_pool( epoch_rewards ); - FD_TEST( stake_reward_pool ); - - /* Try to get stake reward pool before setting any. */ - - FD_TEST( !fd_epoch_rewards_get_stake_reward_pool( NULL ) ); + epoch_rewards->num_partitions = 100UL; /* Hash some accounts */ @@ -106,17 +76,15 @@ int main( int argc, char * * argv ) { fd_pubkey_t pubkey_b = { .key = { 2 } }; fd_pubkey_t pubkey_c = { .key = { 3 } }; - /* Hash where we don't expect to succeed. */ + /* Insert some accounts */ - FD_TEST( fd_epoch_rewards_hash_and_insert( NULL, NULL, NULL, 0UL, 0UL ) ); - FD_TEST( fd_epoch_rewards_hash_and_insert( epoch_rewards, NULL, &pubkey_a, 0UL, 0UL ) ); - FD_TEST( fd_epoch_rewards_hash_and_insert( epoch_rewards, &parent_blockhash, NULL, 0UL, 0UL ) ); + fd_epoch_rewards_insert( epoch_rewards, &pubkey_a, 100UL, 200UL ); + fd_epoch_rewards_insert( epoch_rewards, &pubkey_b, 1000UL, 100UL ); + fd_epoch_rewards_insert( epoch_rewards, &pubkey_c, 50UL, 2000UL ); - /* Hash where we expect to succeed. */ + /* Hash all of the accounts */ - FD_TEST( !fd_epoch_rewards_hash_and_insert( epoch_rewards, &parent_blockhash, &pubkey_a, 100UL, 200UL ) ); - FD_TEST( !fd_epoch_rewards_hash_and_insert( epoch_rewards, &parent_blockhash, &pubkey_b, 1000UL, 100UL ) ); - FD_TEST( !fd_epoch_rewards_hash_and_insert( epoch_rewards, &parent_blockhash, &pubkey_c, 50UL, 2000UL ) ); + fd_epoch_rewards_hash_into_partitions( epoch_rewards, &parent_blockhash, 2UL ); /* Now if we iterate through all of our partitions, we should see each our pubkeys exactly once. */ @@ -125,14 +93,13 @@ int main( int argc, char * * argv ) { ulong pubkey_b_count = 0UL; ulong pubkey_c_count = 0UL; - for( ulong i=0UL; inum_partitions; i++ ) { + fd_epoch_rewards_iter_t iter_[1]; + for( fd_epoch_rewards_iter_t * iter = fd_epoch_rewards_iter_init( iter_, epoch_rewards, i ); + !fd_epoch_rewards_iter_done( iter ); + fd_epoch_rewards_iter_next( iter ) ) { - fd_epoch_stake_reward_t * stake_reward = fd_epoch_stake_reward_dlist_iter_ele( iter, partition, stake_reward_pool ); + fd_epoch_stake_reward_t * stake_reward = fd_epoch_rewards_iter_ele( iter ); if( !memcmp( &stake_reward->stake_pubkey, &pubkey_a, sizeof(fd_pubkey_t) ) ) { FD_TEST( stake_reward->lamports == 200UL ); FD_TEST( stake_reward->credits_observed == 100UL ); @@ -153,29 +120,6 @@ int main( int argc, char * * argv ) { FD_TEST( pubkey_b_count == 1UL ); FD_TEST( pubkey_c_count == 1UL ); - /* Simple checks on accessors and mutators. */ - - FD_TEST( fd_epoch_rewards_is_active( epoch_rewards ) == 0 ); - fd_epoch_rewards_set_active( epoch_rewards, 1 ); - FD_TEST( fd_epoch_rewards_is_active( epoch_rewards ) == 1 ); - - FD_TEST( fd_epoch_rewards_get_starting_block_height( epoch_rewards ) == 0UL ); - fd_epoch_rewards_set_starting_block_height( epoch_rewards, 100UL ); - FD_TEST( fd_epoch_rewards_get_starting_block_height( epoch_rewards ) == 100UL ); - FD_TEST( fd_epoch_rewards_get_exclusive_ending_block_height( epoch_rewards ) == 200UL ); - - FD_TEST( fd_epoch_rewards_get_distributed_rewards( epoch_rewards ) == 0UL ); - fd_epoch_rewards_set_distributed_rewards( epoch_rewards, 1000UL ); - FD_TEST( fd_epoch_rewards_get_distributed_rewards( epoch_rewards ) == 1000UL ); - - FD_TEST( fd_epoch_rewards_get_total_points( epoch_rewards ) == 0 ); - fd_epoch_rewards_set_total_points( epoch_rewards, 1000UL ); - FD_TEST( fd_epoch_rewards_get_total_points( epoch_rewards ) == 1000UL ); - - FD_TEST( fd_epoch_rewards_get_total_rewards( epoch_rewards ) == 0UL ); - fd_epoch_rewards_set_total_rewards( epoch_rewards, 1000UL ); - FD_TEST( fd_epoch_rewards_get_total_rewards( epoch_rewards ) == 1000UL ); - /* Check that we can leave and join again. */ FD_TEST( fd_epoch_rewards_leave( epoch_rewards ) ); diff --git a/src/flamenco/runtime/context/fd_exec_txn_ctx.c b/src/flamenco/runtime/context/fd_exec_txn_ctx.c index 6122bfc681e..61dcfbda6e0 100644 --- a/src/flamenco/runtime/context/fd_exec_txn_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_txn_ctx.c @@ -193,10 +193,9 @@ fd_exec_txn_ctx_setup_basic( fd_exec_txn_ctx_t * ctx ) { memset( ctx->return_data.program_id.key, 0, sizeof(fd_pubkey_t) ); ctx->return_data.len = 0; - ctx->dirty_vote_acc = 0; - ctx->failed_instr = NULL; - ctx->instr_err_idx = INT_MAX; - ctx->capture_ctx = NULL; + ctx->failed_instr = NULL; + ctx->instr_err_idx = INT_MAX; + ctx->capture_ctx = NULL; ctx->instr_info_cnt = 0UL; ctx->cpi_instr_info_cnt = 0UL; diff --git a/src/flamenco/runtime/context/fd_exec_txn_ctx.h b/src/flamenco/runtime/context/fd_exec_txn_ctx.h index c644ae66cde..b1293b33685 100644 --- a/src/flamenco/runtime/context/fd_exec_txn_ctx.h +++ b/src/flamenco/runtime/context/fd_exec_txn_ctx.h @@ -121,8 +121,6 @@ struct fd_exec_txn_ctx { ulong priority_fee; /* Priority fee paid by the fee payer in the transaction */ ulong collected_rent; /* Rent collected from accounts in this transaction */ - uchar dirty_vote_acc : 1; /* 1 if this transaction maybe modified a vote account */ - fd_capture_ctx_t * capture_ctx; /* The instr_infos for the entire transaction are allocated at the start of diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index a624d5c8115..0e7804d7200 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1115,8 +1115,6 @@ fd_runtime_finalize_txn( fd_funk_t * funk, } } else { - int dirty_vote_acc = txn_ctx->dirty_vote_acc; - for( ushort i=0; iaccounts_cnt; i++ ) { /* We are only interested in saving writable accounts and the fee payer account. */ @@ -1129,12 +1127,12 @@ fd_runtime_finalize_txn( fd_funk_t * funk, FD_LOG_CRIT(( "fd_runtime_finalize_txn: failed to join account at idx %u", i )); } - if( dirty_vote_acc && 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_vote_program_id, sizeof(fd_pubkey_t) ) ) { - fd_vote_store_account( acc_rec, bank ); + if( 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_vote_program_id, sizeof(fd_pubkey_t) ) ) { + fd_stakes_update_vote_state( acc_rec, bank ); } if( 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_stake_program_id, sizeof(fd_pubkey_t) ) ) { - fd_update_stake_delegation( acc_rec, bank ); + fd_stakes_update_stake_delegation( acc_rec, bank ); } /* Reclaim any accounts that have 0-lamports, now that any related @@ -1484,11 +1482,13 @@ fd_runtime_process_new_epoch( fd_banks_t * banks, /* Activate new features https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank.rs#L6587-L6598 */ + fd_features_activate( bank, funk, xid, capture_ctx ); fd_features_restore( bank, funk, xid ); /* Apply builtin program feature transitions https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank.rs#L6621-L6624 */ + fd_apply_builtin_program_feature_transitions( bank, funk, xid, capture_ctx, runtime_spad ); /* Get the new rate activation epoch */ @@ -1505,44 +1505,31 @@ fd_runtime_process_new_epoch( fd_banks_t * banks, new_rate_activation_epoch = NULL; } - /* Updates stake history sysvar accumulated values. */ - fd_stakes_activate_epoch( bank, funk, xid, capture_ctx, stake_delegations, new_rate_activation_epoch, runtime_spad ); - - /* Refresh vote accounts in stakes cache using updated stake weights, and merges slot bank vote accounts with the epoch bank vote accounts. - https://github.com/anza-xyz/agave/blob/v2.1.6/runtime/src/stakes.rs#L363-L370 */ - fd_stake_history_t const * history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); - if( FD_UNLIKELY( !history ) ) { - FD_LOG_ERR(( "StakeHistory sysvar could not be read and decoded" )); - } - - /* Now increment the epoch */ + /* Updates stake history sysvar accumulated values and recomputes + stake delegations for vote accounts. */ - fd_bank_epoch_set( bank, fd_bank_epoch_get( bank ) + 1UL ); + fd_stakes_activate_epoch( bank, funk, xid, capture_ctx, stake_delegations, new_rate_activation_epoch ); - fd_refresh_vote_accounts( bank, - stake_delegations, - history, - new_rate_activation_epoch ); - - /* Distribute rewards */ - - fd_hash_t parent_blockhash = {0}; - { - fd_blockhashes_t const * bhq = fd_bank_block_hash_queue_query( bank ); - fd_hash_t const * bhq_last = fd_blockhashes_peek_last( bhq ); - FD_TEST( bhq_last ); - parent_blockhash = *bhq_last; - } + /* Distribute rewards. This involves calculating the rewards for + every vote and stake account. */ + fd_hash_t const * parent_blockhash = fd_blockhashes_peek_last( fd_bank_block_hash_queue_query( bank ) ); fd_begin_partitioned_rewards( bank, funk, xid, capture_ctx, stake_delegations, - &parent_blockhash, - parent_epoch, - runtime_spad ); - + parent_blockhash, + parent_epoch ); + + /* The Agave client handles updating their stakes cache with a call to + update_epoch_stakes() which keys stakes by the leader schedule + epochs and retains up to 6 epochs of stakes. However, to correctly + calculate the leader schedule, we just need to maintain the vote + states for the current epoch, the previous epoch, and the one + before that. + https://github.com/anza-xyz/agave/blob/v3.0.4/runtime/src/bank.rs#L2175 + */ /* Update vote_states_prev_prev with vote_states_prev */ @@ -1552,12 +1539,12 @@ fd_runtime_process_new_epoch( fd_banks_t * banks, fd_update_vote_states_prev( bank ); - /* Update current leaders using epoch_stakes (new T-2 stakes) */ + /* Now that our stakes caches have been updated, we can calculate the + leader schedule for the upcoming epoch epoch using our new + vote_states_prev_prev (stakes for T-2). */ fd_runtime_update_leaders( bank, runtime_spad ); - FD_LOG_NOTICE(( "fd_process_new_epoch end" )); - long end = fd_log_wallclock(); FD_LOG_NOTICE(("fd_process_new_epoch took %ld ns", end - start)); @@ -1741,7 +1728,10 @@ fd_runtime_init_bank_from_genesis( fd_banks_t * banks, the amount of stake that is delegated to each vote account. */ ulong new_rate_activation_epoch = 0UL; - fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + + fd_stake_history_t stake_history[1]; + fd_sysvar_stake_history_read( funk, xid, stake_history ); + fd_refresh_vote_accounts( bank, stake_delegations, diff --git a/src/flamenco/runtime/program/fd_vote_program.c b/src/flamenco/runtime/program/fd_vote_program.c index 6a64c8f5537..c30932f3ed3 100644 --- a/src/flamenco/runtime/program/fd_vote_program.c +++ b/src/flamenco/runtime/program/fd_vote_program.c @@ -2123,7 +2123,7 @@ fd_vote_decode_compact_update( fd_compact_vote_state_update_t * compact_update, /// returns commission split as (voter_portion, staker_portion, was_split) tuple /// -/// if commission calculation is 100% one way or other, indicate with false for was_split +/// if commission calculation is 100% one way or other, indicate with false for was_split // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L543 void @@ -2131,15 +2131,15 @@ fd_vote_commission_split( uchar commission, ulong on, fd_commission_split_t * result ) { uint commission_split = fd_uint_min( (uint)commission, 100 ); - result->is_split = ( commission_split != 0 && commission_split != 100 ); + result->is_split = (commission_split != 0 && commission_split != 100); // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L545 - if( commission_split == 0 ) { + if( commission_split==0U ) { result->voter_portion = 0; result->staker_portion = on; return; } // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L546 - if( commission_split == 100 ) { + if( commission_split==100U ) { result->voter_portion = on; result->staker_portion = 0; return; @@ -2158,9 +2158,9 @@ fd_vote_commission_split( uchar commission, // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L548 result->voter_portion = - (ulong)( (uint128)on * (uint128)commission_split / (uint128)100 ); + (ulong)((uint128)on * (uint128)commission_split / (uint128)100); result->staker_portion = - (ulong)( (uint128)on * (uint128)( 100 - commission_split ) / (uint128)100 ); + (ulong)((uint128)on * (uint128)( 100 - commission_split ) / (uint128)100); } /**********************************************************************/ @@ -2263,10 +2263,6 @@ fd_vote_program_execute( fd_exec_instr_ctx_t * ctx ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER; } - /* Replicate vote account changes to bank caches after processing the - transaction's instructions. */ - ctx->txn_ctx->dirty_vote_acc = 1; - // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_processor.rs#L69 fd_pubkey_t const * signers[FD_TXN_SIG_MAX] = { 0 }; fd_exec_instr_ctx_get_signers( ctx, signers ); @@ -2817,39 +2813,27 @@ fd_vote_convert_to_current( fd_vote_state_versioned_t * self, convert_to_current( self, spad ); } -static void -remove_vote_account( fd_txn_account_t * vote_account, - fd_bank_t * bank ) { +void +fd_vote_store_account( fd_txn_account_t * vote_account, + fd_bank_t * bank ) { fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); - fd_vote_states_remove( vote_states, vote_account->pubkey ); - fd_bank_vote_states_end_locking_modify( bank ); -} -static void -upsert_vote_account( fd_txn_account_t * vote_account, - fd_bank_t * bank ) { - - if( fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { - fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); - fd_vote_states_update_from_account( - vote_states, - vote_account->pubkey, - fd_txn_account_get_data( vote_account ), - fd_txn_account_get_data_len( vote_account ) ); + if( fd_txn_account_get_lamports( vote_account )==0UL ) { + fd_vote_states_remove( vote_states, vote_account->pubkey ); fd_bank_vote_states_end_locking_modify( bank ); - } else { - remove_vote_account( vote_account, bank ); + return; } -} - -void -fd_vote_store_account( fd_txn_account_t * vote_account, - fd_bank_t * bank ) { - if( fd_txn_account_get_lamports( vote_account )==0UL ) { - remove_vote_account( vote_account, bank ); - } else { - upsert_vote_account( vote_account, bank ); + if( !fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { + fd_vote_states_remove( vote_states, vote_account->pubkey ); + fd_bank_vote_states_end_locking_modify( bank ); + return; } + + fd_vote_states_update_from_account( vote_states, + vote_account->pubkey, + fd_txn_account_get_data( vote_account ), + fd_txn_account_get_data_len( vote_account ) ); + fd_bank_vote_states_end_locking_modify( bank ); } diff --git a/src/flamenco/runtime/program/fd_vote_program.h b/src/flamenco/runtime/program/fd_vote_program.h index 77e97042f1e..529790073d7 100644 --- a/src/flamenco/runtime/program/fd_vote_program.h +++ b/src/flamenco/runtime/program/fd_vote_program.h @@ -41,8 +41,7 @@ FD_PROTOTYPES_BEGIN /* fd_vote_program_execute is the instruction processing entrypoint - for the vote program. On return, ctx.txn_ctx->dirty_vote_acc==1 if a - vote account may have been modified. */ + for the vote program. */ int fd_vote_program_execute( fd_exec_instr_ctx_t * ctx ); diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c index be8c1e69125..17c8a6fce70 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c @@ -14,7 +14,7 @@ write_stake_history( fd_bank_t * bank, fd_capture_ctx_t * capture_ctx, fd_stake_history_t * stake_history ) { /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/sysvar/stake_history.rs#L12 */ - uchar enc[16392] = {0}; + uchar enc[FD_SYSVAR_STAKE_HISTORY_BINCODE_SZ] = {0}; fd_bincode_encode_ctx_t encode = { .data = enc, @@ -28,7 +28,7 @@ write_stake_history( fd_bank_t * bank, fd_stake_history_t * fd_sysvar_stake_history_read( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_spad_t * spad ) { + fd_stake_history_t * stake_history ) { fd_txn_account_t stake_rec[1]; int err = fd_txn_account_init_from_funk_readonly( stake_rec, &fd_sysvar_stake_history_id, funk, xid ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { @@ -43,8 +43,8 @@ fd_sysvar_stake_history_read( fd_funk_t * funk, return NULL; } - return fd_bincode_decode_spad( - stake_history, spad, + return fd_bincode_decode_static( + stake_history, stake_history, fd_txn_account_get_data( stake_rec ), fd_txn_account_get_data_len( stake_rec ), &err ); @@ -65,12 +65,12 @@ fd_sysvar_stake_history_update( fd_bank_t * bank fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_epoch_stake_history_entry_pair_t const * pair, - fd_spad_t * runtime_spad ) { - FD_SPAD_FRAME_BEGIN( runtime_spad ) { + fd_epoch_stake_history_entry_pair_t const * pair ) { - // Need to make this maybe zero copies of map... - fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); + fd_stake_history_t stake_history[1]; + if( FD_UNLIKELY( !fd_sysvar_stake_history_read( funk, xid, stake_history ) ) ) { + FD_LOG_CRIT(( "Failed to read stake history sysvar" )); + } if( stake_history->fd_stake_history_offset == 0 ) { stake_history->fd_stake_history_offset = stake_history->fd_stake_history_size - 1; @@ -92,5 +92,4 @@ fd_sysvar_stake_history_update( fd_bank_t * bank write_stake_history( bank, funk, xid, capture_ctx, stake_history ); - } FD_SPAD_FRAME_END; } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h index d5f68f8856e..5e8672203fc 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.h @@ -30,7 +30,7 @@ fd_sysvar_stake_history_init( fd_bank_t * bank, fd_stake_history_t * fd_sysvar_stake_history_read( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_spad_t * spad ); + fd_stake_history_t * stake_history ); /* Update the stake history sysvar account - called during epoch boundary */ void @@ -38,8 +38,7 @@ fd_sysvar_stake_history_update( fd_bank_t * bank fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, - fd_epoch_stake_history_entry_pair_t const * pair, - fd_spad_t * runtime_spad ); + fd_epoch_stake_history_entry_pair_t const * pair ); FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c b/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c index a2d1ace2373..ca18c2676e6 100644 --- a/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c +++ b/src/flamenco/runtime/sysvar/test_sysvar_stake_history.c @@ -56,13 +56,13 @@ test_sysvar_stake_history_update( fd_wksp_t * wksp ) { } }; fd_sysvar_stake_history_init( env->bank, env->funk, &env->xid, NULL ); - fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0, spad ); + fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0 ); fd_sysvar_cache_restore( env->bank, env->funk, &env->xid ); FD_TEST( fd_sysvar_cache_stake_history_is_valid( env->sysvar_cache )==1 ); fd_bank_slot_set( env->bank, 432000UL ); fd_bank_parent_slot_set( env->bank, 431999UL ); - fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0, spad ); + fd_sysvar_stake_history_update( env->bank, env->funk, &env->xid, NULL, &entry0 ); fd_sysvar_cache_restore( env->bank, env->funk, &env->xid ); FD_TEST( fd_sysvar_cache_stake_history_is_valid( env->sysvar_cache )==1 ); diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index b2e5fb4c9e6..70814816045 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -418,7 +418,7 @@ fd_runtime_fuzz_block_ctx_exec( fd_solfuzz_runner_t * runner, fd_solcap_writer_set_slot( capture_ctx->capture, fd_bank_slot_get( runner->bank ) ); } - fd_rewards_recalculate_partitioned_rewards( runner->banks, runner->bank, runner->funk, xid, capture_ctx, runner->spad ); + fd_rewards_recalculate_partitioned_rewards( runner->banks, runner->bank, runner->funk, xid, capture_ctx ); /* Process new epoch may push a new spad frame onto the runtime spad. We should make sure this frame gets cleared (if it was allocated) before executing the block. */ diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 2b763351f61..34835e53f5b 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -117,7 +117,8 @@ fd_runtime_fuzz_txn_ctx_create( fd_solfuzz_runner_t * runner, fd_slot_hashes_global_t * slot_hashes = fd_sysvar_slot_hashes_read( funk, &xid, runner->spad ); FD_TEST( slot_hashes ); - fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, &xid, runner->spad ); + fd_stake_history_t stake_history_[1]; + fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( funk, &xid, stake_history_ ); FD_TEST( stake_history ); fd_sol_sysvar_clock_t clock_[1]; diff --git a/src/flamenco/stakes/fd_stake_delegations.c b/src/flamenco/stakes/fd_stake_delegations.c index 89a883b7ea0..2c34c6e21be 100644 --- a/src/flamenco/stakes/fd_stake_delegations.c +++ b/src/flamenco/stakes/fd_stake_delegations.c @@ -201,7 +201,6 @@ fd_stake_delegations_update( fd_stake_delegations_t * stake_delegations, ulong deactivation_epoch, ulong credits_observed, double warmup_cooldown_rate ) { - fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations ); if( FD_UNLIKELY( !stake_delegation_pool ) ) { FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" )); diff --git a/src/flamenco/stakes/fd_stakes.c b/src/flamenco/stakes/fd_stakes.c index d59bc31ed5c..21283d6a3af 100644 --- a/src/flamenco/stakes/fd_stakes.c +++ b/src/flamenco/stakes/fd_stakes.c @@ -1,8 +1,8 @@ #include "fd_stakes.h" -#include "../runtime/fd_acc_mgr.h" #include "../runtime/fd_bank.h" #include "../runtime/fd_system_ids.h" #include "../runtime/program/fd_stake_program.h" +#include "../runtime/program/fd_vote_program.h" #include "../runtime/sysvar/fd_sysvar_stake_history.h" #include "fd_stake_delegations.h" @@ -25,11 +25,17 @@ fd_stake_weights_by_node( fd_vote_states_t const * vote_states, return weights_cnt; } -static void -compute_stake_delegations( fd_bank_t * bank, - fd_stake_delegations_t const * stake_delegations, - fd_stake_history_t const * history, - ulong * new_rate_activation_epoch ) { +/* We need to update the amount of stake that each vote account has for + the given epoch. This can only be done after the stake history + sysvar has been updated. + + https://github.com/anza-xyz/agave/blob/v3.0.4/runtime/src/stakes.rs#L471 */ +void +fd_refresh_vote_accounts( fd_bank_t * bank, + fd_stake_delegations_t const * stake_delegations, + fd_stake_history_t const * history, + ulong * new_rate_activation_epoch ) { + ulong epoch = fd_bank_epoch_get( bank ); ulong total_stake = 0UL; @@ -49,8 +55,6 @@ compute_stake_delegations( fd_bank_t * bank, fd_stake_delegations_iter_next( iter ) ) { fd_stake_delegation_t const * stake_delegation = fd_stake_delegations_iter_ele( iter ); - // Skip any delegations that are not in the delegation pool - fd_delegation_t delegation = { .voter_pubkey = stake_delegation->vote_account, .stake = stake_delegation->stake, @@ -77,37 +81,34 @@ compute_stake_delegations( fd_bank_t * bank, fd_bank_vote_states_end_locking_modify( bank ); } -/* Refresh vote accounts. - - This updates the epoch bank stakes vote_accounts cache - that is, the total amount - of delegated stake each vote account has, using the current delegation values from inside each - stake account. Contrary to the Agave equivalent, it also merges the stakes cache vote accounts with the - new vote account keys from this epoch. - - https://github.com/solana-labs/solana/blob/c091fd3da8014c0ef83b626318018f238f506435/runtime/src/stakes.rs#L562 */ +/* https://github.com/anza-xyz/agave/blob/v3.0.4/runtime/src/stakes.rs#L280 */ void -fd_refresh_vote_accounts( fd_bank_t * bank, +fd_stakes_activate_epoch( fd_bank_t * bank, + fd_funk_t * funk, + fd_funk_txn_xid_t const * xid, + fd_capture_ctx_t * capture_ctx, fd_stake_delegations_t const * stake_delegations, - fd_stake_history_t const * history, ulong * new_rate_activation_epoch ) { - compute_stake_delegations( - bank, - stake_delegations, - history, - new_rate_activation_epoch ); -} + /* First, we need to accumulate the stats for the current amount of + effective, activating, and deactivating stake for the current + epoch. Once this is computed, we can add update our stake history + sysvar. Afterward, we can refresh the stake values for the vote + accounts for the new epoch. */ -static void -accumulate_stake_cache_delegations( fd_stake_delegations_t const * stake_delegations, - fd_stake_history_t const * history, - ulong * new_rate_activation_epoch, - fd_stake_history_entry_t * accumulator, - ulong epoch ) { + fd_stake_history_t stake_history[1]; + if( FD_UNLIKELY( !fd_sysvar_stake_history_read( funk, xid, stake_history ) ) ) { + FD_LOG_ERR(( "StakeHistory sysvar is missing from sysvar cache" )); + } - ulong effective = 0UL; - ulong activating = 0UL; - ulong deactivating = 0UL; + fd_epoch_stake_history_entry_pair_t new_elem = { + .epoch = fd_bank_epoch_get( bank ), + .entry = { + .effective = 0UL, + .activating = 0UL, + .deactivating = 0UL + } + }; fd_stake_delegations_iter_t iter_[1]; for( fd_stake_delegations_iter_t * iter = fd_stake_delegations_iter_init( iter_, stake_delegations ); @@ -125,82 +126,29 @@ accumulate_stake_cache_delegations( fd_stake_delegations_t const * stake_delegat fd_stake_history_entry_t new_entry = fd_stake_activating_and_deactivating( &delegation, - epoch, - history, + fd_bank_epoch_get( bank ), + stake_history, new_rate_activation_epoch ); - effective += new_entry.effective; - activating += new_entry.activating; - deactivating += new_entry.deactivating; + new_elem.entry.effective += new_entry.effective; + new_elem.entry.activating += new_entry.activating; + new_elem.entry.deactivating += new_entry.deactivating; } - accumulator->effective += effective; - accumulator->activating += activating; - accumulator->deactivating += deactivating; - -} - -/* Accumulates information about epoch stakes into `temp_info`, which is a temporary cache - used to save intermediate state about stake and vote accounts to avoid them from having to - be recomputed on every access, especially at the epoch boundary. Also collects stats in `accumulator` */ -void -fd_accumulate_stake_infos( ulong epoch, - fd_stake_delegations_t const * stake_delegations, - fd_stake_history_t const * history, - ulong * new_rate_activation_epoch, - fd_stake_history_entry_t * accumulator ) { - - accumulate_stake_cache_delegations( - stake_delegations, - history, - new_rate_activation_epoch, - accumulator, - epoch ); + fd_sysvar_stake_history_update( bank, funk, xid, capture_ctx, &new_elem ); -} - -/* https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/runtime/src/stakes.rs#L169 */ -void -fd_stakes_activate_epoch( fd_bank_t * bank, - fd_funk_t * funk, - fd_funk_txn_xid_t const * xid, - fd_capture_ctx_t * capture_ctx, - fd_stake_delegations_t const * stake_delegations, - ulong * new_rate_activation_epoch, - fd_spad_t * runtime_spad ) { - - /* Current stake delegations: list of all current delegations in stake_delegations - https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/runtime/src/stakes.rs#L180 */ - /* Add a new entry to the Stake History sysvar for the previous epoch - https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/runtime/src/stakes.rs#L181-L192 */ + if( FD_UNLIKELY( !fd_sysvar_stake_history_read( funk, xid, stake_history ) ) ) { + FD_LOG_ERR(( "StakeHistory sysvar is missing from sysvar cache" )); + } - fd_stake_history_t const * history = fd_sysvar_stake_history_read( funk, xid, runtime_spad ); - if( FD_UNLIKELY( !history ) ) FD_LOG_ERR(( "StakeHistory sysvar is missing from sysvar cache" )); + /* Now increment the epoch and recompute the stakes for the vote + accounts for the new epoch value. */ - fd_stake_history_entry_t accumulator = { - .effective = 0UL, - .activating = 0UL, - .deactivating = 0UL - }; + fd_bank_epoch_set( bank, fd_bank_epoch_get( bank ) + 1UL ); - /* Accumulate stats for stake accounts */ - fd_accumulate_stake_infos( - fd_bank_epoch_get( bank ), - stake_delegations, - history, - new_rate_activation_epoch, - &accumulator ); - - /* https://github.com/anza-xyz/agave/blob/v2.1.6/runtime/src/stakes.rs#L359 */ - fd_epoch_stake_history_entry_pair_t new_elem = { - .epoch = fd_bank_epoch_get( bank ), - .entry = { - .effective = accumulator.effective, - .activating = accumulator.activating, - .deactivating = accumulator.deactivating - } - }; - - fd_sysvar_stake_history_update( bank, funk, xid, capture_ctx, &new_elem, runtime_spad ); + fd_refresh_vote_accounts( bank, + stake_delegations, + stake_history, + new_rate_activation_epoch ); } @@ -221,78 +169,84 @@ write_stake_state( fd_txn_account_t * stake_acc_rec, return 0; } -/* Removes stake delegation from stakes */ -static void -fd_stakes_remove_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ) { +void +fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, + fd_bank_t * bank ) { + + if( !stake_account->is_mutable ) return; fd_stake_delegations_t * stake_delegations_delta = fd_bank_stake_delegations_delta_locking_modify( bank ); if( FD_UNLIKELY( !stake_delegations_delta ) ) { FD_LOG_CRIT(( "unable to retrieve join to stake delegation delta" )); } - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); - - fd_bank_stake_delegations_delta_end_locking_modify( bank ); -} - -/* Updates stake delegation in epoch stakes */ -static void -fd_stakes_upsert_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ) { - - fd_stake_delegations_t * stake_delegations_delta = fd_bank_stake_delegations_delta_locking_modify( bank ); - if( FD_UNLIKELY( !stake_delegations_delta ) ) { - FD_LOG_CRIT(( "unable to retrieve join to stake delegation delta" )); + if( fd_txn_account_get_lamports( stake_account )==0UL ) { + fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_bank_stake_delegations_delta_end_locking_modify( bank ); + return; } fd_stake_state_v2_t stake_state; int err = fd_stake_get_state( stake_account, &stake_state ); - if( FD_UNLIKELY( err != 0 ) ) { - FD_LOG_WARNING(( "Failed to get stake state" )); + if( FD_UNLIKELY( err!=0 ) ) { + fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( !fd_stake_state_v2_is_stake( &stake_state ) ) ) { - FD_LOG_WARNING(( "Not a valid stake" )); + fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_bank_stake_delegations_delta_end_locking_modify( bank ); + return; + } + + if( FD_UNLIKELY( fd_stake_state_v2_is_uninitialized( &stake_state ) ) ) { + fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( stake_state.inner.stake.stake.delegation.stake==0UL ) ) { - FD_LOG_WARNING(( "Stake is empty" )); + fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } - fd_stake_delegations_update( - stake_delegations_delta, - stake_account->pubkey, - &stake_state.inner.stake.stake.delegation.voter_pubkey, - stake_state.inner.stake.stake.delegation.stake, - stake_state.inner.stake.stake.delegation.activation_epoch, - stake_state.inner.stake.stake.delegation.deactivation_epoch, - stake_state.inner.stake.stake.credits_observed, - stake_state.inner.stake.stake.delegation.warmup_cooldown_rate ); + fd_stake_delegations_update( stake_delegations_delta, + stake_account->pubkey, + &stake_state.inner.stake.stake.delegation.voter_pubkey, + stake_state.inner.stake.stake.delegation.stake, + stake_state.inner.stake.stake.delegation.activation_epoch, + stake_state.inner.stake.stake.delegation.deactivation_epoch, + stake_state.inner.stake.stake.credits_observed, + stake_state.inner.stake.stake.delegation.warmup_cooldown_rate ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); } void -fd_update_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ) { - - int is_empty = fd_txn_account_get_lamports( stake_account )==0UL; - int is_uninit = 1; - if( fd_txn_account_get_data_len( stake_account )>=4UL ) { - uint prefix = FD_LOAD( uint, fd_txn_account_get_data( stake_account ) ); - is_uninit = ( prefix==fd_stake_state_v2_enum_uninitialized ); +fd_stakes_update_vote_state( fd_txn_account_t * vote_account, + fd_bank_t * bank ) { + + if( !vote_account->is_mutable ) return; + + fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); + + if( fd_txn_account_get_lamports( vote_account )==0UL ) { + fd_vote_states_remove( vote_states, vote_account->pubkey ); + fd_bank_vote_states_end_locking_modify( bank ); + return; } - if( is_empty || is_uninit ) { - fd_stakes_remove_stake_delegation( stake_account, bank ); - } else { - fd_stakes_upsert_stake_delegation( stake_account, bank ); + if( !fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { + fd_vote_states_remove( vote_states, vote_account->pubkey ); + fd_bank_vote_states_end_locking_modify( bank ); + return; } + + fd_vote_states_update_from_account( vote_states, + vote_account->pubkey, + fd_txn_account_get_data( vote_account ), + fd_txn_account_get_data_len( vote_account ) ); + fd_bank_vote_states_end_locking_modify( bank ); } diff --git a/src/flamenco/stakes/fd_stakes.h b/src/flamenco/stakes/fd_stakes.h index fba1bc5be8e..ed86cd13a4c 100644 --- a/src/flamenco/stakes/fd_stakes.h +++ b/src/flamenco/stakes/fd_stakes.h @@ -32,8 +32,7 @@ fd_stakes_activate_epoch( fd_bank_t * bank, fd_funk_txn_xid_t const * xid, fd_capture_ctx_t * capture_ctx, fd_stake_delegations_t const * stake_delegations, - ulong * new_rate_activation_epoch, - fd_spad_t * runtime_spad ); + ulong * new_rate_activation_epoch ); fd_stake_history_entry_t stake_and_activating( fd_delegation_t const * delegation, @@ -57,20 +56,23 @@ fd_refresh_vote_accounts( fd_bank_t * bank, fd_stake_history_t const * history, ulong * new_rate_activation_epoch ); +/* fd_stakes_update_delegation is used to maintain the in-memory cache + of the stake delegations that is used at the epoch boundary. Entries + in the cache will be inserted/updated/removed based on the state of + the stake account. */ + void -fd_accumulate_stake_infos( ulong epoch, - fd_stake_delegations_t const * stake_delegations, - fd_stake_history_t const * history, - ulong * new_rate_activation_epoch, - fd_stake_history_entry_t * accumulator ); +fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, + fd_bank_t * bank ); -/* fd_store_stake_delegation is used to update fd_stake_delegations_t - based on a specific transaction account. If the account is empty or - uninitialized, it is removed from the stake delegation map. */ +/* fd_stakes_update_vote_state is used to maintain the in-memory cache + of the vote states that is used at the epoch boundary. Entries in + the cache will be inserted/updated/removed based on the state of + the vote account. */ void -fd_update_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ); +fd_stakes_update_vote_state( fd_txn_account_t * vote_account, + fd_bank_t * bank ); FD_PROTOTYPES_END diff --git a/src/flamenco/stakes/fd_vote_states.c b/src/flamenco/stakes/fd_vote_states.c index 8e3b878ac3e..2eb03790a20 100644 --- a/src/flamenco/stakes/fd_vote_states.c +++ b/src/flamenco/stakes/fd_vote_states.c @@ -402,7 +402,8 @@ fd_vote_states_reset_stakes( fd_vote_states_t * vote_states ) { FD_LOG_CRIT(( "unable to retrieve vote state" )); } - vote_state->stake = 0UL; + vote_state->stake = 0UL; + vote_state->rewards = 0UL; } } diff --git a/src/flamenco/stakes/fd_vote_states.h b/src/flamenco/stakes/fd_vote_states.h index c041c5a6dbb..8b9c0fdcc78 100644 --- a/src/flamenco/stakes/fd_vote_states.h +++ b/src/flamenco/stakes/fd_vote_states.h @@ -59,6 +59,7 @@ struct fd_vote_state_ele { ulong last_vote_slot; long last_vote_timestamp; uchar commission; + ulong rewards; ulong credits_cnt; ushort epoch [ EPOCH_CREDITS_MAX ]; @@ -221,15 +222,15 @@ fd_vote_states_max( fd_vote_states_t const * vote_states ); ulong fd_vote_states_cnt( fd_vote_states_t const * vote_states ); -/* Iterator API for vote states. The iterator is initialized with a - call to fd_vote_states_iter_init. The caller is responsible for - managing the memory for the iterator. It is safe to call +/* Iterator API for vote states. The iterator is initialized with a + call to fd_vote_states_iter_init. The caller is responsible for + managing the memory for the iterator. It is safe to call fd_vote_states_iter_next if the result of - fd_vote_states_iter_done() ==0. It is safe to call + fd_vote_states_iter_done() ==0. It is safe to call fd_vote_states_iter_ele() to get the current vote state. As a note, it is safe to modify the vote state acquired from fd_vote_states_iter_ele() as long as the next_ field is not modified - (which the caller should never do). It is unsafe to insert or remove + (which the caller should never do). It is unsafe to insert or remove fd_vote_state_ele_t from the vote states struct while iterating. Under the hood, the iterator is just a wrapper over the iterator in diff --git a/src/flamenco/types/fd_fuzz_types.h b/src/flamenco/types/fd_fuzz_types.h index 1f09b86808f..50a2634c464 100644 --- a/src/flamenco/types/fd_fuzz_types.h +++ b/src/flamenco/types/fd_fuzz_types.h @@ -953,156 +953,17 @@ void *fd_stake_reward_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { return mem; } -void *fd_vote_reward_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_vote_reward_t *self = (fd_vote_reward_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_vote_reward_t); - fd_vote_reward_new(mem); - fd_pubkey_generate( &self->pubkey, alloc_mem, rng ); - self->vote_rewards = fd_rng_ulong( rng ); - self->commission = fd_rng_uchar( rng ); - self->needs_store = fd_rng_uchar( rng ); - return mem; -} - -void *fd_point_value_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_point_value_t *self = (fd_point_value_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_point_value_t); - fd_point_value_new(mem); - self->rewards = fd_rng_ulong( rng ); - self->points = fd_rng_uint128( rng ); - return mem; -} - -void *fd_partitioned_stake_rewards_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_partitioned_stake_rewards_t *self = (fd_partitioned_stake_rewards_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_partitioned_stake_rewards_t); - fd_partitioned_stake_rewards_new(mem); - self->partitions_len = fd_rng_ulong( rng ) % 8; - ulong total_count = 0UL; - for( ulong i=0; i < 4096; i++ ) { - self->partitions_lengths[i] = fd_rng_ulong( rng ) % 8; - total_count += self->partitions_lengths[ i ]; - } - self->pool = fd_partitioned_stake_rewards_pool_join_new( alloc_mem, total_count ); - self->partitions = fd_partitioned_stake_rewards_dlist_join_new( alloc_mem, self->partitions_len ); - for( ulong i=0; i < self->partitions_len; i++ ) { - fd_partitioned_stake_rewards_dlist_new( &self->partitions[ i ] ); - for( ulong j=0; j < self->partitions_lengths[ i ]; j++ ) { - fd_stake_reward_t * ele = fd_partitioned_stake_rewards_pool_ele_acquire( self->pool ); - fd_stake_reward_new( ele ); - fd_stake_reward_generate( ele, alloc_mem, rng ); - fd_partitioned_stake_rewards_dlist_ele_push_tail( &self->partitions[ i ], ele, self->pool ); - } - } - return mem; -} - -void *fd_stake_reward_calculation_partitioned_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_stake_reward_calculation_partitioned_t *self = (fd_stake_reward_calculation_partitioned_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_stake_reward_calculation_partitioned_t); - fd_stake_reward_calculation_partitioned_new(mem); - fd_partitioned_stake_rewards_generate( &self->partitioned_stake_rewards, alloc_mem, rng ); - self->total_stake_rewards_lamports = fd_rng_ulong( rng ); - return mem; -} - -void *fd_stake_reward_calculation_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_stake_reward_calculation_t *self = (fd_stake_reward_calculation_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_stake_reward_calculation_t); - fd_stake_reward_calculation_new(mem); - self->stake_rewards_len = fd_rng_ulong( rng ) % 8; - self->pool = fd_stake_reward_calculation_pool_join_new( alloc_mem, self->stake_rewards_len ); - self->stake_rewards = fd_stake_reward_calculation_dlist_join_new( alloc_mem, self->stake_rewards_len ); - fd_stake_reward_calculation_dlist_new( self->stake_rewards ); - for( ulong i=0; i < self->stake_rewards_len; i++ ) { - fd_stake_reward_t * ele = fd_stake_reward_calculation_pool_ele_acquire( self->pool ); - fd_stake_reward_new( ele ); - fd_stake_reward_generate( ele, alloc_mem, rng ); - fd_stake_reward_calculation_dlist_ele_push_tail( self->stake_rewards, ele, self->pool ); - } - self->total_stake_rewards_lamports = fd_rng_ulong( rng ); - return mem; -} - -void *fd_calculate_stake_vote_rewards_result_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_calculate_stake_vote_rewards_result_t *self = (fd_calculate_stake_vote_rewards_result_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_calculate_stake_vote_rewards_result_t); - fd_calculate_stake_vote_rewards_result_new(mem); - fd_stake_reward_calculation_generate( &self->stake_reward_calculation, alloc_mem, rng ); - ulong vote_reward_map_len = fd_rng_ulong( rng ) % 8; - self->vote_reward_map_pool = fd_vote_reward_t_map_join_new( alloc_mem, fd_ulong_max( vote_reward_map_len, 15000 ) ); - 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_generate( &node->elem, alloc_mem, rng ); - fd_vote_reward_t_map_insert( self->vote_reward_map_pool, &self->vote_reward_map_root, node ); - } - return mem; -} - -void *fd_calculate_validator_rewards_result_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_calculate_validator_rewards_result_t *self = (fd_calculate_validator_rewards_result_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_calculate_validator_rewards_result_t); - fd_calculate_validator_rewards_result_new(mem); - fd_calculate_stake_vote_rewards_result_generate( &self->calculate_stake_vote_rewards_result, alloc_mem, rng ); - fd_point_value_generate( &self->point_value, alloc_mem, rng ); - return mem; -} - void *fd_partitioned_rewards_calculation_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_partitioned_rewards_calculation_t *self = (fd_partitioned_rewards_calculation_t *) mem; *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_partitioned_rewards_calculation_t); fd_partitioned_rewards_calculation_new(mem); - ulong vote_reward_map_len = fd_rng_ulong( rng ) % 8; - self->vote_reward_map_pool = fd_vote_reward_t_map_join_new( alloc_mem, fd_ulong_max( vote_reward_map_len, 15000 ) ); - 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_generate( &node->elem, alloc_mem, rng ); - fd_vote_reward_t_map_insert( self->vote_reward_map_pool, &self->vote_reward_map_root, node ); - } - fd_stake_reward_calculation_partitioned_generate( &self->stake_rewards_by_partition, alloc_mem, rng ); + self->validator_points = fd_rng_uint128( rng ); self->old_vote_balance_and_staked = fd_rng_ulong( rng ); self->validator_rewards = fd_rng_ulong( rng ); self->validator_rate = fd_rng_double_o( rng ); self->foundation_rate = fd_rng_double_o( rng ); self->prev_epoch_duration_in_years = fd_rng_double_o( rng ); self->capitalization = fd_rng_ulong( rng ); - fd_point_value_generate( &self->point_value, alloc_mem, rng ); - return mem; -} - -void *fd_start_block_height_and_rewards_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_start_block_height_and_rewards_t *self = (fd_start_block_height_and_rewards_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_start_block_height_and_rewards_t); - fd_start_block_height_and_rewards_new(mem); - self->distribution_starting_block_height = fd_rng_ulong( rng ); - fd_partitioned_stake_rewards_generate( &self->partitioned_stake_rewards, alloc_mem, rng ); - return mem; -} - -void *fd_fd_epoch_reward_status_inner_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_fd_epoch_reward_status_inner_t *self = (fd_fd_epoch_reward_status_inner_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_fd_epoch_reward_status_inner_t); - fd_fd_epoch_reward_status_inner_new(mem); - fd_start_block_height_and_rewards_generate( &self->Active, alloc_mem, rng ); - return mem; -} - -void fd_epoch_reward_status_inner_generate( fd_epoch_reward_status_inner_t * self, void **alloc_mem, uint discriminant, fd_rng_t * rng ) { - switch (discriminant) { - case 0: { - fd_start_block_height_and_rewards_generate( &self->Active, alloc_mem, rng ); - break; - } - } -} -void *fd_epoch_reward_status_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_epoch_reward_status_t *self = (fd_epoch_reward_status_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_epoch_reward_status_t); - fd_epoch_reward_status_new(mem); - self->discriminant = fd_rng_uint( rng ) % 2; - fd_epoch_reward_status_inner_generate( &self->inner, alloc_mem, self->discriminant, rng ); return mem; } @@ -2368,15 +2229,6 @@ void *fd_txn_result_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { return mem; } -void *fd_pubkey_rewardinfo_pair_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { - fd_pubkey_rewardinfo_pair_t *self = (fd_pubkey_rewardinfo_pair_t *) mem; - *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_pubkey_rewardinfo_pair_t); - fd_pubkey_rewardinfo_pair_new(mem); - fd_pubkey_generate( &self->pubkey, alloc_mem, rng ); - fd_reward_info_generate( &self->reward_info, alloc_mem, rng ); - return mem; -} - void *fd_calculated_stake_points_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_calculated_stake_points_t *self = (fd_calculated_stake_points_t *) mem; *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_calculated_stake_points_t); diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index 0524fe535c3..d1ff7ca2fb0 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -5598,565 +5598,9 @@ void fd_stake_reward_walk( void * w, fd_stake_reward_t const * self, fd_types_wa fun( w, &self->valid, "valid", FD_FLAMENCO_TYPE_UCHAR, "uchar", level, 0 ); fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_stake_reward", level--, 0 ); } -int fd_vote_reward_encode( fd_vote_reward_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_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; -} -static inline int fd_vote_reward_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( (ulong)ctx->data + 42UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = (void *)( (ulong)ctx->data + 42UL ); - return 0; -} -static void fd_vote_reward_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_vote_reward_t * self = (fd_vote_reward_t *)struct_mem; - fd_pubkey_decode_inner( &self->pubkey, alloc_mem, 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 ); -} -void * fd_vote_reward_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_vote_reward_t * self = (fd_vote_reward_t *)mem; - fd_vote_reward_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_vote_reward_t); - void * * alloc_mem = &alloc_region; - fd_vote_reward_decode_inner( mem, alloc_mem, ctx ); - return self; -} -void fd_vote_reward_walk( void * w, fd_vote_reward_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_vote_reward", level++, 0 ); - fd_pubkey_walk( w, &self->pubkey, fun, "pubkey", level, 0 ); - fun( w, &self->vote_rewards, "vote_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); - fun( w, &self->commission, "commission", FD_FLAMENCO_TYPE_UCHAR, "uchar", level, 0 ); - fun( w, &self->needs_store, "needs_store", FD_FLAMENCO_TYPE_UCHAR, "uchar", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_vote_reward", level--, 0 ); -} -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; -} -static inline int fd_point_value_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( (ulong)ctx->data + 24UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = (void *)( (ulong)ctx->data + 24UL ); - return 0; -} -static void fd_point_value_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_point_value_t * self = (fd_point_value_t *)struct_mem; - fd_bincode_uint64_decode_unsafe( &self->rewards, ctx ); - fd_bincode_uint128_decode_unsafe( &self->points, ctx ); -} -void * fd_point_value_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_point_value_t * self = (fd_point_value_t *)mem; - fd_point_value_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_point_value_t); - void * * alloc_mem = &alloc_region; - fd_point_value_decode_inner( mem, alloc_mem, ctx ); - return self; -} -void fd_point_value_walk( void * w, fd_point_value_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_point_value", level++, 0 ); - fun( w, &self->rewards, "rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); - fun( w, &self->points, "points", FD_FLAMENCO_TYPE_UINT128, "uint128", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_point_value", level--, 0 ); -} -int fd_partitioned_stake_rewards_encode( fd_partitioned_stake_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { - int err; - if( self->partitions ) { - err = fd_bincode_uint64_encode( self->partitions_len, ctx ); - if( FD_UNLIKELY( err ) ) return err; - for( ulong i=0; i < 4096; i++ ) { - err = fd_bincode_uint64_encode( self->partitions_lengths[ i ], ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - for( ulong i=0; i < self->partitions_len; i++ ) { - for( fd_partitioned_stake_rewards_dlist_iter_t iter = fd_partitioned_stake_rewards_dlist_iter_fwd_init( &self->partitions[ i ], self->pool ); - !fd_partitioned_stake_rewards_dlist_iter_done( iter, &self->partitions[ i ], self->pool ); - iter = fd_partitioned_stake_rewards_dlist_iter_fwd_next( iter, &self->partitions[ i ], self->pool ) ) { - fd_stake_reward_t * ele = fd_partitioned_stake_rewards_dlist_iter_ele( iter, &self->partitions[ i ], self->pool ); - err = fd_stake_reward_encode( ele, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - } - } else { - err = fd_bincode_uint64_encode( self->partitions_len, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - return FD_BINCODE_SUCCESS; -} -int fd_partitioned_stake_rewards_encode_global( fd_partitioned_stake_rewards_global_t const * self, fd_bincode_encode_ctx_t * ctx ) { - int err; - return FD_BINCODE_SUCCESS; -} -static int fd_partitioned_stake_rewards_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - ulong partitions_len; - err = fd_bincode_uint64_decode( &partitions_len, ctx ); - if( FD_UNLIKELY( err ) ) return err; - ulong total_count = 0UL; - ulong partitions_lengths[4096]; - for( ulong i=0; i<4096; i++ ) { - err = fd_bincode_uint64_decode( partitions_lengths + i, ctx ); - total_count+=partitions_lengths[ i ]; - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - *total_sz += fd_partitioned_stake_rewards_pool_align() + fd_partitioned_stake_rewards_pool_footprint( total_count ); - *total_sz += fd_partitioned_stake_rewards_dlist_align() + fd_partitioned_stake_rewards_dlist_footprint()*partitions_len; - for( ulong i=0; i < partitions_len; i++ ) { - err = fd_stake_reward_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY ( err ) ) return err; - } - return 0; -} -int fd_partitioned_stake_rewards_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_partitioned_stake_rewards_t); - void const * start_data = ctx->data; - int err = fd_partitioned_stake_rewards_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_partitioned_stake_rewards_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_partitioned_stake_rewards_t * self = (fd_partitioned_stake_rewards_t *)struct_mem; - fd_bincode_uint64_decode_unsafe( &self->partitions_len, ctx ); - ulong total_count = 0UL; - for( ulong i=0; i < 4096; i++ ) { - fd_bincode_uint64_decode_unsafe( self->partitions_lengths + i, ctx ); - total_count += self->partitions_lengths[ i ]; - } - self->pool = fd_partitioned_stake_rewards_pool_join_new( alloc_mem, total_count ); - self->partitions = fd_partitioned_stake_rewards_dlist_join_new( alloc_mem, self->partitions_len ); - for( ulong i=0; i < self->partitions_len; i++ ) { - fd_partitioned_stake_rewards_dlist_new( &self->partitions[ i ] ); - for( ulong j=0; j < self->partitions_lengths[ i ]; j++ ) { - fd_stake_reward_t * ele = fd_partitioned_stake_rewards_pool_ele_acquire( self->pool ); - fd_stake_reward_new( ele ); - fd_stake_reward_decode_inner( ele, alloc_mem, ctx ); - fd_partitioned_stake_rewards_dlist_ele_push_tail( &self->partitions[ i ], ele, self->pool ); - } - } -} -void * fd_partitioned_stake_rewards_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_partitioned_stake_rewards_t * self = (fd_partitioned_stake_rewards_t *)mem; - fd_partitioned_stake_rewards_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_partitioned_stake_rewards_t); - void * * alloc_mem = &alloc_region; - fd_partitioned_stake_rewards_decode_inner( mem, alloc_mem, ctx ); - return self; -} -static void fd_partitioned_stake_rewards_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_partitioned_stake_rewards_global_t * self = (fd_partitioned_stake_rewards_global_t *)struct_mem; - fd_bincode_uint64_decode_unsafe( &self->partitions_len, ctx ); - ulong total_count = 0UL; - for( ulong i=0; i < 4096; i++ ) { - fd_bincode_uint64_decode_unsafe( self->partitions_lengths + i, ctx ); - total_count += self->partitions_lengths[ i ]; - } - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_partitioned_stake_rewards_pool_align() ); - fd_stake_reward_t * pool = fd_partitioned_stake_rewards_pool_join_new( alloc_mem, total_count ); - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_partitioned_stake_rewards_dlist_align() ); - fd_partitioned_stake_rewards_dlist_t * partitions = fd_partitioned_stake_rewards_dlist_join_new( alloc_mem, self->partitions_len ); - for( ulong i=0; i < self->partitions_len; i++ ) { - fd_partitioned_stake_rewards_dlist_new( &partitions[ i ] ); - for( ulong j=0; j < self->partitions_lengths[ i ]; j++ ) { - fd_stake_reward_t * ele = fd_partitioned_stake_rewards_pool_ele_acquire( pool ); - fd_stake_reward_new( ele ); - fd_stake_reward_decode_inner( ele, alloc_mem, ctx ); - fd_partitioned_stake_rewards_dlist_ele_push_tail( &partitions[ i ], ele, pool ); - } - } - self->pool_offset = (ulong)fd_partitioned_stake_rewards_pool_leave( pool ) - (ulong)struct_mem; - self->partitions_offset = (ulong)fd_partitioned_stake_rewards_dlist_leave( partitions ) - (ulong)struct_mem; -} -void * fd_partitioned_stake_rewards_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_partitioned_stake_rewards_global_t * self = (fd_partitioned_stake_rewards_global_t *)mem; - fd_partitioned_stake_rewards_new( (fd_partitioned_stake_rewards_t *)self ); - void * alloc_region = (uchar *)mem + sizeof(fd_partitioned_stake_rewards_global_t); - void * * alloc_mem = &alloc_region; - fd_partitioned_stake_rewards_decode_inner_global( mem, alloc_mem, ctx ); - return self; -} -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_walk( void * w, fd_partitioned_stake_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_partitioned_stake_rewards", level++, 0 ); - if( self->partitions ) { - for( ulong i=0; i < self->partitions_len; i++ ) { - for( fd_partitioned_stake_rewards_dlist_iter_t iter = fd_partitioned_stake_rewards_dlist_iter_fwd_init( &self->partitions[ i ], self->pool ); - !fd_partitioned_stake_rewards_dlist_iter_done( iter, &self->partitions[ i ], self->pool ); - iter = fd_partitioned_stake_rewards_dlist_iter_fwd_next( iter, &self->partitions[ i ], self->pool ) ) { - fd_stake_reward_t * ele = fd_partitioned_stake_rewards_dlist_iter_ele( iter, &self->partitions[ i ], self->pool ); - fd_stake_reward_walk( w, ele, fun, "fd_stake_reward_t", level, 0 ); - } - } - } - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_partitioned_stake_rewards", level--, 0 ); -} -ulong fd_partitioned_stake_rewards_size( fd_partitioned_stake_rewards_t const * self ) { - ulong size = 0; - size += sizeof(ulong); - size += 4096 * sizeof(ulong); - if( self->partitions ) { - for( ulong i=0; i < self->partitions_len; i++ ) { - for( fd_partitioned_stake_rewards_dlist_iter_t iter = fd_partitioned_stake_rewards_dlist_iter_fwd_init( &self->partitions[ i ], self->pool ); - !fd_partitioned_stake_rewards_dlist_iter_done( iter, &self->partitions[ i ], self->pool ); - iter = fd_partitioned_stake_rewards_dlist_iter_fwd_next( iter, &self->partitions[ i ], self->pool ) ) { - fd_stake_reward_t * ele = fd_partitioned_stake_rewards_dlist_iter_ele( iter, &self->partitions[ i ], self->pool ); - size += fd_stake_reward_size( ele ); - } - } - } - return size; -} - -ulong fd_partitioned_stake_rewards_size_global( fd_partitioned_stake_rewards_global_t const * self ) { - ulong size = 0; - FD_LOG_CRIT(( "FIXME: not implemented" )); - return size; -} - -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_partitioned_stake_rewards_encode( &self->partitioned_stake_rewards, 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; -} -static int fd_stake_reward_calculation_partitioned_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - err = fd_partitioned_stake_rewards_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - return 0; -} -int fd_stake_reward_calculation_partitioned_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_stake_reward_calculation_partitioned_t); - void const * start_data = ctx->data; - int err = fd_stake_reward_calculation_partitioned_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_stake_reward_calculation_partitioned_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_stake_reward_calculation_partitioned_t * self = (fd_stake_reward_calculation_partitioned_t *)struct_mem; - fd_partitioned_stake_rewards_decode_inner( &self->partitioned_stake_rewards, alloc_mem, ctx ); - fd_bincode_uint64_decode_unsafe( &self->total_stake_rewards_lamports, ctx ); -} -void * fd_stake_reward_calculation_partitioned_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_stake_reward_calculation_partitioned_t * self = (fd_stake_reward_calculation_partitioned_t *)mem; - fd_stake_reward_calculation_partitioned_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_stake_reward_calculation_partitioned_t); - void * * alloc_mem = &alloc_region; - fd_stake_reward_calculation_partitioned_decode_inner( mem, alloc_mem, ctx ); - return self; -} -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) ); - fd_partitioned_stake_rewards_new( &self->partitioned_stake_rewards ); -} -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, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_stake_reward_calculation_partitioned", level++, 0 ); - fd_partitioned_stake_rewards_walk( w, &self->partitioned_stake_rewards, fun, "partitioned_stake_rewards", level, 0 ); - fun( w, &self->total_stake_rewards_lamports, "total_stake_rewards_lamports", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_stake_reward_calculation_partitioned", level--, 0 ); -} -ulong fd_stake_reward_calculation_partitioned_size( fd_stake_reward_calculation_partitioned_t const * self ) { - ulong size = 0; - size += fd_partitioned_stake_rewards_size( &self->partitioned_stake_rewards ); - size += sizeof(ulong); - return size; -} - -int fd_stake_reward_calculation_encode( fd_stake_reward_calculation_t const * self, fd_bincode_encode_ctx_t * ctx ) { - int err; - if( self->stake_rewards ) { - err = fd_bincode_uint64_encode( self->stake_rewards_len, ctx ); - if( FD_UNLIKELY( err ) ) return err; - for( fd_stake_reward_calculation_dlist_iter_t iter = fd_stake_reward_calculation_dlist_iter_fwd_init( self->stake_rewards, self->pool ); - !fd_stake_reward_calculation_dlist_iter_done( iter, self->stake_rewards, self->pool ); - iter = fd_stake_reward_calculation_dlist_iter_fwd_next( iter, self->stake_rewards, self->pool ) ) { - fd_stake_reward_t * ele = fd_stake_reward_calculation_dlist_iter_ele( iter, self->stake_rewards, self->pool ); - err = fd_stake_reward_encode( ele, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - } else { - err = fd_bincode_uint64_encode( self->stake_rewards_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; -} -static int fd_stake_reward_calculation_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - ulong stake_rewards_len; - err = fd_bincode_uint64_decode( &stake_rewards_len, ctx ); - if( FD_UNLIKELY( err ) ) return err; - *total_sz += fd_stake_reward_calculation_pool_align() + fd_stake_reward_calculation_pool_footprint( stake_rewards_len ); - *total_sz += fd_stake_reward_calculation_dlist_align() + fd_stake_reward_calculation_dlist_footprint()*stake_rewards_len; - for( ulong i=0; i < stake_rewards_len; i++ ) { - err = fd_stake_reward_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY ( err ) ) return err; - } - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - return 0; -} -int fd_stake_reward_calculation_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_stake_reward_calculation_t); - void const * start_data = ctx->data; - int err = fd_stake_reward_calculation_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_stake_reward_calculation_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_stake_reward_calculation_t * self = (fd_stake_reward_calculation_t *)struct_mem; - fd_bincode_uint64_decode_unsafe( &self->stake_rewards_len, ctx ); - self->pool = fd_stake_reward_calculation_pool_join_new( alloc_mem, self->stake_rewards_len ); - self->stake_rewards = fd_stake_reward_calculation_dlist_join_new( alloc_mem, self->stake_rewards_len ); - fd_stake_reward_calculation_dlist_new( self->stake_rewards ); - for( ulong i=0; i < self->stake_rewards_len; i++ ) { - fd_stake_reward_t * ele = fd_stake_reward_calculation_pool_ele_acquire( self->pool ); - fd_stake_reward_new( ele ); - fd_stake_reward_decode_inner( ele, alloc_mem, ctx ); - fd_stake_reward_calculation_dlist_ele_push_tail( self->stake_rewards, ele, self->pool ); - } - fd_bincode_uint64_decode_unsafe( &self->total_stake_rewards_lamports, ctx ); -} -void * fd_stake_reward_calculation_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_stake_reward_calculation_t * self = (fd_stake_reward_calculation_t *)mem; - fd_stake_reward_calculation_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_stake_reward_calculation_t); - void * * alloc_mem = &alloc_region; - fd_stake_reward_calculation_decode_inner( mem, alloc_mem, ctx ); - return self; -} -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_walk( void * w, fd_stake_reward_calculation_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_stake_reward_calculation", level++, 0 ); - if( self->stake_rewards ) { - for( fd_stake_reward_calculation_dlist_iter_t iter = fd_stake_reward_calculation_dlist_iter_fwd_init( self->stake_rewards, self->pool ); - !fd_stake_reward_calculation_dlist_iter_done( iter, self->stake_rewards, self->pool ); - iter = fd_stake_reward_calculation_dlist_iter_fwd_next( iter, self->stake_rewards, self->pool ) ) { - fd_stake_reward_t * ele = fd_stake_reward_calculation_dlist_iter_ele( iter, self->stake_rewards, self->pool ); - fd_stake_reward_walk( w, ele, fun, "fd_stake_reward_t", level, 0 ); - } - } - fun( w, &self->total_stake_rewards_lamports, "total_stake_rewards_lamports", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_stake_reward_calculation", level--, 0 ); -} -ulong fd_stake_reward_calculation_size( fd_stake_reward_calculation_t const * self ) { - ulong size = 0; - size += sizeof(ulong); - if( self->stake_rewards ) { - for( fd_stake_reward_calculation_dlist_iter_t iter = fd_stake_reward_calculation_dlist_iter_fwd_init( self->stake_rewards, self->pool ); - !fd_stake_reward_calculation_dlist_iter_done( iter, self->stake_rewards, self->pool ); - iter = fd_stake_reward_calculation_dlist_iter_fwd_next( iter, self->stake_rewards, self->pool ) ) { - fd_stake_reward_t * ele = fd_stake_reward_calculation_dlist_iter_ele( iter, self->stake_rewards, self->pool ); - size += fd_stake_reward_size( ele ); - } - } - size += sizeof(ulong); - return size; -} - -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_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; -} -static int fd_calculate_stake_vote_rewards_result_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - err = fd_stake_reward_calculation_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - ulong vote_reward_map_len = 0UL; - err = fd_bincode_uint64_decode( &vote_reward_map_len, ctx ); - ulong vote_reward_map_cnt = fd_ulong_max( vote_reward_map_len, 15000 ); - *total_sz += fd_vote_reward_t_map_align() + fd_vote_reward_t_map_footprint( vote_reward_map_cnt ); - if( FD_UNLIKELY( err ) ) return err; - for( ulong i=0; i < vote_reward_map_len; i++ ) { - err = fd_vote_reward_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - } - return 0; -} -int fd_calculate_stake_vote_rewards_result_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_calculate_stake_vote_rewards_result_t); - void const * start_data = ctx->data; - int err = fd_calculate_stake_vote_rewards_result_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_calculate_stake_vote_rewards_result_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_calculate_stake_vote_rewards_result_t * self = (fd_calculate_stake_vote_rewards_result_t *)struct_mem; - fd_stake_reward_calculation_decode_inner( &self->stake_reward_calculation, alloc_mem, ctx ); - ulong vote_reward_map_len; - fd_bincode_uint64_decode_unsafe( &vote_reward_map_len, ctx ); - self->vote_reward_map_pool = fd_vote_reward_t_map_join_new( alloc_mem, fd_ulong_max( vote_reward_map_len, 15000 ) ); - 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_inner( &node->elem, alloc_mem, ctx ); - fd_vote_reward_t_mapnode_t * out = NULL;; - fd_vote_reward_t_map_insert_or_replace( self->vote_reward_map_pool, &self->vote_reward_map_root, node, &out ); - if( out != NULL ) { - fd_vote_reward_t_map_release( self->vote_reward_map_pool, out ); - } - } -} -void * fd_calculate_stake_vote_rewards_result_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_calculate_stake_vote_rewards_result_t * self = (fd_calculate_stake_vote_rewards_result_t *)mem; - fd_calculate_stake_vote_rewards_result_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_calculate_stake_vote_rewards_result_t); - void * * alloc_mem = &alloc_region; - fd_calculate_stake_vote_rewards_result_decode_inner( mem, alloc_mem, ctx ); - return self; -} -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_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, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_calculate_stake_vote_rewards_result", level++, 0 ); - fd_stake_reward_calculation_walk( w, &self->stake_reward_calculation, fun, "stake_reward_calculation", level, 0 ); - 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, 0 ); - } - } - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_calculate_stake_vote_rewards_result", level--, 0 ); -} -ulong fd_calculate_stake_vote_rewards_result_size( fd_calculate_stake_vote_rewards_result_t const * self ) { - ulong size = 0; - size += fd_stake_reward_calculation_size( &self->stake_reward_calculation ); - if( self->vote_reward_map_root ) { - size += sizeof(ulong); - ulong max = fd_vote_reward_t_map_max( self->vote_reward_map_pool ); - size += fd_vote_reward_t_map_footprint( max ); - 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 ) - sizeof(fd_vote_reward_t); - } - } else { - size += sizeof(ulong); - } - return size; -} - -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_calculate_stake_vote_rewards_result_encode( &self->calculate_stake_vote_rewards_result, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_point_value_encode( &self->point_value, ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -static int fd_calculate_validator_rewards_result_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - err = fd_calculate_stake_vote_rewards_result_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_point_value_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - return 0; -} -int fd_calculate_validator_rewards_result_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_calculate_validator_rewards_result_t); - void const * start_data = ctx->data; - int err = fd_calculate_validator_rewards_result_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_calculate_validator_rewards_result_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_calculate_validator_rewards_result_t * self = (fd_calculate_validator_rewards_result_t *)struct_mem; - fd_calculate_stake_vote_rewards_result_decode_inner( &self->calculate_stake_vote_rewards_result, alloc_mem, ctx ); - fd_point_value_decode_inner( &self->point_value, alloc_mem, ctx ); -} -void * fd_calculate_validator_rewards_result_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_calculate_validator_rewards_result_t * self = (fd_calculate_validator_rewards_result_t *)mem; - fd_calculate_validator_rewards_result_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_calculate_validator_rewards_result_t); - void * * alloc_mem = &alloc_region; - fd_calculate_validator_rewards_result_decode_inner( mem, alloc_mem, ctx ); - return self; -} -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 ); - fd_point_value_new( &self->point_value ); -} -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, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_calculate_validator_rewards_result", level++, 0 ); - fd_calculate_stake_vote_rewards_result_walk( w, &self->calculate_stake_vote_rewards_result, fun, "calculate_stake_vote_rewards_result", level, 0 ); - fd_point_value_walk( w, &self->point_value, fun, "point_value", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_calculate_validator_rewards_result", level--, 0 ); -} -ulong fd_calculate_validator_rewards_result_size( fd_calculate_validator_rewards_result_t const * self ) { - ulong size = 0; - size += fd_calculate_stake_vote_rewards_result_size( &self->calculate_stake_vote_rewards_result ); - size += fd_point_value_size( &self->point_value ); - return size; -} - 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 ); + err = fd_bincode_uint128_encode( self->validator_points, 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; @@ -6170,72 +5614,22 @@ int fd_partitioned_rewards_calculation_encode( fd_partitioned_rewards_calculatio if( FD_UNLIKELY( err ) ) return err; err = fd_bincode_uint64_encode( self->capitalization, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_point_value_encode( &self->point_value, ctx ); - if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } -static int fd_partitioned_rewards_calculation_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - ulong vote_reward_map_len = 0UL; - err = fd_bincode_uint64_decode( &vote_reward_map_len, ctx ); - ulong vote_reward_map_cnt = fd_ulong_max( vote_reward_map_len, 15000 ); - *total_sz += fd_vote_reward_t_map_align() + fd_vote_reward_t_map_footprint( vote_reward_map_cnt ); - if( FD_UNLIKELY( err ) ) return err; - for( ulong i=0; i < vote_reward_map_len; i++ ) { - err = fd_vote_reward_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - } - err = fd_stake_reward_calculation_partitioned_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_double_decode_footprint( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_double_decode_footprint( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_double_decode_footprint( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_point_value_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; +static inline int fd_partitioned_rewards_calculation_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { + if( (ulong)ctx->data + 64UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; + ctx->data = (void *)( (ulong)ctx->data + 64UL ); return 0; } -int fd_partitioned_rewards_calculation_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_partitioned_rewards_calculation_t); - void const * start_data = ctx->data; - int err = fd_partitioned_rewards_calculation_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} static void fd_partitioned_rewards_calculation_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { fd_partitioned_rewards_calculation_t * self = (fd_partitioned_rewards_calculation_t *)struct_mem; - ulong vote_reward_map_len; - fd_bincode_uint64_decode_unsafe( &vote_reward_map_len, ctx ); - self->vote_reward_map_pool = fd_vote_reward_t_map_join_new( alloc_mem, fd_ulong_max( vote_reward_map_len, 15000 ) ); - 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_inner( &node->elem, alloc_mem, ctx ); - fd_vote_reward_t_mapnode_t * out = NULL;; - fd_vote_reward_t_map_insert_or_replace( self->vote_reward_map_pool, &self->vote_reward_map_root, node, &out ); - if( out != NULL ) { - fd_vote_reward_t_map_release( self->vote_reward_map_pool, out ); - } - } - fd_stake_reward_calculation_partitioned_decode_inner( &self->stake_rewards_by_partition, alloc_mem, ctx ); + fd_bincode_uint128_decode_unsafe( &self->validator_points, 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_point_value_decode_inner( &self->point_value, alloc_mem, ctx ); } void * fd_partitioned_rewards_calculation_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { fd_partitioned_rewards_calculation_t * self = (fd_partitioned_rewards_calculation_t *)mem; @@ -6245,364 +5639,18 @@ void * fd_partitioned_rewards_calculation_decode( void * mem, fd_bincode_decode_ fd_partitioned_rewards_calculation_decode_inner( mem, alloc_mem, ctx ); return self; } -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 ); - fd_point_value_new( &self->point_value ); -} 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, uint varint ) { (void) varint; fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_partitioned_rewards_calculation", level++, 0 ); - 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, 0 ); - } - } - fd_stake_reward_calculation_partitioned_walk( w, &self->stake_rewards_by_partition, fun, "stake_rewards_by_partition", level, 0 ); + fun( w, &self->validator_points, "validator_points", FD_FLAMENCO_TYPE_UINT128, "uint128", level, 0 ); fun( w, &self->old_vote_balance_and_staked, "old_vote_balance_and_staked", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); fun( w, &self->validator_rewards, "validator_rewards", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); fun( w, &self->validator_rate, "validator_rate", FD_FLAMENCO_TYPE_DOUBLE, "double", level, 0 ); fun( w, &self->foundation_rate, "foundation_rate", FD_FLAMENCO_TYPE_DOUBLE, "double", level, 0 ); fun( w, &self->prev_epoch_duration_in_years, "prev_epoch_duration_in_years", FD_FLAMENCO_TYPE_DOUBLE, "double", level, 0 ); fun( w, &self->capitalization, "capitalization", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); - fd_point_value_walk( w, &self->point_value, fun, "point_value", level, 0 ); fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_partitioned_rewards_calculation", level--, 0 ); } -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); - ulong max = fd_vote_reward_t_map_max( self->vote_reward_map_pool ); - size += fd_vote_reward_t_map_footprint( max ); - 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 ) - sizeof(fd_vote_reward_t); - } - } 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 += fd_point_value_size( &self->point_value ); - return size; -} - -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->distribution_starting_block_height, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_partitioned_stake_rewards_encode( &self->partitioned_stake_rewards, ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -int fd_start_block_height_and_rewards_encode_global( fd_start_block_height_and_rewards_global_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_partitioned_stake_rewards_encode_global( &self->partitioned_stake_rewards, ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -static int fd_start_block_height_and_rewards_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_partitioned_stake_rewards_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - return 0; -} -int fd_start_block_height_and_rewards_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_start_block_height_and_rewards_t); - void const * start_data = ctx->data; - int err = fd_start_block_height_and_rewards_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_start_block_height_and_rewards_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_start_block_height_and_rewards_t * self = (fd_start_block_height_and_rewards_t *)struct_mem; - fd_bincode_uint64_decode_unsafe( &self->distribution_starting_block_height, ctx ); - fd_partitioned_stake_rewards_decode_inner( &self->partitioned_stake_rewards, alloc_mem, ctx ); -} -void * fd_start_block_height_and_rewards_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_start_block_height_and_rewards_t * self = (fd_start_block_height_and_rewards_t *)mem; - fd_start_block_height_and_rewards_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_start_block_height_and_rewards_t); - void * * alloc_mem = &alloc_region; - fd_start_block_height_and_rewards_decode_inner( mem, alloc_mem, ctx ); - return self; -} -static void fd_start_block_height_and_rewards_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_start_block_height_and_rewards_global_t * self = (fd_start_block_height_and_rewards_global_t *)struct_mem; - fd_bincode_uint64_decode_unsafe( &self->distribution_starting_block_height, ctx ); - fd_partitioned_stake_rewards_decode_inner_global( &self->partitioned_stake_rewards, alloc_mem, ctx ); -} -void * fd_start_block_height_and_rewards_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_start_block_height_and_rewards_global_t * self = (fd_start_block_height_and_rewards_global_t *)mem; - fd_start_block_height_and_rewards_new( (fd_start_block_height_and_rewards_t *)self ); - void * alloc_region = (uchar *)mem + sizeof(fd_start_block_height_and_rewards_global_t); - void * * alloc_mem = &alloc_region; - fd_start_block_height_and_rewards_decode_inner_global( mem, alloc_mem, ctx ); - return self; -} -void fd_start_block_height_and_rewards_new(fd_start_block_height_and_rewards_t * self) { - fd_memset( self, 0, sizeof(fd_start_block_height_and_rewards_t) ); - fd_partitioned_stake_rewards_new( &self->partitioned_stake_rewards ); -} -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, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_start_block_height_and_rewards", level++, 0 ); - fun( w, &self->distribution_starting_block_height, "distribution_starting_block_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level, 0 ); - fd_partitioned_stake_rewards_walk( w, &self->partitioned_stake_rewards, fun, "partitioned_stake_rewards", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_start_block_height_and_rewards", level--, 0 ); -} -ulong fd_start_block_height_and_rewards_size( fd_start_block_height_and_rewards_t const * self ) { - ulong size = 0; - size += sizeof(ulong); - size += fd_partitioned_stake_rewards_size( &self->partitioned_stake_rewards ); - return size; -} - -ulong fd_start_block_height_and_rewards_size_global( fd_start_block_height_and_rewards_global_t const * self ) { - ulong size = 0; - size += sizeof(ulong); - size += fd_partitioned_stake_rewards_size_global( &self->partitioned_stake_rewards ); - return size; -} - -int fd_fd_epoch_reward_status_inner_encode( fd_fd_epoch_reward_status_inner_t const * self, fd_bincode_encode_ctx_t * ctx ) { - int err; - err = fd_start_block_height_and_rewards_encode( &self->Active, ctx ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; -} -static int fd_fd_epoch_reward_status_inner_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - err = fd_start_block_height_and_rewards_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - return 0; -} -int fd_fd_epoch_reward_status_inner_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_fd_epoch_reward_status_inner_t); - void const * start_data = ctx->data; - int err = fd_fd_epoch_reward_status_inner_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_fd_epoch_reward_status_inner_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_fd_epoch_reward_status_inner_t * self = (fd_fd_epoch_reward_status_inner_t *)struct_mem; - fd_start_block_height_and_rewards_decode_inner( &self->Active, alloc_mem, ctx ); -} -void * fd_fd_epoch_reward_status_inner_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_fd_epoch_reward_status_inner_t * self = (fd_fd_epoch_reward_status_inner_t *)mem; - fd_fd_epoch_reward_status_inner_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_fd_epoch_reward_status_inner_t); - void * * alloc_mem = &alloc_region; - fd_fd_epoch_reward_status_inner_decode_inner( mem, alloc_mem, ctx ); - return self; -} -void fd_fd_epoch_reward_status_inner_new(fd_fd_epoch_reward_status_inner_t * self) { - fd_memset( self, 0, sizeof(fd_fd_epoch_reward_status_inner_t) ); - fd_start_block_height_and_rewards_new( &self->Active ); -} -void fd_fd_epoch_reward_status_inner_walk( void * w, fd_fd_epoch_reward_status_inner_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_fd_epoch_reward_status_inner", level++, 0 ); - fd_start_block_height_and_rewards_walk( w, &self->Active, fun, "Active", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_fd_epoch_reward_status_inner", level--, 0 ); -} -ulong fd_fd_epoch_reward_status_inner_size( fd_fd_epoch_reward_status_inner_t const * self ) { - ulong size = 0; - size += fd_start_block_height_and_rewards_size( &self->Active ); - return size; -} - -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_epoch_reward_status_is_Inactive(fd_epoch_reward_status_t const * self) { - return self->discriminant == 1; -} -void fd_epoch_reward_status_inner_new( fd_epoch_reward_status_inner_t * self, uint discriminant ); -int fd_epoch_reward_status_inner_decode_footprint( uint discriminant, fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - int err; - switch (discriminant) { - case 0: { - err = fd_start_block_height_and_rewards_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - return FD_BINCODE_SUCCESS; - } - case 1: { - return FD_BINCODE_SUCCESS; - } - default: return FD_BINCODE_ERR_ENCODING; - } -} -static int fd_epoch_reward_status_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - uint discriminant = 0; - int err = fd_bincode_uint32_decode( &discriminant, ctx ); - if( FD_UNLIKELY( err ) ) return err; - return fd_epoch_reward_status_inner_decode_footprint( discriminant, ctx, total_sz ); -} -int fd_epoch_reward_status_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_epoch_reward_status_t); - void const * start_data = ctx->data; - int err = fd_epoch_reward_status_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_epoch_reward_status_inner_decode_inner( fd_epoch_reward_status_inner_t * self, void * * alloc_mem, uint discriminant, fd_bincode_decode_ctx_t * ctx ) { - switch (discriminant) { - case 0: { - fd_start_block_height_and_rewards_decode_inner( &self->Active, alloc_mem, ctx ); - break; - } - case 1: { - break; - } - } -} -static void fd_epoch_reward_status_inner_decode_inner_global( fd_epoch_reward_status_inner_global_t * self, void * * alloc_mem, uint discriminant, fd_bincode_decode_ctx_t * ctx ) { - switch (discriminant) { - case 0: { - fd_start_block_height_and_rewards_decode_inner_global( &self->Active, alloc_mem, ctx ); - break; - } - case 1: { - break; - } - } -} -static void fd_epoch_reward_status_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_epoch_reward_status_t * self = (fd_epoch_reward_status_t *)struct_mem; - fd_bincode_uint32_decode_unsafe( &self->discriminant, ctx ); - fd_epoch_reward_status_inner_decode_inner( &self->inner, alloc_mem, self->discriminant, ctx ); -} -void * fd_epoch_reward_status_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_epoch_reward_status_t * self = (fd_epoch_reward_status_t *)mem; - fd_epoch_reward_status_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_epoch_reward_status_t); - void * * alloc_mem = &alloc_region; - fd_epoch_reward_status_decode_inner( mem, alloc_mem, ctx ); - return self; -} -static int fd_epoch_reward_status_inner_encode_global( fd_epoch_reward_status_inner_global_t const * self, uint discriminant, fd_bincode_encode_ctx_t * ctx ) { - int err; - switch (discriminant) { - case 0: { - err = fd_start_block_height_and_rewards_encode_global( &self->Active, ctx ); - if( FD_UNLIKELY( err ) ) return err; - break; - } - } - return FD_BINCODE_SUCCESS; -} -int fd_epoch_reward_status_encode_global( fd_epoch_reward_status_global_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_epoch_reward_status_inner_encode_global( &self->inner, self->discriminant, ctx ); -} - -static void fd_epoch_reward_status_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_epoch_reward_status_global_t * self = (fd_epoch_reward_status_global_t *)struct_mem; - fd_bincode_uint32_decode_unsafe( &self->discriminant, ctx ); - fd_epoch_reward_status_inner_decode_inner_global( &self->inner, alloc_mem, self->discriminant, ctx ); -} -void * fd_epoch_reward_status_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_epoch_reward_status_t * self = (fd_epoch_reward_status_t *)mem; - fd_epoch_reward_status_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_epoch_reward_status_t); - void * * alloc_mem = &alloc_region; - fd_epoch_reward_status_decode_inner_global( mem, alloc_mem, ctx ); - return self; -} -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 ); - break; - } - case 1: { - break; - } - default: break; // FD_LOG_ERR(( "unhandled type")); - } -} -void fd_epoch_reward_status_new_disc( fd_epoch_reward_status_t * self, uint discriminant ) { - self->discriminant = discriminant; - fd_epoch_reward_status_inner_new( &self->inner, self->discriminant ); -} -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_epoch_reward_status_walk( void * w, fd_epoch_reward_status_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ) { - (void) varint; - fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_epoch_reward_status", level++, 0); - switch( self->discriminant ) { - case 0: { - fun( w, self, "Active", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level, 0 ); - fd_start_block_height_and_rewards_walk( w, &self->inner.Active, fun, "Active", level, 0 ); - break; - } - case 1: { - fun( w, self, "Inactive", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level, 0 ); - break; - } - } - fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_epoch_reward_status", level--, 0 ); -} -ulong fd_epoch_reward_status_size( fd_epoch_reward_status_t const * self ) { - ulong size = 0; - size += sizeof(uint); - switch (self->discriminant) { - case 0: { - size += fd_start_block_height_and_rewards_size( &self->inner.Active ); - break; - } - } - return size; -} - -ulong fd_epoch_reward_status_size_global( fd_epoch_reward_status_global_t const * self ) { - ulong size = 0; - size += sizeof(uint); - switch (self->discriminant) { - case 0: { - size += fd_start_block_height_and_rewards_size_global( &self->inner.Active ); - break; - } - } - return size; -} - -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: { - err = fd_start_block_height_and_rewards_encode( &self->Active, ctx ); - if( FD_UNLIKELY( err ) ) return err; - break; - } - } - return FD_BINCODE_SUCCESS; -} -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_epoch_reward_status_inner_encode( &self->inner, self->discriminant, ctx ); -} - int fd_prev_epoch_inflation_rewards_encode( fd_prev_epoch_inflation_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; err = fd_bincode_uint64_encode( self->validator_rewards, ctx ); @@ -15809,56 +14857,6 @@ int fd_txn_result_encode( fd_txn_result_t const * self, fd_bincode_encode_ctx_t return fd_txn_result_inner_encode( &self->inner, self->discriminant, 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; -} -static int fd_pubkey_rewardinfo_pair_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - int err = 0; - err = fd_pubkey_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_reward_info_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - return 0; -} -int fd_pubkey_rewardinfo_pair_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_pubkey_rewardinfo_pair_t); - void const * start_data = ctx->data; - int err = fd_pubkey_rewardinfo_pair_decode_footprint_inner( ctx, total_sz ); - if( ctx->data>ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - ctx->data = start_data; - return err; -} -static void fd_pubkey_rewardinfo_pair_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { - fd_pubkey_rewardinfo_pair_t * self = (fd_pubkey_rewardinfo_pair_t *)struct_mem; - fd_pubkey_decode_inner( &self->pubkey, alloc_mem, ctx ); - fd_reward_info_decode_inner( &self->reward_info, alloc_mem, ctx ); -} -void * fd_pubkey_rewardinfo_pair_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { - fd_pubkey_rewardinfo_pair_t * self = (fd_pubkey_rewardinfo_pair_t *)mem; - fd_pubkey_rewardinfo_pair_new( self ); - void * alloc_region = (uchar *)mem + sizeof(fd_pubkey_rewardinfo_pair_t); - void * * alloc_mem = &alloc_region; - fd_pubkey_rewardinfo_pair_decode_inner( mem, alloc_mem, ctx ); - return self; -} -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_walk( void * w, fd_pubkey_rewardinfo_pair_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ) { - (void) varint; - fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_pubkey_rewardinfo_pair", level++, 0 ); - fd_pubkey_walk( w, &self->pubkey, fun, "pubkey", level, 0 ); - fd_reward_info_walk( w, &self->reward_info, fun, "reward_info", level, 0 ); - fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_pubkey_rewardinfo_pair", level--, 0 ); -} 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 ); @@ -16426,11 +15424,4 @@ int fd_rent_state_encode( fd_rent_state_t const * self, fd_bincode_encode_ctx_t 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" -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) ); -} #include "fd_types_custom.c" diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index 555eb0f9a83..8fda01f8de3 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -968,213 +968,20 @@ struct fd_stake_reward { typedef struct fd_stake_reward fd_stake_reward_t; #define FD_STAKE_REWARD_ALIGN alignof(fd_stake_reward_t) -/* Encoded Size: Fixed (42 bytes) */ -struct 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_ALIGN alignof(fd_vote_reward_t) - -/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L21 */ -/* Encoded Size: Fixed (24 bytes) */ -struct fd_point_value { - ulong rewards; - uint128 points; -}; -typedef struct fd_point_value fd_point_value_t; -#define FD_POINT_VALUE_ALIGN alignof(fd_point_value_t) - -#define POOL_NAME fd_partitioned_stake_rewards_pool -#define POOL_T fd_stake_reward_t -#define POOL_NEXT parent -#include "../../util/tmpl/fd_pool.c" -static inline fd_stake_reward_t * -fd_partitioned_stake_rewards_pool_join_new( void * * alloc_mem, ulong num ) { - if( FD_UNLIKELY( 0 == num ) ) num = 1; // prevent underflow - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_partitioned_stake_rewards_pool_align() ); - void * pool_mem = *alloc_mem; - *alloc_mem = (uchar *)*alloc_mem + fd_partitioned_stake_rewards_pool_footprint( num ); - return fd_partitioned_stake_rewards_pool_join( fd_partitioned_stake_rewards_pool_new( pool_mem, num ) ); -} -#define DLIST_NAME fd_partitioned_stake_rewards_dlist -#define DLIST_ELE_T fd_stake_reward_t -#include "../../util/tmpl/fd_dlist.c" -static inline fd_partitioned_stake_rewards_dlist_t * -fd_partitioned_stake_rewards_dlist_join_new( void * * alloc_mem, ulong num ) { - if( FD_UNLIKELY( 0 == num ) ) num = 1; // prevent underflow - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_partitioned_stake_rewards_dlist_align() ); - void * dlist_mem = *alloc_mem; - *alloc_mem = (uchar *)*alloc_mem + fd_partitioned_stake_rewards_dlist_footprint(); - return fd_partitioned_stake_rewards_dlist_join( fd_partitioned_stake_rewards_dlist_new( dlist_mem ) ); -} -/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L56 */ -/* Encoded Size: Dynamic */ -struct fd_partitioned_stake_rewards { - ulong partitions_len; - ulong partitions_lengths[4096]; - fd_partitioned_stake_rewards_dlist_t * partitions; - fd_stake_reward_t * pool; -}; -typedef struct fd_partitioned_stake_rewards fd_partitioned_stake_rewards_t; -#define FD_PARTITIONED_STAKE_REWARDS_ALIGN alignof(fd_partitioned_stake_rewards_t) - -struct fd_partitioned_stake_rewards_global { - ulong partitions_len; - ulong partitions_lengths[4096]; - ulong partitions_offset; - ulong pool_offset; -}; -typedef struct fd_partitioned_stake_rewards_global fd_partitioned_stake_rewards_global_t; -#define FD_PARTITIONED_STAKE_REWARDS_GLOBAL_ALIGN alignof(fd_partitioned_stake_rewards_global_t) - -/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L131 */ -/* Encoded Size: Dynamic */ -struct fd_stake_reward_calculation_partitioned { - fd_partitioned_stake_rewards_t partitioned_stake_rewards; - ulong total_stake_rewards_lamports; -}; -typedef struct fd_stake_reward_calculation_partitioned fd_stake_reward_calculation_partitioned_t; -#define FD_STAKE_REWARD_CALCULATION_PARTITIONED_ALIGN alignof(fd_stake_reward_calculation_partitioned_t) - -#define POOL_NAME fd_stake_reward_calculation_pool -#define POOL_T fd_stake_reward_t -#define POOL_NEXT parent -#include "../../util/tmpl/fd_pool.c" -static inline fd_stake_reward_t * -fd_stake_reward_calculation_pool_join_new( void * * alloc_mem, ulong num ) { - if( FD_UNLIKELY( 0 == num ) ) num = 1; // prevent underflow - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_stake_reward_calculation_pool_align() ); - void * pool_mem = *alloc_mem; - *alloc_mem = (uchar *)*alloc_mem + fd_stake_reward_calculation_pool_footprint( num ); - return fd_stake_reward_calculation_pool_join( fd_stake_reward_calculation_pool_new( pool_mem, num ) ); -} -#define DLIST_NAME fd_stake_reward_calculation_dlist -#define DLIST_ELE_T fd_stake_reward_t -#include "../../util/tmpl/fd_dlist.c" -static inline fd_stake_reward_calculation_dlist_t * -fd_stake_reward_calculation_dlist_join_new( void * * alloc_mem, ulong num ) { - if( FD_UNLIKELY( 0 == num ) ) num = 1; // prevent underflow - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_stake_reward_calculation_dlist_align() ); - void * dlist_mem = *alloc_mem; - *alloc_mem = (uchar *)*alloc_mem + fd_stake_reward_calculation_dlist_footprint(); - return fd_stake_reward_calculation_dlist_join( fd_stake_reward_calculation_dlist_new( dlist_mem ) ); -} -/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L94 */ -/* Encoded Size: Dynamic */ -struct fd_stake_reward_calculation { - ulong stake_rewards_len; - fd_stake_reward_calculation_dlist_t * stake_rewards; - fd_stake_reward_t * pool; - ulong total_stake_rewards_lamports; -}; -typedef struct fd_stake_reward_calculation fd_stake_reward_calculation_t; -#define FD_STAKE_REWARD_CALCULATION_ALIGN alignof(fd_stake_reward_calculation_t) - -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" -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_join_new( void * * alloc_mem, ulong len ) { - if( FD_UNLIKELY( 0 == len ) ) len = 1; // prevent underflow - *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_vote_reward_t_map_align() ); - void * map_mem = *alloc_mem; - *alloc_mem = (uchar *)*alloc_mem + fd_vote_reward_t_map_footprint( len ); - return fd_vote_reward_t_map_join( fd_vote_reward_t_map_new( map_mem, len ) ); -} -/* Encoded Size: Dynamic */ -struct 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_ALIGN alignof(fd_calculate_stake_vote_rewards_result_t) - -/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L102 */ -/* Encoded Size: Dynamic */ -struct fd_calculate_validator_rewards_result { - fd_calculate_stake_vote_rewards_result_t calculate_stake_vote_rewards_result; - fd_point_value_t point_value; -}; -typedef struct fd_calculate_validator_rewards_result fd_calculate_validator_rewards_result_t; -#define FD_CALCULATE_VALIDATOR_REWARDS_RESULT_ALIGN alignof(fd_calculate_validator_rewards_result_t) - /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L118 */ -/* Encoded Size: Dynamic */ +/* Encoded Size: Fixed (64 bytes) */ struct 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; + uint128 validator_points; ulong old_vote_balance_and_staked; ulong validator_rewards; double validator_rate; double foundation_rate; double prev_epoch_duration_in_years; ulong capitalization; - fd_point_value_t point_value; }; typedef struct fd_partitioned_rewards_calculation fd_partitioned_rewards_calculation_t; #define FD_PARTITIONED_REWARDS_CALCULATION_ALIGN alignof(fd_partitioned_rewards_calculation_t) -/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L60 */ -/* Encoded Size: Dynamic */ -struct fd_start_block_height_and_rewards { - ulong distribution_starting_block_height; - fd_partitioned_stake_rewards_t partitioned_stake_rewards; -}; -typedef struct fd_start_block_height_and_rewards fd_start_block_height_and_rewards_t; -#define FD_START_BLOCK_HEIGHT_AND_REWARDS_ALIGN alignof(fd_start_block_height_and_rewards_t) - -struct fd_start_block_height_and_rewards_global { - ulong distribution_starting_block_height; - fd_partitioned_stake_rewards_global_t partitioned_stake_rewards; -}; -typedef struct fd_start_block_height_and_rewards_global fd_start_block_height_and_rewards_global_t; -#define FD_START_BLOCK_HEIGHT_AND_REWARDS_GLOBAL_ALIGN alignof(fd_start_block_height_and_rewards_global_t) - -/* Encoded Size: Dynamic */ -struct fd_fd_epoch_reward_status_inner { - fd_start_block_height_and_rewards_t Active; -}; -typedef struct fd_fd_epoch_reward_status_inner fd_fd_epoch_reward_status_inner_t; -#define FD_FD_EPOCH_REWARD_STATUS_INNER_ALIGN alignof(fd_fd_epoch_reward_status_inner_t) - -union fd_epoch_reward_status_inner { - fd_start_block_height_and_rewards_t Active; -}; -typedef union fd_epoch_reward_status_inner fd_epoch_reward_status_inner_t; - -union fd_epoch_reward_status_inner_global { - fd_start_block_height_and_rewards_global_t Active; -}; -typedef union fd_epoch_reward_status_inner_global fd_epoch_reward_status_inner_global_t; - -/* 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_epoch_reward_status_inner_t inner; -}; -typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; -#define FD_EPOCH_REWARD_STATUS_ALIGN alignof(fd_epoch_reward_status_t) -struct fd_epoch_reward_status_global { - uint discriminant; - fd_epoch_reward_status_inner_global_t inner; -}; -typedef struct fd_epoch_reward_status_global fd_epoch_reward_status_global_t; -#define FD_EPOCH_REWARD_STATUS_GLOBAL_ALIGN alignof(fd_epoch_reward_status_global_t) - /* Encoded Size: Fixed (32 bytes) */ struct fd_prev_epoch_inflation_rewards { ulong validator_rewards; @@ -2006,15 +1813,6 @@ struct fd_txn_result { typedef struct fd_txn_result fd_txn_result_t; #define FD_TXN_RESULT_ALIGN alignof(fd_txn_result_t) -/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L85 */ -/* Encoded Size: Fixed (60 bytes) */ -struct 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_ALIGN alignof(fd_pubkey_rewardinfo_pair_t) - /* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/points.rs#L27 */ /* Encoded Size: Fixed (25 bytes) */ struct fd_calculated_stake_points { @@ -2801,118 +2599,18 @@ static inline int fd_stake_reward_decode_footprint( fd_bincode_decode_ctx_t * ct } void * fd_stake_reward_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); -static inline void fd_vote_reward_new( fd_vote_reward_t * self ) { fd_memset( self, 0, sizeof(fd_vote_reward_t) ); } -int fd_vote_reward_encode( fd_vote_reward_t const * self, fd_bincode_encode_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, uint varint ); -static inline ulong fd_vote_reward_size( fd_vote_reward_t const * self ) { (void)self; return 42UL; } -static inline ulong fd_vote_reward_align( void ) { return FD_VOTE_REWARD_ALIGN; } -static inline int fd_vote_reward_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_vote_reward_t); - if( (ulong)ctx->data + 42UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - return 0; -} -void * fd_vote_reward_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - -static inline void fd_point_value_new( fd_point_value_t * self ) { fd_memset( self, 0, sizeof(fd_point_value_t) ); } -int fd_point_value_encode( fd_point_value_t const * self, fd_bincode_encode_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, uint varint ); -static inline ulong fd_point_value_size( fd_point_value_t const * self ) { (void)self; return 24UL; } -static inline ulong fd_point_value_align( void ) { return FD_POINT_VALUE_ALIGN; } -static inline int fd_point_value_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { - *total_sz += sizeof(fd_point_value_t); - if( (ulong)ctx->data + 24UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; - return 0; -} -void * fd_point_value_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - -void fd_partitioned_stake_rewards_new( fd_partitioned_stake_rewards_t * self ); -int fd_partitioned_stake_rewards_encode( fd_partitioned_stake_rewards_t const * self, fd_bincode_encode_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, uint varint ); -ulong fd_partitioned_stake_rewards_size( fd_partitioned_stake_rewards_t const * self ); -static inline ulong fd_partitioned_stake_rewards_align( void ) { return FD_PARTITIONED_STAKE_REWARDS_ALIGN; } -int fd_partitioned_stake_rewards_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_partitioned_stake_rewards_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); -void * fd_partitioned_stake_rewards_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ); -int fd_partitioned_stake_rewards_encode_global( fd_partitioned_stake_rewards_global_t const * self, fd_bincode_encode_ctx_t * ctx ); -ulong fd_partitioned_stake_rewards_size_global( fd_partitioned_stake_rewards_global_t const * self ); - -void fd_stake_reward_calculation_partitioned_new( fd_stake_reward_calculation_partitioned_t * self ); -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_walk( void * w, fd_stake_reward_calculation_partitioned_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ); -ulong fd_stake_reward_calculation_partitioned_size( fd_stake_reward_calculation_partitioned_t const * self ); -static inline ulong fd_stake_reward_calculation_partitioned_align( void ) { return FD_STAKE_REWARD_CALCULATION_PARTITIONED_ALIGN; } -int fd_stake_reward_calculation_partitioned_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_stake_reward_calculation_partitioned_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - -void fd_stake_reward_calculation_new( fd_stake_reward_calculation_t * self ); -int fd_stake_reward_calculation_encode( fd_stake_reward_calculation_t const * self, fd_bincode_encode_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, uint varint ); -ulong fd_stake_reward_calculation_size( fd_stake_reward_calculation_t const * self ); -static inline ulong fd_stake_reward_calculation_align( void ) { return FD_STAKE_REWARD_CALCULATION_ALIGN; } -int fd_stake_reward_calculation_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_stake_reward_calculation_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - -void fd_calculate_stake_vote_rewards_result_new( fd_calculate_stake_vote_rewards_result_t * self ); -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_walk( void * w, fd_calculate_stake_vote_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ); -ulong fd_calculate_stake_vote_rewards_result_size( fd_calculate_stake_vote_rewards_result_t const * self ); -static inline ulong fd_calculate_stake_vote_rewards_result_align( void ) { return FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_ALIGN; } -int fd_calculate_stake_vote_rewards_result_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_calculate_stake_vote_rewards_result_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - -void fd_calculate_validator_rewards_result_new( fd_calculate_validator_rewards_result_t * self ); -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_walk( void * w, fd_calculate_validator_rewards_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ); -ulong fd_calculate_validator_rewards_result_size( fd_calculate_validator_rewards_result_t const * self ); -static inline ulong fd_calculate_validator_rewards_result_align( void ) { return FD_CALCULATE_VALIDATOR_REWARDS_RESULT_ALIGN; } -int fd_calculate_validator_rewards_result_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_calculate_validator_rewards_result_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - -void fd_partitioned_rewards_calculation_new( fd_partitioned_rewards_calculation_t * self ); +static inline void fd_partitioned_rewards_calculation_new( fd_partitioned_rewards_calculation_t * self ) { fd_memset( self, 0, sizeof(fd_partitioned_rewards_calculation_t) ); } int fd_partitioned_rewards_calculation_encode( fd_partitioned_rewards_calculation_t const * self, fd_bincode_encode_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, uint varint ); -ulong fd_partitioned_rewards_calculation_size( fd_partitioned_rewards_calculation_t const * self ); +static inline ulong fd_partitioned_rewards_calculation_size( fd_partitioned_rewards_calculation_t const * self ) { (void)self; return 64UL; } static inline ulong fd_partitioned_rewards_calculation_align( void ) { return FD_PARTITIONED_REWARDS_CALCULATION_ALIGN; } -int fd_partitioned_rewards_calculation_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); +static inline int fd_partitioned_rewards_calculation_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { + *total_sz += sizeof(fd_partitioned_rewards_calculation_t); + if( (ulong)ctx->data + 64UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; + return 0; +} void * fd_partitioned_rewards_calculation_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); -void fd_start_block_height_and_rewards_new( fd_start_block_height_and_rewards_t * self ); -int fd_start_block_height_and_rewards_encode( fd_start_block_height_and_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ); -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, uint varint ); -ulong fd_start_block_height_and_rewards_size( fd_start_block_height_and_rewards_t const * self ); -static inline ulong fd_start_block_height_and_rewards_align( void ) { return FD_START_BLOCK_HEIGHT_AND_REWARDS_ALIGN; } -int fd_start_block_height_and_rewards_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_start_block_height_and_rewards_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); -void * fd_start_block_height_and_rewards_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ); -int fd_start_block_height_and_rewards_encode_global( fd_start_block_height_and_rewards_global_t const * self, fd_bincode_encode_ctx_t * ctx ); -ulong fd_start_block_height_and_rewards_size_global( fd_start_block_height_and_rewards_global_t const * self ); - -void fd_fd_epoch_reward_status_inner_new( fd_fd_epoch_reward_status_inner_t * self ); -int fd_fd_epoch_reward_status_inner_encode( fd_fd_epoch_reward_status_inner_t const * self, fd_bincode_encode_ctx_t * ctx ); -void fd_fd_epoch_reward_status_inner_walk( void * w, fd_fd_epoch_reward_status_inner_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ); -ulong fd_fd_epoch_reward_status_inner_size( fd_fd_epoch_reward_status_inner_t const * self ); -static inline ulong fd_fd_epoch_reward_status_inner_align( void ) { return FD_FD_EPOCH_REWARD_STATUS_INNER_ALIGN; } -int fd_fd_epoch_reward_status_inner_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_fd_epoch_reward_status_inner_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - -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_encode( fd_epoch_reward_status_t const * self, fd_bincode_encode_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, uint varint ); -ulong fd_epoch_reward_status_size( fd_epoch_reward_status_t const * self ); -static inline ulong fd_epoch_reward_status_align( void ) { return FD_EPOCH_REWARD_STATUS_ALIGN; } -int fd_epoch_reward_status_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_epoch_reward_status_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); -void * fd_epoch_reward_status_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ); -int fd_epoch_reward_status_encode_global( fd_epoch_reward_status_global_t const * self, fd_bincode_encode_ctx_t * ctx ); -ulong fd_epoch_reward_status_size_global( fd_epoch_reward_status_global_t const * self ); - -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_epoch_reward_status_enum_Active = 0, -fd_epoch_reward_status_enum_Inactive = 1, -}; static inline void fd_prev_epoch_inflation_rewards_new( fd_prev_epoch_inflation_rewards_t * self ) { fd_memset( self, 0, sizeof(fd_prev_epoch_inflation_rewards_t) ); } int fd_prev_epoch_inflation_rewards_encode( fd_prev_epoch_inflation_rewards_t const * self, fd_bincode_encode_ctx_t * ctx ); void fd_prev_epoch_inflation_rewards_walk( void * w, fd_prev_epoch_inflation_rewards_t const * self, fd_types_walk_fn_t fun, const char *name, uint level, uint varint ); @@ -4103,14 +3801,6 @@ enum { fd_txn_result_enum_ok = 0, fd_txn_result_enum_error = 1, }; -void fd_pubkey_rewardinfo_pair_new( fd_pubkey_rewardinfo_pair_t * self ); -int fd_pubkey_rewardinfo_pair_encode( fd_pubkey_rewardinfo_pair_t const * self, fd_bincode_encode_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, uint varint ); -static inline ulong fd_pubkey_rewardinfo_pair_size( fd_pubkey_rewardinfo_pair_t const * self ) { (void)self; return 60UL; } -static inline ulong fd_pubkey_rewardinfo_pair_align( void ) { return FD_PUBKEY_REWARDINFO_PAIR_ALIGN; } -int fd_pubkey_rewardinfo_pair_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); -void * fd_pubkey_rewardinfo_pair_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); - static inline void fd_calculated_stake_points_new( fd_calculated_stake_points_t * self ) { fd_memset( self, 0, sizeof(fd_calculated_stake_points_t) ); } int fd_calculated_stake_points_encode( fd_calculated_stake_points_t const * self, fd_bincode_encode_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, uint varint ); diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index 8303e2bca17..6674983fa35 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -702,110 +702,20 @@ ] }, - { - "name": "vote_reward", - "type": "struct", - "fields": [ - { "name": "pubkey", "type": "pubkey" }, - { "name": "vote_rewards", "type": "ulong" }, - { "name": "commission", "type": "uchar" }, - { "name": "needs_store", "type": "uchar" } - ] - }, - { - "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": "partitioned_stake_rewards", - "type": "struct", - "fields": [ - { "name": "partitions", "type": "partition", "dlist_t": "fd_stake_reward_t", "dlist_n": "fd_partitioned_stake_rewards", "dlist_max": "4096" } - ], - "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L56" - }, - { - "name": "stake_reward_calculation_partitioned", - "type": "struct", - "fields": [ - { "name": "partitioned_stake_rewards", "type": "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": "stake_reward_calculation", - "type": "struct", - "fields": [ - { "name": "stake_rewards", "type": "dlist", "dlist_t": "fd_stake_reward_t", "dlist_n": "fd_stake_reward_calculation" }, - { "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": "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": "pubkey", "minalloc":15000 } - ] - }, - { - "name": "calculate_validator_rewards_result", - "type": "struct", - "fields": [ - { "name": "calculate_stake_vote_rewards_result", "type": "calculate_stake_vote_rewards_result" }, - { "name": "point_value", "type": "point_value" } - ], - "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L102" - }, { "name": "partitioned_rewards_calculation", "type": "struct", "fields": [ - { "name": "vote_reward_map", "type": "map", "element": "vote_reward", "key": "key", "minalloc":15000 }, - { "name": "stake_rewards_by_partition", "type": "stake_reward_calculation_partitioned" }, + { "name": "validator_points", "type": "uint128" }, { "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": "point_value", "type": "point_value" } + { "name": "capitalization", "type": "ulong" } ], "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L118" }, - { - "name": "start_block_height_and_rewards", - "type": "struct", - "fields": [ - { "name": "distribution_starting_block_height", "type": "ulong" }, - { "name": "partitioned_stake_rewards", "type": "partitioned_stake_rewards" } - ], - "comment": "https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/mod.rs#L60" - }, - { - "name": "fd_epoch_reward_status_inner", - "type": "struct", - "fields": [ - { "name": "Active", "type": "start_block_height_and_rewards" } - ] - }, - { - "name": "epoch_reward_status", - "type": "enum", - "global": true, - "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": "prev_epoch_inflation_rewards", "type": "struct", @@ -1839,15 +1749,6 @@ } ] }, - { - "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": "calculated_stake_points", "type": "struct", diff --git a/src/flamenco/types/fd_types_reflect_generated.c b/src/flamenco/types/fd_types_reflect_generated.c index a1e2a48bf42..97cd688f321 100644 --- a/src/flamenco/types/fd_types_reflect_generated.c +++ b/src/flamenco/types/fd_types_reflect_generated.c @@ -3,7 +3,7 @@ #include "fd_types_custom.h" #include "fd_types_reflect_private.h" #pragma GCC diagnostic ignored "-Wpedantic" -ulong fd_types_vt_list_cnt = 162; +ulong fd_types_vt_list_cnt = 151; fd_types_vt_t const fd_types_vt_list[] = { { .name="fd_hash", .name_len=7, .align=FD_HASH_ALIGN, .new_=(void *)fd_hash_new, .decode=(void *)fd_hash_decode, .size=(void *)fd_hash_size, .walk=(void *)fd_hash_walk, .decode_footprint=(void *)fd_hash_decode_footprint, .encode=(void *)fd_hash_encode }, { .name="fd_pubkey", .name_len=9, .align=FD_PUBKEY_ALIGN, .new_=(void *)fd_pubkey_new, .decode=(void *)fd_pubkey_decode, .size=(void *)fd_pubkey_size, .walk=(void *)fd_pubkey_walk, .decode_footprint=(void *)fd_pubkey_decode_footprint, .encode=(void *)fd_pubkey_encode }, @@ -72,17 +72,7 @@ fd_types_vt_t const fd_types_vt_list[] = { { .name="fd_cluster_type", .name_len=15, .align=FD_CLUSTER_TYPE_ALIGN, .new_=(void *)fd_cluster_type_new, .decode=(void *)fd_cluster_type_decode, .size=(void *)fd_cluster_type_size, .walk=(void *)fd_cluster_type_walk, .decode_footprint=(void *)fd_cluster_type_decode_footprint, .encode=(void *)fd_cluster_type_encode }, { .name="fd_cluster_version", .name_len=18, .align=FD_CLUSTER_VERSION_ALIGN, .new_=(void *)fd_cluster_version_new, .decode=(void *)fd_cluster_version_decode, .size=(void *)fd_cluster_version_size, .walk=(void *)fd_cluster_version_walk, .decode_footprint=(void *)fd_cluster_version_decode_footprint, .encode=(void *)fd_cluster_version_encode }, { .name="fd_stake_reward", .name_len=15, .align=FD_STAKE_REWARD_ALIGN, .new_=(void *)fd_stake_reward_new, .decode=(void *)fd_stake_reward_decode, .size=(void *)fd_stake_reward_size, .walk=(void *)fd_stake_reward_walk, .decode_footprint=(void *)fd_stake_reward_decode_footprint, .encode=(void *)fd_stake_reward_encode }, - { .name="fd_vote_reward", .name_len=14, .align=FD_VOTE_REWARD_ALIGN, .new_=(void *)fd_vote_reward_new, .decode=(void *)fd_vote_reward_decode, .size=(void *)fd_vote_reward_size, .walk=(void *)fd_vote_reward_walk, .decode_footprint=(void *)fd_vote_reward_decode_footprint, .encode=(void *)fd_vote_reward_encode }, - { .name="fd_point_value", .name_len=14, .align=FD_POINT_VALUE_ALIGN, .new_=(void *)fd_point_value_new, .decode=(void *)fd_point_value_decode, .size=(void *)fd_point_value_size, .walk=(void *)fd_point_value_walk, .decode_footprint=(void *)fd_point_value_decode_footprint, .encode=(void *)fd_point_value_encode }, - { .name="fd_partitioned_stake_rewards", .name_len=28, .align=FD_PARTITIONED_STAKE_REWARDS_ALIGN, .new_=(void *)fd_partitioned_stake_rewards_new, .decode=(void *)fd_partitioned_stake_rewards_decode, .size=(void *)fd_partitioned_stake_rewards_size, .walk=(void *)fd_partitioned_stake_rewards_walk, .decode_footprint=(void *)fd_partitioned_stake_rewards_decode_footprint, .encode=(void *)fd_partitioned_stake_rewards_encode }, - { .name="fd_stake_reward_calculation_partitioned", .name_len=39, .align=FD_STAKE_REWARD_CALCULATION_PARTITIONED_ALIGN, .new_=(void *)fd_stake_reward_calculation_partitioned_new, .decode=(void *)fd_stake_reward_calculation_partitioned_decode, .size=(void *)fd_stake_reward_calculation_partitioned_size, .walk=(void *)fd_stake_reward_calculation_partitioned_walk, .decode_footprint=(void *)fd_stake_reward_calculation_partitioned_decode_footprint, .encode=(void *)fd_stake_reward_calculation_partitioned_encode }, - { .name="fd_stake_reward_calculation", .name_len=27, .align=FD_STAKE_REWARD_CALCULATION_ALIGN, .new_=(void *)fd_stake_reward_calculation_new, .decode=(void *)fd_stake_reward_calculation_decode, .size=(void *)fd_stake_reward_calculation_size, .walk=(void *)fd_stake_reward_calculation_walk, .decode_footprint=(void *)fd_stake_reward_calculation_decode_footprint, .encode=(void *)fd_stake_reward_calculation_encode }, - { .name="fd_calculate_stake_vote_rewards_result", .name_len=38, .align=FD_CALCULATE_STAKE_VOTE_REWARDS_RESULT_ALIGN, .new_=(void *)fd_calculate_stake_vote_rewards_result_new, .decode=(void *)fd_calculate_stake_vote_rewards_result_decode, .size=(void *)fd_calculate_stake_vote_rewards_result_size, .walk=(void *)fd_calculate_stake_vote_rewards_result_walk, .decode_footprint=(void *)fd_calculate_stake_vote_rewards_result_decode_footprint, .encode=(void *)fd_calculate_stake_vote_rewards_result_encode }, - { .name="fd_calculate_validator_rewards_result", .name_len=37, .align=FD_CALCULATE_VALIDATOR_REWARDS_RESULT_ALIGN, .new_=(void *)fd_calculate_validator_rewards_result_new, .decode=(void *)fd_calculate_validator_rewards_result_decode, .size=(void *)fd_calculate_validator_rewards_result_size, .walk=(void *)fd_calculate_validator_rewards_result_walk, .decode_footprint=(void *)fd_calculate_validator_rewards_result_decode_footprint, .encode=(void *)fd_calculate_validator_rewards_result_encode }, { .name="fd_partitioned_rewards_calculation", .name_len=34, .align=FD_PARTITIONED_REWARDS_CALCULATION_ALIGN, .new_=(void *)fd_partitioned_rewards_calculation_new, .decode=(void *)fd_partitioned_rewards_calculation_decode, .size=(void *)fd_partitioned_rewards_calculation_size, .walk=(void *)fd_partitioned_rewards_calculation_walk, .decode_footprint=(void *)fd_partitioned_rewards_calculation_decode_footprint, .encode=(void *)fd_partitioned_rewards_calculation_encode }, - { .name="fd_start_block_height_and_rewards", .name_len=33, .align=FD_START_BLOCK_HEIGHT_AND_REWARDS_ALIGN, .new_=(void *)fd_start_block_height_and_rewards_new, .decode=(void *)fd_start_block_height_and_rewards_decode, .size=(void *)fd_start_block_height_and_rewards_size, .walk=(void *)fd_start_block_height_and_rewards_walk, .decode_footprint=(void *)fd_start_block_height_and_rewards_decode_footprint, .encode=(void *)fd_start_block_height_and_rewards_encode }, - { .name="fd_fd_epoch_reward_status_inner", .name_len=31, .align=FD_FD_EPOCH_REWARD_STATUS_INNER_ALIGN, .new_=(void *)fd_fd_epoch_reward_status_inner_new, .decode=(void *)fd_fd_epoch_reward_status_inner_decode, .size=(void *)fd_fd_epoch_reward_status_inner_size, .walk=(void *)fd_fd_epoch_reward_status_inner_walk, .decode_footprint=(void *)fd_fd_epoch_reward_status_inner_decode_footprint, .encode=(void *)fd_fd_epoch_reward_status_inner_encode }, - { .name="fd_epoch_reward_status", .name_len=22, .align=FD_EPOCH_REWARD_STATUS_ALIGN, .new_=(void *)fd_epoch_reward_status_new, .decode=(void *)fd_epoch_reward_status_decode, .size=(void *)fd_epoch_reward_status_size, .walk=(void *)fd_epoch_reward_status_walk, .decode_footprint=(void *)fd_epoch_reward_status_decode_footprint, .encode=(void *)fd_epoch_reward_status_encode }, { .name="fd_prev_epoch_inflation_rewards", .name_len=31, .align=FD_PREV_EPOCH_INFLATION_REWARDS_ALIGN, .new_=(void *)fd_prev_epoch_inflation_rewards_new, .decode=(void *)fd_prev_epoch_inflation_rewards_decode, .size=(void *)fd_prev_epoch_inflation_rewards_size, .walk=(void *)fd_prev_epoch_inflation_rewards_walk, .decode_footprint=(void *)fd_prev_epoch_inflation_rewards_decode_footprint, .encode=(void *)fd_prev_epoch_inflation_rewards_encode }, { .name="fd_vote", .name_len=7, .align=FD_VOTE_ALIGN, .new_=(void *)fd_vote_new, .decode=(void *)fd_vote_decode, .size=(void *)fd_vote_size, .walk=(void *)fd_vote_walk, .decode_footprint=(void *)fd_vote_decode_footprint, .encode=(void *)fd_vote_encode }, { .name="fd_vote_init", .name_len=12, .align=FD_VOTE_INIT_ALIGN, .new_=(void *)fd_vote_init_new, .decode=(void *)fd_vote_init_decode, .size=(void *)fd_vote_init_size, .walk=(void *)fd_vote_init_walk, .decode_footprint=(void *)fd_vote_init_decode_footprint, .encode=(void *)fd_vote_init_encode }, @@ -158,7 +148,6 @@ fd_types_vt_t const fd_types_vt_list[] = { { .name="fd_txn_instr_error", .name_len=18, .align=FD_TXN_INSTR_ERROR_ALIGN, .new_=(void *)fd_txn_instr_error_new, .decode=(void *)fd_txn_instr_error_decode, .size=(void *)fd_txn_instr_error_size, .walk=(void *)fd_txn_instr_error_walk, .decode_footprint=(void *)fd_txn_instr_error_decode_footprint, .encode=(void *)fd_txn_instr_error_encode }, { .name="fd_txn_error_enum", .name_len=17, .align=FD_TXN_ERROR_ENUM_ALIGN, .new_=(void *)fd_txn_error_enum_new, .decode=(void *)fd_txn_error_enum_decode, .size=(void *)fd_txn_error_enum_size, .walk=(void *)fd_txn_error_enum_walk, .decode_footprint=(void *)fd_txn_error_enum_decode_footprint, .encode=(void *)fd_txn_error_enum_encode }, { .name="fd_txn_result", .name_len=13, .align=FD_TXN_RESULT_ALIGN, .new_=(void *)fd_txn_result_new, .decode=(void *)fd_txn_result_decode, .size=(void *)fd_txn_result_size, .walk=(void *)fd_txn_result_walk, .decode_footprint=(void *)fd_txn_result_decode_footprint, .encode=(void *)fd_txn_result_encode }, - { .name="fd_pubkey_rewardinfo_pair", .name_len=25, .align=FD_PUBKEY_REWARDINFO_PAIR_ALIGN, .new_=(void *)fd_pubkey_rewardinfo_pair_new, .decode=(void *)fd_pubkey_rewardinfo_pair_decode, .size=(void *)fd_pubkey_rewardinfo_pair_size, .walk=(void *)fd_pubkey_rewardinfo_pair_walk, .decode_footprint=(void *)fd_pubkey_rewardinfo_pair_decode_footprint, .encode=(void *)fd_pubkey_rewardinfo_pair_encode }, { .name="fd_calculated_stake_points", .name_len=26, .align=FD_CALCULATED_STAKE_POINTS_ALIGN, .new_=(void *)fd_calculated_stake_points_new, .decode=(void *)fd_calculated_stake_points_decode, .size=(void *)fd_calculated_stake_points_size, .walk=(void *)fd_calculated_stake_points_walk, .decode_footprint=(void *)fd_calculated_stake_points_decode_footprint, .encode=(void *)fd_calculated_stake_points_encode }, { .name="fd_calculated_stake_rewards", .name_len=27, .align=FD_CALCULATED_STAKE_REWARDS_ALIGN, .new_=(void *)fd_calculated_stake_rewards_new, .decode=(void *)fd_calculated_stake_rewards_decode, .size=(void *)fd_calculated_stake_rewards_size, .walk=(void *)fd_calculated_stake_rewards_walk, .decode_footprint=(void *)fd_calculated_stake_rewards_decode_footprint, .encode=(void *)fd_calculated_stake_rewards_encode }, { .name="fd_duplicate_slot_proof", .name_len=23, .align=FD_DUPLICATE_SLOT_PROOF_ALIGN, .new_=(void *)fd_duplicate_slot_proof_new, .decode=(void *)fd_duplicate_slot_proof_decode, .size=(void *)fd_duplicate_slot_proof_size, .walk=(void *)fd_duplicate_slot_proof_walk, .decode_footprint=(void *)fd_duplicate_slot_proof_decode_footprint, .encode=(void *)fd_duplicate_slot_proof_encode },