@@ -32,9 +32,7 @@ use crate::c_oracle_header::{
3232 pc_price_t,
3333 pc_prod_t,
3434 pc_pub_key_t,
35- PC_ACCTYPE_MAPPING ,
36- PC_ACCTYPE_PRICE ,
37- PC_ACCTYPE_PRODUCT ,
35+ PythAccount ,
3836 PC_COMP_SIZE ,
3937 PC_MAGIC ,
4038 PC_MAP_TABLE_SIZE ,
@@ -95,7 +93,7 @@ pub fn init_mapping(
9593
9694 // Initialize by setting to zero again (just in case) and populating the account header
9795 let hdr = load :: < cmd_hdr_t > ( instruction_data) ?;
98- initialize_mapping_account ( fresh_mapping_account, hdr. ver_ ) ?;
96+ initialize_checked :: < pc_map_table_t > ( fresh_mapping_account, hdr. ver_ ) ?;
9997
10098 Ok ( SUCCESS )
10199}
@@ -116,13 +114,13 @@ pub fn add_mapping(
116114 check_valid_fresh_account ( next_mapping) ?;
117115
118116 let hdr = load :: < cmd_hdr_t > ( instruction_data) ?;
119- let mut cur_mapping = load_mapping_account_mut ( cur_mapping, hdr. ver_ ) ?;
117+ let mut cur_mapping = load_checked :: < pc_map_table_t > ( cur_mapping, hdr. ver_ ) ?;
120118 pyth_assert (
121119 cur_mapping. num_ == PC_MAP_TABLE_SIZE && pubkey_is_zero ( & cur_mapping. next_ ) ,
122120 ProgramError :: InvalidArgument ,
123121 ) ?;
124122
125- initialize_mapping_account ( next_mapping, hdr. ver_ ) ?;
123+ initialize_checked :: < pc_map_table_t > ( next_mapping, hdr. ver_ ) ?;
126124 pubkey_assign ( & mut cur_mapping. next_ , & next_mapping. key . to_bytes ( ) ) ;
127125
128126 Ok ( SUCCESS )
@@ -156,15 +154,9 @@ pub fn add_price(
156154 check_valid_signable_account ( program_id, price_account, size_of :: < pc_price_t > ( ) ) ?;
157155 check_valid_fresh_account ( price_account) ?;
158156
159- let mut product_data = load_product_account_mut ( product_account, cmd_args. ver_ ) ?;
157+ let mut product_data = load_checked :: < pc_prod_t > ( product_account, cmd_args. ver_ ) ?;
160158
161- clear_account ( price_account) ?;
162-
163- let mut price_data = load_account_as_mut :: < pc_price_t > ( price_account) ?;
164- price_data. magic_ = PC_MAGIC ;
165- price_data. ver_ = cmd_args. ver_ ;
166- price_data. type_ = PC_ACCTYPE_PRICE ;
167- price_data. size_ = ( size_of :: < pc_price_t > ( ) - size_of_val ( & price_data. comp_ ) ) as u32 ;
159+ let mut price_data = initialize_checked :: < pc_price_t > ( price_account, cmd_args. ver_ ) ?;
168160 price_data. expo_ = cmd_args. expo_ ;
169161 price_data. ptype_ = cmd_args. ptype_ ;
170162 pubkey_assign ( & mut price_data. prod_ , & product_account. key . to_bytes ( ) ) ;
@@ -198,7 +190,7 @@ pub fn add_publisher(
198190 check_valid_funding_account ( funding_account) ?;
199191 check_valid_signable_account ( program_id, price_account, size_of :: < pc_price_t > ( ) ) ?;
200192
201- let mut price_data = load_price_account_mut ( price_account, cmd_args. ver_ ) ?;
193+ let mut price_data = load_checked :: < pc_price_t > ( price_account, cmd_args. ver_ ) ?;
202194
203195 if price_data. num_ >= PC_COMP_SIZE {
204196 return Err ( ProgramError :: InvalidArgument ) ;
@@ -246,14 +238,14 @@ pub fn add_product(
246238 check_valid_fresh_account ( new_product_account) ?;
247239
248240 let hdr = load :: < cmd_hdr_t > ( instruction_data) ?;
249- let mut mapping_data = load_mapping_account_mut ( tail_mapping_account, hdr. ver_ ) ?;
241+ let mut mapping_data = load_checked :: < pc_map_table_t > ( tail_mapping_account, hdr. ver_ ) ?;
250242 // The mapping account must have free space to add the product account
251243 pyth_assert (
252244 mapping_data. num_ < PC_MAP_TABLE_SIZE ,
253245 ProgramError :: InvalidArgument ,
254246 ) ?;
255247
256- initialize_product_account ( new_product_account, hdr. ver_ ) ?;
248+ initialize_checked :: < pc_prod_t > ( new_product_account, hdr. ver_ ) ?;
257249
258250 let current_index: usize = try_convert ( mapping_data. num_ ) ?;
259251 pubkey_assign (
@@ -322,94 +314,40 @@ pub fn clear_account(account: &AccountInfo) -> Result<(), ProgramError> {
322314 Ok ( ( ) )
323315}
324316
325-
326- /// Mutably borrow the data in `account` as a mapping account, validating that the account
327- /// is properly formatted. Any mutations to the returned value will be reflected in the
328- /// account data. Use this to read already-initialized accounts.
329- pub fn load_mapping_account_mut < ' a > (
317+ pub fn load_checked < ' a , T : PythAccount > (
330318 account : & ' a AccountInfo ,
331- expected_version : u32 ,
332- ) -> Result < RefMut < ' a , pc_map_table_t > , ProgramError > {
333- let mapping_data = load_account_as_mut :: < pc_map_table_t > ( account) ?;
334-
335- pyth_assert (
336- mapping_data. magic_ == PC_MAGIC
337- && mapping_data. ver_ == expected_version
338- && mapping_data. type_ == PC_ACCTYPE_MAPPING ,
339- ProgramError :: InvalidArgument ,
340- ) ?;
341-
342- Ok ( mapping_data)
343- }
344-
345- /// Initialize account as a new mapping account. This function will zero out any existing data in
346- /// the account.
347- pub fn initialize_mapping_account ( account : & AccountInfo , version : u32 ) -> Result < ( ) , ProgramError > {
348- clear_account ( account) ?;
349-
350- let mut mapping_account = load_account_as_mut :: < pc_map_table_t > ( account) ?;
351- mapping_account. magic_ = PC_MAGIC ;
352- mapping_account. ver_ = version;
353- mapping_account. type_ = PC_ACCTYPE_MAPPING ;
354- mapping_account. size_ =
355- try_convert ( size_of :: < pc_map_table_t > ( ) - size_of_val ( & mapping_account. prod_ ) ) ?;
356-
357- Ok ( ( ) )
358- }
359-
360- /// Initialize account as a new product account. This function will zero out any existing data in
361- /// the account.
362- pub fn initialize_product_account ( account : & AccountInfo , version : u32 ) -> Result < ( ) , ProgramError > {
363- clear_account ( account) ?;
364-
365- let mut prod_account = load_account_as_mut :: < pc_prod_t > ( account) ?;
366- prod_account. magic_ = PC_MAGIC ;
367- prod_account. ver_ = version;
368- prod_account. type_ = PC_ACCTYPE_PRODUCT ;
369- prod_account. size_ = try_convert ( size_of :: < pc_prod_t > ( ) ) ?;
370-
371- Ok ( ( ) )
372- }
373-
374- /// Mutably borrow the data in `account` as a product account, validating that the account
375- /// is properly formatted. Any mutations to the returned value will be reflected in the
376- /// account data. Use this to read already-initialized accounts.
377- pub fn load_product_account_mut < ' a > (
378- account : & ' a AccountInfo ,
379- expected_version : u32 ,
380- ) -> Result < RefMut < ' a , pc_prod_t > , ProgramError > {
381- let product_data = load_account_as_mut :: < pc_prod_t > ( account) ?;
382-
383- pyth_assert (
384- product_data. magic_ == PC_MAGIC
385- && product_data. ver_ == expected_version
386- && product_data. type_ == PC_ACCTYPE_PRODUCT ,
387- ProgramError :: InvalidArgument ,
388- ) ?;
319+ version : u32 ,
320+ ) -> Result < RefMut < ' a , T > , ProgramError > {
321+ {
322+ let account_header = load_account_as :: < pc_acc > ( account) ?;
323+ pyth_assert (
324+ account_header. magic_ == PC_MAGIC
325+ && account_header. ver_ == version
326+ && account_header. type_ == T :: ACCOUNT_TYPE ,
327+ ProgramError :: InvalidArgument ,
328+ ) ?;
329+ }
389330
390- Ok ( product_data )
331+ load_account_as_mut :: < T > ( account )
391332}
392333
393- /// Mutably borrow the data in `account` as a price account, validating that the account
394- /// is properly formatted. Any mutations to the returned value will be reflected in the
395- /// account data. Use this to read already-initialized accounts.
396- fn load_price_account_mut < ' a > (
334+ pub fn initialize_checked < ' a , T : PythAccount > (
397335 account : & ' a AccountInfo ,
398- expected_version : u32 ,
399- ) -> Result < RefMut < ' a , pc_price_t > , ProgramError > {
400- let price_data = load_account_as_mut :: < pc_price_t > ( account) ?;
336+ version : u32 ,
337+ ) -> Result < RefMut < ' a , T > , ProgramError > {
338+ clear_account ( account) ?;
401339
402- pyth_assert (
403- price_data. magic_ == PC_MAGIC
404- && price_data. ver_ == expected_version
405- && price_data. type_ == PC_ACCTYPE_PRICE ,
406- ProgramError :: InvalidArgument ,
407- ) ?;
340+ {
341+ let mut account_header = load_account_as_mut :: < pc_acc > ( account) ?;
342+ account_header. magic_ = PC_MAGIC ;
343+ account_header. ver_ = version;
344+ account_header. type_ = T :: ACCOUNT_TYPE ;
345+ account_header. size_ = T :: INITIAL_SIZE ;
346+ }
408347
409- Ok ( price_data )
348+ load_account_as_mut :: < T > ( account )
410349}
411350
412-
413351// Assign pubkey bytes from source to target, fails if source is not 32 bytes
414352pub fn pubkey_assign ( target : & mut pc_pub_key_t , source : & [ u8 ] ) {
415353 unsafe { target. k1_ . copy_from_slice ( source) }
0 commit comments