From 3295f196446b35aaf4763314f613f23002563828 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Mon, 13 May 2024 17:23:17 +0200 Subject: [PATCH 1/2] refactor: optimize some checks on upd_price - Remove rent check on hot code path because it costs 500CU and add/remove instructions take care of it. - Use abs() on checking confidence threshold because it's incredibly slow on negative prices (2000CU). We don't have negative prices but will guard us in the future. --- program/rust/src/processor/upd_price.rs | 4 ++-- program/rust/src/utils.rs | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/program/rust/src/processor/upd_price.rs b/program/rust/src/processor/upd_price.rs index 5e62f241..2cb43a96 100644 --- a/program/rust/src/processor/upd_price.rs +++ b/program/rust/src/processor/upd_price.rs @@ -13,7 +13,7 @@ use { instruction::UpdPriceArgs, utils::{ check_valid_funding_account, - check_valid_writable_account, + check_valid_writable_account_without_rent_check, get_status_for_conf_price_ratio, is_component_update, pyth_assert, @@ -123,7 +123,7 @@ pub fn upd_price( }?; check_valid_funding_account(funding_account)?; - check_valid_writable_account(program_id, price_account)?; + check_valid_writable_account_without_rent_check(program_id, price_account)?; // Check clock let clock = Clock::from_account_info(clock_account)?; diff --git a/program/rust/src/utils.rs b/program/rust/src/utils.rs index 2f5d41e9..660d136c 100644 --- a/program/rust/src/utils.rs +++ b/program/rust/src/utils.rs @@ -130,6 +130,16 @@ pub fn check_valid_writable_account( ) } +pub fn check_valid_writable_account_without_rent_check( + program_id: &Pubkey, + account: &AccountInfo, +) -> Result<(), ProgramError> { + pyth_assert( + account.is_writable && account.owner == program_id, + OracleError::InvalidWritableAccount.into(), + ) +} + fn valid_readable_account( program_id: &Pubkey, account: &AccountInfo, @@ -180,11 +190,7 @@ pub fn get_status_for_conf_price_ratio( confidence: u64, status: u32, ) -> Result { - let mut threshold_conf = price / MAX_CI_DIVISOR; - - if threshold_conf < 0 { - threshold_conf = -threshold_conf; - } + let threshold_conf = price.abs() / MAX_CI_DIVISOR; if confidence > try_convert::<_, u64>(threshold_conf)? { Ok(PC_STATUS_IGNORED) From 2996b13299ee43f9d9cf9354d88b5c73756d084c Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Mon, 13 May 2024 20:33:55 +0200 Subject: [PATCH 2/2] fix: remove rent check everywhere --- program/rust/src/processor/upd_price.rs | 4 ++-- program/rust/src/tests/test_add_publisher.rs | 16 +--------------- program/rust/src/utils.rs | 19 ++----------------- 3 files changed, 5 insertions(+), 34 deletions(-) diff --git a/program/rust/src/processor/upd_price.rs b/program/rust/src/processor/upd_price.rs index 2cb43a96..5e62f241 100644 --- a/program/rust/src/processor/upd_price.rs +++ b/program/rust/src/processor/upd_price.rs @@ -13,7 +13,7 @@ use { instruction::UpdPriceArgs, utils::{ check_valid_funding_account, - check_valid_writable_account_without_rent_check, + check_valid_writable_account, get_status_for_conf_price_ratio, is_component_update, pyth_assert, @@ -123,7 +123,7 @@ pub fn upd_price( }?; check_valid_funding_account(funding_account)?; - check_valid_writable_account_without_rent_check(program_id, price_account)?; + check_valid_writable_account(program_id, price_account)?; // Check clock let clock = Clock::from_account_info(clock_account)?; diff --git a/program/rust/src/tests/test_add_publisher.rs b/program/rust/src/tests/test_add_publisher.rs index cc7b3c90..1b793cd6 100644 --- a/program/rust/src/tests/test_add_publisher.rs +++ b/program/rust/src/tests/test_add_publisher.rs @@ -58,21 +58,7 @@ fn test_add_publisher() { permissions_account_data.security_authority = *funding_account.key; } - // Expect the instruction to fail, because the price account isn't rent exempt - assert_eq!( - process_instruction( - &program_id, - &[ - funding_account.clone(), - price_account.clone(), - permissions_account.clone(), - ], - instruction_data - ), - Err(OracleError::InvalidWritableAccount.into()) - ); - - // Now give the price account enough lamports to be rent exempt + // Give the price account enough lamports to be rent exempt **price_account.try_borrow_mut_lamports().unwrap() = Rent::minimum_balance(&Rent::default(), PriceAccount::MINIMUM_SIZE); diff --git a/program/rust/src/utils.rs b/program/rust/src/utils.rs index 660d136c..97ef9b53 100644 --- a/program/rust/src/utils.rs +++ b/program/rust/src/utils.rs @@ -115,9 +115,7 @@ fn valid_writable_account( program_id: &Pubkey, account: &AccountInfo, ) -> Result { - Ok(account.is_writable - && account.owner == program_id - && get_rent()?.is_exempt(account.lamports(), account.data_len())) + Ok(account.is_writable && account.owner == program_id) } pub fn check_valid_writable_account( @@ -130,24 +128,11 @@ pub fn check_valid_writable_account( ) } -pub fn check_valid_writable_account_without_rent_check( - program_id: &Pubkey, - account: &AccountInfo, -) -> Result<(), ProgramError> { - pyth_assert( - account.is_writable && account.owner == program_id, - OracleError::InvalidWritableAccount.into(), - ) -} - fn valid_readable_account( program_id: &Pubkey, account: &AccountInfo, ) -> Result { - Ok( - account.owner == program_id - && get_rent()?.is_exempt(account.lamports(), account.data_len()), - ) + Ok(account.owner == program_id) } pub fn check_valid_readable_account(