From 87488ca9ef8e87201c1d81774f2e8052fc75c051 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 4 Dec 2025 19:42:09 +0000 Subject: [PATCH 1/8] vote_states: seeding in runtime properly --- src/discof/restore/utils/fd_ssload.c | 6 +++--- src/flamenco/runtime/fd_bank.c | 12 ++++++++++++ src/flamenco/runtime/fd_runtime.c | 3 +-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/discof/restore/utils/fd_ssload.c b/src/discof/restore/utils/fd_ssload.c index 3f3a2fef924..9d989d1aa8c 100644 --- a/src/discof/restore/utils/fd_ssload.c +++ b/src/discof/restore/utils/fd_ssload.c @@ -199,7 +199,7 @@ fd_ssload_recover( fd_snapshot_manifest_t * manifest, } /* Vote stakes for the previous epoch (E-1). */ - fd_vote_states_t * vote_stakes_prev = fd_vote_states_join( fd_vote_states_new( fd_bank_vote_states_prev_locking_modify( bank ), FD_RUNTIME_MAX_VOTE_ACCOUNTS, 999UL ) ); + fd_vote_states_t * vote_stakes_prev = fd_bank_vote_states_prev_locking_modify( bank ); for( ulong i=0UL; iepoch_stakes[1].vote_stakes_len; i++ ) { fd_snapshot_manifest_vote_stakes_t const * elem = &manifest->epoch_stakes[1].vote_stakes[i]; if( FD_UNLIKELY( !elem->stake ) ) continue; @@ -249,7 +249,7 @@ fd_ssload_recover( fd_snapshot_manifest_t * manifest, fd_bank_total_epoch_stake_set( bank, manifest->epoch_stakes[1].total_stake ); /* Vote stakes for the previous epoch (E-2) */ - fd_vote_states_t * vote_stakes_prev_prev = fd_vote_states_join( fd_vote_states_new( fd_bank_vote_states_prev_prev_locking_modify( bank ), FD_RUNTIME_MAX_VOTE_ACCOUNTS, 999UL ) ); + fd_vote_states_t * vote_stakes_prev_prev = fd_bank_vote_states_prev_prev_locking_modify( bank ); for( ulong i=0UL; iepoch_stakes[0].vote_stakes_len; i++ ) { fd_snapshot_manifest_vote_stakes_t const * elem = &manifest->epoch_stakes[0].vote_stakes[i]; if( FD_UNLIKELY( !elem->stake ) ) continue; @@ -262,7 +262,7 @@ fd_ssload_recover( fd_snapshot_manifest_t * manifest, } /* Vote states for the current epoch. */ - fd_vote_states_t * vote_states = fd_vote_states_join( fd_vote_states_new( fd_bank_vote_states_locking_modify( bank ), FD_RUNTIME_MAX_VOTE_ACCOUNTS, 999UL ) ); + fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); for( ulong i=0UL; ivote_accounts_len; i++ ) { fd_snapshot_manifest_vote_account_t const * elem = &manifest->vote_accounts[ i ]; diff --git a/src/flamenco/runtime/fd_bank.c b/src/flamenco/runtime/fd_bank.c index 7057b9f9861..88e75680424 100644 --- a/src/flamenco/runtime/fd_bank.c +++ b/src/flamenco/runtime/fd_bank.c @@ -311,6 +311,18 @@ fd_banks_new( void * shmem, fd_bank_set_cost_tracker_pool( bank, cost_tracker_pool ); } + for( ulong i=0UL; idata, FD_RUNTIME_MAX_VOTE_ACCOUNTS, seed ) ); + } + + for( ulong i=0UL; idata, FD_RUNTIME_MAX_VOTE_ACCOUNTS, seed ) ); + } + + for( ulong i=0UL; idata, FD_RUNTIME_MAX_VOTE_ACCOUNTS, seed ) ); + } + banks->max_total_banks = max_total_banks; banks->max_fork_width = max_fork_width; banks->root_idx = ULONG_MAX; diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 651724f1249..6d3cfac794d 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1449,7 +1449,6 @@ fd_runtime_init_bank_from_genesis( fd_banks_t * banks, /* FIXME Why is there a previous blockhash at genesis? Why is the last_hash field an option type in Agave, if even the first real block has a previous blockhash? */ - /* TODO: Use a real seed here. */ fd_blockhashes_t * bhq = fd_blockhashes_init( fd_bank_block_hash_queue_modify( bank ), 0UL ); fd_blockhash_info_t * info = fd_blockhashes_push_new( bhq, genesis_hash ); info->fee_calculator.lamports_per_signature = 0UL; @@ -1478,7 +1477,7 @@ fd_runtime_init_bank_from_genesis( fd_banks_t * banks, FD_LOG_CRIT(( "Failed to join and new a stake delegations" )); } - fd_vote_states_t * vote_states = fd_vote_states_join( fd_vote_states_new( fd_bank_vote_states_locking_modify( bank ), FD_RUNTIME_MAX_VOTE_ACCOUNTS, 999UL ) ); + fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); if( FD_UNLIKELY( !vote_states ) ) { FD_LOG_CRIT(( "Failed to join and new a vote states" )); } From 35d2adfff5235e40fb1ec8a2cd152251c814193c Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 4 Dec 2025 20:17:22 +0000 Subject: [PATCH 2/8] wip --- src/flamenco/rewards/fd_epoch_rewards.c | 51 ++++++++++++------- src/flamenco/rewards/fd_epoch_rewards.h | 6 +++ src/flamenco/rewards/fd_rewards.c | 5 +- src/flamenco/runtime/fd_bank.c | 6 ++- src/flamenco/runtime/fd_bank.h | 8 ++- src/flamenco/runtime/tests/fd_block_harness.c | 2 +- src/flamenco/runtime/tests/test_dump_block.c | 4 +- src/flamenco/stakes/fd_stake_delegations.c | 4 +- src/flamenco/stakes/fd_stake_delegations.h | 1 + src/flamenco/stakes/test_stake_delegations.c | 8 +-- 10 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/flamenco/rewards/fd_epoch_rewards.c b/src/flamenco/rewards/fd_epoch_rewards.c index 7d59a500906..9e4e764dc8d 100644 --- a/src/flamenco/rewards/fd_epoch_rewards.c +++ b/src/flamenco/rewards/fd_epoch_rewards.c @@ -14,6 +14,28 @@ #define MAP_NEXT next_map #include "../../util/tmpl/fd_map_chain.c" +static inline fd_epoch_stake_reward_t * +fd_epoch_rewards_get_stake_reward_pool( fd_epoch_rewards_t const * epoch_rewards ) { + return fd_epoch_stake_reward_pool_join( (uchar *)epoch_rewards + epoch_rewards->pool_offset ); +} + +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 ); +} + +static inline fd_epoch_stake_reward_dlist_t * +fd_epoch_rewards_get_partition_index( fd_epoch_rewards_t const * epoch_rewards, ulong idx ) { + 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_epoch_stake_reward_dlist_t * dlist_idx_zero = (fd_epoch_stake_reward_dlist_t *)((uchar *)epoch_rewards + epoch_rewards->dlists_offset); + fd_epoch_stake_reward_dlist_t * partition_dlist = fd_epoch_stake_reward_dlist_join( dlist_idx_zero + idx ); + return partition_dlist; +} + ulong fd_epoch_rewards_align( void ) { return FD_EPOCH_REWARDS_ALIGN; @@ -32,7 +54,8 @@ fd_epoch_rewards_footprint( ulong stake_account_max ) { } void * -fd_epoch_rewards_new( void * shmem, ulong stake_account_max ) { +fd_epoch_rewards_new( void * shmem, + ulong stake_account_max ) { if( FD_UNLIKELY( !shmem ) ) { FD_LOG_WARNING(( "NULL mem" )); @@ -166,26 +189,20 @@ fd_epoch_rewards_delete( void * epoch_rewards_shmem ) { return epoch_rewards_shmem; } -static inline fd_epoch_stake_reward_dlist_t * -fd_epoch_rewards_get_partition_index( fd_epoch_rewards_t const * epoch_rewards, ulong idx ) { - 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; +void +fd_epoch_rewards_init( fd_epoch_rewards_t * epoch_rewards ) { + fd_epoch_stake_reward_t * stake_reward_pool = fd_epoch_rewards_get_stake_reward_pool( epoch_rewards ); + 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_map_t * stake_reward_map = fd_epoch_rewards_get_stake_reward_map( epoch_rewards ); + fd_epoch_stake_reward_map_reset( stake_reward_map ); -static inline fd_epoch_stake_reward_t * -fd_epoch_rewards_get_stake_reward_pool( fd_epoch_rewards_t const * epoch_rewards ) { - return fd_epoch_stake_reward_pool_join( (uchar *)epoch_rewards + epoch_rewards->pool_offset ); -} + fd_epoch_stake_reward_pool_reset( 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 ); + return; } void diff --git a/src/flamenco/rewards/fd_epoch_rewards.h b/src/flamenco/rewards/fd_epoch_rewards.h index 917d13ee71e..bd6291cd997 100644 --- a/src/flamenco/rewards/fd_epoch_rewards.h +++ b/src/flamenco/rewards/fd_epoch_rewards.h @@ -168,6 +168,12 @@ fd_epoch_rewards_leave( fd_epoch_rewards_t const * epoch_rewards ); void * fd_epoch_rewards_delete( void * epoch_rewards ); +/* fd_epoch_rewards_init resets the epoch rewards struct to the initial + state given a valid local join. */ + +void +fd_epoch_rewards_init( fd_epoch_rewards_t * epoch_rewards ); + /* fd_epoch_rewards_insert stores the rewards for a given stake account into the data structure. */ diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index 41c993dcf95..2db8cb12922 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -557,13 +557,12 @@ calculate_stake_vote_rewards( fd_bank_t * bank, new_warmup_cooldown_rate_epoch = NULL; } - ulong minimum_stake_delegation = get_minimum_stake_delegation( bank ); - ulong stake_delegation_cnt = fd_stake_delegations_cnt( stake_delegations ); fd_vote_states_t * vote_states = !!runtime_stack->stakes.prev_vote_credits_used ? fd_bank_vote_states_prev_locking_modify( bank ) : fd_bank_vote_states_locking_modify( bank ); - 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_epoch_rewards_t * epoch_rewards = fd_bank_epoch_rewards_locking_modify( bank ); + fd_epoch_rewards_init( epoch_rewards ); /* Reset the vote rewards for each vote account. */ fd_memset( runtime_stack->stakes.vote_rewards, 0UL, sizeof(runtime_stack->stakes.vote_rewards) ); diff --git a/src/flamenco/runtime/fd_bank.c b/src/flamenco/runtime/fd_bank.c index 88e75680424..480f317ab41 100644 --- a/src/flamenco/runtime/fd_bank.c +++ b/src/flamenco/runtime/fd_bank.c @@ -311,6 +311,10 @@ fd_banks_new( void * shmem, fd_bank_set_cost_tracker_pool( bank, cost_tracker_pool ); } + for( ulong i=0UL; idata, FD_RUNTIME_MAX_STAKE_ACCOUNTS ) ); + } + for( ulong i=0UL; idata, FD_RUNTIME_MAX_VOTE_ACCOUNTS, seed ) ); } @@ -327,7 +331,7 @@ fd_banks_new( void * shmem, banks->max_fork_width = max_fork_width; banks->root_idx = ULONG_MAX; - if( FD_UNLIKELY( !fd_stake_delegations_new( banks->stake_delegations_root, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ) ) { + if( FD_UNLIKELY( !fd_stake_delegations_new( banks->stake_delegations_root, 0UL, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ) ) { FD_LOG_WARNING(( "Unable to create stake delegations root" )); return NULL; } diff --git a/src/flamenco/runtime/fd_bank.h b/src/flamenco/runtime/fd_bank.h index 5becedebe02..522ab66da12 100644 --- a/src/flamenco/runtime/fd_bank.h +++ b/src/flamenco/runtime/fd_bank.h @@ -371,6 +371,10 @@ struct fd_bank { int stake_delegations_delta_dirty; fd_rwlock_t stake_delegations_delta_lock; + /* Vote states. */ + uchar vote_states_mem_[FD_VOTE_STATES_FOOTPRINT] __attribute__((aligned(FD_VOTE_STATES_ALIGN))); + fd_rwlock_t vote_states_lock_; + ulong refcnt; /* (r) reference count on the bank, see replay for more details */ fd_txncache_fork_id_t txncache_fork_id; /* fork id used by the txn cache */ @@ -532,6 +536,8 @@ struct fd_banks { ulong cost_tracker_pool_offset; /* offset of cost tracker pool from banks */ + ulong vote_states_pool_offset_; + /* stake_delegations_root will be the full state of stake delegations for the current root. It can get updated in two ways: 1. On boot the snapshot will be directly read into the rooted @@ -645,7 +651,7 @@ fd_bank_stake_delegations_delta_locking_modify( fd_bank_t * bank ) { fd_rwlock_write( &bank->stake_delegations_delta_lock ); if( !bank->stake_delegations_delta_dirty ) { bank->stake_delegations_delta_dirty = 1; - fd_stake_delegations_new( bank->stake_delegations_delta, FD_STAKE_DELEGATIONS_MAX_PER_SLOT, 1 ); + fd_stake_delegations_new( bank->stake_delegations_delta, FD_STAKE_DELEGATIONS_MAX_PER_SLOT, 1, 999UL ); } return fd_stake_delegations_join( bank->stake_delegations_delta ); } diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index 5910ce5d590..4ba523bd62c 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -345,7 +345,7 @@ fd_solfuzz_pb_block_ctx_create( fd_solfuzz_runner_t * runner, fd_bank_vote_states_prev_prev_end_locking_modify( bank ); fd_stake_delegations_t * stake_delegations = fd_banks_stake_delegations_root_query( banks ); - stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); + stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, 0UL, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); /* Load in all accounts with > 0 lamports provided in the context. The input expects unique account pubkeys. */ vote_states = fd_bank_vote_states_locking_modify( bank ); diff --git a/src/flamenco/runtime/tests/test_dump_block.c b/src/flamenco/runtime/tests/test_dump_block.c index 6cdac32ff95..a6484efdaeb 100644 --- a/src/flamenco/runtime/tests/test_dump_block.c +++ b/src/flamenco/runtime/tests/test_dump_block.c @@ -101,7 +101,7 @@ test_ctx_setup( void ) { /* Initialize stake delegations at the root level */ fd_stake_delegations_t * stake_delegations = fd_banks_stake_delegations_root_query( test_ctx->banks ); - stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); + stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, 0UL, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); FD_TEST( stake_delegations ); /* ===== Create Parent Bank ===== */ @@ -480,7 +480,7 @@ FD_SPAD_FRAME_BEGIN( test_ctx->spad ) { /* Initialize and populate stake delegations cache from accounts */ fd_stake_delegations_t * stake_delegations = fd_banks_stake_delegations_root_query( test_ctx->banks ); - stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); + stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, 0UL, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); /* Initialize and populate current epoch vote states from accounts */ fd_vote_states_t * vote_states_current = fd_bank_vote_states_locking_modify( test_ctx->parent_bank ); diff --git a/src/flamenco/stakes/fd_stake_delegations.c b/src/flamenco/stakes/fd_stake_delegations.c index 045dfe129b7..1a6c9cfd6af 100644 --- a/src/flamenco/stakes/fd_stake_delegations.c +++ b/src/flamenco/stakes/fd_stake_delegations.c @@ -50,6 +50,7 @@ fd_stake_delegations_footprint( ulong max_stake_accounts ) { void * fd_stake_delegations_new( void * mem, + ulong seed, ulong max_stake_accounts, int leave_tombstones ) { if( FD_UNLIKELY( !mem ) ) { @@ -84,8 +85,7 @@ fd_stake_delegations_new( void * mem, return NULL; } - /* TODO: The seed shouldn't be hardcoded. */ - if( FD_UNLIKELY( !fd_stake_delegation_map_new( map_mem, map_chain_cnt, 999UL ) ) ) { + if( FD_UNLIKELY( !fd_stake_delegation_map_new( map_mem, map_chain_cnt, seed ) ) ) { FD_LOG_WARNING(( "Failed to create stake delegations map" )); return NULL; } diff --git a/src/flamenco/stakes/fd_stake_delegations.h b/src/flamenco/stakes/fd_stake_delegations.h index 44f84538ee9..ffd66ee17ff 100644 --- a/src/flamenco/stakes/fd_stake_delegations.h +++ b/src/flamenco/stakes/fd_stake_delegations.h @@ -200,6 +200,7 @@ fd_stake_delegations_footprint( ulong max_stake_accounts ); void * fd_stake_delegations_new( void * mem, + ulong seed, ulong max_stake_accounts, int leave_tombstones ); diff --git a/src/flamenco/stakes/test_stake_delegations.c b/src/flamenco/stakes/test_stake_delegations.c index 94b2be17f6c..e088f1d898f 100644 --- a/src/flamenco/stakes/test_stake_delegations.c +++ b/src/flamenco/stakes/test_stake_delegations.c @@ -36,9 +36,9 @@ int main( int argc, char ** argv ) { FD_TEST( fd_stake_delegations_align()>=alignof(fd_stake_delegations_t) ); FD_TEST( fd_stake_delegations_align()==FD_STAKE_DELEGATIONS_ALIGN ); - FD_TEST( !fd_stake_delegations_new( NULL, max_stake_accounts, 0 ) ); - FD_TEST( !fd_stake_delegations_new( stake_delegations_mem, 0UL, 0 ) ); - void * new_stake_delegations_mem = fd_stake_delegations_new( stake_delegations_mem, max_stake_accounts, 0 ); + FD_TEST( !fd_stake_delegations_new( NULL, 0UL, max_stake_accounts, 0 ) ); + FD_TEST( !fd_stake_delegations_new( stake_delegations_mem, 0UL, 0UL, 0 ) ); + void * new_stake_delegations_mem = fd_stake_delegations_new( stake_delegations_mem, 0UL, max_stake_accounts, 0 ); FD_TEST( new_stake_delegations_mem ); FD_TEST( !fd_stake_delegations_join( NULL ) ); @@ -131,7 +131,7 @@ int main( int argc, char ** argv ) { FD_TEST( !fd_stake_delegations_join( deleted_mem ) ); /* Test stake_delegations where is_tombstone == 1. */ - stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations_mem, max_stake_accounts, 1 ) ); + stake_delegations = fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations_mem, 0UL, max_stake_accounts, 1 ) ); FD_TEST( stake_delegations ); FD_TEST( fd_stake_delegations_cnt( stake_delegations ) == 0UL ); From 720834327ee853c354243233cd0b6790942ca925 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 4 Dec 2025 20:26:39 +0000 Subject: [PATCH 3/8] wip --- src/flamenco/runtime/fd_bank.c | 3 +++ src/flamenco/runtime/fd_bank.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/flamenco/runtime/fd_bank.c b/src/flamenco/runtime/fd_bank.c index 480f317ab41..0701b376d00 100644 --- a/src/flamenco/runtime/fd_bank.c +++ b/src/flamenco/runtime/fd_bank.c @@ -306,6 +306,9 @@ fd_banks_new( void * shmem, #undef HAS_COW_0 #undef HAS_COW_1 + fd_stake_delegations_t * stake_delegations = fd_bank_stake_delegations_delta_locking_modify( bank ); + fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, 0UL, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); + /* The cost tracker is not templatized and must be set manually. */ fd_bank_cost_tracker_t * cost_tracker_pool = fd_banks_get_cost_tracker_pool( banks ); fd_bank_set_cost_tracker_pool( bank, cost_tracker_pool ); diff --git a/src/flamenco/runtime/fd_bank.h b/src/flamenco/runtime/fd_bank.h index 522ab66da12..939b61f8da5 100644 --- a/src/flamenco/runtime/fd_bank.h +++ b/src/flamenco/runtime/fd_bank.h @@ -651,7 +651,7 @@ fd_bank_stake_delegations_delta_locking_modify( fd_bank_t * bank ) { fd_rwlock_write( &bank->stake_delegations_delta_lock ); if( !bank->stake_delegations_delta_dirty ) { bank->stake_delegations_delta_dirty = 1; - fd_stake_delegations_new( bank->stake_delegations_delta, FD_STAKE_DELEGATIONS_MAX_PER_SLOT, 1, 999UL ); + fd_stake_delegations_new( bank->stake_delegations_delta, 999UL, FD_STAKE_DELEGATIONS_MAX_PER_SLOT, 1 ); } return fd_stake_delegations_join( bank->stake_delegations_delta ); } From 630e341819fe55d629abbf4f806d833c7847a303 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 4 Dec 2025 20:34:50 +0000 Subject: [PATCH 4/8] wip --- src/flamenco/runtime/fd_bank.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/flamenco/runtime/fd_bank.c b/src/flamenco/runtime/fd_bank.c index 0701b376d00..480f317ab41 100644 --- a/src/flamenco/runtime/fd_bank.c +++ b/src/flamenco/runtime/fd_bank.c @@ -306,9 +306,6 @@ fd_banks_new( void * shmem, #undef HAS_COW_0 #undef HAS_COW_1 - fd_stake_delegations_t * stake_delegations = fd_bank_stake_delegations_delta_locking_modify( bank ); - fd_stake_delegations_join( fd_stake_delegations_new( stake_delegations, 0UL, FD_RUNTIME_MAX_STAKE_ACCOUNTS, 0 ) ); - /* The cost tracker is not templatized and must be set manually. */ fd_bank_cost_tracker_t * cost_tracker_pool = fd_banks_get_cost_tracker_pool( banks ); fd_bank_set_cost_tracker_pool( bank, cost_tracker_pool ); From 3bf166af7e4f024abba5c27a96be95c36d68608f Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 4 Dec 2025 20:48:29 +0000 Subject: [PATCH 5/8] wip --- src/flamenco/rewards/fd_epoch_rewards.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/flamenco/rewards/fd_epoch_rewards.c b/src/flamenco/rewards/fd_epoch_rewards.c index 9e4e764dc8d..10dc5846957 100644 --- a/src/flamenco/rewards/fd_epoch_rewards.c +++ b/src/flamenco/rewards/fd_epoch_rewards.c @@ -26,11 +26,6 @@ fd_epoch_rewards_get_stake_reward_map( fd_epoch_rewards_t const * epoch_rewards static inline fd_epoch_stake_reward_dlist_t * fd_epoch_rewards_get_partition_index( fd_epoch_rewards_t const * epoch_rewards, ulong idx ) { - 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_epoch_stake_reward_dlist_t * dlist_idx_zero = (fd_epoch_stake_reward_dlist_t *)((uchar *)epoch_rewards + epoch_rewards->dlists_offset); fd_epoch_stake_reward_dlist_t * partition_dlist = fd_epoch_stake_reward_dlist_join( dlist_idx_zero + idx ); return partition_dlist; From 6586c22e0f6ef5e0bbb090b40245f9bef45e988c Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 4 Dec 2025 20:54:10 +0000 Subject: [PATCH 6/8] wip --- src/flamenco/runtime/fd_bank.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/flamenco/runtime/fd_bank.h b/src/flamenco/runtime/fd_bank.h index 939b61f8da5..8edb2e00c9f 100644 --- a/src/flamenco/runtime/fd_bank.h +++ b/src/flamenco/runtime/fd_bank.h @@ -371,10 +371,6 @@ struct fd_bank { int stake_delegations_delta_dirty; fd_rwlock_t stake_delegations_delta_lock; - /* Vote states. */ - uchar vote_states_mem_[FD_VOTE_STATES_FOOTPRINT] __attribute__((aligned(FD_VOTE_STATES_ALIGN))); - fd_rwlock_t vote_states_lock_; - ulong refcnt; /* (r) reference count on the bank, see replay for more details */ fd_txncache_fork_id_t txncache_fork_id; /* fork id used by the txn cache */ From dc514dff387589ec2078a056596990f90ae33d2d Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 4 Dec 2025 21:06:33 +0000 Subject: [PATCH 7/8] wip --- src/flamenco/rewards/fd_epoch_rewards.c | 8 +++++--- src/flamenco/rewards/fd_epoch_rewards.h | 4 +++- src/flamenco/rewards/test_epoch_rewards.c | 6 +++--- src/flamenco/runtime/fd_bank.c | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/flamenco/rewards/fd_epoch_rewards.c b/src/flamenco/rewards/fd_epoch_rewards.c index 10dc5846957..406afbc6264 100644 --- a/src/flamenco/rewards/fd_epoch_rewards.c +++ b/src/flamenco/rewards/fd_epoch_rewards.c @@ -50,7 +50,8 @@ fd_epoch_rewards_footprint( ulong stake_account_max ) { void * fd_epoch_rewards_new( void * shmem, - ulong stake_account_max ) { + ulong stake_account_max, + ulong seed ) { if( FD_UNLIKELY( !shmem ) ) { FD_LOG_WARNING(( "NULL mem" )); @@ -76,7 +77,7 @@ fd_epoch_rewards_new( void * shmem, 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 ) ) ) { + if( FD_UNLIKELY( !fd_epoch_stake_reward_map_new( map, chain_cnt_est, seed ) ) ) { FD_LOG_WARNING(( "bad map" )); return NULL; } @@ -197,7 +198,8 @@ fd_epoch_rewards_init( fd_epoch_rewards_t * epoch_rewards ) { fd_epoch_stake_reward_pool_reset( stake_reward_pool ); - return; + epoch_rewards->stake_rewards_cnt = 0UL; + epoch_rewards->total_stake_rewards = 0UL; } void diff --git a/src/flamenco/rewards/fd_epoch_rewards.h b/src/flamenco/rewards/fd_epoch_rewards.h index bd6291cd997..dd3bfcd8516 100644 --- a/src/flamenco/rewards/fd_epoch_rewards.h +++ b/src/flamenco/rewards/fd_epoch_rewards.h @@ -148,7 +148,9 @@ fd_epoch_rewards_footprint( ulong stake_account_max ); /* fd_epoch_rewards_new initializes the epoch_rewards struct. */ void * -fd_epoch_rewards_new( void * shmem, ulong stake_account_max ); +fd_epoch_rewards_new( void * shmem, + ulong stake_account_max, + ulong seed ); /* fd_epoch_rewards_join returns a pointer to the epoch rewards struct that is stored in the shared memory. */ diff --git a/src/flamenco/rewards/test_epoch_rewards.c b/src/flamenco/rewards/test_epoch_rewards.c index 94edd08bbee..b8d42d86c2c 100644 --- a/src/flamenco/rewards/test_epoch_rewards.c +++ b/src/flamenco/rewards/test_epoch_rewards.c @@ -29,7 +29,7 @@ int main( int argc, char * * argv ) { /* No mem passed in. */ - epoch_rewards_mem = fd_epoch_rewards_new( NULL, STAKE_ACC_MAX ); + epoch_rewards_mem = fd_epoch_rewards_new( NULL, STAKE_ACC_MAX, 0UL ); FD_TEST( !epoch_rewards_mem ); /* Correctly aligned memory. Successful new() call. */ @@ -37,7 +37,7 @@ int main( int argc, char * * argv ) { uchar * mem = fd_wksp_alloc_laddr( wksp, fd_epoch_rewards_align(), fd_epoch_rewards_footprint( STAKE_ACC_MAX ), 1UL ); FD_TEST( mem ); - epoch_rewards_mem = fd_epoch_rewards_new( mem, STAKE_ACC_MAX ); + epoch_rewards_mem = fd_epoch_rewards_new( mem, STAKE_ACC_MAX, 0UL ); FD_TEST( epoch_rewards_mem ); /* Fail join due to bad magic. */ @@ -48,7 +48,7 @@ int main( int argc, char * * argv ) { epoch_rewards = fd_epoch_rewards_join( epoch_rewards_mem ); FD_TEST( !epoch_rewards ); - epoch_rewards_mem = fd_epoch_rewards_new( mem, STAKE_ACC_MAX ); + epoch_rewards_mem = fd_epoch_rewards_new( mem, STAKE_ACC_MAX, 0UL ); FD_TEST( epoch_rewards_mem ); FD_TEST( !fd_epoch_rewards_join( NULL ) ); diff --git a/src/flamenco/runtime/fd_bank.c b/src/flamenco/runtime/fd_bank.c index 480f317ab41..4f8e50b2a19 100644 --- a/src/flamenco/runtime/fd_bank.c +++ b/src/flamenco/runtime/fd_bank.c @@ -312,7 +312,7 @@ fd_banks_new( void * shmem, } for( ulong i=0UL; idata, FD_RUNTIME_MAX_STAKE_ACCOUNTS ) ); + fd_epoch_rewards_join( fd_epoch_rewards_new( fd_bank_epoch_rewards_pool_ele( fd_banks_get_epoch_rewards_pool( banks ), i )->data, FD_RUNTIME_MAX_STAKE_ACCOUNTS, seed ) ); } for( ulong i=0UL; i Date: Thu, 4 Dec 2025 21:17:22 +0000 Subject: [PATCH 8/8] wip --- src/flamenco/runtime/fd_bank.c | 2 ++ src/flamenco/runtime/fd_bank.h | 4 ++-- src/flamenco/stakes/fd_stake_delegations.c | 8 ++++++++ src/flamenco/stakes/fd_stake_delegations.h | 6 ++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/flamenco/runtime/fd_bank.c b/src/flamenco/runtime/fd_bank.c index 4f8e50b2a19..caf17dd8d78 100644 --- a/src/flamenco/runtime/fd_bank.c +++ b/src/flamenco/runtime/fd_bank.c @@ -306,6 +306,8 @@ fd_banks_new( void * shmem, #undef HAS_COW_0 #undef HAS_COW_1 + fd_stake_delegations_join( fd_stake_delegations_new( bank->stake_delegations_delta, seed, FD_STAKE_DELEGATIONS_MAX_PER_SLOT, 1 ) ); + /* The cost tracker is not templatized and must be set manually. */ fd_bank_cost_tracker_t * cost_tracker_pool = fd_banks_get_cost_tracker_pool( banks ); fd_bank_set_cost_tracker_pool( bank, cost_tracker_pool ); diff --git a/src/flamenco/runtime/fd_bank.h b/src/flamenco/runtime/fd_bank.h index 8edb2e00c9f..579f373c258 100644 --- a/src/flamenco/runtime/fd_bank.h +++ b/src/flamenco/runtime/fd_bank.h @@ -647,9 +647,9 @@ fd_bank_stake_delegations_delta_locking_modify( fd_bank_t * bank ) { fd_rwlock_write( &bank->stake_delegations_delta_lock ); if( !bank->stake_delegations_delta_dirty ) { bank->stake_delegations_delta_dirty = 1; - fd_stake_delegations_new( bank->stake_delegations_delta, 999UL, FD_STAKE_DELEGATIONS_MAX_PER_SLOT, 1 ); + fd_stake_delegations_init( fd_type_pun( bank->stake_delegations_delta ) ); } - return fd_stake_delegations_join( bank->stake_delegations_delta ); + return fd_type_pun( bank->stake_delegations_delta ); } static inline void diff --git a/src/flamenco/stakes/fd_stake_delegations.c b/src/flamenco/stakes/fd_stake_delegations.c index 1a6c9cfd6af..3deb98e6d80 100644 --- a/src/flamenco/stakes/fd_stake_delegations.c +++ b/src/flamenco/stakes/fd_stake_delegations.c @@ -192,6 +192,14 @@ fd_stake_delegations_delete( void * mem ) { return mem; } +void +fd_stake_delegations_init( fd_stake_delegations_t * stake_delegations ) { + fd_stake_delegation_map_t * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations ); + fd_stake_delegation_map_reset( stake_delegation_map ); + fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations ); + fd_stake_delegation_pool_reset( stake_delegation_pool ); +} + void fd_stake_delegations_update( fd_stake_delegations_t * stake_delegations, fd_pubkey_t const * stake_account, diff --git a/src/flamenco/stakes/fd_stake_delegations.h b/src/flamenco/stakes/fd_stake_delegations.h index ffd66ee17ff..d0fe697ccb4 100644 --- a/src/flamenco/stakes/fd_stake_delegations.h +++ b/src/flamenco/stakes/fd_stake_delegations.h @@ -224,6 +224,12 @@ fd_stake_delegations_leave( fd_stake_delegations_t * self ); void * fd_stake_delegations_delete( void * mem ); +/* fd_stake_delegations_init resets the state of a valid join of a + stake delegations struct. */ + +void +fd_stake_delegations_init( fd_stake_delegations_t * stake_delegations ); + /* fd_stake_delegations_update will either insert a new stake delegation if the pubkey doesn't exist yet, or it will update the stake delegation for the pubkey if already in the map, overriding any