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
3,924 changes: 3,438 additions & 486 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"nucleus",
"processor",
"programs/magic-root-interface",
"programs/magic-root-program",
"programs/v42-calculator-interface",
"programs/v42-calculator-program",
"solana/account",
Expand Down
4 changes: 4 additions & 0 deletions programs/magic-root-interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ repository.workspace = true
version.workspace = true

[dependencies]
wincode = { workspace = true }

solana-account = { workspace = true, features = ["wincode"] }
solana-instruction = { workspace = true, features = ["wincode"] }
solana-pubkey = { workspace = true }

[lints]
Expand Down
20 changes: 18 additions & 2 deletions programs/magic-root-interface/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
# `magic-root-interface`

This crate defines the MagicRoot program id shared by the runtime and the
native program.
This crate defines the MagicRoot program id and `MagicRootInstruction` wire
schema shared by `magic-root-program` and `engine`. Instruction builders can
depend on the interface without linking the native program runtime.

`MagicRootInstruction::compose` prepends the writable target account and
serializes the instruction with wincode. `PostFinalize` also appends each
follow-up program id and its account metas. Signer bits are cleared in the outer
instruction; the native program supplies the declared follow-up signers when it
invokes each action.

`MagicRootInstruction::compose_account` builds the ordered patch sequence for a
complete account's non-flag fields and appends a finalization instruction that
installs its complete flag value without changing lamports. The underlying
patch sequence applies mode before slot so the program can validate
lifecycle-aware slot progression. Callers are responsible for composing current
account state. Internal create composition appends `PostFinalize` immediately
after finalization; MagicRoot relies on this ordering after authenticating the
engine authority and caller.
70 changes: 69 additions & 1 deletion programs/magic-root-interface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
#![doc = include_str!("../README.md")]

use solana_pubkey::declare_id;
use solana_account::{AccountFieldPatch, OwnedAccount, StateFlags};
use solana_instruction::{AccountMeta, Instruction, error::InstructionError};
use solana_pubkey::{Pubkey, declare_id};
use wincode::{SchemaRead, SchemaWrite};

declare_id!("MagicRootDRJ5atQjSJUxFjXzjeZXMADHUDznbk22gy");

/// Instructions accepted by the MagicRoot built-in program.
#[derive(SchemaRead, SchemaWrite)]
pub enum MagicRootInstruction {
/// Apply a single-field patch to the target account.
Patch(AccountFieldPatch),
/// Replace the target's complete flag value and, when executable, load it
/// into the transaction's program cache. Does not change lamports.
Finalize(StateFlags),
/// Close the target account.
Delete,
/// Run follow-up instructions immediately after finalizing the same target
/// (e.g. initializing a freshly created account); each is invoked via CPI
/// against the accounts it declares.
PostFinalize(Vec<Instruction>),
}

impl MagicRootInstruction {
/// Composes this variant into an [`Instruction`] targeting the MagicRoot
/// program: prepends the target `account` meta, appends any metas the
/// variant requires, and serializes the instruction data.
pub fn compose(&self, account: Pubkey) -> Result<Instruction, InstructionError> {
let mut accounts = vec![AccountMeta::new(account, false)];
self.extend_metas(&mut accounts);
// NOTE this code can never error, wincode serialization for instruction is infallible
let data = wincode::serialize(self).map_err(|_| InstructionError::BorshIoError)?;
Ok(Instruction { program_id: ID, accounts, data })
}

/// Composes `account` into the ordered instruction sequence that patches
/// every non-flag field on `target`, then finalizes it with `account`'s
/// complete flag value.
pub fn compose_account(
target: Pubkey,
account: OwnedAccount,
) -> Result<Vec<Instruction>, InstructionError> {
let flags = account.flags();
let patches = AccountFieldPatch::sequence(account);
let mut instructions = Vec::with_capacity(patches.len() + 1);
for patch in patches {
instructions.push(Self::Patch(patch).compose(target)?);
}
instructions.push(Self::Finalize(flags).compose(target)?);
Ok(instructions)
}

/// Appends the extra account metas a variant requires. Only [`PostFinalize`]
/// contributes any: the program id and de-signed accounts of each follow-up
/// instruction.
///
/// [`PostFinalize`]: MagicRootInstruction::PostFinalize
fn extend_metas(&self, accounts: &mut Vec<AccountMeta>) {
let Self::PostFinalize(ixs) = self else {
return;
};
for ix in ixs {
accounts.push(AccountMeta::new_readonly(ix.program_id, false));
let metas = ix.accounts.clone().into_iter().map(|mut meta| {
meta.is_signer = false;
meta
});
accounts.extend(metas)
}
}
}
32 changes: 32 additions & 0 deletions programs/magic-root-program/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "magic-root-program"

