diff --git a/Cargo.lock b/Cargo.lock index 36a0185cb8..428d9dfd7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3645,9 +3645,12 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "solana-logger 0.24.0", "solana-sdk 0.24.0", "solana_rbpf 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/programs/bpf_loader/Cargo.toml b/programs/bpf_loader/Cargo.toml index 85af5fd76c..0bf5a09aaf 100644 --- a/programs/bpf_loader/Cargo.toml +++ b/programs/bpf_loader/Cargo.toml @@ -13,9 +13,12 @@ bincode = "1.2.1" byteorder = "1.3.2" libc = "0.2.66" log = "0.4.8" +num-derive = { version = "0.3" } +num-traits = { version = "0.2" } solana-logger = { path = "../../logger", version = "0.24.0" } solana-sdk = { path = "../../sdk", version = "0.24.0" } solana_rbpf = "=0.1.21" +thiserror = "1.0" [lib] crate-type = ["lib", "cdylib"] diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 3fb27ad184..720d9038ed 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -5,12 +5,14 @@ pub mod helpers; use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; use log::*; +use num_derive::{FromPrimitive, ToPrimitive}; use solana_rbpf::{memory_region::MemoryRegion, EbpfVm}; use solana_sdk::{ account::KeyedAccount, entrypoint::SUCCESS, instruction::InstructionError, loader_instruction::LoaderInstruction, + program_utils::DecodeError, program_utils::{is_executable, limited_deserialize, next_keyed_account}, pubkey::Pubkey, sysvar::rent, @@ -19,6 +21,7 @@ use std::{ io::{prelude::*, Error}, mem, }; +use thiserror::Error; solana_sdk::declare_program!( solana_sdk::bpf_loader::ID, @@ -26,6 +29,20 @@ solana_sdk::declare_program!( process_instruction ); +#[derive(Error, Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] +pub enum BPFLoaderError { + #[error("Failed to create virtual machine")] + VirtualMachineCreationFailed, + #[error("Virtual machine failed to run the program to completion")] + VirtualMachineFailedToRunProgram, +} + +impl DecodeError for BPFLoaderError { + fn type_of() -> &'static str { + "BPFLoaderError" + } +} + pub fn create_vm(prog: &[u8]) -> Result<(EbpfVm, MemoryRegion), Error> { let mut vm = EbpfVm::new(None)?; vm.set_verifier(bpf_verifier::check)?; @@ -138,7 +155,7 @@ pub fn process_instruction( Ok(info) => info, Err(e) => { warn!("Failed to create BPF VM: {}", e); - return Err(InstructionError::GenericError); + return Err(BPFLoaderError::VirtualMachineCreationFailed.into()); } }; let parameter_accounts = keyed_accounts_iter.as_slice(); @@ -156,7 +173,7 @@ pub fn process_instruction( } Err(e) => { warn!("BPF VM failed to run program: {}", e); - return Err(InstructionError::GenericError); + return Err(BPFLoaderError::VirtualMachineFailedToRunProgram.into()); } } deserialize_parameters(parameter_accounts, ¶meter_bytes)?;