Unverified Commit f26005b9 authored by Shawn Tabrizi's avatar Shawn Tabrizi Committed by GitHub
Browse files

Tweaks to XCM for Benchmarking (#4283)

* tweaks to xcm stuff for benchmarking

* Update xcm/xcm-executor/src/lib.rs
parent 13c2695e
Pipeline #166208 passed with stages
in 39 minutes and 19 seconds
......@@ -1261,6 +1261,12 @@ pub mod pallet {
VersionNotifyTargets::<T>::remove(XCM_VERSION, LatestVersionedMultiLocation(dest));
Ok(())
}
/// Return true if a location is subscribed to XCM version changes.
fn is_subscribed(dest: &MultiLocation) -> bool {
let versioned_dest = LatestVersionedMultiLocation(dest);
VersionNotifyTargets::<T>::contains_key(XCM_VERSION, versioned_dest)
}
}
impl<T: Config> DropAssets for Pallet<T> {
......
......@@ -25,6 +25,9 @@ mod mock;
#[cfg(test)]
mod tests;
#[cfg(feature = "std")]
pub mod test_utils;
mod location_conversion;
pub use location_conversion::{
Account32Hash, AccountId32Aliases, AccountKey20Aliases, ChildParachainConvertsVia,
......
......@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use crate::barriers::AllowSubscriptionsFrom;
use crate::{barriers::AllowSubscriptionsFrom, test_utils::*};
pub use crate::{
AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
FixedRateOfFungible, FixedWeightBounds, LocationInverter, TakeWeightCredit,
......@@ -36,7 +36,6 @@ pub use sp_std::{
marker::PhantomData,
};
pub use xcm::latest::prelude::*;
use xcm_executor::traits::{ClaimAssets, DropAssets, VersionChangeNotifier};
pub use xcm_executor::{
traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset},
Assets, Config,
......@@ -273,57 +272,6 @@ pub type TestBarrier = (
AllowSubscriptionsFrom<IsInVec<AllowSubsFrom>>,
);
parameter_types! {
pub static TrappedAssets: Vec<(MultiLocation, MultiAssets)> = vec![];
}
pub struct TestAssetTrap;
impl DropAssets for TestAssetTrap {
fn drop_assets(origin: &MultiLocation, assets: Assets) -> Weight {
let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get();
t.push((origin.clone(), assets.into()));
TrappedAssets::set(t);
5
}
}
impl ClaimAssets for TestAssetTrap {
fn claim_assets(origin: &MultiLocation, ticket: &MultiLocation, what: &MultiAssets) -> bool {
let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get();
if let (0, X1(GeneralIndex(i))) = (ticket.parents, &ticket.interior) {
if let Some((l, a)) = t.get(*i as usize) {
if l == origin && a == what {
t.swap_remove(*i as usize);
TrappedAssets::set(t);
return true
}
}
}
false
}
}
parameter_types! {
pub static SubscriptionRequests: Vec<(MultiLocation, Option<(QueryId, u64)>)> = vec![];
}
pub struct TestSubscriptionService;
impl VersionChangeNotifier for TestSubscriptionService {
fn start(location: &MultiLocation, query_id: QueryId, max_weight: u64) -> XcmResult {
let mut r = SubscriptionRequests::get();
r.push((location.clone(), Some((query_id, max_weight))));
SubscriptionRequests::set(r);
Ok(())
}
fn stop(location: &MultiLocation) -> XcmResult {
let mut r = SubscriptionRequests::get();
r.push((location.clone(), None));
SubscriptionRequests::set(r);
Ok(())
}
}
pub struct TestConfig;
impl Config for TestConfig {
type Call = TestCall;
......
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
// Shared test utilities and implementations for the XCM Builder.
use frame_support::{dispatch::Weight, parameter_types};
use sp_std::vec::Vec;
pub use xcm::latest::prelude::*;
use xcm_executor::traits::{ClaimAssets, DropAssets, VersionChangeNotifier};
pub use xcm_executor::{
traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset},
Assets, Config,
};
parameter_types! {
pub static SubscriptionRequests: Vec<(MultiLocation, Option<(QueryId, u64)>)> = vec![];
}
pub struct TestSubscriptionService;
impl VersionChangeNotifier for TestSubscriptionService {
fn start(location: &MultiLocation, query_id: QueryId, max_weight: u64) -> XcmResult {
let mut r = SubscriptionRequests::get();
r.push((location.clone(), Some((query_id, max_weight))));
SubscriptionRequests::set(r);
Ok(())
}
fn stop(location: &MultiLocation) -> XcmResult {
let mut r = SubscriptionRequests::get();
r.retain(|(l, _q)| l != location);
r.push((location.clone(), None));
SubscriptionRequests::set(r);
Ok(())
}
fn is_subscribed(location: &MultiLocation) -> bool {
let r = SubscriptionRequests::get();
r.iter().any(|(l, q)| l == location && q.is_some())
}
}
parameter_types! {
pub static TrappedAssets: Vec<(MultiLocation, MultiAssets)> = vec![];
}
pub struct TestAssetTrap;
impl DropAssets for TestAssetTrap {
fn drop_assets(origin: &MultiLocation, assets: Assets) -> Weight {
let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get();
t.push((origin.clone(), assets.into()));
TrappedAssets::set(t);
5
}
}
impl ClaimAssets for TestAssetTrap {
fn claim_assets(origin: &MultiLocation, ticket: &MultiLocation, what: &MultiAssets) -> bool {
let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get();
if let (0, X1(GeneralIndex(i))) = (ticket.parents, &ticket.interior) {
if let Some((l, a)) = t.get(*i as usize) {
if l == origin && a == what {
t.swap_remove(*i as usize);
TrappedAssets::set(t);
return true
}
}
}
false
}
}
......@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use super::{mock::*, *};
use super::{mock::*, test_utils::*, *};
use frame_support::{assert_err, weights::constants::WEIGHT_PER_SECOND};
use xcm::latest::prelude::*;
use xcm_executor::{traits::*, Config, XcmExecutor};
......
......@@ -139,26 +139,7 @@ impl<Config: config::Config> ExecuteXcm<Config::Call> for XcmExecutor<Config> {
}
}
vm.refund_surplus();
drop(vm.trader);
let mut weight_used = xcm_weight.saturating_sub(vm.total_surplus);
if !vm.holding.is_empty() {
log::trace!(target: "xcm::execute_xcm_in_credit", "Trapping assets in holding register: {:?} (original_origin: {:?})", vm.holding, vm.original_origin);
let trap_weight = Config::AssetTrap::drop_assets(&vm.original_origin, vm.holding);
weight_used.saturating_accrue(trap_weight);
};
match vm.error {
None => Outcome::Complete(weight_used),
// TODO: #2841 #REALWEIGHT We should deduct the cost of any instructions following
// the error which didn't end up being executed.
Some((_i, e)) => {
log::debug!(target: "xcm::execute_xcm_in_credit", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, vm.original_origin);
Outcome::Incomplete(weight_used, e)
},
}
vm.post_execute(xcm_weight)
}
}
......@@ -228,6 +209,31 @@ impl<Config: config::Config> XcmExecutor<Config> {
result
}
/// Execute any final operations after having executed the XCM message.
/// This includes refunding surplus weight, trapping extra holding funds, and returning any errors during execution.
pub fn post_execute(mut self, xcm_weight: Weight) -> Outcome {
self.refund_surplus();
drop(self.trader);
let mut weight_used = xcm_weight.saturating_sub(self.total_surplus);
if !self.holding.is_empty() {
log::trace!(target: "xcm::execute_xcm_in_credit", "Trapping assets in holding register: {:?} (original_origin: {:?})", self.holding, self.original_origin);
let trap_weight = Config::AssetTrap::drop_assets(&self.original_origin, self.holding);
weight_used.saturating_accrue(trap_weight);
};
match self.error {
None => Outcome::Complete(weight_used),
// TODO: #2841 #REALWEIGHT We should deduct the cost of any instructions following
// the error which didn't end up being executed.
Some((_i, e)) => {
log::debug!(target: "xcm::execute_xcm_in_credit", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin);
Outcome::Incomplete(weight_used, e)
},
}
}
/// Remove the registered error handler and return it. Do not refund its weight.
fn take_error_handler(&mut self) -> Xcm<Config::Call> {
let mut r = Xcm::<Config::Call>(vec![]);
......
......@@ -58,6 +58,9 @@ pub trait VersionChangeNotifier {
/// Stop notifying `location` should the XCM change. Returns an error if there is no existing
/// notification set up.
fn stop(location: &MultiLocation) -> XcmResult;
/// Return true if a location is subscribed to XCM version changes.
fn is_subscribed(location: &MultiLocation) -> bool;
}
impl VersionChangeNotifier for () {
......@@ -67,4 +70,7 @@ impl VersionChangeNotifier for () {
fn stop(_: &MultiLocation) -> XcmResult {
Err(XcmError::Unimplemented)
}
fn is_subscribed(_: &MultiLocation) -> bool {
false
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment