compile instruction accounts via mock_compile_message#531
Open
buffalojoec wants to merge 5 commits into
Open
Conversation
Hold the decoded instruction as a solana_instruction::Instruction. Lets the harnesses pass it straight to mock_compile_message without rebuilding a copy.
Build the transaction accounts and instruction-account privileges through a compiled Message (mock_compile_message + InvokeContext::prepare_top_level_ instructions) across the instr, vm_syscall and vm_serialization harnesses, matching what the runtime does. Message compilation dedups account keys and merges per-key privileges (is_signer/is_writable to the highest role), the behavior the validator enforces before an instruction reaches the VM. Drops the iterative get_instr_accounts / configure_top_level_instruction_for_tests path and the per-call instruction snapshots/copies that fed it. Note: this changes the returned account set/order (compiled-message accounts only, message order) so resulting_accounts no longer echoes every input account in input order; fixtures need regeneration to match.
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates instruction and syscall execution setup to use Solana’s SanitizedMessage-based path (prepare_top_level_instructions) instead of the older test-only configure_top_level_instruction_for_tests, removing reliance on stable-layout instruction/account snapshots.
Changes:
- Replace
StableInstruction/stable-layout snapshots withsolana_instruction::InstructionandSanitizedMessage. - Build a
SanitizedMessage+ transaction accounts viamock_compile_messageand useprepare_top_level_instructions. - Extend VM syscall cleanup to drop a leaked
SanitizedMessage.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/vm_syscalls.rs | Switches VM syscall execution to prepare_top_level_instructions and manages SanitizedMessage lifetime via leak + explicit cleanup. |
| src/vm_serialization.rs | Updates VM serialization execution to use SanitizedMessage and prepare_top_level_instructions. |
| src/instr.rs | Replaces stable-layout instruction types with Instruction, compiles a SanitizedMessage, and wires it into invoke context setup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mjain-jump
reviewed
Jun 3, 2026
mjain-jump
reviewed
Jun 3, 2026
Compiling the instruction via mock_compile_message builds the transaction context the way the runtime does: only accounts referenced by the message are included, deduped and reordered into message order. As a result the returned modified_accounts dropped any input account the instruction didn't reference and no longer matched the order they were provided. Rebuild the result from the input accounts: emit every input account in input order, using its post-execution version from the transaction context when present and falling back to the provided input version otherwise. This restores the full, input-ordered account set the fixtures/effects compare against.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In Agave, top-level instruction accounts are queried from the compiled transaction
Message, which compiles its account keys here (asCompiledKeys). When a message doesn't properly compile its account keys, duplicate entries are caught by Bank through this check. You can see this being tested here.This means that a sanitized message in SVM's message processor is guaranteed to have no duplicate account keys. Due to the protocol-enforced layout of a Solana
Message, no two instruction accounts sharing the same index can have different roles (writable/signer). This is because aMessageuses an account key's index in itsaccount_keyslist to query its role. Seeis_signerandis_writablein the SDK.In CPI, we don't have a
Messagelayout to enforce uniqueness, but we know the transaction accounts have already been deduped (above). So, the program-runtime will merge a CPI instruction's instruction accounts to the highest role manually viaprepare_next_cpi_instruction.SolFuzz-Agave incorrectly builds the list of instruction accounts because it does not merge instruction accounts to their highest role. Instead, it assigns them whatever role was specified in the
AccountMeta, meaning two accounts sharing the same index can have two different roles.solfuzz-agave/src/instr.rs
Lines 233 to 242 in 4cb2fbc
This PR patches this discrepancy and rectifies all input instruction accounts to resemble a valid message by actually using a real
Messageviamock_compile_message, a DCOU function fromsolana-program-runtime.The issue is: this will break 100% of the instruction fixtures and all CPI syscall fixtures, since the syscall harness shares the same invoke context setup.