0

The documentation on solana.com says:

program data accounts can't be resized

suggesting that the size of a program data account can only be "resized" by:

  1. creating a new program data account,
  2. making the program account reference the new program data account and
  3. closing the old program data account.

At the same time, the section on realloc in the solana_program crate documentation doesn't say anything about a new program data account being replacing the old one.

So, what's, actually, happening?

3 Answers 3

4

Adding this answer as a follow up to the comment

Yes, you’ve got it mostly right. Once a Program Data account (which holds the bytecode of the deployed program) is created, its size is immutable. This is enforced because program data accounts are managed by the Upgradeable Loader, which ensures security, consistency, and stability when upgrading programs.

When you upgrade a program, even if the new bytecode is the same size or smaller than the previous one, a new Program Data account must be created to hold the new bytecode. This is because the Upgradeable Loader doesn’t support in place updates for the program data. Instead, it maintains a controlled upgrade path by creating a fresh Program Data account with the new contents and then updating the Program account to reference the new one.

Even if the new bytecode is the same size or smaller, immutability is maintained to avoid potential issues such as leftover bytecode from the previous version, security concerns, or inconsistencies that could arise from in place modifications. Therefore, a new account is created to ensure a clean slate for the new bytecode.

On the other hand, regular data accounts, such as Associated Token Accounts (ATAs), Program Derived Accounts (PDAs), and any other accounts holding state for your application, can be resized in place using the realloc function provided by Solana.

ATAs (Associated Token Accounts): These are token specific accounts that hold balances of SPL tokens. They can be resized if needed, although in practice, they usually have fixed data layouts (e.g., a token balance and metadata), so resizing isn’t commonly required.

PDAs (Program Derived Accounts): These are typically used to store custom data related to your program and can be dynamically resized depending on your program's needs. For example, you might start with a PDA that holds a small amount of data and later need to expand its size to store more information. In such cases, you can use realloc to resize the account in place without needing to create a new one.

Realloc Process: The realloc function adjusts the size of the account's data. When resizing upwards, you'll need to make sure that the account has enough SOL to cover rent for the increased size. When shrinking, excess lamports may be returned to the account's owner.

1
  • 1
    Thank you very much for the in-depth clarification of the matter!
    – Iaroslav
    Commented Oct 16 at 14:51
3

The Solana documentation correctly states that program data accounts cannot be resized. Once a program data account is created, its size is fixed and cannot be changed directly. This constraint is specifically related to accounts managed by the Upgradeable Loader, which handles executable programs on Solana.

In the context of upgradeable programs, if you need to change the size of a program data account (for example, if you need to add more data to it), the process would involve:

  • reating a new program data account with the desired size.
  • Migrating the data from the old account to the new one.
  • Pointing the program to reference the new account.
  • Closing the old program data account to reclaim any SOL (lamports) used for rent.

This process is essential to how Solana manages upgradeable programs because direct resizing could break the contract guarantees and lead to unintended behavior during program upgrades.

The Role of realloc in Solana Programs The realloc function allows you to reallocate memory for an account, but this is primarily intended for non-program data accounts, such as regular data accounts used by programs.

For example, the realloc function is useful when resizing an account that holds user data (like metadata, tokens, or other state data). It allows you to increase or decrease the size of an account without creating a new one. However, program data accounts are special and are governed by the Solana upgradeable loader, which has stricter rules.

The reason behind this restriction for program data accounts is related to the Solana upgradeable loader. When a program is deployed, it is tied to a program data account that holds the executable code and related data. The upgradeable loader allows the program to be upgraded by referencing new program data, but direct resizing would be problematic because it could potentially introduce instability, especially if the size of the account changes unpredictably during execution or after the program is deployed.

For security and stability, program data accounts are therefore immutable in size once created. This ensures that upgrading a program is a controlled, predictable process.

2
  • Ah, didn't realize there are different rules for updating the different data accounts! So, changing the contents of a Program Data account (containing the program's bytecode) requires a new Program Data account to be created replacing the previously-referenced one in the (main) program account. Also, given that the Program Data accounts are immutable, a new account needs to be created even if the size of the new bytecode you're deploying is <= than the previous one. Right? At the same time, the regular-data accounts (e.g. ATAs and Program Derived Accounts) can be resized in-place.
    – Iaroslav
    Commented Oct 11 at 17:48
  • 1
    Posted another answer to respond to this comment
    – Mitch
    Commented Oct 15 at 11:59
1

The documentation is out of date -- it's possible to resize program data accounts using the ExtendProgram instruction: https://github.com/anza-xyz/agave/blob/10bebfaf422b8e09409cc5b56a35ec40defa27aa/sdk/program/src/bpf_loader_upgradeable.rs#L323

This instruction increases the size of the existing account in-place. You can run it with the CLI using solana program extend <PROGRAM_ID> <ADDITIONAL_BYTES>

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.