From 678c59e6f07ce338479f19fe062a52f2ef26cda5 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Fri, 23 Sep 2022 12:20:27 -0500 Subject: [PATCH 1/6] Before clippy --- program/rust/src/lib.rs | 2 - program/rust/src/rust_oracle.rs | 237 ++++++++++++++++++++++++-------- 2 files changed, 183 insertions(+), 56 deletions(-) diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 544457554..54190d79d 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,8 +1,6 @@ #![deny(warnings)] // Allow non upper case globals from C #![allow(non_upper_case_globals)] -// Allow using the solana_program::entrypoint::deserialize function -#![allow(clippy::not_unsafe_ptr_arg_deref)] mod c_oracle_header; mod deserialize; diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index d5efc9347..d7f3d5c1e 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -88,51 +88,66 @@ extern "C" { pub fn resize_price_account( program_id: &Pubkey, accounts: &[AccountInfo], - _instruction_data: &[u8], + instruction_data: &[u8], ) -> ProgramResult { - let [funding_account_info, price_account_info, system_program] = match accounts { - [x, y, z] => Ok([x, y, z]), + let (funding_account, price_account, system_program, permissions_account_option) = match accounts { + [x, y, z] => Ok((x, y, z, None)), + [x, y, z, p] => Ok((x, y, z, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; - check_valid_funding_account(funding_account_info)?; - check_valid_signable_account(program_id, price_account_info)?; + let hdr = load::(instruction_data)?; + + check_valid_funding_account(funding_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + hdr, + )?; pyth_assert( check_id(system_program.key), OracleError::InvalidSystemAccount.into(), )?; // Check that it is a valid initialized price account { - load_checked::(price_account_info, PC_VERSION)?; + load_checked::(price_account, PC_VERSION)?; } - let account_len = price_account_info.try_data_len()?; + let account_len = price_account.try_data_len()?; match account_len { PriceAccount::MINIMUM_SIZE => { // Ensure account is still rent exempt after resizing let rent: Rent = get_rent()?; let lamports_needed: u64 = rent .minimum_balance(size_of::()) - .saturating_sub(price_account_info.lamports()); + .saturating_sub(price_account.lamports()); if lamports_needed > 0 { send_lamports( - funding_account_info, - price_account_info, + funding_account, + price_account, system_program, lamports_needed, )?; } // We do not need to zero allocate because we won't access the data in the same // instruction - price_account_info.realloc(size_of::(), false)?; + price_account.realloc(size_of::(), false)?; // Check that everything is ok - check_valid_signable_account(program_id, price_account_info)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + hdr, + )?; #[cfg(test)] // Sma feature disabled except in tests { let mut price_account = - load_checked::(price_account_info, PC_VERSION)?; + load_checked::(price_account, PC_VERSION)?; // Initialize Time Machine price_account.initialize_time_machine()?; } @@ -181,16 +196,30 @@ pub fn add_mapping( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let [funding_account, cur_mapping, next_mapping] = match accounts { - [x, y, z] => Ok([x, y, z]), + let (funding_account, cur_mapping, next_mapping, permissions_account_option) = match accounts { + [x, y, z] => Ok((x, y, z, None)), + [x, y, z, p] => Ok((x, y, z, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; - check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, cur_mapping)?; - check_valid_signable_account(program_id, next_mapping)?; - let hdr = load::(instruction_data)?; + + check_valid_funding_account(funding_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + cur_mapping, + funding_account, + permissions_account_option, + hdr, + )?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + next_mapping, + funding_account, + permissions_account_option, + hdr, + )?; + let mut cur_mapping = load_checked::(cur_mapping, hdr.version)?; pyth_assert( cur_mapping.number_of_products == PC_MAP_TABLE_SIZE @@ -338,14 +367,27 @@ pub fn add_price( )?; - let [funding_account, product_account, price_account] = match accounts { - [x, y, z] => Ok([x, y, z]), + let (funding_account, product_account, price_account, permissions_account_option) = match accounts { + [x, y, z] => Ok((x, y, z, None)), + [x, y, z, p] => Ok((x, y, z, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, product_account)?; - check_valid_signable_account(program_id, price_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + product_account, + funding_account, + permissions_account_option, + &cmd_args.header, + )?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + &cmd_args.header, + )?; let mut product_data = load_checked::(product_account, cmd_args.header.version)?; @@ -373,17 +415,32 @@ pub fn del_price( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let [funding_account, product_account, price_account] = match accounts { - [w, x, y] => Ok([w, x, y]), + let (funding_account, product_account, price_account, permissions_account_option) = match accounts { + [w, x, y] => Ok((w, x, y, None)), + [w, x, y, p] => Ok((w, x, y, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; + let cmd_args = load::(instruction_data)?; + check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, product_account)?; - check_valid_signable_account(program_id, price_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + product_account, + funding_account, + permissions_account_option, + &cmd_args, + )?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + &cmd_args, + )?; { - let cmd_args = load::(instruction_data)?; + let mut product_data = load_checked::(product_account, cmd_args.version)?; let price_data = load_checked::(price_account, cmd_args.version)?; pyth_assert( @@ -418,13 +475,21 @@ pub fn init_price( check_exponent_range(cmd_args.exponent)?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), + let (funding_account, price_account, permissions_account_option) = match accounts { + [x, y] => Ok((x, y, None)), + [x, y, p] => Ok((x, y, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + &cmd_args.header, + )?; + let mut price_data = load_checked::(price_account, cmd_args.header.version)?; pyth_assert( @@ -488,13 +553,21 @@ pub fn add_publisher( ProgramError::InvalidArgument, )?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), + let (funding_account, price_account, permissions_account_option) = match accounts { + [x, y] => Ok((x, y, None)), + [x, y, p] => Ok((x, y, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + &cmd_args.header, + )?; + let mut price_data = load_checked::(price_account, cmd_args.header.version)?; @@ -538,13 +611,20 @@ pub fn del_publisher( ProgramError::InvalidArgument, )?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), + let (funding_account, price_account, permissions_account_option) = match accounts { + [x, y] => Ok((x, y, None)), + [x, y, p] => Ok((x, y, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + &cmd_args.header, + )?; let mut price_data = load_checked::(price_account, cmd_args.header.version)?; @@ -574,16 +654,31 @@ pub fn add_product( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let [funding_account, tail_mapping_account, new_product_account] = match accounts { - [x, y, z] => Ok([x, y, z]), + let (funding_account, tail_mapping_account, new_product_account, permissions_account_option) = match accounts { + [x, y, z] => Ok((x, y, z, None)), + [x, y, z, p] => Ok((x, y, z, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; + let hdr = load::(instruction_data)?; + check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, tail_mapping_account)?; - check_valid_signable_account(program_id, new_product_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + tail_mapping_account, + funding_account, + permissions_account_option, + &hdr, + )?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + new_product_account, + funding_account, + permissions_account_option, + &hdr, + )?; - let hdr = load::(instruction_data)?; + let mut mapping_data = load_checked::(tail_mapping_account, hdr.version)?; // The mapping account must have free space to add the product account pyth_assert( @@ -611,15 +706,24 @@ pub fn upd_product( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let [funding_account, product_account] = match accounts { - [x, y] => Ok([x, y]), + let (funding_account, product_account, permissions_account_option) = match accounts { + [x, y] => Ok((x, y, None)), + [x, y, p] => Ok((x, y, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; + let hdr = load::(instruction_data)?; + check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, product_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + product_account, + funding_account, + permissions_account_option, + &hdr, + )?; - let hdr = load::(instruction_data)?; + { // Validate that product_account contains the appropriate account header let mut _product_data = load_checked::(product_account, hdr.version)?; @@ -676,13 +780,21 @@ pub fn set_min_pub( ProgramError::InvalidArgument, )?; - let [funding_account, price_account] = match accounts { - [x, y] => Ok([x, y]), + let (funding_account, price_account, permissions_account_option) = match accounts { + [x, y] => Ok((x, y, None)), + [x, y, p] => Ok((x, y, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, price_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + price_account, + funding_account, + permissions_account_option, + &cmd.header, + )?; + let mut price_account_data = load_checked::(price_account, cmd.header.version)?; price_account_data.min_pub_ = cmd.minimum_publishers; @@ -702,17 +814,34 @@ pub fn del_product( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let [funding_account, mapping_account, product_account] = match accounts { - [w, x, y] => Ok([w, x, y]), + let (funding_account, mapping_account, product_account, permissions_account_option) = match accounts { + [w, x, y] => Ok((w, x, y, None)), + [w, x, y, p] => Ok((w, x, y, Some(p))), _ => Err(OracleError::InvalidNumberOfAccounts), }?; + let cmd_args = load::(instruction_data)?; + check_valid_funding_account(funding_account)?; - check_valid_signable_account(program_id, mapping_account)?; - check_valid_signable_account(program_id, product_account)?; + check_valid_signable_account_or_permissioned_funding_account( + program_id, + mapping_account, + funding_account, + permissions_account_option, + &cmd_args, + )?; + + check_valid_signable_account_or_permissioned_funding_account( + program_id, + product_account, + funding_account, + permissions_account_option, + &cmd_args, + )?; + { - let cmd_args = load::(instruction_data)?; + let mut mapping_data = load_checked::(mapping_account, cmd_args.version)?; let product_data = load_checked::(product_account, cmd_args.version)?; From ead116a74ca13d70c80d5c446e4093dcabea797e Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Fri, 23 Sep 2022 12:21:52 -0500 Subject: [PATCH 2/6] Done --- program/rust/src/rust_oracle.rs | 77 +++++++++++++++++---------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index d7f3d5c1e..0aadc3222 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -90,11 +90,12 @@ pub fn resize_price_account( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let (funding_account, price_account, system_program, permissions_account_option) = match accounts { - [x, y, z] => Ok((x, y, z, None)), - [x, y, z, p] => Ok((x, y, z, Some(p))), - _ => Err(OracleError::InvalidNumberOfAccounts), - }?; + let (funding_account, price_account, system_program, permissions_account_option) = + match accounts { + [x, y, z] => Ok((x, y, z, None)), + [x, y, z, p] => Ok((x, y, z, Some(p))), + _ => Err(OracleError::InvalidNumberOfAccounts), + }?; let hdr = load::(instruction_data)?; @@ -219,7 +220,7 @@ pub fn add_mapping( permissions_account_option, hdr, )?; - + let mut cur_mapping = load_checked::(cur_mapping, hdr.version)?; pyth_assert( cur_mapping.number_of_products == PC_MAP_TABLE_SIZE @@ -367,11 +368,12 @@ pub fn add_price( )?; - let (funding_account, product_account, price_account, permissions_account_option) = match accounts { - [x, y, z] => Ok((x, y, z, None)), - [x, y, z, p] => Ok((x, y, z, Some(p))), - _ => Err(OracleError::InvalidNumberOfAccounts), - }?; + let (funding_account, product_account, price_account, permissions_account_option) = + match accounts { + [x, y, z] => Ok((x, y, z, None)), + [x, y, z, p] => Ok((x, y, z, Some(p))), + _ => Err(OracleError::InvalidNumberOfAccounts), + }?; check_valid_funding_account(funding_account)?; check_valid_signable_account_or_permissioned_funding_account( @@ -415,11 +417,12 @@ pub fn del_price( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let (funding_account, product_account, price_account, permissions_account_option) = match accounts { - [w, x, y] => Ok((w, x, y, None)), - [w, x, y, p] => Ok((w, x, y, Some(p))), - _ => Err(OracleError::InvalidNumberOfAccounts), - }?; + let (funding_account, product_account, price_account, permissions_account_option) = + match accounts { + [w, x, y] => Ok((w, x, y, None)), + [w, x, y, p] => Ok((w, x, y, Some(p))), + _ => Err(OracleError::InvalidNumberOfAccounts), + }?; let cmd_args = load::(instruction_data)?; @@ -429,18 +432,17 @@ pub fn del_price( product_account, funding_account, permissions_account_option, - &cmd_args, + cmd_args, )?; check_valid_signable_account_or_permissioned_funding_account( program_id, price_account, funding_account, permissions_account_option, - &cmd_args, + cmd_args, )?; { - let mut product_data = load_checked::(product_account, cmd_args.version)?; let price_data = load_checked::(price_account, cmd_args.version)?; pyth_assert( @@ -654,11 +656,12 @@ pub fn add_product( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let (funding_account, tail_mapping_account, new_product_account, permissions_account_option) = match accounts { - [x, y, z] => Ok((x, y, z, None)), - [x, y, z, p] => Ok((x, y, z, Some(p))), - _ => Err(OracleError::InvalidNumberOfAccounts), - }?; + let (funding_account, tail_mapping_account, new_product_account, permissions_account_option) = + match accounts { + [x, y, z] => Ok((x, y, z, None)), + [x, y, z, p] => Ok((x, y, z, Some(p))), + _ => Err(OracleError::InvalidNumberOfAccounts), + }?; let hdr = load::(instruction_data)?; @@ -668,17 +671,17 @@ pub fn add_product( tail_mapping_account, funding_account, permissions_account_option, - &hdr, + hdr, )?; check_valid_signable_account_or_permissioned_funding_account( program_id, new_product_account, funding_account, permissions_account_option, - &hdr, + hdr, )?; - + let mut mapping_data = load_checked::(tail_mapping_account, hdr.version)?; // The mapping account must have free space to add the product account pyth_assert( @@ -720,10 +723,10 @@ pub fn upd_product( product_account, funding_account, permissions_account_option, - &hdr, + hdr, )?; - + { // Validate that product_account contains the appropriate account header let mut _product_data = load_checked::(product_account, hdr.version)?; @@ -814,11 +817,12 @@ pub fn del_product( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let (funding_account, mapping_account, product_account, permissions_account_option) = match accounts { - [w, x, y] => Ok((w, x, y, None)), - [w, x, y, p] => Ok((w, x, y, Some(p))), - _ => Err(OracleError::InvalidNumberOfAccounts), - }?; + let (funding_account, mapping_account, product_account, permissions_account_option) = + match accounts { + [w, x, y] => Ok((w, x, y, None)), + [w, x, y, p] => Ok((w, x, y, Some(p))), + _ => Err(OracleError::InvalidNumberOfAccounts), + }?; let cmd_args = load::(instruction_data)?; @@ -828,7 +832,7 @@ pub fn del_product( mapping_account, funding_account, permissions_account_option, - &cmd_args, + cmd_args, )?; check_valid_signable_account_or_permissioned_funding_account( @@ -836,12 +840,11 @@ pub fn del_product( product_account, funding_account, permissions_account_option, - &cmd_args, + cmd_args, )?; { - let mut mapping_data = load_checked::(mapping_account, cmd_args.version)?; let product_data = load_checked::(product_account, cmd_args.version)?; From 3b01b53cff409af5d839d00b546a56670ca48905 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Fri, 23 Sep 2022 12:30:07 -0500 Subject: [PATCH 3/6] Cleanup --- program/rust/src/rust_oracle.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/program/rust/src/rust_oracle.rs b/program/rust/src/rust_oracle.rs index 0aadc3222..d7f200315 100644 --- a/program/rust/src/rust_oracle.rs +++ b/program/rust/src/rust_oracle.rs @@ -43,7 +43,6 @@ use crate::utils::{ check_exponent_range, check_is_upgrade_authority_for_program, check_valid_funding_account, - check_valid_signable_account, check_valid_signable_account_or_permissioned_funding_account, check_valid_writable_account, get_rent, From fd3073a54e39b6a85a11e82f2bcbe3da00f93faa Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Fri, 23 Sep 2022 17:54:53 -0500 Subject: [PATCH 4/6] Add tests --- program/rust/src/lib.rs | 1 - program/rust/src/tests/mod.rs | 1 + .../src/tests/test_permission_migration.rs | 275 ++++++++++++++++++ 3 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 program/rust/src/tests/test_permission_migration.rs diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 54190d79d..33515757f 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,4 +1,3 @@ -#![deny(warnings)] // Allow non upper case globals from C #![allow(non_upper_case_globals)] diff --git a/program/rust/src/tests/mod.rs b/program/rust/src/tests/mod.rs index b2fa4f277..ccc02712d 100644 --- a/program/rust/src/tests/mod.rs +++ b/program/rust/src/tests/mod.rs @@ -8,6 +8,7 @@ mod test_del_product; mod test_del_publisher; mod test_init_mapping; mod test_init_price; +mod test_permission_migration; mod test_resize_account; mod test_set_min_pub; mod test_sizes; diff --git a/program/rust/src/tests/test_permission_migration.rs b/program/rust/src/tests/test_permission_migration.rs new file mode 100644 index 000000000..54f6e076c --- /dev/null +++ b/program/rust/src/tests/test_permission_migration.rs @@ -0,0 +1,275 @@ +use crate::c_oracle_header::{ + MappingAccount, + PermissionAccount, + PriceAccount, + ProductAccount, + PC_ACCTYPE_MAPPING, + PC_MAGIC, + PC_VERSION, +}; +use crate::deserialize::{ + initialize_pyth_account_checked, + load_account_as, +}; +use crate::error::OracleError; +use crate::instruction::OracleCommand::{ + AddMapping, + AddPrice, + AddProduct, + AddPublisher, + DelPrice, + DelProduct, + DelPublisher, + InitMapping, + InitPrice, + ResizePriceAccount, + SetMinPub, + UpdProduct, +}; +use crate::instruction::{ + AddPriceArgs, + AddPublisherArgs, + CommandHeader, + DelPublisherArgs, + InitPriceArgs, + SetMinPubArgs, +}; +use crate::processor::process_instruction; +use crate::tests::test_utils::AccountSetup; +use crate::utils::clear_account; +use bytemuck::bytes_of; +use solana_program::pubkey::Pubkey; +use std::cell::RefCell; +use std::rc::Rc; + +#[test] +fn test_permission_migration() { + let program_id = Pubkey::new_unique(); + + let mut permissions_setup = AccountSetup::new_permission(&program_id); + let permissions_account = permissions_setup.to_account_info(); + + let mut funding_setup = AccountSetup::new_funding(); + let funding_account = funding_setup.to_account_info(); + + let mut attacker_setup = AccountSetup::new_funding(); + let attacker_account = attacker_setup.to_account_info(); + + let mut mapping_setup = AccountSetup::new::(&program_id); + let mut mapping_account = mapping_setup.to_account_info(); + + let mut next_mapping_setup = AccountSetup::new::(&program_id); + let mut next_mapping_account = next_mapping_setup.to_account_info(); + + let mut product_setup = AccountSetup::new::(&program_id); + let mut product_account = product_setup.to_account_info(); + + let mut price_setup = AccountSetup::new::(&program_id); + let mut price_account = price_setup.to_account_info(); + + + product_account.is_signer = false; + mapping_account.is_signer = false; + price_account.is_signer = false; + next_mapping_account.is_signer = false; + + + { + let mut permissions_account_data = + initialize_pyth_account_checked::(&permissions_account, PC_VERSION) + .unwrap(); + permissions_account_data.master_authority = *funding_account.key; + } + + assert_eq!( + process_instruction( + &program_id, + &[ + attacker_account.clone(), + mapping_account.clone(), + next_mapping_account.clone(), + permissions_account.clone() + ], + bytes_of::(&AddMapping.into()) + ), + Err(OracleError::PermissionViolation.into()) + ); + + + process_instruction( + &program_id, + &[ + funding_account.clone(), + mapping_account.clone(), + permissions_account.clone(), + ], + bytes_of::(&InitMapping.into()), + ) + .unwrap(); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + mapping_account.clone(), + next_mapping_account.clone(), + permissions_account.clone() + ], + bytes_of::(&AddMapping.into()) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + mapping_account.clone(), + product_account.clone(), + permissions_account.clone() + ], + bytes_of::(&AddProduct.into()) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + product_account.clone(), + permissions_account.clone() + ], + bytes_of::(&UpdProduct.into()) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + product_account.clone(), + price_account.clone(), + permissions_account.clone() + ], + bytes_of::(&AddPriceArgs { + header: AddPrice.into(), + exponent: -8, + price_type: 1, + }) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + price_account.clone(), + permissions_account.clone() + ], + bytes_of::(&InitPriceArgs { + header: InitPrice.into(), + exponent: -8, + price_type: 1, + }) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + price_account.clone(), + permissions_account.clone() + ], + bytes_of::(&AddPublisherArgs { + header: AddPublisher.into(), + publisher: Pubkey::new_unique(), + }) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + price_account.clone(), + permissions_account.clone() + ], + bytes_of::(&DelPublisherArgs { + header: DelPublisher.into(), + publisher: Pubkey::new_unique(), + }) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + price_account.clone(), + permissions_account.clone() + ], + bytes_of::(&SetMinPubArgs { + header: SetMinPub.into(), + minimum_publishers: 3, + unused_: [0; 3], + }) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + price_account.clone(), + permissions_account.clone() + ], + bytes_of::(&ResizePriceAccount.into()) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + product_account.clone(), + price_account.clone(), + permissions_account.clone() + ], + bytes_of::(&DelPrice.into()) + ), + Err(OracleError::PermissionViolation.into()) + ); + + assert_eq!( + process_instruction( + &program_id, + &[ + funding_account.clone(), + mapping_account.clone(), + product_account.clone(), + permissions_account.clone() + ], + bytes_of::(&DelProduct.into()) + ), + Err(OracleError::PermissionViolation.into()) + ); +} From a1e87b0cb81b7fd73440c481236738caf7b55d34 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Fri, 23 Sep 2022 17:59:12 -0500 Subject: [PATCH 5/6] Reenable flag --- program/rust/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 33515757f..54190d79d 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,3 +1,4 @@ +#![deny(warnings)] // Allow non upper case globals from C #![allow(non_upper_case_globals)] From a8ede63a4d1c30f11188f7d7467b8d33eb1f04ca Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Alapont Date: Fri, 23 Sep 2022 18:06:45 -0500 Subject: [PATCH 6/6] Add tests --- program/rust/src/tests/test_permission_migration.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/program/rust/src/tests/test_permission_migration.rs b/program/rust/src/tests/test_permission_migration.rs index 54f6e076c..67c817289 100644 --- a/program/rust/src/tests/test_permission_migration.rs +++ b/program/rust/src/tests/test_permission_migration.rs @@ -3,14 +3,9 @@ use crate::c_oracle_header::{ PermissionAccount, PriceAccount, ProductAccount, - PC_ACCTYPE_MAPPING, - PC_MAGIC, PC_VERSION, }; -use crate::deserialize::{ - initialize_pyth_account_checked, - load_account_as, -}; +use crate::deserialize::initialize_pyth_account_checked; use crate::error::OracleError; use crate::instruction::OracleCommand::{ AddMapping, @@ -36,11 +31,8 @@ use crate::instruction::{ }; use crate::processor::process_instruction; use crate::tests::test_utils::AccountSetup; -use crate::utils::clear_account; use bytemuck::bytes_of; use solana_program::pubkey::Pubkey; -use std::cell::RefCell; -use std::rc::Rc; #[test] fn test_permission_migration() { @@ -238,6 +230,7 @@ fn test_permission_migration() { &[ funding_account.clone(), price_account.clone(), + price_account.clone(), // Mock system program permissions_account.clone() ], bytes_of::(&ResizePriceAccount.into())