Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
members = [
"solana/account",
"solana/program-runtime",
"solana/svm",
"solana/transaction-context",
"solana/transaction-view",
]
Expand All @@ -21,6 +22,7 @@ magic-root-interface = { path = "programs/magic-root-interface" }
magic-root-program = { path = "programs/magic-root-program" }
solana-account = { path = "solana/account" }
solana-program-runtime = { path = "solana/program-runtime" }
solana-svm = { path = "solana/svm" }
solana-transaction-context = { path = "solana/transaction-context" }

ahash = "0.8.12"
Expand All @@ -33,6 +35,7 @@ blake3 = "1.8.5"
cfg-if = "1.0.4"
criterion = "0.8.2"
derive_more = "2.1.1"
env_logger = "0.11.8"
itertools = "0.13.0"
qualifier_attr = "0.2.2"
rand = "0.9.2"
Expand All @@ -56,17 +59,24 @@ solana-account-info = "3.1.1"
solana-clock = "3.1.0"
solana-compute-budget-instruction = "=4.1.1"
solana-cpi = "3.1.0"
solana-ed25519-program = "3.0.0"
solana-epoch-rewards = "3.0.1"
solana-epoch-schedule = "3.1.0"
solana-feature-gate-interface = { version = "4.0.0", features = ["bincode"] }
solana-fee-calculator = "3.2.0"
solana-fee-structure = "3.0.0"
solana-hash = "4.3.0"
solana-instruction = "3.4.0"
solana-instruction-error = "2.3.0"
solana-instructions-sysvar = "4.0.0"
solana-keypair = "3.1.2"
solana-last-restart-slot = "3.0.0"
solana-loader-v3-interface = "6.1.0"
solana-loader-v3-interface = "7.0.0"
solana-message = "4.1.1"
solana-msg = "3.1.0"
solana-native-token = "3.0.0"
solana-packet = "4.1.0"
solana-precompile-error = "3.0.0"
solana-program-entrypoint = "3.1.1"
solana-program-error = "3.0.1"
solana-pubkey = "4.2.0"
Expand All @@ -77,27 +87,27 @@ solana-short-vec = "=3.2.2"
solana-signature = "=3.4.1"
solana-signer = "3.0.1"
solana-slot-hashes = "3.0.1"
solana-stable-layout = "3.0.0"
solana-sysvar = "3.1.1"
solana-sysvar-id = "3.1.0"
solana-system-interface = ">=3.0.0, <3.2.0"
solana-svm-callback = "4.0.0-rc.1"
solana-svm-feature-set = "4.0.0-rc.1"
solana-svm-log-collector = "4.0.0-rc.1"
solana-svm-measure = "4.0.0-rc.1"
solana-svm-timings = "4.0.0-rc.1"
solana-svm-transaction = "4.0.0-rc.1"
solana-svm-type-overrides = "4.0.0-rc.1"
solana-system-interface = ">=3.0.0, <3.2.0"
solana-system-program = "4.0.0-rc.0"
solana-system-transaction = "3.0.0"
solana-sysvar = "3.1.1"
solana-stable-layout = "3.0.1"
solana-svm-callback = "4.1.1"
solana-svm-feature-set = "4.1.1"
solana-svm-log-collector = "4.1.1"
solana-svm-measure = "4.1.1"
solana-svm-timings = "4.1.1"
solana-svm-transaction = "4.1.1"
solana-svm-type-overrides = "4.1.1"
solana-system-interface = { version = "3.2", features = ["alloc", "bincode", "serde", "wincode"] }
solana-system-program = { version = "=4.1.1", features = ["agave-unstable-api"] }
solana-sysvar = "4.0.0"
solana-sysvar-id = "3.1.0"
solana-transaction = "4.1.1"
solana-transaction-error = "3.2.0"

