Use case
- Minimizing required syscalls and saving CUs during account initialization.
What are you trying to do?
Currently, the #[derive(Accounts)] macro uses RentPlan::FetchOnce for instructions involving init or realloc. This unconditionally executes the sol_get_sysvar syscall at the start of the instruction, costing ~100 to 150 CUs.
During initialization in lang/src/cpi/system.rs, the framework uses Rent strictly to check if an account requires additional lamports:
let lamports = rent.try_minimum_balance(space as usize)?;
if account.lamports() >= lamports {
// Allocate + Assign
} else {
// CreateAccount (transfers lamports)
}
If an account is pre-funded, the framework doesn't actually need to calculate the minimum balance. The Solana runtime natively enforces rent-exemption at the end of the transaction anyway. Fetching the Rent sysvar for pre-funded accounts wastes ~150 CUs for no reason.
Proposed solution
We can move the Rent sysvar fetch to be completely lazy, executing only if an on-chain transfer is strictly required (when account.lamports() == 0).
- Modify
RentPlan::FetchOnce in the derive macro so that it passes a lazy closure or Option<Rent> to the initialization context instead of eagerly fetching the sysvar.
- Update
init_account_with_rent (in lang/src/cpi/system.rs) to check if account.lamports() > 0 before attempting to evaluate the minimum rent balance.
- If true, safely skip the
Rent syscall and proceed directly with Allocate and Assign (the SVM guarantees rent-exemption safety at the end of the transaction).
- If false, invoke the lazy fetch (
sol_get_sysvar) to determine the exact lamports required for the System Program transfer.
This saves ~150 CUs for pre-funded initialization paths automatically.
Use case
What are you trying to do?
Currently, the
#[derive(Accounts)]macro usesRentPlan::FetchOncefor instructions involvinginitorrealloc. This unconditionally executes thesol_get_sysvarsyscall at the start of the instruction, costing ~100 to 150 CUs.During initialization in
lang/src/cpi/system.rs, the framework usesRentstrictly to check if an account requires additional lamports:If an account is pre-funded, the framework doesn't actually need to calculate the minimum balance. The Solana runtime natively enforces rent-exemption at the end of the transaction anyway. Fetching the Rent sysvar for pre-funded accounts wastes ~150 CUs for no reason.
Proposed solution
We can move the
Rentsysvar fetch to be completely lazy, executing only if an on-chain transfer is strictly required (whenaccount.lamports() == 0).RentPlan::FetchOncein thederivemacro so that it passes a lazy closure orOption<Rent>to the initialization context instead of eagerly fetching the sysvar.init_account_with_rent(inlang/src/cpi/system.rs) to checkif account.lamports() > 0before attempting to evaluate the minimum rent balance.Rentsyscall and proceed directly withAllocateandAssign(the SVM guarantees rent-exemption safety at the end of the transaction).sol_get_sysvar) to determine the exact lamports required for the System Program transfer.This saves ~150 CUs for pre-funded initialization paths automatically.