From 80f7ffd6b27e59285a1045f5990f2e789c50f9ba Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 18:17:35 +0000 Subject: [PATCH 1/5] Base test, clippy stopped working --- program/rust/build_utils.rs | 3 +- program/rust/src/lib.rs | 8 +- program/rust/src/log.rs | 1 - program/rust/src/rust_oracle.rs | 5 +- program/rust/src/tests/mod.rs | 2 + program/rust/src/tests/test_add_mapping.rs | 97 +++++++++++++++++++ .../test_init_mapping.rs} | 0 7 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 program/rust/src/tests/mod.rs create mode 100644 program/rust/src/tests/test_add_mapping.rs rename program/rust/src/{test_oracle.rs => tests/test_init_mapping.rs} (100%) diff --git a/program/rust/build_utils.rs b/program/rust/build_utils.rs index 0be568b66..41ddf676c 100644 --- a/program/rust/build_utils.rs +++ b/program/rust/build_utils.rs @@ -24,8 +24,7 @@ impl<'a> DeriveAdderParserCallback<'a> { } //this is required to implement the callback trait -impl UnwindSafe for DeriveAdderParserCallback<'_> { -} +impl UnwindSafe for DeriveAdderParserCallback<'_> {} impl ParseCallbacks for DeriveAdderParserCallback<'_> { fn add_derives(&self, _name: &str) -> Vec { diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 139950f48..74757fe9c 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -4,16 +4,18 @@ // Allow using the solana_program::entrypoint::deserialize function #![allow(clippy::not_unsafe_ptr_arg_deref)] -mod c_oracle_header; +pub mod c_oracle_header; mod deserialize; mod error; mod log; mod processor; -mod rust_oracle; -mod test_oracle; +pub mod rust_oracle; mod time_machine_types; mod utils; +#[cfg(test)] +mod tests; + use crate::c_oracle_header::SUCCESSFULLY_UPDATED_AGGREGATE; use crate::error::{ OracleError, diff --git a/program/rust/src/log.rs b/program/rust/src/log.rs index bc7e3dac5..ff32043bf 100644 --- a/program/rust/src/log.rs +++ b/program/rust/src/log.rs @@ -22,7 +22,6 @@ pub fn pre_log(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResu .try_into() .map_err(|_| OracleError::IntegerCastingError)?; - match instruction_id { command_t_e_cmd_upd_price | command_t_e_cmd_agg_price => { let instruction: cmd_upd_price = cmd_upd_price::try_from_slice(instruction_data)?; diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index b47be8aee..9a77af299 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -57,7 +57,6 @@ pub fn update_version( // Ok(SUCCESS) } - /// initialize the first mapping account in a new linked-list of mapping accounts /// accounts[0] funding account [signer writable] /// accounts[1] new mapping account [signer writable] @@ -187,7 +186,7 @@ pub fn load_account_as_mut<'a, T: Pod>( /// Mutably borrow the data in `account` as a mapping account, validating that the account /// is properly formatted. Any mutations to the returned value will be reflected in the /// account data. Use this to read already-initialized accounts. -fn load_mapping_account_mut<'a>( +pub fn load_mapping_account_mut<'a>( account: &'a AccountInfo, expected_version: u32, ) -> Result, ProgramError> { @@ -206,7 +205,7 @@ fn load_mapping_account_mut<'a>( /// Initialize account as a new mapping account. This function will zero out any existing data in /// the account. -fn initialize_mapping_account(account: &AccountInfo, version: u32) -> Result<(), ProgramError> { +pub fn initialize_mapping_account(account: &AccountInfo, version: u32) -> Result<(), ProgramError> { clear_account(account)?; let mut mapping_account = load_account_as_mut::(account)?; diff --git a/program/rust/src/tests/mod.rs b/program/rust/src/tests/mod.rs new file mode 100644 index 000000000..bee79ef71 --- /dev/null +++ b/program/rust/src/tests/mod.rs @@ -0,0 +1,2 @@ +mod test_add_mapping; +mod test_init_mapping; diff --git a/program/rust/src/tests/test_add_mapping.rs b/program/rust/src/tests/test_add_mapping.rs new file mode 100644 index 000000000..f339fc10c --- /dev/null +++ b/program/rust/src/tests/test_add_mapping.rs @@ -0,0 +1,97 @@ +mod test { + use crate::c_oracle_header::{ + cmd_hdr_t, + command_t_e_cmd_add_mapping, + pc_map_table_t, + PC_MAP_TABLE_SIZE, + PC_VERSION, + }; + use crate::rust_oracle::{ + add_mapping, + initialize_mapping_account, + load_mapping_account_mut, + }; + use bytemuck::bytes_of; + use solana_program::account_info::AccountInfo; + use solana_program::clock::Epoch; + use solana_program::native_token::LAMPORTS_PER_SOL; + use solana_program::pubkey::Pubkey; + use solana_program::rent::Rent; + use solana_program::system_program; + use std::mem::size_of; + + #[test] + fn test_add_mapping() { + let hdr: cmd_hdr_t = cmd_hdr_t { + ver_: PC_VERSION, + cmd_: command_t_e_cmd_add_mapping as i32, + }; + let instruction_data = bytes_of::(&hdr); + + let program_id = Pubkey::new_unique(); + let funding_key = Pubkey::new_unique(); + let cur_mapping_key = Pubkey::new_unique(); + let next_mapping_key = Pubkey::new_unique(); + let system_program = system_program::id(); + + let mut funding_balance = LAMPORTS_PER_SOL.clone(); + let funding_account = AccountInfo::new( + &funding_key, + true, + true, + &mut funding_balance, + &mut [], + &system_program, + false, + Epoch::default(), + ); + + let mut cur_mapping_balance = + Rent::minimum_balance(&Rent::default(), size_of::()); + let mut cur_mapping_raw_data = [0u8; size_of::()]; + + let cur_mapping = AccountInfo::new( + &cur_mapping_key, + true, + true, + &mut cur_mapping_balance, + &mut cur_mapping_raw_data, + &program_id, + false, + Epoch::default(), + ); + + initialize_mapping_account(&cur_mapping, PC_VERSION).unwrap(); + + { + let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); + cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; + } + + let mut next_mapping_balance = + Rent::minimum_balance(&Rent::default(), size_of::()); + let mut next_mapping_raw_data = [0u8; size_of::()]; + + let next_mapping = AccountInfo::new( + &next_mapping_key, + true, + true, + &mut next_mapping_balance, + &mut next_mapping_raw_data, + &program_id, + false, + Epoch::default(), + ); + + assert!(add_mapping( + &program_id, + &[ + funding_account.clone(), + cur_mapping.clone(), + next_mapping.clone() + ], + instruction_data + ) + .is_ok()); + } +} diff --git a/program/rust/src/test_oracle.rs b/program/rust/src/tests/test_init_mapping.rs similarity index 100% rename from program/rust/src/test_oracle.rs rename to program/rust/src/tests/test_init_mapping.rs From cb80d5143f16c7c5854cbc7c05d990be0972b520 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 18:59:31 +0000 Subject: [PATCH 2/5] Test complete --- program/rust/build_utils.rs | 3 +- program/rust/src/lib.rs | 4 +- program/rust/src/rust_oracle.rs | 7 +++ program/rust/src/tests/test_add_mapping.rs | 73 ++++++++++++++++++++++ 4 files changed, 84 insertions(+), 3 deletions(-) diff --git a/program/rust/build_utils.rs b/program/rust/build_utils.rs index 41ddf676c..0be568b66 100644 --- a/program/rust/build_utils.rs +++ b/program/rust/build_utils.rs @@ -24,7 +24,8 @@ impl<'a> DeriveAdderParserCallback<'a> { } //this is required to implement the callback trait -impl UnwindSafe for DeriveAdderParserCallback<'_> {} +impl UnwindSafe for DeriveAdderParserCallback<'_> { +} impl ParseCallbacks for DeriveAdderParserCallback<'_> { fn add_derives(&self, _name: &str) -> Vec { diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 74757fe9c..79e770ca0 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -4,12 +4,12 @@ // Allow using the solana_program::entrypoint::deserialize function #![allow(clippy::not_unsafe_ptr_arg_deref)] -pub mod c_oracle_header; +mod c_oracle_header; mod deserialize; mod error; mod log; mod processor; -pub mod rust_oracle; +mod rust_oracle; mod time_machine_types; mod utils; diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 9a77af299..3a79c7d53 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -24,6 +24,7 @@ use crate::c_oracle_header::{ cmd_hdr_t, pc_acc, pc_map_table_t, + pc_pub_key_t, PC_ACCTYPE_MAPPING, PC_MAGIC, PC_MAP_TABLE_SIZE, @@ -217,3 +218,9 @@ pub fn initialize_mapping_account(account: &AccountInfo, version: u32) -> Result Ok(()) } + +// Assign pubkey bytes from source to target, fails if source is not 32 bytes +#[allow(unused)] +pub fn pubkey_assign(target: &mut pc_pub_key_t, source: &[u8]) { + unsafe { target.k1_.copy_from_slice(source) } +} diff --git a/program/rust/src/tests/test_add_mapping.rs b/program/rust/src/tests/test_add_mapping.rs index f339fc10c..7ab809147 100644 --- a/program/rust/src/tests/test_add_mapping.rs +++ b/program/rust/src/tests/test_add_mapping.rs @@ -3,18 +3,23 @@ mod test { cmd_hdr_t, command_t_e_cmd_add_mapping, pc_map_table_t, + PC_MAGIC, PC_MAP_TABLE_SIZE, PC_VERSION, }; use crate::rust_oracle::{ add_mapping, + clear_account, initialize_mapping_account, + load_account_as_mut, load_mapping_account_mut, + pubkey_assign, }; use bytemuck::bytes_of; use solana_program::account_info::AccountInfo; use solana_program::clock::Epoch; use solana_program::native_token::LAMPORTS_PER_SOL; + use solana_program::program_error::ProgramError; use solana_program::pubkey::Pubkey; use solana_program::rent::Rent; use solana_program::system_program; @@ -93,5 +98,73 @@ mod test { instruction_data ) .is_ok()); + + { + let next_mapping_data = load_mapping_account_mut(&next_mapping, PC_VERSION).unwrap(); + let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); + + assert!(unsafe { + cur_mapping_data + .next_ + .k1_ + .iter() + .zip(&next_mapping_key.to_bytes()) + .all(|(x, y)| *x == *y) + }); + assert!(unsafe { next_mapping_data.next_.k8_.iter().all(|x| *x == 0) }); + pubkey_assign(&mut cur_mapping_data.next_, &Pubkey::default().to_bytes()); + cur_mapping_data.num_ = 0; + } + + clear_account(&next_mapping).unwrap(); + + assert_eq!( + add_mapping( + &program_id, + &[ + funding_account.clone(), + cur_mapping.clone(), + next_mapping.clone() + ], + instruction_data + ), + Err(ProgramError::InvalidArgument) + ); + + { + let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); + assert!(unsafe { cur_mapping_data.next_.k8_.iter().all(|x| *x == 0) }); + cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; + cur_mapping_data.magic_ = 0; + } + + assert_eq!( + add_mapping( + &program_id, + &[ + funding_account.clone(), + cur_mapping.clone(), + next_mapping.clone() + ], + instruction_data + ), + Err(ProgramError::InvalidArgument) + ); + + { + let mut cur_mapping_data = load_account_as_mut::(&cur_mapping).unwrap(); + cur_mapping_data.magic_ = PC_MAGIC; + } + + assert!(add_mapping( + &program_id, + &[ + funding_account.clone(), + cur_mapping.clone(), + next_mapping.clone() + ], + instruction_data + ) + .is_ok()); } } From e9f9ac7a2cf6f7ad76022a9e47bb7e3f1e71608b Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 20:53:26 +0000 Subject: [PATCH 3/5] Tests inside tests --- program/rust/src/tests/test_add_mapping.rs | 302 +++++++++-------- program/rust/src/tests/test_init_mapping.rs | 340 ++++++++++---------- 2 files changed, 318 insertions(+), 324 deletions(-) diff --git a/program/rust/src/tests/test_add_mapping.rs b/program/rust/src/tests/test_add_mapping.rs index 7ab809147..ddcba4d00 100644 --- a/program/rust/src/tests/test_add_mapping.rs +++ b/program/rust/src/tests/test_add_mapping.rs @@ -1,94 +1,124 @@ -mod test { - use crate::c_oracle_header::{ - cmd_hdr_t, - command_t_e_cmd_add_mapping, - pc_map_table_t, - PC_MAGIC, - PC_MAP_TABLE_SIZE, - PC_VERSION, +use crate::c_oracle_header::{ + cmd_hdr_t, + command_t_e_cmd_add_mapping, + pc_map_table_t, + PC_MAGIC, + PC_MAP_TABLE_SIZE, + PC_VERSION, +}; +use crate::rust_oracle::{ + add_mapping, + clear_account, + initialize_mapping_account, + load_account_as_mut, + load_mapping_account_mut, + pubkey_assign, +}; +use bytemuck::bytes_of; +use solana_program::account_info::AccountInfo; +use solana_program::clock::Epoch; +use solana_program::native_token::LAMPORTS_PER_SOL; +use solana_program::program_error::ProgramError; +use solana_program::pubkey::Pubkey; +use solana_program::rent::Rent; +use solana_program::system_program; +use std::mem::size_of; + +#[test] +fn test_add_mapping() { + let hdr: cmd_hdr_t = cmd_hdr_t { + ver_: PC_VERSION, + cmd_: command_t_e_cmd_add_mapping as i32, }; - use crate::rust_oracle::{ - add_mapping, - clear_account, - initialize_mapping_account, - load_account_as_mut, - load_mapping_account_mut, - pubkey_assign, - }; - use bytemuck::bytes_of; - use solana_program::account_info::AccountInfo; - use solana_program::clock::Epoch; - use solana_program::native_token::LAMPORTS_PER_SOL; - use solana_program::program_error::ProgramError; - use solana_program::pubkey::Pubkey; - use solana_program::rent::Rent; - use solana_program::system_program; - use std::mem::size_of; - - #[test] - fn test_add_mapping() { - let hdr: cmd_hdr_t = cmd_hdr_t { - ver_: PC_VERSION, - cmd_: command_t_e_cmd_add_mapping as i32, - }; - let instruction_data = bytes_of::(&hdr); - - let program_id = Pubkey::new_unique(); - let funding_key = Pubkey::new_unique(); - let cur_mapping_key = Pubkey::new_unique(); - let next_mapping_key = Pubkey::new_unique(); - let system_program = system_program::id(); - - let mut funding_balance = LAMPORTS_PER_SOL.clone(); - let funding_account = AccountInfo::new( - &funding_key, - true, - true, - &mut funding_balance, - &mut [], - &system_program, - false, - Epoch::default(), - ); - - let mut cur_mapping_balance = - Rent::minimum_balance(&Rent::default(), size_of::()); - let mut cur_mapping_raw_data = [0u8; size_of::()]; - - let cur_mapping = AccountInfo::new( - &cur_mapping_key, - true, - true, - &mut cur_mapping_balance, - &mut cur_mapping_raw_data, - &program_id, - false, - Epoch::default(), - ); - - initialize_mapping_account(&cur_mapping, PC_VERSION).unwrap(); - - { - let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); - cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; - } - - let mut next_mapping_balance = - Rent::minimum_balance(&Rent::default(), size_of::()); - let mut next_mapping_raw_data = [0u8; size_of::()]; - - let next_mapping = AccountInfo::new( - &next_mapping_key, - true, - true, - &mut next_mapping_balance, - &mut next_mapping_raw_data, - &program_id, - false, - Epoch::default(), - ); + let instruction_data = bytes_of::(&hdr); + + let program_id = Pubkey::new_unique(); + let funding_key = Pubkey::new_unique(); + let cur_mapping_key = Pubkey::new_unique(); + let next_mapping_key = Pubkey::new_unique(); + let system_program = system_program::id(); + + let mut funding_balance = LAMPORTS_PER_SOL.clone(); + let funding_account = AccountInfo::new( + &funding_key, + true, + true, + &mut funding_balance, + &mut [], + &system_program, + false, + Epoch::default(), + ); + + let mut cur_mapping_balance = + Rent::minimum_balance(&Rent::default(), size_of::()); + let mut cur_mapping_raw_data = [0u8; size_of::()]; + + let cur_mapping = AccountInfo::new( + &cur_mapping_key, + true, + true, + &mut cur_mapping_balance, + &mut cur_mapping_raw_data, + &program_id, + false, + Epoch::default(), + ); + + initialize_mapping_account(&cur_mapping, PC_VERSION).unwrap(); + + { + let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); + cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; + } + + let mut next_mapping_balance = + Rent::minimum_balance(&Rent::default(), size_of::()); + let mut next_mapping_raw_data = [0u8; size_of::()]; + + let next_mapping = AccountInfo::new( + &next_mapping_key, + true, + true, + &mut next_mapping_balance, + &mut next_mapping_raw_data, + &program_id, + false, + Epoch::default(), + ); + + assert!(add_mapping( + &program_id, + &[ + funding_account.clone(), + cur_mapping.clone(), + next_mapping.clone() + ], + instruction_data + ) + .is_ok()); + + { + let next_mapping_data = load_mapping_account_mut(&next_mapping, PC_VERSION).unwrap(); + let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); + + assert!(unsafe { + cur_mapping_data + .next_ + .k1_ + .iter() + .zip(&next_mapping_key.to_bytes()) + .all(|(x, y)| *x == *y) + }); + assert!(unsafe { next_mapping_data.next_.k8_.iter().all(|x| *x == 0) }); + pubkey_assign(&mut cur_mapping_data.next_, &Pubkey::default().to_bytes()); + cur_mapping_data.num_ = 0; + } - assert!(add_mapping( + clear_account(&next_mapping).unwrap(); + + assert_eq!( + add_mapping( &program_id, &[ funding_account.clone(), @@ -96,67 +126,19 @@ mod test { next_mapping.clone() ], instruction_data - ) - .is_ok()); - - { - let next_mapping_data = load_mapping_account_mut(&next_mapping, PC_VERSION).unwrap(); - let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); - - assert!(unsafe { - cur_mapping_data - .next_ - .k1_ - .iter() - .zip(&next_mapping_key.to_bytes()) - .all(|(x, y)| *x == *y) - }); - assert!(unsafe { next_mapping_data.next_.k8_.iter().all(|x| *x == 0) }); - pubkey_assign(&mut cur_mapping_data.next_, &Pubkey::default().to_bytes()); - cur_mapping_data.num_ = 0; - } - - clear_account(&next_mapping).unwrap(); - - assert_eq!( - add_mapping( - &program_id, - &[ - funding_account.clone(), - cur_mapping.clone(), - next_mapping.clone() - ], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - { - let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); - assert!(unsafe { cur_mapping_data.next_.k8_.iter().all(|x| *x == 0) }); - cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; - cur_mapping_data.magic_ = 0; - } - - assert_eq!( - add_mapping( - &program_id, - &[ - funding_account.clone(), - cur_mapping.clone(), - next_mapping.clone() - ], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - { - let mut cur_mapping_data = load_account_as_mut::(&cur_mapping).unwrap(); - cur_mapping_data.magic_ = PC_MAGIC; - } - - assert!(add_mapping( + ), + Err(ProgramError::InvalidArgument) + ); + + { + let mut cur_mapping_data = load_mapping_account_mut(&cur_mapping, PC_VERSION).unwrap(); + assert!(unsafe { cur_mapping_data.next_.k8_.iter().all(|x| *x == 0) }); + cur_mapping_data.num_ = PC_MAP_TABLE_SIZE; + cur_mapping_data.magic_ = 0; + } + + assert_eq!( + add_mapping( &program_id, &[ funding_account.clone(), @@ -164,7 +146,23 @@ mod test { next_mapping.clone() ], instruction_data - ) - .is_ok()); + ), + Err(ProgramError::InvalidArgument) + ); + + { + let mut cur_mapping_data = load_account_as_mut::(&cur_mapping).unwrap(); + cur_mapping_data.magic_ = PC_MAGIC; } + + assert!(add_mapping( + &program_id, + &[ + funding_account.clone(), + cur_mapping.clone(), + next_mapping.clone() + ], + instruction_data + ) + .is_ok()); } diff --git a/program/rust/src/tests/test_init_mapping.rs b/program/rust/src/tests/test_init_mapping.rs index 0e313cc49..079615f21 100644 --- a/program/rust/src/tests/test_init_mapping.rs +++ b/program/rust/src/tests/test_init_mapping.rs @@ -1,182 +1,178 @@ -#[cfg(test)] -mod test { - use crate::c_oracle_header::{ - cmd_hdr_t, - command_t_e_cmd_init_mapping, - pc_map_table_t, - PC_ACCTYPE_MAPPING, - PC_MAGIC, - PC_VERSION, +use crate::c_oracle_header::{ + cmd_hdr_t, + command_t_e_cmd_init_mapping, + pc_map_table_t, + PC_ACCTYPE_MAPPING, + PC_MAGIC, + PC_VERSION, +}; +use crate::rust_oracle::{ + clear_account, + init_mapping, + load_account_as, +}; +use bytemuck::bytes_of; +use solana_program::account_info::AccountInfo; +use solana_program::clock::Epoch; +use solana_program::native_token::LAMPORTS_PER_SOL; +use solana_program::program_error::ProgramError; +use solana_program::pubkey::Pubkey; +use solana_program::rent::Rent; +use solana_program::system_program; +use std::cell::RefCell; +use std::mem::size_of; +use std::rc::Rc; + +#[test] +fn test_init_mapping() { + let hdr: cmd_hdr_t = cmd_hdr_t { + ver_: PC_VERSION, + cmd_: command_t_e_cmd_init_mapping as i32, }; - use crate::rust_oracle::{ - clear_account, - init_mapping, - load_account_as, - }; - use bytemuck::bytes_of; - use solana_program::account_info::AccountInfo; - use solana_program::clock::Epoch; - use solana_program::native_token::LAMPORTS_PER_SOL; - use solana_program::program_error::ProgramError; - use solana_program::pubkey::Pubkey; - use solana_program::rent::Rent; - use solana_program::system_program; - use std::cell::RefCell; - use std::mem::size_of; - use std::rc::Rc; - - #[test] - fn test_init_mapping() { - let hdr: cmd_hdr_t = cmd_hdr_t { - ver_: PC_VERSION, - cmd_: command_t_e_cmd_init_mapping as i32, - }; - let instruction_data = bytes_of::(&hdr); - - let program_id = Pubkey::new_unique(); - let program_id_2 = Pubkey::new_unique(); - let funding_key = Pubkey::new_unique(); - let mapping_key = Pubkey::new_unique(); - let system_program = system_program::id(); - - let mut funding_balance = LAMPORTS_PER_SOL.clone(); - let mut funding_account = AccountInfo::new( - &funding_key, - true, - true, - &mut funding_balance, - &mut [], - &system_program, - false, - Epoch::default(), - ); - - let mut mapping_balance = - Rent::minimum_balance(&Rent::default(), size_of::()); - let mut mapping_raw_data = [0u8; size_of::()]; - - let mut mapping_account = AccountInfo::new( - &mapping_key, - true, - true, - &mut mapping_balance, - &mut mapping_raw_data, + let instruction_data = bytes_of::(&hdr); + + let program_id = Pubkey::new_unique(); + let program_id_2 = Pubkey::new_unique(); + let funding_key = Pubkey::new_unique(); + let mapping_key = Pubkey::new_unique(); + let system_program = system_program::id(); + + let mut funding_balance = LAMPORTS_PER_SOL.clone(); + let mut funding_account = AccountInfo::new( + &funding_key, + true, + true, + &mut funding_balance, + &mut [], + &system_program, + false, + Epoch::default(), + ); + + let mut mapping_balance = Rent::minimum_balance(&Rent::default(), size_of::()); + let mut mapping_raw_data = [0u8; size_of::()]; + + let mut mapping_account = AccountInfo::new( + &mapping_key, + true, + true, + &mut mapping_balance, + &mut mapping_raw_data, + &program_id, + false, + Epoch::default(), + ); + + assert!(init_mapping( + &program_id, + &[funding_account.clone(), mapping_account.clone()], + instruction_data + ) + .is_ok()); + + { + let mapping_data = load_account_as::(&mapping_account).unwrap(); + + assert_eq!(mapping_data.ver_, PC_VERSION); + assert_eq!(mapping_data.magic_, PC_MAGIC); + assert_eq!(mapping_data.type_, PC_ACCTYPE_MAPPING); + assert_eq!(mapping_data.size_, 56); + } + + assert_eq!( + init_mapping( + &program_id, + &[funding_account.clone(), mapping_account.clone()], + instruction_data + ), + Err(ProgramError::InvalidArgument) + ); + + clear_account(&mapping_account).unwrap(); + + assert_eq!( + init_mapping(&program_id, &[funding_account.clone()], instruction_data), + Err(ProgramError::InvalidArgument) + ); + + funding_account.is_signer = false; + + assert_eq!( + init_mapping( &program_id, - false, - Epoch::default(), - ); + &[funding_account.clone(), mapping_account.clone()], + instruction_data + ), + Err(ProgramError::InvalidArgument) + ); - assert!(init_mapping( + funding_account.is_signer = true; + mapping_account.is_signer = false; + + assert_eq!( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data - ) - .is_ok()); - - { - let mapping_data = load_account_as::(&mapping_account).unwrap(); - - assert_eq!(mapping_data.ver_, PC_VERSION); - assert_eq!(mapping_data.magic_, PC_MAGIC); - assert_eq!(mapping_data.type_, PC_ACCTYPE_MAPPING); - assert_eq!(mapping_data.size_, 56); - } - - assert_eq!( - init_mapping( - &program_id, - &[funding_account.clone(), mapping_account.clone()], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - clear_account(&mapping_account).unwrap(); - - assert_eq!( - init_mapping(&program_id, &[funding_account.clone()], instruction_data), - Err(ProgramError::InvalidArgument) - ); - - funding_account.is_signer = false; - - assert_eq!( - init_mapping( - &program_id, - &[funding_account.clone(), mapping_account.clone()], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - funding_account.is_signer = true; - mapping_account.is_signer = false; - - assert_eq!( - init_mapping( - &program_id, - &[funding_account.clone(), mapping_account.clone()], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - mapping_account.is_signer = true; - funding_account.is_writable = false; - - assert_eq!( - init_mapping( - &program_id, - &[funding_account.clone(), mapping_account.clone()], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - funding_account.is_writable = true; - mapping_account.is_writable = false; - - assert_eq!( - init_mapping( - &program_id, - &[funding_account.clone(), mapping_account.clone()], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - mapping_account.is_writable = true; - mapping_account.owner = &program_id_2; - - assert_eq!( - init_mapping( - &program_id, - &[funding_account.clone(), mapping_account.clone()], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - mapping_account.owner = &program_id; - let prev_data = mapping_account.data; - mapping_account.data = Rc::new(RefCell::new(&mut [])); - - assert_eq!( - init_mapping( - &program_id, - &[funding_account.clone(), mapping_account.clone()], - instruction_data - ), - Err(ProgramError::InvalidArgument) - ); - - mapping_account.data = prev_data; - - assert!(init_mapping( + ), + Err(ProgramError::InvalidArgument) + ); + + mapping_account.is_signer = true; + funding_account.is_writable = false; + + assert_eq!( + init_mapping( &program_id, &[funding_account.clone(), mapping_account.clone()], instruction_data - ) - .is_ok()); - } + ), + Err(ProgramError::InvalidArgument) + ); + + funding_account.is_writable = true; + mapping_account.is_writable = false; + + assert_eq!( + init_mapping( + &program_id, + &[funding_account.clone(), mapping_account.clone()], + instruction_data + ), + Err(ProgramError::InvalidArgument) + ); + + mapping_account.is_writable = true; + mapping_account.owner = &program_id_2; + + assert_eq!( + init_mapping( + &program_id, + &[funding_account.clone(), mapping_account.clone()], + instruction_data + ), + Err(ProgramError::InvalidArgument) + ); + + mapping_account.owner = &program_id; + let prev_data = mapping_account.data; + mapping_account.data = Rc::new(RefCell::new(&mut [])); + + assert_eq!( + init_mapping( + &program_id, + &[funding_account.clone(), mapping_account.clone()], + instruction_data + ), + Err(ProgramError::InvalidArgument) + ); + + mapping_account.data = prev_data; + + assert!(init_mapping( + &program_id, + &[funding_account.clone(), mapping_account.clone()], + instruction_data + ) + .is_ok()); } From af9a267cc350f793495a974c1344808a39d97a98 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 21:10:17 +0000 Subject: [PATCH 4/5] Public function --- program/rust/src/rust_oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 820309ef9..c6ad8567f 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -294,6 +294,6 @@ fn load_product_account_mut<'a>( } // Assign pubkey bytes from source to target, fails if source is not 32 bytes -fn pubkey_assign(target: &mut pc_pub_key_t, source: &[u8]) { +pub fn pubkey_assign(target: &mut pc_pub_key_t, source: &[u8]) { unsafe { target.k1_.copy_from_slice(source) } } From 4f9299bda5f5d8a217c97aefcc1db5e667f4b33f Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 5 Aug 2022 21:13:25 +0000 Subject: [PATCH 5/5] Delete C add_mapping --- program/c/src/oracle/oracle.c | 42 +---------------- program/c/src/oracle/test_oracle.c | 75 ------------------------------ 2 files changed, 1 insertion(+), 116 deletions(-) diff --git a/program/c/src/oracle/oracle.c b/program/c/src/oracle/oracle.c index 09615a5a7..e91f68ed2 100644 --- a/program/c/src/oracle/oracle.c +++ b/program/c/src/oracle/oracle.c @@ -59,46 +59,6 @@ static bool valid_writable_account( SolParameters *prm, is_rent_exempt( *ka->lamports, ka->data_len ); } -static uint64_t add_mapping( SolParameters *prm, SolAccountInfo *ka ) -{ - // Account (1) is the tail or last mapping account in the chain - // Account (2) is the new mapping account and will become the new tail - // Verify that these are signed, writable accounts with correct ownership - // and size - if ( prm->ka_num != 3 || - !valid_funding_account( &ka[0] ) || - !valid_signable_account( prm, &ka[1], sizeof( pc_map_table_t ) ) || - !valid_signable_account( prm, &ka[2], sizeof( pc_map_table_t ) ) ) { - return ERROR_INVALID_ARGUMENT; - } - // Verify that last mapping account in chain is initialized, full - // and not pointing to a another account in the chain - // Also verify that the new account is uninitialized - cmd_hdr_t *hdr = (cmd_hdr_t*)prm->data; - pc_map_table_t *pptr = (pc_map_table_t*)ka[1].data; - pc_map_table_t *nptr = (pc_map_table_t*)ka[2].data; - if ( pptr->magic_ != PC_MAGIC || - pptr->ver_ != hdr->ver_ || - pptr->type_ != PC_ACCTYPE_MAPPING || - nptr->magic_ != 0 || - pptr->num_ < PC_MAP_TABLE_SIZE || - nptr->num_ != 0 || - !pc_pub_key_is_zero( &pptr->next_ ) ) { - return ERROR_INVALID_ARGUMENT; - } - // Initialize new account and set version number - sol_memset( nptr, 0, sizeof( pc_map_table_t ) ); - nptr->magic_ = PC_MAGIC; - nptr->ver_ = hdr->ver_; - nptr->type_ = PC_ACCTYPE_MAPPING; - nptr->size_ = sizeof( pc_map_table_t ) - sizeof( nptr->prod_ ); - - // Set last mapping account to point to this mapping account - pc_pub_key_t *nkey = (pc_pub_key_t*)ka[2].key; - pc_pub_key_assign( &pptr->next_, nkey ); - return SUCCESS; -} - static uint64_t add_product( SolParameters *prm, SolAccountInfo *ka ) { // Account (1) is the mapping account that we're going to add to and @@ -513,7 +473,7 @@ static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka ) case e_cmd_upd_price_no_fail_on_error: return upd_price_no_fail_on_error( prm, ka ); // init_mapping is overridden in Rust, but still implemented here to make the C unit tests pass. case e_cmd_init_mapping: return ERROR_INVALID_ARGUMENT; - case e_cmd_add_mapping: return add_mapping( prm, ka ); + case e_cmd_add_mapping: return ERROR_INVALID_ARGUMENT; case e_cmd_add_product: return add_product( prm, ka ); case e_cmd_upd_product: return upd_product( prm, ka ); case e_cmd_add_price: return add_price( prm, ka ); diff --git a/program/c/src/oracle/test_oracle.c b/program/c/src/oracle/test_oracle.c index 8076ae83e..c879b7e23 100644 --- a/program/c/src/oracle/test_oracle.c +++ b/program/c/src/oracle/test_oracle.c @@ -7,81 +7,6 @@ uint64_t MAPPING_ACCOUNT_LAMPORTS = 143821440; uint64_t PRODUCT_ACCOUNT_LAMPORTS = 4454400; uint64_t PRICE_ACCOUNT_LAMPORTS = 23942400; -Test(oracle, add_mapping ) { - // start with perfect inputs - cmd_hdr_t idata = { - .ver_ = PC_VERSION, - .cmd_ = e_cmd_add_mapping - }; - pc_map_table_t tptr[1]; - sol_memset( tptr, 0, sizeof( pc_map_table_t ) ); - tptr->magic_ = PC_MAGIC; - tptr->ver_ = PC_VERSION; - tptr->num_ = PC_MAP_TABLE_SIZE; - tptr->type_ = PC_ACCTYPE_MAPPING; - - SolPubkey p_id = {.x = { 0xff, }}; - SolPubkey pkey = {.x = { 1, }}; - SolPubkey tkey = {.x = { 2, }}; - SolPubkey mkey = {.x = { 3, }}; - uint64_t pqty = 100; - pc_map_table_t mptr[1]; - sol_memset( mptr, 0, sizeof( pc_map_table_t ) ); - SolAccountInfo acc[] = {{ - .key = &pkey, - .lamports = &pqty, - .data_len = 0, - .data = NULL, - .owner = NULL, - .rent_epoch = 0, - .is_signer = true, - .is_writable = true, - .executable = false - },{ - .key = &tkey, - .lamports = &MAPPING_ACCOUNT_LAMPORTS, - .data_len = sizeof( pc_map_table_t ), - .data = (uint8_t*)tptr, - .owner = &p_id, - .rent_epoch = 0, - .is_signer = true, - .is_writable = true, - .executable = false - },{ - .key = &mkey, - .lamports = &MAPPING_ACCOUNT_LAMPORTS, - .data_len = sizeof( pc_map_table_t ), - .data = (uint8_t*)mptr, - .owner = &p_id, - .rent_epoch = 0, - .is_signer = true, - .is_writable = true, - .executable = false - }}; - SolParameters prm = { - .ka = acc, - .ka_num = 3, - .data = (const uint8_t*)&idata, - .data_len = sizeof( idata ), - .program_id = &p_id - }; - cr_assert( SUCCESS == dispatch( &prm, acc ) ); - cr_assert( mptr->magic_ == PC_MAGIC ); - cr_assert( mptr->ver_ == PC_VERSION ); - cr_assert( pc_pub_key_equal( &tptr->next_, (pc_pub_key_t*)&mkey ) ); - cr_assert( pc_pub_key_is_zero( &mptr->next_ ) ); - pc_pub_key_set_zero( &tptr->next_ ); - sol_memset( mptr, 0, sizeof( pc_map_table_t ) ); - tptr->num_ = 0; - cr_assert( ERROR_INVALID_ARGUMENT == dispatch( &prm, acc ) ); - cr_assert( pc_pub_key_is_zero( &tptr->next_ ) ); - tptr->num_ = PC_MAP_TABLE_SIZE; - tptr->magic_ = 0; - cr_assert( ERROR_INVALID_ARGUMENT == dispatch( &prm, acc ) ); - tptr->magic_ = PC_MAGIC; - cr_assert( SUCCESS == dispatch( &prm, acc ) ); -} - Test(oracle, add_product) { // start with perfect inputs cmd_add_product_t idata = {