Skip to content

Commit

Permalink
test validator: make feature accounts additive
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Nov 26, 2024
1 parent 6117b48 commit afb1cdf
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 17 deletions.
34 changes: 33 additions & 1 deletion runtime/src/genesis_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ pub fn activate_feature(genesis_config: &mut GenesisConfig, feature_id: Pubkey)
}

#[allow(clippy::too_many_arguments)]
pub fn create_genesis_config_with_leader_ex(
pub fn create_genesis_config_with_leader_ex_no_features(
mint_lamports: u64,
mint_pubkey: &Pubkey,
validator_pubkey: &Pubkey,
Expand Down Expand Up @@ -295,6 +295,38 @@ pub fn create_genesis_config_with_leader_ex(
};

solana_stake_program::add_genesis_accounts(&mut genesis_config);

genesis_config
}

#[allow(clippy::too_many_arguments)]
pub fn create_genesis_config_with_leader_ex(
mint_lamports: u64,
mint_pubkey: &Pubkey,
validator_pubkey: &Pubkey,
validator_vote_account_pubkey: &Pubkey,
validator_stake_account_pubkey: &Pubkey,
validator_stake_lamports: u64,
validator_lamports: u64,
fee_rate_governor: FeeRateGovernor,
rent: Rent,
cluster_type: ClusterType,
initial_accounts: Vec<(Pubkey, AccountSharedData)>,
) -> GenesisConfig {
let mut genesis_config = create_genesis_config_with_leader_ex_no_features(
mint_lamports,
mint_pubkey,
validator_pubkey,
validator_vote_account_pubkey,
validator_stake_account_pubkey,
validator_stake_lamports,
validator_lamports,
fee_rate_governor,
rent,
cluster_type,
initial_accounts,
);

if genesis_config.cluster_type == ClusterType::Development {
activate_all_features(&mut genesis_config);
}
Expand Down
77 changes: 61 additions & 16 deletions test-validator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ use {
solana_rpc_client::{nonblocking, rpc_client::RpcClient},
solana_rpc_client_api::request::MAX_MULTIPLE_ACCOUNTS,
solana_runtime::{
bank_forks::BankForks, genesis_utils::create_genesis_config_with_leader_ex,
runtime_config::RuntimeConfig, snapshot_config::SnapshotConfig,
bank_forks::BankForks,
genesis_utils::{self, create_genesis_config_with_leader_ex_no_features},
runtime_config::RuntimeConfig,
snapshot_config::SnapshotConfig,
},
solana_sdk::{
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
Expand All @@ -44,6 +46,7 @@ use {
commitment_config::CommitmentConfig,
epoch_schedule::EpochSchedule,
exit::Exit,
feature_set::FeatureSet,
fee_calculator::FeeRateGovernor,
instruction::{AccountMeta, Instruction},
message::Message,
Expand Down Expand Up @@ -829,7 +832,7 @@ impl TestValidator {
);
}

let mut genesis_config = create_genesis_config_with_leader_ex(
let mut genesis_config = create_genesis_config_with_leader_ex_no_features(
mint_lamports,
&mint_address,
&validator_identity.pubkey(),
Expand All @@ -852,23 +855,21 @@ impl TestValidator {
genesis_config.ticks_per_slot = ticks_per_slot;
}

// Remove features tagged to deactivate
for deactivate_feature_pk in &config.deactivate_feature_set {
if FEATURE_NAMES.contains_key(deactivate_feature_pk) {
match genesis_config.accounts.remove(deactivate_feature_pk) {
Some(_) => info!("Feature for {:?} deactivated", deactivate_feature_pk),
None => warn!(
"Feature {:?} set for deactivation not found in genesis_config account list, ignored.",
deactivate_feature_pk
),
}
// Only activate features which are not explicitly deactivated.
let mut feature_set = FeatureSet::default().inactive;
for feature in &config.deactivate_feature_set {
if feature_set.remove(feature) {
info!("Feature for {:?} deactivated", feature)
} else {
warn!(
"Feature {:?} set for deactivation is not a known Feature public key",
deactivate_feature_pk
);
feature,
)
}
}
for feature in feature_set {
genesis_utils::activate_feature(&mut genesis_config, feature);
}

let ledger_path = match &config.ledger_path {
None => create_new_tmp_ledger!(&genesis_config).0,
Expand Down Expand Up @@ -1193,7 +1194,7 @@ impl Drop for TestValidator {

#[cfg(test)]
mod test {
use super::*;
use {super::*, solana_sdk::feature::Feature};

#[test]
fn get_health() {
Expand All @@ -1217,4 +1218,48 @@ mod test {
// `start()` blows up when run within tokio
let (_test_validator, _payer) = TestValidatorGenesis::default().start();
}

#[tokio::test]
async fn test_deactivate_features() {
let mut control = FeatureSet::default().inactive;
let mut deactivate_features = Vec::new();
[
solana_sdk::feature_set::deprecate_rewards_sysvar::id(),
solana_sdk::feature_set::disable_fees_sysvar::id(),
]
.into_iter()
.for_each(|feature| {
control.remove(&feature);
deactivate_features.push(feature);
});

// Convert to `Vec` so we can get a slice.
let control: Vec<Pubkey> = control.into_iter().collect();

let (test_validator, _payer) = TestValidatorGenesis::default()
.deactivate_features(&deactivate_features)
.start_async()
.await;

let rpc_client = test_validator.get_async_rpc_client();

// Our deactivated features should be inactive.
let inactive_feature_accounts = rpc_client
.get_multiple_accounts(&deactivate_features)
.await
.unwrap();
for f in inactive_feature_accounts {
assert!(f.is_none());
}

// Everything else should be active.
for chunk in control.chunks(100) {
let active_feature_accounts = rpc_client.get_multiple_accounts(chunk).await.unwrap();
for f in active_feature_accounts {
let account = f.unwrap(); // Should be `Some`.
let feature_state: Feature = bincode::deserialize(account.data()).unwrap();
assert!(feature_state.activated_at.is_some());
}
}
}
}

0 comments on commit afb1cdf

Please sign in to comment.