Open perlish opened 11 months ago
There are a few more bytes allocated to the stack for the bumps so it could cause problems if your instruction in 0.26
was on the edge of maxing out stack memory. You get a lot more heap space with 0.29
so I'd try heap allocating some parts e.g. acounts.
+1 same problem here
Do you have an example instruction that go over the limit compared to previous Anchor version? I can't think of anything else other than the bump change which would add about 8 bytes but we also have a lot of reductions in other places.
Do you have an example instruction that go over the limit compared to previous Anchor version? I can't think of anything else other than the bump change which would add about 8 bytes but we also have a lot of reductions in other places.
Sure! it's a instruction with lots of initializations, was working fine on 0.27, but it breaks the stack limit on 0.29.
I'm changing the accounts to use zero_copy but the main issue are the bumps. Maybe it can be disabled? I could pass them as arguments.
Error: Function _ZN221_$LT$bliv..instructions..initialize_fixed_maturity_market..InitializeFixedMaturityMarket$u20$as$u20$anchor_lang..Accounts$LT$bliv..instructions..initialize_fixed_maturity_market..InitializeFixedMaturityMarketBumps$GT$$GT$12try_accounts17he2ac8ac050d3592aE Stack offset of 5728 exceeded max offset of 4096 by 1632 bytes, please minimize large stack variables
#[derive(Accounts)]
#[instruction(
maturity: u64,
)]
pub struct InitializeFixedMaturityMarket<'info> {
#[account(mut, constraint = market.admin == admin.key())]
pub admin: Signer<'info>,
#[account(
mut,
seeds = [
b"market",
market_token_mint.key().as_ref(),
],
bump = market.bump[0],
constraint = market.admin == admin.key(),
constraint = market.market_token_mint == market_token_mint.key()
)]
pub market: Box<Account<'info, Market>>,
#[account(
constraint = market.market_token_mint == market_token_mint.key()
)]
pub market_token_mint: Box<Account<'info, Mint>>,
#[account(
init,
payer = admin,
seeds = [
b"fixed_maturity_market",
market.key().as_ref(),
principal_token_mint.key().as_ref(),
yield_token_mint.key().as_ref(),
],
bump,
space = FixedMaturityMarket::LEN + 8,
)]
pub fixed_maturity_market: Box<Account<'info, FixedMaturityMarket>>,
#[account(
mut,
seeds = [
b"bliv_token_mint",
market.market_token_mint.key().as_ref()
],
bump = market.bliv_token_mint_bump[0],
)]
pub bliv_token_mint: Box<Account<'info, Mint>>,
#[account(
init,
payer = admin,
token::mint = bliv_token_mint,
token::authority = fixed_maturity_market,
)]
pub bliv_token_vault: Box<Account<'info, TokenAccount>>,
#[account(
init,
payer = admin,
seeds = [
b"principal_token_mint",
market.key().as_ref(),
maturity.to_le_bytes().as_ref(),
],
bump,
mint::decimals = market_token_mint.decimals,
mint::authority = fixed_maturity_market,
)]
pub principal_token_mint: Box<Account<'info, Mint>>,
/// CHECK: checked via the Metadata CPI call
#[account(mut)]
pub principal_token_metadata: UncheckedAccount<'info>,
#[account(
init,
payer = admin,
token::mint = principal_token_mint,
token::authority = fixed_maturity_market,
)]
pub principal_token_vault: Box<Account<'info, TokenAccount>>,
#[account(
init,
payer = admin,
seeds = [
b"yield_token_mint",
market.key().as_ref(),
maturity.to_le_bytes().as_ref(),
],
bump,
mint::decimals = market_token_mint.decimals,
mint::authority = fixed_maturity_market,
)]
pub yield_token_mint: Box<Account<'info, Mint>>,
/// CHECK: checked via the Metadata CPI call
#[account(mut)]
pub yield_token_metadata: UncheckedAccount<'info>,
#[account(
init,
payer = admin,
token::mint = yield_token_mint,
token::authority = fixed_maturity_market,
)]
pub yield_token_vault: Box<Account<'info, TokenAccount>>,
/// CHECK: checked via account constraints
#[account(address = mpl_token_metadata::ID)]
pub metadata_program: UncheckedAccount<'info>,
pub system_program: Program<'info, System>,
pub token_program: Program<'info, Token>,
pub rent: Sysvar<'info, Rent>,
}
Thank you for sharing. I think you should be able to fix this by removing the rent
account and using:
let rent = Rent::get()?;
I'm changing the accounts to use zero_copy but the main issue are the bumps. Maybe it can be disabled? I could pass them as arguments.
5 bumps is bytes(8 because of alignment) so it's pretty small but I agree, it might be good idea to add ability to disable caching bumps.
@acheroncrypto removing rent from instruction only saved 32 bytes :/
It complaints about the bumps on try_accounts:
InitializeFixedMaturityMarketBumps$GT$$GT$12try_accounts17he2ac8ac050d3592aE
I changed my big accounts to use zero copy, but it still is exceeding the stack, now by only 136 bytes.
Interesting enough, removing only 1 TokenAccount initialization, it reduces 464 bytes! So with 6 initializations it adds ~2784 to the stack. Looks like there's really something odd in when using lots of inits and bumps
I guess I'll need to move some initializations to other instruction as a workaround. Any other idea?
Appreciate the help.
I changed my big accounts to use zero copy, but it still is exceeding the stack, now by only 136 bytes.
I think something is off here because there are 5 bumps in your instruction and each bump is 1 byte so it should never add hundreds of bytes to the stack even if some of them gets copied.
Can you try using
anchor-lang = { git = "https://github.com/febo/anchor", branch = "febo/boxed-bumps" }
and let me know whether it fixes your issue?
I recently attempted to upgrade contract from version 26 to version 29. However, after upgrade I encountered a stack usage limitation issue that I believe needs attention and resolution.
same codebase works fine with 0.26, after upgrade to 0.29.0 one of Instruction return error the error is
Access violation in stack frame
solana-cli 1.16.13 anchor 0.29.0 rustc 1.74.0