Skip to main content

InvokeContext

Struct InvokeContext 

Source
pub struct InvokeContext<'a, 'b> {
    pub transaction_context: &'a mut TransactionContext,
    pub program_cache_for_tx_batch: &'a mut ProgramCacheForTx<'b>,
    pub environment_config: EnvironmentConfig<'a>,
    pub execute_time: Option<Measure>,
    pub timings: ExecuteDetailsTimings,
    pub syscall_context: Vec<Option<SyscallContext>>,
    pub account_loader: Option<Box<dyn RuntimeAccountLoader + 'a>>,
    /* private fields */
}
Expand description

Main pipeline from runtime to program execution.

Fields§

§transaction_context: &'a mut TransactionContext

Information about the currently executing transaction.

§program_cache_for_tx_batch: &'a mut ProgramCacheForTx<'b>

The local program cache for the transaction batch.

§environment_config: EnvironmentConfig<'a>

Runtime configurations used to provision the invocation environment.

§execute_time: Option<Measure>

Latest measurement not yet accumulated in ExecuteDetailsTimings::execute_us

§timings: ExecuteDetailsTimings§syscall_context: Vec<Option<SyscallContext>>§account_loader: Option<Box<dyn RuntimeAccountLoader + 'a>>

Implementations§

Source§

impl<'a, 'b> InvokeContext<'a, 'b>

Source

pub fn new( transaction_context: &'a mut TransactionContext, program_cache_for_tx_batch: &'a mut ProgramCacheForTx<'b>, environment_config: EnvironmentConfig<'a>, log_collector: Option<Rc<RefCell<LogCollector>>>, compute_budget: ComputeBudget, ) -> Self

Source

pub fn new_with_account_loader( transaction_context: &'a mut TransactionContext, program_cache_for_tx_batch: &'a mut ProgramCacheForTx<'b>, environment_config: EnvironmentConfig<'a>, log_collector: Option<Rc<RefCell<LogCollector>>>, compute_budget: ComputeBudget, account_loader: Box<dyn RuntimeAccountLoader + 'a>, num_account_locks: usize, num_writable_accounts: usize, ) -> Self

Source

pub fn add_loaded_account( &mut self, pubkey: Pubkey, ) -> Result<(), AccountInsertError>

Attempt to loaded account pubkey into InvokeContext.

Returns Ok(()) on success Returns Err(AccountInsertError::TooManyAccounts) if too many accounts have been loaded. Returns Err(AccountInsertError::AccountAlreadyLoaded) if account has already been loaded.

Source

pub fn get_environments_for_slot( &self, effective_slot: Slot, ) -> Result<&ProgramRuntimeEnvironments, InstructionError>

Source

pub fn push(&mut self) -> Result<(), InstructionError>

Push a stack frame onto the invocation stack

Source

pub fn get_stack_height(&self) -> usize

Current height of the invocation stack, top level instructions are height rialo_s_instruction::TRANSACTION_LEVEL_STACK_HEIGHT

Source

pub fn native_invoke( &mut self, instruction: StableInstruction, signers: &[Pubkey], ) -> Result<(), InstructionError>

Entrypoint for a cross-program invocation from a builtin program

Source

pub fn prepare_instruction( &mut self, instruction: &StableInstruction, signers: &[Pubkey], ) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError>

Helper to prepare for process_instruction()

Source

pub fn prepare_cpi_instruction( &mut self, program_id: Pubkey, account_metas: &[AccountMeta], signers: &[Pubkey], ) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError>

Helper to prepare for process_instruction()

Source

pub fn prepare_instruction_inner( &mut self, callee_program_id: Pubkey, account_metas: &[AccountMeta], signers: &[Pubkey], ) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError>

Source

pub fn process_instruction( &mut self, instruction_data: &[u8], instruction_accounts: &[InstructionAccount], program_indices: &[IndexOfAccount], compute_units_consumed: &mut u64, timings: &mut ExecuteTimings, ) -> Result<(), InstructionError>

Processes an instruction and returns how many compute units were used

Source

pub fn process_precompile<'ix_data>( &mut self, precompile: &Precompile, instruction_data: &[u8], instruction_accounts: &[InstructionAccount], program_indices: &[IndexOfAccount], message_instruction_datas_iter: impl Iterator<Item = &'ix_data [u8]>, ) -> Result<(), InstructionError>

Processes a precompile instruction

Source

pub fn get_log_collector(&self) -> Option<Rc<RefCell<LogCollector>>>

Get this invocation’s LogCollector

Source

pub fn consume_checked(&self, amount: u64) -> Result<(), Box<dyn Error>>

Consume compute units

Source

pub fn mock_set_remaining(&self, remaining: u64)

Set compute units

Only use for tests and benchmarks

Source

pub fn get_compute_budget(&self) -> &ComputeBudget

Get this invocation’s compute budget

Source

pub fn get_feature_set(&self) -> &FeatureSet

Get the current feature set.

Source

