diff --git a/src/entrypoint.rs b/src/entrypoint.rs new file mode 100644 index 00000000..180f10c4 --- /dev/null +++ b/src/entrypoint.rs @@ -0,0 +1,44 @@ +use crate::{fast_process_instruction, slow_process_instruction}; + +use solana_program::entrypoint; + +entrypoint::custom_heap_default!(); +entrypoint::custom_panic_default!(); + +/// # Safety +/// +/// It's pretty close to the code generated by entrypoint!() macro, with one minor tweak to +/// support fallback branch. +#[no_mangle] +pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { + const UNINIT: core::mem::MaybeUninit = + core::mem::MaybeUninit::::uninit(); + let mut accounts = [UNINIT; { pinocchio::MAX_TX_ACCOUNTS }]; + + let (program_id, count, data) = + pinocchio::entrypoint::deserialize::<{ pinocchio::MAX_TX_ACCOUNTS }>(input, &mut accounts); + match fast_process_instruction( + program_id, + core::slice::from_raw_parts(accounts.as_ptr() as _, count), + data, + ) { + Some(Ok(())) => pinocchio::SUCCESS, + Some(Err(error)) => error.into(), + + // Fallback to the slow path that does not use pinocchio SDK. + None => slow_entrypoint(input), + } +} + +/// # Safety +/// +/// It's pretty close to the code generated by entrypoint!() macro, with one difference: the +/// function name is slow_entrypoint() as opposed to entrypoint() because this is a fallback +/// entrypoint (a slow one). +pub unsafe fn slow_entrypoint(input: *mut u8) -> u64 { + let (program_id, accounts, instruction_data) = unsafe { entrypoint::deserialize(input) }; + match slow_process_instruction(program_id, &accounts, instruction_data) { + Ok(()) => entrypoint::SUCCESS, + Err(error) => error.into(), + } +} diff --git a/src/lib.rs b/src/lib.rs index 15a25c76..b3cf4396 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,12 @@ #![allow(unexpected_cfgs)] // silence clippy for target_os solana and other solana program custom features -use crate::processor::process_call_handler; +use crate::discriminator::DlpDiscriminator; use pinocchio_log::log; -use solana_program::{ - account_info::AccountInfo, - declare_id, - entrypoint::{self, ProgramResult}, - msg, - program_error::ProgramError, - pubkey::Pubkey, -}; - -use discriminator::DlpDiscriminator; +use solana_program::account_info::AccountInfo; +use solana_program::entrypoint::ProgramResult; +use solana_program::program_error::ProgramError; +use solana_program::pubkey::Pubkey; +use solana_program::{declare_id, msg}; pub mod args; pub mod consts; @@ -24,6 +19,8 @@ pub mod state; #[cfg(feature = "log-cost")] mod cu; +#[cfg(not(feature = "no-entrypoint"))] +mod entrypoint; declare_id!("DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh"); @@ -31,9 +28,6 @@ pub mod fast { pinocchio_pubkey::declare_id!("DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh"); } -entrypoint::custom_heap_default!(); -entrypoint::custom_panic_default!(); - #[cfg(all(not(feature = "no-entrypoint"), feature = "solana-security-txt"))] solana_security_txt::security_txt! { name: "MagicBlock Delegation Program", @@ -44,44 +38,6 @@ solana_security_txt::security_txt! { source_code: "https://github.com/magicblock-labs/delegation-program" } -/// # Safety -/// -/// It's pretty close to the code generated by entrypoint!() macro, with one minor tweak to -/// support fallback branch. -#[no_mangle] -pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { - const UNINIT: core::mem::MaybeUninit = - core::mem::MaybeUninit::::uninit(); - let mut accounts = [UNINIT; { pinocchio::MAX_TX_ACCOUNTS }]; - - let (program_id, count, data) = - pinocchio::entrypoint::deserialize::<{ pinocchio::MAX_TX_ACCOUNTS }>(input, &mut accounts); - match fast_process_instruction( - program_id, - core::slice::from_raw_parts(accounts.as_ptr() as _, count), - data, - ) { - Some(Ok(())) => pinocchio::SUCCESS, - Some(Err(error)) => error.into(), - - // Fallback to the slow path that does not use pinocchio SDK. - None => slow_entrypoint(input), - } -} - -/// # Safety -/// -/// It's pretty close to the code generated by entrypoint!() macro, with one difference: the -/// function name is slow_entrypoint() as opposed to entrypoint() because this is a fallback -/// entrypoint (a slow one). -pub unsafe fn slow_entrypoint(input: *mut u8) -> u64 { - let (program_id, accounts, instruction_data) = unsafe { entrypoint::deserialize(input) }; - match slow_process_instruction(program_id, &accounts, instruction_data) { - Ok(()) => entrypoint::SUCCESS, - Err(error) => error.into(), - } -} - pub fn fast_process_instruction( program_id: &pinocchio::pubkey::Pubkey, accounts: &[pinocchio::account_info::AccountInfo], @@ -106,19 +62,19 @@ pub fn fast_process_instruction( }; match discriminator { - discriminator::DlpDiscriminator::Delegate => Some(processor::fast::process_delegate( + DlpDiscriminator::Delegate => Some(processor::fast::process_delegate( program_id, accounts, data, )), - discriminator::DlpDiscriminator::CommitState => Some( - processor::fast::process_commit_state(program_id, accounts, data), - ), - discriminator::DlpDiscriminator::CommitStateFromBuffer => Some( + DlpDiscriminator::CommitState => Some(processor::fast::process_commit_state( + program_id, accounts, data, + )), + DlpDiscriminator::CommitStateFromBuffer => Some( processor::fast::process_commit_state_from_buffer(program_id, accounts, data), ), - discriminator::DlpDiscriminator::Finalize => Some(processor::fast::process_finalize( + DlpDiscriminator::Finalize => Some(processor::fast::process_finalize( program_id, accounts, data, )), - discriminator::DlpDiscriminator::Undelegate => Some(processor::fast::process_undelegate( + DlpDiscriminator::Undelegate => Some(processor::fast::process_undelegate( program_id, accounts, data, )), _ => None, @@ -135,40 +91,39 @@ pub fn slow_process_instruction( } let (tag, data) = data.split_at(8); - let ix = discriminator::DlpDiscriminator::try_from(tag[0]) - .or(Err(ProgramError::InvalidInstructionData))?; + let ix = DlpDiscriminator::try_from(tag[0]).or(Err(ProgramError::InvalidInstructionData))?; msg!("Processing instruction: {:?}", ix); match ix { - discriminator::DlpDiscriminator::InitValidatorFeesVault => { + DlpDiscriminator::InitValidatorFeesVault => { processor::process_init_validator_fees_vault(program_id, accounts, data)? } - discriminator::DlpDiscriminator::InitProtocolFeesVault => { + DlpDiscriminator::InitProtocolFeesVault => { processor::process_init_protocol_fees_vault(program_id, accounts, data)? } - discriminator::DlpDiscriminator::ValidatorClaimFees => { + DlpDiscriminator::ValidatorClaimFees => { processor::process_validator_claim_fees(program_id, accounts, data)? } - discriminator::DlpDiscriminator::WhitelistValidatorForProgram => { + DlpDiscriminator::WhitelistValidatorForProgram => { processor::process_whitelist_validator_for_program(program_id, accounts, data)? } - discriminator::DlpDiscriminator::TopUpEphemeralBalance => { + DlpDiscriminator::TopUpEphemeralBalance => { processor::process_top_up_ephemeral_balance(program_id, accounts, data)? } - discriminator::DlpDiscriminator::DelegateEphemeralBalance => { + DlpDiscriminator::DelegateEphemeralBalance => { processor::process_delegate_ephemeral_balance(program_id, accounts, data)? } - discriminator::DlpDiscriminator::CloseEphemeralBalance => { + DlpDiscriminator::CloseEphemeralBalance => { processor::process_close_ephemeral_balance(program_id, accounts, data)? } - discriminator::DlpDiscriminator::ProtocolClaimFees => { + DlpDiscriminator::ProtocolClaimFees => { processor::process_protocol_claim_fees(program_id, accounts, data)? } - discriminator::DlpDiscriminator::CloseValidatorFeesVault => { + DlpDiscriminator::CloseValidatorFeesVault => { processor::process_close_validator_fees_vault(program_id, accounts, data)? } - discriminator::DlpDiscriminator::CallHandler => { - process_call_handler(program_id, accounts, data)? + DlpDiscriminator::CallHandler => { + processor::process_call_handler(program_id, accounts, data)? } _ => { log!("PANIC: Instruction must be processed by fast_process_instruction");