@@ -5,6 +5,7 @@ use std::mem::{
55
66use crate :: c_oracle_header:: {
77 MappingAccount ,
8+ PermissionAccount ,
89 PriceAccount ,
910 PriceComponent ,
1011 PriceEma ,
@@ -18,8 +19,11 @@ use crate::c_oracle_header::{
1819 PC_PTYPE_UNKNOWN ,
1920 PC_STATUS_UNKNOWN ,
2021 PC_VERSION ,
22+ PERMISSIONS_SEED ,
2123} ;
24+
2225use crate :: deserialize:: {
26+ create_pda_if_needed,
2327 initialize_pyth_account_checked,
2428 load,
2529 load_checked,
@@ -31,33 +35,34 @@ use crate::instruction::{
3135 DelPublisherArgs ,
3236 InitPriceArgs ,
3337 SetMinPubArgs ,
38+ UpdPermissionsArgs ,
3439 UpdPriceArgs ,
3540} ;
3641use crate :: time_machine_types:: PriceAccountWrapper ;
3742use crate :: utils:: {
3843 check_exponent_range,
44+ check_is_upgrade_authority_for_program,
3945 check_valid_funding_account,
4046 check_valid_signable_account,
4147 check_valid_writable_account,
4248 is_component_update,
4349 pyth_assert,
4450 read_pc_str_t,
51+ send_lamports,
4552 try_convert,
4653} ;
4754use crate :: OracleError ;
4855use bytemuck:: bytes_of_mut;
4956use solana_program:: account_info:: AccountInfo ;
5057use solana_program:: clock:: Clock ;
5158use solana_program:: entrypoint:: ProgramResult ;
52- use solana_program:: program:: invoke;
5359use solana_program:: program_error:: ProgramError ;
5460use solana_program:: program_memory:: {
5561 sol_memcpy,
5662 sol_memset,
5763} ;
5864use solana_program:: pubkey:: Pubkey ;
5965use solana_program:: rent:: Rent ;
60- use solana_program:: system_instruction:: transfer;
6166use solana_program:: system_program:: check_id;
6267use solana_program:: sysvar:: Sysvar ;
6368
@@ -74,20 +79,6 @@ extern "C" {
7479 pub fn c_upd_aggregate ( _input : * mut u8 , clock_slot : u64 , clock_timestamp : i64 ) -> bool ;
7580}
7681
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-
9182/// resizes a price account so that it fits the Time Machine
9283/// key[0] funding account [signer writable]
9384/// key[1] price account [Signer writable]
@@ -746,3 +737,63 @@ pub fn del_product(
746737
747738 Ok ( ( ) )
748739}
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