From b6cbdb257ee7a55ae8497f3de908fb3a8d35aae8 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 30 Dec 2021 21:25:10 +0100 Subject: [PATCH] tests: add tests for rent_exempt constraint (#1209) --- tests/misc/programs/misc/src/context.rs | 28 +++++++- tests/misc/programs/misc/src/lib.rs | 35 ++++++++-- tests/misc/tests/misc.js | 87 +++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 8 deletions(-) diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs index f0a34b431..cc7c1847b 100644 --- a/tests/misc/programs/misc/src/context.rs +++ b/tests/misc/programs/misc/src/context.rs @@ -123,6 +123,17 @@ pub struct Initialize<'info> { pub data: Account<'info, Data>, } +#[derive(Accounts)] +pub struct InitializeSkipRentExempt<'info> { + #[account(zero, rent_exempt = skip)] + pub data: Account<'info, Data>, +} + +#[derive(Accounts)] +pub struct InitializeNoRentExempt<'info> { + pub data: AccountInfo<'info>, +} + #[derive(Accounts)] pub struct TestOwner<'info> { #[account(owner = *misc.key)] @@ -267,7 +278,7 @@ pub struct TestInitIfNeededChecksOwner<'info> { pub data: UncheckedAccount<'info>, pub payer: Signer<'info>, pub system_program: Program<'info, System>, - pub owner: AccountInfo<'info> + pub owner: AccountInfo<'info>, } #[derive(Accounts)] @@ -291,7 +302,7 @@ pub struct TestInitMintIfNeeded<'info> { pub system_program: AccountInfo<'info>, pub token_program: AccountInfo<'info>, pub mint_authority: AccountInfo<'info>, - pub freeze_authority: AccountInfo<'info>, + pub freeze_authority: AccountInfo<'info>, } #[derive(Accounts)] @@ -322,7 +333,7 @@ pub struct TestInitAssociatedTokenIfNeeded<'info> { pub system_program: Program<'info, System>, pub token_program: Program<'info, Token>, pub associated_token_program: Program<'info, AssociatedToken>, - pub authority: AccountInfo<'info> + pub authority: AccountInfo<'info>, } #[derive(Accounts)] @@ -336,3 +347,14 @@ pub struct TestConstArraySize<'info> { #[account(zero)] pub data: Account<'info, DataConstArraySize>, } + +#[derive(Accounts)] +pub struct NoRentExempt<'info> { + pub data: AccountInfo<'info>, +} + +#[derive(Accounts)] +pub struct EnforceRentExempt<'info> { + #[account(rent_exempt = enforce)] + pub data: AccountInfo<'info>, +} diff --git a/tests/misc/programs/misc/src/lib.rs b/tests/misc/programs/misc/src/lib.rs index 8a77ccb4b..0f89fcf84 100644 --- a/tests/misc/programs/misc/src/lib.rs +++ b/tests/misc/programs/misc/src/lib.rs @@ -48,6 +48,14 @@ pub mod misc { Ok(()) } + pub fn initialize_no_rent_exempt(ctx: Context) -> ProgramResult { + Ok(()) + } + + pub fn initialize_skip_rent_exempt(ctx: Context) -> ProgramResult { + Ok(()) + } + pub fn test_owner(_ctx: Context) -> ProgramResult { Ok(()) } @@ -201,15 +209,23 @@ pub mod misc { Ok(()) } - pub fn test_init_if_needed_checks_owner(ctx: Context) -> ProgramResult { + pub fn test_init_if_needed_checks_owner( + ctx: Context, + ) -> ProgramResult { Ok(()) } - pub fn test_init_if_needed_checks_seeds(ctx: Context, seed_data: String) -> ProgramResult { + pub fn test_init_if_needed_checks_seeds( + ctx: Context, + seed_data: String, + ) -> ProgramResult { Ok(()) } - pub fn test_init_mint_if_needed(ctx: Context, decimals: u8) -> ProgramResult { + pub fn test_init_mint_if_needed( + ctx: Context, + decimals: u8, + ) -> ProgramResult { Ok(()) } @@ -217,7 +233,9 @@ pub mod misc { Ok(()) } - pub fn test_init_associated_token_if_needed(ctx: Context) -> ProgramResult { + pub fn test_init_associated_token_if_needed( + ctx: Context, + ) -> ProgramResult { Ok(()) } @@ -225,7 +243,6 @@ pub mod misc { Ok(()) } - pub fn test_multidimensional_array( ctx: Context, data: [[u8; 10]; 10], @@ -233,4 +250,12 @@ pub mod misc { ctx.accounts.data.data = data; Ok(()) } + + pub fn test_no_rent_exempt(ctx: Context) -> ProgramResult { + Ok(()) + } + + pub fn test_enforce_rent_exempt(ctx: Context) -> ProgramResult { + Ok(()) + } } diff --git a/tests/misc/tests/misc.js b/tests/misc/tests/misc.js index 3cd405a91..fceabbfa9 100644 --- a/tests/misc/tests/misc.js +++ b/tests/misc/tests/misc.js @@ -7,6 +7,7 @@ const { Token, } = require("@solana/spl-token"); const miscIdl = require("../target/idl/misc.json"); +const { SystemProgram } = require("@solana/web3.js"); const utf8 = anchor.utils.bytes.utf8; describe("misc", () => { @@ -1299,4 +1300,90 @@ describe("misc", () => { ); assert.deepStrictEqual(dataAccount.data, array2d); }); + + it("allows non-rent exempt accounts", async () => { + const data = anchor.web3.Keypair.generate(); + await program.rpc.initializeNoRentExempt({ + accounts: { + data: data.publicKey, + rent: anchor.web3.SYSVAR_RENT_PUBKEY, + }, + signers: [data], + instructions: [ + SystemProgram.createAccount({ + programId: program.programId, + space: 8 + 16 + 16, + lamports: + await program.provider.connection.getMinimumBalanceForRentExemption( + 39 + ), + fromPubkey: anchor.getProvider().wallet.publicKey, + newAccountPubkey: data.publicKey, + }), + ], + }); + await program.rpc.testNoRentExempt({ + accounts: { + data: data.publicKey, + }, + }); + }); + + it("allows rent exemption to be skipped", async () => { + const data = anchor.web3.Keypair.generate(); + await program.rpc.initializeSkipRentExempt({ + accounts: { + data: data.publicKey, + rent: anchor.web3.SYSVAR_RENT_PUBKEY, + }, + signers: [data], + instructions: [ + SystemProgram.createAccount({ + programId: program.programId, + space: 8 + 16 + 16, + lamports: + await program.provider.connection.getMinimumBalanceForRentExemption( + 39 + ), + fromPubkey: anchor.getProvider().wallet.publicKey, + newAccountPubkey: data.publicKey, + }), + ], + }); + }); + + it("can use rent_exempt to enforce rent exemption", async () => { + const data = anchor.web3.Keypair.generate(); + await program.rpc.initializeSkipRentExempt({ + accounts: { + data: data.publicKey, + rent: anchor.web3.SYSVAR_RENT_PUBKEY, + }, + signers: [data], + instructions: [ + SystemProgram.createAccount({ + programId: program.programId, + space: 8 + 16 + 16, + lamports: + await program.provider.connection.getMinimumBalanceForRentExemption( + 39 + ), + fromPubkey: anchor.getProvider().wallet.publicKey, + newAccountPubkey: data.publicKey, + }), + ], + }); + + try { + await program.rpc.testEnforceRentExempt({ + accounts: { + data: data.publicKey, + }, + }); + assert.ok(false); + } catch (err) { + assert.equal(2005, err.code); + assert.equal("A rent exempt constraint was violated", err.msg); + } + }); });