mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
runtime: State update apply
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::Nullifier,
|
||||
initialize, entrypoint, update_state,
|
||||
entrypoint,
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
initialize, msg,
|
||||
pasta::pallas,
|
||||
state::{set_update, nullifier_exists},
|
||||
state::{nullifier_exists, set_update},
|
||||
update_state,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, SerialDecodable, SerialEncodable};
|
||||
|
||||
@@ -41,7 +42,7 @@ pub struct BarArgs {
|
||||
#[derive(SerialEncodable, SerialDecodable)]
|
||||
pub struct FooUpdate {
|
||||
pub name: String,
|
||||
pub y: u32
|
||||
pub y: u32,
|
||||
}
|
||||
|
||||
initialize!(init_contract);
|
||||
@@ -68,10 +69,7 @@ fn process_instruction(ix: &[u8]) -> ContractResult {
|
||||
// ...
|
||||
let args: FooArgs = deserialize(tx_data)?;
|
||||
// ...
|
||||
let update = FooUpdate {
|
||||
name: "john_doe".to_string(),
|
||||
y: 110
|
||||
};
|
||||
let update = FooUpdate { name: "john_doe".to_string(), y: 110 };
|
||||
|
||||
let mut update_data = vec![Function::Foo as u8];
|
||||
update_data.extend_from_slice(&serialize(&update));
|
||||
@@ -115,20 +113,16 @@ fn process_instruction(ix: &[u8]) -> ContractResult {
|
||||
}
|
||||
|
||||
update_state!(process_update);
|
||||
fn process_update() -> ContractResult {
|
||||
fn process_update(update_data: &[u8]) -> ContractResult {
|
||||
msg!("Make update!");
|
||||
|
||||
/*
|
||||
let (func_id, update_data) = get_update()?;
|
||||
|
||||
match Function::from(func_id) {
|
||||
match Function::from(update_data[0]) {
|
||||
Function::Foo => {
|
||||
let update: FooUpdate = deserialize(update_data)?;
|
||||
let update: FooUpdate = deserialize(&update_data[1..])?;
|
||||
// update.apply()
|
||||
}
|
||||
_ => unreachable!()
|
||||
};
|
||||
*/
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -140,4 +134,3 @@ fn process_update() -> ContractResult {
|
||||
//fn apply(update) {
|
||||
// // writes happen here
|
||||
//}
|
||||
|
||||
|
||||
@@ -65,9 +65,9 @@ fn run_contract() -> Result<()> {
|
||||
// ============================================================
|
||||
// Serialize the payload into the runtime format and execute it
|
||||
// ============================================================
|
||||
//let update = runtime.exec(&serialize_payload(&payload))?;
|
||||
runtime.exec(&serialize_payload(&payload))?;
|
||||
|
||||
//runtime.apply(update);
|
||||
runtime.apply()?;
|
||||
//Ok(())
|
||||
|
||||
//runtime.exec(&serialize_payload(&payload))?;
|
||||
@@ -76,4 +76,3 @@ fn run_contract() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use super::{
|
||||
};
|
||||
use crate::node::state::ProgramState;
|
||||
|
||||
pub(crate) fn set_update(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i32 {
|
||||
pub(super) fn set_update(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i32 {
|
||||
let env = ctx.data();
|
||||
match env.contract_section {
|
||||
ContractSection::Exec => {
|
||||
@@ -35,7 +35,7 @@ pub(crate) fn set_update(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u3
|
||||
// FIXME: make me preettty!
|
||||
let slice = ptr.slice(&memory_view, len);
|
||||
if slice.is_err() {
|
||||
return -2;
|
||||
return -2
|
||||
}
|
||||
let slice = slice.unwrap();
|
||||
|
||||
@@ -53,36 +53,21 @@ pub(crate) fn set_update(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u3
|
||||
};
|
||||
//
|
||||
|
||||
// FIXME: Shouldn't assert here, but rather return an error.
|
||||
// An assert would make the host panic.
|
||||
assert!(env.contract_update.take().is_none());
|
||||
let func_id = update_data[0];
|
||||
let update_data = &update_data[1..];
|
||||
env.contract_update.set(Some((func_id, update_data.to_vec())));
|
||||
0
|
||||
}
|
||||
_ => {
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_update(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i32 {
|
||||
let env = ctx.data();
|
||||
match env.contract_section {
|
||||
ContractSection::Update => {
|
||||
let memory_view = env.memory_view(&ctx);
|
||||
|
||||
|
||||
|
||||
0
|
||||
|
||||
}
|
||||
_ => { -1 }
|
||||
_ => -1,
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to read a `Nullifier` from the given pointer and check if it's
|
||||
/// an existing nullifier in the blockchain state machine.
|
||||
pub fn nullifier_exists(mut ctx: FunctionEnvMut<Env>, ptr: u32, len: u32) -> i32 {
|
||||
pub(super) fn nullifier_exists(mut ctx: FunctionEnvMut<Env>, ptr: u32, len: u32) -> i32 {
|
||||
let env = ctx.data();
|
||||
match env.contract_section {
|
||||
ContractSection::Null => {
|
||||
@@ -127,7 +112,7 @@ pub fn nullifier_exists(mut ctx: FunctionEnvMut<Env>, ptr: u32, len: u32) -> i32
|
||||
|
||||
/// Try to read a `MerkleNode` from the given pointer and check if it's
|
||||
/// a valid Merkle root in the chain's Merkle tree.
|
||||
pub fn is_valid_merkle(mut ctx: FunctionEnvMut<Env>, ptr: u32, len: u32) -> i32 {
|
||||
pub(super) fn is_valid_merkle(mut ctx: FunctionEnvMut<Env>, ptr: u32, len: u32) -> i32 {
|
||||
/*
|
||||
if let Some(bytes) = env.memory.get_ref().unwrap().read(ptr, len as usize) {
|
||||
debug!(target: "wasm_runtime::is_valid_merkle", "Read bytes: {:?}", bytes);
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
sync::{Arc, Mutex},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use darkfi_sdk::entrypoint;
|
||||
use log::{debug, info};
|
||||
use wasmer::{
|
||||
imports, wasmparser::Operator, AsStoreRef, CompilerConfig, Function, FunctionEnv, Instance,
|
||||
Memory, MemoryView, Module, Pages, Store, Value, WasmPtr, WASM_PAGE_SIZE,
|
||||
Memory, MemoryView, Module, Pages, Store, Value, WASM_PAGE_SIZE,
|
||||
};
|
||||
use wasmer_compiler_singlepass::Singlepass;
|
||||
use wasmer_middlewares::{
|
||||
@@ -34,9 +34,9 @@ use wasmer_middlewares::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
chain_state::{set_update, is_valid_merkle, nullifier_exists},
|
||||
chain_state::{is_valid_merkle, nullifier_exists, set_update},
|
||||
memory::MemoryManipulation,
|
||||
util::drk_log,
|
||||
util::{drk_log, serialize_payload},
|
||||
};
|
||||
use crate::{crypto::contract_id::ContractId, Error, Result};
|
||||
|
||||
@@ -260,10 +260,23 @@ impl Runtime {
|
||||
env_mut.contract_section = ContractSection::Update;
|
||||
|
||||
debug!(target: "wasm_runtime::run", "Getting initialize function");
|
||||
let entrypoint = self.instance.exports.get_function(INITIALIZE)?;
|
||||
let entrypoint = self.instance.exports.get_function(UPDATE)?;
|
||||
|
||||
let update_data = env_mut.contract_update.take().unwrap();
|
||||
// FIXME: Less realloc
|
||||
let mut payload = vec![update_data.0];
|
||||
payload.extend_from_slice(&update_data.1);
|
||||
let payload = serialize_payload(&payload);
|
||||
|
||||
// TODO: Test if this works when state update is larger than the initial payload
|
||||
// The question is if we need to allocate more memory or if it's ok to just
|
||||
// overwrite from zero (and even if overwrite - is there enough space?)
|
||||
let pages_required = payload.len() / WASM_PAGE_SIZE + 1;
|
||||
//self.set_memory_page_size(pages_required as u32)?;
|
||||
self.copy_to_memory(&payload)?;
|
||||
|
||||
debug!(target: "wasm_runtime::run", "Executing wasm");
|
||||
let ret = match entrypoint.call(&mut self.store, &[]) {
|
||||
let ret = match entrypoint.call(&mut self.store, &[Value::I32(0 as i32)]) {
|
||||
Ok(retvals) => {
|
||||
self.print_logs();
|
||||
debug!(target: "wasm_runtime::run", "{}", self.gas_info());
|
||||
@@ -331,6 +344,7 @@ impl Runtime {
|
||||
|
||||
/// Copy payload to the start of the memory
|
||||
fn copy_to_memory(&self, payload: &[u8]) -> Result<()> {
|
||||
// TODO: Maybe should write to first zero memory and return the pointer/offset?
|
||||
// Get the memory view
|
||||
let env = self.ctx.as_ref(&self.store);
|
||||
let memory_view = env.memory_view(&self.store);
|
||||
|
||||
@@ -61,8 +61,10 @@ macro_rules! update_state {
|
||||
($process_update:ident) => {
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __update() -> u64 {
|
||||
match $process_update() {
|
||||
pub unsafe extern "C" fn __update(input: *mut u8) -> u64 {
|
||||
let update_data = $crate::entrypoint::deserialize(input);
|
||||
|
||||
match $process_update(&update_data) {
|
||||
Ok(()) => $crate::entrypoint::SUCCESS,
|
||||
Err(e) => e.into(),
|
||||
}
|
||||
|
||||
@@ -35,18 +35,6 @@ pub fn set_update(update_data: &[u8]) -> Result<(), ContractError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn get_update() -> Result<(u8, Vec<u8>), ContractError> {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
// get_update_ needs to take a buffer?
|
||||
// get pointer for contract_update
|
||||
// piece back into (u8, Vec<u8>)
|
||||
// return
|
||||
return Ok((0, vec![]));
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn nullifier_exists(nullifier: &Nullifier) -> Result<bool, ContractError> {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user