Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make delete return the old data #890

Merged
merged 2 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
43 changes: 40 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,46 @@ 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) {
// [0] represents `None`
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
}

// 1 is the discriminant for `Some`
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())
}
}
Loading