authors.workspace = true
edition.workspace = true
homepage.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
version.workspace = true

[dependencies]
magic-root-interface = { workspace = true }

nucleus = { workspace = true, features = ["tls"] }
wincode = { workspace = true }

solana-account = { workspace = true }
solana-instruction = { workspace = true }
solana-instruction-error = { workspace = true }
solana-program-runtime = { workspace = true }
solana-svm-log-collector = { workspace = true }
solana-transaction-context = { workspace = true }

[dev-dependencies]
solana-pubkey = { workspace = true }
solana-sdk-ids = { workspace = true }
solana-svm-callback = { workspace = true, features = ["agave-unstable-api"] }
solana-svm-feature-set = { workspace = true, features = ["agave-unstable-api"] }

[lints]
workspace = true
44 changes: 44 additions & 0 deletions programs/magic-root-program/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# `magic-root-program`

MagicRoot is the engine's privileged native program for patching, finalizing,
and closing accounts. Its wire schema and program id are defined by
`magic-root-interface`.

Every invocation must use the engine `AUTHORITY` as transaction payer/signer.
Direct transaction instructions are accepted. CPI is accepted only when the
immediate caller is registered in the transaction program cache as a builtin;
MagicRoot itself cannot be the caller. Native-loader account metadata alone does
not grant access. Caller authorization and decoding complete before target-state
authorization. The SVM's separate top-level-only privilege rule is unchanged.

## Instructions

- `Patch` applies one `AccountFieldPatch`. Lamport changes are balanced against
the authority account, including no-op balance patches. Slot patches must
advance the stored slot; an equal slot is accepted only when an earlier patch
in the same transaction genuinely changed the account mode. Older slots are
always rejected. Data patches may produce at most 10 MiB of account data;
larger lengths return `InvalidRealloc`. Account mode transitions use the
policy owned by `AccountSharedData`: read-only and placeholder accounts may
transition to any mode except transient, transient accounts may resolve only
to read-only, and delegated accounts may transition only to transient.
Ephemeral accounts may close. Other mode changes are rejected.
- `Finalize` atomically installs the caller-supplied complete flag value and
loads an executable target into the transaction program cache. It does not
change lamports; failed executable loading rolls back the installed flags.
- `Delete` transitions read-only, placeholder, or ephemeral targets to
`AccountMode::Closed`, and accountsdb removes them during writeback. Modes that
cannot transition to closed are rejected.
- `PostFinalize` invokes follow-up instructions through native CPI and is
placed immediately after the target's `Finalize` by internal composers. It
rejects any immutable instruction account marked writable and any action that
targets MagicRoot itself.

After authority and caller checks pass, MagicRoot does not determine whether a
complete account image is stale. Callers must supply current state; slot and
lifecycle validation still apply.

Complete-account patch sequences apply mode before slot. `AccountSharedData`
marks mode dirty only when its value changes, so a no-op mode patch cannot make
an equal-slot replacement appear fresh. Rejection aborts the transaction, and
therefore rolls back every earlier field patch in that sequence.
86 changes: 86 additions & 0 deletions programs/magic-root-program/src/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use solana_account::{
AccountFieldPatch, AccountMode, ReadableAccount, StateFlags, WritableAccount,
};
use solana_instruction_error::InstructionError;
use solana_program_runtime::{invoke_context::InvokeContext, loaded_programs::ProgramCacheEntry};
use solana_svm_log_collector::ic_msg;
use solana_transaction_context::{IndexOfAccount, MAX_ACCOUNT_DATA_LEN};

