XCM v2: Scripting, Query responses, Exception handling and Error reporting (#3629)

* Intoduce XCM v2

Also some minor fix for v0/v1

* Minor version cleanup

* Minor version cleanup

* Introduce SendError for XcmSend trait to avoid cycles with having Outcome in Xcm

* comment

* Corrent type

* Docs

* Fix build

* Fixes

* Introduce the basic impl

* Docs

* Add function

* Basic implementation

* Weighed responses and on_report

* Make XCM more script-like

* Remove BuyExecution::orders

* Fixes

* Fixes

* Fixes

* Formatting

* Initial draft and make pallet-xcm build

* fix XCM tests

* Formatting

* Fixes

* Formatting

* spelling

* Fixes

* Fixes

* spelling

* tests for translation

* extra fields to XCM pallet

* Formatting

* Fixes

* spelling

* first integration test

* Another integration test

* Formatting

* fix tests

* all tests

* Fixes

* Fixes

* Formatting

* Fixes

* Fixes

* Formatting

* Bump

* Remove unneeded structuring

* add instruction

* Fixes

* spelling

* Fixes

* Fixes

* Formatting

* Fixes

* Fixes

* Formatting

* Introduce and use VersionedResponse

* Introduce versioning to dispatchables' params

* Fixes

* Formatting

* Rest of merge

* more work

* Formatting

* Basic logic

* Fixes

* Fixes

* Add test

* Fixes

* Formatting

* Fixes

* Fixes

* Fixes

* Nits

* Simplify

* Spelling

* Formatting

* Return weight of unexecuted instructions in case of error as surplus

* Formatting

* Fixes

* Test for instruction count limiting

* Formatting

* Docs
This commit is contained in:
Gavin Wood
2021-08-26 12:41:16 +02:00
committed by GitHub
parent 4193f05fa3
commit 8b80b283d4
37 changed files with 3070 additions and 966 deletions
+37 -49
View File
@@ -105,19 +105,13 @@ mod tests {
use super::*;
use codec::Encode;
use frame_support::{assert_ok, weights::Weight};
use frame_support::assert_ok;
use xcm::latest::prelude::*;
use xcm_simulator::TestExt;
// Helper function for forming buy execution message
fn buy_execution<C>(fees: impl Into<MultiAsset>, debt: Weight) -> Order<C> {
Order::BuyExecution {
fees: fees.into(),
weight: 0,
debt,
halt_on_error: false,
instructions: vec![],
}
fn buy_execution<C>(fees: impl Into<MultiAsset>) -> Instruction<C> {
BuyExecution { fees: fees.into(), weight_limit: Unlimited }
}
#[test]
@@ -131,11 +125,11 @@ mod tests {
assert_ok!(RelayChainPalletXcm::send_xcm(
Here,
Parachain(1).into(),
Transact {
Xcm(vec![Transact {
origin_type: OriginKind::SovereignAccount,
require_weight_at_most: INITIAL_BALANCE as u64,
call: remark.encode().into(),
},
}]),
));
});
@@ -158,11 +152,11 @@ mod tests {
assert_ok!(ParachainPalletXcm::send_xcm(
Here,
Parent.into(),
Transact {
Xcm(vec![Transact {
origin_type: OriginKind::SovereignAccount,
require_weight_at_most: INITIAL_BALANCE as u64,
call: remark.encode().into(),
},
}]),
));
});
@@ -185,11 +179,11 @@ mod tests {
assert_ok!(ParachainPalletXcm::send_xcm(
Here,
MultiLocation::new(1, X1(Parachain(2))),
Transact {
Xcm(vec![Transact {
origin_type: OriginKind::SovereignAccount,
require_weight_at_most: INITIAL_BALANCE as u64,
call: remark.encode().into(),
},
}]),
));
});
@@ -206,7 +200,6 @@ mod tests {
MockNet::reset();
let withdraw_amount = 123;
let max_weight_for_execution = 3;
Relay::execute_with(|| {
assert_ok!(RelayChainPalletXcm::reserve_transfer_assets(
@@ -215,7 +208,6 @@ mod tests {
Box::new(X1(AccountId32 { network: Any, id: ALICE.into() }).into().into()),
Box::new((Here, withdraw_amount).into()),
0,
max_weight_for_execution,
));
assert_eq!(
parachain::Balances::free_balance(&para_account_id(1)),
@@ -241,20 +233,17 @@ mod tests {
MockNet::reset();
let send_amount = 10;
let weight_for_execution = 3 * relay_chain::BaseXcmWeight::get();
ParaA::execute_with(|| {
let message = WithdrawAsset {
assets: (Here, send_amount).into(),
effects: vec![
buy_execution((Here, send_amount), weight_for_execution),
Order::DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parachain(2).into(),
},
],
};
let message = Xcm(vec![
WithdrawAsset((Here, send_amount).into()),
buy_execution((Here, send_amount)),
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parachain(2).into(),
},
]);
// Send withdraw and deposit
assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent.into(), message.clone()));
});
@@ -278,27 +267,25 @@ mod tests {
MockNet::reset();
let send_amount = 10;
let weight_for_execution = 3 * relay_chain::BaseXcmWeight::get();
let query_id_set = 1234;
// Send a message which fully succeeds on the relay chain
ParaA::execute_with(|| {
let message = WithdrawAsset {
assets: (Here, send_amount).into(),
effects: vec![
buy_execution((Here, send_amount), weight_for_execution),
Order::DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parachain(2).into(),
},
Order::QueryHolding {
query_id: query_id_set,
dest: Parachain(1).into(),
assets: All.into(),
},
],
};
let message = Xcm(vec![
WithdrawAsset((Here, send_amount).into()),
buy_execution((Here, send_amount)),
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parachain(2).into(),
},
QueryHolding {
query_id: query_id_set,
dest: Parachain(1).into(),
assets: All.into(),
max_response_weight: 1_000_000_000,
},
]);
// Send withdraw and deposit with query holding
assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent.into(), message.clone(),));
});
@@ -318,10 +305,11 @@ mod tests {
ParaA::execute_with(|| {
assert_eq!(
parachain::MsgQueue::received_dmp(),
vec![QueryResponse {
vec![Xcm(vec![QueryResponse {
query_id: query_id_set,
response: Response::Assets(MultiAssets::new())
}]
response: Response::Assets(MultiAssets::new()),
max_weight: 1_000_000_000,
}])],
);
});
}
@@ -121,6 +121,7 @@ pub type XcmOriginToCallOrigin = (
parameter_types! {
pub const UnitWeightCost: Weight = 1;
pub KsmPerSecond: (AssetId, u128) = (Concrete(Parent.into()), 1);
pub const MaxInstructions: u32 = 100;
}
pub type LocalAssetTransactor =
@@ -139,7 +140,7 @@ impl Config for XcmConfig {
type IsTeleporter = ();
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
type Trader = FixedRateOfFungible<KsmPerSecond, ()>;
type ResponseHandler = ();
}
@@ -298,8 +299,10 @@ impl pallet_xcm::Config for Runtime {
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmTeleportFilter = Nothing;
type XcmReserveTransferFilter = Everything;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
type LocationInverter = LocationInverter<Ancestry>;
type Origin = Origin;
type Call = Call;
}
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
@@ -114,6 +114,7 @@ type LocalOriginConverter = (
parameter_types! {
pub const BaseXcmWeight: Weight = 1_000;
pub KsmPerSecond: (AssetId, u128) = (Concrete(KsmLocation::get()), 1);
pub const MaxInstructions: u32 = 100;
}
pub type XcmRouter = super::RelayChainXcmRouter;
@@ -129,7 +130,7 @@ impl Config for XcmConfig {
type IsTeleporter = ();
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;
type Trader = FixedRateOfFungible<KsmPerSecond, ()>;
type ResponseHandler = ();
}
@@ -146,8 +147,10 @@ impl pallet_xcm::Config for Runtime {
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmTeleportFilter = Everything;
type XcmReserveTransferFilter = Everything;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;
type LocationInverter = LocationInverter<Ancestry>;
type Origin = Origin;
type Call = Call;
}
parameter_types! {
@@ -175,6 +178,6 @@ construct_runtime!(
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
ParasOrigin: origin::{Pallet, Origin},
ParasUmp: ump::{Pallet, Call, Storage, Event},
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>},
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin},
}
);
+6 -6
View File
@@ -260,7 +260,7 @@ macro_rules! decl_test_network {
},
)*
_ => {
return Err($crate::XcmError::CannotReachDestination(destination, message));
return Err($crate::XcmError::Unroutable);
}
}
}
@@ -285,7 +285,7 @@ macro_rules! decl_test_network {
);
},
)*
_ => return Err($crate::XcmError::SendFailed("Only sends to children parachain.")),
_ => return Err($crate::XcmError::Transport("Only sends to children parachain.")),
}
}
@@ -296,7 +296,7 @@ macro_rules! decl_test_network {
pub struct ParachainXcmRouter<T>($crate::PhantomData<T>);
impl<T: $crate::Get<$crate::ParaId>> $crate::SendXcm for ParachainXcmRouter<T> {
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::SendResult {
use $crate::{UmpSink, XcmpMessageHandlerT};
match destination.interior() {
@@ -312,7 +312,7 @@ macro_rules! decl_test_network {
Ok(())
},
)*
_ => Err($crate::XcmError::CannotReachDestination(destination, message)),
_ => Err($crate::SendError::CannotReachDestination(destination, message)),
}
}
}
@@ -320,7 +320,7 @@ macro_rules! decl_test_network {
/// XCM router for relay chain.
pub struct RelayChainXcmRouter;
impl $crate::SendXcm for RelayChainXcmRouter {
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::SendResult {
use $crate::DmpMessageHandlerT;
match destination.interior() {
@@ -331,7 +331,7 @@ macro_rules! decl_test_network {
Ok(())
},
)*
_ => Err($crate::XcmError::SendFailed("Only sends to children parachain.")),
_ => Err($crate::SendError::Unroutable),
}
}
}