From 735fd57bba83a356e5975001d6ca8df414413eec Mon Sep 17 00:00:00 2001 From: ohaddahan Date: Fri, 2 Sep 2022 09:55:34 +0300 Subject: [PATCH] init --- .gitignore | 3 +++ Cargo.toml | 9 +++++++++ src/errors.rs | 0 src/lib.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/structs.rs | 15 +++++++++++++++ src/utils.rs | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/errors.rs create mode 100644 src/lib.rs create mode 100644 src/structs.rs create mode 100644 src/utils.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df49965 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/Cargo.lock +.idea \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3f21994 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "solana-sandwich" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +solana-program = "1.11.10" diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..689dd9c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,47 @@ +mod errors; +mod structs; +mod utils; + +use crate::structs::{AllowedRules, InstructionsData}; +use crate::utils::load_instruction_data; +use solana_program::account_info::AccountInfo; +use solana_program::program_error::ProgramError; +use solana_program::sysvar::instructions::load_instruction_at_checked; + +pub fn allowed_only<'a>( + instruction_sysvar_account: &'a AccountInfo<'a>, + rules: Vec, +) -> Result { + let instruction_data = load_instruction_data(instruction_sysvar_account)?; + + for index in 0..instruction_data.num_of_instructions { + let instruction = load_instruction_at_checked(index as usize, instruction_sysvar_account)?; + let rule: &AllowedRules = match rules + .iter() + .find(|rule| rule.program == instruction.program_id) + { + Some(r) => r, + None => { + return Ok(false); + } + }; + + if !rule.before && index > instruction_data.current_index { + return Ok(false); + } + if !rule.after && index < instruction_data.current_index { + return Ok(false); + } + } + + Ok(true) +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + let result = 2 + 2; + assert_eq!(result, 4); + } +} diff --git a/src/structs.rs b/src/structs.rs new file mode 100644 index 0000000..a4afa57 --- /dev/null +++ b/src/structs.rs @@ -0,0 +1,15 @@ +use solana_program::account_info::AccountInfo; +use solana_program::pubkey::Pubkey; + +pub struct AllowedRules { + pub program: Pubkey, + pub before: bool, + pub after: bool, +} + +pub struct InstructionsData<'a> { + pub current_program: Pubkey, + pub current_index: u16, + pub num_of_instructions: u16, + pub instruction_sysvar_account: &'a AccountInfo<'a>, +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..027f293 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,33 @@ +use crate::InstructionsData; +use solana_program::account_info::AccountInfo; +use solana_program::program_error::ProgramError; +use solana_program::serialize_utils::read_u16; +use solana_program::sysvar::instructions::{ + load_current_index_checked, load_instruction_at_checked, +}; + +pub fn load_instruction_data<'a>( + instruction_sysvar_account: &'a AccountInfo<'a>, +) -> Result, ProgramError> { + let data = instruction_sysvar_account.try_borrow_data()?; + let current_index = load_current_index_checked(instruction_sysvar_account)?; + let instruction = + load_instruction_at_checked(current_index as usize, instruction_sysvar_account)?; + let mut current = 0; + let num_of_instructions= match read_u16(&mut current, &**data) { + Ok(index) => { + index + } + Err(_) => { + return Err(ProgramError::InvalidArgument); + // return Err(ReadingNumInstructionsError); + } + }; + + Ok(InstructionsData { + current_program: instruction.program_id, + current_index, + num_of_instructions, + instruction_sysvar_account, + }) +}