mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 15:11: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.
|
||||
///
|
||||
/// 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.
|
||||
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
||||
@@ -506,54 +508,15 @@ pub mod pallet {
|
||||
assets: Box<VersionedMultiAssets>,
|
||||
fee_asset_item: u32,
|
||||
) -> DispatchResult {
|
||||
let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
|
||||
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(())
|
||||
Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, None)
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// 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.
|
||||
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
|
||||
@@ -583,45 +546,14 @@ pub mod pallet {
|
||||
assets: Box<VersionedMultiAssets>,
|
||||
fee_asset_item: u32,
|
||||
) -> DispatchResult {
|
||||
let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
|
||||
let dest = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||
let beneficiary = (*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 = 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(())
|
||||
Self::do_reserve_transfer_assets(
|
||||
origin,
|
||||
dest,
|
||||
beneficiary,
|
||||
assets,
|
||||
fee_asset_item,
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
/// Execute an XCM message from a local, signed, origin.
|
||||
@@ -732,9 +664,218 @@ pub mod pallet {
|
||||
.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> {
|
||||
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`
|
||||
/// in doing so.
|
||||
pub(crate) fn check_xcm_version_change(
|
||||
|
||||
@@ -234,7 +234,7 @@ fn teleport_assets_works() {
|
||||
Xcm(vec![
|
||||
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
||||
ClearOrigin,
|
||||
buy_limited_execution((Here, SEND_AMOUNT), 2000),
|
||||
buy_limited_execution((Here, SEND_AMOUNT), 4000),
|
||||
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`
|
||||
///
|
||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
||||
@@ -280,7 +362,7 @@ fn reserve_transfer_assets_works() {
|
||||
Xcm(vec![
|
||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
||||
ClearOrigin,
|
||||
buy_limited_execution((Parent, SEND_AMOUNT), 2000),
|
||||
buy_limited_execution((Parent, SEND_AMOUNT), 4000),
|
||||
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
|
||||
///
|
||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
||||
|
||||
Reference in New Issue
Block a user