antegen_fiber_program/instructions/
update.rs1use crate::constants::*;
2use crate::errors::AntegenFiberError;
3use crate::state::*;
4use anchor_lang::prelude::*;
5use anchor_lang::solana_program::instruction::Instruction;
6
7use super::create::{initialize_fiber, write_legacy, write_versioned};
8
9#[derive(Accounts)]
12#[instruction(fiber_index: u8)]
13pub struct Update<'info> {
14 pub thread: Signer<'info>,
16
17 #[account(
19 mut,
20 seeds = [SEED_THREAD_FIBER, thread.key().as_ref(), &[fiber_index]],
21 bump,
22 )]
23 pub fiber: UncheckedAccount<'info>,
24
25 pub system_program: Program<'info, System>,
26}
27
28pub fn update(
29 ctx: Context<Update>,
30 fiber_index: u8,
31 instruction: Option<Instruction>,
32 priority_fee: Option<u64>,
33 lookup_tables: Option<Vec<Pubkey>>,
34) -> Result<()> {
35 if let Some(ref lt) = lookup_tables {
36 require!(
37 lt.len() <= MAX_LOOKUP_TABLES_PER_FIBER,
38 AntegenFiberError::LookupTablesExceedMax
39 );
40 }
41
42 let thread_key = ctx.accounts.thread.key();
43 let fiber_info = ctx.accounts.fiber.to_account_info();
44
45 if fiber_info.data_len().eq(&0) {
46 let instruction = instruction.ok_or(anchor_lang::error::ErrorCode::InstructionMissing)?;
48 let fee = priority_fee.unwrap_or(0);
49 initialize_fiber(
50 &ctx.accounts.fiber,
51 &ctx.accounts.system_program,
52 &thread_key,
53 fiber_index,
54 &instruction,
55 fee,
56 lookup_tables.unwrap_or_default(),
57 )?;
58 return Ok(());
59 }
60
61 let fiber_read = {
62 let data = fiber_info.try_borrow_data()?;
63 Fiber::try_deserialize(&mut &data[..])?
64 };
65
66 match fiber_read {
67 Fiber::Legacy(mut state) => {
68 if let Some(ref lt) = lookup_tables {
70 require!(
71 lt.is_empty(),
72 AntegenFiberError::LegacyFiberLookupTablesUnsupported
73 );
74 }
75 state.thread = thread_key;
76 apply_instruction_update(&mut state.compiled_instruction, instruction)?;
77 if let Some(fee) = priority_fee {
78 state.priority_fee = fee;
79 }
80 state.last_executed = 0;
81 state.exec_count = 0;
82 write_legacy(&fiber_info, &state)?;
83 }
84 Fiber::V1(mut state) => {
85 state.version = CURRENT_FIBER_VERSION;
86 state.thread = thread_key;
87 apply_instruction_update(&mut state.compiled_instruction, instruction)?;
88 if let Some(fee) = priority_fee {
89 state.priority_fee = fee;
90 }
91 if let Some(lt) = lookup_tables {
92 state.lookup_tables = lt;
93 }
94 state.last_executed = 0;
95 state.exec_count = 0;
96 write_versioned(&fiber_info, &state)?;
97 }
98 }
99
100 Ok(())
101}
102
103fn apply_instruction_update(
107 compiled_instruction: &mut Vec<u8>,
108 instruction: Option<Instruction>,
109) -> Result<()> {
110 if let Some(ix) = instruction {
111 let compiled = compile_instruction(ix)?;
112 *compiled_instruction = borsh::to_vec(&compiled)?;
113 } else {
114 compiled_instruction.clear();
115 }
116 Ok(())
117}