squads_multisig_program/instructions/
transaction_buffer_extend.rs1use anchor_lang::prelude::*;
2
3use crate::errors::*;
4use crate::state::*;
5
6#[derive(AnchorSerialize, AnchorDeserialize)]
7pub struct TransactionBufferExtendArgs {
8 pub buffer: Vec<u8>,
10}
11
12#[derive(Accounts)]
13#[instruction(args: TransactionBufferExtendArgs)]
14pub struct TransactionBufferExtend<'info> {
15 #[account(
16 seeds = [SEED_PREFIX, SEED_MULTISIG, multisig.create_key.as_ref()],
17 bump = multisig.bump,
18 )]
19 pub multisig: Account<'info, Multisig>,
20
21 #[account(
22 mut,
23 constraint = transaction_buffer.creator == creator.key() @ MultisigError::Unauthorized,
25 seeds = [
26 SEED_PREFIX,
27 multisig.key().as_ref(),
28 SEED_TRANSACTION_BUFFER,
29 creator.key().as_ref(),
30 &transaction_buffer.buffer_index.to_le_bytes()
31 ],
32 bump
33 )]
34 pub transaction_buffer: Account<'info, TransactionBuffer>,
35
36 pub creator: Signer<'info>,
38}
39
40impl TransactionBufferExtend<'_> {
41 fn validate(&self, args: &TransactionBufferExtendArgs) -> Result<()> {
42 let Self {
43 multisig,
44 creator,
45 transaction_buffer,
46 ..
47 } = self;
48
49 require!(
51 multisig.is_member(creator.key()).is_some(),
52 MultisigError::NotAMember
53 );
54
55 require!(
57 multisig.member_has_permission(creator.key(), Permission::Initiate),
58 MultisigError::Unauthorized
59 );
60
61 let current_buffer_size = transaction_buffer.buffer.len() as u16;
64 let remaining_space = transaction_buffer
65 .final_buffer_size
66 .checked_sub(current_buffer_size)
67 .unwrap();
68
69 let new_data_size = args.buffer.len() as u16;
71 require!(
72 new_data_size <= remaining_space,
73 MultisigError::FinalBufferSizeExceeded
74 );
75
76 Ok(())
77 }
78
79 #[access_control(ctx.accounts.validate(&args))]
81 pub fn transaction_buffer_extend(
82 ctx: Context<Self>,
83 args: TransactionBufferExtendArgs,
84 ) -> Result<()> {
85 let transaction_buffer = &mut ctx.accounts.transaction_buffer;
87
88 let buffer_slice_extension = args.buffer;
90
91 transaction_buffer
93 .buffer
94 .extend_from_slice(&buffer_slice_extension);
95
96 transaction_buffer.invariant()?;
98
99 Ok(())
100 }
101}