magicsvm 0.2.1

A fast and lightweight Solana + MagicBlock VM simulator for testing solana programs
use {
    crate::magic::magic_program::{
        ephemeral_accounts::{
            process_close_ephemeral_account, process_create_ephemeral_account,
            process_resize_ephemeral_account,
        },
        schedule_commit::{process_schedule_commit, process_schedule_commit_intent},
    },
    solana_program_runtime::{declare_process_instruction, invoke_context::InvokeContext},
    solana_transaction::InstructionError,
};

mod ephemeral_accounts;
pub(crate) mod instruction;
mod schedule_commit;

pub(crate) use instruction::{magic_instruction, MagicInstruction};

const DEFAULT_MAGIC_PROGRAM_COMPUTE_UNITS: u64 = 150;

declare_process_instruction!(
    MagicProgramEntrypoint,
    DEFAULT_MAGIC_PROGRAM_COMPUTE_UNITS,
    |invoke_context| { process_magic_program_instruction(invoke_context) }
);

fn process_magic_program_instruction(
    invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
    let instruction_context = invoke_context
        .transaction_context
        .get_current_instruction_context()?;
    match magic_instruction(instruction_context.get_instruction_data())? {
        MagicInstruction::ScheduleCommit => process_schedule_commit(&instruction_context, false),
        MagicInstruction::ScheduleCommitAndUndelegate => {
            process_schedule_commit(&instruction_context, true)
        }
        MagicInstruction::ScheduleCommitFinalize {
            request_undelegation,
        } => process_schedule_commit(&instruction_context, request_undelegation),
        MagicInstruction::ScheduleBaseIntent {
            committed_accounts,
            undelegated_accounts,
            ..
        }
        | MagicInstruction::ScheduleIntentBundle {
            committed_accounts,
            undelegated_accounts,
            ..
        } => process_schedule_commit_intent(
            &instruction_context,
            &committed_accounts,
            &undelegated_accounts,
        ),
        MagicInstruction::CreateEphemeralAccount { data_len } => {
            process_create_ephemeral_account(invoke_context, data_len)
        }
        MagicInstruction::ResizeEphemeralAccount { new_data_len } => {
            process_resize_ephemeral_account(invoke_context, new_data_len)
        }
        MagicInstruction::CloseEphemeralAccount => process_close_ephemeral_account(invoke_context),
        MagicInstruction::Noop => Ok(()),
    }
}