Track reserved account keys in bank (#769)

This commit is contained in:
Justin Starry 2024-04-13 09:12:00 +08:00 committed by GitHub
parent 45e09396b9
commit cb13b39118
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 0 deletions

View File

@ -142,6 +142,7 @@ use {
rent::RentDue,
rent_collector::{CollectedInfo, RentCollector, RENT_EXEMPT_RENT_EPOCH},
rent_debits::RentDebits,
reserved_account_keys::ReservedAccountKeys,
reward_info::RewardInfo,
saturating_add_assign,
signature::{Keypair, Signature},
@ -563,6 +564,7 @@ impl PartialEq for Bank {
transaction_log_collector_config: _,
transaction_log_collector: _,
feature_set: _,
reserved_account_keys: _,
drop_callback: _,
freeze_started: _,
vote_only_bank: _,
@ -783,6 +785,9 @@ pub struct Bank {
pub feature_set: Arc<FeatureSet>,
/// Set of reserved account keys that cannot be write locked
reserved_account_keys: Arc<ReservedAccountKeys>,
/// callback function only to be called when dropping and should only be called once
pub drop_callback: RwLock<OptionalDropCallback>,
@ -929,6 +934,7 @@ impl Bank {
),
transaction_log_collector: Arc::<RwLock<TransactionLogCollector>>::default(),
feature_set: Arc::<FeatureSet>::default(),
reserved_account_keys: Arc::<ReservedAccountKeys>::default(),
drop_callback: RwLock::new(OptionalDropCallback(None)),
freeze_started: AtomicBool::default(),
vote_only_bank: false,
@ -1179,6 +1185,7 @@ impl Bank {
transaction_log_collector_config,
transaction_log_collector: Arc::new(RwLock::new(TransactionLogCollector::default())),
feature_set: Arc::clone(&feature_set),
reserved_account_keys: parent.reserved_account_keys.clone(),
drop_callback: RwLock::new(OptionalDropCallback(
parent
.drop_callback
@ -1639,6 +1646,7 @@ impl Bank {
),
transaction_log_collector: Arc::<RwLock<TransactionLogCollector>>::default(),
feature_set: Arc::<FeatureSet>::default(),
reserved_account_keys: Arc::<ReservedAccountKeys>::default(),
drop_callback: RwLock::new(OptionalDropCallback(None)),
freeze_started: AtomicBool::new(fields.hash != Hash::default()),
vote_only_bank: false,
@ -6502,6 +6510,12 @@ impl Bank {
}
}
/// Get a set of all actively reserved account keys that are not allowed to
/// be write-locked during transaction processing.
pub fn get_reserved_account_keys(&self) -> &HashSet<Pubkey> {
&self.reserved_account_keys.active
}
// This is called from snapshot restore AND for each epoch boundary
// The entire code path herein must be idempotent
fn apply_feature_activations(
@ -6532,6 +6546,13 @@ impl Bank {
}
}
// Update active set of reserved account keys which are not allowed to be write locked
self.reserved_account_keys = {
let mut reserved_keys = ReservedAccountKeys::clone(&self.reserved_account_keys);
reserved_keys.update_active_set(&self.feature_set);
Arc::new(reserved_keys)
};
if new_feature_activations.contains(&feature_set::pico_inflation::id()) {
*self.inflation.write().unwrap() = Inflation::pico();
self.fee_rate_governor.burn_percent = 50; // 50% fee burn

View File

@ -7952,6 +7952,32 @@ fn test_compute_active_feature_set() {
assert!(feature_set.is_active(&test_feature));
}
#[test]
fn test_reserved_account_keys() {
let bank0 = create_simple_test_arc_bank(100_000).0;
let mut bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1);
bank.feature_set = Arc::new(FeatureSet::default());
assert_eq!(
bank.get_reserved_account_keys().len(),
20,
"before activating the new feature, bank should already have active reserved keys"
);
// Activate `add_new_reserved_account_keys` feature
bank.store_account(
&feature_set::add_new_reserved_account_keys::id(),
&feature::create_account(&Feature::default(), 42),
);
bank.apply_feature_activations(ApplyFeatureActivationsCaller::NewFromParent, true);
assert_eq!(
bank.get_reserved_account_keys().len(),
29,
"after activating the new feature, bank should have new active reserved keys"
);
}
#[test]
fn test_program_replacement() {
let mut bank = create_simple_test_bank(0);

View File

@ -22,6 +22,16 @@ mod zk_token_proof_program {
solana_sdk::declare_id!("ZkTokenProof1111111111111111111111111111111");
}
// ReservedAccountKeys is not serialized into or deserialized from bank
// snapshots but the bank requires this trait to be implemented anyways.
#[cfg(RUSTC_WITH_SPECIALIZATION)]
impl ::solana_frozen_abi::abi_example::AbiExample for ReservedAccountKeys {
fn example() -> Self {
// ReservedAccountKeys is not Serialize so just rely on Default.
ReservedAccountKeys::default()
}
}
/// `ReservedAccountKeys` holds the set of currently active/inactive
/// account keys that are reserved by the protocol and may not be write-locked
/// during transaction processing.