-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Populate partitioned-rewards PDA during calculation #34624
Populate partitioned-rewards PDA during calculation #34624
Conversation
ce4421f
to
2c9db16
Compare
fcfd1de
to
ae79075
Compare
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #34624 +/- ##
========================================
Coverage 81.7% 81.8%
========================================
Files 823 824 +1
Lines 222865 223077 +212
========================================
+ Hits 182279 182506 +227
+ Misses 40586 40571 -15 |
ae79075
to
5881f7b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mostly lgtm. one nit, one q
runtime/src/bank.rs
Outdated
@@ -3579,6 +3594,30 @@ impl Bank { | |||
self.log_epoch_rewards_sysvar("update"); | |||
} | |||
|
|||
/// Create the persistent PDA containing the epoch-rewards data | |||
fn create_epoch_rewards_partition_list_account( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn create_epoch_rewards_partition_list_account( | |
fn create_epoch_rewards_partition_metadata_account( |
or
fn create_epoch_rewards_partition_list_account( | |
fn create_epoch_rewards_partition_receipt_account( |
we kinda rugged the name dropping the commitment list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, sorry! I thought I fixed all of these. Maybe I rebased badly the last time. Fix pushed.
&solana_sdk::stake::program::id(), | ||
) | ||
.unwrap(); | ||
self.store_account_and_update_capitalization(&address, &new_account); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does this work if an account already exists at the given address? like some smart ass sends it some sol in advance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the method:
Lines 6497 to 6581 in 22fcffe
fn store_account_and_update_capitalization( | |
&self, | |
pubkey: &Pubkey, | |
new_account: &AccountSharedData, | |
) { | |
let old_account_data_size = | |
if let Some(old_account) = self.get_account_with_fixed_root(pubkey) { | |
match new_account.lamports().cmp(&old_account.lamports()) { | |
std::cmp::Ordering::Greater => { | |
let increased = new_account.lamports() - old_account.lamports(); | |
trace!( | |
"store_account_and_update_capitalization: increased: {} {}", | |
pubkey, | |
increased | |
); | |
self.capitalization.fetch_add(increased, Relaxed); | |
} | |
std::cmp::Ordering::Less => { | |
let decreased = old_account.lamports() - new_account.lamports(); | |
trace!( | |
"store_account_and_update_capitalization: decreased: {} {}", | |
pubkey, | |
decreased | |
); | |
self.capitalization.fetch_sub(decreased, Relaxed); | |
} | |
std::cmp::Ordering::Equal => {} | |
} | |
old_account.data().len() | |
} else { | |
trace!( | |
"store_account_and_update_capitalization: created: {} {}", | |
pubkey, | |
new_account.lamports() | |
); | |
self.capitalization | |
.fetch_add(new_account.lamports(), Relaxed); | |
0 | |
}; | |
self.store_account(pubkey, new_account); | |
self.calculate_and_update_accounts_data_size_delta_off_chain( | |
old_account_data_size, | |
new_account.data().len(), | |
); | |
} | |
fn withdraw(&self, pubkey: &Pubkey, lamports: u64) -> Result<()> { | |
match self.get_account_with_fixed_root(pubkey) { | |
Some(mut account) => { | |
let min_balance = match get_system_account_kind(&account) { | |
Some(SystemAccountKind::Nonce) => self | |
.rent_collector | |
.rent | |
.minimum_balance(nonce::State::size()), | |
_ => 0, | |
}; | |
lamports | |
.checked_add(min_balance) | |
.filter(|required_balance| *required_balance <= account.lamports()) | |
.ok_or(TransactionError::InsufficientFundsForFee)?; | |
account | |
.checked_sub_lamports(lamports) | |
.map_err(|_| TransactionError::InsufficientFundsForFee)?; | |
self.store_account(pubkey, &account); | |
Ok(()) | |
} | |
None => Err(TransactionError::AccountNotFound), | |
} | |
} | |
pub fn accounts(&self) -> Arc<Accounts> { | |
self.rc.accounts.clone() | |
} | |
fn finish_init( | |
&mut self, | |
genesis_config: &GenesisConfig, | |
additional_builtins: Option<&[BuiltinPrototype]>, | |
debug_do_not_add_builtins: bool, | |
) { | |
self.rewards_pool_pubkeys = | |
Arc::new(genesis_config.rewards_pools.keys().cloned().collect()); |
If there are more lamports than needed in the existing account, the excess are burned. If less, they are created/supplemented to the new account balance.
It's the same thing other sysvars use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CriesofCarrots can you write up a SIMD so that the firedancer team is aware of this runtime change? |
Thank you for the nudge! Yes, I will. |
…abs#34624)" This reverts commit 4385ed1.
This reverts commit 4385ed1.
Problem
When the partitioned rewards feature is activated, the only way to find the rewards for a specific address will be to iterate through blocks at the beginning of each epoch. This is because we do not persist information about how the rewards were partitioned; in fact, we don't even persist how many blocks the rewards distribution spans, so there is no way to predict how long it will take to find an address. This is not reasonable for stake-account users.
Summary of Changes
When partitioned rewards are calculated, populate a PDA (address seeded by the epoch number) that stores the partition data needed to create an
EpochRewardsHasher
to performantly identify which partition a particular stake address' distribution is in: number of partitions, parent bank's hash, and the hasher kind.