diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 5e04e1e1..044458fe 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -304,9 +304,9 @@ fn reserve_transfer_native_asset_from_relay_to_para() { /// Reserve Transfers of native asset from Parachain to Relay should work #[test] fn reserve_transfer_native_asset_from_para_to_relay() { - init_tracing(); + init_tracing(); - // Setup: reserve transfer from relay to Pop, so that sovereign account accurate for return + // Setup: reserve transfer from relay to Pop, so that sovereign account accurate for return // transfer let amount_to_send: Balance = ROCOCO_ED * 1000; fund_pop_network(RococoRelaySender::get(), amount_to_send, PopNetworkParaReceiver::get()); diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index ee3f5554..b1490902 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] enumflags2 = { version = "0.7.7" } -ink = { version = "4.3.0", default-features = false } +ink = { version = "5.0.0-rc.3", 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"] } sp-io = { version = "23.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } diff --git a/pop-api/examples/balance-transfer/Cargo.toml b/pop-api/examples/balance-transfer/Cargo.toml index 20c307ee..fcac5e73 100755 --- a/pop-api/examples/balance-transfer/Cargo.toml +++ b/pop-api/examples/balance-transfer/Cargo.toml @@ -5,7 +5,7 @@ authors = ["[your_name] <[your_email]>"] edition = "2021" [dependencies] -ink = { version = "4.3.0", default-features = false } +ink = { version = "5.0.0-rc.3", 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 } diff --git a/pop-api/examples/nfts/Cargo.toml b/pop-api/examples/nfts/Cargo.toml index 7b148648..49c49f64 100755 --- a/pop-api/examples/nfts/Cargo.toml +++ b/pop-api/examples/nfts/Cargo.toml @@ -5,14 +5,11 @@ authors = ["[your_name] <[your_email]>"] edition = "2021" [dependencies] -ink = { version = "4.3.0", default-features = false } +ink = { version = "5.0.0-rc.3", 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" 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..a596805d --- /dev/null +++ b/pop-api/examples/place-spot-order/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "pop_api_spot_order_example" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "5.0.0-rc.3", 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 } + +[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/pop-api/examples/read-runtime-state/Cargo.toml b/pop-api/examples/read-runtime-state/Cargo.toml index 20c307ee..e1c898a3 100755 --- a/pop-api/examples/read-runtime-state/Cargo.toml +++ b/pop-api/examples/read-runtime-state/Cargo.toml @@ -5,14 +5,11 @@ authors = ["[your_name] <[your_email]>"] edition = "2021" [dependencies] -ink = { version = "4.3.0", default-features = false } +ink = { version = "5.0.0-rc.3", 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" diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 840b98c4..fe2d8c7d 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -62,19 +62,19 @@ impl ink::env::Environment for Environment { type ChainExtension = PopApi; } -#[ink::chain_extension] +#[ink::chain_extension(extension = 909)] pub trait PopApi { type ErrorCode = PopApiError; - #[ink(extension = 0)] + #[ink(function = 0)] #[allow(private_interfaces)] fn dispatch(call: RuntimeCall) -> Result<()>; - #[ink(extension = 1)] + #[ink(function = 1)] #[allow(private_interfaces)] fn read_state(key: RuntimeStateKeys) -> Result>; - #[ink(extension = 2)] + #[ink(function = 2)] #[allow(private_interfaces)] fn send_xcm(xcm: CrossChainMessage) -> Result<()>; } diff --git a/runtime/src/extensions.rs b/runtime/src/extensions.rs index 48af0815..8b032b89 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> @@ -320,7 +321,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() @@ -330,13 +331,16 @@ where }, }; + // TODO: revisit to replace with signed contract origin + 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)] @@ -619,7 +623,7 @@ mod tests { let _ = env_logger::try_init(); let (wasm_binary, _) = load_wasm_module::( - "../pop-api/examples/read-runtime-state/target/ink/pop_api_read_state_example.wasm", + "../pop-api/examples/read-runtime-state/target/ink/pop_api_extension_demo.wasm", ) .unwrap(); @@ -670,4 +674,67 @@ 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!"); + }); + } }