15

I am trying to store 100KB+ data on a Solana Account. In Solana documents I've read that

"The current maximum size of an account's data is 10 megabytes."

Source: https://docs.solana.com/developing/programming-model/accounts

But when I try to create a space more than 10KB (space = 10240) it gives me error during init tests:

"Error processing Instruction 0: Failed to reallocate account data"

Here is an example code:

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init, payer = user, space=100000)] 
     pub example_account: Account<'info, ExampleAccount>,

    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>
}

#[account]
pub struct ExampleAccount {
    pub data: String,
}

I need to store 100KB data on that account. How can I do that?

2 Answers 2

15

While the maximum account size is 10 megabytes, the maximum permitted size of a reallocation in an inner instruction is 10240 bytes. Anchor has to make a CPI to allocate the space for your account, so the maximum space it can allocate is 10240 bytes. If you want to store more than that, you will have to pass in an account you have created with a separate createAccount instruction.

If you are not initializing the account with a CPI, you would instead do:

#[account(zero)] 
 pub example_account: Account<'info, ExampleAccount>,

And then when you call Initialize:

const create_account_instruction = SystemProgram.createAccount({
    fromPubkey: user,
    newAccountPubkey: exampleAccountKey,
    space: 100000,
    lamports,
    programId: yourProgramId
});
const your_instruction = program.instruction.initialize({ 
    accounts: { 
        exampleAccount: exampleAccountKey,
        user: user,
        systemProgram: systemProgramId
    }
});
const txn = new Transaction().add(create_account_instruction, your_instruction);
12
  • I am confused what does "you will have to pass in an account you have created with a separate createAccount instruction." means. Could you provide an example?
    – curiosity
    Jul 13, 2022 at 3:23
  • Are you familiar with the solana web3 SDK? I've elaborated in my example but you will probably have to be familiar with it to understand what I'm saying.
    – Ellie High
    Jul 13, 2022 at 3:38
  • Don't forget, there's a new realloc method which will allow you to increase by 10kb every transaction
    – Henry E
    Jul 13, 2022 at 7:24
  • Hi, I have tried your code and it works fine, I have created an account with space of 500,000 bytes. My idea is to store 10,000 public keys inside a vector on this account, but with 500K space I can only store 500 pubkeys which is strange because I thought pubkeys just needed 32 bytes, so to store I would need 10,000 * 32 = 320,000 bytes. What am i doing wrong? Ty. Jul 13, 2022 at 18:26
  • 1
    @EllieHigh When I hover on programId field it says: "Public key of the program to assign as the owner of the created account". On your example code, should I replace systemProgramId with my custom program Id? If not, why are we making system account owner of program? I am assuming if systemprogram owns that account, I won't be able to edit data inside it. Just like I can't edit my own SOL balance.
    – curiosity
    Jul 14, 2022 at 1:19
9

It is possible to allocate a PDA with up to 10 MiB. Use the init instruction to allocate 10240 bytes, this is the maximum that is allowed to be allocated through a CPI. Then you can execute another instruction that calls AccountInfo::realloc for every additional 10240 bytes that you need in the account. You can group many of these together in a single transaction. Ensure you have sufficient lamports in the account before reallocating.

The other approach, described in Ellen High's answer, is to initialize an account from a new keypair that signs a transaction containing a transaction-level instruction to the system program to initialize the account up to 10 MiB, plus an instruction that transfers ownership to the program (which can be tx-level or a CPI). But often it is preferable to use a PDA.

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.