SIMD-0385

Transaction V1 Format

Author: jacobcreech, apfitzge · Category: Core Protocol GitHub →

TL;DR

The current live transaction formats, v0 and legacy, have a number of limitations that make them unsuitable for efficient ingestion, processing, and unable to support developer features that are required for today's applications. This proposal presents a new transaction format, `v1`, that is designed to get rid of the need for compute budget instructions, address lookup tables, and more to speed up transaction ingestion and processing.

Summary

The current live transaction formats, v0 and legacy, have a number of limitations that make them unsuitable for efficient ingestion, processing, and unable to support developer features that are required for today's applications. This proposal presents a new transaction format, `v1`, that is designed to get rid of the need for compute budget instructions, address lookup tables, and more to speed up transaction ingestion and processing.

Motivation

The current live transaction formats, v0 and legacy, have a number of inefficiencies and limitations that adversely impact the performance of the cluster. Ingestion is slowed down when trying to prioritize transactions by their Compute Budget instructions. Address lookup tables currently supported by transaction format v0 are also a significant source of complexity for validators to support. By introducing a new transaction format, `v1`, we can address these issues and improve the performance of transactions ingestion, processing, and save developers space in their transaction by including compute budget information in the transaction header itself.

Key Changes

  • 'v1 transaction' - A new transaction format that is designed to enable larger transactions sizes while not having the address lookup table features introduced in v0 transactions. The v1 transaction format also does not require compute budget instructions to be present within the transaction, but instead the TransactionConfigMask detailed below should be used.
  • num_required_signatures: The number of requires signatures
  • num_readonly_signed_accounts: The number of the accounts with signatures that are loaded as read-only
  • num_readonly_unsigned_accounts: The number of accounts without signatures that are loaded as read-only
  • num_required_signatures-num_readonly_signed_accounts additional addresses for which the transaction contains signatures and are loaded as writable, of which the first is the fee payer
  • num_readonly_signed_accounts addresses for which the transaction contains signatures and are loaded as readonly
  • num_addresses-num_required_signatures-num_readonly_unsigned_accounts addresses for which the transaction does not contain signatures and are loaded as writable
  • num_readonly_unsigned_accounts addresses for which the transaction does not contain signatures and are loaded as readonly
  • ProgramAccountIndex: u8: the index in the array of addresses of the address of the program to invoke for this instruction. This field was known as program_id_index in previous versions of the transaction format; it has been renamed to clarify its use without changing its meaning.
  • NumInstructionAccounts: u8: the number of addresses that will be passed to the program when it is invoked. This field was implicitly represented in a different encoding in a previous versions of the transaction format as the element count of the accounts vector.
  • NumInstructionDataBytes: u16: the size in bytes of the data that will be passed as input to the program when it is invoked. This field was implicitly represented in a different encoding in a previous versions of the transaction format as the element count of the data vector.
  • instruction 0's InstructionAccountIndices (InstructionHeaders[0].NumInstructionAccounts bytes)
  • instruction 0's InstructionData (InstructionHeaders[0].NumInstructionDataBytes bytes)
  • instruction 1's InstructionAccountIndices (InstructionHeaders[1].NumInstructionAccounts bytes)
  • instruction 1's InstructionData (InstructionHeaders[1].NumInstructionDataBytes bytes)
  • [0, 1] - total lamports for transaction priority-fee. 8-byte LE u64.
  • [2] - compute-unit-limit. 4 byte LE u32.
  • [3] - requested loaded accounts data size limit. 4 byte LE u32.
  • [4] - requested heap size. 4 byte LE u32.
  • If bits [0, 1] are not set, the priority-fee is 0.

Impact

As developers adopt the new transaction format, validator clients accepting their transactions will be much more efficient at ingestion. The transaction format as currently defined may also support other features such as larger transaction sizes. Notably the proposed format does not support address lookup tables, which are commonly used in the developer community today.

Security Considerations

None at this time.