From e2e2290c5dc2d9cdc44da2f9f47232a7f2771ba3 Mon Sep 17 00:00:00 2001 From: Peter White Date: Mon, 11 Mar 2024 15:09:35 -0600 Subject: [PATCH 1/3] feat(pop-api): add demo contract and unit test for placing a spot order --- pop-api/examples/place-spot-order/.gitignore | 9 +++ pop-api/examples/place-spot-order/Cargo.toml | 28 ++++++++ pop-api/examples/place-spot-order/lib.rs | 67 ++++++++++++++++++++ runtime/src/extensions.rs | 65 +++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100755 pop-api/examples/place-spot-order/.gitignore create mode 100755 pop-api/examples/place-spot-order/Cargo.toml create mode 100755 pop-api/examples/place-spot-order/lib.rs diff --git a/pop-api/examples/place-spot-order/.gitignore b/pop-api/examples/place-spot-order/.gitignore new file mode 100755 index 00000000..8de8f877 --- /dev/null +++ b/pop-api/examples/place-spot-order/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock diff --git a/pop-api/examples/place-spot-order/Cargo.toml b/pop-api/examples/place-spot-order/Cargo.toml new file mode 100755 index 00000000..15299a54 --- /dev/null +++ b/pop-api/examples/place-spot-order/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "pop_api_spot_order_example" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "4.3.0", default-features = false } +pop-api = { path = "../../../pop-api", default-features = false } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } + +[dev-dependencies] +ink_e2e = "4.3.0" + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "pop-api/std", + "scale/std", + "scale-info/std", +] +ink-as-dependency = [] +e2e-tests = [] diff --git a/pop-api/examples/place-spot-order/lib.rs b/pop-api/examples/place-spot-order/lib.rs new file mode 100755 index 00000000..e8994f69 --- /dev/null +++ b/pop-api/examples/place-spot-order/lib.rs @@ -0,0 +1,67 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +use pop_api::nfts; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum ContractError { + InvalidCollection, + ItemAlreadyExists, + NftsError(nfts::Error), + NotOwner, +} + +impl From for ContractError { + fn from(value: nfts::Error) -> Self { + ContractError::NftsError(value) + } +} + +#[ink::contract(env = pop_api::Environment)] +mod pop_api_spot_order_example { + use super::ContractError; + + #[ink(storage)] + #[derive(Default)] + pub struct PopApiSpotOrderExample; + + impl PopApiSpotOrderExample { + #[ink(constructor, payable)] + pub fn new() -> Self { + ink::env::debug_println!("Contract::new"); + Default::default() + } + + #[ink(message)] + pub fn place_spot_order( + &mut self, + max_amount: Balance, + para_id: u32, + ) -> Result<(), ContractError> { + ink::env::debug_println!( + "Contract::place_spot_order: max_amount {:?} para_id: {:?} ", + max_amount, + para_id, + ); + + let res = pop_api::cross_chain::coretime::place_spot_order(max_amount, para_id); + ink::env::debug_println!( + "Contract::place_spot_order: res {:?} ", + res, + ); + + ink::env::debug_println!("Contract::place_spot_order end"); + Ok(()) + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[ink::test] + fn default_works() { + PopApiSpotOrderExample::new(); + } + } +} diff --git a/runtime/src/extensions.rs b/runtime/src/extensions.rs index d4f18a82..8de2ad0e 100644 --- a/runtime/src/extensions.rs +++ b/runtime/src/extensions.rs @@ -663,4 +663,69 @@ mod tests { assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); }); } + + #[test] + #[ignore] + fn place_spot_order_from_contract_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + + let (wasm_binary, _) = load_wasm_module::( + "../pop-api/examples/place-spot-order/target/ink/pop_api_spot_order_example.wasm", + ) + .unwrap(); + + let init_value = 100 * UNIT; + + let result = Contracts::bare_instantiate( + ALICE, + init_value, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + function_selector("new"), + vec![], + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + ) + .result + .unwrap(); + + assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); + + let addr = result.account_id; + + let function = function_selector("place_spot_order"); + + let max_amount = 1 * UNIT; + let para_id = 2000; + + let params = + [function, max_amount.encode(), para_id.encode()].concat(); + + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), + None, + params, + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + pallet_contracts::Determinism::Enforced, + ); + + if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { + log::debug!( + "Contract debug buffer - {:?}", + String::from_utf8(result.debug_message.clone()) + ); + log::debug!("result: {:?}", result); + } + + // check for revert + assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); + + }); + } } From dfabc1baabcd4e79080ed7ad91e76cf575b9e836 Mon Sep 17 00:00:00 2001 From: Peter White Date: Mon, 11 Mar 2024 15:49:13 -0600 Subject: [PATCH 2/3] fix(pop-api): update origin and weight to make XCM calls work --- runtime/src/extensions.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/runtime/src/extensions.rs b/runtime/src/extensions.rs index 8de2ad0e..fb811cf8 100644 --- a/runtime/src/extensions.rs +++ b/runtime/src/extensions.rs @@ -107,6 +107,7 @@ impl TryFrom for v0::FuncId { fn dispatch_call( env: &mut Environment, call: RuntimeCall, + origin: RuntimeOrigin, log_prefix: &str, ) -> Result<(), DispatchError> where @@ -118,9 +119,6 @@ where log::debug!(target:LOG_TARGET, "{} inputted RuntimeCall: {:?}", log_prefix, call); - // contract is the origin by default - let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); - match call.dispatch(origin) { Ok(info) => { log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); @@ -182,7 +180,10 @@ where // read the input as RuntimeCall let call: RuntimeCall = env.read_as_unbounded(len)?; - dispatch_call::(&mut env, call, LOG_PREFIX) + // contract is the origin by default + let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); + + dispatch_call::(&mut env, call, origin, LOG_PREFIX) } fn read_state(env: Environment) -> Result<(), DispatchError> @@ -313,7 +314,7 @@ where .buy_execution(assets.clone().into(), Unlimited) .transact( SovereignAccount, - Weight::from_parts(25_000_000, 10_000), + Weight::from_parts(250_000_000, 10_000), message.encode().into(), ) .refund_surplus() @@ -323,13 +324,15 @@ where }, }; + let origin: RuntimeOrigin = RawOrigin::Root.into(); + // Generate runtime call to dispatch let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { dest: Box::new(dest), message: Box::new(VersionedXcm::V4(message)), }); - dispatch_call::(&mut env, call, LOG_PREFIX) + dispatch_call::(&mut env, call, origin, LOG_PREFIX) } #[cfg(test)] From 0b9f658bff7736e9ae0fe763345b38e83aaa3beb Mon Sep 17 00:00:00 2001 From: Frank Bell Date: Tue, 12 Mar 2024 09:56:58 +0000 Subject: [PATCH 3/3] style: formatting --- runtime/src/extensions.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/runtime/src/extensions.rs b/runtime/src/extensions.rs index fb811cf8..d8696cbe 100644 --- a/runtime/src/extensions.rs +++ b/runtime/src/extensions.rs @@ -703,8 +703,7 @@ mod tests { let max_amount = 1 * UNIT; let para_id = 2000; - let params = - [function, max_amount.encode(), para_id.encode()].concat(); + let params = [function, max_amount.encode(), para_id.encode()].concat(); let result = Contracts::bare_call( ALICE, @@ -728,7 +727,6 @@ mod tests { // check for revert assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - }); } }