general cleanup and re-enabling of earlier disabled features.

This commit is contained in:
x
2022-10-30 07:09:02 +00:00
committed by parazyd
parent e5ca71bd4b
commit a0c61641cf
6 changed files with 32 additions and 61 deletions

View File

@@ -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

View File

@@ -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
// ====================

View File

@@ -16,42 +16,27 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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<u8, Array> = WasmPtr::new(mem_offset);
let ptr: WasmPtr<u8> = 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
/*

View File

@@ -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<Env>, ptr: WasmPtr<u8>, 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");
}
}
}

View File

@@ -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<Vec<String>>,
/// Direct memory access to the VM
pub memory: Option<Memory>,
/// Cloned state machine living in memory
pub state_machine: Arc<MemoryState>,
/// State updates produced by the contract
pub state_updates: Arc<Mutex<Vec<StateUpdate>>>,
}
impl Env {
@@ -86,8 +79,6 @@ pub struct ExecutionResult {
pub exitcode: u8,
/// Logs written from the wasm program
pub logs: Vec<String>,
/// State machine updates produced by the wasm program
pub state_updates: Vec<StateUpdate>,
}
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<Self> {
pub fn new(wasm_bytes: &[u8]) -> Result<Self> {
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<u8> = 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)
}
}

View File

@@ -53,4 +53,3 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> &'a [u8] {
instruction_data
}