diff --git a/core/src/test_validator.rs b/core/src/test_validator.rs index a2fa2beea8..560dd67566 100644 --- a/core/src/test_validator.rs +++ b/core/src/test_validator.rs @@ -16,6 +16,7 @@ use { account::{Account, AccountSharedData}, clock::{Slot, DEFAULT_MS_PER_SLOT}, commitment_config::CommitmentConfig, + epoch_schedule::EpochSchedule, fee_calculator::{FeeCalculator, FeeRateGovernor}, hash::Hash, native_token::sol_to_lamports, @@ -52,6 +53,7 @@ pub struct TestValidatorGenesis { no_bpf_jit: bool, accounts: HashMap, programs: Vec, + epoch_schedule: Option, pub validator_exit: Arc>, pub start_progress: Arc>, } @@ -72,6 +74,11 @@ impl TestValidatorGenesis { self } + pub fn epoch_schedule(&mut self, epoch_schedule: EpochSchedule) -> &mut Self { + self.epoch_schedule = Some(epoch_schedule); + self + } + pub fn rent(&mut self, rent: Rent) -> &mut Self { self.rent = rent; self @@ -313,7 +320,9 @@ impl TestValidator { solana_sdk::genesis_config::ClusterType::Development, accounts.into_iter().collect(), ); - genesis_config.epoch_schedule = solana_sdk::epoch_schedule::EpochSchedule::without_warmup(); + genesis_config.epoch_schedule = config + .epoch_schedule + .unwrap_or_else(EpochSchedule::without_warmup); let ledger_path = match &config.ledger_path { None => create_new_tmp_ledger!(&genesis_config).0, diff --git a/validator/src/bin/solana-test-validator.rs b/validator/src/bin/solana-test-validator.rs index 74aa299c2f..fd2e3fec9f 100644 --- a/validator/src/bin/solana-test-validator.rs +++ b/validator/src/bin/solana-test-validator.rs @@ -14,6 +14,7 @@ use { solana_sdk::{ account::AccountSharedData, clock::Slot, + epoch_schedule::EpochSchedule, native_token::sol_to_lamports, pubkey::Pubkey, rpc_port, @@ -146,6 +147,17 @@ fn main() { .takes_value(false) .help("Disable the just-in-time compiler and instead use the interpreter for BPF"), ) + .arg( + Arg::with_name("slots_per_epoch") + .long("slots-per-epoch") + .value_name("SLOTS") + .validator(is_slot) + .takes_value(true) + .help( + "Override the number of slots in an epoch. \ + If the ledger already exists then this parameter is silently ignored", + ), + ) .arg( Arg::with_name("clone_account") .long("clone") @@ -205,6 +217,7 @@ fn main() { Output::Dashboard }; let rpc_port = value_t_or_exit!(matches, "rpc_port", u16); + let slots_per_epoch = value_t!(matches, "slots_per_epoch", Slot).ok(); let faucet_addr = Some(SocketAddr::new( IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), @@ -359,6 +372,7 @@ fn main() { ("bpf_program", "--bpf-program"), ("clone_account", "--clone"), ("mint_address", "--mint"), + ("slots_per_epoch", "--slots-per-epoch"), ] { if matches.is_present(name) { println!("{} argument ignored, ledger already exists", long); @@ -422,6 +436,14 @@ fn main() { genesis.warp_slot(warp_slot); } + if let Some(slots_per_epoch) = slots_per_epoch { + genesis.epoch_schedule(EpochSchedule::custom( + slots_per_epoch, + slots_per_epoch, + /* enable_warmup_epochs = */ false, + )); + } + match genesis.start_with_mint_address(mint_address) { Ok(test_validator) => { if let Some(dashboard) = dashboard {