Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVM: add new solana-svm-rent-collector crate #2688

Merged
merged 1 commit into from
Aug 23, 2024

Conversation

buffalojoec
Copy link

@buffalojoec buffalojoec commented Aug 21, 2024

Problem

As part of the ongoing effort to evict solana-metrics from the SVM, we've realized that the only way to evict the metrics submission that occurs deep in account rent state management is to factor out all rent management into a plugin trait, similar to TransactionProcessingCallback.

Summary of Changes

As a first step in this process, I've introduced a new crate for SVM rent management - solana-svm-rent-collector. Within this new crate is a trait - SVMRentCollector - that will be used by the SVM (in future PRs) to perform rent management duties, including evaluating account rent state and collecting rent.

Much of the trait is based on the current account_rent_state module in SVM as well as the SDK's RentCollector struct. I've intentionally omitted a few small things (logs and metrics) as well as repurposed method signatures to suit the new trait. I've provided comments for each of these changes.

The new crate also provides an implementation of SVMRentCollector for the SDK's RentCollector struct. Downstream users can simply provide a RentCollector if they do not wish to customize rent behavior, and the SVM can default to RentCollector::default() when no SVMRentCollector implementation is provided.

The idea within Bank would be to create a wrapper struct around RentCollector that will override the methods that require metrics and logging specific to Agave.

This follow-up work will be done in subsequent PRs. Here's a draft of the next one, where I've done the Bank wrapper type: buffalojoec#29.

Comment on lines +56 to +77
/// Check rent state transition for an account directly.
///
/// This method has a default implementation that checks whether the
/// transition is allowed and returns an error if it is not. It also
/// verifies that the account is not the incinerator.
fn check_rent_state_with_account(
&self,
pre_rent_state: &RentState,
post_rent_state: &RentState,
address: &Pubkey,
_account_state: &AccountSharedData,
account_index: IndexOfAccount,
) -> Result<()> {
if !solana_sdk::incinerator::check_id(address)
&& !self.transition_allowed(pre_rent_state, post_rent_state)
{
let account_index = account_index as u8;
Err(TransactionError::InsufficientFundsForRent { account_index })
} else {
Ok(())
}
}
Copy link
Author

@buffalojoec buffalojoec Aug 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I've used the same implementation as the original, but I've omitted the debug! (to avoid a dependency on log) and the metrics submission. The former omission is why _account_state is unused here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the PR description, Bank's wrapper around RentCollector would then override this method to inject debug! and metrics submission.

Comment on lines +82 to +101
/// Determine the rent state of an account.
///
/// This method has a default implementation that treats accounts with zero
/// lamports as uninitialized and uses the implemented `get_rent` to
/// determine whether an account is rent-exempt.
fn get_account_rent_state(&self, account: &AccountSharedData) -> RentState {
if account.lamports() == 0 {
RentState::Uninitialized
} else if self
.get_rent()
.is_exempt(account.lamports(), account.data().len())
{
RentState::RentExempt
} else {
RentState::RentPaying {
data_size: account.data().len(),
lamports: account.lamports(),
}
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've taken the methods from RentState and implemented them on the trait itself to provide more customization.

}
}

#[cfg(test)]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these tests came from SVM's account_rent_state module, but refactored to use the trait methods implemented on RentCollector.

@buffalojoec buffalojoec marked this pull request as ready for review August 21, 2024 20:00
@buffalojoec buffalojoec merged commit d109065 into anza-xyz:master Aug 23, 2024
51 checks passed
ray-kast pushed a commit to abklabs/agave that referenced this pull request Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants