Skip to content

Commit c55944d

Browse files
paritytech-release-backport-bot[bot]karolk91github-actions[bot]acatangiu
authored
[stable2506] Backport #9195 (#9405)
Backport #9195 into `stable2506` from karolk91. See the [documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md) on how to use this bot. <!-- # To be used by other automation, do not modify: original-pr-number: #${pull_number} --> Co-authored-by: Karol Kokoszka <[email protected]> Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Adrian Catangiu <[email protected]>
1 parent 8f68ad1 commit c55944d

File tree

6 files changed

+632
-4
lines changed

6 files changed

+632
-4
lines changed

cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ mod imports {
4444
TestArgs, TestContext, TestExt,
4545
},
4646
xcm_helpers::{
47-
fee_asset, get_amount_from_versioned_assets, non_fee_asset, xcm_transact_paid_execution,
47+
fee_asset, find_mq_processed_id, find_xcm_sent_message_id,
48+
get_amount_from_versioned_assets, non_fee_asset, xcm_transact_paid_execution,
4849
},
50+
xcm_simulator::helpers::TopicIdTracker,
4951
PenpalATeleportableAssetLocation, ASSETS_PALLET_ID, RESERVABLE_ASSET_ID, USDT_ID, XCM_V3,
5052
};
5153
pub(crate) use parachains_common::{AccountId, Balance};

cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/exchange_asset.rs

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// limitations under the License.
1515

