antegen_fiber_program/state/
fiber.rs1use crate::constants::*;
2use crate::errors::AntegenFiberError;
3use crate::state::instruction::*;
4use anchor_lang::prelude::*;
5use anchor_lang::solana_program::instruction::Instruction;
6
7pub const CURRENT_FIBER_VERSION: u8 = 1;
9
10pub const MAX_LOOKUP_TABLES_PER_FIBER: usize = 4;
12
13pub trait FiberInstructionProcessor {
15 fn get_instruction(&self, executor: &Pubkey) -> Result<Instruction>;
18}
19
20#[account]
23#[derive(Debug, InitSpace)]
24pub struct FiberState {
25 pub thread: Pubkey,
27 #[max_len(1024)]
29 pub compiled_instruction: Vec<u8>,
30 pub last_executed: i64,
32 pub exec_count: u64,
34 pub priority_fee: u64,
36}
37
38impl FiberState {
39 pub fn pubkey(thread: Pubkey, fiber_index: u8) -> Pubkey {
41 Pubkey::find_program_address(
42 &[SEED_THREAD_FIBER, thread.as_ref(), &[fiber_index]],
43 &crate::ID,
44 )
45 .0
46 }
47}
48
49impl FiberInstructionProcessor for FiberState {
50 fn get_instruction(&self, executor: &Pubkey) -> Result<Instruction> {
51 decompile_with_payer(&self.compiled_instruction, executor)
52 }
53}
54
55#[account]
59#[derive(Debug, InitSpace)]
60pub struct FiberVersionedState {
61 pub version: u8,
63 pub thread: Pubkey,
65 #[max_len(1024)]
67 pub compiled_instruction: Vec<u8>,
68 pub last_executed: i64,
70 pub exec_count: u64,
72 pub priority_fee: u64,
74 #[max_len(4)]
76 pub lookup_tables: Vec<Pubkey>,
77}
78
79impl FiberVersionedState {
80 pub fn pubkey(thread: Pubkey, fiber_index: u8) -> Pubkey {
81 FiberState::pubkey(thread, fiber_index)
82 }
83}
84
85impl FiberInstructionProcessor for FiberVersionedState {
86 fn get_instruction(&self, executor: &Pubkey) -> Result<Instruction> {
87 decompile_with_payer(&self.compiled_instruction, executor)
88 }
89}
90
91#[derive(Debug)]
98pub enum Fiber {
99 Legacy(FiberState),
100 V1(FiberVersionedState),
101}
102
103impl anchor_lang::AccountDeserialize for Fiber {
104 fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
105 Self::try_deserialize_unchecked(buf)
106 }
107
108 fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
109 if buf.len() < 8 {
110 return Err(error!(AntegenFiberError::InvalidFiberData));
111 }
112 let disc = &buf[..8];
113 if disc == FiberVersionedState::DISCRIMINATOR {
114 let state = FiberVersionedState::try_deserialize(buf)?;
115 Ok(Self::V1(state))
116 } else if disc == FiberState::DISCRIMINATOR {
117 let state = FiberState::try_deserialize(buf)?;
118 Ok(Self::Legacy(state))
119 } else {
120 Err(error!(AntegenFiberError::InvalidFiberData))
121 }
122 }
123}
124
125impl Fiber {
126 pub fn is_legacy(&self) -> bool {
127 matches!(self, Self::Legacy(_))
128 }
129
130 pub fn thread(&self) -> Pubkey {
131 match self {
132 Self::Legacy(s) => s.thread,
133 Self::V1(s) => s.thread,
134 }
135 }
136
137 pub fn compiled_instruction(&self) -> &[u8] {
138 match self {
139 Self::Legacy(s) => &s.compiled_instruction,
140 Self::V1(s) => &s.compiled_instruction,
141 }
142 }
143
144 pub fn priority_fee(&self) -> u64 {
145 match self {
146 Self::Legacy(s) => s.priority_fee,
147 Self::V1(s) => s.priority_fee,
148 }
149 }
150
151 pub fn lookup_tables(&self) -> &[Pubkey] {
152 match self {
153 Self::Legacy(_) => &[],
154 Self::V1(s) => &s.lookup_tables,
155 }
156 }
157}
158
159impl FiberInstructionProcessor for Fiber {
160 fn get_instruction(&self, executor: &Pubkey) -> Result<Instruction> {
161 match self {
162 Self::Legacy(s) => s.get_instruction(executor),
163 Self::V1(s) => s.get_instruction(executor),
164 }
165 }
166}
167
168fn decompile_with_payer(compiled_instruction: &[u8], executor: &Pubkey) -> Result<Instruction> {
169 let compiled = CompiledInstructionV0::try_from_slice(compiled_instruction)?;
170 let mut instruction = decompile_instruction(&compiled)?;
171
172 for acc in instruction.accounts.iter_mut() {
173 if acc.pubkey.eq(&PAYER_PUBKEY) {
174 acc.pubkey = *executor;
175 }
176 }
177
178 Ok(instruction)
179}