diff --git a/Cargo.lock b/Cargo.lock index c71bd32fbab642..4a1ec226339055 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6827,6 +6827,7 @@ dependencies = [ "num-derive", "num-traits", "parking_lot 0.12.3", + "qualifier_attr", "rand 0.8.5", "rustc_version 0.4.0", "serde", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index cba150eac570e7..71a8d24733f4e5 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -98,6 +98,7 @@ assert_matches = { workspace = true } curve25519-dalek = { workspace = true } hex = { workspace = true } solana-logger = { workspace = true } +solana-program = { workspace = true, features = ["dev-context-only-utils"] } solana-sdk = { path = ".", features = ["dev-context-only-utils"] } static_assertions = { workspace = true } tiny-bip39 = { workspace = true } diff --git a/sdk/program/Cargo.toml b/sdk/program/Cargo.toml index 45a6927d8cc447..627094b4059805 100644 --- a/sdk/program/Cargo.toml +++ b/sdk/program/Cargo.toml @@ -25,6 +25,7 @@ log = { workspace = true } memoffset = { workspace = true } num-derive = { workspace = true } num-traits = { workspace = true, features = ["i128"] } +qualifier_attr = { workspace = true, optional = true } serde = { workspace = true } serde_bytes = { workspace = true } serde_derive = { workspace = true } @@ -93,4 +94,5 @@ crate-type = ["cdylib", "rlib"] [features] default = ["borsh"] borsh = ["dep:borsh", "dep:borsh0-10"] +dev-context-only-utils = ["dep:qualifier_attr"] frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"] diff --git a/sdk/program/src/message/legacy.rs b/sdk/program/src/message/legacy.rs index 5f5e808f90cfea..502a9ccd351ba4 100644 --- a/sdk/program/src/message/legacy.rs +++ b/sdk/program/src/message/legacy.rs @@ -662,29 +662,6 @@ impl Message { i < self.header.num_required_signatures as usize } - #[deprecated] - pub fn get_account_keys_by_lock_type(&self) -> (Vec<&Pubkey>, Vec<&Pubkey>) { - let mut writable_keys = vec![]; - let mut readonly_keys = vec![]; - for (i, key) in self.account_keys.iter().enumerate() { - if self.is_maybe_writable(i, None) { - writable_keys.push(key); - } else { - readonly_keys.push(key); - } - } - (writable_keys, readonly_keys) - } - - #[deprecated] - pub fn deserialize_instruction( - index: usize, - data: &[u8], - ) -> Result { - #[allow(deprecated)] - sysvar::instructions::load_instruction_at(index, data) - } - pub fn signer_keys(&self) -> Vec<&Pubkey> { // Clamp in case we're working on un-`sanitize()`ed input let last_key = self @@ -907,36 +884,6 @@ mod tests { assert!(!message.is_account_maybe_reserved(2, None)); } - #[test] - fn test_get_account_keys_by_lock_type() { - let program_id = Pubkey::default(); - let id0 = Pubkey::new_unique(); - let id1 = Pubkey::new_unique(); - let id2 = Pubkey::new_unique(); - let id3 = Pubkey::new_unique(); - let message = Message::new( - &[ - Instruction::new_with_bincode(program_id, &0, vec![AccountMeta::new(id0, false)]), - Instruction::new_with_bincode(program_id, &0, vec![AccountMeta::new(id1, true)]), - Instruction::new_with_bincode( - program_id, - &0, - vec![AccountMeta::new_readonly(id2, false)], - ), - Instruction::new_with_bincode( - program_id, - &0, - vec![AccountMeta::new_readonly(id3, true)], - ), - ], - Some(&id1), - ); - assert_eq!( - message.get_account_keys_by_lock_type(), - (vec![&id1, &id0], vec![&id3, &program_id, &id2]) - ); - } - #[test] fn test_program_ids() { let key0 = Pubkey::new_unique(); diff --git a/sdk/program/src/sysvar/instructions.rs b/sdk/program/src/sysvar/instructions.rs index 855b14b54a7e30..9bc1d001c349d5 100644 --- a/sdk/program/src/sysvar/instructions.rs +++ b/sdk/program/src/sysvar/instructions.rs @@ -29,6 +29,8 @@ #![allow(clippy::arithmetic_side_effects)] +#[cfg(feature = "dev-context-only-utils")] +use qualifier_attr::qualifiers; #[cfg(not(target_os = "solana"))] use { crate::serialize_utils::{append_slice, append_u16, append_u8}, @@ -149,11 +151,10 @@ fn serialize_instructions(instructions: &[BorrowedInstruction]) -> Vec { /// `Transaction`. /// /// `data` is the instructions sysvar account data. -#[deprecated( - since = "1.8.0", - note = "Unsafe because the sysvar accounts address is not checked, please use `load_current_index_checked` instead" -)] -pub fn load_current_index(data: &[u8]) -> u16 { +/// +/// Unsafe because the sysvar accounts address is not checked; only used +/// internally after such a check. +fn load_current_index(data: &[u8]) -> u16 { let mut instr_fixed_data = [0u8; 2]; let len = data.len(); instr_fixed_data.copy_from_slice(&data[len - 2..len]); @@ -174,10 +175,8 @@ pub fn load_current_index_checked( } let instruction_sysvar = instruction_sysvar_account_info.try_borrow_data()?; - let mut instr_fixed_data = [0u8; 2]; - let len = instruction_sysvar.len(); - instr_fixed_data.copy_from_slice(&instruction_sysvar[len - 2..len]); - Ok(u16::from_le_bytes(instr_fixed_data)) + let index = load_current_index(&instruction_sysvar); + Ok(index) } /// Store the current `Instruction`'s index in the instructions sysvar data. @@ -234,11 +233,11 @@ fn deserialize_instruction(index: usize, data: &[u8]) -> Result Result { +/// +/// Unsafe because the sysvar accounts address is not checked; only used +/// internally after such a check. +#[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))] +fn load_instruction_at(index: usize, data: &[u8]) -> Result { deserialize_instruction(index, data) } @@ -257,7 +256,7 @@ pub fn load_instruction_at_checked( } let instruction_sysvar = instruction_sysvar_account_info.try_borrow_data()?; - deserialize_instruction(index, &instruction_sysvar).map_err(|err| match err { + load_instruction_at(index, &instruction_sysvar).map_err(|err| match err { SanitizeError::IndexOutOfBounds => ProgramError::InvalidArgument, _ => ProgramError::InvalidInstructionData, }) @@ -278,13 +277,11 @@ pub fn get_instruction_relative( } let instruction_sysvar = instruction_sysvar_account_info.data.borrow(); - #[allow(deprecated)] let current_index = load_current_index(&instruction_sysvar) as i64; let index = current_index.saturating_add(index_relative_to_current); if index < 0 { return Err(ProgramError::InvalidArgument); } - #[allow(deprecated)] load_instruction_at( current_index.saturating_add(index_relative_to_current) as usize, &instruction_sysvar,