rent_collector.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //! Bank's wrapper around `RentCollector` to allow for overriding of some
  2. //! `SVMRentCollector` trait methods, which are otherwise implemented on
  3. //! `RentCollector` directly.
  4. //!
  5. //! Agave requires submission of logs and metrics during account rent state
  6. //! assessment, which is not included in the `RentCollector` implementation
  7. //! of the `SVMRentCollector` trait. This wrapper allows all `SVMRentCollector`
  8. //! methods to be passed through to the underlying `RentCollector`, except for
  9. //! those which require additional logging and metrics.
  10. use {
  11. log::*,
  12. solana_account::AccountSharedData,
  13. solana_clock::Epoch,
  14. solana_pubkey::Pubkey,
  15. solana_rent::{Rent, RentDue},
  16. solana_rent_collector::RentCollector,
  17. solana_svm_rent_collector::{rent_state::RentState, svm_rent_collector::SVMRentCollector},
  18. solana_transaction_context::IndexOfAccount,
  19. solana_transaction_error::{TransactionError, TransactionResult as Result},
  20. };
  21. /// Wrapper around `RentCollector` to allow for overriding of some
  22. /// `SVMRentCollector` trait methods, which are otherwise implemented on
  23. /// `RentCollector` directly.
  24. ///
  25. /// Overrides inject logging and metrics submission into the rent state
  26. /// assessment process.
  27. pub struct RentCollectorWithMetrics(RentCollector);
  28. impl RentCollectorWithMetrics {
  29. pub fn new(rent_collector: RentCollector) -> Self {
  30. Self(rent_collector)
  31. }
  32. }
  33. impl SVMRentCollector for RentCollectorWithMetrics {
  34. fn get_rent(&self) -> &Rent {
  35. self.0.get_rent()
  36. }
  37. fn get_rent_due(&self, lamports: u64, data_len: usize, account_rent_epoch: Epoch) -> RentDue {
  38. self.0.get_rent_due(lamports, data_len, account_rent_epoch)
  39. }
  40. // Overriden to inject logging and metrics.
  41. fn check_rent_state_with_account(
  42. &self,
  43. pre_rent_state: &RentState,
  44. post_rent_state: &RentState,
  45. address: &Pubkey,
  46. account_state: &AccountSharedData,
  47. account_index: IndexOfAccount,
  48. ) -> Result<()> {
  49. submit_rent_state_metrics(pre_rent_state, post_rent_state);
  50. if !solana_sdk_ids::incinerator::check_id(address)
  51. && !self.transition_allowed(pre_rent_state, post_rent_state)
  52. {
  53. debug!(
  54. "Account {} not rent exempt, state {:?}",
  55. address, account_state,
  56. );
  57. let account_index = account_index as u8;
  58. Err(TransactionError::InsufficientFundsForRent { account_index })
  59. } else {
  60. Ok(())
  61. }
  62. }
  63. }
  64. fn submit_rent_state_metrics(pre_rent_state: &RentState, post_rent_state: &RentState) {
  65. match (pre_rent_state, post_rent_state) {
  66. (&RentState::Uninitialized, &RentState::RentPaying { .. }) => {
  67. inc_new_counter_info!("rent_paying_err-new_account", 1);
  68. }
  69. (&RentState::RentPaying { .. }, &RentState::RentPaying { .. }) => {
  70. inc_new_counter_info!("rent_paying_ok-legacy", 1);
  71. }
  72. (_, &RentState::RentPaying { .. }) => {
  73. inc_new_counter_info!("rent_paying_err-other", 1);
  74. }
  75. _ => {}
  76. }
  77. }