Skip to content

Commit

Permalink
Accept a slice as an entry point arg (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
kpob authored Jan 8, 2024
1 parent 418e712 commit 2d49ebd
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 21 deletions.
2 changes: 1 addition & 1 deletion modules/src/erc1155/erc1155_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Erc1155 for Erc1155Base {
self.balances.get_or_default(&(*owner, *id))
}

fn balance_of_batch(&self, owners: Vec<Address>, ids: Vec<U256>) -> Vec<U256> {
fn balance_of_batch(&self, owners: &[Address], ids: &[U256]) -> Vec<U256> {
if owners.len() != ids.len() {
self.env().revert(Error::AccountsAndIdsLengthMismatch);
}
Expand Down
2 changes: 1 addition & 1 deletion modules/src/erc1155/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub trait Erc1155 {
/// Batched version of [Erc1155::balance_of](Self::balance_of).
///
/// The length of `owners` and `ids` must be the same.
fn balance_of_batch(&self, owners: Vec<Address>, ids: Vec<U256>) -> Vec<U256>;
fn balance_of_batch(&self, owners: &[Address], ids: &[U256]) -> Vec<U256>;
/// Allows or denials the `operator` to transfer the caller’s tokens.
///
/// Emits [crate::erc1155::events::ApprovalForAll].
Expand Down
2 changes: 1 addition & 1 deletion modules/src/erc1155/owned_erc1155.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub trait OwnedErc1155 {
/// Batched version of [Erc1155::balance_of](Self::balance_of).
///
/// The length of `owners` and `ids` must be the same.
fn balance_of_batch(&self, owners: Vec<Address>, ids: Vec<U256>) -> Vec<U256>;
fn balance_of_batch(&self, owners: &[Address], ids: &[U256]) -> Vec<U256>;
/// Allows or denials the `operator` to transfer the caller’s tokens.
///
/// Emits [crate::erc1155::events::ApprovalForAll].
Expand Down
2 changes: 1 addition & 1 deletion modules/src/erc1155_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl OwnedErc1155 for Erc1155Token {
fn balance_of(&self, owner: &Address, id: &U256) -> U256 {
self.core.balance_of(owner, id)
}
fn balance_of_batch(&self, owners: Vec<Address>, ids: Vec<U256>) -> Vec<U256> {
fn balance_of_batch(&self, owners: &[Address], ids: &[U256]) -> Vec<U256> {
self.core.balance_of_batch(owners, ids)
}
fn set_approval_for_all(&mut self, operator: &Address, approved: bool) {
Expand Down
4 changes: 4 additions & 0 deletions odra-macros/src/ast/deployer_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ mod deployer_impl {
let result = __erc20_exec_parts::execute_approve(contract_env);
odra::ToBytes::to_bytes(&result).map(Into::into).unwrap()
}
"airdrop" => {
let result = execute_airdrop(contract_env);
odra::ToBytes::to_bytes(&result).map(Into::into).unwrap()
}
_ => panic!("Unknown method")
}
});
Expand Down
21 changes: 21 additions & 0 deletions odra-macros/src/ast/entrypoints_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,27 @@ mod test {
ret: <() as odra::casper_types::CLTyped>::cl_type(),
ty: odra::contract_def::EntrypointType::Public,
attributes: vec![odra::contract_def::EntrypointAttribute::NonReentrant]
},
odra::contract_def::Entrypoint {
ident: String::from("airdrop"),
args: vec![
odra::contract_def::Argument {
ident: String::from("to"),
ty: <odra::prelude::vec::Vec<Address> as odra::casper_types::CLTyped>::cl_type(),
is_ref: false,
is_slice: false
},
odra::contract_def::Argument {
ident: String::from("amount"),
ty: <U256 as odra::casper_types::CLTyped>::cl_type(),
is_ref: false,
is_slice: false
}
],
is_mut: false,
ret: <() as odra::casper_types::CLTyped>::cl_type(),
ty: odra::contract_def::EntrypointType::Public,
attributes: vec![]
}
]
}
Expand Down
30 changes: 24 additions & 6 deletions odra-macros/src/ast/exec_parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,17 @@ impl TryFrom<(&'_ ModuleImplIR, &'_ FnIR)> for ExecFunctionItem {
}).collect::<Result<syn::punctuated::Punctuated<syn::Expr, syn::token::Comma>, syn::Error>>()?;

let args = func
.arg_names()
.named_args()
.iter()
.map(|ident| utils::stmt::get_named_arg(ident, &exec_env_ident))
.collect();
.map(|arg| {
let ty = utils::ty::unreferenced_ty(&arg.ty()?);
Ok(utils::stmt::get_named_arg(
&arg.name()?,
&exec_env_ident,
&ty
))
})
.collect::<Result<Vec<syn::Stmt>, syn::Error>>()?;

let init_contract_stmt = match func.is_mut() {
true => utils::stmt::new_mut_module(&contract_ident, &module_ident, &env_rc_ident),
Expand Down Expand Up @@ -219,7 +226,7 @@ mod test {
pub fn execute_init(env: odra::ContractEnv) {
let env_rc = Rc::new(env);
let exec_env = odra::ExecutionEnv::new(env_rc.clone());
let total_supply = exec_env.get_named_arg("total_supply");
let total_supply = exec_env.get_named_arg::<Option<U256>>("total_supply");
let mut contract = <Erc20 as odra::Module>::new(env_rc);
let result = contract.init(total_supply);
return result;
Expand Down Expand Up @@ -249,13 +256,24 @@ mod test {
let env_rc = Rc::new(env);
let exec_env = odra::ExecutionEnv::new(env_rc.clone());
exec_env.non_reentrant_before();
let to = exec_env.get_named_arg("to");
let amount = exec_env.get_named_arg("amount");
let to = exec_env.get_named_arg::<Address>("to");
let amount = exec_env.get_named_arg::<U256>("amount");
let mut contract = <Erc20 as odra::Module>::new(env_rc);
let result = contract.approve(&to, &amount);
exec_env.non_reentrant_after();
return result;
}

#[inline]
pub fn execute_airdrop(env: odra::ContractEnv) {
let env_rc = Rc::new(env);
let exec_env = odra::ExecutionEnv::new(env_rc.clone());
let to = exec_env.get_named_arg::<odra::prelude::vec::Vec<Address>>("to");
let amount = exec_env.get_named_arg::<U256>("amount");
let contract = <Erc20 as odra::Module>::new(env_rc);
let result = contract.airdrop(&to, &amount);
return result;
}
}
};

Expand Down
22 changes: 22 additions & 0 deletions odra-macros/src/ast/host_ref_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,28 @@ mod ref_item_tests {
pub fn approve(&mut self, to: Address, amount: U256) {
self.try_approve(to, amount).unwrap()
}

pub fn try_airdrop(&self, to: odra::prelude::vec::Vec<Address>, amount: U256) -> Result<(), odra::OdraError> {
self.env.call_contract(
self.address,
odra::CallDef::new(
String::from("airdrop"),
{
let mut named_args = odra::RuntimeArgs::new();
if self.attached_value > odra::U512::zero() {
let _ = named_args.insert("amount", self.attached_value);
}
let _ = named_args.insert("to", to);
let _ = named_args.insert("amount", amount);
named_args
}
).with_amount(self.attached_value),
)
}

pub fn airdrop(&self, to: odra::prelude::vec::Vec<Address>, amount: U256) {
self.try_airdrop(to, amount).unwrap()
}
}
};
let actual = HostRefItem::try_from(&module).unwrap();
Expand Down
16 changes: 16 additions & 0 deletions odra-macros/src/ast/ref_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,22 @@ mod ref_item_tests {
),
)
}

