1- use std:: borrow:: BorrowMut ;
2- use std:: cell:: RefMut ;
31use std:: mem:: {
42 size_of,
53 size_of_val,
@@ -34,33 +32,42 @@ use crate::c_oracle_header::{
3432 cmd_init_price_t,
3533 cmd_set_min_pub_t,
3634 cmd_upd_product_t,
37- pc_acc,
3835 pc_ema_t,
3936 pc_map_table_t,
4037 pc_price_comp,
4138 pc_price_info_t,
4239 pc_price_t,
4340 pc_prod_t,
4441 pc_pub_key_t,
45- PythAccount ,
4642 PC_COMP_SIZE ,
47- PC_MAGIC ,
4843 PC_MAP_TABLE_SIZE ,
49- PC_MAX_NUM_DECIMALS ,
5044 PC_PROD_ACC_SIZE ,
5145 PC_PTYPE_UNKNOWN ,
5246 PC_VERSION ,
5347 SUCCESSFULLY_UPDATED_AGGREGATE ,
5448} ;
5549use crate :: deserialize:: {
50+ initialize_pyth_account_checked, /* TODO: This has a confusingly similar name to a Solana
51+ * sdk function */
5652 load,
57- load_account_as,
5853 load_account_as_mut,
54+ load_checked,
5955} ;
6056use crate :: error:: OracleResult ;
6157use crate :: OracleError ;
6258
63- use crate :: utils:: pyth_assert;
59+ use crate :: utils:: {
60+ check_exponent_range,
61+ check_valid_fresh_account,
62+ check_valid_funding_account,
63+ check_valid_signable_account,
64+ pubkey_assign,
65+ pubkey_equal,
66+ pubkey_is_zero,
67+ pyth_assert,
68+ read_pc_str_t,
69+ try_convert,
70+ } ;
6471
6572use super :: c_entrypoint_wrapper;
6673const PRICE_T_SIZE : usize = size_of :: < pc_price_t > ( ) ;
@@ -187,7 +194,7 @@ pub fn init_mapping(
187194
188195 // Initialize by setting to zero again (just in case) and populating the account header
189196 let hdr = load :: < cmd_hdr_t > ( instruction_data) ?;
190- initialize_checked :: < pc_map_table_t > ( fresh_mapping_account, hdr. ver_ ) ?;
197+ initialize_pyth_account_checked :: < pc_map_table_t > ( fresh_mapping_account, hdr. ver_ ) ?;
191198
192199 Ok ( SUCCESS )
193200}
@@ -214,7 +221,7 @@ pub fn add_mapping(
214221 ProgramError :: InvalidArgument ,
215222 ) ?;
216223
217- initialize_checked :: < pc_map_table_t > ( next_mapping, hdr. ver_ ) ?;
224+ initialize_pyth_account_checked :: < pc_map_table_t > ( next_mapping, hdr. ver_ ) ?;
218225 pubkey_assign ( & mut cur_mapping. next_ , & next_mapping. key . to_bytes ( ) ) ;
219226
220227 Ok ( SUCCESS )
@@ -250,7 +257,8 @@ pub fn add_price(
250257
251258 let mut product_data = load_checked :: < pc_prod_t > ( product_account, cmd_args. ver_ ) ?;
252259
253- let mut price_data = initialize_checked :: < pc_price_t > ( price_account, cmd_args. ver_ ) ?;
260+ let mut price_data =
261+ initialize_pyth_account_checked :: < pc_price_t > ( price_account, cmd_args. ver_ ) ?;
254262 price_data. expo_ = cmd_args. expo_ ;
255263 price_data. ptype_ = cmd_args. ptype_ ;
256264 pubkey_assign ( & mut price_data. prod_ , & product_account. key . to_bytes ( ) ) ;
@@ -450,7 +458,7 @@ pub fn add_product(
450458 ProgramError :: InvalidArgument ,
451459 ) ?;
452460
453- initialize_checked :: < pc_prod_t > ( new_product_account, hdr. ver_ ) ?;
461+ initialize_pyth_account_checked :: < pc_prod_t > ( new_product_account, hdr. ver_ ) ?;
454462
455463 let current_index: usize = try_convert ( mapping_data. num_ ) ?;
456464 pubkey_assign (
@@ -550,136 +558,3 @@ pub fn set_min_pub(
550558
551559 Ok ( SUCCESS )
552560}
553-
554- fn valid_funding_account ( account : & AccountInfo ) -> bool {
555- account. is_signer && account. is_writable
556- }
557-
558- fn check_valid_funding_account ( account : & AccountInfo ) -> Result < ( ) , ProgramError > {
559- pyth_assert (
560- valid_funding_account ( account) ,
561- OracleError :: InvalidFundingAccount . into ( ) ,
562- )
563- }
564-
565- fn valid_signable_account ( program_id : & Pubkey , account : & AccountInfo , minimum_size : usize ) -> bool {
566- account. is_signer
567- && account. is_writable
568- && account. owner == program_id
569- && account. data_len ( ) >= minimum_size
570- && Rent :: default ( ) . is_exempt ( account. lamports ( ) , account. data_len ( ) )
571- }
572-
573- fn check_valid_signable_account (
574- program_id : & Pubkey ,
575- account : & AccountInfo ,
576- minimum_size : usize ,
577- ) -> Result < ( ) , ProgramError > {
578- pyth_assert (
579- valid_signable_account ( program_id, account, minimum_size) ,
580- OracleError :: InvalidSignableAccount . into ( ) ,
581- )
582- }
583-
584- /// Returns `true` if the `account` is fresh, i.e., its data can be overwritten.
585- /// Use this check to prevent accidentally overwriting accounts whose data is already populated.
586- fn valid_fresh_account ( account : & AccountInfo ) -> bool {
587- let pyth_acc = load_account_as :: < pc_acc > ( account) ;
588- match pyth_acc {
589- Ok ( pyth_acc) => pyth_acc. magic_ == 0 && pyth_acc. ver_ == 0 ,
590- Err ( _) => false ,
591- }
592- }
593-
594- fn check_valid_fresh_account ( account : & AccountInfo ) -> Result < ( ) , ProgramError > {
595- pyth_assert (
596- valid_fresh_account ( account) ,
597- OracleError :: InvalidFreshAccount . into ( ) ,
598- )
599- }
600-
601- // Check that an exponent is within the range of permitted exponents for price accounts.
602- fn check_exponent_range ( expo : i32 ) -> Result < ( ) , ProgramError > {
603- pyth_assert (
604- expo >= -( PC_MAX_NUM_DECIMALS as i32 ) && expo <= PC_MAX_NUM_DECIMALS as i32 ,
605- ProgramError :: InvalidArgument ,
606- )
607- }
608-
609- /// Sets the data of account to all-zero
610- pub fn clear_account ( account : & AccountInfo ) -> Result < ( ) , ProgramError > {
611- let mut data = account
612- . try_borrow_mut_data ( )
613- . map_err ( |_| ProgramError :: InvalidArgument ) ?;
614- let length = data. len ( ) ;
615- sol_memset ( data. borrow_mut ( ) , 0 , length) ;
616- Ok ( ( ) )
617- }
618-
619- pub fn load_checked < ' a , T : PythAccount > (
620- account : & ' a AccountInfo ,
621- version : u32 ,
622- ) -> Result < RefMut < ' a , T > , ProgramError > {
623- {
624- let account_header = load_account_as :: < pc_acc > ( account) ?;
625- pyth_assert (
626- account_header. magic_ == PC_MAGIC
627- && account_header. ver_ == version
628- && account_header. type_ == T :: ACCOUNT_TYPE ,
629- ProgramError :: InvalidArgument ,
630- ) ?;
631- }
632-
633- load_account_as_mut :: < T > ( account)
634- }
635-
636- pub fn initialize_checked < ' a , T : PythAccount > (
637- account : & ' a AccountInfo ,
638- version : u32 ,
639- ) -> Result < RefMut < ' a , T > , ProgramError > {
640- clear_account ( account) ?;
641-
642- {
643- let mut account_header = load_account_as_mut :: < pc_acc > ( account) ?;
644- account_header. magic_ = PC_MAGIC ;
645- account_header. ver_ = version;
646- account_header. type_ = T :: ACCOUNT_TYPE ;
647- account_header. size_ = T :: INITIAL_SIZE ;
648- }
649-
650- load_account_as_mut :: < T > ( account)
651- }
652-
653- // Assign pubkey bytes from source to target, fails if source is not 32 bytes
654- pub fn pubkey_assign ( target : & mut pc_pub_key_t , source : & [ u8 ] ) {
655- unsafe { target. k1_ . copy_from_slice ( source) }
656- }
657-
658- pub fn pubkey_is_zero ( key : & pc_pub_key_t ) -> bool {
659- return unsafe { key. k8_ . iter ( ) . all ( |x| * x == 0 ) } ;
660- }
661-
662- pub fn pubkey_equal ( target : & pc_pub_key_t , source : & [ u8 ] ) -> bool {
663- unsafe { target. k1_ == * source }
664- }
665-
666- /// Convert `x: T` into a `U`, returning the appropriate `OracleError` if the conversion fails.
667- pub fn try_convert < T , U : TryFrom < T > > ( x : T ) -> Result < U , OracleError > {
668- // Note: the error here assumes we're only applying this function to integers right now.
669- U :: try_from ( x) . map_err ( |_| OracleError :: IntegerCastingError )
670- }
671-
672- /// Read a `pc_str_t` from the beginning of `source`. Returns a slice of `source` containing
673- /// the bytes of the `pc_str_t`.
674- pub fn read_pc_str_t ( source : & [ u8 ] ) -> Result < & [ u8 ] , ProgramError > {
675- if source. is_empty ( ) {
676- Err ( ProgramError :: InvalidArgument )
677- } else {
678- let tag_len: usize = try_convert ( source[ 0 ] ) ?;
679- if tag_len + 1 > source. len ( ) {
680- Err ( ProgramError :: InvalidArgument )
681- } else {
682- Ok ( & source[ ..( 1 + tag_len) ] )
683- }
684- }
685- }
0 commit comments