From f1e034b9be8eaa05720872441ed104c8e9f8ee68 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Tue, 2 Jul 2024 15:23:33 -0700 Subject: [PATCH 01/14] Minor cleanup Give the host functions better names --- interface/src/lib.rs | 3 +++ tests/host/src/main.rs | 10 ++++------ vm/entrypoint/src/syscalls/host.rs | 13 ++++--------- vm/hostfunctions/src/lib.rs | 4 ++-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/interface/src/lib.rs b/interface/src/lib.rs index 541b4378..fa25407c 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -121,6 +121,9 @@ pub struct AthenaMessage { pub sender: Address, pub input_data: Option>, pub value: Balance, + // code is currently unused, and it seems redundant. + // it's not in the yellow paper. + // TODO: remove me? pub code: Vec, } diff --git a/tests/host/src/main.rs b/tests/host/src/main.rs index c95f4cbb..93973b5b 100644 --- a/tests/host/src/main.rs +++ b/tests/host/src/main.rs @@ -14,13 +14,11 @@ pub fn main() { let value = [16843009u32; 8]; // result will be written to key, overwriting input value - unsafe { - athena_vm::host::host_write_storage(key.as_mut_ptr(), address.as_ptr(), value.as_ptr()) - }; - assert_eq!(key, [0u32; 8], "host_write_storage failed"); + unsafe { athena_vm::host::write_storage(key.as_mut_ptr(), address.as_ptr(), value.as_ptr()) }; + assert_eq!(key, [0u32; 8], "write_storage failed"); // result will be written to key, overwriting input value - unsafe { athena_vm::host::host_read_storage(key2.as_mut_ptr(), address.as_ptr()) }; - assert_eq!(value, key2, "host_read_storage failed"); + unsafe { athena_vm::host::read_storage(key2.as_mut_ptr(), address.as_ptr()) }; + assert_eq!(value, key2, "read_storage failed"); println!("success"); } diff --git a/vm/entrypoint/src/syscalls/host.rs b/vm/entrypoint/src/syscalls/host.rs index dd8c3f2d..adbd1d30 100644 --- a/vm/entrypoint/src/syscalls/host.rs +++ b/vm/entrypoint/src/syscalls/host.rs @@ -1,17 +1,12 @@ -// use athena_interface::{Address, Bytes32}; - -cfg_if::cfg_if! { - if #[cfg(target_os = "zkvm")] { - use core::arch::asm; - } -} +#[cfg(target_os = "zkvm")] +use core::arch::asm; /// Read from host storage at the given address and key. /// /// The output is stored in the `key` pointer. #[allow(unused_variables)] #[no_mangle] -pub extern "C" fn host_read_storage(key: *mut u32, address: *const u32) { +pub extern "C" fn read_storage(key: *mut u32, address: *const u32) { #[cfg(target_os = "zkvm")] unsafe { asm!( @@ -31,7 +26,7 @@ pub extern "C" fn host_read_storage(key: *mut u32, address: *const u32) { /// The result status code is stored in the `key` pointer. #[allow(unused_variables)] #[no_mangle] -pub extern "C" fn host_write_storage(key: *mut u32, address: *const u32, value: *const u32) { +pub extern "C" fn write_storage(key: *mut u32, address: *const u32, value: *const u32) { #[cfg(target_os = "zkvm")] unsafe { asm!( diff --git a/vm/hostfunctions/src/lib.rs b/vm/hostfunctions/src/lib.rs index 20f825da..e348bab6 100644 --- a/vm/hostfunctions/src/lib.rs +++ b/vm/hostfunctions/src/lib.rs @@ -1,4 +1,4 @@ extern "C" { - pub fn host_read_storage(key: *mut u32, address: *const u32); - pub fn host_write_storage(key: *mut u32, address: *const u32, value: *const u32); + pub fn read_storage(key: *mut u32, address: *const u32); + pub fn write_storage(key: *mut u32, address: *const u32, value: *const u32); } From 752a6ed16fa3dac92d151355c58144ce60d7cef9 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Tue, 2 Jul 2024 17:47:27 -0700 Subject: [PATCH 02/14] Checkpoint: implementing call host function Added basic host function definition Working on runtime syscall implementation Added new athena context struct --- core/src/runtime/mod.rs | 9 +++- core/src/runtime/syscall.rs | 4 ++ core/src/syscall/host.rs | 66 +++++++++++++++++++++++++++++- interface/src/context.rs | 37 +++++++++++++++++ interface/src/lib.rs | 8 +++- vm/entrypoint/src/syscalls/host.rs | 26 ++++++++++++ vm/entrypoint/src/syscalls/mod.rs | 1 + vm/hostfunctions/src/lib.rs | 1 + 8 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 interface/src/context.rs diff --git a/core/src/runtime/mod.rs b/core/src/runtime/mod.rs index 8444ad63..c7a43205 100644 --- a/core/src/runtime/mod.rs +++ b/core/src/runtime/mod.rs @@ -30,7 +30,7 @@ use thiserror::Error; use crate::utils::AthenaCoreOpts; -use athena_interface::{HostInterface, HostProvider}; +use athena_interface::{AthenaContext, HostInterface, HostProvider}; /// An implementation of a runtime for the Athena RISC-V VM. /// @@ -43,6 +43,9 @@ pub struct Runtime { /// The program. pub program: Arc, + /// Runtime context. + pub context: Option, + /// The state of the execution. pub state: ExecutionState, @@ -99,6 +102,7 @@ where program: Program, host: Option>>>, opts: AthenaCoreOpts, + context: Option, ) -> Self { // Create a shared reference to the program and host. let program = Arc::new(program); @@ -120,6 +124,7 @@ where .unwrap_or(0); Self { + context, state: ExecutionState::new(program.pc_start), program, host, @@ -714,7 +719,7 @@ where ) } - fn gas_left(&self) -> Option { + pub(crate) fn gas_left(&self) -> Option { // gas left can be negative, if we spent too much on the last instruction return self .max_gas diff --git a/core/src/runtime/syscall.rs b/core/src/runtime/syscall.rs index 783b93df..59878576 100644 --- a/core/src/runtime/syscall.rs +++ b/core/src/runtime/syscall.rs @@ -29,6 +29,7 @@ pub enum SyscallCode { /// Host functions HOST_READ = 0x00_00_00_A0, HOST_WRITE = 0x00_00_00_A1, + HOST_CALL = 0x00_00_00_A2, /// Executes the `HINT_LEN` precompile. HINT_LEN = 0x00_00_00_F0, @@ -45,6 +46,7 @@ impl SyscallCode { 0x00_00_00_02 => SyscallCode::WRITE, 0x00_00_00_A0 => SyscallCode::HOST_READ, 0x00_00_00_A1 => SyscallCode::HOST_WRITE, + 0x00_00_00_A2 => SyscallCode::HOST_CALL, 0x00_00_00_F0 => SyscallCode::HINT_LEN, 0x00_00_00_F1 => SyscallCode::HINT_READ, _ => panic!("invalid syscall number: {}", value), @@ -169,6 +171,7 @@ pub fn default_syscall_map() -> HashMap assert_eq!(code as u32, athena_vm::syscalls::WRITE), SyscallCode::HOST_READ => assert_eq!(code as u32, athena_vm::syscalls::HOST_READ), SyscallCode::HOST_WRITE => assert_eq!(code as u32, athena_vm::syscalls::HOST_WRITE), + SyscallCode::HOST_CALL => assert_eq!(code as u32, athena_vm::syscalls::HOST_CALL), SyscallCode::HINT_LEN => assert_eq!(code as u32, athena_vm::syscalls::HINT_LEN), SyscallCode::HINT_READ => assert_eq!(code as u32, athena_vm::syscalls::HINT_READ), } diff --git a/core/src/syscall/host.rs b/core/src/syscall/host.rs index ead62c37..31733a3a 100644 --- a/core/src/syscall/host.rs +++ b/core/src/syscall/host.rs @@ -1,6 +1,7 @@ use crate::runtime::{Register, Syscall, SyscallContext}; use athena_interface::{ - AddressWrapper, Bytes32Wrapper, HostInterface, ADDRESS_LENGTH, BYTES32_LENGTH, + AddressWrapper, AthenaMessage, Bytes32Wrapper, HostInterface, MessageKind, ADDRESS_LENGTH, + BYTES32_LENGTH, }; pub struct SyscallHostRead; @@ -74,3 +75,66 @@ where None } } + +pub struct SyscallHostCall; + +impl SyscallHostCall { + pub const fn new() -> Self { + Self + } +} + +impl Syscall for SyscallHostCall +where + T: HostInterface, +{ + fn execute(&self, ctx: &mut SyscallContext, arg1: u32, arg2: u32) -> Option { + // make sure we have a runtime context + let athena_ctx = ctx + .rt + .context + .as_ref() + .expect("Missing Athena runtime context"); + let host = ctx.rt.host.as_mut().expect("Missing host interface"); + + // get remaining gas + // note: this does not factor in the cost of the current instruction + let gas_left = ctx.rt.gas_left().expect("Missing gas information"); + + // note: the host is responsible for checking stack depth, not us + + // marshal inputs + let address_words = ADDRESS_LENGTH / 4; + let address = ctx.slice_unsafe(arg1, address_words); + let address = AddressWrapper::from(address); + + // we need to read the input length from the next register + let a2 = Register::X12; + let rt = &mut ctx.rt; + let len = rt.register(a2) as usize; + // let len = ctx.word_unsafe(len_ptr); + + // `len` is denominated in number of bytes; we read words in chunks of four bytes + let input = ctx.slice_unsafe(arg2, len / 4); + + // construct the outbound message + let msg = AthenaMessage::new( + MessageKind::Call, + athena_ctx.depth() + 1, + u32::try_from(gas_left).expect("Invalid gas left"), + address.into(), + athena_ctx.address().clone(), + None, + 0, + Vec::new(), + ); + let result = host.borrow_mut().call(msg); + + // save return code + let mut status_word = [0u32; 8]; + status_word[0] = result.status_code as u32; + ctx.mw_slice(arg1, &status_word); + + None + } +} diff --git a/interface/src/context.rs b/interface/src/context.rs new file mode 100644 index 00000000..6a5e7da1 --- /dev/null +++ b/interface/src/context.rs @@ -0,0 +1,37 @@ +/// The runtime context struct stores information received as part of the inbound +/// execution message that's guaranteed not to change during the context of the +/// program execution. +use crate::Address; +pub struct AthenaContext { + address: Address, + caller: Address, + depth: u32, + max_depth: u32, +} + +impl AthenaContext { + pub fn new(address: Address, caller: Address, depth: u32, max_depth: u32) -> Self { + AthenaContext { + address, + caller, + depth, + max_depth, + } + } + + pub fn address(&self) -> &Address { + &self.address + } + + pub fn caller(&self) -> &Address { + &self.caller + } + + pub fn depth(&self) -> u32 { + self.depth + } + + pub fn max_depth(&self) -> u32 { + self.max_depth + } +} diff --git a/interface/src/lib.rs b/interface/src/lib.rs index fa25407c..91749912 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -2,6 +2,9 @@ //! //! A library with no external dependencies that includes core types and traits. +mod context; +pub use context::*; + use std::{ fmt, ops::{Deref, DerefMut}, @@ -115,7 +118,7 @@ pub enum MessageKind { #[derive(Debug, Clone, PartialEq)] pub struct AthenaMessage { pub kind: MessageKind, - pub depth: i32, + pub depth: u32, pub gas: u32, pub recipient: Address, pub sender: Address, @@ -130,7 +133,7 @@ pub struct AthenaMessage { impl AthenaMessage { pub fn new( kind: MessageKind, - depth: i32, + depth: u32, gas: u32, recipient: Address, sender: Address, @@ -152,6 +155,7 @@ impl AthenaMessage { } #[derive(Debug, Clone, Copy, PartialEq)] +#[repr(u32)] pub enum StatusCode { Success, Failure, diff --git a/vm/entrypoint/src/syscalls/host.rs b/vm/entrypoint/src/syscalls/host.rs index adbd1d30..c779dc69 100644 --- a/vm/entrypoint/src/syscalls/host.rs +++ b/vm/entrypoint/src/syscalls/host.rs @@ -1,6 +1,32 @@ #[cfg(target_os = "zkvm")] use core::arch::asm; +/// Call a function in a foreign program. +/// +/// `address` is the callee address, `input` is a bytearray to be passed to the +/// callee function, and `len` is the number of bytes to read from the input bytearray. +/// For now there is no return value and no return status code. The caller can assume +/// that, if this function returns, the call was successful. +/// +/// See https://github.com/athenavm/athena/issues/5 for more information. +#[allow(unused_variables)] +#[no_mangle] +pub extern "C" fn call(address: *const u32, input: *const u32, len: usize) { + #[cfg(target_os = "zkvm")] + unsafe { + asm!( + "ecall", + in("t0") crate::syscalls::HOST_CALL, + in("a0") address, + in("a1") input, + in("a2") len, + ) + } + + #[cfg(not(target_os = "zkvm"))] + unreachable!() +} + /// Read from host storage at the given address and key. /// /// The output is stored in the `key` pointer. diff --git a/vm/entrypoint/src/syscalls/mod.rs b/vm/entrypoint/src/syscalls/mod.rs index f77b5daf..6147ee12 100644 --- a/vm/entrypoint/src/syscalls/mod.rs +++ b/vm/entrypoint/src/syscalls/mod.rs @@ -28,3 +28,4 @@ pub const HINT_READ: u32 = 0x00_00_00_F1; /// Host functions pub const HOST_READ: u32 = 0x00_00_00_A0; pub const HOST_WRITE: u32 = 0x00_00_00_A1; +pub const HOST_CALL: u32 = 0x00_00_00_A2; diff --git a/vm/hostfunctions/src/lib.rs b/vm/hostfunctions/src/lib.rs index e348bab6..c07a1ab7 100644 --- a/vm/hostfunctions/src/lib.rs +++ b/vm/hostfunctions/src/lib.rs @@ -1,4 +1,5 @@ extern "C" { + pub fn call(address: *const u32, input: *const u32, len: usize); pub fn read_storage(key: *mut u32, address: *const u32); pub fn write_storage(key: *mut u32, address: *const u32, value: *const u32); } From c769b9930bda26731205b01f169e224ebb60ec58 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Wed, 3 Jul 2024 18:20:44 -0700 Subject: [PATCH 03/14] Checkpoint: adding host call syscall Error handling, cleaning up some minor issues --- core/src/runtime/io.rs | 2 +- core/src/runtime/mod.rs | 67 ++++++++++++++++++++++--------------- core/src/runtime/syscall.rs | 3 +- core/src/syscall/host.rs | 17 ++++++---- interface/src/context.rs | 8 +---- interface/src/lib.rs | 27 +++++++++++++++ runner/src/vm.rs | 9 +++-- sdk/src/lib.rs | 19 +++++++---- 8 files changed, 101 insertions(+), 51 deletions(-) diff --git a/core/src/runtime/io.rs b/core/src/runtime/io.rs index e652391e..9add2cd5 100644 --- a/core/src/runtime/io.rs +++ b/core/src/runtime/io.rs @@ -85,7 +85,7 @@ pub mod tests { fn test_io_run() { setup_logger(); let program = Program::from(IO_ELF); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); let points = points(); runtime.write_stdin(&points.0); runtime.write_stdin(&points.1); diff --git a/core/src/runtime/mod.rs b/core/src/runtime/mod.rs index c7a43205..820a5f92 100644 --- a/core/src/runtime/mod.rs +++ b/core/src/runtime/mod.rs @@ -30,7 +30,7 @@ use thiserror::Error; use crate::utils::AthenaCoreOpts; -use athena_interface::{AthenaContext, HostInterface, HostProvider}; +use athena_interface::{AthenaContext, HostInterface, HostProvider, StatusCode}; /// An implementation of a runtime for the Athena RISC-V VM. /// @@ -81,6 +81,8 @@ pub struct Runtime { pub enum ExecutionError { #[error("execution failed with exit code {0}")] HaltWithNonZeroExitCode(u32), + #[error("host call failed with status code {0}")] + HostCallFailed(StatusCode), #[error("invalid memory access for opcode {0} and address {1}")] InvalidMemoryAccess(Opcode, u32), #[error("unimplemented syscall {0}")] @@ -141,7 +143,7 @@ where /// Recover runtime state from a program and existing execution state. pub fn recover(program: Program, state: ExecutionState, opts: AthenaCoreOpts) -> Self { - let mut runtime = Self::new(program, None, opts); + let mut runtime = Self::new(program, None, opts, None); runtime.state = state; runtime } @@ -592,6 +594,13 @@ where a = syscall_id; } + // Check for failure from the call host function. + if syscall == SyscallCode::HOST_CALL { + let return_code = res.unwrap(); + let status_code = StatusCode::try_from(return_code).unwrap(); + return Err(ExecutionError::HostCallFailed(status_code)); + } + // If the syscall is `HALT` and the exit code is non-zero, return an error. if syscall == SyscallCode::HALT && precompile_rt.exit_code != 0 { return Err(ExecutionError::HaltWithNonZeroExitCode( @@ -846,7 +855,7 @@ pub mod tests { #[test] fn test_simple_program_run() { let program = simple_program(); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 42); } @@ -855,7 +864,7 @@ pub mod tests { #[should_panic] fn test_panic() { let program = panic_program(); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); } @@ -869,6 +878,7 @@ pub mod tests { program, Some(Arc::new(RefCell::new(provider))), AthenaCoreOpts::default(), + None, ); let gas_left = runtime.execute().unwrap(); assert_eq!(gas_left, None); @@ -888,6 +898,7 @@ pub mod tests { program.clone(), Some(provider.clone()), AthenaCoreOpts::default().with_options(vec![with_max_gas(4331)]), + None, ); assert!(matches!(runtime.execute(), Err(ExecutionError::OutOfGas()))); @@ -897,6 +908,7 @@ pub mod tests { Some(provider.clone()), // program should cost 4332 gas units AthenaCoreOpts::default().with_options(vec![with_max_gas(4332)]), + None, ); let gas_left = runtime.execute().unwrap(); assert_eq!(gas_left, Some(0)); @@ -907,6 +919,7 @@ pub mod tests { Some(provider.clone()), // program should cost 4332 gas units AthenaCoreOpts::default().with_options(vec![with_max_gas(4333)]), + None, ); let gas_left = runtime.execute().unwrap(); assert_eq!(gas_left, Some(1)); @@ -924,7 +937,7 @@ pub mod tests { Instruction::new(Opcode::ADD, 31, 30, 29, false, false), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 42); } @@ -941,7 +954,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 32); } @@ -958,7 +971,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 32); } @@ -975,7 +988,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 37); @@ -993,7 +1006,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 5); } @@ -1010,7 +1023,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 1184); } @@ -1027,7 +1040,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 1); } @@ -1044,7 +1057,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 1); } @@ -1061,7 +1074,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 0); } @@ -1078,7 +1091,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 0); } @@ -1095,7 +1108,7 @@ pub mod tests { ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 84); } @@ -1111,7 +1124,7 @@ pub mod tests { Instruction::new(Opcode::ADD, 31, 30, 4, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 5 - 1 + 4); } @@ -1127,7 +1140,7 @@ pub mod tests { Instruction::new(Opcode::XOR, 31, 30, 42, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 10); } @@ -1143,7 +1156,7 @@ pub mod tests { Instruction::new(Opcode::OR, 31, 30, 42, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 47); } @@ -1159,7 +1172,7 @@ pub mod tests { Instruction::new(Opcode::AND, 31, 30, 42, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 0); } @@ -1173,7 +1186,7 @@ pub mod tests { Instruction::new(Opcode::SLL, 31, 29, 4, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 80); } @@ -1187,7 +1200,7 @@ pub mod tests { Instruction::new(Opcode::SRL, 31, 29, 4, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 2); } @@ -1201,7 +1214,7 @@ pub mod tests { Instruction::new(Opcode::SRA, 31, 29, 4, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 2); } @@ -1215,7 +1228,7 @@ pub mod tests { Instruction::new(Opcode::SLT, 31, 29, 37, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 0); } @@ -1229,7 +1242,7 @@ pub mod tests { Instruction::new(Opcode::SLTU, 31, 29, 37, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.register(Register::X31), 0); } @@ -1248,7 +1261,7 @@ pub mod tests { Instruction::new(Opcode::JALR, 5, 11, 8, false, true), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.registers()[Register::X5 as usize], 8); assert_eq!(runtime.registers()[Register::X11 as usize], 100); @@ -1262,7 +1275,7 @@ pub mod tests { Instruction::new(opcode, 12, 10, 11, false, false), ]; let program = Program::new(instructions, 0, 0); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); assert_eq!(runtime.registers()[Register::X12 as usize], expected); } @@ -1480,7 +1493,7 @@ pub mod tests { #[test] fn test_simple_memory_program_run() { let program = simple_memory_program(); - let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default()); + let mut runtime = Runtime::::new(program, None, AthenaCoreOpts::default(), None); runtime.execute().unwrap(); // Assert SW & LW case diff --git a/core/src/runtime/syscall.rs b/core/src/runtime/syscall.rs index 59878576..e470924c 100644 --- a/core/src/runtime/syscall.rs +++ b/core/src/runtime/syscall.rs @@ -5,7 +5,8 @@ use strum_macros::EnumIter; use crate::runtime::{Register, Runtime}; use crate::syscall::{ - SyscallHalt, SyscallHintLen, SyscallHintRead, SyscallHostRead, SyscallHostWrite, SyscallWrite, + SyscallHalt, SyscallHintLen, SyscallHintRead, SyscallHostCall, SyscallHostRead, SyscallHostWrite, + SyscallWrite, }; use crate::{runtime::MemoryReadRecord, runtime::MemoryWriteRecord}; diff --git a/core/src/syscall/host.rs b/core/src/syscall/host.rs index 31733a3a..8c9c9263 100644 --- a/core/src/syscall/host.rs +++ b/core/src/syscall/host.rs @@ -1,3 +1,5 @@ +use std::borrow::BorrowMut; + use crate::runtime::{Register, Syscall, SyscallContext}; use athena_interface::{ AddressWrapper, AthenaMessage, Bytes32Wrapper, HostInterface, MessageKind, ADDRESS_LENGTH, @@ -95,7 +97,12 @@ where .context .as_ref() .expect("Missing Athena runtime context"); - let host = ctx.rt.host.as_mut().expect("Missing host interface"); + let host = ctx + .rt + .host + .as_ref() + .expect("Missing host interface") + .borrow_mut(); // get remaining gas // note: this does not factor in the cost of the current instruction @@ -128,13 +135,9 @@ where 0, Vec::new(), ); - let result = host.borrow_mut().call(msg); - - // save return code - let mut status_word = [0u32; 8]; - status_word[0] = result.status_code as u32; - ctx.mw_slice(arg1, &status_word); + let result = host.call(msg); + // no return value None } } diff --git a/interface/src/context.rs b/interface/src/context.rs index 6a5e7da1..0fc9986b 100644 --- a/interface/src/context.rs +++ b/interface/src/context.rs @@ -6,16 +6,14 @@ pub struct AthenaContext { address: Address, caller: Address, depth: u32, - max_depth: u32, } impl AthenaContext { - pub fn new(address: Address, caller: Address, depth: u32, max_depth: u32) -> Self { + pub fn new(address: Address, caller: Address, depth: u32) -> Self { AthenaContext { address, caller, depth, - max_depth, } } @@ -30,8 +28,4 @@ impl AthenaContext { pub fn depth(&self) -> u32 { self.depth } - - pub fn max_depth(&self) -> u32 { - self.max_depth - } } diff --git a/interface/src/lib.rs b/interface/src/lib.rs index 91749912..381e5e45 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -6,6 +6,7 @@ mod context; pub use context::*; use std::{ + convert::TryFrom, fmt, ops::{Deref, DerefMut}, }; @@ -173,6 +174,32 @@ pub enum StatusCode { OutOfMemory, } +impl TryFrom for StatusCode { + type Error = &'static str; + + fn try_from(value: u32) -> Result { + match value { + x if x == StatusCode::Success as u32 => Ok(StatusCode::Success), + x if x == StatusCode::Failure as u32 => Ok(StatusCode::Failure), + x if x == StatusCode::Revert as u32 => Ok(StatusCode::Revert), + x if x == StatusCode::OutOfGas as u32 => Ok(StatusCode::OutOfGas), + x if x == StatusCode::UndefinedInstruction as u32 => Ok(StatusCode::UndefinedInstruction), + x if x == StatusCode::InvalidMemoryAccess as u32 => Ok(StatusCode::InvalidMemoryAccess), + x if x == StatusCode::CallDepthExceeded as u32 => Ok(StatusCode::CallDepthExceeded), + x if x == StatusCode::PrecompileFailure as u32 => Ok(StatusCode::PrecompileFailure), + x if x == StatusCode::ContractValidationFailure as u32 => { + Ok(StatusCode::ContractValidationFailure) + } + x if x == StatusCode::ArgumentOutOfRange as u32 => Ok(StatusCode::ArgumentOutOfRange), + x if x == StatusCode::InsufficientBalance as u32 => Ok(StatusCode::InsufficientBalance), + x if x == StatusCode::InternalError as u32 => Ok(StatusCode::InternalError), + x if x == StatusCode::Rejected as u32 => Ok(StatusCode::Rejected), + x if x == StatusCode::OutOfMemory as u32 => Ok(StatusCode::OutOfMemory), + _ => Err("Invalid StatusCode"), + } + } +} + impl fmt::Display for StatusCode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/runner/src/vm.rs b/runner/src/vm.rs index 4eaff0fa..30fd3e34 100644 --- a/runner/src/vm.rs +++ b/runner/src/vm.rs @@ -1,7 +1,9 @@ use std::{cell::RefCell, sync::Arc}; use crate::host::{AthenaCapability, AthenaOption, SetOptionError}; -use athena_interface::{AthenaMessage, ExecutionResult, HostInterface, HostProvider, StatusCode}; +use athena_interface::{ + AthenaContext, AthenaMessage, ExecutionResult, HostInterface, HostProvider, StatusCode, +}; use athena_sdk::{AthenaStdin, ExecutionClient}; pub trait VmInterface { @@ -48,6 +50,9 @@ where // note: ignore _msg.code, should only be used on deploy code: &[u8], ) -> ExecutionResult { + // construct context object + let context = AthenaContext::new(msg.recipient, msg.sender, msg.depth); + let mut stdin = AthenaStdin::new(); // input data is optional @@ -57,7 +62,7 @@ where let (output, gas_left) = self .client - .execute(&code, stdin, Some(host), Some(msg.gas)) + .execute(&code, stdin, Some(host), Some(msg.gas), Some(context)) .unwrap(); ExecutionResult::new( StatusCode::Success, diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index bc07a142..47ea6ce0 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -16,7 +16,7 @@ use anyhow::{Ok, Result}; pub use athena_core::io::{AthenaPublicValues, AthenaStdin}; use athena_core::runtime::{Program, Runtime}; use athena_core::utils::AthenaCoreOpts; -use athena_interface::{HostInterface, HostProvider}; +use athena_interface::{AthenaContext, HostInterface, HostProvider}; /// A client for interacting with Athena. pub struct ExecutionClient; @@ -64,6 +64,7 @@ impl ExecutionClient { stdin: AthenaStdin, host: Option>>>, max_gas: Option, + context: Option, ) -> Result<(AthenaPublicValues, Option)> { let program = Program::from(elf); let opts = match max_gas { @@ -72,7 +73,7 @@ impl ExecutionClient { AthenaCoreOpts::default().with_options(vec![athena_core::utils::with_max_gas(max_gas)]) } }; - let mut runtime = Runtime::new(program, host, opts); + let mut runtime = Runtime::new(program, host, opts, context); runtime.write_vecs(&stdin.buffer); let gas_left = runtime.execute().unwrap(); Ok(( @@ -102,7 +103,9 @@ mod tests { let elf = include_bytes!("../../examples/fibonacci/program/elf/fibonacci-program"); let mut stdin = AthenaStdin::new(); stdin.write(&10usize); - client.execute::(elf, stdin, None, None).unwrap(); + client + .execute::(elf, stdin, None, None, None) + .unwrap(); } #[test] @@ -113,7 +116,7 @@ mod tests { let stdin = AthenaStdin::new(); let host = Arc::new(RefCell::new(HostProvider::new(MockHost::new()))); client - .execute::(elf, stdin, Some(host), None) + .execute::(elf, stdin, Some(host), None, None) .unwrap(); } @@ -124,7 +127,9 @@ mod tests { let client = ExecutionClient::new(); let elf = include_bytes!("../../tests/host/elf/host-test"); let stdin = AthenaStdin::new(); - client.execute::(elf, stdin, None, None).unwrap(); + client + .execute::(elf, stdin, None, None, None) + .unwrap(); } #[test] @@ -135,6 +140,8 @@ mod tests { let elf = include_bytes!("../../tests/panic/elf/panic-test"); let mut stdin = AthenaStdin::new(); stdin.write(&10usize); - client.execute::(elf, stdin, None, None).unwrap(); + client + .execute::(elf, stdin, None, None, None) + .unwrap(); } } From bf587defaa1e0816ab3d4417ab85a4382280f086 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Thu, 4 Jul 2024 16:38:31 -0500 Subject: [PATCH 04/14] Set return value --- core/src/syscall/host.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/syscall/host.rs b/core/src/syscall/host.rs index 8c9c9263..3718f602 100644 --- a/core/src/syscall/host.rs +++ b/core/src/syscall/host.rs @@ -135,9 +135,6 @@ where 0, Vec::new(), ); - let result = host.call(msg); - - // no return value - None + Some(host.call(msg) as u32) } } From e88dc95369b9c8a1e871104271ab026e0d0ac6c3 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Thu, 18 Jul 2024 11:13:20 -0700 Subject: [PATCH 05/14] Bugfix --- core/src/syscall/host.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/src/syscall/host.rs b/core/src/syscall/host.rs index 3718f602..5584ae84 100644 --- a/core/src/syscall/host.rs +++ b/core/src/syscall/host.rs @@ -1,5 +1,3 @@ -use std::borrow::BorrowMut; - use crate::runtime::{Register, Syscall, SyscallContext}; use athena_interface::{ AddressWrapper, AthenaMessage, Bytes32Wrapper, HostInterface, MessageKind, ADDRESS_LENGTH, @@ -97,7 +95,7 @@ where .context .as_ref() .expect("Missing Athena runtime context"); - let host = ctx + let mut host = ctx .rt .host .as_ref() @@ -135,6 +133,12 @@ where 0, Vec::new(), ); - Some(host.call(msg) as u32) + let res = host.call(msg); + + // calculate gas spent + let gas_spent = gas_left - res.gas_left; + rt.state.clk += gas_spent; + + Some(res.status_code as u32) } } From b643d620a5339f5e46079fc23236b14449c17b22 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Thu, 18 Jul 2024 11:44:56 -0700 Subject: [PATCH 06/14] Fix tests --- cli/src/commands/execute.rs | 4 +++- core/Cargo.toml | 1 - core/src/syscall/host.rs | 37 +++++++++++++++++++++++++++++-------- ffi/vmlib/src/lib.rs | 6 +++--- sdk/src/lib.rs | 2 +- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/cli/src/commands/execute.rs b/cli/src/commands/execute.rs index 615cc778..805741d7 100644 --- a/cli/src/commands/execute.rs +++ b/cli/src/commands/execute.rs @@ -113,7 +113,9 @@ impl ExecuteCmd { let start_time = Instant::now(); let client = ExecutionClient::new(); // no host interface needed for direct execution - let (output, _gas_left) = client.execute::(&elf, stdin, None, None).unwrap(); + let (output, _gas_left) = client + .execute::(&elf, stdin, None, None, None) + .unwrap(); let elapsed = elapsed(start_time.elapsed()); let green = AnsiColor::Green.on_default().effects(Effects::BOLD); diff --git a/core/Cargo.toml b/core/Cargo.toml index fee449e8..ecd6b612 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -15,7 +15,6 @@ elf = "0.7.4" log = "0.4.21" nohash-hasher = "0.2.0" rrs-lib = { git = "https://github.com/GregAC/rrs.git" } - cfg-if = "1.0.0" hex = "0.4.3" serde_with = "3.8.1" diff --git a/core/src/syscall/host.rs b/core/src/syscall/host.rs index 5584ae84..9c57e384 100644 --- a/core/src/syscall/host.rs +++ b/core/src/syscall/host.rs @@ -104,7 +104,12 @@ where // get remaining gas // note: this does not factor in the cost of the current instruction - let gas_left = ctx.rt.gas_left().expect("Missing gas information"); + let gas_left: u32 = ctx + .rt + .gas_left() + .expect("Missing gas information") + .try_into() + .expect("gas arithmetic error"); // note: the host is responsible for checking stack depth, not us @@ -115,12 +120,24 @@ where // we need to read the input length from the next register let a2 = Register::X12; - let rt = &mut ctx.rt; - let len = rt.register(a2) as usize; - // let len = ctx.word_unsafe(len_ptr); + let len = ctx.rt.register(a2) as usize; + + // check byte alignment + assert!(len % 4 == 0, "input is not byte-aligned"); // `len` is denominated in number of bytes; we read words in chunks of four bytes - let input = ctx.slice_unsafe(arg2, len / 4); + // then convert into a standard bytearray. + let input = if len > 0 { + let input_slice = ctx.slice_unsafe(arg2, len / 4); + Some( + input_slice + .iter() + .flat_map(|&num| num.to_le_bytes().to_vec()) + .collect(), + ) + } else { + None + }; // construct the outbound message let msg = AthenaMessage::new( @@ -129,15 +146,19 @@ where u32::try_from(gas_left).expect("Invalid gas left"), address.into(), athena_ctx.address().clone(), - None, + input, 0, Vec::new(), ); let res = host.call(msg); // calculate gas spent - let gas_spent = gas_left - res.gas_left; - rt.state.clk += gas_spent; + // TODO: should this be a panic or should it just return an out of gas error? + // for now, it's a panic, since this should not happen. + let gas_spent = gas_left + .checked_sub(res.gas_left) + .expect("host call spent more than available gas"); + ctx.rt.state.clk += gas_spent; Some(res.status_code as u32) } diff --git a/ffi/vmlib/src/lib.rs b/ffi/vmlib/src/lib.rs index 5cd2a2ec..36800d30 100644 --- a/ffi/vmlib/src/lib.rs +++ b/ffi/vmlib/src/lib.rs @@ -143,7 +143,7 @@ impl From for AthenaMessageWrapper { let byteswrapper: Bytes32Wrapper = item.value.into(); AthenaMessageWrapper(AthenaMessage { kind: kind.0, - depth: item.depth, + depth: u32::try_from(item.depth).expect("Depth value out of range"), gas: u32::try_from(item.gas).expect("Gas value out of range"), recipient: AddressWrapper::from(item.recipient).into(), sender: AddressWrapper::from(item.sender).into(), @@ -169,7 +169,7 @@ impl From for ffi::athcon_message { let value: Bytes32AsU64 = item.0.value.into(); ffi::athcon_message { kind, - depth: item.0.depth, + depth: item.0.depth as i32, gas: item.0.gas as i64, recipient: AddressWrapper(item.0.recipient).into(), sender: AddressWrapper(item.0.sender).into(), @@ -195,7 +195,7 @@ impl From<&AthconExecutionMessage> for AthenaMessageWrapper { let byteswrapper = Bytes32Wrapper::from(*item.value()); AthenaMessageWrapper(AthenaMessage { kind: kind.0, - depth: item.depth(), + depth: u32::try_from(item.depth()).expect("Depth value out of range"), gas: u32::try_from(item.gas()).expect("Gas value out of range"), recipient: AddressWrapper::from(*item.recipient()).into(), sender: AddressWrapper::from(*item.sender()).into(), diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 47ea6ce0..89c2defe 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -56,7 +56,7 @@ impl ExecutionClient { /// stdin.write(&10usize); /// /// // Execute the program on the inputs. - /// let (public_values, gas_left) = client.execute::(elf, stdin, None, None).unwrap(); + /// let (public_values, gas_left) = client.execute::(elf, stdin, None, None, None).unwrap(); /// ``` pub fn execute( &self, From 3a43c203e397e1b2522f549a3bc638eb962773aa Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Thu, 18 Jul 2024 13:36:14 -0700 Subject: [PATCH 07/14] Improve tests Make MockHost more sophisticated and more like a real host. Expand the host test smart contract. Add some entrypoint helper functions. --- interface/src/lib.rs | 87 ++++++++++++++++++++++++++--- tests/fibonacci/elf/fibonacci-test | Bin 107512 -> 107800 bytes tests/hint-io/elf/hint-io-test | Bin 143516 -> 143796 bytes tests/host/elf/host-test | Bin 96960 -> 98720 bytes tests/host/src/main.rs | 68 ++++++++++++++++------ tests/panic/elf/panic-test | Bin 71400 -> 71684 bytes vm/entrypoint/Cargo.toml | 2 + vm/entrypoint/src/helpers/mod.rs | 16 ++++++ vm/entrypoint/src/lib.rs | 4 ++ 9 files changed, 150 insertions(+), 27 deletions(-) create mode 100644 vm/entrypoint/src/helpers/mod.rs diff --git a/interface/src/lib.rs b/interface/src/lib.rs index 381e5e45..93a16c18 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -6,6 +6,7 @@ mod context; pub use context::*; use std::{ + collections::BTreeMap, convert::TryFrom, fmt, ops::{Deref, DerefMut}, @@ -71,6 +72,16 @@ impl From for Bytes32 { } } +impl From
for Bytes32Wrapper { + fn from(value: Address) -> Bytes32Wrapper { + let mut bytes = [0u8; 32]; + bytes[..24].copy_from_slice(&value); + Bytes32Wrapper(bytes) + } +} + +// This is based on EIP-2200. +// See https://evmc.ethereum.org/storagestatus.html. #[derive(Debug, PartialEq)] #[repr(u32)] pub enum StorageStatus { @@ -295,30 +306,77 @@ where // a very simple mock host implementation for testing // also useful for filling in the missing generic type // when running the VM in standalone mode, without a bound host interface -pub struct MockHost; +pub struct MockHost { + // stores state keyed by address and key + storage: BTreeMap<(Address, Bytes32), Bytes32>, + + // stores balance keyed by address + balance: BTreeMap, + // stores contract bytecode + // codebase: HashMap>, +} impl MockHost { pub fn new() -> Self { - MockHost {} + MockHost::default() + } +} + +pub const ADDRESS_ALICE: Address = [1u8; ADDRESS_LENGTH]; +pub const ADDRESS_BOB: Address = [2u8; ADDRESS_LENGTH]; +pub const ADDRESS_CHARLIE: Address = [3u8; ADDRESS_LENGTH]; +pub const SOME_COINS: Balance = 1000000; +// "sentinel value" useful for testing: 0xc0ffee +// also useful as a morning wake up! +pub const HELLO_WORLD: Bytes32 = [ + 0xc0, 0xff, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +]; + +impl Default for MockHost { + fn default() -> Self { + // init + let mut storage = BTreeMap::new(); + let mut balance = BTreeMap::new(); + // let mut codebase = HashMap::new(); + + // pre-populate some balances, values, and code for testing + balance.insert(ADDRESS_ALICE, SOME_COINS); + balance.insert(ADDRESS_BOB, SOME_COINS); + balance.insert(ADDRESS_CHARLIE, SOME_COINS); + storage.insert((ADDRESS_ALICE, HELLO_WORLD), HELLO_WORLD); + + Self { + storage, + balance, + // codebase, + } } } impl HostInterface for MockHost { fn account_exists(&self, _addr: &Address) -> bool { - true + self.balance.contains_key(_addr) } fn get_storage(&self, _addr: &Address, _key: &Bytes32) -> Bytes32 { - // return all 1's - [1u8; BYTES32_LENGTH] + self + .storage + .get(&(*_addr, *_key)) + .copied() + .unwrap_or(Bytes32::default()) } fn set_storage(&mut self, _addr: &Address, _key: &Bytes32, _value: &Bytes32) -> StorageStatus { - StorageStatus::StorageAssigned + // this is a very simplistic implementation and does NOT handle all possible cases correctly + match self.storage.insert((*_addr, *_key), *_value) { + None => StorageStatus::StorageAdded, + Some(_) => StorageStatus::StorageModified, + } } fn get_balance(&self, _addr: &Address) -> u64 { - 0 + self.balance.get(_addr).copied().unwrap_or(0) } fn get_tx_context(&self) -> TransactionContext { @@ -329,7 +387,18 @@ impl HostInterface for MockHost { unimplemented!() } - fn call(&mut self, _msg: AthenaMessage) -> ExecutionResult { - unimplemented!() + fn call(&mut self, msg: AthenaMessage) -> ExecutionResult { + // mock host knows about one callable contract + let status_code = if msg.recipient == ADDRESS_CHARLIE { + // calling charlie works + StatusCode::Success + } else { + // no one else picks up the phone + StatusCode::Failure + }; + + let gas_left = msg.gas.checked_sub(1).expect("gas underflow"); + + return ExecutionResult::new(status_code, gas_left, None, None); } } diff --git a/tests/fibonacci/elf/fibonacci-test b/tests/fibonacci/elf/fibonacci-test index a4a5053144ef718d7fac7813dbdd2da7d55dab3a..c9de47f884e751aed51443a2802d5dcc2c0ad28a 100755 GIT binary patch delta 18597 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 O{V^Y6*>GX9+W!JCyk#8# delta 18302 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 delta 25908 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 diff --git a/tests/host/elf/host-test b/tests/host/elf/host-test index 7234afe94c43908e2cbef662c44d3bef3b244a32..5764656af31d9f9ed5c482734ebb08cd53b4f7b3 100755 GIT binary patch delta 34634 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�%)T7tQ~za*Fv*~ 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 delta 32963 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 diff --git a/tests/host/src/main.rs b/tests/host/src/main.rs index 93973b5b..5b872d21 100644 --- a/tests/host/src/main.rs +++ b/tests/host/src/main.rs @@ -1,24 +1,56 @@ #![no_main] athena_vm::entrypoint!(main); +use athena_vm::helpers::{address_to_32bit_words, address_to_bytes32, bytes32_to_32bit_words}; +use athena_vm::types::{ + StorageStatus::StorageAdded, StorageStatus::StorageModified, ADDRESS_ALICE, ADDRESS_BOB, + ADDRESS_CHARLIE, HELLO_WORLD, SOME_COINS, +}; + +// storage status is returned as a 256-bit value +const STORAGE_ADDED: [u32; 8] = [StorageAdded as u32, 0, 0, 0, 0, 0, 0, 0]; +const STORAGE_MODIFIED: [u32; 8] = [StorageModified as u32, 0, 0, 0, 0, 0, 0, 0]; + pub fn main() { - // use 32-bit words - let address = [0u32; 6]; - let mut key = [2u32; 8]; - let mut key2 = [2u32; 8]; - - // expected output value - // [1u8; 32] i.e. 32 x 1-bytes - // we convert [u8; 32] into [u32; 8] where each u32 is a 4 byte chunk - // 0x01010101 == 16843009 - let value = [16843009u32; 8]; - - // result will be written to key, overwriting input value - unsafe { athena_vm::host::write_storage(key.as_mut_ptr(), address.as_ptr(), value.as_ptr()) }; - assert_eq!(key, [0u32; 8], "write_storage failed"); - - // result will be written to key, overwriting input value - unsafe { athena_vm::host::read_storage(key2.as_mut_ptr(), address.as_ptr()) }; - assert_eq!(value, key2, "read_storage failed"); + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + let value = bytes32_to_32bit_words(HELLO_WORLD); + let value2: [u32; 8] = [0xaa; 8]; + let value_unset: [u32; 8] = [0; 8]; + let address_alice = address_to_32bit_words(ADDRESS_ALICE); + let address_bob = address_to_32bit_words(ADDRESS_BOB); + + // note: for all of these calls, the result is written to the first argument, hence as_mut_ptr() + + // Alice already has a storage item + unsafe { athena_vm::host::read_storage(key.as_mut_ptr(), address_alice.as_ptr()) }; + assert_eq!(value, key, "read_storage failed"); + + // Modify it + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + unsafe { + athena_vm::host::write_storage(key.as_mut_ptr(), address_alice.as_ptr(), value2.as_ptr()) + }; + assert_eq!(key, STORAGE_MODIFIED, "write_storage failed"); + + // Read the modified value + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + unsafe { athena_vm::host::read_storage(key.as_mut_ptr(), address_alice.as_ptr()) }; + assert_eq!(value2, key, "read_storage failed"); + + // Bob has no storage item + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + unsafe { athena_vm::host::read_storage(key.as_mut_ptr(), address_bob.as_ptr()) }; + assert_eq!(value_unset, key, "read_storage failed"); + + // Write to Bob's storage + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + unsafe { athena_vm::host::write_storage(key.as_mut_ptr(), address_bob.as_ptr(), value.as_ptr()) }; + assert_eq!(key, STORAGE_ADDED, "write_storage failed"); + + // Read the new value + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + unsafe { athena_vm::host::read_storage(key.as_mut_ptr(), address_bob.as_ptr()) }; + assert_eq!(value, key, "read_storage failed"); + println!("success"); } diff --git a/tests/panic/elf/panic-test b/tests/panic/elf/panic-test index bc0179de4ef4cf40915fe33beb5e5ce9a6654f81..f6ce48aef42f37c8b4a5464e9954fa74f7f3753d 100755 GIT binary patch delta 13067 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 RdmRK$!t=J*u$kHIe*x~1u$KS; delta 12791 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 diff --git a/vm/entrypoint/Cargo.toml b/vm/entrypoint/Cargo.toml index d89324a3..114446db 100644 --- a/vm/entrypoint/Cargo.toml +++ b/vm/entrypoint/Cargo.toml @@ -9,8 +9,10 @@ edition.workspace = true [dependencies] athena-hostfunctions = { path = "../hostfunctions" } +athena-interface = { path = "../../interface" } athena-precompiles = { path = "../precompiles" } bincode = "1.3.3" +bytemuck = "1.7.0" cfg-if = "1.0.0" getrandom = { version = "0.2.14", features = ["custom"] } serde = { version = "1.0.201", features = ["derive"] } diff --git a/vm/entrypoint/src/helpers/mod.rs b/vm/entrypoint/src/helpers/mod.rs new file mode 100644 index 00000000..feb824f1 --- /dev/null +++ b/vm/entrypoint/src/helpers/mod.rs @@ -0,0 +1,16 @@ +use athena_interface::{Address, Bytes32, Bytes32Wrapper}; +use bytemuck::cast; + +// Simple helper functions for smart contracts + +pub fn address_to_bytes32(address: Address) -> Bytes32 { + Bytes32Wrapper::from(address).into() +} + +pub fn address_to_32bit_words(address: Address) -> [u32; 6] { + cast::<[u8; 24], [u32; 6]>(address) +} + +pub fn bytes32_to_32bit_words(bytes32: Bytes32) -> [u32; 8] { + cast::<[u8; 32], [u32; 8]>(bytes32) +} diff --git a/vm/entrypoint/src/lib.rs b/vm/entrypoint/src/lib.rs index 18e8d048..f44576a6 100644 --- a/vm/entrypoint/src/lib.rs +++ b/vm/entrypoint/src/lib.rs @@ -1,4 +1,5 @@ pub mod heap; +pub mod helpers; pub mod syscalls; pub mod host { pub use athena_hostfunctions::*; @@ -9,6 +10,9 @@ pub mod io { pub mod precompiles { pub use athena_precompiles::*; } +pub mod types { + pub use athena_interface::*; +} extern crate alloc; From 292a14ad39f79dbed9222e1ce4a695b90bdc6870 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Thu, 18 Jul 2024 15:15:04 -0700 Subject: [PATCH 08/14] Properly propagate errors out of runner/sdk Update gas tests --- core/src/runtime/mod.rs | 43 +++++++++++++++++++++++---------------- interface/src/context.rs | 2 ++ runner/Cargo.toml | 1 + runner/src/vm.rs | 26 +++++++++++++++-------- sdk/src/lib.rs | 21 ++++++++++--------- tests/host/elf/host-test | Bin 98720 -> 98920 bytes tests/host/src/main.rs | 9 ++++++++ 7 files changed, 67 insertions(+), 35 deletions(-) diff --git a/core/src/runtime/mod.rs b/core/src/runtime/mod.rs index 820a5f92..8c35ee53 100644 --- a/core/src/runtime/mod.rs +++ b/core/src/runtime/mod.rs @@ -598,7 +598,9 @@ where if syscall == SyscallCode::HOST_CALL { let return_code = res.unwrap(); let status_code = StatusCode::try_from(return_code).unwrap(); - return Err(ExecutionError::HostCallFailed(status_code)); + if status_code != StatusCode::Success { + return Err(ExecutionError::HostCallFailed(status_code)); + } } // If the syscall is `HALT` and the exit code is non-zero, return an error. @@ -819,7 +821,7 @@ pub mod tests { runtime::ExecutionError, utils::{self, with_max_gas}, }; - use athena_interface::{HostProvider, MockHost}; + use athena_interface::{Address, AthenaContext, HostProvider, MockHost}; use crate::{ runtime::Register, @@ -874,41 +876,48 @@ pub mod tests { let program = host_program(); let host = MockHost::new(); let provider = HostProvider::new(host); + let ctx = AthenaContext::new(Address::default(), Address::default(), 0); + let opts = AthenaCoreOpts::default().with_options(vec![with_max_gas(100000)]); let mut runtime = Runtime::::new( program, Some(Arc::new(RefCell::new(provider))), - AthenaCoreOpts::default(), - None, + opts, + Some(ctx), ); let gas_left = runtime.execute().unwrap(); - assert_eq!(gas_left, None); + + // don't bother checking exact gas value, that's checked in the following test + assert!(gas_left.is_some()); } #[test] fn test_host_gas() { let program = host_program(); - let host = MockHost::new(); - let provider = HostProvider::new(host); - let provider = Arc::new(RefCell::new(provider)); + let ctx = AthenaContext::new(Address::default(), Address::default(), 0); + + // we need a new host provider for each test to reset state + fn get_provider() -> Arc>> { + Arc::new(RefCell::new(HostProvider::new(MockHost::new()))) + } // program should cost 4332 gas units // failure let mut runtime = Runtime::::new( program.clone(), - Some(provider.clone()), - AthenaCoreOpts::default().with_options(vec![with_max_gas(4331)]), - None, + Some(get_provider()), + AthenaCoreOpts::default().with_options(vec![with_max_gas(11236)]), + Some(ctx.clone()), ); assert!(matches!(runtime.execute(), Err(ExecutionError::OutOfGas()))); // success runtime = Runtime::::new( program.clone(), - Some(provider.clone()), + Some(get_provider()), // program should cost 4332 gas units - AthenaCoreOpts::default().with_options(vec![with_max_gas(4332)]), - None, + AthenaCoreOpts::default().with_options(vec![with_max_gas(11237)]), + Some(ctx.clone()), ); let gas_left = runtime.execute().unwrap(); assert_eq!(gas_left, Some(0)); @@ -916,10 +925,10 @@ pub mod tests { // success runtime = Runtime::::new( program.clone(), - Some(provider.clone()), + Some(get_provider()), // program should cost 4332 gas units - AthenaCoreOpts::default().with_options(vec![with_max_gas(4333)]), - None, + AthenaCoreOpts::default().with_options(vec![with_max_gas(11238)]), + Some(ctx.clone()), ); let gas_left = runtime.execute().unwrap(); assert_eq!(gas_left, Some(1)); diff --git a/interface/src/context.rs b/interface/src/context.rs index 0fc9986b..c7c34a47 100644 --- a/interface/src/context.rs +++ b/interface/src/context.rs @@ -2,6 +2,8 @@ /// execution message that's guaranteed not to change during the context of the /// program execution. use crate::Address; + +#[derive(Debug, Clone)] pub struct AthenaContext { address: Address, caller: Address, diff --git a/runner/Cargo.toml b/runner/Cargo.toml index 8efad08b..be09b44e 100644 --- a/runner/Cargo.toml +++ b/runner/Cargo.toml @@ -10,5 +10,6 @@ edition.workspace = true [dependencies] athcon-sys = { path = "../ffi/athcon/bindings/rust/athcon-sys" } athcon-vm = { path = "../ffi/athcon/bindings/rust/athcon-vm" } +athena-core = { path = "../core" } athena-interface = { path = "../interface" } athena-sdk = { path = "../sdk" } diff --git a/runner/src/vm.rs b/runner/src/vm.rs index 30fd3e34..5fd29ab8 100644 --- a/runner/src/vm.rs +++ b/runner/src/vm.rs @@ -1,6 +1,7 @@ use std::{cell::RefCell, sync::Arc}; use crate::host::{AthenaCapability, AthenaOption, SetOptionError}; +use athena_core::runtime::ExecutionError; use athena_interface::{ AthenaContext, AthenaMessage, ExecutionResult, HostInterface, HostProvider, StatusCode, }; @@ -60,16 +61,25 @@ where stdin.write_vec(input_data); } - let (output, gas_left) = self + // let (output, gas_left) = self + match self .client .execute(&code, stdin, Some(host), Some(msg.gas), Some(context)) - .unwrap(); - ExecutionResult::new( - StatusCode::Success, - gas_left.unwrap(), - Some(output.to_vec()), - None, - ) + { + Ok((public_values, gas_left)) => ExecutionResult::new( + StatusCode::Success, + gas_left.unwrap(), + Some(public_values.to_vec()), + None, + ), + // map error to execution result + Err(e) => match e { + ExecutionError::OutOfGas() => ExecutionResult::new(StatusCode::OutOfGas, 0, None, None), + ExecutionError::HostCallFailed(code) => ExecutionResult::new(code, 0, None, None), + // general error + _ => ExecutionResult::new(StatusCode::Failure, 0, None, None), + }, + } } } diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 89c2defe..93ab4f19 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -12,9 +12,8 @@ pub mod utils { use std::cell::RefCell; use std::sync::Arc; -use anyhow::{Ok, Result}; pub use athena_core::io::{AthenaPublicValues, AthenaStdin}; -use athena_core::runtime::{Program, Runtime}; +use athena_core::runtime::{ExecutionError, Program, Runtime}; use athena_core::utils::AthenaCoreOpts; use athena_interface::{AthenaContext, HostInterface, HostProvider}; @@ -65,7 +64,7 @@ impl ExecutionClient { host: Option>>>, max_gas: Option, context: Option, - ) -> Result<(AthenaPublicValues, Option)> { + ) -> Result<(AthenaPublicValues, Option), ExecutionError> { let program = Program::from(elf); let opts = match max_gas { None => AthenaCoreOpts::default(), @@ -75,11 +74,12 @@ impl ExecutionClient { }; let mut runtime = Runtime::new(program, host, opts, context); runtime.write_vecs(&stdin.buffer); - let gas_left = runtime.execute().unwrap(); - Ok(( - AthenaPublicValues::from(&runtime.state.public_values_stream), - gas_left, - )) + runtime.execute().map(|gas_left| { + ( + AthenaPublicValues::from(&runtime.state.public_values_stream), + gas_left, + ) + }) } } @@ -94,7 +94,7 @@ mod tests { use std::{cell::RefCell, sync::Arc}; use crate::{utils, AthenaStdin, ExecutionClient}; - use athena_interface::{HostProvider, MockHost}; + use athena_interface::{AthenaContext, HostProvider, MockHost, ADDRESS_ALICE}; #[test] fn test_execute() { @@ -115,8 +115,9 @@ mod tests { let elf = include_bytes!("../../tests/host/elf/host-test"); let stdin = AthenaStdin::new(); let host = Arc::new(RefCell::new(HostProvider::new(MockHost::new()))); + let ctx = AthenaContext::new(ADDRESS_ALICE, ADDRESS_ALICE, 0); client - .execute::(elf, stdin, Some(host), None, None) + .execute::(elf, stdin, Some(host), Some(1_000_000), Some(ctx)) .unwrap(); } diff --git a/tests/host/elf/host-test b/tests/host/elf/host-test index 5764656af31d9f9ed5c482734ebb08cd53b4f7b3..6703dcdd37160d7eb7f5c367b732ba39b406021a 100755 GIT binary patch delta 32505 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 j7t)+m-F&4H=R6d^Im6a)uQa0C&=&P;8;Bk diff --git a/tests/host/src/main.rs b/tests/host/src/main.rs index 5b872d21..ce12807c 100644 --- a/tests/host/src/main.rs +++ b/tests/host/src/main.rs @@ -18,6 +18,7 @@ pub fn main() { let value_unset: [u32; 8] = [0; 8]; let address_alice = address_to_32bit_words(ADDRESS_ALICE); let address_bob = address_to_32bit_words(ADDRESS_BOB); + let address_charlie = address_to_32bit_words(ADDRESS_CHARLIE); // note: for all of these calls, the result is written to the first argument, hence as_mut_ptr() @@ -52,5 +53,13 @@ pub fn main() { unsafe { athena_vm::host::read_storage(key.as_mut_ptr(), address_bob.as_ptr()) }; assert_eq!(value, key, "read_storage failed"); + // Alice does not accept calls + // unsafe { athena_vm::host::call(address_alice.as_ptr(), std::ptr::null(), 0) }; + + // Charlie does accept calls + // Note: there is no way to check the result of a call + // It either works, or it panics + unsafe { athena_vm::host::call(address_charlie.as_ptr(), std::ptr::null(), 0) }; + println!("success"); } From 055ec634eb3ba685b78ce57fef892946a4bcabc9 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Thu, 18 Jul 2024 16:26:12 -0700 Subject: [PATCH 09/14] Add bad call test First hand-coded asm host call test --- core/src/runtime/mod.rs | 50 +++++++++++++++++++++++++++++++++++++++++ interface/src/lib.rs | 9 +------- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/core/src/runtime/mod.rs b/core/src/runtime/mod.rs index 8c35ee53..6baf0116 100644 --- a/core/src/runtime/mod.rs +++ b/core/src/runtime/mod.rs @@ -934,6 +934,56 @@ pub mod tests { assert_eq!(gas_left, Some(1)); } + #[test] + fn test_bad_call() { + utils::setup_logger(); + + let instructions = vec![ + // X10 is arg1 (ptr to address) + // memory location to store an address + Instruction::new( + Opcode::ADD, + Register::X10 as u32, + 0, + 0x12345678, + false, + true, + ), + // store arbitrary address here + Instruction::new(Opcode::SW, Register::X10 as u32, 0, 0x12345678, false, true), + // X11 is arg2 (ptr to input) + // zero pointer + Instruction::new(Opcode::ADD, Register::X11 as u32, 0, 0, false, true), + // X12 is arg3 (input len) + // no input + Instruction::new(Opcode::ADD, Register::X12 as u32, 0, 0, false, true), + // X5 is syscall ID: 0xA2 (HOST_CALL) + Instruction::new(Opcode::ADD, Register::X5 as u32, 0, 0xA2, false, true), + Instruction::new(Opcode::ECALL, 0, 0, 0, false, false), + ]; + let program = Program::new(instructions, 0, 0); + + let host = MockHost::new(); + let provider = HostProvider::new(host); + let ctx = AthenaContext::new(Address::default(), Address::default(), 0); + let opts = AthenaCoreOpts::default().with_options(vec![with_max_gas(100000)]); + let mut runtime = Runtime::::new( + program, + Some(Arc::new(RefCell::new(provider))), + opts, + Some(ctx), + ); + match runtime.execute() { + Err(e) => match e { + ExecutionError::HostCallFailed(code) => { + assert_eq!(code, athena_interface::StatusCode::Failure); + } + _ => panic!("unexpected error: {:?}", e), + }, + Ok(_) => panic!("expected error, got Ok"), + } + } + #[test] fn test_add() { // main: diff --git a/interface/src/lib.rs b/interface/src/lib.rs index 93a16c18..54c97d59 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -312,8 +312,6 @@ pub struct MockHost { // stores balance keyed by address balance: BTreeMap, - // stores contract bytecode - // codebase: HashMap>, } impl MockHost { @@ -338,7 +336,6 @@ impl Default for MockHost { // init let mut storage = BTreeMap::new(); let mut balance = BTreeMap::new(); - // let mut codebase = HashMap::new(); // pre-populate some balances, values, and code for testing balance.insert(ADDRESS_ALICE, SOME_COINS); @@ -346,11 +343,7 @@ impl Default for MockHost { balance.insert(ADDRESS_CHARLIE, SOME_COINS); storage.insert((ADDRESS_ALICE, HELLO_WORLD), HELLO_WORLD); - Self { - storage, - balance, - // codebase, - } + Self { storage, balance } } } From 711c8d3cf27a6484c4ec971541c6a387c340a884 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Thu, 18 Jul 2024 19:35:25 -0700 Subject: [PATCH 10/14] First draft of recursive fibonacci test --- examples/fibonacci/program/src/main.rs | 44 +++++++++++----------- tests/fibonacci/src/main.rs | 27 ++++++-------- tests/recursive_call/Cargo.toml | 8 ++++ tests/recursive_call/src/main.rs | 51 ++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 37 deletions(-) create mode 100644 tests/recursive_call/Cargo.toml create mode 100644 tests/recursive_call/src/main.rs diff --git a/examples/fibonacci/program/src/main.rs b/examples/fibonacci/program/src/main.rs index 374a7af2..f7237e73 100644 --- a/examples/fibonacci/program/src/main.rs +++ b/examples/fibonacci/program/src/main.rs @@ -4,33 +4,33 @@ // These two lines are necessary for the program to properly compile. // // Under the hood, we wrap your main function with some extra code so that it behaves properly -// inside the zkVM. +// inside the VM. #![no_main] athena_vm::entrypoint!(main); pub fn main() { - // Read an input to the program. - // - // Behind the scenes, this compiles down to a custom system call which handles reading inputs. - let n = athena_vm::io::read::(); + // Read an input to the program. + // + // Behind the scenes, this compiles down to a custom system call which handles reading inputs. + let n = athena_vm::io::read::(); - // Write n to public input - athena_vm::io::write(&n); + // Write n to public input + athena_vm::io::write(&n); - // Compute the n'th fibonacci number, using normal Rust code. - let mut a = 0; - let mut b = 1; - for _ in 0..n { - let mut c = a + b; - c %= 7919; // Modulus to prevent overflow. - a = b; - b = c; - } + // Compute the n'th fibonacci number, using normal Rust code. + let mut a = 0; + let mut b = 1; + for _ in 0..n { + let mut c = a + b; + c %= 7919; // Modulus to prevent overflow. + a = b; + b = c; + } - // Write the output of the program. - // - // Behind the scenes, this also compiles down to a custom system call which handles writing - // outputs. - athena_vm::io::write(&a); - athena_vm::io::write(&b); + // Write the output of the program. + // + // Behind the scenes, this also compiles down to a custom system call which handles writing + // outputs. + athena_vm::io::write(&a); + athena_vm::io::write(&b); } diff --git a/tests/fibonacci/src/main.rs b/tests/fibonacci/src/main.rs index 6c68bbb4..6b111908 100644 --- a/tests/fibonacci/src/main.rs +++ b/tests/fibonacci/src/main.rs @@ -9,19 +9,16 @@ athena_vm::entrypoint!(main); pub fn main() { - // Read an input to the program. - // - // Behind the scenes, this compiles down to a custom system call which handles reading inputs. - let n = 10; - // Compute the n'th fibonacci number, using normal Rust code. - let mut a = 0; - let mut b = 1; - for _ in 0..n { - let mut c = a + b; - c %= 7919; // Modulus to prevent overflow. - a = b; - b = c; - } - athena_vm::io::write(&a); - athena_vm::io::write(&b); + let n = 10; + // Compute the n'th fibonacci number, using normal Rust code. + let mut a = 0; + let mut b = 1; + for _ in 0..n { + let mut c = a + b; + c %= 7919; // Modulus to prevent overflow. + a = b; + b = c; + } + athena_vm::io::write(&a); + athena_vm::io::write(&b); } diff --git a/tests/recursive_call/Cargo.toml b/tests/recursive_call/Cargo.toml new file mode 100644 index 00000000..fadac757 --- /dev/null +++ b/tests/recursive_call/Cargo.toml @@ -0,0 +1,8 @@ +[workspace] +[package] +name = "recursive-call-test" +version = "0.1.0" +edition = "2021" + +[dependencies] +athena-vm = { path = "../../vm/entrypoint", features = ["rv32e"] } diff --git a/tests/recursive_call/src/main.rs b/tests/recursive_call/src/main.rs new file mode 100644 index 00000000..df7010cf --- /dev/null +++ b/tests/recursive_call/src/main.rs @@ -0,0 +1,51 @@ +#![no_main] +athena_vm::entrypoint!(main); + +use athena_vm::helpers::{address_to_32bit_words, address_to_bytes32, bytes32_to_32bit_words}; +use athena_vm::types::{ + StorageStatus::StorageAdded, StorageStatus::StorageModified, ADDRESS_ALICE, HELLO_WORLD, +}; + +// storage status is returned as a 256-bit value +const STORAGE_ADDED: [u32; 8] = [StorageAdded as u32, 0, 0, 0, 0, 0, 0, 0]; +const STORAGE_MODIFIED: [u32; 8] = [StorageModified as u32, 0, 0, 0, 0, 0, 0, 0]; + +// emulate a return value by writing the return value to storage. +// Athena doesn't support return values yet. +fn return_value(value: u32) { + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + let val: [u32; 8] = [value, 0, 0, 0, 0, 0, 0, 0]; + let address = address_to_32bit_words(ADDRESS_ALICE); + unsafe { athena_vm::host::write_storage(key.as_mut_ptr(), address.as_ptr(), val.as_ptr()) }; + assert_eq!(key, STORAGE_MODIFIED, "write_storage failed"); +} + +fn recursive_call(value: u32) -> u32 { + // we need a pointer to the value as an array + let val: [u32; 1] = [value]; + let address = address_to_32bit_words(ADDRESS_ALICE); + unsafe { athena_vm::host::call(address.as_ptr(), val.as_ptr(), 1) }; + + // read the return value + let mut key = bytes32_to_32bit_words(HELLO_WORLD); + unsafe { athena_vm::host::read_storage(key.as_mut_ptr(), address.as_ptr()) }; + return key[0]; +} + +pub fn main() { + // Read an input to the program. + // + // Behind the scenes, this compiles down to a custom system call which handles reading inputs. + let n = athena_vm::io::read::(); + + // Base case + if n <= 1 { + return_value(n); + return; + } + + // Recursive case + let a = recursive_call(n - 1); + let b = recursive_call(n - 2); + return_value(a + b); +} From 85b404073cb98e467b86ae77a04d0023bca1be2d Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 19 Jul 2024 13:50:07 -0700 Subject: [PATCH 11/14] Checkpoint: implementing recursive host test Make MockHost a lot smarter. Add a program map. Refactor some test-related and interface code, consolidate things in interface crate. Add AthenaRevision. Allow MockHost to recursively call into the VM. Required some memory magic. --- ffi/vmlib/src/lib.rs | 21 ++- interface/src/lib.rs | 185 ++++++++++++++++++- runner/src/host.rs | 111 ----------- runner/src/lib.rs | 2 +- runner/src/vm.rs | 128 +------------ sdk/src/lib.rs | 15 ++ tests/host/src/main.rs | 2 +- tests/recursive_call/elf/recursive-call-test | Bin 0 -> 109876 bytes tests/recursive_call/src/main.rs | 9 +- 9 files changed, 226 insertions(+), 247 deletions(-) create mode 100755 tests/recursive_call/elf/recursive-call-test diff --git a/ffi/vmlib/src/lib.rs b/ffi/vmlib/src/lib.rs index 36800d30..7838cd26 100644 --- a/ffi/vmlib/src/lib.rs +++ b/ffi/vmlib/src/lib.rs @@ -8,10 +8,10 @@ use athcon_vm::{ SetOptionError, }; use athena_interface::{ - Address, AthenaMessage, Balance, Bytes32, ExecutionResult, HostInterface, HostProvider, - MessageKind, StatusCode, StorageStatus, TransactionContext, + Address, AthenaMessage, AthenaRevision, Balance, Bytes32, ExecutionResult, HostInterface, + HostProvider, MessageKind, StatusCode, StorageStatus, TransactionContext, VmInterface, }; -use athena_runner::{AthenaVm, Bytes32AsU64, VmInterface}; +use athena_runner::{AthenaVm, Bytes32AsU64}; #[athcon_declare_vm("Athena", "athena1", "0.1.0")] pub struct AthenaVMWrapper { @@ -60,11 +60,24 @@ impl AthconVm for AthenaVMWrapper { let host = Arc::new(RefCell::new(provider)); // Execute the code and proxy the result back to the caller - let execution_result = self.athena_vm.execute(host, rev as u32, athena_msg.0, code); + let execution_result = + self + .athena_vm + .execute(host, RevisionWrapper::from(rev).0, athena_msg.0, code); ExecutionResultWrapper(execution_result).into() } } +struct RevisionWrapper(AthenaRevision); + +impl From for RevisionWrapper { + fn from(rev: Revision) -> Self { + match rev { + Revision::ATHCON_FRONTIER => RevisionWrapper(AthenaRevision::AthenaFrontier), + } + } +} + struct AddressWrapper(Address); impl From for AddressWrapper { diff --git a/interface/src/lib.rs b/interface/src/lib.rs index 54c97d59..b6f2b2a4 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -6,10 +6,12 @@ mod context; pub use context::*; use std::{ + cell::RefCell, collections::BTreeMap, convert::TryFrom, fmt, ops::{Deref, DerefMut}, + sync::Arc, }; pub const ADDRESS_LENGTH: usize = 24; @@ -306,18 +308,28 @@ where // a very simple mock host implementation for testing // also useful for filling in the missing generic type // when running the VM in standalone mode, without a bound host interface -pub struct MockHost { +pub struct MockHost<'a> { + // VM instance + vm: MockVm, + // stores state keyed by address and key storage: BTreeMap<(Address, Bytes32), Bytes32>, // stores balance keyed by address balance: BTreeMap, + + // stores contract code + programs: BTreeMap, } -impl MockHost { +impl<'a> MockHost<'a> { pub fn new() -> Self { MockHost::default() } + + pub fn deploy_code(&mut self, address: Address, code: &'a [u8]) { + self.programs.insert(address, code); + } } pub const ADDRESS_ALICE: Address = [1u8; ADDRESS_LENGTH]; @@ -331,11 +343,15 @@ pub const HELLO_WORLD: Bytes32 = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; -impl Default for MockHost { +impl<'a> Default for MockHost<'a> { fn default() -> Self { + // instantiate a mock VM + let vm = MockVm::new(); + // init let mut storage = BTreeMap::new(); let mut balance = BTreeMap::new(); + let programs = BTreeMap::new(); // pre-populate some balances, values, and code for testing balance.insert(ADDRESS_ALICE, SOME_COINS); @@ -343,11 +359,16 @@ impl Default for MockHost { balance.insert(ADDRESS_CHARLIE, SOME_COINS); storage.insert((ADDRESS_ALICE, HELLO_WORLD), HELLO_WORLD); - Self { storage, balance } + Self { + vm, + storage, + balance, + programs, + } } } -impl HostInterface for MockHost { +impl<'a> HostInterface for MockHost<'a> { fn account_exists(&self, _addr: &Address) -> bool { self.balance.contains_key(_addr) } @@ -381,7 +402,25 @@ impl HostInterface for MockHost { } fn call(&mut self, msg: AthenaMessage) -> ExecutionResult { - // mock host knows about one callable contract + // check programs list first + if let Some(code) = self.programs.get(&msg.recipient).cloned() { + // create an owned, cloned copy of VM before taking the host from self + let vm = self.vm.clone(); + + // HostProvider requires an owned instance, so we need to take it from self + let provider = HostProvider::new(std::mem::take(self)); + let host = Arc::new(RefCell::new(provider)); + let res = vm.execute(host.clone(), AthenaRevision::AthenaFrontier, msg, code); + + // Restore self + *self = Arc::try_unwrap(host) + .unwrap_or_else(|_| panic!("Arc still has multiple strong references")) + .into_inner() + .host; + return res; + } + + // otherwise, pass a call to Charlie, fail all other calls let status_code = if msg.recipient == ADDRESS_CHARLIE { // calling charlie works StatusCode::Success @@ -395,3 +434,137 @@ impl HostInterface for MockHost { return ExecutionResult::new(status_code, gas_left, None, None); } } + +// currently unused +#[derive(Debug, Clone, Copy)] +pub enum AthenaCapability {} + +// currently unused +#[derive(Debug, Clone)] +pub enum AthenaOption {} + +#[derive(Debug)] +pub enum SetOptionError { + InvalidKey, + InvalidValue, +} + +#[derive(Debug)] +pub enum AthenaRevision { + AthenaFrontier, +} + +pub trait VmInterface { + fn get_capabilities(&self) -> Vec; + fn set_option(&self, option: AthenaOption, value: &str) -> Result<(), SetOptionError>; + fn execute( + &self, + host: Arc>>, + rev: AthenaRevision, + msg: AthenaMessage, + code: &[u8], + ) -> ExecutionResult; +} + +// a very simple mock VM implementation +#[derive(Clone)] +struct MockVm {} + +impl MockVm { + fn new() -> Self { + MockVm {} + } +} + +impl VmInterface for MockVm +where + T: HostInterface, +{ + fn get_capabilities(&self) -> Vec { + vec![] + } + + fn set_option(&self, _option: AthenaOption, _value: &str) -> Result<(), SetOptionError> { + Err(SetOptionError::InvalidKey) + } + + fn execute( + &self, + host: Arc>>, + _rev: AthenaRevision, + msg: AthenaMessage, + _code: &[u8], + ) -> ExecutionResult { + // process a few basic messages + + // save context and perform a call + + // restore context + + // get block hash + let output = host.borrow().get_block_hash(0); + + ExecutionResult::new( + StatusCode::Success, + msg.gas - 1, + Some(output.to_vec()), + None, + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::{cell::RefCell, sync::Arc}; + + #[test] + fn test_mock_vm() { + // construct a mock host + let host = MockHost::new(); + let host_provider = HostProvider::new(host); + let host_interface = Arc::new(RefCell::new(host_provider)); + + // construct a mock vm + let vm = MockVm::new(); + + // test execution + vm.execute( + host_interface, + AthenaRevision::AthenaFrontier, + AthenaMessage::new( + MessageKind::Call, + 0, + 1000, + Address::default(), + Address::default(), + None, + Balance::default(), + vec![], + ), + &[], + ); + } + + #[test] + fn test_get_storage() { + let mut host = MockHost::new(); + let address = [8; 24]; + let key = [1; 32]; + let value = [2; 32]; + assert_eq!( + host.set_storage(&address, &key, &value), + StorageStatus::StorageAssigned + ); + let retrieved_value = host.get_storage(&address, &key); + assert_eq!(retrieved_value, value); + } + + #[test] + fn test_get_balance() { + let host = MockHost::new(); + let address = [8; 24]; + let balance = host.get_balance(&address); + assert_eq!(balance, 0); + } +} diff --git a/runner/src/host.rs b/runner/src/host.rs index c7e14bfd..bc816a90 100644 --- a/runner/src/host.rs +++ b/runner/src/host.rs @@ -30,114 +30,3 @@ impl From for Bytes32AsU64 { Bytes32AsU64(bytes) } } - -// currently unused -#[derive(Debug, Clone, Copy)] -pub enum AthenaCapability {} - -// currently unused -#[derive(Debug, Clone)] -pub enum AthenaOption {} - -#[derive(Debug)] -pub enum SetOptionError { - InvalidKey, - InvalidValue, -} - -#[cfg(test)] -use std::collections::BTreeMap; - -#[cfg(test)] -use athena_interface::{ - Address, AthenaMessage, ExecutionResult, HostInterface, StorageStatus, TransactionContext, -}; - -#[cfg(test)] -pub(crate) struct MockHost { - context: Option, - - // stores state keyed by address and key - storage: BTreeMap<(Address, Bytes32), Bytes32>, - - // stores balance keyed by address - balance: BTreeMap, -} - -#[cfg(test)] -impl MockHost { - pub fn new(context: Option) -> Self { - MockHost { - context: context, - storage: BTreeMap::new(), - balance: BTreeMap::new(), - } - } -} - -#[cfg(test)] -impl HostInterface for MockHost { - fn account_exists(&self, addr: &Address) -> bool { - self.balance.contains_key(addr) - } - - // return null bytes if the account or key do not exist - fn get_storage(&self, address: &Address, key: &Bytes32) -> Bytes32 { - *self - .storage - .get(&(*address, *key)) - .unwrap_or(&Bytes32::default()) - } - - fn set_storage(&mut self, address: &Address, key: &Bytes32, value: &Bytes32) -> StorageStatus { - self.storage.insert((*address, *key), *value); - return StorageStatus::StorageAssigned; - } - - // return 0 if the account does not exist - fn get_balance(&self, address: &Address) -> u64 { - self - .balance - .get(address) - .map_or_else(|| 0, |balance| Bytes32AsU64(*balance).into()) - } - - fn get_tx_context(&self) -> TransactionContext { - self.context.unwrap() - } - - fn get_block_hash(&self, _number: i64) -> Bytes32 { - Bytes32::default() - } - - fn call(&mut self, _msg: AthenaMessage) -> ExecutionResult { - ExecutionResult::new(athena_interface::StatusCode::Failure, 0, None, None) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_get_storage() { - let mut host = MockHost::new(None); - let address = [8; 24]; - let key = [1; 32]; - let value = [2; 32]; - assert_eq!( - host.set_storage(&address, &key, &value), - StorageStatus::StorageAssigned - ); - let retrieved_value = host.get_storage(&address, &key); - assert_eq!(retrieved_value, value); - } - - #[test] - fn test_get_balance() { - let host = MockHost::new(None); - let address = [8; 24]; - let balance = host.get_balance(&address); - assert_eq!(balance, 0); - } -} diff --git a/runner/src/lib.rs b/runner/src/lib.rs index c8a54bf8..594e0ac4 100644 --- a/runner/src/lib.rs +++ b/runner/src/lib.rs @@ -2,4 +2,4 @@ pub mod host; pub mod vm; pub use host::Bytes32AsU64; -pub use vm::{AthenaVm, VmInterface}; +pub use vm::AthenaVm; diff --git a/runner/src/vm.rs b/runner/src/vm.rs index 5fd29ab8..57b83651 100644 --- a/runner/src/vm.rs +++ b/runner/src/vm.rs @@ -1,24 +1,12 @@ use std::{cell::RefCell, sync::Arc}; -use crate::host::{AthenaCapability, AthenaOption, SetOptionError}; use athena_core::runtime::ExecutionError; use athena_interface::{ - AthenaContext, AthenaMessage, ExecutionResult, HostInterface, HostProvider, StatusCode, + AthenaCapability, AthenaContext, AthenaMessage, AthenaOption, AthenaRevision, ExecutionResult, + HostInterface, HostProvider, SetOptionError, StatusCode, VmInterface, }; use athena_sdk::{AthenaStdin, ExecutionClient}; -pub trait VmInterface { - fn get_capabilities(&self) -> Vec; - fn set_option(&self, option: AthenaOption, value: &str) -> Result<(), SetOptionError>; - fn execute( - &self, - host: Arc>>, - rev: u32, - msg: AthenaMessage, - code: &[u8], - ) -> ExecutionResult; -} - pub struct AthenaVm { client: ExecutionClient, } @@ -46,7 +34,7 @@ where fn execute( &self, host: Arc>>, - _rev: u32, + _rev: AthenaRevision, msg: AthenaMessage, // note: ignore _msg.code, should only be used on deploy code: &[u8], @@ -88,124 +76,20 @@ mod tests { use std::{cell::RefCell, sync::Arc}; use super::*; - use crate::host::MockHost; - use crate::VmInterface; - use athena_interface::{Address, AthenaMessage, Balance, MessageKind, StatusCode}; - - struct MockVm {} - - impl MockVm { - fn new() -> Self { - MockVm {} - } - } - - impl VmInterface for MockVm - where - T: HostInterface, - { - fn get_capabilities(&self) -> Vec { - vec![] - } - - fn set_option(&self, _option: AthenaOption, _value: &str) -> Result<(), SetOptionError> { - Err(SetOptionError::InvalidKey) - } - - fn execute( - &self, - host: Arc>>, - _rev: u32, - msg: AthenaMessage, - _code: &[u8], - ) -> ExecutionResult { - // process a few basic messages - - // save context and perform a call - - // restore context - - // get block hash - let output = host.borrow().get_block_hash(0); - - ExecutionResult::new( - StatusCode::Success, - msg.gas - 1, - Some(output.to_vec()), - None, - ) - } - } + use athena_interface::{Address, AthenaMessage, AthenaRevision, Balance, MessageKind, MockHost}; #[test] #[should_panic] fn test_empty_code() { // construct a mock host - let host = MockHost::new(None); + let host = MockHost::new(); let host_provider = HostProvider::new(host); let host_interface = Arc::new(RefCell::new(host_provider)); // construct a vm AthenaVm::new().execute( host_interface, - 0, - AthenaMessage::new( - MessageKind::Call, - 0, - 1000, - Address::default(), - Address::default(), - None, - Balance::default(), - vec![], - ), - &[], - ); - } - - // #[test] - // fn test_minimal_elf() { - // // construct a mock host - // let host = MockHost::new(None); - // let host_provider = HostProvider::new(host); - // let host_interface = Arc::new(RefCell::new(host_provider)); - - // // construct a vm - // let vm = AthenaVm::new(); - - // let execution_result = vm.execute( - // host_interface, - // 0, - // AthenaMessage::new( - // MessageKind::Call, - // 0, - // 1000, - // Address::default(), - // Address::default(), - // None, - // Balance::default(), - // vec![], - // ), - // include_bytes!("../../tests/minimal/elf/minimal-test.elf"), - // ); - // assert_eq!(execution_result.gas_left, 1000); - // assert_eq!(execution_result.status_code, StatusCode::Success); - // } - - #[test] - fn test_mock_vm() { - // construct a mock host - let host = MockHost::new(None); - let host_provider = HostProvider::new(host); - let host_interface = Arc::new(RefCell::new(host_provider)); - - // construct a mock vm - let vm = MockVm::new(); - - // test execution - vm.execute( - host_interface, - 0, + AthenaRevision::AthenaFrontier, AthenaMessage::new( MessageKind::Call, 0, diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 93ab4f19..9dcfd525 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -133,6 +133,21 @@ mod tests { .unwrap(); } + #[test] + fn test_recursive_call() { + utils::setup_logger(); + let client = ExecutionClient::new(); + let elf = include_bytes!("../../tests/recursive_call/elf/recursive-call-test"); + let mut stdin = AthenaStdin::new(); + stdin.write::(&10); + let host = Arc::new(RefCell::new(HostProvider::new(MockHost::new()))); + host.borrow_mut().deploy_code(ADDRESS_ALICE, elf); + let ctx = AthenaContext::new(ADDRESS_ALICE, ADDRESS_ALICE, 0); + client + .execute::(elf, stdin, Some(host), Some(1_000_000), Some(ctx)) + .unwrap(); + } + #[test] #[should_panic] fn test_execute_panic() { diff --git a/tests/host/src/main.rs b/tests/host/src/main.rs index ce12807c..dd61383c 100644 --- a/tests/host/src/main.rs +++ b/tests/host/src/main.rs @@ -1,7 +1,7 @@ #![no_main] athena_vm::entrypoint!(main); -use athena_vm::helpers::{address_to_32bit_words, address_to_bytes32, bytes32_to_32bit_words}; +use athena_vm::helpers::{address_to_32bit_words, bytes32_to_32bit_words}; use athena_vm::types::{ StorageStatus::StorageAdded, StorageStatus::StorageModified, ADDRESS_ALICE, ADDRESS_BOB, ADDRESS_CHARLIE, HELLO_WORLD, SOME_COINS, diff --git a/tests/recursive_call/elf/recursive-call-test b/tests/recursive_call/elf/recursive-call-test new file mode 100755 index 0000000000000000000000000000000000000000..19f1be1636a12514e4ec0955322c44784bf83e79 GIT binary patch literal 109876 zcmeFa3z$^pefa;LIhR@1mD}MaK^%8>7eZ7n3oIIw%qj!gSfjy(q_L6pFdzx;;$Bdb zG@0S->>6W@cm(oKQwzc_X_6-53Y#Wrv#Sg=>92_zfi_L!Wd-t2twDsvDzg92_dPRv z0ko#I{Xfs|DbI5_bIy4$-}ig}e&5S}DS6!@!!T6gUqrp8bNXZ~C^Oinz~J zF%?zQRf#HAj((PRhQ6NXSuQJo4Ynq~3^k6MT=HFwmN)#9MvG$lI+|5VE?eH`zaRZm z-u-z@U#BinO0J>xU;cqoFaI*8FIrJIa|v8h|Hea2E9B>y|MYiWno6zpemMB`Vt&dc z?Q7TuKmG5o|HZ)nV&H!<@V^-NUkv_jO0P>zs%;*-;Z4m0G3D z+a@m2_apiHQM1BU{vyg{ZRMpM%QZ6n@zOEMbtb5ItVeaV$5fC_zFE}~Q*PAxH`ht1 zz%kV3 z$1;X%^cVt{jL|G##JyDot>DIHysh9w!{|HjjI$>{5yJoE;qdPNPRhRxewXI)`cl5m z%esGX;B!?uD&3jOf!nn5UdjPS8aPh$2hLjMH6746?0wii?I)9znWcKamOE{hXQ`V6 ze#WrP78(k^HI2e?IjT$AU9=w@&|VfgzH}J8q*bt~qCk`9I*V%GLUH=E+w{qHjV1OsXKA-&lARmuEksr$m z`X9o_iDwIN3cbMZ>+u<5ocQ#N<66*7WWdfwTpPZ}A3c&zjEu)Jk$9;QiI;Iza82i$ z!F37OWkw`l$DxiD)=?v*e!#Qq7?JQ@dQ`rgl5eh~BAe;|NIHFyr|d!-r-py)zR;Tt zKgFt}W|XuSi79XGc5r3^Yma5pwqI6_elhHcrq&I=b?xK*@v^N2`~u%j z>h|S_OKX(9Z*P6aQ|OS4SALa;=x>gEsi)msc0c zA3eM6MA*han~E~@G0>(uE^YedhN`r8sm)63zkfM%Y?^=Ugo;mRT;=eRJ^qGx1#k?s z({0Ifo-QwR32(LLUX;7rmOK*J%MI572O%H)RP(E|=r@6b+!pkfEBJfz*SasG=X8Af z7!|L`pf5Klx5ZI{M;Uv*kKYvZU7mOUIe@2yzs!ni<*jH1zZQA}Ix)6zT&hAp#|*

qsdTg@$+SMxF!TWD=eT(ZmzfeKMH{zv~ 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 literal 0 HcmV?d00001 diff --git a/tests/recursive_call/src/main.rs b/tests/recursive_call/src/main.rs index df7010cf..a6e1a45f 100644 --- a/tests/recursive_call/src/main.rs +++ b/tests/recursive_call/src/main.rs @@ -1,11 +1,13 @@ #![no_main] athena_vm::entrypoint!(main); -use athena_vm::helpers::{address_to_32bit_words, address_to_bytes32, bytes32_to_32bit_words}; +use athena_vm::helpers::{address_to_32bit_words, bytes32_to_32bit_words}; use athena_vm::types::{ StorageStatus::StorageAdded, StorageStatus::StorageModified, ADDRESS_ALICE, HELLO_WORLD, }; +// Note: the test harness installs this contract code at ADDRESS_ALICE + // storage status is returned as a 256-bit value const STORAGE_ADDED: [u32; 8] = [StorageAdded as u32, 0, 0, 0, 0, 0, 0, 0]; const STORAGE_MODIFIED: [u32; 8] = [StorageModified as u32, 0, 0, 0, 0, 0, 0, 0]; @@ -17,7 +19,10 @@ fn return_value(value: u32) { let val: [u32; 8] = [value, 0, 0, 0, 0, 0, 0, 0]; let address = address_to_32bit_words(ADDRESS_ALICE); unsafe { athena_vm::host::write_storage(key.as_mut_ptr(), address.as_ptr(), val.as_ptr()) }; - assert_eq!(key, STORAGE_MODIFIED, "write_storage failed"); + assert!( + key == STORAGE_ADDED || key == STORAGE_MODIFIED, + "write_storage failed" + ); } fn recursive_call(value: u32) -> u32 { From 115581fafa354c66e5f42c893b94e9855ba2f32f Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 19 Jul 2024 13:56:19 -0700 Subject: [PATCH 12/14] All tests passing but the new one --- core/src/runtime/mod.rs | 2 +- interface/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/runtime/mod.rs b/core/src/runtime/mod.rs index 6baf0116..f5d02eb7 100644 --- a/core/src/runtime/mod.rs +++ b/core/src/runtime/mod.rs @@ -896,7 +896,7 @@ pub mod tests { let ctx = AthenaContext::new(Address::default(), Address::default(), 0); // we need a new host provider for each test to reset state - fn get_provider() -> Arc>> { + fn get_provider<'a>() -> Arc>>> { Arc::new(RefCell::new(HostProvider::new(MockHost::new()))) } diff --git a/interface/src/lib.rs b/interface/src/lib.rs index b6f2b2a4..6fd122fb 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -398,7 +398,7 @@ impl<'a> HostInterface for MockHost<'a> { } fn get_block_hash(&self, _block_height: i64) -> Bytes32 { - unimplemented!() + Bytes32::default() } fn call(&mut self, msg: AthenaMessage) -> ExecutionResult { @@ -554,7 +554,7 @@ mod tests { let value = [2; 32]; assert_eq!( host.set_storage(&address, &key, &value), - StorageStatus::StorageAssigned + StorageStatus::StorageAdded ); let retrieved_value = host.get_storage(&address, &key); assert_eq!(retrieved_value, value); From 2763d0e92ed5e36df77fbd8f96d72676d57531fd Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 19 Jul 2024 16:38:32 -0700 Subject: [PATCH 13/14] Recursive host test is working --- interface/Cargo.toml | 1 + interface/src/lib.rs | 104 ++++--------------- runner/src/vm.rs | 48 ++++++++- sdk/src/lib.rs | 15 --- tests/fibonacci/elf/fibonacci-test | Bin 107800 -> 108084 bytes tests/hint-io/elf/hint-io-test | Bin 143796 -> 144084 bytes tests/host/elf/host-test | Bin 98920 -> 99208 bytes tests/panic/elf/panic-test | Bin 71684 -> 71968 bytes tests/recursive_call/elf/recursive-call-test | Bin 109876 -> 131972 bytes tests/recursive_call/src/main.rs | 10 +- 10 files changed, 77 insertions(+), 101 deletions(-) diff --git a/interface/Cargo.toml b/interface/Cargo.toml index de4dd543..536d36a5 100644 --- a/interface/Cargo.toml +++ b/interface/Cargo.toml @@ -9,3 +9,4 @@ edition.workspace = true [dependencies] bytemuck = "1.16.0" +log = "0.4.21" diff --git a/interface/src/lib.rs b/interface/src/lib.rs index 6fd122fb..a24600c2 100644 --- a/interface/src/lib.rs +++ b/interface/src/lib.rs @@ -310,7 +310,7 @@ where // when running the VM in standalone mode, without a bound host interface pub struct MockHost<'a> { // VM instance - vm: MockVm, + vm: Option<&'a dyn VmInterface>>, // stores state keyed by address and key storage: BTreeMap<(Address, Bytes32), Bytes32>, @@ -327,6 +327,13 @@ impl<'a> MockHost<'a> { MockHost::default() } + pub fn new_with_vm(vm: &'a dyn VmInterface>) -> Self { + MockHost { + vm: Some(vm), + ..MockHost::default() + } + } + pub fn deploy_code(&mut self, address: Address, code: &'a [u8]) { self.programs.insert(address, code); } @@ -345,9 +352,6 @@ pub const HELLO_WORLD: Bytes32 = [ impl<'a> Default for MockHost<'a> { fn default() -> Self { - // instantiate a mock VM - let vm = MockVm::new(); - // init let mut storage = BTreeMap::new(); let mut balance = BTreeMap::new(); @@ -360,7 +364,7 @@ impl<'a> Default for MockHost<'a> { storage.insert((ADDRESS_ALICE, HELLO_WORLD), HELLO_WORLD); Self { - vm, + vm: None, storage, balance, programs, @@ -402,6 +406,13 @@ impl<'a> HostInterface for MockHost<'a> { } fn call(&mut self, msg: AthenaMessage) -> ExecutionResult { + log::info!("MockHost::call:depth {} :: {:?}", msg.depth, msg); + + // don't go too deep! + if msg.depth > 10 { + return ExecutionResult::new(StatusCode::CallDepthExceeded, 0, None, None); + } + // check programs list first if let Some(code) = self.programs.get(&msg.recipient).cloned() { // create an owned, cloned copy of VM before taking the host from self @@ -410,7 +421,12 @@ impl<'a> HostInterface for MockHost<'a> { // HostProvider requires an owned instance, so we need to take it from self let provider = HostProvider::new(std::mem::take(self)); let host = Arc::new(RefCell::new(provider)); - let res = vm.execute(host.clone(), AthenaRevision::AthenaFrontier, msg, code); + let res = vm.expect("missing VM instance").execute( + host.clone(), + AthenaRevision::AthenaFrontier, + msg, + code, + ); // Restore self *self = Arc::try_unwrap(host) @@ -466,85 +482,9 @@ pub trait VmInterface { ) -> ExecutionResult; } -// a very simple mock VM implementation -#[derive(Clone)] -struct MockVm {} - -impl MockVm { - fn new() -> Self { - MockVm {} - } -} - -impl VmInterface for MockVm -where - T: HostInterface, -{ - fn get_capabilities(&self) -> Vec { - vec![] - } - - fn set_option(&self, _option: AthenaOption, _value: &str) -> Result<(), SetOptionError> { - Err(SetOptionError::InvalidKey) - } - - fn execute( - &self, - host: Arc>>, - _rev: AthenaRevision, - msg: AthenaMessage, - _code: &[u8], - ) -> ExecutionResult { - // process a few basic messages - - // save context and perform a call - - // restore context - - // get block hash - let output = host.borrow().get_block_hash(0); - - ExecutionResult::new( - StatusCode::Success, - msg.gas - 1, - Some(output.to_vec()), - None, - ) - } -} - #[cfg(test)] mod tests { use super::*; - use std::{cell::RefCell, sync::Arc}; - - #[test] - fn test_mock_vm() { - // construct a mock host - let host = MockHost::new(); - let host_provider = HostProvider::new(host); - let host_interface = Arc::new(RefCell::new(host_provider)); - - // construct a mock vm - let vm = MockVm::new(); - - // test execution - vm.execute( - host_interface, - AthenaRevision::AthenaFrontier, - AthenaMessage::new( - MessageKind::Call, - 0, - 1000, - Address::default(), - Address::default(), - None, - Balance::default(), - vec![], - ), - &[], - ); - } #[test] fn test_get_storage() { diff --git a/runner/src/vm.rs b/runner/src/vm.rs index 57b83651..6d48049a 100644 --- a/runner/src/vm.rs +++ b/runner/src/vm.rs @@ -49,7 +49,6 @@ where stdin.write_vec(input_data); } - // let (output, gas_left) = self match self .client .execute(&code, stdin, Some(host), Some(msg.gas), Some(context)) @@ -76,7 +75,10 @@ mod tests { use std::{cell::RefCell, sync::Arc}; use super::*; - use athena_interface::{Address, AthenaMessage, AthenaRevision, Balance, MessageKind, MockHost}; + use athena_interface::{ + Address, AthenaMessage, AthenaRevision, Balance, MessageKind, MockHost, ADDRESS_ALICE, + }; + use athena_sdk::utils; #[test] #[should_panic] @@ -103,4 +105,46 @@ mod tests { &[], ); } + + // Note: we run this test here, as opposed to at a lower level (inside the SDK), since recursive host calls + // require access to an actual VM instance. + #[test] + fn test_recursive_call() { + utils::setup_logger(); + let client = ExecutionClient::new(); + let elf = include_bytes!("../../tests/recursive_call/elf/recursive-call-test"); + let mut stdin = AthenaStdin::new(); + stdin.write::(&8); + let vm = AthenaVm::new(); + let host = Arc::new(RefCell::new(HostProvider::new(MockHost::new_with_vm(&vm)))); + host.borrow_mut().deploy_code(ADDRESS_ALICE, elf); + let ctx = AthenaContext::new(ADDRESS_ALICE, ADDRESS_ALICE, 0); + let (mut output, _) = client + .execute::( + elf, + stdin, + Some(host.clone()), + Some(1_000_000), + Some(ctx.clone()), + ) + .unwrap(); + let result = output.read::(); + assert_eq!(result, 21, "got wrong fibonacci value"); + + // trying to go any higher should result in an out-of-gas error + let mut stdin = AthenaStdin::new(); + stdin.write::(&9); + let res = client.execute::( + elf, + stdin, + Some(host.clone()), + Some(1_000_000), + Some(ctx.clone()), + ); + match res { + Ok(_) => panic!("expected out-of-gas error"), + Err(ExecutionError::HostCallFailed(StatusCode::OutOfGas)) => (), + Err(_) => panic!("expected out-of-gas error"), + } + } } diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 9dcfd525..93ab4f19 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -133,21 +133,6 @@ mod tests { .unwrap(); } - #[test] - fn test_recursive_call() { - utils::setup_logger(); - let client = ExecutionClient::new(); - let elf = include_bytes!("../../tests/recursive_call/elf/recursive-call-test"); - let mut stdin = AthenaStdin::new(); - stdin.write::(&10); - let host = Arc::new(RefCell::new(HostProvider::new(MockHost::new()))); - host.borrow_mut().deploy_code(ADDRESS_ALICE, elf); - let ctx = AthenaContext::new(ADDRESS_ALICE, ADDRESS_ALICE, 0); - client - .execute::(elf, stdin, Some(host), Some(1_000_000), Some(ctx)) - .unwrap(); - } - #[test] #[should_panic] fn test_execute_panic() { diff --git a/tests/fibonacci/elf/fibonacci-test b/tests/fibonacci/elf/fibonacci-test index c9de47f884e751aed51443a2802d5dcc2c0ad28a..595d907f555e8b6b11f2b89695a2f66310e11b1d 100755 GIT binary patch delta 17591 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 JxLhUL{{RZ7%KiWV delta 17308 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 MLdZqK^>4QS1sjN-WdHyG diff --git a/tests/hint-io/elf/hint-io-test b/tests/hint-io/elf/hint-io-test index bb8a32fe0f8901c63a5eeabae0a94ec15f5302a1..9bb6b323d6ec0db95ba860035bcb679866b2bb32 100755 GIT binary patch delta 24829 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 ZLe+i$YRDIOT{&5UD)DZOulBkc{x4E2KU@F+ delta 24550 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 O8oUY2TmBEnoY(OH diff --git a/tests/host/elf/host-test b/tests/host/elf/host-test index 6703dcdd37160d7eb7f5c367b732ba39b406021a..ccc81e61b4af1d4c08937d24117843bd6a3bbd75 100755 GIT binary patch delta 17317 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 delta 17019 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 delta 40950 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 aTseL5lN!RL1SY*!0mJv8FqNomO8*ZYI=c@5 diff --git a/tests/recursive_call/src/main.rs b/tests/recursive_call/src/main.rs index a6e1a45f..f94f621a 100644 --- a/tests/recursive_call/src/main.rs +++ b/tests/recursive_call/src/main.rs @@ -15,6 +15,7 @@ const STORAGE_MODIFIED: [u32; 8] = [StorageModified as u32, 0, 0, 0, 0, 0, 0, 0] // emulate a return value by writing the return value to storage. // Athena doesn't support return values yet. fn return_value(value: u32) { + println!("Returning {}", value); let mut key = bytes32_to_32bit_words(HELLO_WORLD); let val: [u32; 8] = [value, 0, 0, 0, 0, 0, 0, 0]; let address = address_to_32bit_words(ADDRESS_ALICE); @@ -23,13 +24,14 @@ fn return_value(value: u32) { key == STORAGE_ADDED || key == STORAGE_MODIFIED, "write_storage failed" ); + athena_vm::io::write::(&value); } fn recursive_call(value: u32) -> u32 { // we need a pointer to the value as an array - let val: [u32; 1] = [value]; + let val: [u32; 4] = [value, 0, 0, 0]; let address = address_to_32bit_words(ADDRESS_ALICE); - unsafe { athena_vm::host::call(address.as_ptr(), val.as_ptr(), 1) }; + unsafe { athena_vm::host::call(address.as_ptr(), val.as_ptr(), 4) }; // read the return value let mut key = bytes32_to_32bit_words(HELLO_WORLD); @@ -43,6 +45,8 @@ pub fn main() { // Behind the scenes, this compiles down to a custom system call which handles reading inputs. let n = athena_vm::io::read::(); + println!("Calculating the {}th Fibonacci number", n); + // Base case if n <= 1 { return_value(n); @@ -51,6 +55,8 @@ pub fn main() { // Recursive case let a = recursive_call(n - 1); + println!("Got {} for n - 1", a); let b = recursive_call(n - 2); + println!("Got {} for n - 2", b); return_value(a + b); } From 0ee47af3f33ae82c667031ac79e3d891d90631cd Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 19 Jul 2024 16:50:23 -0700 Subject: [PATCH 14/14] Add stack depth test --- runner/src/vm.rs | 18 ++++++++++++++++++ tests/stack_depth/Cargo.toml | 8 ++++++++ tests/stack_depth/elf/stack-depth-test | Bin 0 -> 68800 bytes tests/stack_depth/src/main.rs | 13 +++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 tests/stack_depth/Cargo.toml create mode 100755 tests/stack_depth/elf/stack-depth-test create mode 100644 tests/stack_depth/src/main.rs diff --git a/runner/src/vm.rs b/runner/src/vm.rs index 6d48049a..ec4f53c2 100644 --- a/runner/src/vm.rs +++ b/runner/src/vm.rs @@ -147,4 +147,22 @@ mod tests { Err(_) => panic!("expected out-of-gas error"), } } + + #[test] + fn test_stack_depth() { + utils::setup_logger(); + let client = ExecutionClient::new(); + let elf = include_bytes!("../../tests/stack_depth/elf/stack-depth-test"); + let stdin = AthenaStdin::new(); + let vm = AthenaVm::new(); + let host = Arc::new(RefCell::new(HostProvider::new(MockHost::new_with_vm(&vm)))); + host.borrow_mut().deploy_code(ADDRESS_ALICE, elf); + let ctx = AthenaContext::new(ADDRESS_ALICE, ADDRESS_ALICE, 0); + let res = client.execute::(elf, stdin, Some(host), Some(1_000_000), Some(ctx)); + match res { + Ok(_) => panic!("expected stack depth error"), + Err(ExecutionError::HostCallFailed(StatusCode::CallDepthExceeded)) => (), + Err(_) => panic!("expected stack depth error"), + } + } } diff --git a/tests/stack_depth/Cargo.toml b/tests/stack_depth/Cargo.toml new file mode 100644 index 00000000..8aa1065f --- /dev/null +++ b/tests/stack_depth/Cargo.toml @@ -0,0 +1,8 @@ +[workspace] +[package] +name = "stack-depth-test" +version = "0.1.0" +edition = "2021" + +[dependencies] +athena-vm = { path = "../../vm/entrypoint", features = ["rv32e"] } diff --git a/tests/stack_depth/elf/stack-depth-test b/tests/stack_depth/elf/stack-depth-test new file mode 100755 index 0000000000000000000000000000000000000000..4f6e157b9f8e904eb1c33f0c259ab631a4259b5b GIT binary patch literal 68800 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 X;eD)6x_