anchor_lang/
bpf_upgradeable_state.rs

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