Tweaks to XCM for Benchmarking (#4283)

* tweaks to xcm stuff for benchmarking

* Update xcm/xcm-executor/src/lib.rs
This commit is contained in:
Shawn Tabrizi
2021-11-15 17:38:11 -04:00
committed by GitHub
parent 08b8929c32
commit 59e90a77f0
7 changed files with 126 additions and 74 deletions
+6
View File
@@ -1261,6 +1261,12 @@ pub mod pallet {
VersionNotifyTargets::<T>::remove(XCM_VERSION, LatestVersionedMultiLocation(dest)); VersionNotifyTargets::<T>::remove(XCM_VERSION, LatestVersionedMultiLocation(dest));
Ok(()) 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> { impl<T: Config> DropAssets for Pallet<T> {
+3
View File
@@ -25,6 +25,9 @@ mod mock;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
#[cfg(feature = "std")]
pub mod test_utils;
mod location_conversion; mod location_conversion;
pub use location_conversion::{ pub use location_conversion::{
Account32Hash, AccountId32Aliases, AccountKey20Aliases, ChildParachainConvertsVia, Account32Hash, AccountId32Aliases, AccountKey20Aliases, ChildParachainConvertsVia,
+1 -53
View File
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use crate::barriers::AllowSubscriptionsFrom; use crate::{barriers::AllowSubscriptionsFrom, test_utils::*};
pub use crate::{ pub use crate::{
AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
FixedRateOfFungible, FixedWeightBounds, LocationInverter, TakeWeightCredit, FixedRateOfFungible, FixedWeightBounds, LocationInverter, TakeWeightCredit,
@@ -36,7 +36,6 @@ pub use sp_std::{
marker::PhantomData, marker::PhantomData,
}; };
pub use xcm::latest::prelude::*; pub use xcm::latest::prelude::*;
use xcm_executor::traits::{ClaimAssets, DropAssets, VersionChangeNotifier};
pub use xcm_executor::{ pub use xcm_executor::{
traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset}, traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset},
Assets, Config, Assets, Config,
@@ -273,57 +272,6 @@ pub type TestBarrier = (
AllowSubscriptionsFrom<IsInVec<AllowSubsFrom>>, 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; pub struct TestConfig;
impl Config for TestConfig { impl Config for TestConfig {
type Call = TestCall; type Call = TestCall;
@@ -0,0 +1,83 @@
// 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
}
}
+1 -1
View File
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // 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 frame_support::{assert_err, weights::constants::WEIGHT_PER_SECOND};
use xcm::latest::prelude::*; use xcm::latest::prelude::*;
use xcm_executor::{traits::*, Config, XcmExecutor}; use xcm_executor::{traits::*, Config, XcmExecutor};
+26 -20
View File
@@ -139,26 +139,7 @@ impl<Config: config::Config> ExecuteXcm<Config::Call> for XcmExecutor<Config> {
} }
} }
vm.refund_surplus(); vm.post_execute(xcm_weight)
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)
},
}
} }
} }
@@ -228,6 +209,31 @@ impl<Config: config::Config> XcmExecutor<Config> {
result 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. /// Remove the registered error handler and return it. Do not refund its weight.
fn take_error_handler(&mut self) -> Xcm<Config::Call> { fn take_error_handler(&mut self) -> Xcm<Config::Call> {
let mut r = Xcm::<Config::Call>(vec![]); 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 /// Stop notifying `location` should the XCM change. Returns an error if there is no existing
/// notification set up. /// notification set up.
fn stop(location: &MultiLocation) -> XcmResult; 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 () { impl VersionChangeNotifier for () {
@@ -67,4 +70,7 @@ impl VersionChangeNotifier for () {
fn stop(_: &MultiLocation) -> XcmResult { fn stop(_: &MultiLocation) -> XcmResult {
Err(XcmError::Unimplemented) Err(XcmError::Unimplemented)
} }
fn is_subscribed(_: &MultiLocation) -> bool {
false
}
} }