Add Program loader/environment instruction errors (#14120)
This commit is contained in:
@ -13,7 +13,6 @@ use crate::{
|
||||
serialization::{deserialize_parameters, serialize_parameters},
|
||||
syscalls::SyscallError,
|
||||
};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use solana_rbpf::{
|
||||
ebpf::MM_HEAP_START,
|
||||
error::{EbpfError, UserDefinedError},
|
||||
@ -26,7 +25,6 @@ use solana_sdk::{
|
||||
bpf_loader, bpf_loader_deprecated,
|
||||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||
clock::Clock,
|
||||
decode_error::DecodeError,
|
||||
entrypoint::SUCCESS,
|
||||
feature_set::bpf_compute_budget_balancing,
|
||||
instruction::InstructionError,
|
||||
@ -48,22 +46,6 @@ solana_sdk::declare_builtin!(
|
||||
solana_bpf_loader_program::process_instruction
|
||||
);
|
||||
|
||||
/// Errors returned by the BPFLoader if the VM fails to run the program
|
||||
#[derive(Error, Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)]
|
||||
pub enum BPFLoaderError {
|
||||
#[error("failed to create virtual machine")]
|
||||
VirtualMachineCreationFailed = 0x0b9f_0001,
|
||||
#[error("virtual machine failed to run the program to completion")]
|
||||
VirtualMachineFailedToRunProgram = 0x0b9f_0002,
|
||||
#[error("failed to compile program")]
|
||||
JustInTimeCompilationFailed = 0x0b9f_0003,
|
||||
}
|
||||
impl<E> DecodeError<E> for BPFLoaderError {
|
||||
fn type_of() -> &'static str {
|
||||
"BPFLoaderError"
|
||||
}
|
||||
}
|
||||
|
||||
/// Errors returned by functions the BPF Loader registers with the VM
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
pub enum BPFError {
|
||||
@ -107,6 +89,8 @@ pub fn create_and_cache_executor(
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
use_jit: bool,
|
||||
) -> Result<Arc<BPFExecutor>, InstructionError> {
|
||||
let logger = invoke_context.get_logger();
|
||||
|
||||
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
|
||||
let mut program = Executable::<BPFError, ThisInstructionMeter>::from_elf(
|
||||
data,
|
||||
@ -127,11 +111,16 @@ pub fn create_and_cache_executor(
|
||||
!invoke_context.is_feature_active(&bpf_compute_budget_balancing::id()),
|
||||
)
|
||||
.map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e)))?;
|
||||
let syscall_registry = syscalls::register_syscalls(invoke_context)
|
||||
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
||||
let syscall_registry = syscalls::register_syscalls(invoke_context).map_err(|e| {
|
||||
log!(logger, "Failed to register syscalls: {}", e);
|
||||
InstructionError::ProgramEnvironmentSetupFailure
|
||||
})?;
|
||||
program.set_syscall_registry(syscall_registry);
|
||||
if use_jit && program.jit_compile().is_err() {
|
||||
return Err(BPFLoaderError::JustInTimeCompilationFailed.into());
|
||||
if use_jit {
|
||||
if let Err(err) = program.jit_compile() {
|
||||
log!(logger, "Failed to compile program {:?}", err);
|
||||
return Err(InstructionError::ProgramFailedToCompile);
|
||||
}
|
||||
}
|
||||
let executor = Arc::new(BPFExecutor { program });
|
||||
invoke_context.add_executor(key, executor.clone());
|
||||
@ -682,7 +671,7 @@ impl Executor for BPFExecutor {
|
||||
Ok(info) => info,
|
||||
Err(e) => {
|
||||
log!(logger, "Failed to create BPF VM: {}", e);
|
||||
return Err(BPFLoaderError::VirtualMachineCreationFailed.into());
|
||||
return Err(InstructionError::ProgramEnvironmentSetupFailure);
|
||||
}
|
||||
};
|
||||
|
||||
@ -721,7 +710,10 @@ impl Executor for BPFExecutor {
|
||||
EbpfError::UserError(BPFError::SyscallError(
|
||||
SyscallError::InstructionError(error),
|
||||
)) => error,
|
||||
_ => BPFLoaderError::VirtualMachineFailedToRunProgram.into(),
|
||||
err => {
|
||||
log!(logger, "Program failed to complete: {:?}", err);
|
||||
InstructionError::ProgramFailedToComplete
|
||||
}
|
||||
};
|
||||
|
||||
stable_log::program_failure(&logger, program.unsigned_key(), &error);
|
||||
@ -1010,7 +1002,7 @@ mod tests {
|
||||
Arc::new(FeatureSet::default()),
|
||||
);
|
||||
assert_eq!(
|
||||
Err(InstructionError::Custom(194969602)),
|
||||
Err(InstructionError::ProgramFailedToComplete),
|
||||
process_instruction(&bpf_loader::id(), &keyed_accounts, &[], &mut invoke_context)
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user