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 TransactionContextInformation 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>
impl<'a, 'b> InvokeContext<'a, 'b>
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
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
Sourcepub fn add_loaded_account(
&mut self,
pubkey: Pubkey,
) -> Result<(), AccountInsertError>
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.
pub fn get_environments_for_slot( &self, effective_slot: Slot, ) -> Result<&ProgramRuntimeEnvironments, InstructionError>
Sourcepub fn push(&mut self) -> Result<(), InstructionError>
pub fn push(&mut self) -> Result<(), InstructionError>
Push a stack frame onto the invocation stack
Sourcepub fn get_stack_height(&self) -> usize
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
Sourcepub fn native_invoke(
&mut self,
instruction: StableInstruction,
signers: &[Pubkey],
) -> Result<(), InstructionError>
pub fn native_invoke( &mut self, instruction: StableInstruction, signers: &[Pubkey], ) -> Result<(), InstructionError>
Entrypoint for a cross-program invocation from a builtin program
Sourcepub fn prepare_instruction(
&mut self,
instruction: &StableInstruction,
signers: &[Pubkey],
) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError>
pub fn prepare_instruction( &mut self, instruction: &StableInstruction, signers: &[Pubkey], ) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError>
Helper to prepare for process_instruction()
Sourcepub fn prepare_cpi_instruction(
&mut self,
program_id: Pubkey,
account_metas: &[AccountMeta],
signers: &[Pubkey],
) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError>
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()
pub fn prepare_instruction_inner( &mut self, callee_program_id: Pubkey, account_metas: &[AccountMeta], signers: &[Pubkey], ) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError>
Sourcepub fn process_instruction(
&mut self,
instruction_data: &[u8],
instruction_accounts: &[InstructionAccount],
program_indices: &[IndexOfAccount],
compute_units_consumed: &mut u64,
timings: &mut ExecuteTimings,
) -> Result<(), InstructionError>
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
Sourcepub 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>
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
Sourcepub fn get_log_collector(&self) -> Option<Rc<RefCell<LogCollector>>>
pub fn get_log_collector(&self) -> Option<Rc<RefCell<LogCollector>>>
Get this invocation’s LogCollector
Sourcepub fn mock_set_remaining(&self, remaining: u64)
pub fn mock_set_remaining(&self, remaining: u64)
Set compute units
Only use for tests and benchmarks
Sourcepub fn get_compute_budget(&self) -> &ComputeBudget
pub fn get_compute_budget(&self) -> &ComputeBudget
Get this invocation’s compute budget
Sourcepub fn get_feature_set(&self) -> &FeatureSet
pub fn get_feature_set(&self) -> &FeatureSet
Get the current feature set.
Sourcepub fn mock_set_feature_set(&mut self, feature_set: Arc<FeatureSet>)
pub fn mock_set_feature_set(&mut self, feature_set: Arc<FeatureSet>)
Set feature set.
Only use for tests and benchmarks.
Sourcepub fn get_sysvar_cache(&self) -> &SysvarCache
pub fn get_sysvar_cache(&self) -> &SysvarCache
Get cached sysvars
Sourcepub fn get_epoch_vote_account_stake(&self, pubkey: &'a Pubkey) -> u64
pub fn get_epoch_vote_account_stake(&self, pubkey: &'a Pubkey) -> u64
Get cached stake for the epoch vote account.
Sourcepub fn get_current_epoch(&self) -> u64
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.
Sourcepub fn get_next_epoch(&self) -> u64
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.
Sourcepub fn get_last_freeze_timestamp(&self) -> u64
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.
Sourcepub fn mock_set_last_freeze_timestamp(&mut self, timestamp: u64)
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:
- Sets the pending epoch to 1 (to avoid underflow when computing current epoch)
- Pushes a
StakeCacheDataentry to history with epoch=0 and the specified timestamp
Only use for tests and benchmarks.
Sourcepub fn mock_insert_stake_account(
&mut self,
pubkey: Pubkey,
account: StakeAccount,
)
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.
Sourcepub fn freeze_stakes(&self)
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_rate → commission_rate, etc.
To access the frozen validator data after calling this method, use
get_all_validator_accounts_from_last_frozen().
Sourcepub fn signal_freeze_stakes(&self)
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().
Sourcepub fn get_all_validator_accounts_from_last_frozen(
&self,
) -> Vec<(Pubkey, ValidatorAccount)>
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.
Sourcepub fn frozen_stake_history_len(&self) -> usize
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).
Sourcepub fn request_epoch_rewards_init(&self, epoch: u64, total_rewards: u64)
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 distributedtotal_rewards- The total amount of rewards to be distributed this epoch
Sourcepub fn front_frozen_epoch(&self) -> Option<u64>
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.
Sourcepub fn is_validator_referenced(
&self,
validator: &Pubkey,
validator_info: &ValidatorInfo,
last_freeze_timestamp: u64,
current_timestamp: u64,
) -> bool
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 checkvalidator_info- The validator’s info (used to compute unbonding end viaend_of_unbonding)last_freeze_timestamp- Timestamp from last FreezeStakes (epoch boundary)current_timestamp- Current block timestamp from Clock sysvar
Sourcepub fn has_locked_stakers(
&self,
validator: &Pubkey,
lockup_period: u64,
current_timestamp: u64,
) -> bool
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 checklockup_period- The validator’s lockup period in millisecondscurrent_timestamp- Current block timestamp from Clock sysvar (in milliseconds)
§Returns
true if at least one staker is still within their lockup period.
Sourcepub fn is_validator_referenced_excluding_self_bond(
&self,
validator_pubkey: &Pubkey,
validator_info: &ValidatorInfo,
last_freeze_timestamp: u64,
current_timestamp: u64,
) -> bool
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.
Sourcepub fn get_stake_account_from_pending(
&self,
pubkey: &Pubkey,
) -> Option<StakeAccount>
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.
Sourcepub fn is_epoch_rewards_init_pending(&self) -> bool
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.
Sourcepub fn completed_frozen_epochs(&self) -> Vec<u64>
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.
Sourcepub fn epoch_rewards_exists(&self, epoch: u64) -> bool
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.
pub fn get_check_aligned(&self) -> bool
pub fn set_syscall_context( &mut self, syscall_context: SyscallContext, ) -> Result<(), InstructionError>
pub fn get_syscall_context(&self) -> Result<&SyscallContext, InstructionError>
pub fn get_syscall_context_mut( &mut self, ) -> Result<&mut SyscallContext, InstructionError>
Trait Implementations§
Source§impl ContextObject for InvokeContext<'_, '_>
impl ContextObject for InvokeContext<'_, '_>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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