use anchor_lang::prelude::*;
use crate::errors::*;
use crate::state::*;
#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct TransactionBufferExtendArgs {
pub buffer: Vec<u8>,
}
#[derive(Accounts)]
#[instruction(args: TransactionBufferExtendArgs)]
pub struct TransactionBufferExtend<'info> {
#[account(
seeds = [SEED_PREFIX, SEED_MULTISIG, multisig.create_key.as_ref()],
bump = multisig.bump,
)]
pub multisig: Account<'info, Multisig>,
#[account(
mut,
// Only the creator can extend the buffer
constraint = transaction_buffer.creator == creator.key() @ MultisigError::Unauthorized,
seeds = [
SEED_PREFIX,
multisig.key().as_ref(),
SEED_TRANSACTION_BUFFER,
creator.key().as_ref(),
&transaction_buffer.buffer_index.to_le_bytes()
],
bump
)]
pub transaction_buffer: Account<'info, TransactionBuffer>,
pub creator: Signer<'info>,
}
impl TransactionBufferExtend<'_> {
fn validate(&self, args: &TransactionBufferExtendArgs) -> Result<()> {
let Self {
multisig,
creator,
transaction_buffer,
..
} = self;
require!(
multisig.is_member(creator.key()).is_some(),
MultisigError::NotAMember
);
require!(
multisig.member_has_permission(creator.key(), Permission::Initiate),
MultisigError::Unauthorized
);
let current_buffer_size = transaction_buffer.buffer.len() as u16;
let remaining_space = transaction_buffer
.final_buffer_size
.checked_sub(current_buffer_size)
.unwrap();
let new_data_size = args.buffer.len() as u16;
require!(
new_data_size <= remaining_space,
MultisigError::FinalBufferSizeExceeded
);
Ok(())
}
#[access_control(ctx.accounts.validate(&args))]
pub fn transaction_buffer_extend(
ctx: Context<Self>,
args: TransactionBufferExtendArgs,
) -> Result<()> {
let transaction_buffer = &mut ctx.accounts.transaction_buffer;
let buffer_slice_extension = args.buffer;
transaction_buffer
.buffer
.extend_from_slice(&buffer_slice_extension);
transaction_buffer.invariant()?;
Ok(())
}
}