antegen_fiber_program/instructions/
fiber_create.rs1use crate::constants::*;
2use crate::errors::AntegenFiberError;
3use crate::state::*;
4use anchor_lang::prelude::*;
5use anchor_lang::solana_program::instruction::Instruction;
6use anchor_lang::solana_program::program::invoke_signed;
7use anchor_lang::solana_program::system_instruction;
8
9#[derive(Accounts)]
12#[instruction(fiber_index: u8)]
13pub struct FiberCreate<'info> {
14 pub thread: Signer<'info>,
16
17 #[account(mut)]
19 pub fiber: UncheckedAccount<'info>,
20
21 pub system_program: Program<'info, System>,
22}
23
24pub fn fiber_create(
25 ctx: Context<FiberCreate>,
26 fiber_index: u8,
27 instruction: Instruction,
28 priority_fee: u64,
29) -> Result<()> {
30 let thread_key = ctx.accounts.thread.key();
31 let fiber_info = ctx.accounts.fiber.to_account_info();
32
33 if fiber_info.data_len() == 0 {
34 initialize_fiber(
36 &ctx.accounts.fiber,
37 &ctx.accounts.system_program,
38 &thread_key,
39 fiber_index,
40 &instruction,
41 priority_fee,
42 )
43 } else {
44 let mut data = fiber_info.try_borrow_mut_data()?;
46 let discriminator = FiberState::DISCRIMINATOR;
47 if data[..8] != discriminator[..] {
48 return Err(anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch.into());
49 }
50
51 let compiled = compile_instruction(instruction)?;
52 let compiled_bytes = borsh::to_vec(&compiled)?;
53
54 let mut state: FiberState = FiberState::try_deserialize(&mut &data[..])?;
55 state.thread = thread_key;
56 state.compiled_instruction = compiled_bytes;
57 state.priority_fee = priority_fee;
58 state.last_executed = 0;
59 state.exec_count = 0;
60
61 let state_bytes = borsh::to_vec(&state)?;
62 data[8..8 + state_bytes.len()].copy_from_slice(&state_bytes);
63 Ok(())
64 }
65}
66
67pub fn initialize_fiber<'info>(
72 fiber: &UncheckedAccount<'info>,
73 system_program: &Program<'info, System>,
74 thread_key: &Pubkey,
75 fiber_index: u8,
76 instruction: &Instruction,
77 priority_fee: u64,
78) -> Result<()> {
79 let fiber_info = fiber.to_account_info();
80
81 let (expected_pda, bump) = Pubkey::find_program_address(
83 &[SEED_THREAD_FIBER, thread_key.as_ref(), &[fiber_index]],
84 &crate::ID,
85 );
86 require!(
87 expected_pda.eq(&fiber.key()),
88 AntegenFiberError::InvalidFiberPDA
89 );
90
91 let space = 8 + FiberState::INIT_SPACE;
93 let rent = Rent::get()?;
94 let min_lamports = rent.minimum_balance(space);
95 require!(
96 fiber_info.lamports().ge(&min_lamports),
97 AntegenFiberError::InsufficientRent
98 );
99
100 let seeds: &[&[u8]] = &[
102 SEED_THREAD_FIBER,
103 thread_key.as_ref(),
104 &[fiber_index],
105 &[bump],
106 ];
107
108 invoke_signed(
109 &system_instruction::allocate(&fiber.key(), space as u64),
110 &[fiber_info.clone(), system_program.to_account_info()],
111 &[seeds],
112 )?;
113
114 invoke_signed(
116 &system_instruction::assign(&fiber.key(), &crate::ID),
117 &[fiber_info.clone(), system_program.to_account_info()],
118 &[seeds],
119 )?;
120
121 let compiled = compile_instruction(instruction.clone())?;
123 let compiled_bytes = borsh::to_vec(&compiled)?;
124
125 let state = FiberState {
126 thread: *thread_key,
127 compiled_instruction: compiled_bytes,
128 priority_fee,
129 last_executed: 0,
130 exec_count: 0,
131 };
132
133 let mut data = fiber_info.try_borrow_mut_data()?;
135 let discriminator = FiberState::DISCRIMINATOR;
136 data[..8].copy_from_slice(discriminator);
137
138 let state_bytes = borsh::to_vec(&state)?;
140 data[8..8 + state_bytes.len()].copy_from_slice(&state_bytes);
141
142 Ok(())
143}