[patch.crates-io]
agave-transaction-view = { path = "solana/transaction-view" }
solana-account = { path = "solana/account" }
solana-program-runtime = { path = "solana/program-runtime" }
solana-svm = { path = "solana/svm" }
solana-transaction-context = { path = "solana/transaction-context" }

[workspace.lints.rust]
missing_docs = "deny"
Expand Down
165 changes: 165 additions & 0 deletions solana/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Engine Runtime Differences from Agave

This directory contains the Agave runtime forks required by the engine. These
crates execute caller-loaded transactions and return account changes; they do
not own consensus, fork choice, confirmation, persistence, or validator commit
policy.

The differences below are intentional compatibility constraints for account
representation, transaction context, serialization, VM mapping, and CPI.

## Runtime boundary

- `solana-svm` loads accounts through a caller callback and returns execution
results and mutated accounts.
- Persistence, commit decisions, and deployment policy remain outside the fork.
- Program loading is limited to programs required by the transaction and checks
native-loader or `PROGRAM_OWNERS` ownership.
- Rent-state and lamport-balance checks remain part of execution.

## Account representation

`solana-account` replaces the shared-data representation with copy-on-write
storage. `AccountSharedData` contains either an owned `Arc<Vec<u8>>` or a borrowed
view into an aligned external buffer. `DirtyMarkers` record changes to data,
owner, lamports, slot, mode, and state flags for higher-layer writeback.

Borrowed storage has these invariants:

- The buffer is 8-byte aligned and remains live for the borrow.
- One header and pubkey prefix are followed by two account images.
- `AccountHeader::sequence` selects the active image.
- `translate` copies active state into the shadow image before mutation.
- `commit` publishes the shadow image; `reset` abandons it.
- `rollback` is valid only after `commit`.

Writes remain borrowed while they fit the image capacity. Growth beyond that
capacity promotes the account to owned storage. Shared owned data becomes unique
through `Arc::make_mut` before mutation.

`AccountMode` contains `ReadOnly`, `Placeholder`, `System`, `Delegated`,
`Ephemeral`, `Transient`, and `Closed`. Only delegated and ephemeral accounts are
mutable by user programs. Transient accounts remain persistent but immutable
after the transaction that legally transitions them from delegated. The
transaction access guard recognizes that transition through the mode dirty
marker; a freshly loaded transient account has a clean marker and remains
immutable. The same transaction-local exception lets a legal mode transition
close an account. Ephemeral accounts remain persistent until then. `StateFlags`
contains `EXECUTABLE` and `COMPRESSED`.
`AccountSharedData` does not store `rent_epoch`; compatibility APIs return or
ignore the masked value required by their interface.

## Transaction context

`solana-transaction-context` stores accounts in `UnsafeCell`s guarded by explicit
borrow counters. This permits the VM access handler to remap account data while
runtime borrow rules remain enforced.

`TransactionAccounts` records touched accounts, total account-data resize, and
instruction lamport deltas. `AccountRef` and `AccountRefMut` release their
counters on drop. `ExecutionRecord` returns keyed accounts, return data, touched
count, and resize delta. All references must be released before context
deconstruction; failure of `Rc::try_unwrap` indicates a lifetime bug.

## Transaction parsing and Engine-private transactions

`agave-transaction-view` parses Legacy, v0, V1, and Engine-private Magicblock
transactions directly from their serialized bytes. Legacy and v0 retain the
standard Solana wire layouts, while V1 retains the Agave V1 layout. All three
accept serialized sizes through `u16::MAX` bytes, inclusive. The compact-u16
parser supports the complete canonical one-, two-, and three-byte encoding, so
instruction data and other framed arrays are no longer limited by the former
two-byte parser assumption.

Frame offsets and total lengths are stored as `u32`. Fallible parsing uses
checked range arithmetic and validates every frame before unchecked iterators
or typed views access the original bytes. The engine is guaranteed not to run
on 16-bit targets, so conversion from validated `u32` offsets to `usize` is
direct.

