Skip to main content

anchor_lang/
bpf_upgradeable_state.rs

1use crate::{
2    error::ErrorCode,
3    solana_program::{
4        bpf_loader_upgradeable::UpgradeableLoaderState, program_error::ProgramError, pubkey::Pubkey,
5    },
6    AccountDeserialize, AccountSerialize, Owner, Result,
7};
8
9#[derive(Clone)]
10pub struct ProgramData {
11    pub slot: u64,
12    pub upgrade_authority_address: Option<Pubkey>,
13}
14
15impl AccountDeserialize for ProgramData {
16    fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
17        ProgramData::try_deserialize_unchecked(buf)
18    }
19
20    fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
21        let program_state = AccountDeserialize::try_deserialize_unchecked(buf)?;
22
23        match program_state {
24            UpgradeableLoaderState::Uninitialized => Err(ErrorCode::AccountNotProgramData.into()),
25            UpgradeableLoaderState::Buffer {
26                authority_address: _,
27            } => Err(ErrorCode::AccountNotProgramData.into()),
28            UpgradeableLoaderState::Program {
29                programdata_address: _,
30            } => Err(ErrorCode::AccountNotProgramData.into()),
31            UpgradeableLoaderState::ProgramData {
32                slot,
33                upgrade_authority_address,
34            } => Ok(ProgramData {
35                slot,
36                upgrade_authority_address,
37            }),
38        }
39    }
40}
41
42impl AccountSerialize for ProgramData {
43    fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
44        // no-op
45        Ok(())
46    }
47}
48
49impl Owner for ProgramData {
50    fn owner() -> crate::solana_program::pubkey::Pubkey {
51        anchor_lang::solana_program::bpf_loader_upgradeable::ID
52    }
53}
54
55impl Owner for UpgradeableLoaderState {
56    fn owner() -> Pubkey {
57        anchor_lang::solana_program::bpf_loader_upgradeable::ID
58    }
59}
60
61impl AccountSerialize for UpgradeableLoaderState {
62    fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
63        // no-op
64        Ok(())
65    }
66}
67
68impl AccountDeserialize for UpgradeableLoaderState {
69    fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
70        UpgradeableLoaderState::try_deserialize_unchecked(buf)
71    }
72
73    fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
74        bincode::deserialize(buf).map_err(|_| ProgramError::InvalidAccountData.into())
75    }
76}
77
78#[cfg(feature = "idl-build")]
79mod idl_build {
80    use super::*;
81
82    impl crate::IdlBuild for ProgramData {}
83    impl crate::Discriminator for ProgramData {
84        const DISCRIMINATOR: &'static [u8] = &[];
85    }
86}