Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

XCM: ExpectTransactStatus instruction #6578

Merged
merged 7 commits into from
Jan 19, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions runtime/kusama/src/weights/xcm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for KusamaXcmWeight<RuntimeCall> {
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
XcmGeneric::<Runtime>::expect_error()
}
fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight {
XcmGeneric::<Runtime>::expect_transact_status()
}
fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
XcmGeneric::<Runtime>::query_pallet()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
pub(crate) fn expect_error() -> Weight {
Weight::from_ref_time(3_645_000 as u64)
}
pub(crate) fn expect_transact_status() -> Weight {
Weight::from_ref_time(3_645_000 as u64)
}
// Storage: XcmPallet SupportedVersion (r:1 w:0)
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
Expand Down
3 changes: 3 additions & 0 deletions runtime/rococo/src/weights/xcm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for RococoXcmWeight<RuntimeCall> {
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
XcmGeneric::<Runtime>::expect_error()
}
fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight {
XcmGeneric::<Runtime>::expect_transact_status()
}
fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
XcmGeneric::<Runtime>::query_pallet()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
pub(crate) fn expect_error() -> Weight {
Weight::from_ref_time(3_633_000 as u64)
}
pub(crate) fn expect_transact_status() -> Weight {
Weight::from_ref_time(3_633_000 as u64)
}
// Storage: XcmPallet SupportedVersion (r:1 w:0)
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
Expand Down
3 changes: 3 additions & 0 deletions runtime/westend/src/weights/xcm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for WestendXcmWeight<RuntimeCall> {
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
XcmGeneric::<Runtime>::expect_error()
}
fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight {
XcmGeneric::<Runtime>::expect_transact_status()
}
fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
XcmGeneric::<Runtime>::query_pallet()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
pub(crate) fn expect_error() -> Weight {
Weight::from_ref_time(5_775_000 as u64)
}
pub(crate) fn expect_transact_status() -> Weight {
Weight::from_ref_time(5_775_000 as u64)
}
// Storage: XcmPallet SupportedVersion (r:1 w:0)
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
Expand Down
29 changes: 20 additions & 9 deletions xcm/src/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ pub enum Instruction<Call> {
/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets
/// under the ownership of `dest` within this consensus system (i.e. its sovereign account).
///
/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the wantn
/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given
/// `xcm`.
///
/// - `assets`: The asset(s) to be withdrawn.
Expand Down Expand Up @@ -588,7 +588,7 @@ pub enum Instruction<Call> {
/// Errors:
DescendOrigin(InteriorMultiLocation),

/// Immediately report the contents of the Error Register to the wantn destination via XCM.
/// Immediately report the contents of the Error Register to the given destination via XCM.
///
/// A `QueryResponse` message of type `ExecutionOutcome` is sent to the described destination.
///
Expand All @@ -614,7 +614,7 @@ pub enum Instruction<Call> {
/// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign
/// account).
///
/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the wantn `effects`.
/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`.
///
/// - `assets`: The asset(s) to remove from holding.
/// - `dest`: The location whose sovereign account will own the assets and thus the effective
Expand Down Expand Up @@ -652,7 +652,7 @@ pub enum Instruction<Call> {
/// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The
/// sovereign account of this consensus system *on the reserve location* will have appropriate
/// assets withdrawn and `effects` will be executed on them. There will typically be only one
/// valid location on any wantn asset/chain combination.
/// valid location on any given asset/chain combination.
/// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve
/// location*.
///
Expand All @@ -677,7 +677,7 @@ pub enum Instruction<Call> {
/// Errors:
InitiateTeleport { assets: MultiAssetFilter, dest: MultiLocation, xcm: Xcm<()> },

/// Report to a wantn destination the contents of the Holding Register.
/// Report to a given destination the contents of the Holding Register.
///
/// A `QueryResponse` message of type `Assets` is sent to the described destination.
///
Expand Down Expand Up @@ -795,7 +795,7 @@ pub enum Instruction<Call> {
/// Errors: *Fallible*
UnsubscribeVersion,

/// Reduce Holding by up to the wantn assets.
/// Reduce Holding by up to the given assets.
///
/// Holding is reduced by as much as possible up to the assets in the parameter. It is not an
/// error if the Holding does not contain the assets (to make this an error, use `ExpectAsset`
Expand All @@ -806,30 +806,39 @@ pub enum Instruction<Call> {
/// Errors: *Infallible*
BurnAsset(MultiAssets),

/// Throw an error if Holding does not contain at least the wantn assets.
/// Throw an error if Holding does not contain at least the given assets.
///
/// Kind: *Instruction*
///
/// Errors:
/// - `ExpectationFalse`: If Holding Register does not contain the assets in the parameter.
ExpectAsset(MultiAssets),

/// Ensure that the Origin Register equals some wantn value and throw an error if not.
/// Ensure that the Origin Register equals some given value and throw an error if not.
///
/// Kind: *Instruction*
///
/// Errors:
/// - `ExpectationFalse`: If Origin Register is not equal to the parameter.
ExpectOrigin(Option<MultiLocation>),

/// Ensure that the Error Register equals some wantn value and throw an error if not.
/// Ensure that the Error Register equals some given value and throw an error if not.
///
/// Kind: *Instruction*
///
/// Errors:
/// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter.
ExpectError(Option<(u32, Error)>),

/// Ensure that the Transact StatusError Register equals some given value and throw an error if
gavofyork marked this conversation as resolved.
Show resolved Hide resolved
/// not.
///
/// Kind: *Instruction*
///
/// Errors:
/// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter.
gavofyork marked this conversation as resolved.
Show resolved Hide resolved
ExpectTransactStatus(MaybeErrorCode),

/// Query the existence of a particular pallet type.
///
/// - `module_name`: The module name of the pallet to query.
Expand Down Expand Up @@ -1088,6 +1097,7 @@ impl<Call> Instruction<Call> {
ExpectAsset(assets) => ExpectAsset(assets),
ExpectOrigin(origin) => ExpectOrigin(origin),
ExpectError(error) => ExpectError(error),
ExpectTransactStatus(transact_status) => ExpectTransactStatus(transact_status),
QueryPallet { module_name, response_info } =>
QueryPallet { module_name, response_info },
ExpectPallet { index, name, module_name, crate_major, min_crate_minor } =>
Expand Down Expand Up @@ -1156,6 +1166,7 @@ impl<Call, W: XcmWeightInfo<Call>> GetWeight<W> for Instruction<Call> {
ExpectAsset(assets) => W::expect_asset(assets),
ExpectOrigin(origin) => W::expect_origin(origin),
ExpectError(error) => W::expect_error(error),
ExpectTransactStatus(transact_status) => W::expect_transact_status(transact_status),
QueryPallet { module_name, response_info } =>
W::query_pallet(module_name, response_info),
ExpectPallet { index, name, module_name, crate_major, min_crate_minor } =>
Expand Down
62 changes: 62 additions & 0 deletions xcm/xcm-builder/src/tests/transacting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,68 @@ fn report_failed_transact_status_should_work() {
assert_eq!(sent_xcm(), vec![(Parent.into(), expected_msg, expected_hash)]);
}

#[test]
fn expect_successful_transact_status_should_work() {
AllowUnpaidFrom::set(vec![Parent.into()]);

let message = Xcm::<TestCall>(vec![
Transact {
origin_kind: OriginKind::Native,
require_weight_at_most: Weight::from_parts(50, 50),
call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(),
},
ExpectTransactStatus(MaybeErrorCode::Success),
]);
let hash = fake_message_hash(&message);
let weight_limit = Weight::from_parts(70, 70);
let r = XcmExecutor::<TestConfig>::execute_xcm(Parent, message, hash, weight_limit);
assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70)));

let message = Xcm::<TestCall>(vec![
Transact {
origin_kind: OriginKind::Native,
require_weight_at_most: Weight::from_parts(50, 50),
call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(),
},
ExpectTransactStatus(MaybeErrorCode::Success),
]);
let hash = fake_message_hash(&message);
let weight_limit = Weight::from_parts(70, 70);
let r = XcmExecutor::<TestConfig>::execute_xcm(Parent, message, hash, weight_limit);
assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse));
}

#[test]
fn expect_failed_transact_status_should_work() {
AllowUnpaidFrom::set(vec![Parent.into()]);

let message = Xcm::<TestCall>(vec![
Transact {
origin_kind: OriginKind::Native,
require_weight_at_most: Weight::from_parts(50, 50),
call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(),
},
ExpectTransactStatus(MaybeErrorCode::Error(vec![2])),
]);
let hash = fake_message_hash(&message);
let weight_limit = Weight::from_parts(70, 70);
let r = XcmExecutor::<TestConfig>::execute_xcm(Parent, message, hash, weight_limit);
assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70)));

let message = Xcm::<TestCall>(vec![
Transact {
origin_kind: OriginKind::Native,
require_weight_at_most: Weight::from_parts(50, 50),
call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(),
},
ExpectTransactStatus(MaybeErrorCode::Error(vec![2])),
]);
let hash = fake_message_hash(&message);
let weight_limit = Weight::from_parts(70, 70);
let r = XcmExecutor::<TestConfig>::execute_xcm(Parent, message, hash, weight_limit);
assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse));
}

#[test]
fn clear_transact_status_should_work() {
AllowUnpaidFrom::set(vec![Parent.into()]);
Expand Down
4 changes: 4 additions & 0 deletions xcm/xcm-executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,10 @@ impl<Config: config::Config> XcmExecutor<Config> {
ensure!(self.error == error, XcmError::ExpectationFalse);
Ok(())
},
ExpectTransactStatus(transact_status) => {
ensure!(self.transact_status == transact_status, XcmError::ExpectationFalse);
Ok(())
},
QueryPallet { module_name, response_info } => {
let pallets = Config::PalletInstancesInfo::infos()
.into_iter()
Expand Down