solana_feature_gate_program/
instruction.rs1use {
4 num_enum::{IntoPrimitive, TryFromPrimitive},
5 shank::ShankInstruction,
6 solana_program::{
7 incinerator,
8 instruction::{AccountMeta, Instruction},
9 program_error::ProgramError,
10 pubkey::Pubkey,
11 system_program,
12 },
13};
14
15#[rustfmt::skip]
17#[derive(Clone, Debug, PartialEq, IntoPrimitive, ShankInstruction, TryFromPrimitive)]
18#[repr(u8)]
19pub enum FeatureGateInstruction {
20 #[account(
36 0,
37 writable,
38 signer,
39 name = "feature",
40 description = "The feature account to revoke"
41 )]
42 #[account(
43 1,
44 writable,
45 name = "incinerator",
46 description = "The incinerator account"
47 )]
48 #[account(
49 2,
50 name = "system_program",
51 description = "The system program"
52 )]
53 RevokePendingActivation,
54}
55impl FeatureGateInstruction {
56 pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
59 if input.len() != 1 {
60 return Err(ProgramError::InvalidInstructionData);
61 }
62 Self::try_from(input[0]).map_err(|_| ProgramError::InvalidInstructionData)
63 }
64
65 pub fn pack(&self) -> Vec<u8> {
68 vec![self.to_owned().into()]
69 }
70}
71
72pub fn revoke_pending_activation(feature_id: &Pubkey) -> Instruction {
74 let accounts = vec![
75 AccountMeta::new(*feature_id, true),
76 AccountMeta::new(incinerator::id(), false),
77 AccountMeta::new_readonly(system_program::id(), false),
78 ];
79
80 let data = FeatureGateInstruction::RevokePendingActivation.pack();
81
82 Instruction {
83 program_id: crate::id(),
84 accounts,
85 data,
86 }
87}
88
89#[cfg(test)]
90mod test {
91 use super::*;
92
93 fn test_pack_unpack(instruction: &FeatureGateInstruction) {
94 let packed = instruction.pack();
95 let unpacked = FeatureGateInstruction::unpack(&packed).unwrap();
96 assert_eq!(instruction, &unpacked);
97 }
98
99 #[test]
100 fn test_pack_unpack_revoke_pending_activation() {
101 test_pack_unpack(&FeatureGateInstruction::RevokePendingActivation);
102 }
103}