lang: add rent exempt check for init_if_needed when init is not needed (#1250)

This commit is contained in:
Paul 2022-01-06 21:31:36 +01:00 committed by GitHub
parent a830644203
commit 4d4cba5add
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 0 deletions

View File

@ -13,6 +13,7 @@ incremented for features.
### Fixes
* lang: `init_if_needed` now checks rent exemption when init is not needed ([#1250](https://github.com/project-serum/anchor/pull/1250)).
* lang: Add missing owner check when `associated_token::authority` is used ([#1240](https://github.com/project-serum/anchor/pull/1240)).
* ts: Add type declarations for conditional `workspace` and `Wallet` exports ([#1137](https://github.com/project-serum/anchor/pull/1137)).
* ts: Change commitment message `recent` to `processed` and `max` to `finalized` ([#1128](https://github.com/project-serum/anchor/pull/1128))

View File

@ -621,6 +621,13 @@ pub fn generate_init(
return Err(anchor_lang::__private::ErrorCode::ConstraintOwner.into());
}
{
let required_lamports = __anchor_rent.minimum_balance(space);
if pa.to_account_info().lamports() < required_lamports {
return Err(anchor_lang::__private::ErrorCode::ConstraintRentExempt.into());
}
}
#pda_check
}
pa

View File

@ -360,3 +360,22 @@ pub struct EnforceRentExempt<'info> {
#[account(rent_exempt = enforce)]
pub data: AccountInfo<'info>,
}
#[derive(Accounts)]
pub struct InitDecreaseLamports<'info> {
#[account(init, payer = user, space = 1000)]
pub data: AccountInfo<'info>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>
}
#[derive(Accounts)]
pub struct InitIfNeededChecksRentExemption<'info> {
#[account(init_if_needed, payer = user, space = 1000)]
pub data: AccountInfo<'info>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>
}

View File

@ -258,4 +258,14 @@ pub mod misc {
pub fn test_enforce_rent_exempt(ctx: Context<EnforceRentExempt>) -> ProgramResult {
Ok(())
}
pub fn init_decrease_lamports(ctx: Context<InitDecreaseLamports>) -> ProgramResult {
**ctx.accounts.data.try_borrow_mut_lamports()? -= 1;
**ctx.accounts.user.try_borrow_mut_lamports()? += 1;
Ok(())
}
pub fn init_if_needed_checks_rent_exemption(_ctx: Context<InitIfNeededChecksRentExemption>) -> ProgramResult {
Ok(())
}
}

View File

@ -1398,6 +1398,32 @@ describe("misc", () => {
}
});
it("init_if_needed checks rent_exemption if init is not needed", async () => {
const data = anchor.web3.Keypair.generate();
await program.rpc.initDecreaseLamports({
accounts: {
data: data.publicKey,
user: anchor.getProvider().wallet.publicKey,
systemProgram: SystemProgram.programId,
},
signers: [data],
});
try {
await program.rpc.initIfNeededChecksRentExemption({
accounts: {
data: data.publicKey,
user: anchor.getProvider().wallet.publicKey,
systemProgram: SystemProgram.programId,
},
signers: [data],
});
assert.ok(false);
} catch (err) {
assert.equal(err.code, 2005);
}
});
it("Can use multidimensional array", async () => {
const array2d = new Array(10).fill(new Array(10).fill(99));
const data = anchor.web3.Keypair.generate();