runtime: add rent debit charges to block metadata
This commit is contained in:
parent
e9bc1c6b07
commit
97eab7edf9
@ -5,7 +5,8 @@ use crate::{
|
|||||||
accounts_index::{AccountSecondaryIndexes, IndexKey},
|
accounts_index::{AccountSecondaryIndexes, IndexKey},
|
||||||
ancestors::Ancestors,
|
ancestors::Ancestors,
|
||||||
bank::{
|
bank::{
|
||||||
NonceRollbackFull, NonceRollbackInfo, TransactionCheckResult, TransactionExecutionResult,
|
NonceRollbackFull, NonceRollbackInfo, RentDebits, TransactionCheckResult,
|
||||||
|
TransactionExecutionResult,
|
||||||
},
|
},
|
||||||
blockhash_queue::BlockhashQueue,
|
blockhash_queue::BlockhashQueue,
|
||||||
rent_collector::RentCollector,
|
rent_collector::RentCollector,
|
||||||
@ -99,12 +100,14 @@ pub type TransactionAccounts = Vec<AccountSharedData>;
|
|||||||
pub type TransactionAccountDeps = Vec<(Pubkey, AccountSharedData)>;
|
pub type TransactionAccountDeps = Vec<(Pubkey, AccountSharedData)>;
|
||||||
pub type TransactionRent = u64;
|
pub type TransactionRent = u64;
|
||||||
pub type TransactionLoaders = Vec<Vec<(Pubkey, AccountSharedData)>>;
|
pub type TransactionLoaders = Vec<Vec<(Pubkey, AccountSharedData)>>;
|
||||||
|
pub type TransactionRentDebits = RentDebits;
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
pub struct LoadedTransaction {
|
pub struct LoadedTransaction {
|
||||||
pub accounts: TransactionAccounts,
|
pub accounts: TransactionAccounts,
|
||||||
pub account_deps: TransactionAccountDeps,
|
pub account_deps: TransactionAccountDeps,
|
||||||
pub loaders: TransactionLoaders,
|
pub loaders: TransactionLoaders,
|
||||||
pub rent: TransactionRent,
|
pub rent: TransactionRent,
|
||||||
|
pub rent_debits: TransactionRentDebits,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TransactionLoadResult = (Result<LoadedTransaction>, Option<NonceRollbackFull>);
|
pub type TransactionLoadResult = (Result<LoadedTransaction>, Option<NonceRollbackFull>);
|
||||||
@ -206,6 +209,7 @@ impl Accounts {
|
|||||||
let demote_sysvar_write_locks =
|
let demote_sysvar_write_locks =
|
||||||
feature_set.is_active(&feature_set::demote_sysvar_write_locks::id());
|
feature_set.is_active(&feature_set::demote_sysvar_write_locks::id());
|
||||||
let mut key_check = MessageProgramIdsCache::new(&message);
|
let mut key_check = MessageProgramIdsCache::new(&message);
|
||||||
|
let mut rent_debits = RentDebits::default();
|
||||||
for (i, key) in message.account_keys.iter().enumerate() {
|
for (i, key) in message.account_keys.iter().enumerate() {
|
||||||
let account = if key_check.is_non_loader_key(key, i) {
|
let account = if key_check.is_non_loader_key(key, i) {
|
||||||
if payer_index.is_none() {
|
if payer_index.is_none() {
|
||||||
@ -258,6 +262,8 @@ impl Accounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tx_rent += rent;
|
tx_rent += rent;
|
||||||
|
rent_debits.push(key, rent, account.lamports());
|
||||||
|
|
||||||
account
|
account
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -319,6 +325,7 @@ impl Accounts {
|
|||||||
account_deps,
|
account_deps,
|
||||||
loaders,
|
loaders,
|
||||||
rent: tx_rent,
|
rent: tx_rent,
|
||||||
|
rent_debits,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -995,8 +1002,11 @@ impl Accounts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if account.rent_epoch() == INITIAL_RENT_EPOCH {
|
if account.rent_epoch() == INITIAL_RENT_EPOCH {
|
||||||
loaded_transaction.rent +=
|
let rent = rent_collector.collect_from_created_account(&key, account);
|
||||||
rent_collector.collect_from_created_account(&key, account);
|
loaded_transaction.rent += rent;
|
||||||
|
loaded_transaction
|
||||||
|
.rent_debits
|
||||||
|
.push(key, rent, account.lamports());
|
||||||
}
|
}
|
||||||
accounts.push((key, &*account));
|
accounts.push((key, &*account));
|
||||||
}
|
}
|
||||||
@ -1968,6 +1978,7 @@ mod tests {
|
|||||||
account_deps: vec![],
|
account_deps: vec![],
|
||||||
loaders: transaction_loaders0,
|
loaders: transaction_loaders0,
|
||||||
rent: transaction_rent0,
|
rent: transaction_rent0,
|
||||||
|
rent_debits: RentDebits::default(),
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
@ -1981,6 +1992,7 @@ mod tests {
|
|||||||
account_deps: vec![],
|
account_deps: vec![],
|
||||||
loaders: transaction_loaders1,
|
loaders: transaction_loaders1,
|
||||||
rent: transaction_rent1,
|
rent: transaction_rent1,
|
||||||
|
rent_debits: RentDebits::default(),
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
@ -2363,6 +2375,7 @@ mod tests {
|
|||||||
account_deps: vec![],
|
account_deps: vec![],
|
||||||
loaders: transaction_loaders,
|
loaders: transaction_loaders,
|
||||||
rent: transaction_rent,
|
rent: transaction_rent,
|
||||||
|
rent_debits: RentDebits::default(),
|
||||||
}),
|
}),
|
||||||
nonce_rollback,
|
nonce_rollback,
|
||||||
);
|
);
|
||||||
@ -2481,6 +2494,7 @@ mod tests {
|
|||||||
account_deps: vec![],
|
account_deps: vec![],
|
||||||
loaders: transaction_loaders,
|
loaders: transaction_loaders,
|
||||||
rent: transaction_rent,
|
rent: transaction_rent,
|
||||||
|
rent_debits: RentDebits::default(),
|
||||||
}),
|
}),
|
||||||
nonce_rollback,
|
nonce_rollback,
|
||||||
);
|
);
|
||||||
|
@ -131,6 +131,27 @@ pub const SECONDS_PER_YEAR: f64 = 365.25 * 24.0 * 60.0 * 60.0;
|
|||||||
|
|
||||||
pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5;
|
pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
|
pub struct RentDebits(pub Vec<(Pubkey, RewardInfo)>);
|
||||||
|
|
||||||
|
impl RentDebits {
|
||||||
|
pub fn push(&mut self, account: &Pubkey, rent: u64, post_balance: u64) {
|
||||||
|
if rent != 0 {
|
||||||
|
let rent_debit = i64::try_from(rent).ok().and_then(|r| r.checked_neg());
|
||||||
|
if let Some(rent_debit) = rent_debit {
|
||||||
|
let reward_info = RewardInfo {
|
||||||
|
reward_type: RewardType::Rent,
|
||||||
|
lamports: rent_debit,
|
||||||
|
post_balance,
|
||||||
|
};
|
||||||
|
self.0.push((*account, reward_info));
|
||||||
|
} else {
|
||||||
|
warn!("out of range rent debit from {}: {}", account, rent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct ExecuteTimings {
|
pub struct ExecuteTimings {
|
||||||
pub check_us: u64,
|
pub check_us: u64,
|
||||||
@ -3547,18 +3568,22 @@ impl Bank {
|
|||||||
fn collect_rent(
|
fn collect_rent(
|
||||||
&self,
|
&self,
|
||||||
res: &[TransactionExecutionResult],
|
res: &[TransactionExecutionResult],
|
||||||
loaded_accounts: &[TransactionLoadResult],
|
loaded_accounts: &mut [TransactionLoadResult],
|
||||||
) {
|
) {
|
||||||
let mut collected_rent: u64 = 0;
|
let mut collected_rent: u64 = 0;
|
||||||
for (i, (raccs, _nonce_rollback)) in loaded_accounts.iter().enumerate() {
|
for (i, (raccs, _nonce_rollback)) in loaded_accounts.iter_mut().enumerate() {
|
||||||
let (res, _nonce_rollback) = &res[i];
|
let (res, _nonce_rollback) = &res[i];
|
||||||
if res.is_err() || raccs.is_err() {
|
if res.is_err() || raccs.is_err() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let loaded_transaction = raccs.as_ref().unwrap();
|
let loaded_transaction = raccs.as_mut().unwrap();
|
||||||
|
|
||||||
collected_rent += loaded_transaction.rent;
|
collected_rent += loaded_transaction.rent;
|
||||||
|
self.rewards
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.append(&mut loaded_transaction.rent_debits.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.collected_rent.fetch_add(collected_rent, Relaxed);
|
self.collected_rent.fetch_add(collected_rent, Relaxed);
|
||||||
@ -3630,19 +3655,23 @@ impl Bank {
|
|||||||
let account_count = accounts.len();
|
let account_count = accounts.len();
|
||||||
|
|
||||||
// parallelize?
|
// parallelize?
|
||||||
let mut rent = 0;
|
let mut total_rent = 0;
|
||||||
|
let mut rent_debits = RentDebits::default();
|
||||||
for (pubkey, mut account) in accounts {
|
for (pubkey, mut account) in accounts {
|
||||||
rent += self
|
let rent = self
|
||||||
.rent_collector
|
.rent_collector
|
||||||
.collect_from_existing_account(&pubkey, &mut account);
|
.collect_from_existing_account(&pubkey, &mut account);
|
||||||
|
total_rent += rent;
|
||||||
// Store all of them unconditionally to purge old AppendVec,
|
// Store all of them unconditionally to purge old AppendVec,
|
||||||
// even if collected rent is 0 (= not updated).
|
// even if collected rent is 0 (= not updated).
|
||||||
// Also, there's another subtle side-effect from this: this
|
// Also, there's another subtle side-effect from this: this
|
||||||
// ensures we verify the whole on-chain state (= all accounts)
|
// ensures we verify the whole on-chain state (= all accounts)
|
||||||
// via the account delta hash slowly once per an epoch.
|
// via the account delta hash slowly once per an epoch.
|
||||||
self.store_account(&pubkey, &account);
|
self.store_account(&pubkey, &account);
|
||||||
|
rent_debits.push(&pubkey, rent, account.lamports());
|
||||||
}
|
}
|
||||||
self.collected_rent.fetch_add(rent, Relaxed);
|
self.collected_rent.fetch_add(total_rent, Relaxed);
|
||||||
|
self.rewards.write().unwrap().append(&mut rent_debits.0);
|
||||||
|
|
||||||
datapoint_info!("collect_rent_eagerly", ("accounts", account_count, i64));
|
datapoint_info!("collect_rent_eagerly", ("accounts", account_count, i64));
|
||||||
}
|
}
|
||||||
@ -6093,13 +6122,17 @@ pub(crate) mod tests {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(address, reward)| {
|
.map(|(address, reward)| {
|
||||||
assert_eq!(reward.reward_type, RewardType::Rent);
|
if reward.lamports > 0 {
|
||||||
if *address == validator_2_pubkey {
|
assert_eq!(reward.reward_type, RewardType::Rent);
|
||||||
assert_eq!(reward.post_balance, validator_2_portion + 42 - tweak_2);
|
if *address == validator_2_pubkey {
|
||||||
} else if *address == validator_3_pubkey {
|
assert_eq!(reward.post_balance, validator_2_portion + 42 - tweak_2);
|
||||||
assert_eq!(reward.post_balance, validator_3_portion + 42);
|
} else if *address == validator_3_pubkey {
|
||||||
|
assert_eq!(reward.post_balance, validator_3_portion + 42);
|
||||||
|
}
|
||||||
|
reward.lamports as u64
|
||||||
|
} else {
|
||||||
|
0
|
||||||
}
|
}
|
||||||
reward.lamports as u64
|
|
||||||
})
|
})
|
||||||
.sum::<u64>()
|
.sum::<u64>()
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user