|
|
@@ -1,6 +1,7 @@
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
use crate::borsh_encoding::{decode_at_offset, encode_arguments, BorshToken};
|
|
|
+use anchor_syn::idl::Idl;
|
|
|
use base58::{FromBase58, ToBase58};
|
|
|
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
|
|
use libc::c_char;
|
|
|
@@ -12,19 +13,17 @@ use solana_rbpf::{
|
|
|
elf::Executable,
|
|
|
error::EbpfError,
|
|
|
memory_region::{AccessType, MemoryMapping, MemoryRegion},
|
|
|
- question_mark,
|
|
|
- syscalls::BpfSyscallContext,
|
|
|
- user_error::UserError,
|
|
|
verifier::RequisiteVerifier,
|
|
|
vm::{
|
|
|
- Config, EbpfVm, SyscallObject, SyscallRegistry, TestInstructionMeter, VerifiedExecutable,
|
|
|
+ Config, EbpfVm, ProgramResult, SyscallRegistry, TestInstructionMeter, VerifiedExecutable,
|
|
|
},
|
|
|
};
|
|
|
-use solang::compile;
|
|
|
-
|
|
|
-use anchor_syn::idl::Idl;
|
|
|
-use solang::abi::anchor::{discriminator, generate_anchor_idl};
|
|
|
-use solang::{file_resolver::FileResolver, Target};
|
|
|
+use solang::{
|
|
|
+ abi::anchor::{discriminator, generate_anchor_idl},
|
|
|
+ compile,
|
|
|
+ file_resolver::FileResolver,
|
|
|
+ Target,
|
|
|
+};
|
|
|
use std::{
|
|
|
cell::{RefCell, RefMut},
|
|
|
collections::HashMap,
|
|
|
@@ -39,6 +38,20 @@ use tiny_keccak::{Hasher, Keccak};
|
|
|
mod borsh_encoding;
|
|
|
mod solana_tests;
|
|
|
|
|
|
+/// Error handling for syscall methods
|
|
|
+macro_rules! question_mark {
|
|
|
+ ( $value:expr, $result:ident ) => {{
|
|
|
+ let value = $value;
|
|
|
+ match value {
|
|
|
+ Err(err) => {
|
|
|
+ *$result = ProgramResult::Err(err.into());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Ok(value) => value,
|
|
|
+ }
|
|
|
+ }};
|
|
|
+}
|
|
|
+
|
|
|
pub type Account = [u8; 32];
|
|
|
|
|
|
pub fn account_new() -> Account {
|
|
|
@@ -384,7 +397,7 @@ fn update_parameters(
|
|
|
#[derive(Clone)]
|
|
|
struct SyscallContext<'a> {
|
|
|
vm: Rc<RefCell<&'a mut VirtualMachine>>,
|
|
|
- input: &'a [u8],
|
|
|
+ input_len: usize,
|
|
|
refs: Rc<RefCell<&'a mut Vec<AccountRef>>>,
|
|
|
heap: *const u8,
|
|
|
}
|
|
|
@@ -473,14 +486,8 @@ impl<'a> SyscallContext<'a> {
|
|
|
}
|
|
|
|
|
|
struct SolPanic();
|
|
|
-impl SolPanic {
|
|
|
- /// new
|
|
|
- pub fn init<C, E>(_unused: C) -> Box<dyn SyscallObject<UserError>> {
|
|
|
- Box::new(Self {})
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-impl SyscallObject<UserError> for SolPanic {
|
|
|
+impl SolPanic {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
_src: u64,
|
|
|
@@ -489,24 +496,18 @@ impl SyscallObject<UserError> for SolPanic {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
_memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
println!("sol_panic_()");
|
|
|
- *result = Err(EbpfError::ExecutionOverrun(0));
|
|
|
+ *result = ProgramResult::Err(EbpfError::ExecutionOverrun(0));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
struct SolLog<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
-impl<'a> SolLog<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-impl<'a> SyscallObject<UserError> for SolLog<'a> {
|
|
|
+impl<'a> SolLog<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
vm_addr: u64,
|
|
|
@@ -515,11 +516,11 @@ impl<'a> SyscallObject<UserError> for SolLog<'a> {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
self.context.heap_verify();
|
|
|
|
|
|
- let host_addr = question_mark!(memory_mapping.map(AccessType::Load, vm_addr, len), result);
|
|
|
+ let host_addr = memory_mapping.map(AccessType::Load, vm_addr, len).unwrap();
|
|
|
let c_buf: *const c_char = host_addr as *const c_char;
|
|
|
unsafe {
|
|
|
for i in 0..len {
|
|
|
@@ -537,7 +538,7 @@ impl<'a> SyscallObject<UserError> for SolLog<'a> {
|
|
|
if let Ok(mut vm) = self.context.vm.try_borrow_mut() {
|
|
|
vm.logs.push_str(message);
|
|
|
}
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -546,13 +547,6 @@ struct SolLogPubKey<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
impl<'a> SolLogPubKey<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> SyscallObject<UserError> for SolLogPubKey<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
pubkey_addr: u64,
|
|
|
@@ -561,7 +555,7 @@ impl<'a> SyscallObject<UserError> for SolLogPubKey<'a> {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
self.context.heap_verify();
|
|
|
|
|
|
@@ -574,7 +568,7 @@ impl<'a> SyscallObject<UserError> for SolLogPubKey<'a> {
|
|
|
if let Ok(mut vm) = self.context.vm.try_borrow_mut() {
|
|
|
vm.logs.push_str(&message);
|
|
|
}
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -582,13 +576,6 @@ struct SolLogU64<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
impl<'a> SolLogU64<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> SyscallObject<UserError> for SolLogU64<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
arg1: u64,
|
|
|
@@ -597,7 +584,7 @@ impl<'a> SyscallObject<UserError> for SolLogU64<'a> {
|
|
|
arg4: u64,
|
|
|
arg5: u64,
|
|
|
_memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
let message = format!("{arg1:#x}, {arg2:#x}, {arg3:#x}, {arg4:#x}, {arg5:#x}");
|
|
|
|
|
|
@@ -608,7 +595,7 @@ impl<'a> SyscallObject<UserError> for SolLogU64<'a> {
|
|
|
if let Ok(mut vm) = self.context.vm.try_borrow_mut() {
|
|
|
vm.logs.push_str(&message);
|
|
|
}
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -616,13 +603,6 @@ struct SolSha256<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
impl<'a> SolSha256<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> SyscallObject<UserError> for SolSha256<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
src: u64,
|
|
|
@@ -631,7 +611,7 @@ impl<'a> SyscallObject<UserError> for SolSha256<'a> {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
self.context.heap_verify();
|
|
|
|
|
|
@@ -658,7 +638,7 @@ impl<'a> SyscallObject<UserError> for SolSha256<'a> {
|
|
|
|
|
|
println!("sol_sha256: {}", hex::encode(hash));
|
|
|
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -666,13 +646,6 @@ struct SolKeccak256<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
impl<'a> SolKeccak256<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> SyscallObject<UserError> for SolKeccak256<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
src: u64,
|
|
|
@@ -681,7 +654,7 @@ impl<'a> SyscallObject<UserError> for SolKeccak256<'a> {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
self.context.heap_verify();
|
|
|
|
|
|
@@ -708,18 +681,11 @@ impl<'a> SyscallObject<UserError> for SolKeccak256<'a> {
|
|
|
|
|
|
println!("sol_keccak256: {}", hex::encode(hash));
|
|
|
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
struct SolCreateProgramAddress();
|
|
|
impl SolCreateProgramAddress {
|
|
|
- /// new
|
|
|
- pub fn init<C, E>(_unused: C) -> Box<dyn SyscallObject<UserError>> {
|
|
|
- Box::new(Self {})
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl SyscallObject<UserError> for SolCreateProgramAddress {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
seed_ptr: u64,
|
|
|
@@ -728,7 +694,7 @@ impl SyscallObject<UserError> for SolCreateProgramAddress {
|
|
|
dest: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
assert!(seed_len <= 16);
|
|
|
|
|
|
@@ -765,19 +731,12 @@ impl SyscallObject<UserError> for SolCreateProgramAddress {
|
|
|
|
|
|
println!("sol_create_program_address: {}", pda.0.to_base58());
|
|
|
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
struct SolTryFindProgramAddress();
|
|
|
impl SolTryFindProgramAddress {
|
|
|
- /// new
|
|
|
- pub fn init<C, E>(_unused: C) -> Box<dyn SyscallObject<UserError>> {
|
|
|
- Box::new(Self {})
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl SyscallObject<UserError> for SolTryFindProgramAddress {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
seed_ptr: u64,
|
|
|
@@ -786,7 +745,7 @@ impl SyscallObject<UserError> for SolTryFindProgramAddress {
|
|
|
dest: u64,
|
|
|
bump: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
assert!(seed_len <= 16);
|
|
|
|
|
|
@@ -800,7 +759,7 @@ impl SyscallObject<UserError> for SolTryFindProgramAddress {
|
|
|
for (addr, len) in arrays {
|
|
|
assert!(*len < 32);
|
|
|
|
|
|
- let buf = question_mark!(translate_slice::<u8>(memory_mapping, *addr, *len), result);
|
|
|
+ let buf = translate_slice::<u8>(memory_mapping, *addr, *len).unwrap();
|
|
|
|
|
|
println!("seed:{}", hex::encode(buf));
|
|
|
|
|
|
@@ -836,7 +795,7 @@ impl SyscallObject<UserError> for SolTryFindProgramAddress {
|
|
|
bump_seed[0]
|
|
|
);
|
|
|
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -844,13 +803,6 @@ struct SyscallSetReturnData<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
impl<'a> SyscallSetReturnData<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> SyscallObject<UserError> for SyscallSetReturnData<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
addr: u64,
|
|
|
@@ -859,7 +811,7 @@ impl<'a> SyscallObject<UserError> for SyscallSetReturnData<'a> {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
self.context.heap_verify();
|
|
|
|
|
|
@@ -876,7 +828,7 @@ impl<'a> SyscallObject<UserError> for SyscallSetReturnData<'a> {
|
|
|
vm.return_data = Some((vm.stack[0].program, buf.to_vec()));
|
|
|
}
|
|
|
|
|
|
- *result = Ok(0);
|
|
|
+ *result = ProgramResult::Ok(0);
|
|
|
} else {
|
|
|
panic!();
|
|
|
}
|
|
|
@@ -887,13 +839,6 @@ struct SyscallGetReturnData<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
impl<'a> SyscallGetReturnData<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> SyscallObject<UserError> for SyscallGetReturnData<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
addr: u64,
|
|
|
@@ -902,7 +847,7 @@ impl<'a> SyscallObject<UserError> for SyscallGetReturnData<'a> {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
self.context.heap_verify();
|
|
|
|
|
|
@@ -926,9 +871,9 @@ impl<'a> SyscallObject<UserError> for SyscallGetReturnData<'a> {
|
|
|
program_id_result.copy_from_slice(program_id);
|
|
|
}
|
|
|
|
|
|
- *result = Ok(return_data.len() as u64);
|
|
|
+ *result = ProgramResult::Ok(return_data.len() as u64);
|
|
|
} else {
|
|
|
- *result = Ok(0);
|
|
|
+ *result = ProgramResult::Ok(0);
|
|
|
}
|
|
|
} else {
|
|
|
panic!();
|
|
|
@@ -940,13 +885,6 @@ struct SyscallLogData<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
impl<'a> SyscallLogData<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> SyscallObject<UserError> for SyscallLogData<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
addr: u64,
|
|
|
@@ -955,7 +893,7 @@ impl<'a> SyscallObject<UserError> for SyscallLogData<'a> {
|
|
|
_arg4: u64,
|
|
|
_arg5: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
self.context.heap_verify();
|
|
|
|
|
|
@@ -985,7 +923,7 @@ impl<'a> SyscallObject<UserError> for SyscallLogData<'a> {
|
|
|
|
|
|
vm.events.push(events.to_vec());
|
|
|
|
|
|
- *result = Ok(0);
|
|
|
+ *result = ProgramResult::Ok(0);
|
|
|
} else {
|
|
|
panic!();
|
|
|
}
|
|
|
@@ -1088,25 +1026,24 @@ fn translate(
|
|
|
access_type: AccessType,
|
|
|
vm_addr: u64,
|
|
|
len: u64,
|
|
|
-) -> Result<u64, EbpfError<UserError>> {
|
|
|
- memory_mapping.map::<UserError>(access_type, vm_addr, len)
|
|
|
+) -> ProgramResult {
|
|
|
+ memory_mapping.map(access_type, vm_addr, len)
|
|
|
}
|
|
|
|
|
|
fn translate_type_inner<'a, T>(
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
access_type: AccessType,
|
|
|
vm_addr: u64,
|
|
|
-) -> Result<&'a mut T, EbpfError<UserError>> {
|
|
|
+) -> Result<&'a mut T, EbpfError> {
|
|
|
unsafe {
|
|
|
- translate(memory_mapping, access_type, vm_addr, size_of::<T>() as u64)
|
|
|
- .map(|value| &mut *(value as *mut T))
|
|
|
+ match translate(memory_mapping, access_type, vm_addr, size_of::<T>() as u64) {
|
|
|
+ ProgramResult::Ok(value) => Ok(&mut *(value as *mut T)),
|
|
|
+ ProgramResult::Err(e) => Err(e),
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-fn translate_type<'a, T>(
|
|
|
- memory_mapping: &MemoryMapping,
|
|
|
- vm_addr: u64,
|
|
|
-) -> Result<&'a T, EbpfError<UserError>> {
|
|
|
+fn translate_type<'a, T>(memory_mapping: &MemoryMapping, vm_addr: u64) -> Result<&'a T, EbpfError> {
|
|
|
translate_type_inner::<T>(memory_mapping, AccessType::Load, vm_addr).map(|value| &*value)
|
|
|
}
|
|
|
|
|
|
@@ -1114,7 +1051,7 @@ fn translate_slice<'a, T>(
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
vm_addr: u64,
|
|
|
len: u64,
|
|
|
-) -> Result<&'a [T], EbpfError<UserError>> {
|
|
|
+) -> Result<&'a [T], EbpfError> {
|
|
|
translate_slice_inner::<T>(memory_mapping, AccessType::Load, vm_addr, len).map(|value| &*value)
|
|
|
}
|
|
|
|
|
|
@@ -1122,7 +1059,7 @@ fn translate_slice_mut<'a, T>(
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
vm_addr: u64,
|
|
|
len: u64,
|
|
|
-) -> Result<&'a mut [T], EbpfError<UserError>> {
|
|
|
+) -> Result<&'a mut [T], EbpfError> {
|
|
|
translate_slice_inner::<T>(memory_mapping, AccessType::Store, vm_addr, len)
|
|
|
}
|
|
|
|
|
|
@@ -1131,7 +1068,7 @@ fn translate_slice_inner<'a, T>(
|
|
|
access_type: AccessType,
|
|
|
vm_addr: u64,
|
|
|
len: u64,
|
|
|
-) -> Result<&'a mut [T], EbpfError<UserError>> {
|
|
|
+) -> Result<&'a mut [T], EbpfError> {
|
|
|
if len == 0 {
|
|
|
Ok(&mut [])
|
|
|
} else {
|
|
|
@@ -1141,10 +1078,10 @@ fn translate_slice_inner<'a, T>(
|
|
|
vm_addr,
|
|
|
len.saturating_mul(size_of::<T>() as u64),
|
|
|
) {
|
|
|
- Ok(value) => {
|
|
|
+ ProgramResult::Ok(value) => {
|
|
|
Ok(unsafe { std::slice::from_raw_parts_mut(value as *mut T, len as usize) })
|
|
|
}
|
|
|
- Err(e) => Err(e),
|
|
|
+ ProgramResult::Err(e) => Err(e),
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1152,19 +1089,12 @@ fn translate_slice_inner<'a, T>(
|
|
|
struct SyscallInvokeSignedC<'a> {
|
|
|
context: SyscallContext<'a>,
|
|
|
}
|
|
|
-impl<'a> SyscallInvokeSignedC<'a> {
|
|
|
- /// new
|
|
|
- pub fn init(context: SyscallContext<'a>) -> Box<(dyn SyscallObject<UserError> + 'a)> {
|
|
|
- Box::new(Self { context })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
impl<'a> SyscallInvokeSignedC<'a> {
|
|
|
fn translate_instruction(
|
|
|
&self,
|
|
|
addr: u64,
|
|
|
memory_mapping: &MemoryMapping,
|
|
|
- ) -> Result<Instruction, EbpfError<UserError>> {
|
|
|
+ ) -> Result<Instruction, EbpfError> {
|
|
|
let ix_c = translate_type::<SolInstruction>(memory_mapping, addr)?;
|
|
|
|
|
|
let program_id = translate_type::<Pubkey>(memory_mapping, ix_c.program_id_addr)?;
|
|
|
@@ -1185,7 +1115,7 @@ impl<'a> SyscallInvokeSignedC<'a> {
|
|
|
is_writable: meta_c.is_writable,
|
|
|
})
|
|
|
})
|
|
|
- .collect::<Result<Vec<AccountMeta>, EbpfError<UserError>>>()?;
|
|
|
+ .collect::<Result<Vec<AccountMeta>, EbpfError>>()?;
|
|
|
|
|
|
Ok(Instruction {
|
|
|
program_id: program_id.clone(),
|
|
|
@@ -1214,7 +1144,7 @@ fn create_program_address(program_id: &Account, seeds: &[&[u8]]) -> Pubkey {
|
|
|
Pubkey(new_address)
|
|
|
}
|
|
|
|
|
|
-impl<'a> SyscallObject<UserError> for SyscallInvokeSignedC<'a> {
|
|
|
+impl<'a> SyscallInvokeSignedC<'a> {
|
|
|
fn call(
|
|
|
&mut self,
|
|
|
instruction_addr: u64,
|
|
|
@@ -1223,7 +1153,7 @@ impl<'a> SyscallObject<UserError> for SyscallInvokeSignedC<'a> {
|
|
|
signers_seeds_addr: u64,
|
|
|
signers_seeds_len: u64,
|
|
|
memory_mapping: &mut MemoryMapping,
|
|
|
- result: &mut Result<u64, EbpfError<UserError>>,
|
|
|
+ result: &mut ProgramResult,
|
|
|
) {
|
|
|
let instruction = self
|
|
|
.translate_instruction(instruction_addr, memory_mapping)
|
|
|
@@ -1438,26 +1368,29 @@ impl<'a> SyscallObject<UserError> for SyscallInvokeSignedC<'a> {
|
|
|
vm.stack.insert(0, p);
|
|
|
|
|
|
let res = vm.execute(&instruction.accounts, &instruction.data);
|
|
|
- assert_eq!(res, Ok(0));
|
|
|
+ assert_eq!(res.unwrap(), 0);
|
|
|
|
|
|
let refs = self.context.refs.try_borrow_mut().unwrap();
|
|
|
|
|
|
- update_parameters(self.context.input, refs, &vm.account_data);
|
|
|
+ let input = translate_slice_mut::<u8>(
|
|
|
+ memory_mapping,
|
|
|
+ ebpf::MM_INPUT_START,
|
|
|
+ self.context.input_len as u64,
|
|
|
+ )
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ update_parameters(input, refs, &vm.account_data);
|
|
|
|
|
|
vm.stack.remove(0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- *result = Ok(0)
|
|
|
+ *result = ProgramResult::Ok(0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
impl VirtualMachine {
|
|
|
- fn execute(
|
|
|
- &mut self,
|
|
|
- metas: &[AccountMeta],
|
|
|
- calldata: &[u8],
|
|
|
- ) -> Result<u64, EbpfError<UserError>> {
|
|
|
+ fn execute(&mut self, metas: &[AccountMeta], calldata: &[u8]) -> ProgramResult {
|
|
|
println!("running bpf with calldata:{}", hex::encode(calldata));
|
|
|
|
|
|
let (mut parameter_bytes, mut refs) = serialize_parameters(calldata, metas, self);
|
|
|
@@ -1467,112 +1400,89 @@ impl VirtualMachine {
|
|
|
|
|
|
let mut syscall_registry = SyscallRegistry::default();
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(
|
|
|
- b"sol_panic_",
|
|
|
- SolPanic::init::<BpfSyscallContext, UserError>,
|
|
|
- SolPanic::call,
|
|
|
- )
|
|
|
+ .register_syscall_by_name(b"sol_panic_", SolPanic::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(b"sol_log_", SolLog::init, SolLog::call)
|
|
|
+ .register_syscall_by_name(b"sol_log_", SolLog::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(b"sol_log_pubkey", SolLogPubKey::init, SolLogPubKey::call)
|
|
|
+ .register_syscall_by_name(b"sol_log_pubkey", SolLogPubKey::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(b"sol_log_64_", SolLogU64::init, SolLogU64::call)
|
|
|
+ .register_syscall_by_name(b"sol_log_64_", SolLogU64::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(b"sol_sha256", SolSha256::init, SolSha256::call)
|
|
|
+ .register_syscall_by_name(b"sol_sha256", SolSha256::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(b"sol_keccak256", SolKeccak256::init, SolKeccak256::call)
|
|
|
+ .register_syscall_by_name(b"sol_keccak256", SolKeccak256::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(
|
|
|
- b"sol_create_program_address",
|
|
|
- SolCreateProgramAddress::init::<BpfSyscallContext, UserError>,
|
|
|
- SolCreateProgramAddress::call,
|
|
|
- )
|
|
|
+ .register_syscall_by_name(b"sol_create_program_address", SolCreateProgramAddress::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
.register_syscall_by_name(
|
|
|
b"sol_try_find_program_address",
|
|
|
- SolTryFindProgramAddress::init::<BpfSyscallContext, UserError>,
|
|
|
SolTryFindProgramAddress::call,
|
|
|
)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(
|
|
|
- b"sol_invoke_signed_c",
|
|
|
- SyscallInvokeSignedC::init,
|
|
|
- SyscallInvokeSignedC::call,
|
|
|
- )
|
|
|
+ .register_syscall_by_name(b"sol_invoke_signed_c", SyscallInvokeSignedC::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(
|
|
|
- b"sol_set_return_data",
|
|
|
- SyscallSetReturnData::init,
|
|
|
- SyscallSetReturnData::call,
|
|
|
- )
|
|
|
+ .register_syscall_by_name(b"sol_set_return_data", SyscallSetReturnData::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(
|
|
|
- b"sol_get_return_data",
|
|
|
- SyscallGetReturnData::init,
|
|
|
- SyscallGetReturnData::call,
|
|
|
- )
|
|
|
+ .register_syscall_by_name(b"sol_get_return_data", SyscallGetReturnData::call)
|
|
|
.unwrap();
|
|
|
|
|
|
syscall_registry
|
|
|
- .register_syscall_by_name(b"sol_log_data", SyscallLogData::init, SyscallLogData::call)
|
|
|
+ .register_syscall_by_name(b"sol_log_data", SyscallLogData::call)
|
|
|
.unwrap();
|
|
|
|
|
|
// program.program
|
|
|
println!("program: {}", program.program.to_base58());
|
|
|
|
|
|
- let executable = Executable::<UserError, TestInstructionMeter>::from_elf(
|
|
|
+ let executable = Executable::<TestInstructionMeter>::from_elf(
|
|
|
&self.account_data[&program.program].data,
|
|
|
Config::default(),
|
|
|
syscall_registry,
|
|
|
)
|
|
|
.expect("should work");
|
|
|
|
|
|
- let verified_executable = VerifiedExecutable::<
|
|
|
- RequisiteVerifier,
|
|
|
- UserError,
|
|
|
- TestInstructionMeter,
|
|
|
- >::from_executable(executable)
|
|
|
- .unwrap();
|
|
|
+ let verified_executable =
|
|
|
+ VerifiedExecutable::<RequisiteVerifier, TestInstructionMeter>::from_executable(
|
|
|
+ executable,
|
|
|
+ )
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let mut context = SyscallContext {
|
|
|
+ vm: Rc::new(RefCell::new(self)),
|
|
|
+ input_len: parameter_bytes.len(),
|
|
|
+ refs: Rc::new(RefCell::new(&mut refs)),
|
|
|
+ heap: heap.as_ptr(),
|
|
|
+ };
|
|
|
|
|
|
let parameter_region =
|
|
|
MemoryRegion::new_writable(&mut parameter_bytes, ebpf::MM_INPUT_START);
|
|
|
- let mut vm = EbpfVm::<RequisiteVerifier, UserError, TestInstructionMeter>::new(
|
|
|
+ let mut vm = EbpfVm::new(
|
|
|
&verified_executable,
|
|
|
+ &mut context,
|
|
|
&mut heap,
|
|
|
vec![parameter_region],
|
|
|
)
|
|
|
.unwrap();
|
|
|
|
|
|
- let context = SyscallContext {
|
|
|
- vm: Rc::new(RefCell::new(self)),
|
|
|
- input: ¶meter_bytes,
|
|
|
- refs: Rc::new(RefCell::new(&mut refs)),
|
|
|
- heap: heap.as_ptr(),
|
|
|
- };
|
|
|
-
|
|
|
- vm.bind_syscall_context_objects(context).unwrap();
|
|
|
-
|
|
|
let res = vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: 1000000 });
|
|
|
|
|
|
deserialize_parameters(¶meter_bytes, &refs, &mut self.account_data);
|
|
|
@@ -1613,8 +1523,11 @@ impl VirtualMachine {
|
|
|
|
|
|
let res = self.execute(&default_metas, &calldata);
|
|
|
|
|
|
- println!("res:{res:?}");
|
|
|
- assert_eq!(res, Ok(expected));
|
|
|
+ if let ProgramResult::Ok(res) = res {
|
|
|
+ assert_eq!(res, expected);
|
|
|
+ } else {
|
|
|
+ panic!("{res:?}");
|
|
|
+ }
|
|
|
if let Some((_, return_data)) = &self.return_data {
|
|
|
assert_eq!(return_data.len(), 0);
|
|
|
}
|
|
|
@@ -1659,9 +1572,9 @@ impl VirtualMachine {
|
|
|
|
|
|
let res = self.execute(metas, &calldata);
|
|
|
match res {
|
|
|
- Ok(0) => (),
|
|
|
- Ok(error_code) => panic!("unexpected return {error_code:#x}"),
|
|
|
- Err(e) => panic!("error: {e:?}"),
|
|
|
+ ProgramResult::Ok(0) => (),
|
|
|
+ ProgramResult::Ok(error_code) => panic!("unexpected return {error_code:#x}"),
|
|
|
+ ProgramResult::Err(e) => panic!("error: {e:?}"),
|
|
|
};
|
|
|
|
|
|
let return_data = if let Some((_, return_data)) = &self.return_data {
|
|
|
@@ -1686,11 +1599,7 @@ impl VirtualMachine {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn function_must_fail(
|
|
|
- &mut self,
|
|
|
- name: &str,
|
|
|
- args: &[BorshToken],
|
|
|
- ) -> Result<u64, EbpfError<UserError>> {
|
|
|
+ fn function_must_fail(&mut self, name: &str, args: &[BorshToken]) -> ProgramResult {
|
|
|
let program = &self.stack[0];
|
|
|
|
|
|
println!("function for {}", hex::encode(program.data));
|