cronos_scheduler/state/
manager.rs

1use {
2    super::InstructionData,
3    crate::{errors::CronosError, pda::PDA, responses::ExecResponse},
4    anchor_lang::{
5        prelude::*,
6        solana_program::{
7            instruction::Instruction,
8            program::{get_return_data, invoke_signed},
9        },
10        AnchorDeserialize,
11    },
12    std::convert::TryFrom,
13};
14
15pub const SEED_MANAGER: &[u8] = b"manager";
16
17/**
18 * Manager
19 */
20
21#[account]
22#[derive(Debug)]
23pub struct Manager {
24    pub authority: Pubkey,
25    pub queue_count: u128,
26}
27
28impl Manager {
29    pub fn pda(authority: Pubkey) -> PDA {
30        Pubkey::find_program_address(&[SEED_MANAGER, authority.as_ref()], &crate::ID)
31    }
32}
33
34impl TryFrom<Vec<u8>> for Manager {
35    type Error = Error;
36    fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
37        Manager::try_deserialize(&mut data.as_slice())
38    }
39}
40
41/**
42 * ManagerAccount
43 */
44
45pub trait ManagerAccount {
46    fn new(&mut self, authority: Pubkey) -> Result<()>;
47
48    fn sign(
49        &self,
50        account_infos: &[AccountInfo],
51        bump: u8,
52        ix: &InstructionData,
53    ) -> Result<Option<ExecResponse>>;
54}
55
56impl ManagerAccount for Account<'_, Manager> {
57    fn new(&mut self, authority: Pubkey) -> Result<()> {
58        self.authority = authority;
59        self.queue_count = 0;
60        Ok(())
61    }
62
63    fn sign(
64        &self,
65        account_infos: &[AccountInfo],
66        bump: u8,
67        ix: &InstructionData,
68    ) -> Result<Option<ExecResponse>> {
69        invoke_signed(
70            &Instruction::from(ix),
71            account_infos,
72            &[&[SEED_MANAGER, self.authority.as_ref(), &[bump]]],
73        )
74        .map_err(|_err| CronosError::InnerIxFailed)?;
75
76        match get_return_data() {
77            None => Ok(None),
78            Some((program_id, return_data)) => {
79                if program_id != ix.program_id {
80                    Err(CronosError::InvalidReturnData.into())
81                } else {
82                    Ok(Some(
83                        ExecResponse::try_from_slice(return_data.as_slice())
84                            .map_err(|_err| CronosError::InvalidExecResponse)?,
85                    ))
86                }
87            }
88        }
89    }
90}