Skip to main content
Technical proposal SIMD-0449 Review

Direct Account Pointers in Program Input

  1. Idea
  2. Draft
  3. Review
  4. Accept
  5. Implement
  6. Active

Decision brief

Why this proposal matters

Serialize pointers for instruction accounts to allow direct account access without requiring parsing of the account section.

Source-backed reading aid · source language: EN

Proposal at a glance

What changes

  • accounts slice pointer: A slice of 64-bit (8-byte) pointers, with one pointer per instruction account, stored at the end of the program input parameters.
  • read the number of accounts from r1.
  • read the length of the instruction data from r2 - 8.

Stakeholder map

Who is affected

Builders & client teams Medium impact

On-chain programs are positively impacted by this change. The program entrypoint complexity is significantly reduced, along with the number of compute units consumed. The implementation is relatively simple, as it relies on information that is already available during program input serialization.

Action requirement unknown
Validators & operators Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown
Users & stakers Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown
Governance & ecosystem Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown

Exact source revision

Full proposal document

Source-language document. Technical identifiers and evidence remain unchanged. f1f6c8b05dc2

Summary

Serialize pointers for instruction accounts to allow direct account access without requiring parsing of the account section.

Motivation

Currently, sBPF programs in ABIv1 must parse the accounts section of the serialized input region to extract account boundary information in order to provide the program with a slice of accounts. This parsing represents most of the entrypoint's cost.

Since account boundaries are already known to the VM when preparing the program input, they can instead be serialized directly into the input. This allows the entrypoint to derive the accounts slice without iterating over or parsing the accounts section.

As a result, the entrypoint consumes a constant number of compute units, independent of the number of accounts.

New Terminology

  • accounts slice pointer: A slice of 64-bit (8-byte) pointers, with one pointer per instruction account, stored at the end of the program input parameters.

Detailed Design

When the feature is activated, the VM serializes the slice of account pointers after the program ID in the program input parameters for any ABIv1 program (i.e., those that do not use Loader v1). All other parameters remain unchanged:

- 8 bytes: number of accounts (little-endian)
- <variable>: accounts section
- 8 bytes: length of instruction data (little-endian)
- <variable>: instruction data bytes
- 32 bytes: program ID
- 0-7 bytes: padding bytes to align offset to 8-bytes
- [u64; <number of accounts>]: slice of account pointers

Each account pointer is the address (u64 little-endian) of the first byte of the account information. They all must be valid addresses within the input section. Duplicated accounts will have the same pointer value, i.e., they will point to the same account. These are the same addresses that entrypoints previously had to compute when parsing the accounts section, but it is now provided directly as an input parameter.

The slice of account pointers is made available to all ABIv1 programs, under all loaders, regardless of whether it is read or not. Since this data is appended after the standard input parameters, existing programs are unaffected.

Given that, after SIMD-0321 is activated, programs will receive a direct pointer to the instruction data, programs can derive the location of the slice of account pointers without parsing the accounts section:

  • read the number of accounts from r1.
  • read the length of the instruction data from r2 - 8.
  • pass the following three references to the program entrypoint:
    1. program_id: a &[u8] slice created from r2 + <length of the instruction data> with length equal to 32 bytes.
    2. accounts: a &[AccountView] slice created from r2 + <length of the instruction data> + 32 + padding with length equal to <number of accounts>.
    3. instruction_data: a &[u8] slice created from r2 with length equal to <length of instruction data>.

Alternatives Considered

While ABIv2 proposes a new serialization layout that provides a similar slice of accounts and likewise avoids parsing the accounts section, the approach proposed in this SIMD is comparatively simpler and fully backward compatible with current ABIv1.

Impact

On-chain programs are positively impacted by this change. The program entrypoint complexity is significantly reduced, along with the number of compute units consumed. The implementation is relatively simple, as it relies on information that is already available during program input serialization.

  • Current entrypoint (pinocchio):
NameCUsDelta
Account (1)17--
Account (2)17--
Account (3)37--
Account (4)45--
Account (8)78--
Account (16)143--
Account (32)261--
Account (64)504--
  • Estimated entrypoint (after the changes proposed):
