From 37650a3d988a297a8cac41ae8ad564571fe4442f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20P=C5=82askonka?= Date: Tue, 9 Jan 2024 14:20:50 +0100 Subject: [PATCH] Template for workspace project (#309) * Added template for workspace project. To avoid name collisions of bins in workspace, bins had to be prepended with project name. Rewritten modules to fit changes to core. * Fixed contract template --- examples2/Cargo.toml | 4 +- modules/Cargo.toml | 4 +- modules/src/access/ownable.rs | 56 ++++++++----------- templates/blank/Cargo.toml | 4 +- templates/blank/Odra.toml | 2 +- templates/blank/README.md | 2 +- templates/full/Cargo.toml | 4 +- templates/full/Odra.toml | 2 +- templates/full/README.md | 2 +- templates/full/src/flipper.rs | 2 +- templates/module.rs.template | 15 +++-- templates/workspace/.gitignore | 1 + templates/workspace/CHANGELOG.md | 8 +++ templates/workspace/Cargo.toml | 16 ++++++ templates/workspace/Odra.toml | 7 +++ templates/workspace/README.md | 31 ++++++++++ templates/workspace/flapper/.gitignore | 7 +++ templates/workspace/flapper/Cargo.toml | 17 ++++++ .../workspace/flapper/bin/build_contract.rs | 4 ++ .../workspace/flapper/bin/build_schema.rs | 10 ++++ templates/workspace/flapper/build.rs | 8 +++ templates/workspace/flapper/src/flapper.rs | 56 +++++++++++++++++++ templates/workspace/flapper/src/lib.rs | 5 ++ templates/workspace/flipper/.gitignore | 7 +++ templates/workspace/flipper/Cargo.toml | 17 ++++++ .../workspace/flipper/bin/build_contract.rs | 4 ++ .../workspace/flipper/bin/build_schema.rs | 10 ++++ templates/workspace/flipper/build.rs | 8 +++ templates/workspace/flipper/src/flipper.rs | 56 +++++++++++++++++++ templates/workspace/flipper/src/lib.rs | 5 ++ templates/workspace/rust-toolchain | 1 + 31 files changed, 325 insertions(+), 50 deletions(-) create mode 100644 templates/workspace/.gitignore create mode 100644 templates/workspace/CHANGELOG.md create mode 100644 templates/workspace/Cargo.toml create mode 100644 templates/workspace/Odra.toml create mode 100644 templates/workspace/README.md create mode 100644 templates/workspace/flapper/.gitignore create mode 100644 templates/workspace/flapper/Cargo.toml create mode 100644 templates/workspace/flapper/bin/build_contract.rs create mode 100644 templates/workspace/flapper/bin/build_schema.rs create mode 100644 templates/workspace/flapper/build.rs create mode 100644 templates/workspace/flapper/src/flapper.rs create mode 100644 templates/workspace/flapper/src/lib.rs create mode 100644 templates/workspace/flipper/.gitignore create mode 100644 templates/workspace/flipper/Cargo.toml create mode 100644 templates/workspace/flipper/bin/build_contract.rs create mode 100644 templates/workspace/flipper/bin/build_schema.rs create mode 100644 templates/workspace/flipper/build.rs create mode 100644 templates/workspace/flipper/src/flipper.rs create mode 100644 templates/workspace/flipper/src/lib.rs create mode 100644 templates/workspace/rust-toolchain diff --git a/examples2/Cargo.toml b/examples2/Cargo.toml index b7a4d472..9728a380 100644 --- a/examples2/Cargo.toml +++ b/examples2/Cargo.toml @@ -7,12 +7,12 @@ edition = "2021" odra = { path = "../odra" } [[bin]] -name = "build_contract" +name = "examples2_build_contract" path = "bin/build_contract.rs" test = false [[bin]] -name = "build_schema" +name = "examples2_build_schema" path = "bin/build_schema.rs" test = false diff --git a/modules/Cargo.toml b/modules/Cargo.toml index 1ff43d10..19ff1e9c 100644 --- a/modules/Cargo.toml +++ b/modules/Cargo.toml @@ -15,12 +15,12 @@ casper-event-standard = "0.4.1" hex = { version = "0.4.3", default-features = false } [[bin]] -name = "build_contract" +name = "odra_modules_build_contract" path = "bin/build_contract.rs" test = false [[bin]] -name = "build_schema" +name = "odra_modules_build_schema" path = "bin/build_schema.rs" test = false diff --git a/modules/src/access/ownable.rs b/modules/src/access/ownable.rs index 96da9bc3..2e245fdd 100644 --- a/modules/src/access/ownable.rs +++ b/modules/src/access/ownable.rs @@ -171,8 +171,8 @@ mod test { new_owner: Some(deployer) }; - env.emitted_event(&ownable.address, &event); - env.emitted_event(&ownable_2step.address, &event); + env.emitted_event(&ownable.address(), &event); + env.emitted_event(&ownable_2step.address(), &event); } #[test] @@ -181,14 +181,14 @@ mod test { let (mut contract, initial_owner) = setup_ownable(); // when the current owner transfers ownership - let new_owner = contract.env.get_account(1); + let new_owner = contract.env().get_account(1); contract.transfer_ownership(new_owner); // then the new owner is set assert_eq!(new_owner, contract.get_owner()); // then a OwnershipTransferred event was emitted - contract.env.emitted_event( - &contract.address, + contract.env().emitted_event( + &contract.address(), &OwnershipTransferred { previous_owner: Some(initial_owner), new_owner: Some(new_owner) @@ -202,11 +202,11 @@ mod test { let (mut contract, initial_owner) = setup_ownable_2_step(); // when the current owner transfers ownership - let new_owner = contract.env.get_account(1); + let new_owner = contract.env().get_account(1); contract.transfer_ownership(new_owner); // when the pending owner accepts the transfer - contract.env.set_caller(new_owner); + contract.env().set_caller(new_owner); contract.accept_ownership(); // then the new owner is set @@ -214,15 +214,15 @@ mod test { // then the pending owner is unset assert_eq!(None, contract.get_pending_owner()); // then OwnershipTransferStarted and OwnershipTransferred events were emitted - contract.env.emitted_event( - &contract.address, + contract.env().emitted_event( + &contract.address(), &OwnershipTransferStarted { previous_owner: Some(initial_owner), new_owner: Some(new_owner) } ); - contract.env.emitted_event( - &contract.address, + contract.env().emitted_event( + &contract.address(), &OwnershipTransferred { previous_owner: Some(initial_owner), new_owner: Some(new_owner) @@ -236,8 +236,8 @@ mod test { let (mut contract, _) = setup_ownable(); // when a non-owner account is the caller - let (caller, new_owner) = (contract.env.get_account(1), contract.env.get_account(2)); - contract.env.set_caller(caller); + let (caller, new_owner) = (contract.env().get_account(1), contract.env().get_account(2)); + contract.env().set_caller(caller); // then ownership transfer fails let err = contract.try_transfer_ownership(new_owner).unwrap_err(); @@ -250,15 +250,15 @@ mod test { let (mut contract, initial_owner) = setup_ownable_2_step(); // when a non-owner account is the caller - let (caller, new_owner) = (contract.env.get_account(1), contract.env.get_account(2)); - contract.env.set_caller(caller); + let (caller, new_owner) = (contract.env().get_account(1), contract.env().get_account(2)); + contract.env().set_caller(caller); // then ownership transfer fails let err = contract.try_transfer_ownership(new_owner).unwrap_err(); assert_eq!(err, CallerNotTheOwner.into()); // when the owner is the caller - contract.env.set_caller(initial_owner); + contract.env().set_caller(initial_owner); contract.transfer_ownership(new_owner); // then the pending owner is set @@ -287,8 +287,8 @@ mod test { contract.renounce_ownership(); // then an event is emitted - contract.env.emitted_event( - &contract.address, + contract.env().emitted_event( + &contract.address(), &OwnershipTransferred { previous_owner: Some(initial_owner), new_owner: None @@ -310,8 +310,8 @@ mod test { contracts.iter_mut().for_each(|contract| { // when a non-owner account is the caller - let caller = contract.env.get_account(1); - contract.env.set_caller(caller); + let caller = contract.env().get_account(1); + contract.env().set_caller(caller); // then renounce ownership fails let err = contract.try_renounce_ownership().unwrap_err(); @@ -344,19 +344,11 @@ mod test { let env = odra::test_env(); let ownable = OwnableDeployer::init(&env); let ownable_2_step = Ownable2StepDeployer::init(&env); + let renouncable_ref = RenounceableHostRef::new(*ownable.address(), env.clone()); + let renouncable_2_step_ref = + RenounceableHostRef::new(*ownable_2_step.address(), env.clone()); ( - vec![ - RenounceableHostRef { - address: ownable.address, - env: env.clone(), - attached_value: Default::default() - }, - RenounceableHostRef { - address: ownable_2_step.address, - env: env.clone(), - attached_value: Default::default() - }, - ], + vec![renouncable_ref, renouncable_2_step_ref], env.get_account(0) ) } diff --git a/templates/blank/Cargo.toml b/templates/blank/Cargo.toml index 7ec054bd..f57e4d3a 100644 --- a/templates/blank/Cargo.toml +++ b/templates/blank/Cargo.toml @@ -7,12 +7,12 @@ edition = "2021" #odra_dependency [[bin]] -name = "build_contract" +name = "{{project-name}}_build_contract" path = "bin/build_contract.rs" test = false [[bin]] -name = "build_schema" +name = "{{project_name}}_build_schema" path = "bin/build_schema.rs" test = false diff --git a/templates/blank/Odra.toml b/templates/blank/Odra.toml index ac534068..dfb3ec39 100644 --- a/templates/blank/Odra.toml +++ b/templates/blank/Odra.toml @@ -1,3 +1,3 @@ #[[contracts]] -#name = "mycontract" +#name = "Mycontract" #fqn = "{{project-name}}::Mycontract" diff --git a/templates/blank/README.md b/templates/blank/README.md index 077e8246..f8bceffe 100644 --- a/templates/blank/README.md +++ b/templates/blank/README.md @@ -1,7 +1,7 @@ # {{project-name}} ## Usage -It's recommend to install +It's recommended to install [cargo-odra](https://github.com/odradev/cargo-odra) first. ### Build diff --git a/templates/full/Cargo.toml b/templates/full/Cargo.toml index 7ec054bd..c7f36768 100644 --- a/templates/full/Cargo.toml +++ b/templates/full/Cargo.toml @@ -7,12 +7,12 @@ edition = "2021" #odra_dependency [[bin]] -name = "build_contract" +name = "{{project-name}}_build_contract" path = "bin/build_contract.rs" test = false [[bin]] -name = "build_schema" +name = "{{project-name}}_build_schema" path = "bin/build_schema.rs" test = false diff --git a/templates/full/Odra.toml b/templates/full/Odra.toml index c82a035a..2b314faa 100644 --- a/templates/full/Odra.toml +++ b/templates/full/Odra.toml @@ -1,3 +1,3 @@ [[contracts]] -name = "flipper" +name = "Flipper" fqn = "{{project-name}}::Flipper" diff --git a/templates/full/README.md b/templates/full/README.md index 077e8246..f8bceffe 100644 --- a/templates/full/README.md +++ b/templates/full/README.md @@ -1,7 +1,7 @@ # {{project-name}} ## Usage -It's recommend to install +It's recommended to install [cargo-odra](https://github.com/odradev/cargo-odra) first. ### Build diff --git a/templates/full/src/flipper.rs b/templates/full/src/flipper.rs index 500b0221..c629f841 100644 --- a/templates/full/src/flipper.rs +++ b/templates/full/src/flipper.rs @@ -18,7 +18,7 @@ pub struct Flipper { impl Flipper { /// Odra constructor. /// - /// Initializes the contract with the value of value. + /// Initializes the contract. pub fn init(&mut self) { self.value.set(false); } diff --git a/templates/module.rs.template b/templates/module.rs.template index c23546f7..1b40b13f 100644 --- a/templates/module.rs.template +++ b/templates/module.rs.template @@ -1,18 +1,23 @@ use odra::prelude::*; -use odra::{Module, Variable, ContractEnv}; +use odra::Variable; -/// A #module_name module storage definition. +/// A module definition. Each module struct consists Variables and Mappings +/// or/and another modules. #[odra::module] pub struct #module_name { - env: Rc, + /// The module itself does not store the value, + /// it's a proxy that writes/reads value to/from the host. value: Variable, } -/// Module entrypoints implementation. +/// Module implementation. +/// +/// To generate entrypoints, +/// an implementation block must be marked as #[odra::module]. #[odra::module] impl #module_name { /// #module_name constructor. - /// Initializes the contract with the value of value. + /// Initializes the contract. pub fn init(&mut self) { self.value.set(false); } diff --git a/templates/workspace/.gitignore b/templates/workspace/.gitignore new file mode 100644 index 00000000..ea8c4bf7 --- /dev/null +++ b/templates/workspace/.gitignore @@ -0,0 +1 @@ +/target diff --git a/templates/workspace/CHANGELOG.md b/templates/workspace/CHANGELOG.md new file mode 100644 index 00000000..90583ee2 --- /dev/null +++ b/templates/workspace/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +Changelog for `{{project-name}}`. + +## [0.1.0] - {{date}} +### Added +- `flipper` module. +- `flapper` module. diff --git a/templates/workspace/Cargo.toml b/templates/workspace/Cargo.toml new file mode 100644 index 00000000..7a0f6ed9 --- /dev/null +++ b/templates/workspace/Cargo.toml @@ -0,0 +1,16 @@ +[workspace] +members = [ + "flipper", + "flapper", + ] +resolver = "2" + +[workspace.dependencies] +#odra_dependency + +[profile.release] +codegen-units = 1 +lto = true + +[profile.dev.package."*"] +opt-level = 3 diff --git a/templates/workspace/Odra.toml b/templates/workspace/Odra.toml new file mode 100644 index 00000000..f0fa5989 --- /dev/null +++ b/templates/workspace/Odra.toml @@ -0,0 +1,7 @@ +[[contracts]] +name = "Flipper" +fqn = "flipper::Flipper" + +[[contracts]] +name = "Flapper" +fqn = "flapper::Flapper" diff --git a/templates/workspace/README.md b/templates/workspace/README.md new file mode 100644 index 00000000..f8bceffe --- /dev/null +++ b/templates/workspace/README.md @@ -0,0 +1,31 @@ +# {{project-name}} + +## Usage +It's recommended to install +[cargo-odra](https://github.com/odradev/cargo-odra) first. + +### Build + +``` +$ cargo odra build +``` +To build a wasm file, you need to pass the -b parameter. +The result files will be placed in `${project-root}/wasm` directory. + +``` +$ cargo odra build -b casper +``` + +### Test +To run test on your local machine, you can basically execute the command: + +``` +$ cargo odra test +``` + +To test actual wasm files against a backend, +you need to specify the backend passing -b argument to `cargo-odra`. + +``` +$ cargo odra test -b casper +``` diff --git a/templates/workspace/flapper/.gitignore b/templates/workspace/flapper/.gitignore new file mode 100644 index 00000000..50623a06 --- /dev/null +++ b/templates/workspace/flapper/.gitignore @@ -0,0 +1,7 @@ +.idea +.vscode +/target +Cargo.lock +.backend* +.builder* +/wasm diff --git a/templates/workspace/flapper/Cargo.toml b/templates/workspace/flapper/Cargo.toml new file mode 100644 index 00000000..ba2bd0f6 --- /dev/null +++ b/templates/workspace/flapper/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "flapper" +version = "0.1.0" +edition = "2021" + +[dependencies] +odra = { workspace = true } + +[[bin]] +name = "flapper_build_contract" +path = "bin/build_contract.rs" +test = false + +[[bin]] +name = "flapper_build_schema" +path = "bin/build_schema.rs" +test = false diff --git a/templates/workspace/flapper/bin/build_contract.rs b/templates/workspace/flapper/bin/build_contract.rs new file mode 100644 index 00000000..15fb02de --- /dev/null +++ b/templates/workspace/flapper/bin/build_contract.rs @@ -0,0 +1,4 @@ +#![no_std] +#![no_main] +#![allow(unused_imports, clippy::single_component_path_imports)] +use flapper; diff --git a/templates/workspace/flapper/bin/build_schema.rs b/templates/workspace/flapper/bin/build_schema.rs new file mode 100644 index 00000000..a9631a54 --- /dev/null +++ b/templates/workspace/flapper/bin/build_schema.rs @@ -0,0 +1,10 @@ +use odra::contract_def::ContractBlueprint; + +extern "Rust" { + fn module_schema() -> ContractBlueprint; +} + +fn main() { + let schema = unsafe { module_schema() }; + println!("{:#?}", schema); +} diff --git a/templates/workspace/flapper/build.rs b/templates/workspace/flapper/build.rs new file mode 100644 index 00000000..7f61e3e8 --- /dev/null +++ b/templates/workspace/flapper/build.rs @@ -0,0 +1,8 @@ +use std::env; + +pub fn main() { + println!("cargo:rerun-if-env-changed=ODRA_MODULE"); + let module = env::var("ODRA_MODULE").unwrap_or_else(|_| "".to_string()); + let msg = format!("cargo:rustc-cfg=odra_module=\"{}\"", module); + println!("{}", msg); +} diff --git a/templates/workspace/flapper/src/flapper.rs b/templates/workspace/flapper/src/flapper.rs new file mode 100644 index 00000000..7d7e330e --- /dev/null +++ b/templates/workspace/flapper/src/flapper.rs @@ -0,0 +1,56 @@ +use odra::prelude::*; +use odra::Variable; + +/// A module definition. Each module struct consists Variables and Mappings +/// or/and another modules. +#[odra::module] +pub struct Flapper { + /// The module itself does not store the value, + /// it's a proxy that writes/reads value to/from the host. + value: Variable, +} + +/// Module implementation. +/// +/// To generate entrypoints, +/// an implementation block must be marked as #[odra::module]. +#[odra::module] +impl Flapper { + /// Odra constructor. + /// + /// Initializes the contract. + pub fn init(&mut self) { + self.value.set(false); + } + + /// Replaces the current value with the passed argument. + pub fn set(&mut self, value: bool) { + self.value.set(value); + } + + /// Replaces the current value with the opposite value. + pub fn flap(&mut self) { + self.value.set(!self.get()); + } + + /// Retrieves value from the storage. + /// If the value has never been set, the default value is returned. + pub fn get(&self) -> bool { + self.value.get_or_default() + } +} + +#[cfg(test)] +mod tests { + use crate::flapper::FlapperDeployer; + + #[test] + fn flapping() { + let env = odra::test_env(); + // To test a module we need to deploy it using autogenerated Deployer. + let mut contract = FlapperDeployer::init(&env); + assert!(!contract.get()); + contract.flap(); + assert!(contract.get()); + } +} diff --git a/templates/workspace/flapper/src/lib.rs b/templates/workspace/flapper/src/lib.rs new file mode 100644 index 00000000..89fb943d --- /dev/null +++ b/templates/workspace/flapper/src/lib.rs @@ -0,0 +1,5 @@ +#![cfg_attr(not(test), no_std)] +#![cfg_attr(not(test), no_main)] +extern crate alloc; + +pub mod flapper; diff --git a/templates/workspace/flipper/.gitignore b/templates/workspace/flipper/.gitignore new file mode 100644 index 00000000..50623a06 --- /dev/null +++ b/templates/workspace/flipper/.gitignore @@ -0,0 +1,7 @@ +.idea +.vscode +/target +Cargo.lock +.backend* +.builder* +/wasm diff --git a/templates/workspace/flipper/Cargo.toml b/templates/workspace/flipper/Cargo.toml new file mode 100644 index 00000000..eb78c7ae --- /dev/null +++ b/templates/workspace/flipper/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "flipper" +version = "0.1.0" +edition = "2021" + +[dependencies] +odra = { workspace = true } + +[[bin]] +name = "flipper_build_contract" +path = "bin/build_contract.rs" +test = false + +[[bin]] +name = "flipper_build_schema" +path = "bin/build_schema.rs" +test = false diff --git a/templates/workspace/flipper/bin/build_contract.rs b/templates/workspace/flipper/bin/build_contract.rs new file mode 100644 index 00000000..a19b4280 --- /dev/null +++ b/templates/workspace/flipper/bin/build_contract.rs @@ -0,0 +1,4 @@ +#![no_std] +#![no_main] +#![allow(unused_imports, clippy::single_component_path_imports)] +use flipper; diff --git a/templates/workspace/flipper/bin/build_schema.rs b/templates/workspace/flipper/bin/build_schema.rs new file mode 100644 index 00000000..a9631a54 --- /dev/null +++ b/templates/workspace/flipper/bin/build_schema.rs @@ -0,0 +1,10 @@ +use odra::contract_def::ContractBlueprint; + +extern "Rust" { + fn module_schema() -> ContractBlueprint; +} + +fn main() { + let schema = unsafe { module_schema() }; + println!("{:#?}", schema); +} diff --git a/templates/workspace/flipper/build.rs b/templates/workspace/flipper/build.rs new file mode 100644 index 00000000..7f61e3e8 --- /dev/null +++ b/templates/workspace/flipper/build.rs @@ -0,0 +1,8 @@ +use std::env; + +pub fn main() { + println!("cargo:rerun-if-env-changed=ODRA_MODULE"); + let module = env::var("ODRA_MODULE").unwrap_or_else(|_| "".to_string()); + let msg = format!("cargo:rustc-cfg=odra_module=\"{}\"", module); + println!("{}", msg); +} diff --git a/templates/workspace/flipper/src/flipper.rs b/templates/workspace/flipper/src/flipper.rs new file mode 100644 index 00000000..c629f841 --- /dev/null +++ b/templates/workspace/flipper/src/flipper.rs @@ -0,0 +1,56 @@ +use odra::prelude::*; +use odra::Variable; + +/// A module definition. Each module struct consists Variables and Mappings +/// or/and another modules. +#[odra::module] +pub struct Flipper { + /// The module itself does not store the value, + /// it's a proxy that writes/reads value to/from the host. + value: Variable, +} + +/// Module implementation. +/// +/// To generate entrypoints, +/// an implementation block must be marked as #[odra::module]. +#[odra::module] +impl Flipper { + /// Odra constructor. + /// + /// Initializes the contract. + pub fn init(&mut self) { + self.value.set(false); + } + + /// Replaces the current value with the passed argument. + pub fn set(&mut self, value: bool) { + self.value.set(value); + } + + /// Replaces the current value with the opposite value. + pub fn flip(&mut self) { + self.value.set(!self.get()); + } + + /// Retrieves value from the storage. + /// If the value has never been set, the default value is returned. + pub fn get(&self) -> bool { + self.value.get_or_default() + } +} + +#[cfg(test)] +mod tests { + use crate::flipper::FlipperDeployer; + + #[test] + fn flipping() { + let env = odra::test_env(); + // To test a module we need to deploy it using autogenerated Deployer. + let mut contract = FlipperDeployer::init(&env); + assert!(!contract.get()); + contract.flip(); + assert!(contract.get()); + } +} diff --git a/templates/workspace/flipper/src/lib.rs b/templates/workspace/flipper/src/lib.rs new file mode 100644 index 00000000..df27ba35 --- /dev/null +++ b/templates/workspace/flipper/src/lib.rs @@ -0,0 +1,5 @@ +#![cfg_attr(not(test), no_std)] +#![cfg_attr(not(test), no_main)] +extern crate alloc; + +pub mod flipper; diff --git a/templates/workspace/rust-toolchain b/templates/workspace/rust-toolchain new file mode 100644 index 00000000..b6f2add3 --- /dev/null +++ b/templates/workspace/rust-toolchain @@ -0,0 +1 @@ +nightly-2023-03-01