spl_token_2022/extension/cpi_guard/
processor.rs1use {
2 crate::{
3 check_program_account,
4 error::TokenError,
5 extension::{
6 cpi_guard::{in_cpi, instruction::CpiGuardInstruction, CpiGuard},
7 BaseStateWithExtensionsMut, PodStateWithExtensionsMut,
8 },
9 instruction::decode_instruction_type,
10 pod::PodAccount,
11 processor::Processor,
12 },
13 solana_program::{
14 account_info::{next_account_info, AccountInfo},
15 entrypoint::ProgramResult,
16 msg,
17 pubkey::Pubkey,
18 },
19};
20
21fn process_toggle_cpi_guard(
24 program_id: &Pubkey,
25 accounts: &[AccountInfo],
26 enable: bool,
27) -> ProgramResult {
28 let account_info_iter = &mut accounts.iter();
29 let token_account_info = next_account_info(account_info_iter)?;
30 let owner_info = next_account_info(account_info_iter)?;
31 let owner_info_data_len = owner_info.data_len();
32
33 let mut account_data = token_account_info.data.borrow_mut();
34 let mut account = PodStateWithExtensionsMut::<PodAccount>::unpack(&mut account_data)?;
35
36 Processor::validate_owner(
37 program_id,
38 &account.base.owner,
39 owner_info,
40 owner_info_data_len,
41 account_info_iter.as_slice(),
42 )?;
43
44 if in_cpi() {
45 return Err(TokenError::CpiGuardSettingsLocked.into());
46 }
47
48 let extension = if let Ok(extension) = account.get_extension_mut::<CpiGuard>() {
49 extension
50 } else {
51 account.init_extension::<CpiGuard>(true)?
52 };
53 extension.lock_cpi = enable.into();
54 Ok(())
55}
56
57pub(crate) fn process_instruction(
58 program_id: &Pubkey,
59 accounts: &[AccountInfo],
60 input: &[u8],
61) -> ProgramResult {
62 check_program_account(program_id)?;
63
64 match decode_instruction_type(input)? {
65 CpiGuardInstruction::Enable => {
66 msg!("CpiGuardInstruction::Enable");
67 process_toggle_cpi_guard(program_id, accounts, true )
68 }
69 CpiGuardInstruction::Disable => {
70 msg!("CpiGuardInstruction::Disable");
71 process_toggle_cpi_guard(program_id, accounts, false )
72 }
73 }
74}