@@ -5,6 +5,7 @@ use std::mem::{
5
5
6
6
use crate :: c_oracle_header:: {
7
7
MappingAccount ,
8
+ PermissionAccount ,
8
9
PriceAccount ,
9
10
PriceComponent ,
10
11
PriceEma ,
@@ -18,8 +19,11 @@ use crate::c_oracle_header::{
18
19
PC_PTYPE_UNKNOWN ,
19
20
PC_STATUS_UNKNOWN ,
20
21
PC_VERSION ,
22
+ PERMISSIONS_SEED ,
21
23
} ;
24
+
22
25
use crate :: deserialize:: {
26
+ create_pda_if_needed,
23
27
initialize_pyth_account_checked,
24
28
load,
25
29
load_checked,
@@ -31,33 +35,34 @@ use crate::instruction::{
31
35
DelPublisherArgs ,
32
36
InitPriceArgs ,
33
37
SetMinPubArgs ,
38
+ UpdPermissionsArgs ,
34
39
UpdPriceArgs ,
35
40
} ;
36
41
use crate :: time_machine_types:: PriceAccountWrapper ;
37
42
use crate :: utils:: {
38
43
check_exponent_range,
44
+ check_is_upgrade_authority_for_program,
39
45
check_valid_funding_account,
40
46
check_valid_signable_account,
41
47
check_valid_writable_account,
42
48
is_component_update,
43
49
pyth_assert,
44
50
read_pc_str_t,
51
+ send_lamports,
45
52
try_convert,
46
53
} ;
47
54
use crate :: OracleError ;
48
55
use bytemuck:: bytes_of_mut;
49
56
use solana_program:: account_info:: AccountInfo ;
50
57
use solana_program:: clock:: Clock ;
51
58
use solana_program:: entrypoint:: ProgramResult ;
52
- use solana_program:: program:: invoke;
53
59
use solana_program:: program_error:: ProgramError ;
54
60
use solana_program:: program_memory:: {
55
61
sol_memcpy,
56
62
sol_memset,
57
63
} ;
58
64
use solana_program:: pubkey:: Pubkey ;
59
65
use solana_program:: rent:: Rent ;
60
- use solana_program:: system_instruction:: transfer;
61
66
use solana_program:: system_program:: check_id;
62
67
use solana_program:: sysvar:: Sysvar ;
63
68
@@ -74,20 +79,6 @@ extern "C" {
74
79
pub fn c_upd_aggregate ( _input : * mut u8 , clock_slot : u64 , clock_timestamp : i64 ) -> bool ;
75
80
}
76
81
77
- fn send_lamports < ' a > (
78
- from : & AccountInfo < ' a > ,
79
- to : & AccountInfo < ' a > ,
80
- system_program : & AccountInfo < ' a > ,
81
- amount : u64 ,
82
- ) -> Result < ( ) , ProgramError > {
83
- let transfer_instruction = transfer ( from. key , to. key , amount) ;
84
- invoke (
85
- & transfer_instruction,
86
- & [ from. clone ( ) , to. clone ( ) , system_program. clone ( ) ] ,
87
- ) ?;
88
- Ok ( ( ) )
89
- }
90
-
91
82
/// resizes a price account so that it fits the Time Machine
92
83
/// key[0] funding account [signer writable]
93
84
/// key[1] price account [Signer writable]
@@ -746,3 +737,63 @@ pub fn del_product(
746
737
747
738
Ok ( ( ) )
748
739
}
740
+
741
+
742
+ /// Updates permissions for the pyth oracle program
743
+ /// This function can create and update the permissions accounts, which stores
744
+ /// several public keys that can execute administrative instructions in the pyth program
745
+ pub fn upd_permissions (
746
+ program_id : & Pubkey ,
747
+ accounts : & [ AccountInfo ] ,
748
+ instruction_data : & [ u8 ] ,
749
+ ) -> ProgramResult {
750
+ let [ funding_account, program_account, programdata_account, permissions_account, system_program] =
751
+ match accounts {
752
+ [ v, w, x, y, z] => Ok ( [ v, w, x, y, z] ) ,
753
+ _ => Err ( ProgramError :: InvalidArgument ) ,
754
+ } ?;
755
+
756
+ let cmd_args = load :: < UpdPermissionsArgs > ( instruction_data) ?;
757
+
758
+ check_valid_funding_account ( funding_account) ?;
759
+ check_is_upgrade_authority_for_program (
760
+ funding_account,
761
+ program_account,
762
+ programdata_account,
763
+ program_id,
764
+ ) ?;
765
+
766
+ let ( permission_pda_address, bump_seed) =
767
+ Pubkey :: find_program_address ( & [ PERMISSIONS_SEED . as_bytes ( ) ] , program_id) ;
768
+ pyth_assert (
769
+ permission_pda_address == * permissions_account. key ,
770
+ OracleError :: InvalidPda . into ( ) ,
771
+ ) ?;
772
+
773
+ pyth_assert (
774
+ check_id ( system_program. key ) ,
775
+ OracleError :: InvalidSystemAccount . into ( ) ,
776
+ ) ?;
777
+
778
+
779
+ // Create permissions account if it doesn't exist
780
+ create_pda_if_needed :: < PermissionAccount > (
781
+ permissions_account,
782
+ funding_account,
783
+ system_program,
784
+ program_id,
785
+ & [ PERMISSIONS_SEED . as_bytes ( ) , & [ bump_seed] ] ,
786
+ cmd_args. header . version ,
787
+ ) ?;
788
+
789
+ check_valid_writable_account ( program_id, permissions_account) ?;
790
+
791
+ let mut permissions_account_data =
792
+ load_checked :: < PermissionAccount > ( permissions_account, cmd_args. header . version ) ?;
793
+ permissions_account_data. master_authority = cmd_args. master_authority ;
794
+
795
+ permissions_account_data. data_curation_authority = cmd_args. data_curation_authority ;
796
+ permissions_account_data. security_authority = cmd_args. security_authority ;
797
+
798
+ Ok ( ( ) )
799
+ }
0 commit comments