Skip to content
31 changes: 30 additions & 1 deletion programs/system/src/instructions/create_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use pinocchio::{
instruction::{AccountMeta, Instruction, Signer},
program::invoke_signed,
pubkey::Pubkey,
sysvars::rent::Rent,
program_error::ProgramError,
ProgramResult,
};

Expand All @@ -28,7 +30,34 @@ pub struct CreateAccount<'a> {
pub owner: &'a Pubkey,
}

impl CreateAccount<'_> {
impl<'a> CreateAccount<'a> {
pub fn with_rent_check(
from: &'a AccountInfo,
to: &'a AccountInfo,
rent_sysvar: &'a AccountInfo,
space: u64,
owner: &'a Pubkey,
) -> Result<Self, ProgramError> {
let rent = Rent::from_account_info(rent_sysvar)?;
let lamports = rent.minimum_balance(space as usize);

if from.lamports() < lamports {
return Err(ProgramError::InsufficientFunds);
}

if !to.data_is_empty() {
return Err(ProgramError::InvalidAccountData);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not too sure if we need this checks – the CPI will do this validation and raised the appropriate error.


Ok(Self {
from,
to,
lamports,
space,
owner,
})
}

#[inline(always)]
pub fn invoke(&self) -> ProgramResult {
self.invoke_signed(&[])
Expand Down
41 changes: 39 additions & 2 deletions programs/system/src/instructions/create_account_with_seed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use pinocchio::{
account_info::AccountInfo,
instruction::{AccountMeta, Instruction, Signer},
program::invoke_signed,
pubkey::Pubkey,
program_error::ProgramError,
pubkey::{Pubkey, MAX_SEED_LEN},
sysvars::rent::Rent,
ProgramResult,
};

Expand Down Expand Up @@ -40,7 +42,42 @@ pub struct CreateAccountWithSeed<'a, 'b, 'c> {
pub owner: &'c Pubkey,
}

impl CreateAccountWithSeed<'_, '_, '_> {
impl<'a, 'b, 'c> CreateAccountWithSeed<'a, 'b, 'c> {
pub fn with_rent_check(
from: &'a AccountInfo,
to: &'a AccountInfo,
base: Option<&'a AccountInfo>,
seed: &'b str,
rent_sysvar: &'a AccountInfo,
space: u64,
owner: &'c Pubkey,
) -> Result<Self, ProgramError> {
let rent = Rent::from_account_info(rent_sysvar)?;
let lamports = rent.minimum_balance(space as usize);

if seed.len() > MAX_SEED_LEN {
return Err(ProgramError::InvalidInstructionData);
}

if from.lamports() < lamports {
return Err(ProgramError::InsufficientFunds);
}

if !to.data_is_empty() {
return Err(ProgramError::InvalidAccountData);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, might be better to remove this checks.


Ok(Self {
from,
to,
base,
seed,
lamports,
space,
owner,
})
}

#[inline(always)]
pub fn invoke(&self) -> ProgramResult {
self.invoke_signed(&[])
Expand Down