Skip to content

Commit

Permalink
simplifying lifetimes
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronc committed Oct 4, 2024
1 parent c5d0c1c commit 3e44e3a
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 54 deletions.
14 changes: 7 additions & 7 deletions rust/examples/bank.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
#![allow(missing_docs)]
#[ixc::module_handler(Bank)]
#[ixc::handler(Bank)]
pub mod bank {
use ixc::*;

pub struct Bank {
#[schema(name(address, denom), value(amount))]
balances: UIntMap<(Address, String), u128>,
balances: Map<(AccountID, String), u128>,
}

#[derive(StructCodec)]
#[derive(SchemaValue)]
pub struct Coin<'a> {
pub denom: &'a str,
pub amount: u128,
}

#[module_api]
#[handler_api]
pub trait BankAPI {
fn send(&self, ctx: &mut Context, to: Address, amount: &[Coin], evt: &mut EventBus<EventSend>) -> Response<()>;
fn send(&self, ctx: &mut Context, to: AccountID, amount: &[Coin], evt: &mut EventBus<EventSend>) -> Result<()>;
}

#[derive(StructCodec)]
#[derive(SchemaValue)]
pub struct EventSend<'a> {
pub from: Address,
pub to: Address,
pub coin: Coin<'a>,
}

impl BankAPI for Bank {
fn send(&self, ctx: &mut Context, to: Address, amount: &[Coin], evt: &mut EventBus<EventSend>) -> Response<()> {
fn send(&self, ctx: &mut Context, to: AccountID, amount: &[Coin], evt: &mut EventBus<EventSend>) -> Result<()> {
for coin in amount {
self.balances.safe_sub(ctx, (ctx.sender(), coin.denom), coin.amount)?;
self.balances.add(ctx, (to, coin.denom), coin.amount)?;
Expand Down
2 changes: 1 addition & 1 deletion rust/examples/simple_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod simple_asset {
#[on_create]
pub fn init(&self, ctx: &mut Context, initial_balance: u128) -> Result<()> {
let owner = ctx.caller();
self.owner.set(ctx, owner)?;
self.owner.set(ctx, &owner)?;
self.balances.set(ctx, owner, initial_balance)
}

Expand Down
6 changes: 3 additions & 3 deletions rust/schema/src/state_object/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use crate::structs::{StructDecodeVisitor, StructEncodeVisitor, StructType};
use crate::value::SchemaValue;

/// Encode an object value.
pub fn encode_object_value<'a, V: ObjectValue>(value: &V::In<'a>, writer_factory: &'a dyn WriterFactory) -> Result<&'a [u8], EncodeError> {
struct Visitor<'b, 'c, U:ObjectValue>(&'c U::In<'b>);
impl <'b, 'c, U:ObjectValue> ValueEncodeVisitor for Visitor<'b, 'c, U> {
pub fn encode_object_value<'a, 'b, V: ObjectValue>(value: &V::In<'b>, writer_factory: &'a dyn WriterFactory) -> Result<&'a [u8], EncodeError> {
struct Visitor<'c, 'd, U:ObjectValue>(&'c U::In<'d>);
impl <'c, 'd, U:ObjectValue> ValueEncodeVisitor for Visitor<'c, 'd, U> {
fn encode(&self, encoder: &mut dyn Encoder) -> Result<(), EncodeError> {
U::encode(self.0, encoder)
}
Expand Down
4 changes: 4 additions & 0 deletions rust/schema_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ fn derive_struct_schema(input: &syn::DeriveInput, str: &DataStruct) -> manyhow::
}
}

// impl < #lifetime > ::ixc_schema::SchemaValue < #lifetime > for &#lifetime #struct_name #ty_generics #where_clause {
// type Type = ::ixc_schema::types::StructT< #struct_name #ty_generics >;
// }

impl < #lifetime > ::ixc_schema::value::ListElementValue < #lifetime > for #struct_name #ty_generics #where_clause {}
impl #impl_generics ::ixc_schema::state_object::ObjectFieldValue for #struct_name #ty_generics #where_clause {
type In< #lifetime2 > = #struct_name #ty_generics2;
Expand Down
2 changes: 1 addition & 1 deletion rust/state_objects/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ where
}

/// Sets the value of the item.
pub fn set<'value>(&self, ctx: &'value mut Context, value: V::In<'value>) -> Result<()> {
pub fn set<'value>(&self, ctx: &'value mut Context, value: &V::In<'value>) -> Result<()> {
self.map.set(ctx, (), value)
}
}
Expand Down
2 changes: 1 addition & 1 deletion rust/state_objects/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ pub use set::{Set};
pub use item::{Item};
pub use index::{Index};
pub use unique::{UniqueIndex};
pub use uint_map::{UIntMap};
// pub use uint_map::{UIntMap};
pub use ordered_map::{OrderedMap};
pub use ordered_set::{OrderedSet};
42 changes: 18 additions & 24 deletions rust/state_objects/src/map.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! The map module contains the `Map` struct, which represents a key-value map in storage.

use std::borrow::Borrow;
use bump_scope::allocator_api2::alloc::Allocator;
use ixc_core::error::Error;
use ixc_core::{Context, Result};
Expand Down Expand Up @@ -28,8 +29,11 @@ impl<K: ObjectKey, V: ObjectValue> Map<K, V> {
// }

/// Gets the value of the map at the given key.
pub fn get<'key, 'value>(&self, ctx: &'value Context<'key>, key: K::In<'key>) -> Result<Option<V::Out<'value>>> {
let key_bz = encode_object_key::<K>(&self.prefix, &key, ctx.memory_manager())
pub fn get<'a, 'b, L>(&self, ctx: &'a Context, key: L) -> Result<Option<V::Out<'a>>>
where
L: Borrow<K::In<'b>>,
{
let key_bz = encode_object_key::<K>(&self.prefix, key.borrow(), ctx.memory_manager())
// .map_err(|_| Error::KnownHandlerError(HandlerErrorCode::EncodingError))?;
.map_err(|_| ())?;

Expand All @@ -45,37 +49,27 @@ impl<K: ObjectKey, V: ObjectValue> Map<K, V> {
Ok(Some(value))
}

// /// Gets the value of the map at the given key, possibly from a previous block.
// pub fn stale_get<'key>(&self, ctx: &Context<'key>, key: K::Value<'key>) -> Result<'key, V::Value<'key>> {
// todo!()
// }

/// Sets the value of the map at the given key.
pub fn set<'key, 'value>(&self, ctx: &'value mut Context<'key>, key: K::In<'key>, value: V::In<'value>) -> Result<()> {
let key_bz = encode_object_key::<K>(&self.prefix, &key, ctx.memory_manager())
pub fn set<'a, L, U>(&self, ctx: &mut Context, key: L, value: U) -> Result<()>
where
L: Borrow<K::In<'a>>,
U: Borrow<V::In<'a>>,
{
let key_bz = encode_object_key::<K>(&self.prefix, key.borrow(), ctx.memory_manager())
// .map_err(|_| Error::KnownHandlerError(HandlerErrorCode::EncodingError))?;
.map_err(|_| ())?;
let value_bz = encode_object_value::<V>(&value, ctx.memory_manager())
let value_bz = encode_object_value::<V>(value.borrow(), ctx.memory_manager())
// .map_err(|_| Error::KnownHandlerError(HandlerErrorCode::EncodingError))?;
.map_err(|_| ())?;
unsafe { KVStoreClient.set(ctx, key_bz, value_bz) }
}

// /// Updates the value of the map at the given key.
// pub fn update<'key, 'value>(&self, ctx: &mut Context<'key>, key: K::In<'key>, updater: impl FnOnce(Option<V::In<'value>>) -> Option<V::In<'value>>) -> Result<()> {
// todo!()
// }

// /// Lazily updates the value of the map at the given key at some later point in time.
// /// This function is unsafe because updater must be commutative and that cannot be guaranteed by the type system.
// pub unsafe fn lazy_update<'a, 'b>(&self, ctx: &mut Context<'a>, key: K::Value<'a>, updater: impl FnOnce(Option<V::Value<'b>>) -> Option<V::Value<'b>>) -> Response<()> {
// todo!()
// }
//

/// Deletes the value of the map at the given key.
pub fn delete<'key>(&self, ctx: &mut Context<'key>, key: &K::In<'key>) -> Result<()> {
let key_bz = encode_object_key::<K>(&self.prefix, key, ctx.memory_manager())
pub fn delete<'a, L>(&self, ctx: &mut Context, key: L) -> Result<()>
where
L: Borrow<K::In<'a>>,
{
let key_bz = encode_object_key::<K>(&self.prefix, key.borrow(), ctx.memory_manager())
// .map_err(|_| Error::KnownHandlerError(HandlerErrorCode::EncodingError))?;
.map_err(|_| ())?;
unsafe { KVStoreClient.delete(ctx, key_bz) }
Expand Down
40 changes: 23 additions & 17 deletions rust/state_objects/src/uint_map.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
use std::borrow::Borrow;
use ixc_core::{Context, Result};
use ixc_schema::state_object::ObjectKey;
use ixc_schema::state_object::{ObjectFieldValue, ObjectKey};
use crate::Map;

/// A map from keys to 128-bit unsigned integers.
pub struct UIntMap<K, V: UInt> {
map: Map<K, V>,
}

pub trait UInt: Sized {
pub trait UInt: ObjectFieldValue<In<'static>=Self, Out<'static>=Self> + Sized + Clone + 'static
{
fn add(self, other: Self) -> Option<Self>;
fn sub(self, other: Self) -> Option<Self>;
const ZERO: Self;
}

impl UInt for u64 {
fn add(self, other: Self) -> Option<Self> {
self.checked_add(other)
}

fn sub(self, other: Self) -> Option<Self> {
self.checked_sub(other)
}
}
impl UInt for u128 {
fn add(self, other: Self) -> Option<Self> {
self.checked_add(other)
Expand All @@ -29,24 +23,36 @@ impl UInt for u128 {
fn sub(self, other: Self) -> Option<Self> {
self.checked_sub(other)
}

const ZERO: Self = 0;
}

impl<'a, K: ObjectKey, V: UInt> UIntMap<K, V> {
impl<K: ObjectKey, V: UInt> UIntMap<K, V> {
/// Gets the current value for the given key, defaulting always to 0.
pub fn get(&self, ctx: &Context, key: K::In<'_>) -> Result<u128> {
// let value = self.map.get(ctx, key)?;
// Ok(value.unwrap_or(0))
pub fn get<'a, L>(&self, ctx: &Context, key: L) -> Result<V>
where
L: Borrow<K::In<'a>>,
{
// let value = self.map.get(ctx, key)?.clone();
// Ok(value.unwrap_or(V::ZERO))
todo!()
}

/// Adds the given value to the current value for the given key.
pub fn add(&self, ctx: &mut Context, key: K::In<'_>, value: u128) -> Result<u128> {
pub fn add<'a, L>(&self, ctx: &mut Context, key: L, value: V) -> Result<V>
where
L: Borrow<K::In<'a>>,
{
// let current = self.get(ctx, key.borrow())?;
// let new_value = V::add(current, value).ok_or_else(|| ())?;
// self.map.set(ctx, key.borrow(), &new_value)?;
// Ok(new_value)
todo!()
}

/// Subtracts the given value from the current value for the given key,
/// returning an error if the subtraction would result in a negative value.
pub fn safe_sub(&self, ctx: &mut Context, key: K::In<'_>, value: u128) -> Result<u128> {
pub fn safe_sub(&self, ctx: &mut Context, key: &K::In<'_>, value: V) -> Result<V> {
todo!()
}
}

0 comments on commit 3e44e3a

Please sign in to comment.