diff --git a/program-runtime/src/sysvar_cache.rs b/program-runtime/src/sysvar_cache.rs index c403f1c057cbe5..697feb200617bf 100644 --- a/program-runtime/src/sysvar_cache.rs +++ b/program-runtime/src/sysvar_cache.rs @@ -1,15 +1,15 @@ #[allow(deprecated)] -use solana_sdk::sysvar::{ - fees::Fees, last_restart_slot::LastRestartSlot, recent_blockhashes::RecentBlockhashes, -}; +use solana_sdk::sysvar::{fees::Fees, recent_blockhashes::RecentBlockhashes}; use { crate::invoke_context::InvokeContext, + serde::de::DeserializeOwned, solana_sdk::{ instruction::InstructionError, pubkey::Pubkey, sysvar::{ - clock::Clock, epoch_rewards::EpochRewards, epoch_schedule::EpochSchedule, rent::Rent, - slot_hashes::SlotHashes, stake_history::StakeHistory, Sysvar, SysvarId, + clock::Clock, epoch_rewards::EpochRewards, epoch_schedule::EpochSchedule, + last_restart_slot::LastRestartSlot, rent::Rent, slot_hashes::SlotHashes, + stake_history::StakeHistory, Sysvar, SysvarId, }, transaction_context::{IndexOfAccount, InstructionContext, TransactionContext}, }, @@ -26,189 +26,229 @@ impl ::solana_frozen_abi::abi_example::AbiExample for SysvarCache { #[derive(Default, Clone, Debug)] pub struct SysvarCache { - clock: Option>, - epoch_schedule: Option>, - epoch_rewards: Option>, + // full account data as provided by bank, including any trailing zeroes + // the setters MUST NOT be changed to serialize an object representation + // it is required that the syscall be able to access the full buffer + // TODO enforce this in tests + clock: Option>, + epoch_schedule: Option>, + epoch_rewards: Option>, + rent: Option>, + slot_hashes: Option>, + stake_history: Option>, + last_restart_slot: Option>, + + // object representations of large sysvars for convenience + // these are used by the stake and vote builtin programs + // these should be removed once those programs are ported to bpf + slot_hashes_obj: Option>, + stake_history_obj: Option>, + + // deprecated sysvars, these should be removed once practical #[allow(deprecated)] - fees: Option>, - rent: Option>, - slot_hashes: Option>, + fees: Option, #[allow(deprecated)] - recent_blockhashes: Option>, - stake_history: Option>, - last_restart_slot: Option>, + recent_blockhashes: Option, } impl SysvarCache { - pub fn get_clock(&self) -> Result, InstructionError> { - self.clock - .clone() - .ok_or(InstructionError::UnsupportedSysvar) - } - - pub fn set_clock(&mut self, clock: Clock) { - self.clock = Some(Arc::new(clock)); + fn sysvar_id_to_buffer(&self, sysvar_id: &Pubkey) -> &Option> { + if *sysvar_id == Clock::id() { + &self.clock + } else if *sysvar_id == EpochSchedule::id() { + &self.epoch_schedule + } else if *sysvar_id == EpochRewards::id() { + &self.epoch_rewards + } else if *sysvar_id == Rent::id() { + &self.rent + } else if *sysvar_id == SlotHashes::id() { + &self.slot_hashes + } else if *sysvar_id == StakeHistory::id() { + &self.stake_history + } else if *sysvar_id == LastRestartSlot::id() { + &self.last_restart_slot + } else { + &None + } } - pub fn get_epoch_schedule(&self) -> Result, InstructionError> { - self.epoch_schedule - .clone() - .ok_or(InstructionError::UnsupportedSysvar) + pub fn read_sysvar_into( + &self, + sysvar_id: &Pubkey, + length: usize, + offset: usize, + out_buf: &mut [u8], + ) -> Result<(), InstructionError> { + if let Some(ref sysvar_buf) = self.sysvar_id_to_buffer(sysvar_id) { + if length == 0 { + panic!("zero length error"); + } + + match length.checked_add(offset) { + Some(limit) if limit <= sysvar_buf.len() => (), + _ => panic!("overrun error"), + } + + if length != out_buf.len() { + panic!("bad out_buf error"); + } + + if let Some(sysvar_slice) = offset + .checked_add(length) + .and_then(|limit| sysvar_buf.get(offset..limit)) + { + out_buf.copy_from_slice(sysvar_slice); + } else { + panic!("shouldnt happen"); + } + + Ok(()) + } else { + panic!("not found err"); + } } - pub fn set_epoch_schedule(&mut self, epoch_schedule: EpochSchedule) { - self.epoch_schedule = Some(Arc::new(epoch_schedule)); + // most if not all of the obj getter functions can be removed once builtins transition to bpf + fn get_sysvar_obj( + &self, + sysvar_id: &Pubkey, + ) -> Result { + if let Some(ref sysvar_buf) = self.sysvar_id_to_buffer(sysvar_id) { + bincode::deserialize(sysvar_buf).map_err(|_| InstructionError::UnsupportedSysvar) + } else { + Err(InstructionError::UnsupportedSysvar) + } } - pub fn get_epoch_rewards(&self) -> Result, InstructionError> { - self.epoch_rewards - .clone() - .ok_or(InstructionError::UnsupportedSysvar) + pub fn get_clock(&self) -> Result { + self.get_sysvar_obj(&Clock::id()) } - pub fn set_epoch_rewards(&mut self, epoch_rewards: EpochRewards) { - self.epoch_rewards = Some(Arc::new(epoch_rewards)); + pub fn get_epoch_schedule(&self) -> Result { + self.get_sysvar_obj(&EpochSchedule::id()) } - #[deprecated] - #[allow(deprecated)] - pub fn get_fees(&self) -> Result, InstructionError> { - self.fees.clone().ok_or(InstructionError::UnsupportedSysvar) + pub fn get_epoch_rewards(&self) -> Result { + self.get_sysvar_obj(&EpochRewards::id()) } - #[deprecated] - #[allow(deprecated)] - pub fn set_fees(&mut self, fees: Fees) { - self.fees = Some(Arc::new(fees)); + pub fn get_rent(&self) -> Result { + self.get_sysvar_obj(&Rent::id()) } - pub fn get_rent(&self) -> Result, InstructionError> { - self.rent.clone().ok_or(InstructionError::UnsupportedSysvar) + pub fn get_last_restart_slot(&self) -> Result { + self.get_sysvar_obj(&LastRestartSlot::id()) } - pub fn set_rent(&mut self, rent: Rent) { - self.rent = Some(Arc::new(rent)); - } - - pub fn get_last_restart_slot(&self) -> Result, InstructionError> { - self.last_restart_slot + pub fn get_stake_history(&self) -> Result, InstructionError> { + self.stake_history_obj .clone() .ok_or(InstructionError::UnsupportedSysvar) } - pub fn set_last_restart_slot(&mut self, last_restart_slot: LastRestartSlot) { - self.last_restart_slot = Some(Arc::new(last_restart_slot)); - } - pub fn get_slot_hashes(&self) -> Result, InstructionError> { - self.slot_hashes + self.slot_hashes_obj .clone() .ok_or(InstructionError::UnsupportedSysvar) } - pub fn set_slot_hashes(&mut self, slot_hashes: SlotHashes) { - self.slot_hashes = Some(Arc::new(slot_hashes)); - } - #[deprecated] #[allow(deprecated)] - pub fn get_recent_blockhashes(&self) -> Result, InstructionError> { - self.recent_blockhashes - .clone() - .ok_or(InstructionError::UnsupportedSysvar) + pub fn get_fees(&self) -> Result { + self.fees.clone().ok_or(InstructionError::UnsupportedSysvar) } #[deprecated] #[allow(deprecated)] - pub fn set_recent_blockhashes(&mut self, recent_blockhashes: RecentBlockhashes) { - self.recent_blockhashes = Some(Arc::new(recent_blockhashes)); - } - - pub fn get_stake_history(&self) -> Result, InstructionError> { - self.stake_history + pub fn get_recent_blockhashes(&self) -> Result { + self.recent_blockhashes .clone() .ok_or(InstructionError::UnsupportedSysvar) } - pub fn set_stake_history(&mut self, stake_history: StakeHistory) { - self.stake_history = Some(Arc::new(stake_history)); - } - pub fn fill_missing_entries( &mut self, mut get_account_data: F, ) { if self.clock.is_none() { get_account_data(&Clock::id(), &mut |data: &[u8]| { - if let Ok(clock) = bincode::deserialize(data) { - self.set_clock(clock); + if bincode::deserialize::(data).is_ok() { + self.clock = Some(data.to_vec()); } }); } + if self.epoch_schedule.is_none() { get_account_data(&EpochSchedule::id(), &mut |data: &[u8]| { - if let Ok(epoch_schedule) = bincode::deserialize(data) { - self.set_epoch_schedule(epoch_schedule); + if bincode::deserialize::(data).is_ok() { + self.epoch_schedule = Some(data.to_vec()); } }); } if self.epoch_rewards.is_none() { get_account_data(&EpochRewards::id(), &mut |data: &[u8]| { - if let Ok(epoch_rewards) = bincode::deserialize(data) { - self.set_epoch_rewards(epoch_rewards); + if bincode::deserialize::(data).is_ok() { + self.epoch_rewards = Some(data.to_vec()); } }); } - #[allow(deprecated)] - if self.fees.is_none() { - get_account_data(&Fees::id(), &mut |data: &[u8]| { - if let Ok(fees) = bincode::deserialize(data) { - self.set_fees(fees); - } - }); - } if self.rent.is_none() { get_account_data(&Rent::id(), &mut |data: &[u8]| { - if let Ok(rent) = bincode::deserialize(data) { - self.set_rent(rent); + if bincode::deserialize::(data).is_ok() { + self.rent = Some(data.to_vec()); } }); } + if self.slot_hashes.is_none() { get_account_data(&SlotHashes::id(), &mut |data: &[u8]| { - if let Ok(slot_hashes) = bincode::deserialize(data) { - self.set_slot_hashes(slot_hashes); - } - }); - } - #[allow(deprecated)] - if self.recent_blockhashes.is_none() { - get_account_data(&RecentBlockhashes::id(), &mut |data: &[u8]| { - if let Ok(recent_blockhashes) = bincode::deserialize(data) { - self.set_recent_blockhashes(recent_blockhashes); + if let Ok(obj) = bincode::deserialize::(data) { + self.slot_hashes = Some(data.to_vec()); + self.slot_hashes_obj = Some(Arc::new(obj)); } }); } + if self.stake_history.is_none() { get_account_data(&StakeHistory::id(), &mut |data: &[u8]| { - if let Ok(stake_history) = bincode::deserialize(data) { - self.set_stake_history(stake_history); + if let Ok(obj) = bincode::deserialize::(data) { + self.stake_history = Some(data.to_vec()); + self.stake_history_obj = Some(Arc::new(obj)); } }); } + if self.last_restart_slot.is_none() { get_account_data(&LastRestartSlot::id(), &mut |data: &[u8]| { - if let Ok(last_restart_slot) = bincode::deserialize(data) { - self.set_last_restart_slot(last_restart_slot); + if bincode::deserialize::(data).is_ok() { + self.last_restart_slot = Some(data.to_vec()); + } + }); + } + + #[allow(deprecated)] + if self.fees.is_none() { + get_account_data(&Fees::id(), &mut |data: &[u8]| { + if let Ok(fees) = bincode::deserialize(data) { + self.fees = Some(fees); + } + }); + } + + #[allow(deprecated)] + if self.recent_blockhashes.is_none() { + get_account_data(&RecentBlockhashes::id(), &mut |data: &[u8]| { + if let Ok(recent_blockhashes) = bincode::deserialize(data) { + self.recent_blockhashes = Some(recent_blockhashes); } }); } } pub fn reset(&mut self) { - *self = SysvarCache::default(); + *self = Self::default(); } } @@ -237,7 +277,7 @@ pub mod get_sysvar_with_account_check { invoke_context: &InvokeContext, instruction_context: &InstructionContext, instruction_account_index: IndexOfAccount, - ) -> Result, InstructionError> { + ) -> Result { check_sysvar_account::( invoke_context.transaction_context, instruction_context, @@ -250,7 +290,7 @@ pub mod get_sysvar_with_account_check { invoke_context: &InvokeContext, instruction_context: &InstructionContext, instruction_account_index: IndexOfAccount, - ) -> Result, InstructionError> { + ) -> Result { check_sysvar_account::( invoke_context.transaction_context, instruction_context, @@ -277,7 +317,7 @@ pub mod get_sysvar_with_account_check { invoke_context: &InvokeContext, instruction_context: &InstructionContext, instruction_account_index: IndexOfAccount, - ) -> Result, InstructionError> { + ) -> Result { check_sysvar_account::( invoke_context.transaction_context, instruction_context, @@ -303,7 +343,7 @@ pub mod get_sysvar_with_account_check { invoke_context: &InvokeContext, instruction_context: &InstructionContext, instruction_account_index: IndexOfAccount, - ) -> Result, InstructionError> { + ) -> Result { check_sysvar_account::( invoke_context.transaction_context, instruction_context, diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index ee9b4fdef5c37c..3c6ca4b5171680 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -202,7 +202,7 @@ macro_rules! processor { } fn get_sysvar( - sysvar: Result, InstructionError>, + sysvar: Result, var_addr: *mut u8, ) -> u64 { let invoke_context = get_invoke_context(); diff --git a/programs/bpf_loader/src/syscalls/mod.rs b/programs/bpf_loader/src/syscalls/mod.rs index 63e15171a7af5d..d5721bd5ca3ad4 100644 --- a/programs/bpf_loader/src/syscalls/mod.rs +++ b/programs/bpf_loader/src/syscalls/mod.rs @@ -7,6 +7,7 @@ pub use self::{ sysvar::{ SyscallGetClockSysvar, SyscallGetEpochRewardsSysvar, SyscallGetEpochScheduleSysvar, SyscallGetFeesSysvar, SyscallGetLastRestartSlotSysvar, SyscallGetRentSysvar, + SyscallGetSysvar, }, }; #[allow(deprecated)] @@ -38,8 +39,9 @@ use { disable_deploy_of_alloc_free_syscall, disable_fees_sysvar, enable_alt_bn128_compression_syscall, enable_alt_bn128_syscall, enable_big_mod_exp_syscall, enable_partitioned_epoch_reward, enable_poseidon_syscall, - error_on_syscall_bpf_function_hash_collisions, last_restart_slot_sysvar, - reject_callx_r10, remaining_compute_units_syscall_enabled, switch_to_new_elf_parser, + error_on_syscall_bpf_function_hash_collisions, get_sysvar_syscall_enabled, + last_restart_slot_sysvar, reject_callx_r10, remaining_compute_units_syscall_enabled, + switch_to_new_elf_parser, }, hash::{Hash, Hasher}, instruction::{AccountMeta, InstructionError, ProcessedSiblingInstruction}, @@ -278,6 +280,7 @@ pub fn create_program_runtime_environment_v1<'a>( let enable_poseidon_syscall = feature_set.is_active(&enable_poseidon_syscall::id()); let remaining_compute_units_syscall_enabled = feature_set.is_active(&remaining_compute_units_syscall_enabled::id()); + let get_sysvar_syscall_enabled = feature_set.is_active(&get_sysvar_syscall_enabled::id()); // !!! ATTENTION !!! // When adding new features for RBPF here, // also add them to `Bank::apply_builtin_program_feature_transitions()`. @@ -464,6 +467,14 @@ pub fn create_program_runtime_environment_v1<'a>( SyscallAltBn128Compression::vm, )?; + // Sysvar getter + register_feature_gated_function!( + result, + get_sysvar_syscall_enabled, + *b"sol_get_sysvar", + SyscallGetSysvar::vm, + )?; + // Log data result.register_function_hashed(*b"sol_log_data", SyscallLogData::vm)?; @@ -3365,11 +3376,19 @@ mod tests { src_rewards.active = true; let mut sysvar_cache = SysvarCache::default(); - sysvar_cache.set_clock(src_clock.clone()); - sysvar_cache.set_epoch_schedule(src_epochschedule.clone()); - sysvar_cache.set_fees(src_fees.clone()); - sysvar_cache.set_rent(src_rent.clone()); - sysvar_cache.set_epoch_rewards(src_rewards.clone()); + sysvar_cache.fill_missing_entries(|pubkey, callback| { + if *pubkey == sysvar::clock::id() { + callback(&bincode::serialize(&src_clock.clone()).unwrap()) + } else if *pubkey == sysvar::epoch_schedule::id() { + callback(&bincode::serialize(&src_epochschedule.clone()).unwrap()) + } else if *pubkey == sysvar::fees::id() { + callback(&bincode::serialize(&src_fees.clone()).unwrap()) + } else if *pubkey == sysvar::rent::id() { + callback(&bincode::serialize(&src_rent.clone()).unwrap()) + } else if *pubkey == sysvar::epoch_rewards::id() { + callback(&bincode::serialize(&src_rewards.clone()).unwrap()) + } + }); let transaction_accounts = vec![ ( diff --git a/programs/bpf_loader/src/syscalls/sysvar.rs b/programs/bpf_loader/src/syscalls/sysvar.rs index e8777569cef1da..94e901759d5a3c 100644 --- a/programs/bpf_loader/src/syscalls/sysvar.rs +++ b/programs/bpf_loader/src/syscalls/sysvar.rs @@ -1,7 +1,7 @@ use super::*; fn get_sysvar( - sysvar: Result, InstructionError>, + sysvar: Result, var_addr: u64, check_aligned: bool, memory_mapping: &mut MemoryMapping, @@ -16,8 +16,11 @@ fn get_sysvar( )?; let var = translate_type_mut::(memory_mapping, var_addr, check_aligned)?; - let sysvar: Arc = sysvar?; - *var = T::clone(sysvar.as_ref()); + // this clone looks unecessary, but it exists to zero out trailing alignment bytes + // it is unclear whether this should ever matter + // but there are tests using MemoryMapping that expect to see this + // we preserve the previous behavior out of an abundance of caution + *var = sysvar?.clone(); Ok(SUCCESS) } @@ -156,3 +159,35 @@ declare_builtin_function!( ) } ); + +declare_builtin_function!( + /// Get a slice of a Sysvar in-memory representation + SyscallGetSysvar, + fn rust( + invoke_context: &mut InvokeContext, + sysvar_id_addr: u64, + length: u64, + offset: u64, + var_addr: u64, + _arg5: u64, + memory_mapping: &mut MemoryMapping, + ) -> Result { + let check_aligned = invoke_context.get_check_aligned(); + consume_compute_meter( + invoke_context, + invoke_context + .get_compute_budget() + .sysvar_base_cost + .saturating_add(length), + )?; + + let sysvar_id = translate_type::(memory_mapping, sysvar_id_addr, check_aligned)?; + + let var = translate_slice_mut::(memory_mapping, var_addr, length, check_aligned)?; + + let cache = invoke_context.get_sysvar_cache(); + cache.read_sysvar_into(sysvar_id, length as usize, offset as usize, var)?; + + Ok(SUCCESS) + } +); diff --git a/programs/stake/src/stake_state.rs b/programs/stake/src/stake_state.rs index f20283cfbd8582..31b65237e67f2b 100644 --- a/programs/stake/src/stake_state.rs +++ b/programs/stake/src/stake_state.rs @@ -65,7 +65,7 @@ pub(crate) fn new_warmup_cooldown_rate_epoch(invoke_context: &InvokeContext) -> .unwrap(); invoke_context .feature_set - .new_warmup_cooldown_rate_epoch(epoch_schedule.as_ref()) + .new_warmup_cooldown_rate_epoch(&epoch_schedule) } fn get_stake_status( diff --git a/programs/vote/src/vote_processor.rs b/programs/vote/src/vote_processor.rs index 72309a26ca2b55..1fdeb6044e63c3 100644 --- a/programs/vote/src/vote_processor.rs +++ b/programs/vote/src/vote_processor.rs @@ -146,8 +146,8 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| &mut me, commission, &signers, - sysvar_cache.get_epoch_schedule()?.as_ref(), - sysvar_cache.get_clock()?.as_ref(), + &sysvar_cache.get_epoch_schedule()?, + &sysvar_cache.get_clock()?, &invoke_context.feature_set, ) } diff --git a/runtime/src/bank/sysvar_cache.rs b/runtime/src/bank/sysvar_cache.rs index e45f64e96aaf3f..1f559b1ae05cf3 100644 --- a/runtime/src/bank/sysvar_cache.rs +++ b/runtime/src/bank/sysvar_cache.rs @@ -152,7 +152,7 @@ mod tests { bank1_cached_slot_hashes ); assert_eq!( - *bank1_sysvar_cache.get_epoch_rewards().unwrap(), + bank1_sysvar_cache.get_epoch_rewards().unwrap(), expected_epoch_rewards, ); } diff --git a/sdk/program/src/program_stubs.rs b/sdk/program/src/program_stubs.rs index cf890659fa68a1..b82a9d5adb1abe 100644 --- a/sdk/program/src/program_stubs.rs +++ b/sdk/program/src/program_stubs.rs @@ -43,6 +43,15 @@ pub trait SyscallStubs: Sync + Send { sol_log("SyscallStubs: sol_invoke_signed() not available"); Ok(()) } + fn sol_get_sysvar( + &self, + _sysvar_id_addr: *const u8, + _length: u64, + _offset: u64, + _var_addr: *mut u8, + ) -> u64 { + UNSUPPORTED_SYSVAR + } fn sol_get_clock_sysvar(&self, _var_addr: *mut u8) -> u64 { UNSUPPORTED_SYSVAR } @@ -145,6 +154,20 @@ pub(crate) fn sol_invoke_signed( .sol_invoke_signed(instruction, account_infos, signers_seeds) } +// HANA to be used in forthcoming stake history and slot hashes impls +#[allow(dead_code)] +pub(crate) fn sol_get_sysvar( + sysvar_id_addr: *const u8, + length: u64, + offset: u64, + var_addr: *mut u8, +) -> u64 { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_sysvar(sysvar_id_addr, length, offset, var_addr) +} + pub(crate) fn sol_get_clock_sysvar(var_addr: *mut u8) -> u64 { SYSCALL_STUBS.read().unwrap().sol_get_clock_sysvar(var_addr) } diff --git a/sdk/program/src/stake_history.rs b/sdk/program/src/stake_history.rs index 0441482fd2f38e..01fea3fe8439fa 100644 --- a/sdk/program/src/stake_history.rs +++ b/sdk/program/src/stake_history.rs @@ -73,6 +73,24 @@ impl StakeHistory { } (self.0).truncate(MAX_ENTRIES); } + + // HANA just making sure we stay typechecking + fn _get_entry_placeholder() -> Option { + let id_addr = crate::sysvar::stake_history::id().0.as_ptr(); + let mut var = StakeHistoryEntry::default(); + let var_addr = &mut var as *mut _ as *mut u8; + + #[cfg(target_os = "solana")] + let result = unsafe { crate::syscalls::sol_get_sysvar(id_addr, 32, 8, var_addr) }; + + #[cfg(not(target_os = "solana"))] + let result = crate::program_stubs::sol_get_sysvar(id_addr, 32, 8, var_addr); + + match result { + crate::entrypoint::SUCCESS => Some(var), + _ => None, + } + } } impl Deref for StakeHistory { diff --git a/sdk/program/src/syscalls/definitions.rs b/sdk/program/src/syscalls/definitions.rs index b2dedceba953a0..044b3be05a708e 100644 --- a/sdk/program/src/syscalls/definitions.rs +++ b/sdk/program/src/syscalls/definitions.rs @@ -46,11 +46,6 @@ define_syscall!(fn sol_sha256(vals: *const u8, val_len: u64, hash_result: *mut u define_syscall!(fn sol_keccak256(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64); define_syscall!(fn sol_secp256k1_recover(hash: *const u8, recovery_id: u64, signature: *const u8, result: *mut u8) -> u64); define_syscall!(fn sol_blake3(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64); -define_syscall!(fn sol_get_clock_sysvar(addr: *mut u8) -> u64); -define_syscall!(fn sol_get_epoch_schedule_sysvar(addr: *mut u8) -> u64); -define_syscall!(fn sol_get_fees_sysvar(addr: *mut u8) -> u64); -define_syscall!(fn sol_get_rent_sysvar(addr: *mut u8) -> u64); -define_syscall!(fn sol_get_last_restart_slot(addr: *mut u8) -> u64); define_syscall!(fn sol_memcpy_(dst: *mut u8, src: *const u8, n: u64)); define_syscall!(fn sol_memmove_(dst: *mut u8, src: *const u8, n: u64)); define_syscall!(fn sol_memcmp_(s1: *const u8, s2: *const u8, n: u64, result: *mut i32)); @@ -68,10 +63,21 @@ define_syscall!(fn sol_curve_multiscalar_mul(curve_id: u64, scalars_addr: *const define_syscall!(fn sol_curve_pairing_map(curve_id: u64, point: *const u8, result: *mut u8) -> u64); define_syscall!(fn sol_alt_bn128_group_op(group_op: u64, input: *const u8, input_size: u64, result: *mut u8) -> u64); define_syscall!(fn sol_big_mod_exp(params: *const u8, result: *mut u8) -> u64); -define_syscall!(fn sol_get_epoch_rewards_sysvar(addr: *mut u8) -> u64); define_syscall!(fn sol_poseidon(parameters: u64, endianness: u64, vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64); define_syscall!(fn sol_remaining_compute_units() -> u64); define_syscall!(fn sol_alt_bn128_compression(op: u64, input: *const u8, input_size: u64, result: *mut u8) -> u64); +define_syscall!(fn sol_get_sysvar(sysvar_id_addr: *const u8, length: u64, offset: u64, addr: *mut u8) -> u64); + +// HANA these can all be deprecated as they are superceded by sol_get_sysvar +// but marking #[deprecated] does nothing +define_syscall!(fn sol_get_clock_sysvar(addr: *mut u8) -> u64); +define_syscall!(fn sol_get_epoch_schedule_sysvar(addr: *mut u8) -> u64); +define_syscall!(fn sol_get_rent_sysvar(addr: *mut u8) -> u64); +define_syscall!(fn sol_get_last_restart_slot(addr: *mut u8) -> u64); +define_syscall!(fn sol_get_epoch_rewards_sysvar(addr: *mut u8) -> u64); + +// HANA this cant go through sol_get_sysvar but i wonder if we have a mechanism to remove it at all +define_syscall!(fn sol_get_fees_sysvar(addr: *mut u8) -> u64); #[cfg(target_feature = "static-syscalls")] pub const fn sys_hash(name: &str) -> usize { diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index a162ea852aebf7..64a2dcc08d5c6a 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -789,6 +789,10 @@ pub mod deprecate_unused_legacy_vote_plumbing { solana_sdk::declare_id!("6Uf8S75PVh91MYgPQSHnjRAPQq6an5BDv9vomrCwDqLe"); } +pub mod get_sysvar_syscall_enabled { + solana_sdk::declare_id!("CLCoTADvV64PSrnR6QXty6Fwrt9Xc6EdxSJE4wLRePjq"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -981,6 +985,7 @@ lazy_static! { (remove_rounding_in_fee_calculation::id(), "Removing unwanted rounding in fee calculation #34982"), (deprecate_unused_legacy_vote_plumbing::id(), "Deprecate unused legacy vote tx plumbing"), (enable_tower_sync_ix::id(), "Enable tower sync vote instruction"), + (get_sysvar_syscall_enabled::id(), "Enable syscall for fetching Sysvar bytes #XXXXX"), // HANA /*************** ADD NEW FEATURES HERE ***************/ ] .iter() diff --git a/svm/src/transaction_processor.rs b/svm/src/transaction_processor.rs index d827695e159f4b..02af83134bcf17 100644 --- a/svm/src/transaction_processor.rs +++ b/svm/src/transaction_processor.rs @@ -2180,22 +2180,13 @@ mod tests { let cached_fees = sysvar_cache.get_fees(); let cached_rent = sysvar_cache.get_rent(); - assert_eq!( - cached_clock.expect("clock sysvar missing in cache"), - clock.into() - ); + assert_eq!(cached_clock.expect("clock sysvar missing in cache"), clock); assert_eq!( cached_epoch_schedule.expect("epoch_schedule sysvar missing in cache"), - epoch_schedule.into() - ); - assert_eq!( - cached_fees.expect("fees sysvar missing in cache"), - fees.into() - ); - assert_eq!( - cached_rent.expect("rent sysvar missing in cache"), - rent.into() + epoch_schedule ); + assert_eq!(cached_fees.expect("fees sysvar missing in cache"), fees); + assert_eq!(cached_rent.expect("rent sysvar missing in cache"), rent); assert!(sysvar_cache.get_slot_hashes().is_err()); assert!(sysvar_cache.get_epoch_rewards().is_err()); } @@ -2265,22 +2256,13 @@ mod tests { let cached_fees = sysvar_cache.get_fees(); let cached_rent = sysvar_cache.get_rent(); - assert_eq!( - cached_clock.expect("clock sysvar missing in cache"), - clock.into() - ); + assert_eq!(cached_clock.expect("clock sysvar missing in cache"), clock); assert_eq!( cached_epoch_schedule.expect("epoch_schedule sysvar missing in cache"), - epoch_schedule.into() - ); - assert_eq!( - cached_fees.expect("fees sysvar missing in cache"), - fees.into() - ); - assert_eq!( - cached_rent.expect("rent sysvar missing in cache"), - rent.into() + epoch_schedule ); + assert_eq!(cached_fees.expect("fees sysvar missing in cache"), fees); + assert_eq!(cached_rent.expect("rent sysvar missing in cache"), rent); assert!(sysvar_cache.get_slot_hashes().is_err()); assert!(sysvar_cache.get_epoch_rewards().is_err()); }