pub fn airdrop(&self, to: odra::prelude::vec::Vec<Address>, amount: U256) {
self.env
.call_contract(
self.address,
odra::CallDef::new(
String::from("airdrop"),
{
let mut named_args = odra::RuntimeArgs::new();
let _ = named_args.insert("to", to);
let _ = named_args.insert("amount", amount);
named_args
},
),
)
}
}
};
let actual = RefItem::try_from(&module).unwrap();
Expand Down
26 changes: 26 additions & 0 deletions odra-macros/src/ast/test_parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,28 @@ mod test {
pub fn approve(&mut self, to: Address, amount: U256) {
self.try_approve(to, amount).unwrap()
}

pub fn try_airdrop(&self, to: odra::prelude::vec::Vec<Address>, amount: U256) -> Result<(), odra::OdraError> {
self.env.call_contract(
self.address,
odra::CallDef::new(
String::from("airdrop"),
{
let mut named_args = odra::RuntimeArgs::new();
if self.attached_value > odra::U512::zero() {
let _ = named_args.insert("amount", self.attached_value);
}
let _ = named_args.insert("to", to);
let _ = named_args.insert("amount", amount);
named_args
}
).with_amount(self.attached_value),
)
}

pub fn airdrop(&self, to: odra::prelude::vec::Vec<Address>, amount: U256) {
self.try_airdrop(to, amount).unwrap()
}
}

