Skip to content

Commit

Permalink
Runtime: add RentCollectorWithMetrics wrapper type for SVM
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Aug 21, 2024
1 parent 2db9bb5 commit e432739
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ solana-runtime-transaction = { workspace = true }
solana-sdk = { workspace = true }
solana-stake-program = { workspace = true }
solana-svm = { workspace = true }
solana-svm-rent-collector = { workspace = true }
solana-svm-transaction = { workspace = true }
solana-system-program = { workspace = true }
solana-timings = { workspace = true }
Expand Down
5 changes: 5 additions & 0 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use {
bank_forks::BankForks,
epoch_stakes::{split_epoch_stakes, EpochStakes, NodeVoteAccounts, VersionedEpochStakes},
installed_scheduler_pool::{BankWithScheduler, InstalledSchedulerRwLock},
rent_collector::RentCollectorWithMetrics,
runtime_config::RuntimeConfig,
serde_snapshot::BankIncrementalSnapshotPersistence,
snapshot_hash::SnapshotHash,
Expand Down Expand Up @@ -3470,6 +3471,10 @@ impl Bank {
timings.saturating_add_in_place(ExecuteTimingType::CheckUs, check_us);

let (blockhash, lamports_per_signature) = self.last_blockhash_and_lamports_per_signature();
// TODO: Pass into `TransactionProcessingEnvironment` in place of
// `rent_collector` when SVM supports the new `SVMRentCollector` trait.
let _rent_collector_with_metrics =
RentCollectorWithMetrics::new(self.rent_collector.clone());
let processing_environment = TransactionProcessingEnvironment {
blockhash,
epoch_total_stake: self.epoch_total_stake(self.epoch()),
Expand Down
1 change: 1 addition & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod loader_utils;
pub mod non_circulating_supply;
pub mod prioritization_fee;
pub mod prioritization_fee_cache;
pub mod rent_collector;
pub mod root_bank_cache;
pub mod serde_snapshot;
pub mod snapshot_archive_info;
Expand Down
90 changes: 90 additions & 0 deletions runtime/src/rent_collector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//! Bank's wrapper around `RentCollector` to allow for overriding of some
//! `SVMRentCollector` trait methods, which are otherwise implemented on
//! `RentCollector` directly.
//!
//! Agave requires submission of logs and metrics during account rent state
//! assessment, which is not included in the `RentCollector` implementation
//! of the `SVMRentCollector` trait. This wrapper allows all `SVMRentCollector`
//! methods to be passed through to the underlying `RentCollector`, except for
//! those which require additional logging and metrics.
use {
log::*,
solana_sdk::{
account::AccountSharedData,
clock::Epoch,
pubkey::Pubkey,
rent::{Rent, RentDue},
rent_collector::{CollectedInfo, RentCollector},
transaction::{Result, TransactionError},
transaction_context::IndexOfAccount,
},
solana_svm_rent_collector::{rent_state::RentState, svm_rent_collector::SVMRentCollector},
};

/// Wrapper around `RentCollector` to allow for overriding of some
/// `SVMRentCollector` trait methods, which are otherwise implemented on
/// `RentCollector` directly.
///
/// Overrides inject logging and metrics submission into the rent state
/// assessment process.
pub struct RentCollectorWithMetrics(RentCollector);

impl RentCollectorWithMetrics {
pub fn new(rent_collector: RentCollector) -> Self {
Self(rent_collector)
}
}

impl SVMRentCollector for RentCollectorWithMetrics {
fn collect_rent(&self, address: &Pubkey, account: &mut AccountSharedData) -> CollectedInfo {
self.0.collect_rent(address, account)
}

fn get_rent(&self) -> &Rent {
self.0.get_rent()
}

fn get_rent_due(&self, lamports: u64, data_len: usize, account_rent_epoch: Epoch) -> RentDue {
self.0.get_rent_due(lamports, data_len, account_rent_epoch)
}

// Overriden to inject logging and metrics.
fn check_rent_state_with_account(
&self,
pre_rent_state: &RentState,
post_rent_state: &RentState,
address: &Pubkey,
account_state: &AccountSharedData,
account_index: IndexOfAccount,
) -> Result<()> {
submit_rent_state_metrics(pre_rent_state, post_rent_state);
if !solana_sdk::incinerator::check_id(address)
&& !self.transition_allowed(pre_rent_state, post_rent_state)
{
debug!(
"Account {} not rent exempt, state {:?}",
address, account_state,
);
let account_index = account_index as u8;
Err(TransactionError::InsufficientFundsForRent { account_index })
} else {
Ok(())
}
}
}

fn submit_rent_state_metrics(pre_rent_state: &RentState, post_rent_state: &RentState) {
match (pre_rent_state, post_rent_state) {
(&RentState::Uninitialized, &RentState::RentPaying { .. }) => {
inc_new_counter_info!("rent_paying_err-new_account", 1);
}
(&RentState::RentPaying { .. }, &RentState::RentPaying { .. }) => {
inc_new_counter_info!("rent_paying_ok-legacy", 1);
}
(_, &RentState::RentPaying { .. }) => {
inc_new_counter_info!("rent_paying_err-other", 1);
}
_ => {}
}
}

0 comments on commit e432739

Please sign in to comment.