pub fn mock_set_feature_set(&mut self, feature_set: Arc<FeatureSet>)

Set feature set.

Only use for tests and benchmarks.

Source

pub fn get_sysvar_cache(&self) -> &SysvarCache

Get cached sysvars

Source

pub fn get_epoch_vote_account_stake(&self, pubkey: &'a Pubkey) -> u64

Get cached stake for the epoch vote account.

Source

pub fn get_current_epoch(&self) -> u64

Get the CURRENT epoch (the epoch that is actively running).

This is the epoch to use when checking stake activation/deactivation status, unbonding periods, lockup periods, etc.

§Implementation Note

The stake cache stores the NEXT epoch (the epoch being prepared for when stake changes become effective). We subtract 1 to get the current epoch. saturating_sub handles the edge case of epoch 0.

Source

pub fn get_next_epoch(&self) -> u64

Get the NEXT epoch (the epoch being prepared in the stake cache).

This is the epoch that accumulated stake changes will become effective in AFTER the next FreezeStakes call. Most instruction logic should use get_current_epoch() instead; this method is primarily for internal use and the FreezeStakes instruction.

Source

pub fn get_last_freeze_timestamp(&self) -> u64

Get the timestamp of the last FreezeStakes call (last epoch boundary).

This is the timestamp from history.back() which represents when the most recent epoch boundary occurred. Use this for state transition checks:

  • A stake is “activating” while activation_requested >= last_freeze_timestamp
  • A stake becomes “activated” when activation_requested < last_freeze_timestamp
  • A stake is “deactivating” while deactivation_requested >= last_freeze_timestamp
  • A stake becomes “deactivated” when deactivation_requested < last_freeze_timestamp

Returns 0 if no history exists (should not happen in normal operation since StakingState::new_with_initial_history() guarantees at least one entry).

Note: For duration enforcement (lockup, unbonding), use the current timestamp from Clock sysvar instead, to provide real-time guarantees.

Source

pub fn mock_set_last_freeze_timestamp(&mut self, timestamp: u64)

Set the last freeze timestamp for testing.

This is the primary mock function for timestamp-based tests. It sets up the stake cache so that get_last_freeze_timestamp() returns the specified timestamp.

The function:

  1. Sets the pending epoch to 1 (to avoid underflow when computing current epoch)
  2. Pushes a StakeCacheData entry to history with epoch=0 and the specified timestamp

Only use for tests and benchmarks.

Source

pub fn mock_insert_stake_account( &mut self, pubkey: Pubkey, account: StakeAccount, )

Insert a stake account into the pending cache for testing.

This allows unit tests to set up stake accounts that reference validators, which is needed to test the validator withdrawal blocking logic.

Only use for tests and benchmarks.

Source

pub fn freeze_stakes(&self)

Freeze the pending stake cache data.

This performs an O(1) swap of the pending stake cache data using std::mem::take() and pushes it to the back of the frozen queue. This is typically called by the ValidatorRegistry program’s FreezeStakes instruction to capture the validator set at a specific point.

This method also sets the epoch_stakes_frozen flag to signal the Bank to propagate new_commission_ratecommission_rate, etc.

To access the frozen validator data after calling this method, use get_all_validator_accounts_from_last_frozen().

Source

pub fn signal_freeze_stakes(&self)

Signal that FreezeStakes was requested without performing the swap.

The actual pending → frozen swap is deferred to finalize_impl() to ensure pending modifications are persisted first. This only sets the epoch_stakes_frozen flag, which is read by apply_pending_validator_changes_if_needed() and consumed by finalize_impl().

Source

pub fn get_all_validator_accounts_from_last_frozen( &self, ) -> Vec<(Pubkey, ValidatorAccount)>

Get all validator accounts from the last frozen epoch (current epoch state).

Returns a vector of (pubkey, ValidatorAccount) pairs for all validators, sorted by pubkey. This performs a layered lookup: frozen (newest to oldest) → baseline, skipping pending (next epoch changes).

This method allows builtin programs (like TokenomicsGovernance) to access the frozen validator data directly without needing CPI return data.

Source

pub fn frozen_stake_history_len(&self) -> usize

Get the length of the frozen stake history.

Used by DistributeRewards to check if there are enough frozen snapshots to merge. We require at least 2 entries to allow popping (to preserve the current epoch snapshot).

Source

pub fn request_epoch_rewards_init(&self, epoch: u64, total_rewards: u64)

Request epoch rewards initialization.

Called by DistributeRewards instruction to signal the Bank to create an EpochRewards account for tracking partitioned reward distribution. The Bank will detect this signal after transaction execution and create the account outside of instruction processing.

§Arguments
  • epoch - The epoch number for which rewards are being distributed
  • total_rewards - The total amount of rewards to be distributed this epoch
Source

pub fn front_frozen_epoch(&self) -> Option<u64>

Get the epoch of the oldest frozen snapshot (front of the queue).

This is the epoch that will be popped by pop_front_and_merge_to_baseline(). Used by DistributeRewards to know which epoch rewards are being distributed.

Returns None if no frozen snapshots exist.

Source

pub fn is_validator_referenced( &self, validator: &Pubkey, validator_info: &ValidatorInfo, last_freeze_timestamp: u64, current_timestamp: u64, ) -> bool

Check if any stake account references the given validator whose unbonding period is NOT yet complete.

This performs an O(n) search over all stake accounts using a layered lookup (pending → frozen → baseline) to determine if the validator is referenced by an active or still-unbonding stake.

Used by ValidatorRegistry’s Withdraw handler to prevent withdrawal below rent-exempt minimum while stake accounts still reference the validator.

A stake is considered to “reference” the validator if:

  • It is delegated to this validator, AND
  • Either active (no deactivation) OR still unbonding (unbonding not complete)

Stake accounts whose unbonding is complete are NOT counted, since they can be fully withdrawn or reactivated to another validator.

§Arguments
  • validator - The validator pubkey to check
  • validator_info - The validator’s info (used to compute unbonding end via end_of_unbonding)
  • last_freeze_timestamp - Timestamp from last FreezeStakes (epoch boundary)
  • current_timestamp - Current block timestamp from Clock sysvar
Source

pub fn has_locked_stakers( &self, validator: &Pubkey, lockup_period: u64, current_timestamp: u64, ) -> bool

Check if any stake account delegated to the given validator is still within its lockup period.

Delegates to StakesHandle::has_locked_stakers() which performs an O(n) scan over all stake accounts. A staker is “locked” if their activation_requested + lockup_period > current_timestamp.

§Arguments
  • validator - The validator pubkey to check
  • lockup_period - The validator’s lockup period in milliseconds
  • current_timestamp - Current block timestamp from Clock sysvar (in milliseconds)
§Returns

true if at least one staker is still within their lockup period.

Source

pub fn is_validator_referenced_excluding_self_bond( &self, validator_pubkey: &Pubkey, validator_info: &ValidatorInfo, last_freeze_timestamp: u64, current_timestamp: u64, ) -> bool

Check if a validator is referenced by any stake accounts (excluding the self-bond).

This variant excludes the self-bond PDA from the check to prevent circular logic where the self-bond cannot be deactivated because its existence always makes is_validator_referenced() return true.

Source

pub fn get_stake_account_from_pending( &self, pubkey: &Pubkey, ) -> Option<StakeAccount>

Look up a stake account by pubkey from the pending layer (next epoch state).

Searches: pending → frozen (newest to oldest) → baseline. Returns Some(StakeAccount) if found, None if not found or tombstoned.

Source

pub fn is_epoch_rewards_init_pending(&self) -> bool

Check if an epoch rewards initialization request is pending for this block.

Used by DistributeRewards to prevent multiple reward distributions in the same block. If this returns true, the DistributeRewards instruction should fail with InvalidArgument.

Source

pub fn completed_frozen_epochs(&self) -> Vec<u64>

Get completed frozen epochs (excludes the last/current epoch).

Returns epochs in order from oldest to newest. These are the epochs that have completed and are eligible for reward distribution. We exclude the last frozen epoch because it represents the current epoch that is still accumulating rewards.

Source

pub fn epoch_rewards_exists(&self, epoch: u64) -> bool

Check if an EpochRewards account exists for the given epoch.

Delegates to the StakesHandle which contains the callback provided by Bank to query the StateStore. This allows DistributeRewards to find the first completed frozen epoch that doesn’t yet have an EpochRewards account.

Source

pub fn get_check_aligned(&self) -> bool

Source

pub fn set_syscall_context( &mut self, syscall_context: SyscallContext, ) -> Result<(), InstructionError>

Source

pub fn get_syscall_context(&self) -> Result<&SyscallContext, InstructionError>

Source

pub fn get_syscall_context_mut( &mut self, ) -> Result<&mut SyscallContext, InstructionError>

Source

pub fn get_traces(&self) -> &Vec<Vec<[u64; 12]>>

Return a references to traces

Trait Implementations§

Source§

impl ContextObject for InvokeContext<'_, '_>

Source§

fn trace(&mut self, state: [u64; 12])

Called for every instruction executed when tracing is enabled
Source§

fn consume(&mut self, amount: u64)

Consume instructions from meter
Source§

fn get_remaining(&self) -> u64

Get the number of remaining instructions allowed

Auto Trait Implementations§

§

impl<'a, 'b> !Freeze for InvokeContext<'a, 'b>

§

impl<'a, 'b> !RefUnwindSafe for InvokeContext<'a, 'b>

§

impl<'a, 'b> !Send for InvokeContext<'a, 'b>

§

impl<'a, 'b> !Sync for InvokeContext<'a, 'b>

§

impl<'a, 'b> Unpin for InvokeContext<'a, 'b>

§

impl<'a, 'b> UnsafeUnpin for InvokeContext<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for InvokeContext<'a, 'b>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V