Move slot cleanup to AccountsBackgroundService (#13911)
* Move bank drop to AccountsBackgroundService * Send to ABS on drop instead, protects against other places banks are dropped * Fix Abi * test Co-authored-by: Carl Lin <carl@solana.com>
This commit is contained in:
@@ -699,6 +699,11 @@ impl fmt::Display for RewardType {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DropCallback: fmt::Debug {
|
||||
fn callback(&self, b: &Bank);
|
||||
fn clone_box(&self) -> Box<dyn DropCallback + Send + Sync>;
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, AbiExample, Clone, Copy)]
|
||||
pub struct RewardInfo {
|
||||
pub reward_type: RewardType,
|
||||
@@ -706,6 +711,16 @@ pub struct RewardInfo {
|
||||
pub post_balance: u64, // Account balance in lamports after `lamports` was applied
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct OptionalDropCallback(Option<Box<dyn DropCallback + Send + Sync>>);
|
||||
|
||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||
impl AbiExample for OptionalDropCallback {
|
||||
fn example() -> Self {
|
||||
Self(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Manager for the state of all accounts and programs after processing its entries.
|
||||
/// AbiExample is needed even without Serialize/Deserialize; actual (de-)serialization
|
||||
/// are implemented elsewhere for versioning
|
||||
@@ -849,6 +864,8 @@ pub struct Bank {
|
||||
pub transaction_log_collector: Arc<RwLock<TransactionLogCollector>>,
|
||||
|
||||
pub feature_set: Arc<FeatureSet>,
|
||||
|
||||
pub drop_callback: RwLock<OptionalDropCallback>,
|
||||
}
|
||||
|
||||
impl Default for BlockhashQueue {
|
||||
@@ -995,6 +1012,15 @@ impl Bank {
|
||||
transaction_log_collector_config: parent.transaction_log_collector_config.clone(),
|
||||
transaction_log_collector: Arc::new(RwLock::new(TransactionLogCollector::default())),
|
||||
feature_set: parent.feature_set.clone(),
|
||||
drop_callback: RwLock::new(OptionalDropCallback(
|
||||
parent
|
||||
.drop_callback
|
||||
.read()
|
||||
.unwrap()
|
||||
.0
|
||||
.as_ref()
|
||||
.map(|drop_callback| drop_callback.clone_box()),
|
||||
)),
|
||||
};
|
||||
|
||||
datapoint_info!(
|
||||
@@ -1035,6 +1061,10 @@ impl Bank {
|
||||
new
|
||||
}
|
||||
|
||||
pub fn set_callback(&self, callback: Option<Box<dyn DropCallback + Send + Sync>>) {
|
||||
*self.drop_callback.write().unwrap() = OptionalDropCallback(callback);
|
||||
}
|
||||
|
||||
/// Like `new_from_parent` but additionally:
|
||||
/// * Doesn't assume that the parent is anywhere near `slot`, parent could be millions of slots
|
||||
/// in the past
|
||||
@@ -1113,6 +1143,7 @@ impl Bank {
|
||||
transaction_log_collector_config: new(),
|
||||
transaction_log_collector: new(),
|
||||
feature_set: new(),
|
||||
drop_callback: RwLock::new(OptionalDropCallback(None)),
|
||||
};
|
||||
bank.finish_init(genesis_config, additional_builtins);
|
||||
|
||||
@@ -4615,9 +4646,16 @@ impl Bank {
|
||||
|
||||
impl Drop for Bank {
|
||||
fn drop(&mut self) {
|
||||
// For root slots this is a noop
|
||||
if !self.skip_drop.load(Relaxed) {
|
||||
self.rc.accounts.purge_slot(self.slot());
|
||||
if let Some(drop_callback) = self.drop_callback.read().unwrap().0.as_ref() {
|
||||
drop_callback.callback(self);
|
||||
} else {
|
||||
// Default case
|
||||
// 1. Tests
|
||||
// 2. At startup when replaying blockstore and there's no
|
||||
// AccountsBackgroundService to perform cleanups yet.
|
||||
self.rc.accounts.purge_slot(self.slot());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user