diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs index 33b8de26dad0..e686829ec30d 100644 --- a/xcm/pallet-xcm/src/lib.rs +++ b/xcm/pallet-xcm/src/lib.rs @@ -52,8 +52,8 @@ use frame_system::pallet_prelude::*; pub use pallet::*; use xcm_executor::{ traits::{ - CheckSuspension, ClaimAssets, DropAssets, FinishedQuery, MatchesFungible, OnResponse, QueryResponseStatus, - VersionChangeNotifier, WeightBounds, XcmQueryHandler, + CheckSuspension, ClaimAssets, DropAssets, MatchesFungible, OnResponse, QueryHandler, + QueryResponseStatus, VersionChangeNotifier, WeightBounds, }, Assets, }; @@ -1120,7 +1120,7 @@ pub mod pallet { /// The maximum number of distinct assets allowed to be transferred in a single helper extrinsic. const MAX_ASSETS_FOR_TRANSFER: usize = 2; -impl XcmQueryHandler for Pallet { +impl QueryHandler for Pallet { type QueryId = u64; type BlockNumber = T::BlockNumber; type Error = XcmError; @@ -1153,41 +1153,26 @@ impl XcmQueryHandler for Pallet { Ok(query_id) } + /// Removes response when ready and emits [Event::ResponseTaken] event. fn take_response(query_id: Self::QueryId) -> QueryResponseStatus { match Queries::::get(query_id) { - Some(QueryStatus::Ready { response, at }) => { - let response = response.try_into(); - match response { - Ok(response) => { - Queries::::remove(query_id); - Self::deposit_event(Event::ResponseTaken(query_id)); - QueryResponseStatus::Finished(FinishedQuery::Response { response, at }) - }, - Err(_) => QueryResponseStatus::UnexpectedVersion, - } - }, - Some(QueryStatus::VersionNotifier { origin, is_active }) => { - let origin = origin.try_into(); - match origin { - Ok(origin) => - QueryResponseStatus::Finished(FinishedQuery::VersionNotification { - origin, - is_active, - }), - Err(_) => QueryResponseStatus::UnexpectedVersion, - } + Some(QueryStatus::Ready { response, at }) => match response.try_into() { + Ok(response) => { + Queries::::remove(query_id); + Self::deposit_event(Event::ResponseTaken(query_id)); + QueryResponseStatus::Ready { response, at } + }, + Err(_) => QueryResponseStatus::UnexpectedVersion, }, - Some(QueryStatus::Pending { .. }) => QueryResponseStatus::Pending, + Some(QueryStatus::Pending { timeout, .. }) => QueryResponseStatus::Pending { timeout }, + Some(_) => QueryResponseStatus::UnexpectedVersion, None => QueryResponseStatus::NotFound, } } - fn expect_response(id: Self::QueryId) { - let query_status = QueryStatus::Ready { - response: VersionedResponse::V3(Response::Null), - at: Self::BlockNumber::default(), - }; - Queries::::insert(id, query_status); + #[cfg(feature = "runtime-benchmarks")] + fn expect_response(id: Self::QueryId, status: QueryStatus) { + Queries::::insert(id, status); } } diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs index d6f01f9e0fc8..34630e06aa76 100644 --- a/xcm/pallet-xcm/src/mock.rs +++ b/xcm/pallet-xcm/src/mock.rs @@ -50,6 +50,7 @@ pub mod pallet_test_notifier { use frame_system::pallet_prelude::*; use sp_runtime::DispatchResult; use xcm::latest::prelude::*; + use xcm_executor::traits::QueryHandler; #[pallet::pallet] pub struct Pallet(_); @@ -85,7 +86,7 @@ pub mod pallet_test_notifier { let id = who .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) .map_err(|_| Error::::BadAccountFormat)?; - let qid = as XcmQueryHandler>::new_query( + let qid = as QueryHandler>::new_query( Junction::AccountId32 { network: None, id }, 100u32.into(), querier, diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs index 5d999c825cc5..5cf08a9847e3 100644 --- a/xcm/pallet-xcm/src/tests.rs +++ b/xcm/pallet-xcm/src/tests.rs @@ -28,7 +28,7 @@ use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash}; use xcm::{latest::QueryResponseInfo, prelude::*}; use xcm_builder::AllowKnownQueryResponses; use xcm_executor::{ - traits::{FinishedQuery, QueryResponseStatus, ShouldExecute, XcmQueryHandler}, + traits::{QueryHandler, QueryResponseStatus, ShouldExecute}, XcmExecutor, }; @@ -166,10 +166,8 @@ fn report_outcome_works() { )) ); - let response = QueryResponseStatus::Finished(FinishedQuery::Response { - response: Response::ExecutionResult(None), - at: 1, - }); + let response = + QueryResponseStatus::Ready { response: Response::ExecutionResult(None), at: 1 }; assert_eq!(XcmPallet::take_response(0), response); }); } @@ -269,10 +267,8 @@ fn custom_querier_works() { )) ); - let response = QueryResponseStatus::Finished(FinishedQuery::Response { - response: Response::ExecutionResult(None), - at: 1, - }); + let response = + QueryResponseStatus::Ready { response: Response::ExecutionResult(None), at: 1 }; assert_eq!(XcmPallet::take_response(0), response); }); } diff --git a/xcm/xcm-builder/src/pay.rs b/xcm/xcm-builder/src/pay.rs index 5365febaeb5c..0456189b8cbf 100644 --- a/xcm/xcm-builder/src/pay.rs +++ b/xcm/xcm-builder/src/pay.rs @@ -23,7 +23,7 @@ use frame_support::traits::{ use polkadot_core_primitives::AccountId; use sp_std::{marker::PhantomData, vec}; use xcm::{opaque::lts::Weight, prelude::*}; -use xcm_executor::traits::{FinishedQuery, QueryResponseStatus, XcmQueryHandler}; +use xcm_executor::traits::{QueryHandler, QueryResponseStatus}; /// Implementation of the `frame_support_traits::tokens::Pay` trait, to allow /// for generic payments of a given `AssetKind` and `Balance` from an implied origin, to a @@ -55,7 +55,7 @@ impl< DestinationChain: Get, SenderAccount: Get, Router: SendXcm, - Querier: XcmQueryHandler, + Querier: QueryHandler, Timeout: Get, Beneficiary: Into<[u8; 32]> + Clone, AssetKind: Into, @@ -107,23 +107,22 @@ impl< } fn check_payment(id: Self::Id) -> PaymentStatus { + use QueryResponseStatus::*; match Querier::take_response(id) { - QueryResponseStatus::Finished(FinishedQuery::Response { response, at: _ }) => - match response { - Response::ExecutionResult(Some(_)) => PaymentStatus::Failure, - Response::ExecutionResult(None) => PaymentStatus::Success, - _ => PaymentStatus::Unknown, - }, - QueryResponseStatus::Pending => PaymentStatus::InProgress, - QueryResponseStatus::NotFound | - QueryResponseStatus::UnexpectedVersion | - QueryResponseStatus::Finished(FinishedQuery::VersionNotification { .. }) => - PaymentStatus::Unknown, + Ready { response, .. } => match response { + Response::ExecutionResult(None) => PaymentStatus::Success, + Response::ExecutionResult(Some(_)) => PaymentStatus::Failure, + _ => PaymentStatus::Unknown, + }, + Pending { .. } => PaymentStatus::InProgress, + NotFound | UnexpectedVersion => PaymentStatus::Unknown, } } #[cfg(feature = "runtime-benchmarks")] - fn ensure_successful(_: &Self::Beneficiary, _: Self::Balance) {} + fn ensure_successful(_: &Self::Beneficiary, _: Self::Balance) { + Querier::expect_response(id); + } #[cfg(feature = "runtime-benchmarks")] fn ensure_concluded(id: Self::Id) { diff --git a/xcm/xcm-executor/src/traits/mod.rs b/xcm/xcm-executor/src/traits/mod.rs index 524cbe205cfd..246803de88b2 100644 --- a/xcm/xcm-executor/src/traits/mod.rs +++ b/xcm/xcm-executor/src/traits/mod.rs @@ -38,9 +38,7 @@ pub use token_matching::{ Error, MatchesFungible, MatchesFungibles, MatchesNonFungible, MatchesNonFungibles, }; mod on_response; -pub use on_response::{ - FinishedQuery, OnResponse, QueryResponseStatus, VersionChangeNotifier, XcmQueryHandler, -}; +pub use on_response::{OnResponse, QueryHandler, QueryResponseStatus, VersionChangeNotifier}; mod should_execute; pub use should_execute::{CheckSuspension, ShouldExecute}; mod transact_asset; diff --git a/xcm/xcm-executor/src/traits/on_response.rs b/xcm/xcm-executor/src/traits/on_response.rs index a580d0961ce4..e78200ed3cb2 100644 --- a/xcm/xcm-executor/src/traits/on_response.rs +++ b/xcm/xcm-executor/src/traits/on_response.rs @@ -103,19 +103,13 @@ impl VersionChangeNotifier for () { } } -#[derive(Debug, PartialEq, Eq)] -pub enum FinishedQuery { - Response { response: Response, at: BlockNumber }, - VersionNotification { origin: MultiLocation, is_active: bool }, -} - /// The possible state of an XCM query response. #[derive(Debug, PartialEq, Eq)] pub enum QueryResponseStatus { /// The response has arrived, and includes the inner Response and the block number it arrived at. - Finished(FinishedQuery), + Ready { response: Response, at: BlockNumber }, /// The response has not yet arrived, the XCM might still be executing or the response might be in transit. - Pending, + Pending { timeout: BlockNumber }, /// No response with the given `QueryId` was found, or the response was already queried and removed from local storage. NotFound, /// Got an unexpected XCM version. @@ -123,7 +117,7 @@ pub enum QueryResponseStatus { } /// Provides methods to expect responses from XCMs and query their status. -pub trait XcmQueryHandler { +pub trait QueryHandler { type QueryId: From + FullCodec + MaxEncodedLen @@ -161,14 +155,10 @@ pub trait XcmQueryHandler { timeout: Self::BlockNumber, ) -> result::Result; - /// Makes sure to expect a response with the given id - /// Used for bencharks. - fn expect_response(id: Self::QueryId); - /// Attempt to remove and return the response of query with ID `query_id`. - /// - /// Returns `Finished` if the response is available and includes inner response. - /// Returns `Pending` if the response is not yet available. - /// Returns `NotFound` if the response is not available and won't ever be. fn take_response(id: Self::QueryId) -> QueryResponseStatus; + + /// Makes sure to expect a response with the given id. + #[cfg(feature = "runtime-benchmarks")] + fn expect_response(id: Self::QueryId); }