4

I'm looking for a way to handle a big struct.

I want to understand how to create an account storing more than 10_000 structs inside is possible.

Is there a simple way to do it? Or should I have to implement an account storing many accounts storing structs?

I was looking at https://github.com/solana-developers/program-examples but didn't find anything related to this use case. I was thinking about something like that but it's not working and it reachs the transaction size limit:

#[account]
#[derive(InitSpace)]
pub struct Data {
    #[max_len(10000)]
    pub indexes: Vec<UserData>,
}


#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
pub struct UserData {
    pub name: String,
    pub owner: Pubkey,
    pub image: String,
}

Thanks for the help

1 Answer 1

3

I'm guessing you're trying to initiate your account with size ::INIT_SPACE in your transaction. This won't work because the maximum amount of bytes you can (re)alloc in one transaction is 10240 bytes. As we can tell by Data, the size of it will be more than that.

To circumvent this, you will need to initialize it with less than 10240 bytes of size and then realloc the account and extend it's length until you have the length you need.

8
  • Thank you for your answer but what about accounts with more than 10mb of data?
    – GoT
    Commented Jul 4 at 19:52
  • You can't make accounts larger than 10MB (solana.stackexchange.com/questions/4017/…). If you have more data than that to store, I suggest spreading it across multiple PDAs. A common way to do this is to have a counter in your seeds, e.g. [<some_seed>, 0] for the first account up until 10 MB, then the next PDA with [<some_seed>, 1], [<some_seed>, 2] etc.
    – McBain
    Commented Jul 4 at 21:33
  • So, If I understand correctly I have to pre-create all accounts needed, and pass them to the method I want to call each time it's needed, or is there a way to: - initialize the default account - create an account if some_seed is bigger than X automatically - retrieve these accounts on demand
    – GoT
    Commented Jul 5 at 7:08
  • 1
    You could also just create one account and have a check in your instruction that checks if that account is full when you try to insert one more UserData. If it is, it throws an error and tells the client to create (using a different instruction for example) a new PDA and use that instead.
    – McBain
    Commented Jul 5 at 8:41
  • 1
    All the code for this would go beyond the scope of these comments, but if this is interesting to you feel free accept this one & open another question asking around this specifically.
    – McBain
    Commented Jul 5 at 8:41

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.