solana_rent_debits/
lib.rs

1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2use {
3    solana_pubkey::Pubkey,
4    solana_reward_info::{RewardInfo, RewardType},
5    std::collections::HashMap,
6};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct RentDebit {
10    rent_collected: u64,
11    post_balance: u64,
12}
13
14impl RentDebit {
15    fn try_into_reward_info(self) -> Option<RewardInfo> {
16        let rent_debit = i64::try_from(self.rent_collected)
17            .ok()
18            .and_then(|r| r.checked_neg());
19        rent_debit.map(|rent_debit| RewardInfo {
20            reward_type: RewardType::Rent,
21            lamports: rent_debit,
22            post_balance: self.post_balance,
23            commission: None, // Not applicable
24        })
25    }
26}
27
28#[derive(Clone, Debug, Default, PartialEq, Eq)]
29pub struct RentDebits(HashMap<Pubkey, RentDebit>);
30impl RentDebits {
31    pub fn get_account_rent_debit(&self, address: &Pubkey) -> u64 {
32        self.0
33            .get(address)
34            .map(|r| r.rent_collected)
35            .unwrap_or_default()
36    }
37
38    // These functions/fields are only usable from a dev context (i.e. tests and benches)
39    #[cfg(feature = "dev-context-only-utils")]
40    pub fn len(&self) -> usize {
41        self.0.len()
42    }
43
44    #[cfg(feature = "dev-context-only-utils")]
45    pub fn is_empty(&self) -> bool {
46        self.0.is_empty()
47    }
48
49    pub fn insert(&mut self, address: &Pubkey, rent_collected: u64, post_balance: u64) {
50        if rent_collected != 0 {
51            self.0.insert(
52                *address,
53                RentDebit {
54                    rent_collected,
55                    post_balance,
56                },
57            );
58        }
59    }
60
61    pub fn into_unordered_rewards_iter(self) -> impl Iterator<Item = (Pubkey, RewardInfo)> {
62        self.0
63            .into_iter()
64            .filter_map(|(address, rent_debit)| Some((address, rent_debit.try_into_reward_info()?)))
65    }
66}