Harden XCM v1 for Recursions (#3586)

* Guard against XCM recursive bombs by setting a recursion limit

* Add test and set a lower recursion limit

* Use u32 instead of usize for recursion limit

* Make spellcheck happy

* Cargo fmt

* Limit XCM decoding depth in UMP message processing

* Modify test to check for recursion in BuyExecution

* Update xcm/xcm-simulator/example/src/lib.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Make cargo fmt happy

* WIP for testing recursion limit in WASM

* Revert "WIP for testing recursion limit in WASM"

This reverts commit 39181b46d1adf79358f5ae8aafcf480e0c0c22e6.

* Remove XCM recursion limit test

* Add recursion test for XCM message execution

* Set a more sensible recursion limit

* Cargo fmt

* Implement successful_origin for benchmarks

* Set recursion limit to 8 and create integration tests directory for xcm-executor

* Cargo fmt

* Add runtime-benchmarks feature to test-runtime

* Give up creating ConvertOriginToLocal and use EnsureXcm

* Re-add ConvertOriginToLocal

* Fix compilation

* Update xcm/xcm-executor/src/lib.rs

Co-authored-by: Gavin Wood <gavin@parity.io>

* Add decoding limit to all versioned XCM decode calls

* Fix recursion limit test

* Set a lower recursion count for recursion test

* move integration tests to their own folder, fix recursion check in execute_effects

* Remove xcm-executor integration tests directory

* fix up

* Update Cargo.lock

* Update runtime/parachains/src/ump.rs

* use proper decode limit

* fix decode depth limit

* here too

* Update traits.rs

* fix compile

* fix test

* Revert `decode_all_with_depth_limit` changes in parachain.rs

* Remove unused imports in parachain.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Bastian Köcher <info@kchr.de>
Co-authored-by: Gavin Wood <gavin@parity.io>
This commit is contained in:
Shawn Tabrizi
2021-08-07 21:29:12 +02:00
committed by GitHub
parent d1ef456a4d
commit 9ee8013d6d
14 changed files with 375 additions and 13 deletions
@@ -0,0 +1,91 @@
// Copyright 2021 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/>.
use frame_support::{parameter_types, traits::All, weights::Weight};
use xcm::latest::{
Error as XcmError, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, NetworkId,
Result as XcmResult, SendXcm, Xcm,
};
use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
use xcm_executor::{
traits::{InvertLocation, TransactAsset, WeightTrader},
Assets,
};
parameter_types! {
pub const OurNetwork: NetworkId = NetworkId::Polkadot;
}
/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior location
/// of this chain.
pub type LocalOriginToLocation = (
// And a usual Signed origin to be used in XCM as a corresponding AccountId32
SignedToAccountId32<crate::Origin, crate::AccountId, OurNetwork>,
);
pub struct DoNothingRouter;
impl SendXcm for DoNothingRouter {
fn send_xcm(_dest: MultiLocation, _msg: Xcm<()>) -> XcmResult {
Ok(())
}
}
pub type Barrier = AllowUnpaidExecutionFrom<All<MultiLocation>>;
pub struct DummyAssetTransactor;
impl TransactAsset for DummyAssetTransactor {
fn deposit_asset(_what: &MultiAsset, _who: &MultiLocation) -> XcmResult {
Ok(())
}
fn withdraw_asset(_what: &MultiAsset, _who: &MultiLocation) -> Result<Assets, XcmError> {
let asset: MultiAsset = (X1(Parent), 100_000).into();
Ok(asset.into())
}
}
pub struct DummyWeightTrader;
impl WeightTrader for DummyWeightTrader {
fn new() -> Self {
DummyWeightTrader
}
fn buy_weight(&mut self, _weight: Weight, _payment: Assets) -> Result<Assets, XcmError> {
Ok(Assets::default())
}
}
pub struct InvertNothing;
impl InvertLocation for InvertNothing {
fn invert_location(_: &MultiLocation) -> MultiLocation {
MultiLocation::Here
}
}
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type Call = super::Call;
type XcmSender = DoNothingRouter;
type AssetTransactor = DummyAssetTransactor;
type OriginConverter = pallet_xcm::XcmPassthrough<super::Origin>;
type IsReserve = ();
type IsTeleporter = ();
type LocationInverter = InvertNothing;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<super::BaseXcmWeight, super::Call>;
type Trader = DummyWeightTrader;
type ResponseHandler = ();
}