diff --git a/example/smart-contract/tests/runtime.rs b/example/smart-contract/tests/runtime.rs
index 54f3be769..1c7d28d17 100644
--- a/example/smart-contract/tests/runtime.rs
+++ b/example/smart-contract/tests/runtime.rs
@@ -17,7 +17,6 @@
*/
use darkfi::{
- node::{MemoryState, State},
runtime::{util::serialize_payload, vm_runtime::Runtime},
Result,
};
@@ -41,16 +40,16 @@ fn run_contract() -> Result<()> {
// =============================================================
// Build a ledger state so the runtime has something to work on
// =============================================================
- let state_machine = State::dummy()?;
+ //let state_machine = State::dummy()?;
// Add a nullifier to the nullifier set. (This is checked by the contract)
- state_machine.nullifiers.insert(&[Nullifier::from(pallas::Base::from(0x10))])?;
+ //state_machine.nullifiers.insert(&[Nullifier::from(pallas::Base::from(0x10))])?;
// ================================================================
// Load the wasm binary into memory and create an execution runtime
// ================================================================
let wasm_bytes = std::fs::read("contract.wasm")?;
- let mut runtime = Runtime::new(&wasm_bytes, MemoryState::new(state_machine))?;
+ let mut runtime = Runtime::new(&wasm_bytes)?;
// =============================================
// Build some kind of payload to show an example
diff --git a/src/error.rs b/src/error.rs
index 9498b25d8..73bdca4cd 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -286,10 +286,18 @@ pub enum Error {
#[error("Wasmer instantiation error: {0}")]
WasmerInstantiationError(String),
+ #[cfg(feature = "wasm-runtime")]
+ #[error("wasm memory error")]
+ WasmerMemoryError,
+
#[cfg(feature = "wasm-runtime")]
#[error("wasm runtime out of memory")]
WasmerOomError,
+ #[cfg(feature = "wasm-runtime")]
+ #[error("contract execution error")]
+ ContractExecError(u64),
+
// ====================
// Miscellaneous errors
// ====================
diff --git a/src/runtime/memory.rs b/src/runtime/memory.rs
index 2f0dab0a6..6d65ab3c8 100644
--- a/src/runtime/memory.rs
+++ b/src/runtime/memory.rs
@@ -16,42 +16,27 @@
* along with this program. If not, see .
*/
-use wasmer::{Memory, WasmPtr};
+use wasmer::{MemoryView, WasmPtr};
use crate::{Error, Result};
pub trait MemoryManipulation {
- fn write(&self, mem_offset: u32, value_slice: &[u8]) -> Result<()>;
- fn read(&self, mem_offset: u32, value_len: usize) -> Option<&[u8]>;
+ fn write_slice(&self, value_slice: &[u8], mem_offset: u32) -> Result<()>;
+ fn read_slice(&self, value_len: usize, mem_offset: u32) -> Option<&[u8]>;
}
-impl MemoryManipulation for Memory {
- fn write(&self, mem_offset: u32, value_slice: &[u8]) -> Result<()> {
- // DISABLED
- /*
+impl<'a> MemoryManipulation for MemoryView<'a> {
+ fn write_slice(&self, value_slice: &[u8], mem_offset: u32) -> Result<()> {
// Prepare WasmPtr
- let target_ptr: WasmPtr = WasmPtr::new(mem_offset);
+ let ptr: WasmPtr = WasmPtr::new(mem_offset);
- // Allocate necessary memory space on guest
- let guest_value_slice = match target_ptr.deref(self, 0, value_slice.len() as u32) {
- Some(slice) => slice,
- None => [].to_vec(),
- };
+ // Write to the slice
+ let slice = ptr.slice(self, value_slice.len() as u32).map_err(|_| Error::WasmerOomError)?;
- if guest_value_slice.is_empty() {
- return Err(Error::WasmerOomError)
- }
-
- // Copy bytes to guest
- for i in 0..value_slice.len() {
- guest_value_slice[i].set(value_slice[i]);
- }
- */
-
- Ok(())
+ slice.write_slice(value_slice).map_err(|_| Error::WasmerOomError)
}
- fn read(&self, mem_offset: u32, value_len: usize) -> Option<&[u8]> {
+ fn read_slice(&self, value_len: usize, mem_offset: u32) -> Option<&[u8]> {
// TODO: use data_size() ?
// DISABLED
/*
diff --git a/src/runtime/util.rs b/src/runtime/util.rs
index 322ac6dd9..52bb04134 100644
--- a/src/runtime/util.rs
+++ b/src/runtime/util.rs
@@ -17,7 +17,7 @@
*/
use log::{error, warn};
-use wasmer::{FunctionEnvMut, AsStoreRef, WasmPtr};
+use wasmer::{AsStoreRef, FunctionEnvMut, WasmPtr};
use super::{memory::MemoryManipulation, vm_runtime::Env};
@@ -45,10 +45,9 @@ pub(crate) fn drk_log(mut ctx: FunctionEnvMut, ptr: WasmPtr, len: u32)
let mut logs = env.logs.borrow_mut();
logs.push(msg);
std::mem::drop(logs);
- },
+ }
Err(_) => {
error!(target: "wasm_runtime::drk_log", "Failed to read UTF-8 string from VM memory");
}
}
}
-
diff --git a/src/runtime/vm_runtime.rs b/src/runtime/vm_runtime.rs
index 12e3ab775..00f37489d 100644
--- a/src/runtime/vm_runtime.rs
+++ b/src/runtime/vm_runtime.rs
@@ -38,10 +38,7 @@ use super::{
memory::MemoryManipulation,
util::drk_log,
};
-use crate::{
- node::{state::StateUpdate, MemoryState},
- Result,
-};
+use crate::{Error, Result};
/// Name of the wasm linear memory in our guest module
const MEMORY: &str = "memory";
@@ -56,10 +53,6 @@ pub struct Env {
pub logs: RefCell>,
/// Direct memory access to the VM
pub memory: Option,
- /// Cloned state machine living in memory
- pub state_machine: Arc,
- /// State updates produced by the contract
- pub state_updates: Arc>>,
}
impl Env {
@@ -86,8 +79,6 @@ pub struct ExecutionResult {
pub exitcode: u8,
/// Logs written from the wasm program
pub logs: Vec,
- /// State machine updates produced by the wasm program
- pub state_updates: Vec,
}
pub struct Runtime {
@@ -98,7 +89,7 @@ pub struct Runtime {
impl Runtime {
/// Create a new wasm runtime instance that contains the given wasm module.
- pub fn new(wasm_bytes: &[u8], state_machine: MemoryState) -> Result {
+ pub fn new(wasm_bytes: &[u8]) -> Result {
info!(target: "warm_runtime::new", "Instantiating a new runtime");
// This function will be called for each `Operator` encountered during
// the wasm module execution. It should return the cost of the operator
@@ -129,11 +120,8 @@ impl Runtime {
// This section will need changing
debug!(target: "wasm_runtime::new", "Importing functions");
let logs = RefCell::new(vec![]);
- let state_machine = Arc::new(state_machine);
- let state_updates = Arc::new(Mutex::new(vec![]));
- let ctx =
- FunctionEnv::new(&mut store, Env { logs, memory: None, state_machine, state_updates });
+ let ctx = FunctionEnv::new(&mut store, Env { logs, memory: None });
let imports = imports! {
"env" => {
@@ -169,7 +157,7 @@ impl Runtime {
/// Run the hardcoded `ENTRYPOINT` function with the given payload as input.
pub fn run(&mut self, payload: &[u8]) -> Result<()> {
let pages_required = payload.len() / WASM_PAGE_SIZE + 1;
- self.set_memory_page_size(pages_required as u32);
+ self.set_memory_page_size(pages_required as u32)?;
self.copy_to_memory(payload)?;
@@ -200,8 +188,7 @@ impl Runtime {
match retval {
entrypoint::SUCCESS => Ok(()),
- // _ => Err(ContractError(retval)),
- _ => todo!(),
+ _ => Err(Error::ContractExecError(retval)),
}
}
@@ -226,13 +213,14 @@ impl Runtime {
}
/// Set the memory page size
- fn set_memory_page_size(&mut self, pages: u32) {
+ fn set_memory_page_size(&mut self, pages: u32) -> Result<()> {
// Grab memory by value
let memory = self.take_memory();
// Modify the memory
- memory.grow(&mut self.store, Pages(pages));
+ memory.grow(&mut self.store, Pages(pages)).map_err(|_| Error::WasmerMemoryError)?;
// Replace the memory back again
self.ctx.as_mut(&mut self.store).memory = Some(memory);
+ Ok(())
}
/// Take Memory by value. Needed to modify the Memory object
/// Will panic if memory isn't set.
@@ -247,13 +235,6 @@ impl Runtime {
// Get the memory view
let env = self.ctx.as_ref(&self.store);
let memory_view = env.memory_view(&self.store);
-
- // Pointer to offset 0
- let ptr: WasmPtr = WasmPtr::new(0);
-
- // Write to the slice
- let slice = ptr.slice(&memory_view, payload.len() as u32).expect("FIXME FIXME FIXME");
- slice.write_slice(payload).expect("FIXME FIXME FIXME");
- Ok(())
+ memory_view.write_slice(payload, 0)
}
}
diff --git a/src/sdk/src/entrypoint.rs b/src/sdk/src/entrypoint.rs
index d5730edde..9cbc66add 100644
--- a/src/sdk/src/entrypoint.rs
+++ b/src/sdk/src/entrypoint.rs
@@ -53,4 +53,3 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> &'a [u8] {
instruction_data
}
-