Track reserved account keys in bank (#769)
This commit is contained in:
parent
45e09396b9
commit
cb13b39118
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue