Skip to content

Commit

Permalink
program struct refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
samliok committed Dec 4, 2023
1 parent 7db59e5 commit d19f883
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 99 deletions.
4 changes: 2 additions & 2 deletions x/programs/examples/imports/pstate/pstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (i *Import) Register(link runtime.Link, meter runtime.Meter, _ runtime.Supp
return nil
}

func (i *Import) putFn(caller *wasmtime.Caller, idPtr int64, keyPtr int32, valuePtr int32) int32 {
func (i *Import) putFn(caller *wasmtime.Caller, idPtr int32, keyPtr int32, valuePtr int32) int32 {
client := runtime.NewExportClient(caller)
memory := runtime.NewMemory(client)
programIDBytes, err := memory.Range(uint64(idPtr), uint64(ids.IDLen))
Expand Down Expand Up @@ -99,7 +99,7 @@ func (i *Import) putFn(caller *wasmtime.Caller, idPtr int64, keyPtr int32, value
return 0
}

func (i *Import) getFn(caller *wasmtime.Caller, idPtr int64, keyPtr int32) int64 {
func (i *Import) getFn(caller *wasmtime.Caller, idPtr int32, keyPtr int32) int64 {
client := runtime.NewExportClient(caller)
memory := runtime.NewMemory(client)
programIDBytes, err := memory.Range(uint64(idPtr), uint64(ids.IDLen))
Expand Down
Binary file modified x/programs/examples/testdata/token.wasm
Binary file not shown.
24 changes: 19 additions & 5 deletions x/programs/examples/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (t *Token) Run(ctx context.Context) error {
return err
}

programIDPtr, err := runtime.WriteBytes(rt.Memory(), programID[:])
programIDPtr, err := newParameterPtr(ctx, programID, rt)
if err != nil {
return err
}
Expand Down Expand Up @@ -124,8 +124,13 @@ func (t *Token) Run(ctx context.Context) error {
)

// mint 100 tokens to alice
mintAlice := int64(1000)
_, err = rt.Call(ctx, "mint_to", programIDPtr, alicePtr, mintAlice)
mintAlice := int64(100)
mintAlicePtr, err := newParameterPtr(ctx, mintAlice, rt)
if err != nil {
return err
}

_, err = rt.Call(ctx, "mint_to", programIDPtr, alicePtr, mintAlicePtr)
if err != nil {
return err
}
Expand Down Expand Up @@ -153,7 +158,11 @@ func (t *Token) Run(ctx context.Context) error {

// transfer 50 from alice to bob
transferToBob := int64(50)
_, err = rt.Call(ctx, "transfer", programIDPtr, alicePtr, bobPtr, transferToBob)
transferToBobPtr, err := newParameterPtr(ctx, transferToBob, rt)
if err != nil {
return err
}
_, err = rt.Call(ctx, "transfer", programIDPtr, alicePtr, bobPtr, transferToBobPtr)
if err != nil {
return err
}
Expand All @@ -162,7 +171,12 @@ func (t *Token) Run(ctx context.Context) error {
zap.Int64("to bob", transferToBob),
)

_, err = rt.Call(ctx, "transfer", programIDPtr, alicePtr, bobPtr, 1)
onePtr, err := newParameterPtr(ctx, int64(1), rt)
if err != nil {
return err
}

_, err = rt.Call(ctx, "transfer", programIDPtr, alicePtr, bobPtr, onePtr)
if err != nil {
return err
}
Expand Down
73 changes: 8 additions & 65 deletions x/programs/rust/sdk_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,10 @@ use syn::{
use unzip_n::unzip_n;
unzip_n!(3);

enum ParamKind {
SupportedPrimitive,
Program,
Pointer,
}

impl From<&Box<Type>> for ParamKind {
fn from(ty: &Box<Type>) -> Self {
if is_supported_primitive(ty) {
ParamKind::SupportedPrimitive
} else if is_program(ty) {
ParamKind::Program
} else {
ParamKind::Pointer
}
}
}

impl ParamKind {
fn converted_param_tokenstream(&self, param_name: &Ident) -> proc_macro2::TokenStream {
match self {
// return the original parameter if it is a supported primitive type
ParamKind::SupportedPrimitive => {
quote! {
#param_name
}
}
// use the From<i64> trait to convert from i64 to a Program struct
ParamKind::Program => {
quote! {
#param_name.into()
}
}
// only convert from_raw_ptr if not a supported primitive type or Program
ParamKind::Pointer => {
quote! {
unsafe { wasmlanche_sdk::state::from_raw_ptr(#param_name).expect("error serializing ptr") }
}
}
}
fn convert_param(param_name: &Ident) -> proc_macro2::TokenStream {
quote! {
unsafe { wasmlanche_sdk::state::from_raw_ptr(#param_name).expect("error serializing ptr") }
}
}

Expand All @@ -76,15 +40,12 @@ pub fn public(_: TokenStream, item: TokenStream) -> TokenStream {

if let Pat::Ident(ref pat_ident) = **pat {
let param_name = &pat_ident.ident;
let param_descriptor = ty.into();
let param_type = if is_supported_primitive(ty) {
ty.to_token_stream()
} else {
// let param_descriptor = ty.into();
let param_type =
parse_str::<Type>("i64")
.expect("valid i64 type")
.to_token_stream()
};
return (param_name, param_type, param_descriptor);
.to_token_stream();
return (param_name, param_type, convert_param(param_name));
}
// add unused variable
if let Pat::Wild(_) = **pat {
Expand All @@ -94,7 +55,7 @@ pub fn public(_: TokenStream, item: TokenStream) -> TokenStream {
parse_str::<Type>("i64")
.expect("valid i64 type")
.to_token_stream(),
ParamKind::Program,
convert_param(&empty_param),
);
} else {
panic!("Unused variables only supported for Program.")
Expand All @@ -105,13 +66,6 @@ pub fn public(_: TokenStream, item: TokenStream) -> TokenStream {
});

let (param_names, param_types, converted_params) = full_params
.map(|(param_name, param_type, param_kind)| {
(
param_name,
param_type,
param_kind.converted_param_tokenstream(param_name),
)
})
.unzip_n_vec();

// Extract the original function's return type. This must be a WASM supported type.
Expand Down Expand Up @@ -202,17 +156,6 @@ fn generate_to_vec(
.collect()
}

/// Returns whether the type_path represents a supported primitive type.
fn is_supported_primitive(type_path: &std::boxed::Box<Type>) -> bool {
if let Type::Path(ref type_path) = **type_path {
let ident = &type_path.path.segments[0].ident;
let ident_str = ident.to_string();
matches!(ident_str.as_str(), "i32" | "i64" | "bool")
} else {
false
}
}

/// Returns whether the type_path represents a Program type.
fn is_program(type_path: &std::boxed::Box<Type>) -> bool {
if let Type::Path(ref type_path) = **type_path {
Expand Down
8 changes: 4 additions & 4 deletions x/programs/rust/wasmlanche_sdk/src/host/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::program::Program;
extern "C" {
#[link_name = "call_program"]
fn _call_program(
caller_id: i64,
target_id: i64,
caller_id: *const u8,
target_id: *const u8,
max_units: i64,
function_ptr: *const u8,
function_len: usize,
Expand All @@ -27,8 +27,8 @@ pub(crate) fn call(
let function_bytes = function_name.as_bytes();
unsafe {
_call_program(
caller.id(),
target.id(),
caller.id().as_ptr(),
target.id().as_ptr(),
max_units,
function_bytes.as_ptr(),
function_bytes.len(),
Expand Down
8 changes: 4 additions & 4 deletions x/programs/rust/wasmlanche_sdk/src/host/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ use borsh::{to_vec, BorshSerialize};
#[link(wasm_import_module = "state")]
extern "C" {
#[link_name = "put"]
fn _put(caller_id: i64, key_ptr: *const u8, value: *const u8) -> i32;
fn _put(caller_id: *const u8, key_ptr: *const u8, value: *const u8) -> i32;

#[link_name = "get"]
fn _get(caller_id: i64, key_ptr: *const u8) -> i64;
fn _get(caller_id: *const u8, key_ptr: *const u8) -> i64;
}

/// Persists the bytes at `value_ptr` to the bytes at key ptr on the host storage.
Expand All @@ -30,7 +30,7 @@ where
let value_bytes = prepend_length(&value_bytes);
let key_bytes = prepend_length(key.as_bytes());

match unsafe { _put(caller.id(), key_bytes.as_ptr(), value_bytes.as_ptr()) } {
match unsafe { _put(caller.id().as_ptr(), key_bytes.as_ptr(), value_bytes.as_ptr()) } {
0 => Ok(()),
_ => Err(StateError::Write),
}
Expand All @@ -43,5 +43,5 @@ where
pub(crate) unsafe fn get_bytes(caller: &Program, key: &Key) -> i64 {
// prepend length to key
let key = prepend_length(key.as_bytes());
unsafe { _get(caller.id(), key.as_ptr()) }
unsafe { _get(caller.id().as_ptr(), key.as_ptr()) }
}
29 changes: 10 additions & 19 deletions x/programs/rust/wasmlanche_sdk/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,25 @@ use crate::{
/// Represents the current Program in the context of the caller. Or an external
/// program that is being invoked.
#[derive(Clone, Copy, BorshDeserialize, BorshSerialize)]
pub struct Program {
id: i64,
}
pub struct Program([u8; Self::LEN]);


impl Program {
/// The length of ids.ID
pub const LEN: usize = 32;

/// Returns the id of the program.
#[must_use]
pub fn id(self) -> i64 {
self.id
pub fn id(self) -> [u8; Self::LEN] {
self.0
}


/// Returns a State object that can be used to interact with persistent
/// storage exposed by the host.
#[must_use]
pub fn state(&self) -> State {
State::new(self.id.into())
pub fn state(self) -> State {
State::new(self)
}

/// Attempts to call another program `target` from this program `caller`.
Expand All @@ -43,18 +46,6 @@ impl Program {
}
}

impl From<Program> for i64 {
fn from(program: Program) -> Self {
program.id()
}
}

impl From<i64> for Program {
fn from(value: i64) -> Self {
Self { id: value }
}
}

#[macro_export]
macro_rules! serialize_params {
($($param:expr),*) => {
Expand Down

0 comments on commit d19f883

Please sign in to comment.