Problem Slot status can be used of in other scenarios in addition to account information such as transactions, blocks. The current implementation is too tightly coupled. Summary of Changes Decouple the slot status notification from accounts notification. Created a new slot status notification module.
181 lines
6.2 KiB
Rust
181 lines
6.2 KiB
Rust
/// Module responsible for notifying plugins of account updates
|
|
use {
|
|
crate::accountsdb_plugin_manager::AccountsDbPluginManager,
|
|
log::*,
|
|
solana_accountsdb_plugin_interface::accountsdb_plugin_interface::{
|
|
ReplicaAccountInfo, ReplicaAccountInfoVersions,
|
|
},
|
|
solana_measure::measure::Measure,
|
|
solana_metrics::*,
|
|
solana_runtime::{
|
|
accounts_update_notifier_interface::AccountsUpdateNotifierInterface,
|
|
append_vec::{StoredAccountMeta, StoredMeta},
|
|
},
|
|
solana_sdk::{
|
|
account::{AccountSharedData, ReadableAccount},
|
|
clock::Slot,
|
|
},
|
|
std::sync::{Arc, RwLock},
|
|
};
|
|
#[derive(Debug)]
|
|
pub(crate) struct AccountsUpdateNotifierImpl {
|
|
plugin_manager: Arc<RwLock<AccountsDbPluginManager>>,
|
|
}
|
|
|
|
impl AccountsUpdateNotifierInterface for AccountsUpdateNotifierImpl {
|
|
fn notify_account_update(&self, slot: Slot, meta: &StoredMeta, account: &AccountSharedData) {
|
|
if let Some(account_info) = self.accountinfo_from_shared_account_data(meta, account) {
|
|
self.notify_plugins_of_account_update(account_info, slot, false);
|
|
}
|
|
}
|
|
|
|
fn notify_account_restore_from_snapshot(&self, slot: Slot, account: &StoredAccountMeta) {
|
|
let mut measure_all = Measure::start("accountsdb-plugin-notify-account-restore-all");
|
|
let mut measure_copy = Measure::start("accountsdb-plugin-copy-stored-account-info");
|
|
|
|
let account = self.accountinfo_from_stored_account_meta(account);
|
|
measure_copy.stop();
|
|
|
|
inc_new_counter_debug!(
|
|
"accountsdb-plugin-copy-stored-account-info-us",
|
|
measure_copy.as_us() as usize,
|
|
100000,
|
|
100000
|
|
);
|
|
|
|
if let Some(account_info) = account {
|
|
self.notify_plugins_of_account_update(account_info, slot, true);
|
|
}
|
|
measure_all.stop();
|
|
|
|
inc_new_counter_debug!(
|
|
"accountsdb-plugin-notify-account-restore-all-us",
|
|
measure_all.as_us() as usize,
|
|
100000,
|
|
100000
|
|
);
|
|
}
|
|
|
|
fn notify_end_of_restore_from_snapshot(&self) {
|
|
let mut plugin_manager = self.plugin_manager.write().unwrap();
|
|
if plugin_manager.plugins.is_empty() {
|
|
return;
|
|
}
|
|
|
|
for plugin in plugin_manager.plugins.iter_mut() {
|
|
let mut measure = Measure::start("accountsdb-plugin-end-of-restore-from-snapshot");
|
|
match plugin.notify_end_of_startup() {
|
|
Err(err) => {
|
|
error!(
|
|
"Failed to notify the end of restore from snapshot, error: {} to plugin {}",
|
|
err,
|
|
plugin.name()
|
|
)
|
|
}
|
|
Ok(_) => {
|
|
trace!(
|
|
"Successfully notified the end of restore from snapshot to plugin {}",
|
|
plugin.name()
|
|
);
|
|
}
|
|
}
|
|
measure.stop();
|
|
inc_new_counter_debug!(
|
|
"accountsdb-plugin-end-of-restore-from-snapshot",
|
|
measure.as_us() as usize
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AccountsUpdateNotifierImpl {
|
|
pub fn new(plugin_manager: Arc<RwLock<AccountsDbPluginManager>>) -> Self {
|
|
AccountsUpdateNotifierImpl { plugin_manager }
|
|
}
|
|
|
|
fn accountinfo_from_shared_account_data<'a>(
|
|
&self,
|
|
meta: &'a StoredMeta,
|
|
account: &'a AccountSharedData,
|
|
) -> Option<ReplicaAccountInfo<'a>> {
|
|
Some(ReplicaAccountInfo {
|
|
pubkey: meta.pubkey.as_ref(),
|
|
lamports: account.lamports(),
|
|
owner: account.owner().as_ref(),
|
|
executable: account.executable(),
|
|
rent_epoch: account.rent_epoch(),
|
|
data: account.data(),
|
|
write_version: meta.write_version,
|
|
})
|
|
}
|
|
|
|
fn accountinfo_from_stored_account_meta<'a>(
|
|
&self,
|
|
stored_account_meta: &'a StoredAccountMeta,
|
|
) -> Option<ReplicaAccountInfo<'a>> {
|
|
Some(ReplicaAccountInfo {
|
|
pubkey: stored_account_meta.meta.pubkey.as_ref(),
|
|
lamports: stored_account_meta.account_meta.lamports,
|
|
owner: stored_account_meta.account_meta.owner.as_ref(),
|
|
executable: stored_account_meta.account_meta.executable,
|
|
rent_epoch: stored_account_meta.account_meta.rent_epoch,
|
|
data: stored_account_meta.data,
|
|
write_version: stored_account_meta.meta.write_version,
|
|
})
|
|
}
|
|
|
|
fn notify_plugins_of_account_update(
|
|
&self,
|
|
account: ReplicaAccountInfo,
|
|
slot: Slot,
|
|
is_startup: bool,
|
|
) {
|
|
let mut measure2 = Measure::start("accountsdb-plugin-notify_plugins_of_account_update");
|
|
let mut plugin_manager = self.plugin_manager.write().unwrap();
|
|
|
|
if plugin_manager.plugins.is_empty() {
|
|
return;
|
|
}
|
|
for plugin in plugin_manager.plugins.iter_mut() {
|
|
let mut measure = Measure::start("accountsdb-plugin-update-account");
|
|
match plugin.update_account(
|
|
ReplicaAccountInfoVersions::V0_0_1(&account),
|
|
slot,
|
|
is_startup,
|
|
) {
|
|
Err(err) => {
|
|
error!(
|
|
"Failed to update account {} at slot {}, error: {} to plugin {}",
|
|
bs58::encode(account.pubkey).into_string(),
|
|
slot,
|
|
err,
|
|
plugin.name()
|
|
)
|
|
}
|
|
Ok(_) => {
|
|
trace!(
|
|
"Successfully updated account {} at slot {} to plugin {}",
|
|
bs58::encode(account.pubkey).into_string(),
|
|
slot,
|
|
plugin.name()
|
|
);
|
|
}
|
|
}
|
|
measure.stop();
|
|
inc_new_counter_debug!(
|
|
"accountsdb-plugin-update-account-us",
|
|
measure.as_us() as usize,
|
|
100000,
|
|
100000
|
|
);
|
|
}
|
|
measure2.stop();
|
|
inc_new_counter_debug!(
|
|
"accountsdb-plugin-notify_plugins_of_account_update-us",
|
|
measure2.as_us() as usize,
|
|
100000,
|
|
100000
|
|
);
|
|
}
|
|
}
|