spl_governance/state/
program_metadata.rs

1//! ProgramMetadata Account
2
3use {
4    crate::state::enums::GovernanceAccountType,
5    borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
6    solana_program::{
7        account_info::AccountInfo, clock::Slot, program_error::ProgramError,
8        program_pack::IsInitialized, pubkey::Pubkey,
9    },
10    spl_governance_tools::account::{get_account_data, AccountMaxSize},
11};
12
13/// Program metadata account. It stores information about the particular
14/// SPL-Governance program instance
15#[derive(Clone, Debug, PartialEq, Eq, BorshDeserialize, BorshSerialize, BorshSchema)]
16pub struct ProgramMetadata {
17    /// Governance account type
18    pub account_type: GovernanceAccountType,
19
20    /// The slot when the metadata was captured
21    pub updated_at: Slot,
22
23    /// The version of the program
24    /// Max 11 characters XXX.YYY.ZZZ
25    pub version: String,
26
27    /// Reserved
28    pub reserved: [u8; 64],
29}
30
31impl AccountMaxSize for ProgramMetadata {
32    fn get_max_size(&self) -> Option<usize> {
33        Some(88)
34    }
35}
36
37impl IsInitialized for ProgramMetadata {
38    fn is_initialized(&self) -> bool {
39        self.account_type == GovernanceAccountType::ProgramMetadata
40    }
41}
42
43/// Returns ProgramMetadata PDA address
44pub fn get_program_metadata_address(program_id: &Pubkey) -> Pubkey {
45    Pubkey::find_program_address(&get_program_metadata_seeds(), program_id).0
46}
47
48/// Returns ProgramMetadata PDA seeds
49pub fn get_program_metadata_seeds<'a>() -> [&'a [u8]; 1] {
50    [b"metadata"]
51}
52
53/// Deserializes account and checks owner program
54pub fn get_program_metadata_data(
55    program_id: &Pubkey,
56    program_metadata_info: &AccountInfo,
57) -> Result<ProgramMetadata, ProgramError> {
58    get_account_data::<ProgramMetadata>(program_id, program_metadata_info)
59}
60
61#[cfg(test)]
62mod test {
63
64    use super::*;
65
66    #[test]
67    fn test_max_size() {
68        let program_metadata_data = ProgramMetadata {
69            account_type: GovernanceAccountType::TokenOwnerRecordV2,
70            updated_at: 10,
71            reserved: [0; 64],
72            version: "111.122.155".to_string(),
73        };
74
75        let size = program_metadata_data.try_to_vec().unwrap().len();
76
77        assert_eq!(program_metadata_data.get_max_size(), Some(size));
78    }
79}