@@ -88,47 +88,56 @@ extern "C" {
8888pub fn resize_price_account (
8989 program_id : & Pubkey ,
9090 accounts : & [ AccountInfo ] ,
91- _instruction_data : & [ u8 ] ,
91+ instruction_data : & [ u8 ] ,
9292) -> ProgramResult {
93- let [ funding_account_info, price_account_info, system_program] = match accounts {
94- [ x, y, z] => Ok ( [ x, y, z] ) ,
93+ let ( funding_account, price_account, system_program, permissions_account_option) = match accounts {
94+ [ x, y, z] => Ok ( ( x, y, z, None ) ) ,
95+ [ x, y, z, p] => Ok ( ( x, y, z, Some ( p) ) ) ,
9596 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
9697 } ?;
9798
98- check_valid_funding_account ( funding_account_info) ?;
99- check_valid_signable_account ( program_id, price_account_info) ?;
99+ let hdr = load :: < CommandHeader > ( instruction_data) ?;
100+
101+ check_valid_funding_account ( funding_account) ?;
102+ check_valid_signable_account_or_permissioned_funding_account (
103+ program_id,
104+ price_account,
105+ funding_account,
106+ permissions_account_option,
107+ hdr,
108+ ) ?;
100109 pyth_assert (
101110 check_id ( system_program. key ) ,
102111 OracleError :: InvalidSystemAccount . into ( ) ,
103112 ) ?;
104113 // Check that it is a valid initialized price account
105114 {
106- load_checked :: < PriceAccount > ( price_account_info , PC_VERSION ) ?;
115+ load_checked :: < PriceAccount > ( price_account , PC_VERSION ) ?;
107116 }
108- let account_len = price_account_info . try_data_len ( ) ?;
117+ let account_len = price_account . try_data_len ( ) ?;
109118 match account_len {
110119 PriceAccount :: MINIMUM_SIZE => {
111120 // Ensure account is still rent exempt after resizing
112121 let rent: Rent = get_rent ( ) ?;
113122 let lamports_needed: u64 = rent
114123 . minimum_balance ( size_of :: < PriceAccountWrapper > ( ) )
115- . saturating_sub ( price_account_info . lamports ( ) ) ;
124+ . saturating_sub ( price_account . lamports ( ) ) ;
116125 if lamports_needed > 0 {
117126 send_lamports (
118- funding_account_info ,
119- price_account_info ,
127+ funding_account ,
128+ price_account ,
120129 system_program,
121130 lamports_needed,
122131 ) ?;
123132 }
124133 // We do not need to zero allocate because we won't access the data in the same
125134 // instruction
126- price_account_info . realloc ( size_of :: < PriceAccountWrapper > ( ) , false ) ?;
135+ price_account . realloc ( size_of :: < PriceAccountWrapper > ( ) , false ) ?;
127136
128137 // Check that everything is ok
129- check_valid_signable_account ( program_id, price_account_info ) ?;
138+ check_valid_signable_account ( program_id, price_account ) ?;
130139 let mut price_account =
131- load_checked :: < PriceAccountWrapper > ( price_account_info , PC_VERSION ) ?;
140+ load_checked :: < PriceAccountWrapper > ( price_account , PC_VERSION ) ?;
132141 // Initialize Time Machine
133142 price_account. initialize_time_machine ( ) ?;
134143 Ok ( ( ) )
@@ -175,16 +184,30 @@ pub fn add_mapping(
175184 accounts : & [ AccountInfo ] ,
176185 instruction_data : & [ u8 ] ,
177186) -> ProgramResult {
178- let [ funding_account, cur_mapping, next_mapping] = match accounts {
179- [ x, y, z] => Ok ( [ x, y, z] ) ,
187+ let ( funding_account, cur_mapping, next_mapping, permissions_account_option) = match accounts {
188+ [ x, y, z] => Ok ( ( x, y, z, None ) ) ,
189+ [ x, y, z, p] => Ok ( ( x, y, z, Some ( p) ) ) ,
180190 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
181191 } ?;
182192
183- check_valid_funding_account ( funding_account) ?;
184- check_valid_signable_account ( program_id, cur_mapping) ?;
185- check_valid_signable_account ( program_id, next_mapping) ?;
186-
187193 let hdr = load :: < CommandHeader > ( instruction_data) ?;
194+
195+ check_valid_funding_account ( funding_account) ?;
196+ check_valid_signable_account_or_permissioned_funding_account (
197+ program_id,
198+ cur_mapping,
199+ funding_account,
200+ permissions_account_option,
201+ hdr,
202+ ) ?;
203+ check_valid_signable_account_or_permissioned_funding_account (
204+ program_id,
205+ next_mapping,
206+ funding_account,
207+ permissions_account_option,
208+ hdr,
209+ ) ?;
210+
188211 let mut cur_mapping = load_checked :: < MappingAccount > ( cur_mapping, hdr. version ) ?;
189212 pyth_assert (
190213 cur_mapping. number_of_products == PC_MAP_TABLE_SIZE
@@ -326,14 +349,27 @@ pub fn add_price(
326349 ) ?;
327350
328351
329- let [ funding_account, product_account, price_account] = match accounts {
330- [ x, y, z] => Ok ( [ x, y, z] ) ,
352+ let ( funding_account, product_account, price_account, permissions_account_option) = match accounts {
353+ [ x, y, z] => Ok ( ( x, y, z, None ) ) ,
354+ [ x, y, z, p] => Ok ( ( x, y, z, Some ( p) ) ) ,
331355 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
332356 } ?;
333357
334358 check_valid_funding_account ( funding_account) ?;
335- check_valid_signable_account ( program_id, product_account) ?;
336- check_valid_signable_account ( program_id, price_account) ?;
359+ check_valid_signable_account_or_permissioned_funding_account (
360+ program_id,
361+ product_account,
362+ funding_account,
363+ permissions_account_option,
364+ & cmd_args. header ,
365+ ) ?;
366+ check_valid_signable_account_or_permissioned_funding_account (
367+ program_id,
368+ price_account,
369+ funding_account,
370+ permissions_account_option,
371+ & cmd_args. header ,
372+ ) ?;
337373
338374 let mut product_data =
339375 load_checked :: < ProductAccount > ( product_account, cmd_args. header . version ) ?;
@@ -361,17 +397,32 @@ pub fn del_price(
361397 accounts : & [ AccountInfo ] ,
362398 instruction_data : & [ u8 ] ,
363399) -> ProgramResult {
364- let [ funding_account, product_account, price_account] = match accounts {
365- [ w, x, y] => Ok ( [ w, x, y] ) ,
400+ let ( funding_account, product_account, price_account, permissions_account_option) = match accounts {
401+ [ w, x, y] => Ok ( ( w, x, y, None ) ) ,
402+ [ w, x, y, p] => Ok ( ( w, x, y, Some ( p) ) ) ,
366403 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
367404 } ?;
368405
406+ let cmd_args = load :: < CommandHeader > ( instruction_data) ?;
407+
369408 check_valid_funding_account ( funding_account) ?;
370- check_valid_signable_account ( program_id, product_account) ?;
371- check_valid_signable_account ( program_id, price_account) ?;
409+ check_valid_signable_account_or_permissioned_funding_account (
410+ program_id,
411+ product_account,
412+ funding_account,
413+ permissions_account_option,
414+ & cmd_args,
415+ ) ?;
416+ check_valid_signable_account_or_permissioned_funding_account (
417+ program_id,
418+ price_account,
419+ funding_account,
420+ permissions_account_option,
421+ & cmd_args,
422+ ) ?;
372423
373424 {
374- let cmd_args = load :: < CommandHeader > ( instruction_data ) ? ;
425+
375426 let mut product_data = load_checked :: < ProductAccount > ( product_account, cmd_args. version ) ?;
376427 let price_data = load_checked :: < PriceAccount > ( price_account, cmd_args. version ) ?;
377428 pyth_assert (
@@ -406,13 +457,21 @@ pub fn init_price(
406457
407458 check_exponent_range ( cmd_args. exponent ) ?;
408459
409- let [ funding_account, price_account] = match accounts {
410- [ x, y] => Ok ( [ x, y] ) ,
460+ let ( funding_account, price_account, permissions_account_option) = match accounts {
461+ [ x, y] => Ok ( ( x, y, None ) ) ,
462+ [ x, y, p] => Ok ( ( x, y, Some ( p) ) ) ,
411463 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
412464 } ?;
413465
414466 check_valid_funding_account ( funding_account) ?;
415- check_valid_signable_account ( program_id, price_account) ?;
467+ check_valid_signable_account_or_permissioned_funding_account (
468+ program_id,
469+ price_account,
470+ funding_account,
471+ permissions_account_option,
472+ & cmd_args. header ,
473+ ) ?;
474+
416475
417476 let mut price_data = load_checked :: < PriceAccount > ( price_account, cmd_args. header . version ) ?;
418477 pyth_assert (
@@ -476,13 +535,21 @@ pub fn add_publisher(
476535 ProgramError :: InvalidArgument ,
477536 ) ?;
478537
479- let [ funding_account, price_account] = match accounts {
480- [ x, y] => Ok ( [ x, y] ) ,
538+ let ( funding_account, price_account, permissions_account_option) = match accounts {
539+ [ x, y] => Ok ( ( x, y, None ) ) ,
540+ [ x, y, p] => Ok ( ( x, y, Some ( p) ) ) ,
481541 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
482542 } ?;
483543
484544 check_valid_funding_account ( funding_account) ?;
485- check_valid_signable_account ( program_id, price_account) ?;
545+ check_valid_signable_account_or_permissioned_funding_account (
546+ program_id,
547+ price_account,
548+ funding_account,
549+ permissions_account_option,
550+ & cmd_args. header ,
551+ ) ?;
552+
486553
487554 let mut price_data = load_checked :: < PriceAccount > ( price_account, cmd_args. header . version ) ?;
488555
@@ -526,13 +593,20 @@ pub fn del_publisher(
526593 ProgramError :: InvalidArgument ,
527594 ) ?;
528595
529- let [ funding_account, price_account] = match accounts {
530- [ x, y] => Ok ( [ x, y] ) ,
596+ let ( funding_account, price_account, permissions_account_option) = match accounts {
597+ [ x, y] => Ok ( ( x, y, None ) ) ,
598+ [ x, y, p] => Ok ( ( x, y, Some ( p) ) ) ,
531599 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
532600 } ?;
533601
534602 check_valid_funding_account ( funding_account) ?;
535- check_valid_signable_account ( program_id, price_account) ?;
603+ check_valid_signable_account_or_permissioned_funding_account (
604+ program_id,
605+ price_account,
606+ funding_account,
607+ permissions_account_option,
608+ & cmd_args. header ,
609+ ) ?;
536610
537611 let mut price_data = load_checked :: < PriceAccount > ( price_account, cmd_args. header . version ) ?;
538612
@@ -562,16 +636,31 @@ pub fn add_product(
562636 accounts : & [ AccountInfo ] ,
563637 instruction_data : & [ u8 ] ,
564638) -> ProgramResult {
565- let [ funding_account, tail_mapping_account, new_product_account] = match accounts {
566- [ x, y, z] => Ok ( [ x, y, z] ) ,
639+ let ( funding_account, tail_mapping_account, new_product_account, permissions_account_option) = match accounts {
640+ [ x, y, z] => Ok ( ( x, y, z, None ) ) ,
641+ [ x, y, z, p] => Ok ( ( x, y, z, Some ( p) ) ) ,
567642 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
568643 } ?;
569644
645+ let hdr = load :: < CommandHeader > ( instruction_data) ?;
646+
570647 check_valid_funding_account ( funding_account) ?;
571- check_valid_signable_account ( program_id, tail_mapping_account) ?;
572- check_valid_signable_account ( program_id, new_product_account) ?;
648+ check_valid_signable_account_or_permissioned_funding_account (
649+ program_id,
650+ tail_mapping_account,
651+ funding_account,
652+ permissions_account_option,
653+ & hdr,
654+ ) ?;
655+ check_valid_signable_account_or_permissioned_funding_account (
656+ program_id,
657+ new_product_account,
658+ funding_account,
659+ permissions_account_option,
660+ & hdr,
661+ ) ?;
573662
574- let hdr = load :: < CommandHeader > ( instruction_data ) ? ;
663+
575664 let mut mapping_data = load_checked :: < MappingAccount > ( tail_mapping_account, hdr. version ) ?;
576665 // The mapping account must have free space to add the product account
577666 pyth_assert (
@@ -599,15 +688,24 @@ pub fn upd_product(
599688 accounts : & [ AccountInfo ] ,
600689 instruction_data : & [ u8 ] ,
601690) -> ProgramResult {
602- let [ funding_account, product_account] = match accounts {
603- [ x, y] => Ok ( [ x, y] ) ,
691+ let ( funding_account, product_account, permissions_account_option) = match accounts {
692+ [ x, y] => Ok ( ( x, y, None ) ) ,
693+ [ x, y, p] => Ok ( ( x, y, Some ( p) ) ) ,
604694 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
605695 } ?;
606696
697+ let hdr = load :: < CommandHeader > ( instruction_data) ?;
698+
607699 check_valid_funding_account ( funding_account) ?;
608- check_valid_signable_account ( program_id, product_account) ?;
700+ check_valid_signable_account_or_permissioned_funding_account (
701+ program_id,
702+ product_account,
703+ funding_account,
704+ permissions_account_option,
705+ & hdr,
706+ ) ?;
609707
610- let hdr = load :: < CommandHeader > ( instruction_data ) ? ;
708+
611709 {
612710 // Validate that product_account contains the appropriate account header
613711 let mut _product_data = load_checked :: < ProductAccount > ( product_account, hdr. version ) ?;
@@ -664,13 +762,21 @@ pub fn set_min_pub(
664762 ProgramError :: InvalidArgument ,
665763 ) ?;
666764
667- let [ funding_account, price_account] = match accounts {
668- [ x, y] => Ok ( [ x, y] ) ,
765+ let ( funding_account, price_account, permissions_account_option) = match accounts {
766+ [ x, y] => Ok ( ( x, y, None ) ) ,
767+ [ x, y, p] => Ok ( ( x, y, Some ( p) ) ) ,
669768 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
670769 } ?;
671770
672771 check_valid_funding_account ( funding_account) ?;
673- check_valid_signable_account ( program_id, price_account) ?;
772+ check_valid_signable_account_or_permissioned_funding_account (
773+ program_id,
774+ price_account,
775+ funding_account,
776+ permissions_account_option,
777+ & cmd. header ,
778+ ) ?;
779+
674780
675781 let mut price_account_data = load_checked :: < PriceAccount > ( price_account, cmd. header . version ) ?;
676782 price_account_data. min_pub_ = cmd. minimum_publishers ;
@@ -690,17 +796,34 @@ pub fn del_product(
690796 accounts : & [ AccountInfo ] ,
691797 instruction_data : & [ u8 ] ,
692798) -> ProgramResult {
693- let [ funding_account, mapping_account, product_account] = match accounts {
694- [ w, x, y] => Ok ( [ w, x, y] ) ,
799+ let ( funding_account, mapping_account, product_account, permissions_account_option) = match accounts {
800+ [ w, x, y] => Ok ( ( w, x, y, None ) ) ,
801+ [ w, x, y, p] => Ok ( ( w, x, y, Some ( p) ) ) ,
695802 _ => Err ( OracleError :: InvalidNumberOfAccounts ) ,
696803 } ?;
697804
805+ let cmd_args = load :: < CommandHeader > ( instruction_data) ?;
806+
698807 check_valid_funding_account ( funding_account) ?;
699- check_valid_signable_account ( program_id, mapping_account) ?;
700- check_valid_signable_account ( program_id, product_account) ?;
808+ check_valid_signable_account_or_permissioned_funding_account (
809+ program_id,
810+ mapping_account,
811+ funding_account,
812+ permissions_account_option,
813+ & cmd_args,
814+ ) ?;
815+
816+ check_valid_signable_account_or_permissioned_funding_account (
817+ program_id,
818+ product_account,
819+ funding_account,
820+ permissions_account_option,
821+ & cmd_args,
822+ ) ?;
823+
701824
702825 {
703- let cmd_args = load :: < CommandHeader > ( instruction_data ) ? ;
826+
704827 let mut mapping_data = load_checked :: < MappingAccount > ( mapping_account, cmd_args. version ) ?;
705828 let product_data = load_checked :: < ProductAccount > ( product_account, cmd_args. version ) ?;
706829
0 commit comments