Magicblock is private transaction version 127 and reuses the V1 layout with a
distinct prefix. Its signatures follow the V1 message at the end of the byte
stream. The Engine transaction composer compiles account operations as V1,
writes the Magicblock prefix, signs the exact message range, and verifies that
the first static account is the configured Engine authority. Magicblock
transactions may be at most 16 MiB and raise only the SVM instruction-trace
limit to 255; standard versions retain their existing structural limits. The
account accessor uses this private path so a 64 KiB account payload can be split
into patch instructions and executed atomically without relaxing standard
transaction policy.

Address lookup tables are intentionally disabled. Any transaction containing a
lookup table entry fails sanitization with `AddressLookupMismatch`; an empty v0
lookup list remains valid and resolves without loaded addresses. Sequencing and
simulation therefore resolve transactions without supplying loaded addresses.

The crate-specific wire and safety contracts are documented in
[`transaction-view/README.md`](transaction-view/README.md). Keep its version
prefix, signed message range, size limits, sanitizer, Engine composer, and SVM
trace-limit override synchronized.

## VM account mapping

Account data is always mapped directly into the SBF VM. Do not restore the
removed `virtual_address_space_adjustments` or `account_data_direct_mapping`
branches that copied account data through serialized program input.

Serialization retains loader ABI metadata:

- Deprecated-loader accounts use ABI v0.
- Loader-v2 and loader-v3 accounts use ABI v1.
- ABI v1 optionally includes direct account pointers.

The serialized input contains metadata, lamports, lengths, owners, instruction
data, and program id. Account data resides in separate `MemoryRegion`s.
Deprecated-loader regions reserve the current length; newer loaders also reserve
`MAX_PERMITTED_DATA_INCREASE`. Deserialization reads mutable metadata but does
not copy account bytes back from the input buffer.

## Access-violation growth

Writable borrowed or shared-owned account data may initially be mapped
read-only. The first VM store enters the transaction-context handler, which:

- handles stores only and requires an account-index region payload;
- rejects accesses outside the account's reserved address range;
- records touch and resize deltas before growing data;
- grows only to the requested access length; and
- replaces the region host pointer, length, and writability.

Keep serialization, `TransactionContext::access_violation_handler`, and VM error
mapping synchronized. They jointly map growth failures to account-specific
readonly, size, and realloc errors.

## CPI synchronization

`CallerAccount::serialized_data` remains empty. CPI entry and exit synchronize
lamports, owner, and data length, while account bytes remain directly mapped.
When storage can move, CPI replaces the caller `MemoryRegion` with one created
from the current account.

Strict syscall parameter-address checks are always enforced. CPI rejects
`AccountInfo` fields whose key, owner, lamports, data, or data-length pointers do
not reference the canonical VM locations for the passed account. This is required
because account bytes are mapped directly into the VM and cannot be protected by
copy-back serialization.

Inner-instruction growth uses the caller's original length plus the permitted
increase. Deprecated loaders reserve only the original length. Any account-region
layout change must update CPI pointer checks, region replacement, and VM access
handling together.

## Maintenance constraints

- Preserve direct account-region mapping as the only runtime path.
- Preserve ABI v0 and ABI v1 metadata compatibility.
- Keep borrowed layout changes synchronized across account, transaction-context,
serialization, and mapping code.
- Preserve full compact-u16 parsing and checked `u32` transaction framing.
- Keep Magicblock construction and execution policy synchronized with
`agave-transaction-view`.
- Do not enable address lookup resolution without revisiting ingress,
sanitization, scheduling, and simulation together.
- Treat dirty markers and touched flags as the caller's writeback signal.
- Keep persistence, consensus, validator fee policy, and batch commit decisions
outside these runtime crates.
4 changes: 1 addition & 3 deletions solana/program-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ name = "solana-program-runtime"
authors = { workspace = true }
description = "Solana program runtime"
documentation = "https://docs.rs/solana-program-runtime"
version = { workspace = true }
authors = { workspace = true }
repository = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
Expand Down
Loading