use {
solana_program_runtime::invoke_context::InvokeContext, solana_svm_timings::ExecuteTimings,
solana_svm_transaction::svm_message::SVMMessage, solana_transaction_context::IndexOfAccount,
solana_transaction_error::TransactionError,
};
pub(crate) fn process_message<'ix_data>(
message: &'ix_data impl SVMMessage,
program_indices: &[IndexOfAccount],
invoke_context: &mut InvokeContext<'_, 'ix_data>,
execute_timings: &mut ExecuteTimings,
accumulated_consumed_units: &mut u64,
) -> Result<(), TransactionError> {
debug_assert_eq!(program_indices.len(), message.num_instructions());
for (top_level_instruction_index, ((program_id, instruction), program_account_index)) in message
.program_instructions_iter()
.zip(program_indices.iter())
.enumerate()
{
invoke_context
.prepare_next_top_level_instruction(
message,
&instruction,
*program_account_index,
instruction.data,
)
.map_err(|err| {
TransactionError::InstructionError(top_level_instruction_index as u8, err)
})?;
let mut compute_units_consumed = 0;
let result = if invoke_context.is_precompile(program_id) {
invoke_context.process_precompile(
program_id,
instruction.data,
message.instructions_iter().map(|ix| ix.data),
)
} else {
invoke_context.process_instruction(&mut compute_units_consumed, execute_timings)
};
*accumulated_consumed_units =
accumulated_consumed_units.saturating_add(compute_units_consumed);
result.map_err(|err| {
TransactionError::InstructionError(top_level_instruction_index as u8, err)
})?;
}
Ok(())
}