use crate::{errors::*, state::compile_instruction, *};
use anchor_lang::{prelude::*, solana_program::instruction::Instruction};
#[derive(Accounts)]
#[instruction(fiber_index: u8)]
pub struct FiberCreate<'info> {
#[account(
constraint = authority.key().eq(&thread.authority) || authority.key().eq(&thread.key())
)]
pub authority: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
#[account(
mut,
seeds = [
SEED_THREAD,
thread.authority.as_ref(),
thread.id.as_slice(),
],
bump = thread.bump,
)]
pub thread: Account<'info, Thread>,
#[account(
init,
seeds = [
SEED_THREAD_FIBER,
thread.key().as_ref(),
&[fiber_index],
],
bump,
payer = payer,
space = 8 + FiberState::INIT_SPACE
)]
pub fiber: Account<'info, FiberState>,
#[account(address = anchor_lang::system_program::ID)]
pub system_program: Program<'info, System>,
}
pub fn fiber_create(
ctx: Context<FiberCreate>,
fiber_index: u8,
instruction: Instruction,
signer_seeds: Vec<Vec<Vec<u8>>>,
priority_fee: u64,
) -> Result<()> {
let thread = &mut ctx.accounts.thread;
require!(
fiber_index == thread.fiber_next_id,
AntegenThreadError::InvalidFiberIndex
);
if instruction.program_id.eq(&crate::ID)
&& instruction.data.len().ge(&8)
&& instruction.data[..8].eq(crate::instruction::DeleteThread::DISCRIMINATOR)
{
return Err(AntegenThreadError::InvalidInstruction.into());
}
let fiber = &mut ctx.accounts.fiber;
let compiled = compile_instruction(instruction, signer_seeds)?;
let compiled_bytes = borsh::to_vec(&compiled)?;
fiber.thread = thread.key();
fiber.fiber_index = fiber_index;
fiber.compiled_instruction = compiled_bytes;
fiber.priority_fee = priority_fee;
fiber.last_executed = 0;
fiber.exec_count = 0;
if !thread.fiber_ids.contains(&fiber_index) {
thread.fiber_ids.push(fiber_index);
thread.fiber_ids.sort();
}
thread.fiber_next_id = thread.fiber_next_id.saturating_add(1);
Ok(())
}