1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use crate::anchor_traits::*;
use crate::cfg_client;
#[allow(unused_imports)]
use crate::impl_account_deserialize;
use crate::SWITCHBOARD_ON_DEMAND_PROGRAM_ID;
use bytemuck::{Pod, Zeroable};
use solana_program::pubkey::Pubkey;

const STATE_SEED: &[u8] = b"STATE";

#[derive(Debug, Copy, Clone)]
pub struct StateEpochInfo {
    pub id: u64,
    pub reserved1: u64,
    pub slot_end: u64,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct State {
    pub bump: u8,
    pub test_only_disable_mr_enclave_check: u8,
    padding1: [u8; 6],
    pub authority: Pubkey,
    pub guardian_queue: Pubkey,
    pub reserved1: u64,
    pub epoch_length: u64,
    pub current_epoch: StateEpochInfo,
    pub next_epoch: StateEpochInfo,
    pub finalized_epoch: StateEpochInfo,
    // xswitch vault
    pub stake_pool: Pubkey,
    pub stake_program: Pubkey,
    pub switch_mint: Pubkey,
    pub sgx_advisories: [u16; 32],
    pub advisories_len: u8,
    _ebuf4: [u8; 15],
    _ebuf3: [u8; 256],
    _ebuf2: [u8; 512],
    _ebuf1: [u8; 1024],
}
unsafe impl Pod for State {}
unsafe impl Zeroable for State {}

cfg_client! {
    impl_account_deserialize!(State);
}

impl Discriminator for State {
    const DISCRIMINATOR: [u8; 8] = [216, 146, 107, 94, 104, 75, 182, 177];
}

impl Owner for State {
    fn owner() -> Pubkey {
        *SWITCHBOARD_ON_DEMAND_PROGRAM_ID
    }
}

impl State {
    pub fn size() -> usize {
        8 + std::mem::size_of::<State>()
    }

    pub fn get_pda() -> Pubkey {
        let (pda_key, _) =
            Pubkey::find_program_address(&[STATE_SEED], &*SWITCHBOARD_ON_DEMAND_PROGRAM_ID);
        pda_key
    }

    pub fn get_program_pda(program_id: Option<Pubkey>) -> Pubkey {
        let (pda_key, _) = Pubkey::find_program_address(
            &[STATE_SEED],
            &program_id.unwrap_or(*SWITCHBOARD_ON_DEMAND_PROGRAM_ID),
        );
        pda_key
    }

    cfg_client! {
        pub async fn fetch_async(
            client: &solana_client::nonblocking::rpc_client::RpcClient,
        ) -> std::result::Result<Self, crate::OnDemandError> {
            let pubkey = State::get_pda();
            crate::client::fetch_zerocopy_account_async(client, pubkey).await
        }
    }
}