/// Applies a single-field patch to the target account.
pub(crate) fn patch(
ctx: &InvokeContext<'_, '_>,
target: IndexOfAccount,
patch: AccountFieldPatch,
) -> Result<(), InstructionError> {
let mut account = ctx.transaction_context.accounts().try_borrow_mut(target)?;
ic_msg!(ctx, "MagicRoot: patch {:?}", patch);
let data_len = match &patch {
AccountFieldPatch::DataAt { offset, data } => {
let end = offset.checked_add(data.len()).ok_or(InstructionError::InvalidRealloc)?;
Some(account.data().len().max(end))
}
AccountFieldPatch::DataLen(len) => Some(*len),
_ => None,
};
if data_len.is_some_and(|len| len > MAX_ACCOUNT_DATA_LEN as usize) {
return Err(InstructionError::InvalidRealloc);
}
let old = account.lamports();
if let Err(error) = patch.apply(&mut account) {
ic_msg!(ctx, "MagicRoot: {}", error);
return Err(InstructionError::InvalidArgument);
}
let new = account.lamports();
let mut authority = ctx.transaction_context.accounts().try_borrow_mut(0)?;
// Balance target changes against the authority to preserve total lamports.
if new > old {
authority.checked_sub_lamports(new - old)?;
} else if new < old {
authority.checked_add_lamports(old - new)?;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Ok(())
}

/// Loads an executable target into the transaction's program cache.
pub(crate) fn finalize(
ctx: &mut InvokeContext<'_, '_>,
target: IndexOfAccount,
flags: StateFlags,
) -> Result<(), InstructionError> {
let mut account = ctx.transaction_context.accounts().try_borrow_mut(target)?;
account.set_flags(flags);
if !account.executable() {
return Ok(());
}
let pubkey = ctx.transaction_context.get_key_of_account_at_index(target)?;
let entry = ProgramCacheEntry::new(
ctx.environment_config
.program_runtime_environments_for_execution
.get_env_for_execution()
.clone(),
account.data(),
)
.map_err(|_| {
ic_msg!(ctx, "MagicRoot: program load failed {}", pubkey);
InstructionError::ProgramEnvironmentSetupFailure
})?
.into();
ctx.program_cache_for_tx_batch.store_modified_entry(*pubkey, entry);
ic_msg!(ctx, "MagicRoot: finalized program load");
Ok(())
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

/// Marks the target account closed for removal from storage.
pub(crate) fn delete(
ctx: &InvokeContext<'_, '_>,
target: IndexOfAccount,
) -> Result<(), InstructionError> {
let mut acc = ctx.transaction_context.accounts().try_borrow_mut(target)?;

if let Err(error) = acc.set_mode(AccountMode::Closed) {
ic_msg!(ctx, "MagicRoot: {}", error);
return Err(InstructionError::InvalidArgument);
}
ic_msg!(ctx, "MagicRoot: removed");
Ok(())
}
25 changes: 25 additions & 0 deletions programs/magic-root-program/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#![doc = include_str!("../README.md")]

mod account;
mod post_finalize;
mod processor;
#[cfg(test)]
mod tests;

use solana_instruction_error::InstructionError;
use solana_program_runtime::invoke_context::InvokeContext;

/// Instruction-account index of the account a MagicRoot instruction operates on.
pub const TARGET_ACCOUNT_IDX: u16 = 0;

/// Executes a MagicRoot instruction: authorizes the caller, decodes the
/// instruction, then dispatches it to the matching handler.
pub fn process(ctx: &mut InvokeContext<'_, '_>) -> Result<(), InstructionError> {
processor::process(ctx)
}

#[allow(missing_docs)]
pub mod entrypoint {
use solana_program_runtime::declare_process_instruction;
declare_process_instruction!(MagicRootEntrypoint, 150, |ctx| { super::process(ctx) });
}
39 changes: 39 additions & 0 deletions programs/magic-root-program/src/post_finalize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use solana_instruction::Instruction;
use solana_instruction_error::InstructionError;
use solana_program_runtime::invoke_context::InvokeContext;
use solana_svm_log_collector::ic_msg;

/// Runs the post-finalize follow-up instructions, invoking each action via CPI
/// while vouching for exactly the signers that action itself declares, then
/// rejects the whole instruction if an account exposed as writable did not end
/// in a mode this engine may mutate.
pub(crate) fn process(
ctx: &mut InvokeContext<'_, '_>,
actions: Vec<Instruction>,
) -> Result<(), InstructionError> {
ic_msg!(ctx, "MagicRoot: post-finalize {} action(s)", actions.len());
for action in actions {
let signers: Vec<_> = action
.accounts
.iter()
.filter_map(|meta| meta.is_signer.then_some(meta.pubkey))
.collect();
ctx.native_invoke(action, &signers)?;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

let instruction = ctx.transaction_context.get_current_instruction_context()?;
let count = instruction.get_number_of_instruction_accounts();
for i in 0..count {
let index = instruction.get_index_of_instruction_account_in_transaction(i)?;
let account = ctx.transaction_context.accounts().try_borrow(index)?;
if instruction.is_instruction_account_writable(i)? && !account.mutable() {
ic_msg!(
ctx,
"MagicRoot: post-finalize rejected immutable writable account: {}",
ctx.transaction_context.get_key_of_account_at_index(index)?
);
return Err(InstructionError::Immutable);
}
}
Ok(())
}
Loading