use crate::constants::*;
use crate::state::*;
use anchor_lang::prelude::*;
use anchor_lang::solana_program::instruction::Instruction;
use super::create::initialize_fiber;
#[derive(Accounts)]
#[instruction(fiber_index: u8)]
pub struct Update<'info> {
pub thread: Signer<'info>,
#[account(
mut,
seeds = [SEED_THREAD_FIBER, thread.key().as_ref(), &[fiber_index]],
bump,
)]
pub fiber: UncheckedAccount<'info>,
pub system_program: Program<'info, System>,
}
pub fn update(
ctx: Context<Update>,
fiber_index: u8,
instruction: Option<Instruction>,
priority_fee: Option<u64>,
) -> Result<()> {
let thread_key = ctx.accounts.thread.key();
let fiber_info = ctx.accounts.fiber.to_account_info();
if fiber_info.data_len().eq(&0) {
let instruction = instruction.ok_or(anchor_lang::error::ErrorCode::InstructionMissing)?;
let fee = priority_fee.unwrap_or(0);
initialize_fiber(
&ctx.accounts.fiber,
&ctx.accounts.system_program,
&thread_key,
fiber_index,
&instruction,
fee,
)?;
} else {
let mut data = fiber_info.try_borrow_mut_data()?;
let discriminator = FiberState::DISCRIMINATOR;
if data[..8] != discriminator[..] {
return Err(anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch.into());
}
let mut state: FiberState = FiberState::try_deserialize(&mut &data[..])?;
state.thread = thread_key;
if let Some(instruction) = instruction {
let compiled = compile_instruction(instruction)?;
state.compiled_instruction = borsh::to_vec(&compiled)?;
} else {
state.compiled_instruction = vec![];
}
if let Some(fee) = priority_fee {
state.priority_fee = fee;
}
state.last_executed = 0;
state.exec_count = 0;
let state_bytes = borsh::to_vec(&state)?;
data[8..8 + state_bytes.len()].copy_from_slice(&state_bytes);
}
Ok(())
}