@@ -32,9 +32,7 @@ use crate::c_oracle_header::{
32
32
pc_price_t,
33
33
pc_prod_t,
34
34
pc_pub_key_t,
35
- PC_ACCTYPE_MAPPING ,
36
- PC_ACCTYPE_PRICE ,
37
- PC_ACCTYPE_PRODUCT ,
35
+ PythAccount ,
38
36
PC_COMP_SIZE ,
39
37
PC_MAGIC ,
40
38
PC_MAP_TABLE_SIZE ,
@@ -95,7 +93,7 @@ pub fn init_mapping(
95
93
96
94
// Initialize by setting to zero again (just in case) and populating the account header
97
95
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_ ) ?;
99
97
100
98
Ok ( SUCCESS )
101
99
}
@@ -116,13 +114,13 @@ pub fn add_mapping(
116
114
check_valid_fresh_account ( next_mapping) ?;
117
115
118
116
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_ ) ?;
120
118
pyth_assert (
121
119
cur_mapping. num_ == PC_MAP_TABLE_SIZE && pubkey_is_zero ( & cur_mapping. next_ ) ,
122
120
ProgramError :: InvalidArgument ,
123
121
) ?;
124
122
125
- initialize_mapping_account ( next_mapping, hdr. ver_ ) ?;
123
+ initialize_checked :: < pc_map_table_t > ( next_mapping, hdr. ver_ ) ?;
126
124
pubkey_assign ( & mut cur_mapping. next_ , & next_mapping. key . to_bytes ( ) ) ;
127
125
128
126
Ok ( SUCCESS )
@@ -156,15 +154,9 @@ pub fn add_price(
156
154
check_valid_signable_account ( program_id, price_account, size_of :: < pc_price_t > ( ) ) ?;
157
155
check_valid_fresh_account ( price_account) ?;
158
156
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_ ) ?;
160
158
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_ ) ?;
168
160
price_data. expo_ = cmd_args. expo_ ;
169
161
price_data. ptype_ = cmd_args. ptype_ ;
170
162
pubkey_assign ( & mut price_data. prod_ , & product_account. key . to_bytes ( ) ) ;
@@ -198,7 +190,7 @@ pub fn add_publisher(
198
190
check_valid_funding_account ( funding_account) ?;
199
191
check_valid_signable_account ( program_id, price_account, size_of :: < pc_price_t > ( ) ) ?;
200
192
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_ ) ?;
202
194
203
195
if price_data. num_ >= PC_COMP_SIZE {
204
196
return Err ( ProgramError :: InvalidArgument ) ;
@@ -246,14 +238,14 @@ pub fn add_product(
246
238
check_valid_fresh_account ( new_product_account) ?;
247
239
248
240
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_ ) ?;
250
242
// The mapping account must have free space to add the product account
251
243
pyth_assert (
252
244
mapping_data. num_ < PC_MAP_TABLE_SIZE ,
253
245
ProgramError :: InvalidArgument ,
254
246
) ?;
255
247
256
- initialize_product_account ( new_product_account, hdr. ver_ ) ?;
248
+ initialize_checked :: < pc_prod_t > ( new_product_account, hdr. ver_ ) ?;
257
249
258
250
let current_index: usize = try_convert ( mapping_data. num_ ) ?;
259
251
pubkey_assign (
@@ -322,94 +314,40 @@ pub fn clear_account(account: &AccountInfo) -> Result<(), ProgramError> {
322
314
Ok ( ( ) )
323
315
}
324
316
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 > (
330
318
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
+ }
389
330
390
- Ok ( product_data )
331
+ load_account_as_mut :: < T > ( account )
391
332
}
392
333
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 > (
397
335
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) ?;
401
339
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
+ }
408
347
409
- Ok ( price_data )
348
+ load_account_as_mut :: < T > ( account )
410
349
}
411
350
412
-
413
351
// Assign pubkey bytes from source to target, fails if source is not 32 bytes
414
352
pub fn pubkey_assign ( target : & mut pc_pub_key_t , source : & [ u8 ] ) {
415
353
unsafe { target. k1_ . copy_from_slice ( source) }
0 commit comments