From 31cfcdc54c329fd2405ff2370789048bb49fbc06 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelhas Date: Thu, 13 Oct 2022 11:21:19 +0100 Subject: [PATCH 1/3] feat(acurast-receiver): adds pallet that allows target parachains to receive fulfillments from acurast --- pallets/acurast-receiver/Cargo.toml | 49 +++++++ pallets/acurast-receiver/README.md | 86 ++++++++++++ pallets/acurast-receiver/src/benchmarking.rs | 12 ++ pallets/acurast-receiver/src/lib.rs | 78 +++++++++++ pallets/acurast-receiver/src/mock.rs | 139 +++++++++++++++++++ pallets/acurast-receiver/src/tests.rs | 33 +++++ pallets/acurast-receiver/src/traits.rs | 18 +++ 7 files changed, 415 insertions(+) create mode 100644 pallets/acurast-receiver/Cargo.toml create mode 100644 pallets/acurast-receiver/README.md create mode 100644 pallets/acurast-receiver/src/benchmarking.rs create mode 100644 pallets/acurast-receiver/src/lib.rs create mode 100644 pallets/acurast-receiver/src/mock.rs create mode 100644 pallets/acurast-receiver/src/tests.rs create mode 100644 pallets/acurast-receiver/src/traits.rs diff --git a/pallets/acurast-receiver/Cargo.toml b/pallets/acurast-receiver/Cargo.toml new file mode 100644 index 00000000..5ef9d53a --- /dev/null +++ b/pallets/acurast-receiver/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "pallet-acurast-receiver" +authors = ["Papers AG"] +description = "Pallet for defining the receiving logic from acurast parachain." +version = "0.0.1" +license = "Unlicense" +homepage = "https://docs.acurast.com/" +edition = "2021" +publish = false +repository = "https://github.com/acurast/" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ + "derive", +] } + +# Benchmarks +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", optional = true, default-features = false } + +# Substrate +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } +scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } + +[dev-dependencies] +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } +# XCM +xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.29" } +xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.29" } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.29" } + +[features] +default = ["std"] +std = [ + "codec/std", + "scale-info/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking/std", +] + +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/acurast-receiver/README.md b/pallets/acurast-receiver/README.md new file mode 100644 index 00000000..fea8ecdc --- /dev/null +++ b/pallets/acurast-receiver/README.md @@ -0,0 +1,86 @@ +# Acurast Receiver Pallet + +## 🚧🚧🚧 The project is still a work in progress 🚧🚧🚧 + +## Introduction + +The `pallet-acurast-receiver` adds support for parachains to receive [XCM](https://wiki.polkadot.network/docs/learn-xcm) messages from [Acurast parachain](https://docs.acurast.com/). + +The Pallet exposes the following extrinsics. + +### fulfill + +Allows to post the fulfillment of a registered job. The `fulfill` call will fail if the job was not previously assigned to the origin. The fulfillment structure consists of: + +## Setup + +1. Add the following dependency to your Cargo manifest: + +```toml +[dependencies] +pallet-acurast-receiver = { git = "https://github.com/Acurast/acurast-core.git" } +``` + +2. Implement `pallet_acurast_receiver::Config` for your `Runtime` and add the Pallet: + +```rust +/// Runtime example + +pub struct ParachainBarrier; +impl pallet_acurast_receiver::traits::ParachainBarrier for ParachainBarrier { + fn ensure_xcm_origin( + origin: frame_system::pallet_prelude::OriginFor, + ) -> Result<(), sp_runtime::DispatchError> { + // List of allowd parachains + let allowed_parachains = [ + // The Acurast parachain identifier + xcm::opaque::latest::Junction::Parachain(2001), + ]; + + // Ensure that the call comes from an xcm message + let location = pallet_xcm::ensure_xcm(origin)?; + + let is_valid_origin = location + .interior() + .iter() + .any(|junction| allowed_parachains.contains(junction)); + + if !is_valid_origin { + return Err(sp_runtime::DispatchError::Other( + "MultiLocation not allowed.", + )); + } + + Ok(()) + } +} + +pub struct OnAcurastFulfillment; +impl pallet_acurast_receiver::traits::OnFulfillment for OnAcurastFulfillment { + fn fulfill( + payload: &[u8], + ) -> sp_runtime::DispatchResultWithInfo { + // handle payload (e.i. Call a contract) + } +} + +impl pallet_acurast_receiver::Config for Runtime { + type Event = Event; + type Payload = sp_runtime::bounded::bounded_vec::BoundedVec>; + type OnFulfillment = OnAcurastFulfillment; + type Barrier = ParachainBarrier; +} + +// Add pallet to the runtime +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + // All your other pallets + ... + AcurastReceiver: pallet_acurast_receiver::{Pallet, Storage, Call, Event}; + } +); +``` diff --git a/pallets/acurast-receiver/src/benchmarking.rs b/pallets/acurast-receiver/src/benchmarking.rs new file mode 100644 index 00000000..9bdbd6ee --- /dev/null +++ b/pallets/acurast-receiver/src/benchmarking.rs @@ -0,0 +1,12 @@ +//! Benchmarking setup for pallet-template + +use super::*; + +#[allow(unused)] +use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_system::RawOrigin; + +benchmarks! { + // TODO: add benchmarks + impl_benchmark_test_suite!(crate::Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/acurast-receiver/src/lib.rs b/pallets/acurast-receiver/src/lib.rs new file mode 100644 index 00000000..ea231ef2 --- /dev/null +++ b/pallets/acurast-receiver/src/lib.rs @@ -0,0 +1,78 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +pub mod traits; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +#[frame_support::pallet] +pub mod pallet { + use crate::traits::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::OriginFor; + + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type Event: From> + IsType<::Event>; + /// The fulfillment payload. + type Payload: Parameter + + Member + + MaxEncodedLen + + Clone + + Into>; + /// Handler to notify the runtime when a new fulfillment is received. + type OnFulfillment: OnFulfillment; + /// Handle origin validation + type Barrier: ParachainBarrier; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + /// TODO: We may want to add a storage for job identifiers, allowing acurast parachain to send + /// the (job identifer + payload). The requester address would be indexed by job identifier. + + // Pallets use events to inform users when important changes are made. + // https://docs.substrate.io/v3/runtime/events-and-errors + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + FulfillReceived(T::Payload), + } + + // Errors inform users that something went wrong. + #[pallet::error] + pub enum Error {} + + #[pallet::call] + impl Pallet { + /// Dispatchable function that notifies the runtime about a fulfilment coming from acurast parachain. + #[pallet::weight(Weight::from_ref_time(10_000).saturating_add(T::DbWeight::get().writes(1)))] + pub fn fulfill(origin: OriginFor, payload: T::Payload) -> DispatchResult { + // Check that the extrinsic comes from a trusted xcm channel. + T::Barrier::ensure_xcm_origin(origin)?; + + // Notify the runtime about the fulfillment. + match T::OnFulfillment::fulfill(&payload.clone().into()) { + Err(err) => Err(err.error), + Ok(_) => { + // Emit events + Self::deposit_event(Event::FulfillReceived(payload)); + + Ok(()) + } + } + } + } +} diff --git a/pallets/acurast-receiver/src/mock.rs b/pallets/acurast-receiver/src/mock.rs new file mode 100644 index 00000000..5c1ea670 --- /dev/null +++ b/pallets/acurast-receiver/src/mock.rs @@ -0,0 +1,139 @@ +use crate as pallet_acurast_receiver; +use frame_support::{ + traits::{ConstU16, ConstU32, ConstU64, Everything, Nothing}, + weights::{Pays, PostDispatchInfo}, + BoundedVec, +}; +use frame_system as system; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; +use xcm::v2::Junction::Parachain; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + AcurastReceiver: pallet_acurast_receiver::{Pallet, Call, Storage, Event}, + PolkadotXcm: pallet_xcm::{Pallet, Storage, Call, Event, Origin, Config}, + } +); + +frame_support::parameter_types! { + /// The amount of weight an XCM operation takes. This is safe overestimate. + pub UnitWeightCost: xcm::v2::Weight = 200_000_000; + /// Maximum number of instructions in a single XCM fragment. A sanity check against + /// weight caculations getting too crazy. + pub MaxInstructions: u32 = 100; + // The ancestry, defines the multilocation describing this consensus system + pub Ancestry: xcm::v2::MultiLocation = Parachain(2001).into(); +} + +impl pallet_xcm::Config for Test { + type Event = Event; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = (); + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Nothing; + type XcmExecutor = (); + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = xcm_builder::FixedWeightBounds; + type LocationInverter = xcm_builder::LocationInverter; + type Origin = Origin; + type Call = Call; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; +} + +impl system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = ConstU16<42>; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +pub struct OnAcurastFulfillment; +impl crate::traits::OnFulfillment for OnAcurastFulfillment { + fn fulfill( + _payload: &[u8], + ) -> frame_support::sp_runtime::DispatchResultWithInfo { + Ok(PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::No, + }) + } +} + +pub struct ParachainBarrier; +impl crate::traits::ParachainBarrier for ParachainBarrier { + fn ensure_xcm_origin( + origin: frame_system::pallet_prelude::OriginFor, + ) -> Result<(), sp_runtime::DispatchError> { + // List of allowd parachains + let allowed_parachains = [ + // Acurast + xcm::opaque::latest::Junction::Parachain(2001), + ]; + + // Ensure that the call comes from an xcm message + let location = pallet_xcm::ensure_xcm(origin)?; + + let is_valid_origin = location + .interior() + .iter() + .any(|junction| allowed_parachains.contains(junction)); + + if !is_valid_origin { + return Err(sp_runtime::DispatchError::Other( + "MultiLocation not allowed.", + )); + } + + Ok(()) + } +} + +impl pallet_acurast_receiver::Config for Test { + type Event = Event; + type Payload = BoundedVec>; + type OnFulfillment = OnAcurastFulfillment; + type Barrier = ParachainBarrier; +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + system::GenesisConfig::default() + .build_storage::() + .unwrap() + .into() +} diff --git a/pallets/acurast-receiver/src/tests.rs b/pallets/acurast-receiver/src/tests.rs new file mode 100644 index 00000000..82fa3062 --- /dev/null +++ b/pallets/acurast-receiver/src/tests.rs @@ -0,0 +1,33 @@ +use crate::mock::*; +use frame_support::{assert_err, assert_ok, traits::ConstU32, BoundedVec}; +use xcm::v2::{Junction::Parachain, Junctions::X1, MultiLocation}; + +#[test] +fn test_fulfill() { + let payload: BoundedVec> = vec![0; 128].try_into().unwrap(); + + new_test_ext().execute_with(|| { + // Mock and xcm origin + let xcm_origin = Origin::from(pallet_xcm::Origin::Xcm(MultiLocation { + parents: 1, + interior: X1(Parachain(2001)), + })); + + // Dispatch fulfill extrinsic with valid origin. + assert_ok!(AcurastReceiver::fulfill(xcm_origin, payload.clone())); + }); + + new_test_ext().execute_with(|| { + // Mock and xcm origin + let xcm_origin = Origin::from(pallet_xcm::Origin::Xcm(MultiLocation { + parents: 1, + interior: X1(Parachain(2000)), + })); + + // Dispatch fulfill extrinsic with wrong origin. + assert_err!( + AcurastReceiver::fulfill(xcm_origin, payload.clone()), + "MultiLocation not allowed." + ); + }); +} diff --git a/pallets/acurast-receiver/src/traits.rs b/pallets/acurast-receiver/src/traits.rs new file mode 100644 index 00000000..40704724 --- /dev/null +++ b/pallets/acurast-receiver/src/traits.rs @@ -0,0 +1,18 @@ +use frame_support::weights::PostDispatchInfo; +use frame_system::pallet_prelude::OriginFor; + +use crate::Config; + +/// Handle fulfillment messages. +pub trait OnFulfillment { + fn fulfill( + payload: &[u8], + ) -> frame_support::sp_runtime::DispatchResultWithInfo; +} + +/// Allows execution only from trusted origins. +pub trait ParachainBarrier { + fn ensure_xcm_origin( + origin: OriginFor, + ) -> Result<(), frame_support::sp_runtime::DispatchError>; +} From 5f4036b988444637036bf31edd573e28362e56c2 Mon Sep 17 00:00:00 2001 From: Mike Godenzi Date: Thu, 20 Oct 2022 09:27:05 +0200 Subject: [PATCH 2/3] feat(acurast-receiver-pallet-generic-routing): modified interface to accept optional bytes --- pallets/acurast-receiver/Cargo.toml | 6 +- pallets/acurast-receiver/src/benchmarking.rs | 16 +- pallets/acurast-receiver/src/lib.rs | 110 ++++++----- pallets/acurast-receiver/src/mock.rs | 194 ++++++++++--------- pallets/acurast-receiver/src/tests.rs | 46 ++--- pallets/acurast-receiver/src/traits.rs | 16 +- 6 files changed, 198 insertions(+), 190 deletions(-) diff --git a/pallets/acurast-receiver/Cargo.toml b/pallets/acurast-receiver/Cargo.toml index 5ef9d53a..9b1c8190 100644 --- a/pallets/acurast-receiver/Cargo.toml +++ b/pallets/acurast-receiver/Cargo.toml @@ -13,9 +13,7 @@ repository = "https://github.com/acurast/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ - "derive", -] } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } # Benchmarks frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", optional = true, default-features = false } @@ -24,11 +22,11 @@ frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } [dev-dependencies] sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false } # XCM xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.29" } diff --git a/pallets/acurast-receiver/src/benchmarking.rs b/pallets/acurast-receiver/src/benchmarking.rs index 9bdbd6ee..49d3283c 100644 --- a/pallets/acurast-receiver/src/benchmarking.rs +++ b/pallets/acurast-receiver/src/benchmarking.rs @@ -1,12 +1,12 @@ //! Benchmarking setup for pallet-template -use super::*; +// use super::*; -#[allow(unused)] -use frame_benchmarking::{benchmarks, whitelisted_caller}; -use frame_system::RawOrigin; +// #[allow(unused)] +// use frame_benchmarking::{benchmarks, whitelisted_caller}; +// use frame_system::RawOrigin; -benchmarks! { - // TODO: add benchmarks - impl_benchmark_test_suite!(crate::Pallet, crate::mock::new_test_ext(), crate::mock::Test); -} +// benchmarks! { +// // TODO: add benchmarks +// impl_benchmark_test_suite!(crate::Pallet, crate::mock::new_test_ext(), crate::mock::Test); +// } diff --git a/pallets/acurast-receiver/src/lib.rs b/pallets/acurast-receiver/src/lib.rs index ea231ef2..6b176694 100644 --- a/pallets/acurast-receiver/src/lib.rs +++ b/pallets/acurast-receiver/src/lib.rs @@ -15,64 +15,70 @@ mod benchmarking; #[frame_support::pallet] pub mod pallet { - use crate::traits::*; - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::OriginFor; + use crate::traits::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::OriginFor; + use sp_std::prelude::*; - /// Configure the pallet by specifying the parameters and types on which it depends. - #[pallet::config] - pub trait Config: frame_system::Config { - /// Because this pallet emits events, it depends on the runtime's definition of an event. - type Event: From> + IsType<::Event>; - /// The fulfillment payload. - type Payload: Parameter - + Member - + MaxEncodedLen - + Clone - + Into>; - /// Handler to notify the runtime when a new fulfillment is received. - type OnFulfillment: OnFulfillment; - /// Handle origin validation - type Barrier: ParachainBarrier; - } + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type Event: From> + IsType<::Event>; + /// The fulfillment payload. + type Payload: Parameter + Member + Clone + Into>; + /// Generic parameters + type Parameters: Parameter + Member + Clone + Into>; + /// Handler to notify the runtime when a new fulfillment is received. + type OnFulfillment: OnFulfillment; + /// Handle origin validation + type Barrier: ParachainBarrier; + } - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(_); + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); - /// TODO: We may want to add a storage for job identifiers, allowing acurast parachain to send - /// the (job identifer + payload). The requester address would be indexed by job identifier. + /// TODO: We may want to add a storage for job identifiers, allowing acurast parachain to send + /// the (job identifer + payload). The requester address would be indexed by job identifier. - // Pallets use events to inform users when important changes are made. - // https://docs.substrate.io/v3/runtime/events-and-errors - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - FulfillReceived(T::Payload), - } + // Pallets use events to inform users when important changes are made. + // https://docs.substrate.io/v3/runtime/events-and-errors + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + FulfillReceived(T::Payload, Option), + } - // Errors inform users that something went wrong. - #[pallet::error] - pub enum Error {} + // Errors inform users that something went wrong. + #[pallet::error] + pub enum Error {} - #[pallet::call] - impl Pallet { - /// Dispatchable function that notifies the runtime about a fulfilment coming from acurast parachain. - #[pallet::weight(Weight::from_ref_time(10_000).saturating_add(T::DbWeight::get().writes(1)))] - pub fn fulfill(origin: OriginFor, payload: T::Payload) -> DispatchResult { - // Check that the extrinsic comes from a trusted xcm channel. - T::Barrier::ensure_xcm_origin(origin)?; + #[pallet::call] + impl Pallet { + /// Dispatchable function that notifies the runtime about a fulfilment coming from acurast parachain. + #[pallet::weight(Weight::from_ref_time(10_000).saturating_add(T::DbWeight::get().writes(1)))] + pub fn fulfill( + origin: OriginFor, + payload: T::Payload, + parameters: Option, + ) -> DispatchResult { + // Check that the extrinsic comes from a trusted xcm channel. + T::Barrier::ensure_xcm_origin(origin)?; - // Notify the runtime about the fulfillment. - match T::OnFulfillment::fulfill(&payload.clone().into()) { - Err(err) => Err(err.error), - Ok(_) => { - // Emit events - Self::deposit_event(Event::FulfillReceived(payload)); + // Notify the runtime about the fulfillment. + match T::OnFulfillment::fulfill( + payload.clone().into(), + parameters.clone().map(|parameters| parameters.into()), + ) { + Err(err) => Err(err.error), + Ok(_) => { + // Emit events + Self::deposit_event(Event::FulfillReceived(payload, parameters)); - Ok(()) - } - } - } - } + Ok(()) + } + } + } + } } diff --git a/pallets/acurast-receiver/src/mock.rs b/pallets/acurast-receiver/src/mock.rs index 5c1ea670..a5417954 100644 --- a/pallets/acurast-receiver/src/mock.rs +++ b/pallets/acurast-receiver/src/mock.rs @@ -1,15 +1,15 @@ use crate as pallet_acurast_receiver; use frame_support::{ - traits::{ConstU16, ConstU32, ConstU64, Everything, Nothing}, - weights::{Pays, PostDispatchInfo}, - BoundedVec, + traits::{ConstU16, ConstU64, Everything, Nothing}, + weights::{Pays, PostDispatchInfo}, }; use frame_system as system; use sp_core::H256; use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, }; +use sp_std::prelude::*; use xcm::v2::Junction::Parachain; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; @@ -17,123 +17,125 @@ type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - AcurastReceiver: pallet_acurast_receiver::{Pallet, Call, Storage, Event}, - PolkadotXcm: pallet_xcm::{Pallet, Storage, Call, Event, Origin, Config}, - } + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + AcurastReceiver: pallet_acurast_receiver::{Pallet, Call, Storage, Event}, + PolkadotXcm: pallet_xcm::{Pallet, Storage, Call, Event, Origin, Config}, + } ); frame_support::parameter_types! { - /// The amount of weight an XCM operation takes. This is safe overestimate. - pub UnitWeightCost: xcm::v2::Weight = 200_000_000; - /// Maximum number of instructions in a single XCM fragment. A sanity check against - /// weight caculations getting too crazy. - pub MaxInstructions: u32 = 100; - // The ancestry, defines the multilocation describing this consensus system - pub Ancestry: xcm::v2::MultiLocation = Parachain(2001).into(); + /// The amount of weight an XCM operation takes. This is safe overestimate. + pub UnitWeightCost: xcm::v2::Weight = 200_000_000; + /// Maximum number of instructions in a single XCM fragment. A sanity check against + /// weight caculations getting too crazy. + pub MaxInstructions: u32 = 100; + // The ancestry, defines the multilocation describing this consensus system + pub Ancestry: xcm::v2::MultiLocation = Parachain(2001).into(); } impl pallet_xcm::Config for Test { - type Event = Event; - type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; - type XcmRouter = (); - type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; - type XcmExecuteFilter = Nothing; - type XcmExecutor = (); - type XcmTeleportFilter = Nothing; - type XcmReserveTransferFilter = Everything; - type Weigher = xcm_builder::FixedWeightBounds; - type LocationInverter = xcm_builder::LocationInverter; - type Origin = Origin; - type Call = Call; - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Event = Event; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = (); + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Nothing; + type XcmExecutor = (); + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = xcm_builder::FixedWeightBounds; + type LocationInverter = xcm_builder::LocationInverter; + type Origin = Origin; + type Call = Call; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; } impl system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type Origin = Origin; - type Call = Call; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type BlockHashCount = ConstU64<250>; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = ConstU16<42>; - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = ConstU16<42>; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; } pub struct OnAcurastFulfillment; impl crate::traits::OnFulfillment for OnAcurastFulfillment { - fn fulfill( - _payload: &[u8], - ) -> frame_support::sp_runtime::DispatchResultWithInfo { - Ok(PostDispatchInfo { - actual_weight: None, - pays_fee: Pays::No, - }) - } + fn fulfill( + _payload: Vec, + _parameters: Option>, + ) -> frame_support::sp_runtime::DispatchResultWithInfo { + Ok(PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::No, + }) + } } pub struct ParachainBarrier; impl crate::traits::ParachainBarrier for ParachainBarrier { - fn ensure_xcm_origin( - origin: frame_system::pallet_prelude::OriginFor, - ) -> Result<(), sp_runtime::DispatchError> { - // List of allowd parachains - let allowed_parachains = [ - // Acurast - xcm::opaque::latest::Junction::Parachain(2001), - ]; + fn ensure_xcm_origin( + origin: frame_system::pallet_prelude::OriginFor, + ) -> Result<(), sp_runtime::DispatchError> { + // List of allowd parachains + let allowed_parachains = [ + // Acurast + xcm::opaque::latest::Junction::Parachain(2001), + ]; - // Ensure that the call comes from an xcm message - let location = pallet_xcm::ensure_xcm(origin)?; + // Ensure that the call comes from an xcm message + let location = pallet_xcm::ensure_xcm(origin)?; - let is_valid_origin = location - .interior() - .iter() - .any(|junction| allowed_parachains.contains(junction)); + let is_valid_origin = location + .interior() + .iter() + .any(|junction| allowed_parachains.contains(junction)); - if !is_valid_origin { - return Err(sp_runtime::DispatchError::Other( - "MultiLocation not allowed.", - )); - } + if !is_valid_origin { + return Err(sp_runtime::DispatchError::Other( + "MultiLocation not allowed.", + )); + } - Ok(()) - } + Ok(()) + } } impl pallet_acurast_receiver::Config for Test { - type Event = Event; - type Payload = BoundedVec>; - type OnFulfillment = OnAcurastFulfillment; - type Barrier = ParachainBarrier; + type Event = Event; + type Payload = Vec; + type Parameters = Vec; + type OnFulfillment = OnAcurastFulfillment; + type Barrier = ParachainBarrier; } // Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { - system::GenesisConfig::default() - .build_storage::() - .unwrap() - .into() + system::GenesisConfig::default() + .build_storage::() + .unwrap() + .into() } diff --git a/pallets/acurast-receiver/src/tests.rs b/pallets/acurast-receiver/src/tests.rs index 82fa3062..8d69d3ba 100644 --- a/pallets/acurast-receiver/src/tests.rs +++ b/pallets/acurast-receiver/src/tests.rs @@ -1,33 +1,33 @@ use crate::mock::*; -use frame_support::{assert_err, assert_ok, traits::ConstU32, BoundedVec}; +use frame_support::{assert_err, assert_ok}; use xcm::v2::{Junction::Parachain, Junctions::X1, MultiLocation}; #[test] fn test_fulfill() { - let payload: BoundedVec> = vec![0; 128].try_into().unwrap(); + let payload = vec![0u8; 128]; - new_test_ext().execute_with(|| { - // Mock and xcm origin - let xcm_origin = Origin::from(pallet_xcm::Origin::Xcm(MultiLocation { - parents: 1, - interior: X1(Parachain(2001)), - })); + new_test_ext().execute_with(|| { + // Mock and xcm origin + let xcm_origin = Origin::from(pallet_xcm::Origin::Xcm(MultiLocation { + parents: 1, + interior: X1(Parachain(2001)), + })); - // Dispatch fulfill extrinsic with valid origin. - assert_ok!(AcurastReceiver::fulfill(xcm_origin, payload.clone())); - }); + // Dispatch fulfill extrinsic with valid origin. + assert_ok!(AcurastReceiver::fulfill(xcm_origin, payload.clone(), None)); + }); - new_test_ext().execute_with(|| { - // Mock and xcm origin - let xcm_origin = Origin::from(pallet_xcm::Origin::Xcm(MultiLocation { - parents: 1, - interior: X1(Parachain(2000)), - })); + new_test_ext().execute_with(|| { + // Mock and xcm origin + let xcm_origin = Origin::from(pallet_xcm::Origin::Xcm(MultiLocation { + parents: 1, + interior: X1(Parachain(2000)), + })); - // Dispatch fulfill extrinsic with wrong origin. - assert_err!( - AcurastReceiver::fulfill(xcm_origin, payload.clone()), - "MultiLocation not allowed." - ); - }); + // Dispatch fulfill extrinsic with wrong origin. + assert_err!( + AcurastReceiver::fulfill(xcm_origin, payload.clone(), None), + "MultiLocation not allowed." + ); + }); } diff --git a/pallets/acurast-receiver/src/traits.rs b/pallets/acurast-receiver/src/traits.rs index 40704724..8df83386 100644 --- a/pallets/acurast-receiver/src/traits.rs +++ b/pallets/acurast-receiver/src/traits.rs @@ -1,18 +1,20 @@ -use frame_support::weights::PostDispatchInfo; +use frame_support::{ + sp_runtime::{DispatchError, DispatchResultWithInfo}, + weights::PostDispatchInfo, +}; use frame_system::pallet_prelude::OriginFor; use crate::Config; /// Handle fulfillment messages. pub trait OnFulfillment { - fn fulfill( - payload: &[u8], - ) -> frame_support::sp_runtime::DispatchResultWithInfo; + fn fulfill( + payload: Vec, + parameters: Option>, + ) -> DispatchResultWithInfo; } /// Allows execution only from trusted origins. pub trait ParachainBarrier { - fn ensure_xcm_origin( - origin: OriginFor, - ) -> Result<(), frame_support::sp_runtime::DispatchError>; + fn ensure_xcm_origin(origin: OriginFor) -> Result<(), DispatchError>; } From 07e3e375c663808cca2e031ea25e485b0417e6f1 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelhas Date: Thu, 20 Oct 2022 10:05:54 +0100 Subject: [PATCH 3/3] chore: rename receiver crate to acurast-xcm-receiver --- .../Cargo.toml | 2 +- .../README.md | 16 ++++++++-------- .../src/benchmarking.rs | 0 .../src/lib.rs | 0 .../src/mock.rs | 6 +++--- .../src/tests.rs | 0 .../src/traits.rs | 0 7 files changed, 12 insertions(+), 12 deletions(-) rename pallets/{acurast-receiver => acurast-xcm-receiver}/Cargo.toml (98%) rename pallets/{acurast-receiver => acurast-xcm-receiver}/README.md (70%) rename pallets/{acurast-receiver => acurast-xcm-receiver}/src/benchmarking.rs (100%) rename pallets/{acurast-receiver => acurast-xcm-receiver}/src/lib.rs (100%) rename pallets/{acurast-receiver => acurast-xcm-receiver}/src/mock.rs (96%) rename pallets/{acurast-receiver => acurast-xcm-receiver}/src/tests.rs (100%) rename pallets/{acurast-receiver => acurast-xcm-receiver}/src/traits.rs (100%) diff --git a/pallets/acurast-receiver/Cargo.toml b/pallets/acurast-xcm-receiver/Cargo.toml similarity index 98% rename from pallets/acurast-receiver/Cargo.toml rename to pallets/acurast-xcm-receiver/Cargo.toml index 9b1c8190..28d5ea9d 100644 --- a/pallets/acurast-receiver/Cargo.toml +++ b/pallets/acurast-xcm-receiver/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "pallet-acurast-receiver" +name = "pallet-acurast-xcm-receiver" authors = ["Papers AG"] description = "Pallet for defining the receiving logic from acurast parachain." version = "0.0.1" diff --git a/pallets/acurast-receiver/README.md b/pallets/acurast-xcm-receiver/README.md similarity index 70% rename from pallets/acurast-receiver/README.md rename to pallets/acurast-xcm-receiver/README.md index fea8ecdc..3fe6413d 100644 --- a/pallets/acurast-receiver/README.md +++ b/pallets/acurast-xcm-receiver/README.md @@ -1,10 +1,10 @@ -# Acurast Receiver Pallet +# Acurast XCM Receiver Pallet ## 🚧🚧🚧 The project is still a work in progress 🚧🚧🚧 ## Introduction -The `pallet-acurast-receiver` adds support for parachains to receive [XCM](https://wiki.polkadot.network/docs/learn-xcm) messages from [Acurast parachain](https://docs.acurast.com/). +The `pallet-acurast-xcm-receiver` adds support for parachains to receive [XCM](https://wiki.polkadot.network/docs/learn-xcm) messages from [Acurast parachain](https://docs.acurast.com/). The Pallet exposes the following extrinsics. @@ -18,16 +18,16 @@ Allows to post the fulfillment of a registered job. The `fulfill` call will fail ```toml [dependencies] -pallet-acurast-receiver = { git = "https://github.com/Acurast/acurast-core.git" } +pallet-acurast-xcm-receiver = { git = "https://github.com/Acurast/acurast-core.git" } ``` -2. Implement `pallet_acurast_receiver::Config` for your `Runtime` and add the Pallet: +2. Implement `pallet_acurast_xcm_receiver::Config` for your `Runtime` and add the Pallet: ```rust /// Runtime example pub struct ParachainBarrier; -impl pallet_acurast_receiver::traits::ParachainBarrier for ParachainBarrier { +impl pallet_acurast_xcm_receiver::traits::ParachainBarrier for ParachainBarrier { fn ensure_xcm_origin( origin: frame_system::pallet_prelude::OriginFor, ) -> Result<(), sp_runtime::DispatchError> { @@ -56,7 +56,7 @@ impl pallet_acurast_receiver::traits::ParachainBarrier for ParachainBar } pub struct OnAcurastFulfillment; -impl pallet_acurast_receiver::traits::OnFulfillment for OnAcurastFulfillment { +impl pallet_acurast_xcm_receiver::traits::OnFulfillment for OnAcurastFulfillment { fn fulfill( payload: &[u8], ) -> sp_runtime::DispatchResultWithInfo { @@ -64,7 +64,7 @@ impl pallet_acurast_receiver::traits::OnFulfillment for OnAcurastFulfil } } -impl pallet_acurast_receiver::Config for Runtime { +impl pallet_acurast_xcm_receiver::Config for Runtime { type Event = Event; type Payload = sp_runtime::bounded::bounded_vec::BoundedVec>; type OnFulfillment = OnAcurastFulfillment; @@ -80,7 +80,7 @@ construct_runtime!( { // All your other pallets ... - AcurastReceiver: pallet_acurast_receiver::{Pallet, Storage, Call, Event}; + AcurastReceiver: pallet_acurast_xcm_receiver::{Pallet, Storage, Call, Event}; } ); ``` diff --git a/pallets/acurast-receiver/src/benchmarking.rs b/pallets/acurast-xcm-receiver/src/benchmarking.rs similarity index 100% rename from pallets/acurast-receiver/src/benchmarking.rs rename to pallets/acurast-xcm-receiver/src/benchmarking.rs diff --git a/pallets/acurast-receiver/src/lib.rs b/pallets/acurast-xcm-receiver/src/lib.rs similarity index 100% rename from pallets/acurast-receiver/src/lib.rs rename to pallets/acurast-xcm-receiver/src/lib.rs diff --git a/pallets/acurast-receiver/src/mock.rs b/pallets/acurast-xcm-receiver/src/mock.rs similarity index 96% rename from pallets/acurast-receiver/src/mock.rs rename to pallets/acurast-xcm-receiver/src/mock.rs index a5417954..f24e11c3 100644 --- a/pallets/acurast-receiver/src/mock.rs +++ b/pallets/acurast-xcm-receiver/src/mock.rs @@ -1,4 +1,4 @@ -use crate as pallet_acurast_receiver; +use crate as pallet_acurast_xcm_receiver; use frame_support::{ traits::{ConstU16, ConstU64, Everything, Nothing}, weights::{Pays, PostDispatchInfo}, @@ -23,7 +23,7 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, - AcurastReceiver: pallet_acurast_receiver::{Pallet, Call, Storage, Event}, + AcurastReceiver: pallet_acurast_xcm_receiver::{Pallet, Call, Storage, Event}, PolkadotXcm: pallet_xcm::{Pallet, Storage, Call, Event, Origin, Config}, } ); @@ -124,7 +124,7 @@ impl crate::traits::ParachainBarrier for ParachainBarrier { } } -impl pallet_acurast_receiver::Config for Test { +impl pallet_acurast_xcm_receiver::Config for Test { type Event = Event; type Payload = Vec; type Parameters = Vec; diff --git a/pallets/acurast-receiver/src/tests.rs b/pallets/acurast-xcm-receiver/src/tests.rs similarity index 100% rename from pallets/acurast-receiver/src/tests.rs rename to pallets/acurast-xcm-receiver/src/tests.rs diff --git a/pallets/acurast-receiver/src/traits.rs b/pallets/acurast-xcm-receiver/src/traits.rs similarity index 100% rename from pallets/acurast-receiver/src/traits.rs rename to pallets/acurast-xcm-receiver/src/traits.rs