antegen_thread_program/instructions/
fiber_update.rs

1use crate::{errors::*, state::compile_instruction, *};
2use anchor_lang::{prelude::*, solana_program::instruction::Instruction};
3
4/// Accounts required by the `fiber_update` instruction.
5#[derive(Accounts)]
6#[instruction(instruction: SerializableInstruction)]
7pub struct FiberUpdate<'info> {
8    /// The authority of the thread or the thread itself
9    #[account(
10        constraint = authority.key().eq(&thread.authority) || authority.key().eq(&thread.key())
11    )]
12    pub authority: Signer<'info>,
13
14    /// The thread the fiber belongs to
15    #[account(
16        address = fiber.thread,
17    )]
18    pub thread: Account<'info, Thread>,
19
20    /// The fiber account to update
21    #[account(
22        mut,
23        constraint = fiber.thread == thread.key() @ AntegenThreadError::InvalidFiberAccount,
24    )]
25    pub fiber: Account<'info, FiberState>,
26}
27
28pub fn fiber_update(ctx: Context<FiberUpdate>, instruction: Instruction) -> Result<()> {
29    // Prevent thread_delete instructions in fibers
30    if instruction.program_id.eq(&crate::ID)
31        && instruction.data.len() >= 8
32        && instruction.data[..8].eq(crate::instruction::DeleteThread::DISCRIMINATOR)
33    {
34        return Err(AntegenThreadError::InvalidInstruction.into());
35    }
36
37    let fiber: &mut Account<'_, FiberState> = &mut ctx.accounts.fiber;
38    let thread: &Account<'_, Thread> = &ctx.accounts.thread;
39
40    let signer_seeds = vec![vec![
41        SEED_THREAD.to_vec(),
42        thread.authority.to_bytes().to_vec(),
43        thread.id.clone(),
44    ]];
45
46    // Compile the new instruction
47    let compiled: CompiledInstructionV0 = compile_instruction(instruction, signer_seeds)?;
48    let compiled_bytes: Vec<u8> = compiled.try_to_vec()?;
49
50    // Update fiber with new instruction and reset stats
51    fiber.compiled_instruction = compiled_bytes;
52    fiber.last_executed = 0;
53    fiber.exec_count = 0;
54
55    Ok(())
56}