0

When I am creating CPI using the anchor CPI feature, I do not encounter a memory allocation failure. However, when using program::invoke_signed, I do encounter this issue.

  let mut ireceive_ctx = CpiContext::<idapp::cpi::accounts::IReceive>::new_with_signer(
        handler_program.to_account_info(),
        idapp::cpi::accounts::IReceive {
            dapp_account: handler_account.to_account_info(),
            packet_account: packet_account.to_account_info(),
            gateway_authority: authority.to_account_info(),
            system_program: system_program.to_account_info(),
        },
        signer_seeds,
    );

    ireceive_ctx.remaining_accounts = ctx.remaining_accounts.into();
    let res = idapp::cpi::i_receive(
        ireceive_ctx,
        request_payload_account.get_request_sender(),
        request_payload_account.get_src_chain_id(),
    );
pub fn _i_receive<'info>(
    ctx: &Context<'_, '_, '_, 'info, CompleteIReceive<'info>>,
    request_sender: &String,
    src_chain_id: &String,
    remaining_accounts: &[AccountInfo<'info>],
    signer_seeds: &[&[&[u8]]],
) -> Result<()> {
    let ix = _i_receive_intruction(
        ctx.accounts.handler_program.key,
        request_sender,
        src_chain_id,
        ctx.accounts.handler_account.key,
        &ctx.accounts.packet_account.key(),
        &ctx.accounts.authority.key(),
        ctx.accounts.system_program.key,
        remaining_accounts,
    )?;
    program::invoke_signed(
        &ix,
        &[
            &[
                ctx.accounts.handler_account.to_account_info(),
                ctx.accounts.packet_account.to_account_info(),
                ctx.accounts.authority.to_account_info(),
                ctx.accounts.system_program.to_account_info(),
            ],
            remaining_accounts,
        ]
        .concat(),
        signer_seeds,
    )
    .map_err(Into::into)
}

pub fn _i_receive_intruction(
    dapp_program_id: &Pubkey,
    request_sender: &String,
    src_chain_id: &String,
    dapp_account: &Pubkey,
    packet_account: &Pubkey,
    gateway_authority: &Pubkey,
    system_account: &Pubkey,
    remaining_accounts: &[AccountInfo],
) -> Result<Instruction> {
    let mut data = Vec::with_capacity(8 + (4 + request_sender.len()) + (4 + src_chain_id.len()));
    data.extend_from_slice(
        &anchor_lang::solana_program::hash::hash("global:i_receive".as_bytes()).to_bytes()[..8],
    );
    data.extend_from_slice(&request_sender.len().to_le_bytes());
    data.extend_from_slice(&request_sender.as_bytes());
    data.extend_from_slice(&src_chain_id.len().to_le_bytes());
    data.extend_from_slice(&src_chain_id.as_bytes());
    let mut accounts = Vec::with_capacity(4 + remaining_accounts.len());
    accounts.push(AccountMeta::new(*dapp_account, false));
    accounts.push(AccountMeta::new_readonly(*packet_account, false));
    accounts.push(AccountMeta::new_readonly(*gateway_authority, true));
    accounts.push(AccountMeta::new_readonly(*system_account, false));
    for remaining_acc in remaining_accounts.iter() {
        accounts.push(AccountMeta::new(remaining_acc.key(), false));
    }
    Ok(Instruction {
        program_id: *dapp_program_id,
        accounts,
        data,
    })
}

1 Answer 1

0

Modifying the structure of the accounts can help. Wrapping some accounts in Box might resolve the issue by reducing the stack memory used to store the data.

To modify the existing function to use Box, you can do the following:

  1. Wrap the accounts in Box to allocate them on the heap instead of the stack.

  2. Adjust the function signature and usage accordingly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.