Skip to main content

antegen_fiber_program/instructions/
fiber_update.rs

1use crate::constants::*;
2use crate::state::*;
3use anchor_lang::prelude::*;
4use anchor_lang::solana_program::instruction::Instruction;
5
6use super::fiber_create::initialize_fiber;
7
8/// Accounts required by the `update_fiber` instruction.
9/// Thread PDA must be signer. Fiber must be pre-funded if not yet initialized.
10#[derive(Accounts)]
11#[instruction(fiber_index: u8)]
12pub struct FiberUpdate<'info> {
13    /// Thread PDA - must be signer
14    pub thread: Signer<'info>,
15
16    /// CHECK: Validated via seeds — may not be initialized yet
17    #[account(
18        mut,
19        seeds = [SEED_THREAD_FIBER, thread.key().as_ref(), &[fiber_index]],
20        bump,
21    )]
22    pub fiber: UncheckedAccount<'info>,
23
24    pub system_program: Program<'info, System>,
25}
26
27pub fn fiber_update(
28    ctx: Context<FiberUpdate>,
29    fiber_index: u8,
30    instruction: Instruction,
31    priority_fee: Option<u64>,
32) -> Result<()> {
33    let thread_key = ctx.accounts.thread.key();
34    let fiber_info = ctx.accounts.fiber.to_account_info();
35
36    if fiber_info.data_len().eq(&0) {
37        // Not initialized — do full init (same as fiber_create)
38        let fee = priority_fee.unwrap_or(0);
39        initialize_fiber(
40            &ctx.accounts.fiber,
41            &ctx.accounts.system_program,
42            &thread_key,
43            fiber_index,
44            &instruction,
45            fee,
46        )?;
47    } else {
48        // Already initialized — update in place
49        // Deserialize existing account
50        let mut data = fiber_info.try_borrow_mut_data()?;
51
52        // Verify discriminator
53        let discriminator = FiberState::DISCRIMINATOR;
54        if data[..8] != discriminator[..] {
55            return Err(anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch.into());
56        }
57
58        // Recompile the instruction
59        let compiled = compile_instruction(instruction)?;
60        let compiled_bytes = borsh::to_vec(&compiled)?;
61
62        // Build updated state
63        let mut state: FiberState = FiberState::try_deserialize(&mut &data[..])?;
64        state.thread = thread_key;
65        state.compiled_instruction = compiled_bytes;
66        if let Some(fee) = priority_fee {
67            state.priority_fee = fee;
68        }
69        state.last_executed = 0;
70        state.exec_count = 0;
71
72        // Re-serialize
73        let state_bytes = borsh::to_vec(&state)?;
74        data[8..8 + state_bytes.len()].copy_from_slice(&state_bytes);
75    }
76
77    Ok(())
78}