mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 16:21:02 +00:00
Fix weights on hard-coded XCM fragments (#4144)
* Fix weights on hard-coded XCM fragments * Formatting
This commit is contained in:
@@ -473,7 +473,9 @@ pub mod pallet {
|
|||||||
|
|
||||||
/// Teleport some assets from the local chain to some destination chain.
|
/// Teleport some assets from the local chain to some destination chain.
|
||||||
///
|
///
|
||||||
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector.
|
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector and
|
||||||
|
/// fee-weight is calculated locally and thus remote weights are assumed to be equal to
|
||||||
|
/// local weights.
|
||||||
///
|
///
|
||||||
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
|
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
|
||||||
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
||||||
@@ -506,54 +508,15 @@ pub mod pallet {
|
|||||||
assets: Box<VersionedMultiAssets>,
|
assets: Box<VersionedMultiAssets>,
|
||||||
fee_asset_item: u32,
|
fee_asset_item: u32,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
|
Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, None)
|
||||||
let dest = MultiLocation::try_from(*dest).map_err(|()| Error::<T>::BadVersion)?;
|
|
||||||
let beneficiary =
|
|
||||||
MultiLocation::try_from(*beneficiary).map_err(|()| Error::<T>::BadVersion)?;
|
|
||||||
let assets = MultiAssets::try_from(*assets).map_err(|()| Error::<T>::BadVersion)?;
|
|
||||||
|
|
||||||
ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::<T>::TooManyAssets);
|
|
||||||
let value = (origin_location, assets.drain());
|
|
||||||
ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
|
|
||||||
let (origin_location, assets) = value;
|
|
||||||
let inv_dest = T::LocationInverter::invert_location(&dest)
|
|
||||||
.map_err(|()| Error::<T>::DestinationNotInvertible)?;
|
|
||||||
let fees = assets
|
|
||||||
.get(fee_asset_item as usize)
|
|
||||||
.ok_or(Error::<T>::Empty)?
|
|
||||||
.clone()
|
|
||||||
.reanchored(&inv_dest)
|
|
||||||
.map_err(|_| Error::<T>::CannotReanchor)?;
|
|
||||||
let max_assets = assets.len() as u32;
|
|
||||||
let assets = assets.into();
|
|
||||||
let mut remote_message = Xcm(vec![
|
|
||||||
BuyExecution { fees, weight_limit: Limited(0) },
|
|
||||||
DepositAsset { assets: Wild(All), max_assets, beneficiary },
|
|
||||||
]);
|
|
||||||
// use local weight for remote message and hope for the best.
|
|
||||||
let remote_weight = T::Weigher::weight(&mut remote_message)
|
|
||||||
.map_err(|()| Error::<T>::UnweighableMessage)?;
|
|
||||||
if let Some(BuyExecution { weight_limit: Limited(ref mut limit), .. }) =
|
|
||||||
remote_message.0.get_mut(0)
|
|
||||||
{
|
|
||||||
*limit = remote_weight;
|
|
||||||
}
|
|
||||||
let mut message = Xcm(vec![
|
|
||||||
WithdrawAsset(assets),
|
|
||||||
InitiateTeleport { assets: Wild(All), dest, xcm: remote_message.into() },
|
|
||||||
]);
|
|
||||||
let weight =
|
|
||||||
T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
|
|
||||||
let outcome =
|
|
||||||
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
|
|
||||||
Self::deposit_event(Event::Attempted(outcome));
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transfer some assets from the local chain to the sovereign account of a destination chain and forward
|
/// Transfer some assets from the local chain to the sovereign account of a destination chain and forward
|
||||||
/// a notification XCM.
|
/// a notification XCM.
|
||||||
///
|
///
|
||||||
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector.
|
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector and
|
||||||
|
/// fee-weight is calculated locally and thus remote weights are assumed to be equal to
|
||||||
|
/// local weights.
|
||||||
///
|
///
|
||||||
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
|
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
|
||||||
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
||||||
@@ -583,45 +546,14 @@ pub mod pallet {
|
|||||||
assets: Box<VersionedMultiAssets>,
|
assets: Box<VersionedMultiAssets>,
|
||||||
fee_asset_item: u32,
|
fee_asset_item: u32,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
|
Self::do_reserve_transfer_assets(
|
||||||
let dest = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
origin,
|
||||||
let beneficiary = (*beneficiary).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
dest,
|
||||||
let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
beneficiary,
|
||||||
|
assets,
|
||||||
ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::<T>::TooManyAssets);
|
fee_asset_item,
|
||||||
let value = (origin_location, assets.drain());
|
None,
|
||||||
ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
|
)
|
||||||
let (origin_location, assets) = value;
|
|
||||||
let inv_dest = T::LocationInverter::invert_location(&dest)
|
|
||||||
.map_err(|()| Error::<T>::DestinationNotInvertible)?;
|
|
||||||
let fees = assets
|
|
||||||
.get(fee_asset_item as usize)
|
|
||||||
.ok_or(Error::<T>::Empty)?
|
|
||||||
.clone()
|
|
||||||
.reanchored(&inv_dest)
|
|
||||||
.map_err(|_| Error::<T>::CannotReanchor)?;
|
|
||||||
let max_assets = assets.len() as u32;
|
|
||||||
let assets = assets.into();
|
|
||||||
let mut remote_message = Xcm(vec![
|
|
||||||
BuyExecution { fees, weight_limit: Limited(0) },
|
|
||||||
DepositAsset { assets: Wild(All), max_assets, beneficiary },
|
|
||||||
]);
|
|
||||||
// use local weight for remote message and hope for the best.
|
|
||||||
let remote_weight = T::Weigher::weight(&mut remote_message)
|
|
||||||
.map_err(|()| Error::<T>::UnweighableMessage)?;
|
|
||||||
if let Some(BuyExecution { weight_limit: Limited(ref mut limit), .. }) =
|
|
||||||
remote_message.0.get_mut(0)
|
|
||||||
{
|
|
||||||
*limit = remote_weight;
|
|
||||||
}
|
|
||||||
let mut message =
|
|
||||||
Xcm(vec![TransferReserveAsset { assets, dest, xcm: remote_message.into() }]);
|
|
||||||
let weight =
|
|
||||||
T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
|
|
||||||
let outcome =
|
|
||||||
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
|
|
||||||
Self::deposit_event(Event::Attempted(outcome));
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute an XCM message from a local, signed, origin.
|
/// Execute an XCM message from a local, signed, origin.
|
||||||
@@ -732,9 +664,218 @@ pub mod pallet {
|
|||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transfer some assets from the local chain to the sovereign account of a destination chain and forward
|
||||||
|
/// a notification XCM.
|
||||||
|
///
|
||||||
|
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector.
|
||||||
|
///
|
||||||
|
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
|
||||||
|
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
||||||
|
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
|
||||||
|
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be
|
||||||
|
/// an `AccountId32` value.
|
||||||
|
/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the fee on the
|
||||||
|
/// `dest` side.
|
||||||
|
/// - `fee_asset_item`: The index into `assets` of the item which should be used to pay
|
||||||
|
/// fees.
|
||||||
|
/// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase.
|
||||||
|
#[pallet::weight({
|
||||||
|
match ((*assets.clone()).try_into(), (*dest.clone()).try_into()) {
|
||||||
|
(Ok(assets), Ok(dest)) => {
|
||||||
|
use sp_std::vec;
|
||||||
|
let mut message = Xcm(vec![
|
||||||
|
TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) }
|
||||||
|
]);
|
||||||
|
T::Weigher::weight(&mut message).map_or(Weight::max_value(), |w| 100_000_000 + w)
|
||||||
|
},
|
||||||
|
_ => Weight::max_value(),
|
||||||
|
}
|
||||||
|
})]
|
||||||
|
pub fn limited_reserve_transfer_assets(
|
||||||
|
origin: OriginFor<T>,
|
||||||
|
dest: Box<VersionedMultiLocation>,
|
||||||
|
beneficiary: Box<VersionedMultiLocation>,
|
||||||
|
assets: Box<VersionedMultiAssets>,
|
||||||
|
fee_asset_item: u32,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> DispatchResult {
|
||||||
|
Self::do_reserve_transfer_assets(
|
||||||
|
origin,
|
||||||
|
dest,
|
||||||
|
beneficiary,
|
||||||
|
assets,
|
||||||
|
fee_asset_item,
|
||||||
|
Some(weight_limit),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Teleport some assets from the local chain to some destination chain.
|
||||||
|
///
|
||||||
|
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector.
|
||||||
|
///
|
||||||
|
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
|
||||||
|
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
||||||
|
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
|
||||||
|
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be
|
||||||
|
/// an `AccountId32` value.
|
||||||
|
/// - `assets`: The assets to be withdrawn. The first item should be the currency used to to pay the fee on the
|
||||||
|
/// `dest` side. May not be empty.
|
||||||
|
/// - `dest_weight`: Equal to the total weight on `dest` of the XCM message
|
||||||
|
/// `Teleport { assets, effects: [ BuyExecution{..}, DepositAsset{..} ] }`.
|
||||||
|
/// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase.
|
||||||
|
#[pallet::weight({
|
||||||
|
let maybe_assets: Result<MultiAssets, ()> = (*assets.clone()).try_into();
|
||||||
|
let maybe_dest: Result<MultiLocation, ()> = (*dest.clone()).try_into();
|
||||||
|
match (maybe_assets, maybe_dest) {
|
||||||
|
(Ok(assets), Ok(dest)) => {
|
||||||
|
use sp_std::vec;
|
||||||
|
let mut message = Xcm(vec![
|
||||||
|
WithdrawAsset(assets),
|
||||||
|
InitiateTeleport { assets: Wild(All), dest, xcm: Xcm(vec![]) },
|
||||||
|
]);
|
||||||
|
T::Weigher::weight(&mut message).map_or(Weight::max_value(), |w| 100_000_000 + w)
|
||||||
|
},
|
||||||
|
_ => Weight::max_value(),
|
||||||
|
}
|
||||||
|
})]
|
||||||
|
pub fn limited_teleport_assets(
|
||||||
|
origin: OriginFor<T>,
|
||||||
|
dest: Box<VersionedMultiLocation>,
|
||||||
|
beneficiary: Box<VersionedMultiLocation>,
|
||||||
|
assets: Box<VersionedMultiAssets>,
|
||||||
|
fee_asset_item: u32,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> DispatchResult {
|
||||||
|
Self::do_teleport_assets(
|
||||||
|
origin,
|
||||||
|
dest,
|
||||||
|
beneficiary,
|
||||||
|
assets,
|
||||||
|
fee_asset_item,
|
||||||
|
Some(weight_limit),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> Pallet<T> {
|
impl<T: Config> Pallet<T> {
|
||||||
|
fn do_reserve_transfer_assets(
|
||||||
|
origin: OriginFor<T>,
|
||||||
|
dest: Box<VersionedMultiLocation>,
|
||||||
|
beneficiary: Box<VersionedMultiLocation>,
|
||||||
|
assets: Box<VersionedMultiAssets>,
|
||||||
|
fee_asset_item: u32,
|
||||||
|
maybe_weight_limit: Option<WeightLimit>,
|
||||||
|
) -> DispatchResult {
|
||||||
|
let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
|
||||||
|
let dest = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
|
let beneficiary: MultiLocation =
|
||||||
|
(*beneficiary).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
|
let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
|
|
||||||
|
ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::<T>::TooManyAssets);
|
||||||
|
let value = (origin_location, assets.drain());
|
||||||
|
ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
|
||||||
|
let (origin_location, assets) = value;
|
||||||
|
let inv_dest = T::LocationInverter::invert_location(&dest)
|
||||||
|
.map_err(|()| Error::<T>::DestinationNotInvertible)?;
|
||||||
|
let fees = assets
|
||||||
|
.get(fee_asset_item as usize)
|
||||||
|
.ok_or(Error::<T>::Empty)?
|
||||||
|
.clone()
|
||||||
|
.reanchored(&inv_dest)
|
||||||
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
let max_assets = assets.len() as u32;
|
||||||
|
let assets: MultiAssets = assets.into();
|
||||||
|
let weight_limit = match maybe_weight_limit {
|
||||||
|
Some(weight_limit) => weight_limit,
|
||||||
|
None => {
|
||||||
|
let beneficiary = beneficiary.clone();
|
||||||
|
let fees = fees.clone();
|
||||||
|
let mut remote_message = Xcm(vec![
|
||||||
|
ReserveAssetDeposited(assets.clone()),
|
||||||
|
ClearOrigin,
|
||||||
|
BuyExecution { fees, weight_limit: Limited(0) },
|
||||||
|
DepositAsset { assets: Wild(All), max_assets, beneficiary },
|
||||||
|
]);
|
||||||
|
// use local weight for remote message and hope for the best.
|
||||||
|
let remote_weight = T::Weigher::weight(&mut remote_message)
|
||||||
|
.map_err(|()| Error::<T>::UnweighableMessage)?;
|
||||||
|
Limited(remote_weight)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let xcm = Xcm(vec![
|
||||||
|
BuyExecution { fees, weight_limit },
|
||||||
|
DepositAsset { assets: Wild(All), max_assets, beneficiary },
|
||||||
|
]);
|
||||||
|
let mut message = Xcm(vec![TransferReserveAsset { assets, dest, xcm }]);
|
||||||
|
let weight =
|
||||||
|
T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
|
||||||
|
let outcome =
|
||||||
|
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
|
||||||
|
Self::deposit_event(Event::Attempted(outcome));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_teleport_assets(
|
||||||
|
origin: OriginFor<T>,
|
||||||
|
dest: Box<VersionedMultiLocation>,
|
||||||
|
beneficiary: Box<VersionedMultiLocation>,
|
||||||
|
assets: Box<VersionedMultiAssets>,
|
||||||
|
fee_asset_item: u32,
|
||||||
|
maybe_weight_limit: Option<WeightLimit>,
|
||||||
|
) -> DispatchResult {
|
||||||
|
let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
|
||||||
|
let dest = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
|
let beneficiary: MultiLocation =
|
||||||
|
(*beneficiary).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
|
let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
|
|
||||||
|
ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::<T>::TooManyAssets);
|
||||||
|
let value = (origin_location, assets.drain());
|
||||||
|
ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
|
||||||
|
let (origin_location, assets) = value;
|
||||||
|
let inv_dest = T::LocationInverter::invert_location(&dest)
|
||||||
|
.map_err(|()| Error::<T>::DestinationNotInvertible)?;
|
||||||
|
let fees = assets
|
||||||
|
.get(fee_asset_item as usize)
|
||||||
|
.ok_or(Error::<T>::Empty)?
|
||||||
|
.clone()
|
||||||
|
.reanchored(&inv_dest)
|
||||||
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
let max_assets = assets.len() as u32;
|
||||||
|
let assets: MultiAssets = assets.into();
|
||||||
|
let weight_limit = match maybe_weight_limit {
|
||||||
|
Some(weight_limit) => weight_limit,
|
||||||
|
None => {
|
||||||
|
let beneficiary = beneficiary.clone();
|
||||||
|
let fees = fees.clone();
|
||||||
|
let mut remote_message = Xcm(vec![
|
||||||
|
ReceiveTeleportedAsset(assets.clone()),
|
||||||
|
ClearOrigin,
|
||||||
|
BuyExecution { fees, weight_limit: Limited(0) },
|
||||||
|
DepositAsset { assets: Wild(All), max_assets, beneficiary },
|
||||||
|
]);
|
||||||
|
// use local weight for remote message and hope for the best.
|
||||||
|
let remote_weight = T::Weigher::weight(&mut remote_message)
|
||||||
|
.map_err(|()| Error::<T>::UnweighableMessage)?;
|
||||||
|
Limited(remote_weight)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let xcm = Xcm(vec![
|
||||||
|
BuyExecution { fees, weight_limit },
|
||||||
|
DepositAsset { assets: Wild(All), max_assets, beneficiary },
|
||||||
|
]);
|
||||||
|
let mut message =
|
||||||
|
Xcm(vec![WithdrawAsset(assets), InitiateTeleport { assets: Wild(All), dest, xcm }]);
|
||||||
|
let weight =
|
||||||
|
T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
|
||||||
|
let outcome =
|
||||||
|
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
|
||||||
|
Self::deposit_event(Event::Attempted(outcome));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Will always make progress, and will do its best not to use much more than `weight_cutoff`
|
/// Will always make progress, and will do its best not to use much more than `weight_cutoff`
|
||||||
/// in doing so.
|
/// in doing so.
|
||||||
pub(crate) fn check_xcm_version_change(
|
pub(crate) fn check_xcm_version_change(
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ fn teleport_assets_works() {
|
|||||||
Xcm(vec![
|
Xcm(vec![
|
||||||
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
||||||
ClearOrigin,
|
ClearOrigin,
|
||||||
buy_limited_execution((Here, SEND_AMOUNT), 2000),
|
buy_limited_execution((Here, SEND_AMOUNT), 4000),
|
||||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||||
]),
|
]),
|
||||||
)]
|
)]
|
||||||
@@ -248,6 +248,88 @@ fn teleport_assets_works() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test `limited_teleport_assets`
|
||||||
|
///
|
||||||
|
/// Asserts that the sender's balance is decreased as a result of execution of
|
||||||
|
/// local effects.
|
||||||
|
#[test]
|
||||||
|
fn limmited_teleport_assets_works() {
|
||||||
|
let balances =
|
||||||
|
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||||
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
|
let weight = 2 * BaseXcmWeight::get();
|
||||||
|
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
||||||
|
let dest: MultiLocation = AccountId32 { network: Any, id: BOB.into() }.into();
|
||||||
|
assert_ok!(XcmPallet::limited_teleport_assets(
|
||||||
|
Origin::signed(ALICE),
|
||||||
|
Box::new(RelayLocation::get().into()),
|
||||||
|
Box::new(dest.clone().into()),
|
||||||
|
Box::new((Here, SEND_AMOUNT).into()),
|
||||||
|
0,
|
||||||
|
WeightLimit::Limited(5000),
|
||||||
|
));
|
||||||
|
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
||||||
|
assert_eq!(
|
||||||
|
sent_xcm(),
|
||||||
|
vec![(
|
||||||
|
RelayLocation::get().into(),
|
||||||
|
Xcm(vec![
|
||||||
|
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
||||||
|
ClearOrigin,
|
||||||
|
buy_limited_execution((Here, SEND_AMOUNT), 5000),
|
||||||
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||||
|
]),
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1);
|
||||||
|
let _check_v0_ok: xcm::v0::Xcm<()> = versioned_sent.try_into().unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
last_event(),
|
||||||
|
Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test `limited_teleport_assets` with unlimited weight
|
||||||
|
///
|
||||||
|
/// Asserts that the sender's balance is decreased as a result of execution of
|
||||||
|
/// local effects.
|
||||||
|
#[test]
|
||||||
|
fn unlimmited_teleport_assets_works() {
|
||||||
|
let balances =
|
||||||
|
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||||
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
|
let weight = 2 * BaseXcmWeight::get();
|
||||||
|
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
||||||
|
let dest: MultiLocation = AccountId32 { network: Any, id: BOB.into() }.into();
|
||||||
|
assert_ok!(XcmPallet::limited_teleport_assets(
|
||||||
|
Origin::signed(ALICE),
|
||||||
|
Box::new(RelayLocation::get().into()),
|
||||||
|
Box::new(dest.clone().into()),
|
||||||
|
Box::new((Here, SEND_AMOUNT).into()),
|
||||||
|
0,
|
||||||
|
WeightLimit::Unlimited,
|
||||||
|
));
|
||||||
|
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
||||||
|
assert_eq!(
|
||||||
|
sent_xcm(),
|
||||||
|
vec![(
|
||||||
|
RelayLocation::get().into(),
|
||||||
|
Xcm(vec![
|
||||||
|
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
||||||
|
ClearOrigin,
|
||||||
|
buy_execution((Here, SEND_AMOUNT)),
|
||||||
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||||
|
]),
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
last_event(),
|
||||||
|
Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Test `reserve_transfer_assets`
|
/// Test `reserve_transfer_assets`
|
||||||
///
|
///
|
||||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
||||||
@@ -280,7 +362,7 @@ fn reserve_transfer_assets_works() {
|
|||||||
Xcm(vec![
|
Xcm(vec![
|
||||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
||||||
ClearOrigin,
|
ClearOrigin,
|
||||||
buy_limited_execution((Parent, SEND_AMOUNT), 2000),
|
buy_limited_execution((Parent, SEND_AMOUNT), 4000),
|
||||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||||
]),
|
]),
|
||||||
)]
|
)]
|
||||||
@@ -294,6 +376,98 @@ fn reserve_transfer_assets_works() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test `limited_reserve_transfer_assets`
|
||||||
|
///
|
||||||
|
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
||||||
|
/// is increased. Verifies the correct message is sent and event is emitted.
|
||||||
|
#[test]
|
||||||
|
fn limited_reserve_transfer_assets_works() {
|
||||||
|
let balances =
|
||||||
|
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||||
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
|
let weight = BaseXcmWeight::get();
|
||||||
|
let dest: MultiLocation =
|
||||||
|
Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }.into();
|
||||||
|
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
||||||
|
assert_ok!(XcmPallet::limited_reserve_transfer_assets(
|
||||||
|
Origin::signed(ALICE),
|
||||||
|
Box::new(Parachain(PARA_ID).into().into()),
|
||||||
|
Box::new(dest.clone().into()),
|
||||||
|
Box::new((Here, SEND_AMOUNT).into()),
|
||||||
|
0,
|
||||||
|
WeightLimit::Limited(5000),
|
||||||
|
));
|
||||||
|
// Alice spent amount
|
||||||
|
assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
||||||
|
// Destination account (parachain account) has amount
|
||||||
|
let para_acc: AccountId = ParaId::from(PARA_ID).into_account();
|
||||||
|
assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT);
|
||||||
|
assert_eq!(
|
||||||
|
sent_xcm(),
|
||||||
|
vec![(
|
||||||
|
Parachain(PARA_ID).into(),
|
||||||
|
Xcm(vec![
|
||||||
|
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
||||||
|
ClearOrigin,
|
||||||
|
buy_limited_execution((Parent, SEND_AMOUNT), 5000),
|
||||||
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||||
|
]),
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1);
|
||||||
|
let _check_v0_ok: xcm::v0::Xcm<()> = versioned_sent.try_into().unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
last_event(),
|
||||||
|
Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test `limited_reserve_transfer_assets` with unlimited weight purchasing
|
||||||
|
///
|
||||||
|
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
||||||
|
/// is increased. Verifies the correct message is sent and event is emitted.
|
||||||
|
#[test]
|
||||||
|
fn unlimited_reserve_transfer_assets_works() {
|
||||||
|
let balances =
|
||||||
|
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||||
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
|
let weight = BaseXcmWeight::get();
|
||||||
|
let dest: MultiLocation =
|
||||||
|
Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }.into();
|
||||||
|
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
||||||
|
assert_ok!(XcmPallet::limited_reserve_transfer_assets(
|
||||||
|
Origin::signed(ALICE),
|
||||||
|
Box::new(Parachain(PARA_ID).into().into()),
|
||||||
|
Box::new(dest.clone().into()),
|
||||||
|
Box::new((Here, SEND_AMOUNT).into()),
|
||||||
|
0,
|
||||||
|
WeightLimit::Unlimited,
|
||||||
|
));
|
||||||
|
// Alice spent amount
|
||||||
|
assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
||||||
|
// Destination account (parachain account) has amount
|
||||||
|
let para_acc: AccountId = ParaId::from(PARA_ID).into_account();
|
||||||
|
assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT);
|
||||||
|
assert_eq!(
|
||||||
|
sent_xcm(),
|
||||||
|
vec![(
|
||||||
|
Parachain(PARA_ID).into(),
|
||||||
|
Xcm(vec![
|
||||||
|
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
||||||
|
ClearOrigin,
|
||||||
|
buy_execution((Parent, SEND_AMOUNT)),
|
||||||
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||||
|
]),
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
last_event(),
|
||||||
|
Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Test local execution of XCM
|
/// Test local execution of XCM
|
||||||
///
|
///
|
||||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
||||||
|
|||||||
Reference in New Issue
Block a user