1616
use crate::{
17-
create_pool_with_wnd_on,
17+
assets_balance_on, create_pool_with_wnd_on, foreign_balance_on,
1818
imports::{
1919
asset_hub_westend_runtime::{ExistentialDeposit, Runtime},
2020
*,
@@ -156,3 +156,173 @@ fn test_exchange_asset(
156156
}
157157
});
158158
}
159+
160+
#[test]
161+
fn exchange_asset_from_penpal_via_asset_hub_back_to_penpal() {
162+
let sender = PenpalASender::get();
163+
let sov_of_penpal_on_asset_hub = AssetHubWestend::sovereign_account_id_of(
164+
AssetHubWestend::sibling_location_of(PenpalA::para_id()),
165+
);
166+
let wnd_from_parachain_pov: Location = RelayLocation::get();
167+
let usdt_asset_hub_pov =
168+
Location::new(0, [PalletInstance(ASSETS_PALLET_ID), GeneralIndex(USDT_ID.into())]);
169+
let usdt_penpal_pov = PenpalUsdtFromAssetHub::get();
170+
let amount_of_wnd_to_transfer_to_ah = WESTEND_ED * 1_000_000_000;
171+
let amount_of_usdt_we_want_from_exchange = 1_000_000_000;
172+
173+
let mut topic_id_tracker = TopicIdTracker::new();
174+
175+
// SA-of-Penpal-on-AHW should contain WND amount equal at least the amount that will be
176+
// transferred-in to AH Since AH is the reserve for WND
177+
AssetHubWestend::fund_accounts(vec![(
178+
sov_of_penpal_on_asset_hub.clone().into(),
179+
ASSET_HUB_WESTEND_ED + amount_of_wnd_to_transfer_to_ah,
180+
)]);
181+
// Give the sender enough WND
182+
PenpalA::mint_foreign_asset(
183+
<PenpalA as Chain>::RuntimeOrigin::signed(PenpalAssetOwner::get()),
184+
wnd_from_parachain_pov.clone(),
185+
sender.clone(),
186+
amount_of_wnd_to_transfer_to_ah,
187+
);
188+
189+
// We create a pool between WND and USDT in AssetHub so we can do the exchange
190+
create_pool_with_wnd_on!(
191+
AssetHubWestend,
192+
usdt_asset_hub_pov.clone(),
193+
false,
194+
AssetHubWestendSender::get(),
195+
1_000_000_000_000,
196+
20_000_000_000
197+
);
198+
199+
// Query initial balances
200+
let sender_usdt_on_penpal_before =
201+
foreign_balance_on!(PenpalA, usdt_penpal_pov.clone(), &sender);
202+
let sender_usdt_on_ah_before = assets_balance_on!(AssetHubWestend, USDT_ID, &sender);
203+
204+
let asset_hub_location_penpal_pov = PenpalA::sibling_location_of(AssetHubWestend::para_id());
205+
let penpal_location_ah_pov = AssetHubWestend::sibling_location_of(PenpalA::para_id());
206+
207+
PenpalA::execute_with(|| {
208+
let sender_signed_origin = <PenpalA as Chain>::RuntimeOrigin::signed(sender.clone());
209+
210+
let local_fees_amount = 80_000_000_000_000u128;
211+
let remote_fees_amount = 200_000_000_000_000u128;
212+
213+
let penpal_local_fees: Asset = (wnd_from_parachain_pov.clone(), local_fees_amount).into();
214+
let ah_remote_fees: Asset = (wnd_from_parachain_pov.clone(), remote_fees_amount).into();
215+
let penpal_remote_fees: Asset = (wnd_from_parachain_pov.clone(), remote_fees_amount).into();
216+
let wnd_to_withdraw: Asset =
217+
(wnd_from_parachain_pov.clone(), amount_of_wnd_to_transfer_to_ah).into();
218+
219+
// xcm to be executed by penpal, sent by ah
220+
let xcm_back_on_penpal = Xcm(vec![
221+
RefundSurplus,
222+
DepositAsset { assets: Wild(All), beneficiary: sender.clone().into() },
223+
]);
224+
// xcm to be executed by ah, sent by penpal
225+
let xcm_on_ah = Xcm(vec![
226+
ExchangeAsset {
227+
give: Definite((wnd_from_parachain_pov.clone(), 100_000_000_000u128).into()),
228+
want: (usdt_asset_hub_pov.clone(), amount_of_usdt_we_want_from_exchange).into(),
229+
maximal: false,
230+
},
231+
InitiateTransfer {
232+
destination: penpal_location_ah_pov,
233+
remote_fees: Some(AssetTransferFilter::ReserveDeposit(
234+
penpal_remote_fees.clone().into(),
235+
)),
236+
preserve_origin: false,
237+
assets: BoundedVec::truncate_from(vec![AssetTransferFilter::ReserveDeposit(Wild(
238+
All,
239+
))]),
240+
remote_xcm: xcm_back_on_penpal,
241+
},
242+
RefundSurplus,
243+
DepositAsset { assets: Wild(All), beneficiary: sender.clone().into() },
244+
]);
245+
// xcm to be executed locally on penpal as starting point
246+
let xcm = Xcm::<()>(vec![
247+
WithdrawAsset(wnd_to_withdraw.into()),
248+
PayFees { asset: penpal_local_fees },
249+
InitiateTransfer {
250+
destination: asset_hub_location_penpal_pov,
251+
remote_fees: Some(AssetTransferFilter::ReserveWithdraw(
252+
ah_remote_fees.clone().into(),
253+
)),
254+
preserve_origin: false,
255+
assets: BoundedVec::truncate_from(vec![AssetTransferFilter::ReserveWithdraw(
256+
Wild(All),
257+
)]),
258+
remote_xcm: xcm_on_ah,
259+
},
260+
RefundSurplus,
261+
DepositAsset { assets: Wild(All), beneficiary: sender.clone().into() },
262+
]);
263+
// initiate transaction
264+
<PenpalA as PenpalAPallet>::PolkadotXcm::execute(
265+
sender_signed_origin,
266+
bx!(xcm::VersionedXcm::from(xcm.into())),
267+
Weight::MAX,
268+
)
269+
.unwrap();
270+
271+
// verify expected events;
272+
PenpalA::assert_xcm_pallet_attempted_complete(None);
273+
274+
let msg_sent_id = find_xcm_sent_message_id::<PenpalA>().expect("Missing Sent Event");
275+
topic_id_tracker.insert("PenpalA_sent", msg_sent_id.into());
276+
});
277+
AssetHubWestend::execute_with(|| {
278+
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
279+
assert_expected_events!(
280+
AssetHubWestend,
281+
vec![
282+
RuntimeEvent::MessageQueue(
283+
pallet_message_queue::Event::Processed { success: true, .. }
284+
) => {},
285+
RuntimeEvent::AssetConversion(
286+
pallet_asset_conversion::Event::SwapCreditExecuted { amount_out, ..}
287+
) => { amount_out: *amount_out == amount_of_usdt_we_want_from_exchange, },
288+
]
289+
);
290+
291+
let mq_prc_id = find_mq_processed_id::<AssetHubWestend>().expect("Missing Processed Event");
292+
topic_id_tracker.insert("AssetHubWestend_received", mq_prc_id);
293+
let msg_sent_id =
294+
find_xcm_sent_message_id::<AssetHubWestend>().expect("Missing Sent Event");
295+
topic_id_tracker.insert("AssetHubWestend_sent", msg_sent_id.into());
296+
});
297+
298+
PenpalA::execute_with(|| {
299+
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
300+
assert_expected_events!(
301+
PenpalA,
302+
vec![
303+
RuntimeEvent::MessageQueue(
304+
pallet_message_queue::Event::Processed { success: true, .. }
305+
) => {},
306+
]
307+
);
308+
309+
let mq_prc_id = find_mq_processed_id::<PenpalA>().expect("Missing Processed Event");
310+
topic_id_tracker.insert("PenpalA_received", mq_prc_id);
311+
});
312+
313+
topic_id_tracker.assert_unique();
314+
315+
// Query final balances
316+
let sender_usdt_on_ah_after = assets_balance_on!(AssetHubWestend, USDT_ID, &sender);
317+
let sender_usdt_on_penpal_after =
318+
foreign_balance_on!(PenpalA, usdt_penpal_pov.clone(), &sender);
319+
320+
// Receiver's balance is increased by usdt amount we got from exchange
321+
assert_eq!(
322+
sender_usdt_on_penpal_after,
323+
sender_usdt_on_penpal_before + amount_of_usdt_we_want_from_exchange
324+
);
325+
// Usdt amount on senders account AH side should stay the same i.e. all usdt came from exchange
326+
// not free balance
327+
assert_eq!(sender_usdt_on_ah_before, sender_usdt_on_ah_after);
328+
}

cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,19 @@ macro_rules! foreign_balance_on {
3636
emulated_integration_tests_common::impls::paste::paste! {
3737
<$chain>::execute_with(|| {
3838
type ForeignAssets = <$chain as [<$chain Pallet>]>::ForeignAssets;
39-
<ForeignAssets as Inspect<_>>::balance($id, $who)
39+
<ForeignAssets as frame_support::traits::fungibles::Inspect<_>>::balance($id, $who)
40+
})
41+
}
42+
};
43+
}
44+
45+
#[macro_export]
46+
macro_rules! assets_balance_on {
47+
( $chain:ident, $id:expr, $who:expr ) => {
48+
emulated_integration_tests_common::impls::paste::paste! {
49+
<$chain>::execute_with(|| {
50+
type Assets = <$chain as [<$chain Pallet>]>::Assets;
51+
<Assets as frame_support::traits::fungibles::Inspect<_>>::balance($id, $who)
4052
})
4153
}
4254
};

0 commit comments

Comments
 (0)