SIMD-0312

CreateAccountAllowPrefund

Author: Peter Keay · Category: Core Protocol GitHub →

TL;DR

A `CreateAccountAllowPrefund` instruction added to the system program reduces network overhead for applications that need to fund account rent (in whole or in part) in advance of account creation.

Summary

A `CreateAccountAllowPrefund` instruction added to the system program reduces network overhead for applications that need to fund account rent (in whole or in part) in advance of account creation.

Motivation

The existing `CreateAccount` system program instruction creates accounts within a program by use of `transfer`, `allocate`, and `assign`. `CreateAccount` fails if `lamports > 0`. This was intended as a protection measure, preventing developers from accidentally passing in some normal wallet address and permanently locking its lamports after `allocate` and `assign`. However, it is common practice to provide rent lamports to accounts prior to the actual creation (allocation and assigning) of the account space, rather than forcing the fee payer of the transaction to provide all of the required lamports. In this and similar instances, developers currently must manually construct a patched `CreateAccount` call of their own with 2-3 CPI calls: sometimes `Transfer`, then `Allocate`, and then `Assign`. While these actions themselves are minimally expensive, the overhead incurred with every Cross-Program Invocation - depth check, signer check, account copy, etc. - can make up the bulk of the computation done in the transaction. Each CPI incurs a minimum of 1_000 compute units, plus additional amounts depending on the instruction and account length. `CreateAccountAllowPrefund` performs `allocate`, `assign`, and `transfer` without asserting that the created account has zero lamports. Applications which do not need to `transfer` can specify 0 lamports, effectively providing them with an `AllocateAndAssign`. p-ATA program benchmarks demonstrate that use of `CreateAccountAllowPrefund` can save approximately 2_500 compute units: https://github.com/solana-program/associated-token-account/pull/102 This is a stopgap measure, as it extends the undesired interface sprawl of helper instructions such as `CreateAccount`. However, any redesign of Cross-Program Invocations to safely reduce overhead would be an extensive protocol upgrade and slow to land. In the meantime, the network will benefit from `CreateAccountAllowPrefund`.

Key Changes

  • Prefund: sending lamports to an account to pay for its rent in whole or in
  • The instruction has a new discriminant (13).
  • The funding account is optional.
  • Due to #2, the accounts are ordered differently.
  • Allocate: As with CreateAccount, this instruction calls allocate,
  • Assign: As with CreateAccount, this instruction calls assign.
  • Transfer: If lamports is greater than 0, it transfers the
  • The funding_account is not provided when lamports > 0.
  • The funding_account does not have enough lamports for the transfer (when
  • The new_account already contains data or is not owned by the System
  • The new_account does not have sufficient lamports to be rent-exempt
  • Required accounts are not writable or not signers.
  • The requested space exceeds the max permitted data length.

Impact

The primary impact is an available reduction in CPI overhead for programs which currently must perform these operations manually across 2 to 3 CPIs. As mentioned previously, the p-ATA program takes advantage of `CreateAccountAllowPrefund` to save approximately 2_500 compute units: https://github.com/solana-program/associated-token-account/pull/102

Backwards Compatibility

This SIMD requires a feature gate, as it adds a new System Program instruction.

Security Considerations

Developers using `CreateAccountAllowPrefund` should ensure they are not passing an unintended wallet account with lamports. The usual checks of `allocate` and `assign` are still performed - an account with data or with an owner other than the system program will not be modified - but since the lamport check is removed, a wallet account with lamports can be bricked by this instruction.