2019-08-23 14:04:53 -07:00
|
|
|
//! calculate and collect rent from Accounts
|
2019-10-08 22:34:26 -07:00
|
|
|
use solana_sdk::{
|
|
|
|
account::Account, clock::Epoch, epoch_schedule::EpochSchedule, rent_calculator::RentCalculator,
|
|
|
|
};
|
2019-08-23 14:04:53 -07:00
|
|
|
|
|
|
|
#[derive(Default, Serialize, Deserialize, Clone)]
|
|
|
|
pub struct RentCollector {
|
|
|
|
pub epoch: Epoch,
|
|
|
|
pub epoch_schedule: EpochSchedule,
|
|
|
|
pub slots_per_year: f64,
|
2019-09-17 04:42:55 -07:00
|
|
|
pub rent_calculator: RentCalculator,
|
2019-08-23 14:04:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl RentCollector {
|
|
|
|
pub fn new(
|
|
|
|
epoch: Epoch,
|
|
|
|
epoch_schedule: &EpochSchedule,
|
|
|
|
slots_per_year: f64,
|
2019-09-17 04:42:55 -07:00
|
|
|
rent_calculator: &RentCalculator,
|
2019-08-23 14:04:53 -07:00
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
epoch,
|
|
|
|
epoch_schedule: *epoch_schedule,
|
|
|
|
slots_per_year,
|
2019-09-17 04:42:55 -07:00
|
|
|
rent_calculator: *rent_calculator,
|
2019-08-23 14:04:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn clone_with_epoch(&self, epoch: Epoch) -> Self {
|
|
|
|
Self {
|
|
|
|
epoch,
|
|
|
|
..self.clone()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// updates this account's lamports and status and returns
|
|
|
|
// the account rent collected, if any
|
|
|
|
//
|
2019-10-15 19:15:47 -07:00
|
|
|
pub fn update(&self, account: &mut Account) -> u64 {
|
2019-08-23 14:04:53 -07:00
|
|
|
if account.data.is_empty() || account.rent_epoch > self.epoch {
|
2019-10-15 19:15:47 -07:00
|
|
|
0
|
2019-08-23 14:04:53 -07:00
|
|
|
} else {
|
|
|
|
let slots_elapsed: u64 = (account.rent_epoch..=self.epoch)
|
|
|
|
.map(|epoch| self.epoch_schedule.get_slots_in_epoch(epoch + 1))
|
|
|
|
.sum();
|
|
|
|
|
2019-09-17 04:42:55 -07:00
|
|
|
let (rent_due, exempt) = self.rent_calculator.due(
|
2019-08-23 14:04:53 -07:00
|
|
|
account.lamports,
|
|
|
|
account.data.len(),
|
|
|
|
slots_elapsed as f64 / self.slots_per_year,
|
|
|
|
);
|
|
|
|
|
|
|
|
if exempt || rent_due != 0 {
|
|
|
|
if account.lamports > rent_due {
|
|
|
|
account.rent_epoch = self.epoch + 1;
|
|
|
|
account.lamports -= rent_due;
|
2019-10-15 19:15:47 -07:00
|
|
|
rent_due
|
2019-08-23 14:04:53 -07:00
|
|
|
} else {
|
2019-10-15 19:15:47 -07:00
|
|
|
let rent_charged = account.lamports;
|
|
|
|
*account = Account::default();
|
|
|
|
rent_charged
|
2019-08-23 14:04:53 -07:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// maybe collect rent later, leave account alone
|
2019-10-15 19:15:47 -07:00
|
|
|
0
|
2019-08-23 14:04:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|