diff --git a/crates/core/src/surfnet/locker.rs b/crates/core/src/surfnet/locker.rs index a223b24a..138631c0 100644 --- a/crates/core/src/surfnet/locker.rs +++ b/crates/core/src/surfnet/locker.rs @@ -34,6 +34,7 @@ use solana_client::{ use solana_clock::{Clock, Slot, UnixTimestamp}; use solana_commitment_config::{CommitmentConfig, CommitmentLevel}; use solana_epoch_info::EpochInfo; +use solana_epoch_schedule::EpochSchedule; use solana_hash::Hash; use solana_loader_v3_interface::{get_program_data_address, state::UpgradeableLoaderState}; use solana_message::{ @@ -215,23 +216,30 @@ impl SurfnetSvmLocker { do_profile_instructions: bool, log_bytes_limit: Option, ) -> SurfpoolResult { - let mut epoch_info = if let Some(remote_client) = remote_ctx { - remote_client.get_epoch_info().await? + let (mut epoch_info, epoch_schedule) = if let Some(remote_client) = remote_ctx { + let epoch_info = remote_client.get_epoch_info().await?; + let epoch_schedule = remote_client.get_epoch_schedule().await?; + (epoch_info, epoch_schedule) } else { - EpochInfo { - epoch: 0, - slot_index: 0, - slots_in_epoch: SLOTS_PER_EPOCH, - absolute_slot: FINALIZATION_SLOT_THRESHOLD, - block_height: FINALIZATION_SLOT_THRESHOLD, - transaction_count: None, - } + let epoch_schedule = EpochSchedule::without_warmup(); + ( + EpochInfo { + epoch: 0, + slot_index: 0, + slots_in_epoch: epoch_schedule.slots_per_epoch, + absolute_slot: FINALIZATION_SLOT_THRESHOLD, + block_height: FINALIZATION_SLOT_THRESHOLD, + transaction_count: None, + }, + epoch_schedule, + ) }; epoch_info.transaction_count = None; self.with_svm_writer(|svm_writer| { svm_writer.initialize( epoch_info.clone(), + epoch_schedule.clone(), slot_time, remote_ctx, do_profile_instructions, @@ -3776,6 +3784,7 @@ mod tests { use solana_account::Account; use solana_account_decoder::UiAccountEncoding; + use solana_epoch_schedule::EpochSchedule; use solana_transaction_status::TransactionStatusMeta; use super::*; @@ -4836,4 +4845,28 @@ mod tests { assert!(sigs.contains(&sig_a.to_string())); assert!(sigs.contains(&sig_b.to_string())); } + + #[tokio::test(flavor = "multi_thread")] + async fn initializes_epoch_schedule_without_warmup_when_offline() { + let (surfnet_svm, _simnet_events_rx, _geyser_events_rx) = SurfnetSvm::default(); + let svm_locker = SurfnetSvmLocker::new(surfnet_svm); + + svm_locker + .initialize(400, &None, false, None) + .await + .expect("initialize should succeed"); + + let epoch_schedule = + svm_locker.with_svm_reader(|svm_reader| svm_reader.inner.get_sysvar::()); + + assert!( + !epoch_schedule.warmup, + "offline initialization should disable warmup to match mainnet" + ); + assert_eq!( + epoch_schedule.get_first_slot_in_epoch(886), + 886_u64 * 432_000, + "first slot should align with mainnet epoch boundaries when warmup is disabled" + ); + } } diff --git a/crates/core/src/surfnet/remote.rs b/crates/core/src/surfnet/remote.rs index 6dcaff28..99aa44fc 100644 --- a/crates/core/src/surfnet/remote.rs +++ b/crates/core/src/surfnet/remote.rs @@ -20,6 +20,7 @@ use solana_client::{ use solana_clock::Slot; use solana_commitment_config::CommitmentConfig; use solana_epoch_info::EpochInfo; +use solana_epoch_schedule::EpochSchedule; use solana_hash::Hash; use solana_loader_v3_interface::get_program_data_address; use solana_pubkey::Pubkey; @@ -91,6 +92,10 @@ impl SurfnetRemoteClient { self.client.get_epoch_info().await.map_err(Into::into) } + pub async fn get_epoch_schedule(&self) -> SurfpoolResult { + self.client.get_epoch_schedule().await.map_err(Into::into) + } + pub async fn get_account( &self, pubkey: &Pubkey, diff --git a/crates/core/src/surfnet/svm.rs b/crates/core/src/surfnet/svm.rs index 25aaf54e..556c92e4 100644 --- a/crates/core/src/surfnet/svm.rs +++ b/crates/core/src/surfnet/svm.rs @@ -27,6 +27,7 @@ use solana_client::{ use solana_clock::{Clock, Slot}; use solana_commitment_config::{CommitmentConfig, CommitmentLevel}; use solana_epoch_info::EpochInfo; +use solana_epoch_schedule::EpochSchedule; use solana_feature_gate_interface::Feature; use solana_genesis_config::GenesisConfig; use solana_hash::Hash; @@ -652,6 +653,7 @@ impl SurfnetSvm { pub fn initialize( &mut self, epoch_info: EpochInfo, + epoch_schedule: EpochSchedule, slot_time: u64, remote_ctx: &Option, do_profile_instructions: bool, @@ -675,6 +677,8 @@ impl SurfnetSvm { let _ = self.register_idl(template.idl, None); } + self.inner.set_sysvar(&epoch_schedule); + if let Some(remote_client) = remote_ctx { let _ = self .simnet_events_tx