mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 09:21:04 +00:00
XCM: ExpectTransactStatus instruction (#6578)
* Introduce ExpectTransactStatus instruction * Remove other changes * Implement * Implement rest * Benchmark * Update xcm/src/v3/mod.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Update xcm/src/v3/mod.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
This commit is contained in:
@@ -198,6 +198,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for KusamaXcmWeight<RuntimeCall> {
|
|||||||
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
|
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
|
||||||
XcmGeneric::<Runtime>::expect_error()
|
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 {
|
fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
|
||||||
XcmGeneric::<Runtime>::query_pallet()
|
XcmGeneric::<Runtime>::query_pallet()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,6 +142,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
|||||||
pub(crate) fn expect_error() -> Weight {
|
pub(crate) fn expect_error() -> Weight {
|
||||||
Weight::from_ref_time(3_645_000 as u64)
|
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 SupportedVersion (r:1 w:0)
|
||||||
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
|
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
|
||||||
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
|
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
|
||||||
|
|||||||
@@ -198,6 +198,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for RococoXcmWeight<RuntimeCall> {
|
|||||||
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
|
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
|
||||||
XcmGeneric::<Runtime>::expect_error()
|
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 {
|
fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
|
||||||
XcmGeneric::<Runtime>::query_pallet()
|
XcmGeneric::<Runtime>::query_pallet()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
|||||||
pub(crate) fn expect_error() -> Weight {
|
pub(crate) fn expect_error() -> Weight {
|
||||||
Weight::from_ref_time(3_633_000 as u64)
|
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 SupportedVersion (r:1 w:0)
|
||||||
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
|
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
|
||||||
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
|
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
|
||||||
|
|||||||
@@ -201,6 +201,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for WestendXcmWeight<RuntimeCall> {
|
|||||||
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
|
fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
|
||||||
XcmGeneric::<Runtime>::expect_error()
|
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 {
|
fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
|
||||||
XcmGeneric::<Runtime>::query_pallet()
|
XcmGeneric::<Runtime>::query_pallet()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
|||||||
pub(crate) fn expect_error() -> Weight {
|
pub(crate) fn expect_error() -> Weight {
|
||||||
Weight::from_ref_time(5_775_000 as u64)
|
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 SupportedVersion (r:1 w:0)
|
||||||
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
|
// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
|
||||||
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
|
// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
|
||||||
|
|||||||
@@ -360,6 +360,22 @@ benchmarks! {
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expect_transact_status {
|
||||||
|
let mut executor = new_executor::<T>(Default::default());
|
||||||
|
// 1024 is an overestimate but should be good enough until we have `max_encoded_len`.
|
||||||
|
// Eventually it should be replaced by `DispatchError::max_encoded_len()`.
|
||||||
|
let worst_error = || MaybeErrorCode::Error(vec![0; 1024]);
|
||||||
|
executor.set_transact_status(worst_error());
|
||||||
|
|
||||||
|
let instruction = Instruction::ExpectTransactStatus(worst_error());
|
||||||
|
let xcm = Xcm(vec![instruction]);
|
||||||
|
let mut _result = Ok(());
|
||||||
|
}: {
|
||||||
|
_result = executor.bench_process(xcm);
|
||||||
|
} verify {
|
||||||
|
assert!(matches!(_result, Ok(..)));
|
||||||
|
}
|
||||||
|
|
||||||
query_pallet {
|
query_pallet {
|
||||||
let query_id = Default::default();
|
let query_id = Default::default();
|
||||||
let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?;
|
let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?;
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ pub enum Instruction<Call> {
|
|||||||
/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets
|
/// 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).
|
/// 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`.
|
/// `xcm`.
|
||||||
///
|
///
|
||||||
/// - `assets`: The asset(s) to be withdrawn.
|
/// - `assets`: The asset(s) to be withdrawn.
|
||||||
@@ -588,7 +588,7 @@ pub enum Instruction<Call> {
|
|||||||
/// Errors:
|
/// Errors:
|
||||||
DescendOrigin(InteriorMultiLocation),
|
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.
|
/// A `QueryResponse` message of type `ExecutionOutcome` is sent to the described destination.
|
||||||
///
|
///
|
||||||
@@ -614,7 +614,7 @@ pub enum Instruction<Call> {
|
|||||||
/// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign
|
/// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign
|
||||||
/// account).
|
/// 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.
|
/// - `assets`: The asset(s) to remove from holding.
|
||||||
/// - `dest`: The location whose sovereign account will own the assets and thus the effective
|
/// - `dest`: The location whose sovereign account will own the assets and thus the effective
|
||||||
@@ -652,7 +652,7 @@ pub enum Instruction<Call> {
|
|||||||
/// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The
|
/// - `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
|
/// 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
|
/// 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
|
/// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve
|
||||||
/// location*.
|
/// location*.
|
||||||
///
|
///
|
||||||
@@ -677,7 +677,7 @@ pub enum Instruction<Call> {
|
|||||||
/// Errors:
|
/// Errors:
|
||||||
InitiateTeleport { assets: MultiAssetFilter, dest: MultiLocation, xcm: Xcm<()> },
|
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.
|
/// A `QueryResponse` message of type `Assets` is sent to the described destination.
|
||||||
///
|
///
|
||||||
@@ -795,7 +795,7 @@ pub enum Instruction<Call> {
|
|||||||
/// Errors: *Fallible*
|
/// Errors: *Fallible*
|
||||||
UnsubscribeVersion,
|
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
|
/// 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`
|
/// error if the Holding does not contain the assets (to make this an error, use `ExpectAsset`
|
||||||
@@ -806,7 +806,7 @@ pub enum Instruction<Call> {
|
|||||||
/// Errors: *Infallible*
|
/// Errors: *Infallible*
|
||||||
BurnAsset(MultiAssets),
|
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*
|
/// Kind: *Instruction*
|
||||||
///
|
///
|
||||||
@@ -814,7 +814,7 @@ pub enum Instruction<Call> {
|
|||||||
/// - `ExpectationFalse`: If Holding Register does not contain the assets in the parameter.
|
/// - `ExpectationFalse`: If Holding Register does not contain the assets in the parameter.
|
||||||
ExpectAsset(MultiAssets),
|
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*
|
/// Kind: *Instruction*
|
||||||
///
|
///
|
||||||
@@ -822,7 +822,7 @@ pub enum Instruction<Call> {
|
|||||||
/// - `ExpectationFalse`: If Origin Register is not equal to the parameter.
|
/// - `ExpectationFalse`: If Origin Register is not equal to the parameter.
|
||||||
ExpectOrigin(Option<MultiLocation>),
|
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*
|
/// Kind: *Instruction*
|
||||||
///
|
///
|
||||||
@@ -830,6 +830,15 @@ pub enum Instruction<Call> {
|
|||||||
/// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter.
|
/// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter.
|
||||||
ExpectError(Option<(u32, Error)>),
|
ExpectError(Option<(u32, Error)>),
|
||||||
|
|
||||||
|
/// Ensure that the Transact Status Register equals some given value and throw an error if
|
||||||
|
/// not.
|
||||||
|
///
|
||||||
|
/// Kind: *Instruction*
|
||||||
|
///
|
||||||
|
/// Errors:
|
||||||
|
/// - `ExpectationFalse`: If the value of the Transact Status Register is not equal to the parameter.
|
||||||
|
ExpectTransactStatus(MaybeErrorCode),
|
||||||
|
|
||||||
/// Query the existence of a particular pallet type.
|
/// Query the existence of a particular pallet type.
|
||||||
///
|
///
|
||||||
/// - `module_name`: The module name of the pallet to query.
|
/// - `module_name`: The module name of the pallet to query.
|
||||||
@@ -1088,6 +1097,7 @@ impl<Call> Instruction<Call> {
|
|||||||
ExpectAsset(assets) => ExpectAsset(assets),
|
ExpectAsset(assets) => ExpectAsset(assets),
|
||||||
ExpectOrigin(origin) => ExpectOrigin(origin),
|
ExpectOrigin(origin) => ExpectOrigin(origin),
|
||||||
ExpectError(error) => ExpectError(error),
|
ExpectError(error) => ExpectError(error),
|
||||||
|
ExpectTransactStatus(transact_status) => ExpectTransactStatus(transact_status),
|
||||||
QueryPallet { module_name, response_info } =>
|
QueryPallet { module_name, response_info } =>
|
||||||
QueryPallet { module_name, response_info },
|
QueryPallet { module_name, response_info },
|
||||||
ExpectPallet { index, name, module_name, crate_major, min_crate_minor } =>
|
ExpectPallet { index, name, module_name, crate_major, min_crate_minor } =>
|
||||||
@@ -1156,6 +1166,7 @@ impl<Call, W: XcmWeightInfo<Call>> GetWeight<W> for Instruction<Call> {
|
|||||||
ExpectAsset(assets) => W::expect_asset(assets),
|
ExpectAsset(assets) => W::expect_asset(assets),
|
||||||
ExpectOrigin(origin) => W::expect_origin(origin),
|
ExpectOrigin(origin) => W::expect_origin(origin),
|
||||||
ExpectError(error) => W::expect_error(error),
|
ExpectError(error) => W::expect_error(error),
|
||||||
|
ExpectTransactStatus(transact_status) => W::expect_transact_status(transact_status),
|
||||||
QueryPallet { module_name, response_info } =>
|
QueryPallet { module_name, response_info } =>
|
||||||
W::query_pallet(module_name, response_info),
|
W::query_pallet(module_name, response_info),
|
||||||
ExpectPallet { index, name, module_name, crate_major, min_crate_minor } =>
|
ExpectPallet { index, name, module_name, crate_major, min_crate_minor } =>
|
||||||
|
|||||||
@@ -156,6 +156,68 @@ fn report_failed_transact_status_should_work() {
|
|||||||
assert_eq!(sent_xcm(), vec![(Parent.into(), expected_msg, expected_hash)]);
|
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]
|
#[test]
|
||||||
fn clear_transact_status_should_work() {
|
fn clear_transact_status_should_work() {
|
||||||
AllowUnpaidFrom::set(vec![Parent.into()]);
|
AllowUnpaidFrom::set(vec![Parent.into()]);
|
||||||
|
|||||||
@@ -753,6 +753,10 @@ impl<Config: config::Config> XcmExecutor<Config> {
|
|||||||
ensure!(self.error == error, XcmError::ExpectationFalse);
|
ensure!(self.error == error, XcmError::ExpectationFalse);
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
|
ExpectTransactStatus(transact_status) => {
|
||||||
|
ensure!(self.transact_status == transact_status, XcmError::ExpectationFalse);
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
QueryPallet { module_name, response_info } => {
|
QueryPallet { module_name, response_info } => {
|
||||||
let pallets = Config::PalletInstancesInfo::infos()
|
let pallets = Config::PalletInstancesInfo::infos()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|||||||
Reference in New Issue
Block a user