Skip to content

Commit

Permalink
Make delete return the old data
Browse files Browse the repository at this point in the history
  • Loading branch information
richardpringle committed May 6, 2024
1 parent f002156 commit ae8d85c
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 23 deletions.
10 changes: 9 additions & 1 deletion x/programs/cmd/simulator/cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,15 @@ func runStepFunc(

return nil
}
id, _, balance, err := programExecuteFunc(ctx, log, db, params, method, maxUnits)
id, response, balance, err := programExecuteFunc(ctx, log, db, params, method, maxUnits)
if err != nil {
return err
}
resp.setResponse(response)
ok, err := validateAssertion(response[0], require)
if !ok {
return fmt.Errorf("%w", ErrResultAssertionFailed)
}
if err != nil {
return err
}
Expand Down
42 changes: 39 additions & 3 deletions x/programs/examples/imports/pstate/pstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,45 @@ func (i *Import) deleteFn(caller *program.Caller, memOffset int32, size int32) (
}

k := storage.ProgramPrefixKey(args.ProgramID[:], args.Key)
bytes, err = i.mu.GetValue(context.Background(), k)
if err != nil {
if errors.Is(err, database.ErrNotFound) {
val, err := program.WriteBytes(memory, []byte{0})
if err != nil {
i.log.Error("failed to write to memory",
zap.Error(err),
)
return nil, err
}

return types.ValI32(int32(val)), nil
}

i.log.Error("failed to get value from storage",
zap.Error(err),
)
return nil, err
}

// prepend 1 to val
bytes = append([]byte{1}, bytes...)

ptr, err := program.WriteBytes(memory, bytes)
if err != nil {
{
i.log.Error("failed to write to memory",
zap.Error(err),
)
}
return nil, err
}

if err := i.mu.Remove(context.Background(), k); err != nil {
i.log.Error("failed to remove from storage", zap.Error(err))
return types.ValI32(-1), nil
i.log.Error("failed to delete value from storage",
zap.Error(err),
)
return nil, err
}
return types.ValI32(0), nil

return types.ValI32(int32(ptr)), nil
}
15 changes: 9 additions & 6 deletions x/programs/rust/examples/token/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ pub fn mint_to(context: Context, recipient: Address, amount: i64) -> bool {

/// Burn the token from the recipient.
#[public]
pub fn burn_from(context: Context, recipient: Address) -> bool {
pub fn burn_from(context: Context, recipient: Address) -> i64 {
let Context { program } = context;
program
.state()
.delete(StateKey::Balance(recipient))
.expect("failed to burn recipient tokens");
true
.delete::<i64>(StateKey::Balance(recipient))
.expect("failed to burn recipient tokens")
.expect("recipient balance not found")
}

/// Transfers balance from the sender to the the recipient.
Expand Down Expand Up @@ -184,6 +184,7 @@ mod tests {
.map(Param::Key);
let alice_initial_balance = 1000;
let transfer_amount = 100;
let post_transfer_balance = alice_initial_balance - transfer_amount;

let mut plan = Plan::new(owner_key_id.clone());

Expand Down Expand Up @@ -262,7 +263,7 @@ mod tests {
max_units: 0,
params: vec![program_id.into(), alice_key.clone()],
require: Some(Require {
result: ResultAssertion::NumericEq(alice_initial_balance - transfer_amount),
result: ResultAssertion::NumericEq(post_transfer_balance),
}),
});

Expand All @@ -281,7 +282,9 @@ mod tests {
method: "burn_from".into(),
params: vec![program_id.into(), alice_key.clone()],
max_units: 1000000,
require: None,
require: Some(Require {
result: ResultAssertion::NumericEq(post_transfer_balance),
}),
});

plan.add_step(Step {
Expand Down
2 changes: 1 addition & 1 deletion x/programs/rust/wasmlanche-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod memory;
mod program;

pub use self::{
memory::{from_host_ptr, CPointer},
memory::from_host_ptr,
params::{serialize_param, Params},
program::Program,
};
Expand Down
3 changes: 0 additions & 3 deletions x/programs/rust/wasmlanche-sdk/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ use crate::state::Error as StateError;
use borsh::{from_slice, BorshDeserialize};
use std::{alloc::Layout, cell::RefCell, collections::HashMap};

#[repr(C)]
pub struct CPointer(pub *const u8, pub usize);

thread_local! {
/// Map of pointer to the length of its content on the heap
static GLOBAL_STORE: RefCell<HashMap<*const u8, usize>> = RefCell::new(HashMap::new());
Expand Down
19 changes: 10 additions & 9 deletions x/programs/rust/wasmlanche-sdk/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ where
/// # Errors
/// Returns an [Error] if the key cannot be serialized
/// or if the host fails to delete the key and the associated value
pub fn delete(&mut self, key: K) -> Result<(), Error> {
pub fn delete<T: BorshDeserialize>(&mut self, key: K) -> Result<Option<T>, Error> {
self.cache.remove(&key);

let args = GetAndDeleteArgs {
Expand Down Expand Up @@ -199,7 +199,10 @@ struct GetAndDeleteArgs {
}

mod host {
use crate::state::Error;
use super::Error;
use crate::memory::from_host_ptr;
use borsh::BorshDeserialize;
use std::ptr::NonNull;

/// Persists the bytes at key on the host storage.
pub(super) fn put_bytes(bytes: &[u8]) -> Result<(), Error> {
Expand Down Expand Up @@ -235,17 +238,15 @@ mod host {
}

/// Deletes the bytes at key ptr from the host storage
pub(super) fn delete_bytes(bytes: &[u8]) -> Result<(), Error> {
pub(super) fn delete_bytes<T: BorshDeserialize>(bytes: &[u8]) -> Result<Option<T>, Error> {
#[link(wasm_import_module = "state")]
extern "C" {
#[link_name = "delete"]
fn ffi(ptr: *const u8, len: usize) -> i32;
fn ffi(ptr: *const u8, len: usize) -> NonNull<u8>;
}

let result = unsafe { ffi(bytes.as_ptr(), bytes.len()) };
match result {
0 => Ok(()),
_ => Err(Error::Delete),
}
let ptr = unsafe { ffi(bytes.as_ptr(), bytes.len()) };

from_host_ptr(ptr.as_ptr())
}
}

0 comments on commit ae8d85c

Please sign in to comment.