NameCUsDelta
Account (1)11-6
Account (2)11-6
Account (3)11-26
Account (4)11-34
Account (8)11-67
Account (16)11-132
Account (32)11-250
Account (64)11-493

The benchmark above represents the cost of parsing accounts in the entrypoint of a program with an empty instruction processor. The scaffold code for it can be found here.

Security Considerations

Since programs currently do not read data from the input parameters beyond the program ID, this change does not introduce any security concerns.

Backwards Compatibility

This feature is fully backwards compatible with current ABIv1 since no program entrypoint reads data from the input parameters after the program ID.

Evidence graph

Related proposals and rollout

One or more sources are unavailable.

Upstream review record

Upstream discussion & review

GitHub review is editorial context, not evidence of on-chain support, voting, or outcome.

PR #449 · merged SIMD-0449: Direct Account Pointers in Program Input 26 comments and reviews · May 4, 2026
@febo

While it's not a super big difference at the end of the day, I think it probably makes sense to add programid to r3 instead of using the ix data length from r2. This allows you to use purely static offsets. Since @buffalojoec already did the hard work of adding data flow graph analysis to program-sync(https://github.com/blueshift-gg/program-sync) to check for uninitialized r2 usage, the work required to ensure that r3 is also safe to use is quite trivial now. Unfortunately it won't be purely static offsets since there are padding bytes between programid and accountspointer to make it 8-bytes aligned. But it does simplify the logic to compute the offset, so I am happy either way. Another opti

GitHub ↗
@deanmlittle

While it's not a super big difference at the end of the day, I think it probably makes sense to add programid to r3 instead of using the ix data length from r2. This allows you to use purely static offsets. Since @buffalojoec already did the hard work of adding data flow graph analysis to program-sync(https://github.com/blueshift-gg/program-sync) to check for uninitialized r2 usage, the work required to ensure that r3 is also safe to use is quite trivial now. Unfortunately it won't be purely static offsets since there are padding bytes between programid and accountspointer to make it 8-bytes aligned. But it does simplify the logic to compute the offset, so I am happy either way. Another opti

GitHub ↗
@bw-solana

is the plan to still proceed with 177 and have two ways of getting account metadata? Or should we slim down 177 in response to this SIMD?

GitHub ↗
@Lichtso

This SIMD does kinda backport this specific ABIv2 feature to ABIv1. have two ways of getting account metadata This won't be the case because a program must choose between ABI v0, v1, or v2. It can't have multiple.

GitHub ↗
@simd-botbot

✅ All approvals received! @febo, you can now merge this by commenting /merge. ✅ Status: Ready to merge

GitHub ↗
@simd-botbot

✅ Merge successful! febo(https://github.com/febo)'s PR has been merged.

GitHub ↗
@febo

Ah, yes, if we are ensuring the pointers are aligned then I think it would actually be the same number of CUs. In that case, perhaps it does make sense for r3 to point to the first account in this section so you can construct the pointer array statically from the r1+0 and r3+0. Program ID isn't really that useful anyway as most people use a const ID and allow the runtime itself to fail things like PDA derivation. Well, I just wanted to raise this point. If you like the idea, I think it's probably not too controversial to include it. We can always do this later too if you think it's too much. We can definitely consider to do it later.

GitHub ↗

simd.watch community discussion · SIMD-0449

Powered by Giscus · Sign in with GitHub to comment

Community comments load when this section approaches the viewport.

Provenance

Evidence & technical details

Rollout or chain data, source revisions, freshness and integrity.
2

SIMD

Deployment Status

Document lifecycleReview
CategoryCore protocol

Feature Gate not yet created

Exact source revision

Sources & integrity

  • Proposal document pinned_commit_blob
    f1f6c8b05dc205552d3c290a854a438392701107
  • simd-document document · stale · Oct 17, 2026
    f1f6c8b05dc205552d3c290a854a438392701107

One or more sources are unavailable.