chunk_loader/instructions/
load_chunk.rs1use crate::{state::*, utils::*};
2use anchor_lang::{prelude::*, Discriminator};
3
4#[derive(Accounts)]
5#[instruction(chunk_holder_id: u32)]
6pub struct LoadChunk<'info> {
7 #[account(mut)]
8 owner: Signer<'info>,
9 #[account(
11 mut,
12 seeds = [b"CHUNK_HOLDER", &owner.key().to_bytes(), &chunk_holder_id.to_le_bytes()],
13 bump,
14 )]
15 chunk_holder: AccountInfo<'info>,
16 system_program: Program<'info, System>,
17}
18
19pub fn load_chunk(ctx: Context<LoadChunk>, chunk_holder_id: u32, chunk: Chunk) -> Result<()> {
20 let owner = &ctx.accounts.owner;
21 let chunk_holder = &ctx.accounts.chunk_holder;
22
23 let (space, data) = if chunk_holder.data_is_empty() {
24 (
25 1 + ChunkHolder::INIT_SPACE + chunk.self_space(),
26 ChunkHolder {
27 owner: owner.key(),
28 chunks: vec![chunk],
29 },
30 )
31 } else {
32 let data = chunk_holder.try_borrow_data()?;
33 let Some(rest_data) = data.strip_prefix(ChunkHolder::DISCRIMINATOR) else {
34 return err!(ErrorCode::AccountDiscriminatorMismatch);
35 };
36 let space = chunk_holder.data_len() + chunk.self_space();
37 let mut data = ChunkHolder::deserialize(&mut &rest_data[..])?;
38 data.chunks.push(chunk);
39 (space, data)
40 };
41
42 init_or_realloc_with_admin(
43 chunk_holder,
44 space,
45 owner.key(),
46 &data,
47 owner.to_account_info(),
48 &[&[
49 b"CHUNK_HOLDER",
50 &owner.key().to_bytes(),
51 &chunk_holder_id.to_le_bytes(),
52 &[ctx.bumps.chunk_holder],
53 ]],
54 false,
55 )?;
56
57 Ok(())
58}