pub struct Erc20Deployer;
Expand All @@ -192,6 +214,10 @@ mod test {
let result = __erc20_exec_parts::execute_approve(contract_env);
odra::ToBytes::to_bytes(&result).map(Into::into).unwrap()
}
"airdrop" => {
let result = execute_airdrop(contract_env);
odra::ToBytes::to_bytes(&result).map(Into::into).unwrap()
}
_ => panic!("Unknown method")
}
});
Expand Down
20 changes: 20 additions & 0 deletions odra-macros/src/ast/wasm_parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,21 @@ mod test {
),
);
entry_points
.add_entry_point(
odra::casper_types::EntryPoint::new(
"airdrop",
vec![
odra::casper_types::Parameter::new("to", <odra::prelude::vec::Vec<Address> as
odra::casper_types::CLTyped > ::cl_type()),
odra::casper_types::Parameter::new("amount", <U256 as
odra::casper_types::CLTyped > ::cl_type())
],
<() as odra::casper_types::CLTyped>::cl_type(),
odra::casper_types::EntryPointAccess::Public,
odra::casper_types::EntryPointType::Contract,
),
);
entry_points
}

#[no_mangle]
Expand Down Expand Up @@ -366,6 +381,11 @@ mod test {
fn approve() {
__erc20_exec_parts::execute_approve(odra::odra_casper_wasm_env::WasmContractEnv::new_env());
}

#[no_mangle]
fn airdrop() {
execute_airdrop(odra::odra_casper_wasm_env::WasmContractEnv::new_env());
}
}
};

Expand Down
2 changes: 1 addition & 1 deletion odra-macros/src/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ impl FnIR {
self.typed_args()
.into_iter()
.map(|pat_ty| syn::PatType {
ty: Box::new(utils::syn::unreferenced_ty(&pat_ty.ty)),
ty: Box::new(utils::ty::unreferenced_ty(&pat_ty.ty)),
..pat_ty
})
.collect()
Expand Down
3 changes: 3 additions & 0 deletions odra-macros/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ pub mod mock {
});
}

pub fn airdrop(to: &[Address], amount: &U256) {
}

fn private_function() {

}
Expand Down
2 changes: 1 addition & 1 deletion odra-macros/src/utils/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn new_parameter(name: String, ty: syn::Type) -> syn::Expr {
}

pub fn as_cl_type(ty: &syn::Type) -> syn::Expr {
let ty = super::syn::unreferenced_ty(ty);
let ty = super::ty::unreferenced_ty(ty);
let ty_cl_typed = super::ty::cl_typed();
let ty = super::syn::as_casted_ty_stream(&ty, ty_cl_typed);
parse_quote!(#ty::cl_type())
Expand Down
4 changes: 2 additions & 2 deletions odra-macros/src/utils/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ pub fn install_contract(entry_points: syn::Expr, schemas: syn::Expr, args: syn::
);)
}

pub fn get_named_arg(arg_ident: &syn::Ident, env_ident: &syn::Ident) -> syn::Stmt {
pub fn get_named_arg(arg_ident: &syn::Ident, env_ident: &syn::Ident, ty: &syn::Type) -> syn::Stmt {
let arg_name = arg_ident.to_string();
parse_quote!(let #arg_ident = #env_ident.get_named_arg(#arg_name);)
parse_quote!(let #arg_ident = #env_ident.get_named_arg::<#ty>(#arg_name);)
}

pub fn new_execution_env(ident: &syn::Ident, env_rc_ident: &syn::Ident) -> syn::Stmt {
Expand Down
7 changes: 0 additions & 7 deletions odra-macros/src/utils/syn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,6 @@ pub fn is_ref(ty: &syn::Type) -> bool {
matches!(ty, syn::Type::Reference(_))
}

pub fn unreferenced_ty(ty: &syn::Type) -> syn::Type {
match ty {
syn::Type::Reference(syn::TypeReference { elem, .. }) => *elem.clone(),
_ => ty.clone()
}
}

fn clear_path(ty: &syn::TypePath) -> syn::Result<syn::TypePath> {
let mut owned_ty = ty.to_owned();

Expand Down
20 changes: 20 additions & 0 deletions odra-macros/src/utils/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,23 @@ pub fn typed_btree_map(key: &syn::Type, value: &syn::Type) -> syn::Type {
pub fn btree_map() -> syn::Type {
parse_quote!(odra::prelude::BTreeMap)
}

fn slice_to_vec(ty: &syn::Type) -> syn::Type {
match ty {
syn::Type::Slice(ty) => vec_of(ty.elem.as_ref()),
_ => ty.clone()
}
}

pub fn unreferenced_ty(ty: &syn::Type) -> syn::Type {
match ty {
syn::Type::Reference(syn::TypeReference { elem, .. }) => {
if matches!(**elem, syn::Type::Reference(_)) {
unreferenced_ty(elem)
} else {
slice_to_vec(elem)
}
}
_ => slice_to_vec(ty)
}
}

0 comments on commit 2d49ebd

Please sign in to comment.