Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more emulated bridge tests #512

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions integration-tests/emulated/chains/relays/kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.

pub mod genesis;
pub use kusama_runtime;

// Cumulus
use emulated_integration_tests_common::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.

pub mod genesis;
pub use polkadot_runtime;

// Cumulus
use emulated_integration_tests_common::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ pub use kusama_polkadot_system_emulated_network::{
bridge_hub_kusama_emulated_chain::{
genesis::ED as BRIDGE_HUB_KUSAMA_ED, BridgeHubKusamaParaPallet as BridgeHubKusamaPallet,
},
kusama_emulated_chain::{genesis::ED as KUSAMA_ED, KusamaRelayPallet as KusamaPallet},
kusama_emulated_chain::{
genesis::ED as KUSAMA_ED,
kusama_runtime::xcm_config::UniversalLocation as KusamaRelayUniversalLocation,
KusamaRelayPallet as KusamaPallet,
},
penpal_emulated_chain::{
penpal_runtime::xcm_config::{
CustomizableAssetFromSystemAssetHub as PenpalCustomizableAssetFromSystemAssetHub,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,47 +55,21 @@ fn set_up_ksm_for_penpal_kusama_through_kah_to_pah(
(ksm_at_kusama_parachains, ksm_at_asset_hub_polkadot)
}

fn send_assets_from_penpal_kusama_through_kusama_ah_to_polkadot_ah(
destination: Location,
assets: (Assets, TransferType),
fees: (AssetId, TransferType),
custom_xcm_on_dest: Xcm<()>,
) {
fn send_assets_from_kusama_chain_through_kusama_ah_to_polkadot_ah<F: FnOnce()>(send_fn: F) {
send_assets_over_bridge(|| {
let sov_penpal_on_kah = AssetHubKusama::sovereign_account_id_of(
AssetHubKusama::sibling_location_of(PenpalA::para_id()),
);
let sov_pah_on_kah =
AssetHubKusama::sovereign_account_of_parachain_on_other_global_consensus(
Polkadot,
AssetHubPolkadot::para_id(),
);
// send message over bridge
assert_ok!(PenpalA::execute_with(|| {
let signed_origin = <PenpalA as Chain>::RuntimeOrigin::signed(PenpalASender::get());
<PenpalA as PenpalAPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin,
bx!(destination.into()),
bx!(assets.0.into()),
bx!(assets.1),
bx!(fees.0.into()),
bx!(fees.1),
bx!(VersionedXcm::from(custom_xcm_on_dest)),
WeightLimit::Unlimited,
)
}));
// call transfer extrinsic on sender chain
send_fn();
// verify intermediary AH Kusama hop
AssetHubKusama::execute_with(|| {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
assert_expected_events!(
AssetHubKusama,
vec![
// Amount to reserve transfer is withdrawn from Penpal's sovereign account
RuntimeEvent::Balances(
pallet_balances::Event::Burned { who, .. }
) => {
who: *who == sov_penpal_on_kah.clone(),
},
// Amount deposited in PAH's sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) => {
who: *who == sov_pah_on_kah.clone(),
Expand All @@ -115,7 +89,6 @@ fn send_ksm_from_asset_hub_kusama_to_asset_hub_polkadot() {
let amount = ASSET_HUB_KUSAMA_ED * 1_000;
let sender = AssetHubKusamaSender::get();
let receiver = AssetHubPolkadotReceiver::get();
let ksm_at_asset_hub_kusama = ksm_at_ah_kusama();
let bridged_ksm_at_ah_polkadot = bridged_ksm_at_ah_polkadot();

create_foreign_on_ah_polkadot(bridged_ksm_at_ah_polkadot.clone(), true);
Expand All @@ -131,12 +104,10 @@ fn send_ksm_from_asset_hub_kusama_to_asset_hub_polkadot() {
let receiver_ksms_before =
foreign_balance_on_ah_polkadot(bridged_ksm_at_ah_polkadot.clone(), &receiver);

let ksm_at_ah_kusama_latest = ksm_at_ah_kusama();

// send KSMs, use them for fees
send_assets_over_bridge(|| {
let destination = asset_hub_polkadot_location();
let assets: Assets = (ksm_at_ah_kusama_latest, amount).into();
let assets: Assets = (ksm_at_ah_kusama(), amount).into();
let fee_idx = 0;
assert_ok!(send_assets_from_asset_hub_kusama(destination, assets, fee_idx));
});
Expand All @@ -149,7 +120,7 @@ fn send_ksm_from_asset_hub_kusama_to_asset_hub_polkadot() {
vec![
// issue KSMs on PAH
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => {
asset_id: *asset_id == ksm_at_asset_hub_kusama,
asset_id: *asset_id == bridged_ksm_at_ah_polkadot,
owner: *owner == AssetHubPolkadotReceiver::get(),
},
// message processed successfully
Expand Down Expand Up @@ -347,6 +318,115 @@ fn send_back_dot_usdt_and_weth_from_asset_hub_kusama_to_asset_hub_polkadot() {
assert_eq!(receiver_weth_after, receiver_weth_before + amount_to_send);
}

#[test]
/// Test transfer of KSM from Kusama Relay through AssetHub Kusama to AssetHub Polkadot.
fn send_ksm_from_kusama_relay_through_asset_hub_kusama_to_asset_hub_polkadot() {
let amount = KUSAMA_ED * 100;
let sender = KusamaSender::get();
let receiver = AssetHubPolkadotReceiver::get();
let ksm_at_kusama: Location = Here.into();
let bridged_ksm_at_ah_polkadot = bridged_ksm_at_ah_polkadot();

create_foreign_on_ah_polkadot(bridged_ksm_at_ah_polkadot.clone(), true);
set_up_pool_with_dot_on_ah_polkadot(bridged_ksm_at_ah_polkadot.clone(), true);

let sov_ahp_on_ahk = AssetHubKusama::sovereign_account_of_parachain_on_other_global_consensus(
Polkadot,
AssetHubPolkadot::para_id(),
);
let sender_ksms_before = <Kusama as Chain>::account_data_of(sender.clone()).free;
let ksms_in_reserve_on_ahk_before =
<AssetHubKusama as Chain>::account_data_of(sov_ahp_on_ahk.clone()).free;
let receiver_ksms_before =
foreign_balance_on_ah_polkadot(bridged_ksm_at_ah_polkadot.clone(), &receiver);

// send KSMs over the bridge, teleport to local AH, reserve deposit to remote AH
{
let final_destination = Location::new(
1,
[GlobalConsensus(Polkadot), Parachain(AssetHubPolkadot::para_id().into())],
);
let intermediary_hop = Kusama::child_location_of(AssetHubKusama::para_id());
let context = Kusama::execute_with(KusamaRelayUniversalLocation::get);

// what happens at final destination
let beneficiary = AccountId32Junction { network: None, id: receiver.clone().into() }.into();
// use KSM as fees on the final destination (PAH), only use half the amount as some
// of it was already spent on intermediate hop (KAH)
let remote_fees: Asset = (bridged_ksm_at_ah_polkadot.clone(), amount / 2).into();
// buy execution using KSMs, then deposit all unspent KSMs
let xcm_on_final_dest = Xcm::<()>(vec![
BuyExecution { fees: remote_fees, weight_limit: WeightLimit::Unlimited },
DepositAsset { assets: Wild(AllCounted(1)), beneficiary },
]);

// what happens at intermediary hop
// reanchor final dest (Asset Hub Polkadot) to the view of hop (Asset Hub Kusama)
let mut final_destination = final_destination.clone();
final_destination.reanchor(&intermediary_hop, &context).unwrap();
// on Asset Hub Kusama, forward a deposit reserve KSMs to Asset Hub Polkadot
let xcm_on_hop = Xcm::<()>(vec![DepositReserveAsset {
assets: Wild(AllCounted(1)), // KSMs
dest: final_destination, // PAH
xcm: xcm_on_final_dest, // XCM to execute on PAH
}]);
// assets to send from Kusama Relay and how they reach the intermediary hop
let assets: Assets = vec![(ksm_at_kusama.clone(), amount).into()].into();
let asset_transfer_type = TransferType::Teleport;
let fees_id: AssetId = ksm_at_kusama.into();
let fees_transfer_type = TransferType::Teleport;

// initiate the transfer
send_assets_from_kusama_chain_through_kusama_ah_to_polkadot_ah(|| {
// send message over bridge
assert_ok!(Kusama::execute_with(|| {
let signed_origin = <Kusama as Chain>::RuntimeOrigin::signed(sender.clone());
<Kusama as KusamaPallet>::XcmPallet::transfer_assets_using_type_and_then(
signed_origin,
bx!(intermediary_hop.into()),
bx!(assets.into()),
bx!(asset_transfer_type),
bx!(fees_id.into()),
bx!(fees_transfer_type),
bx!(VersionedXcm::from(xcm_on_hop)),
WeightLimit::Unlimited,
)
}));
});
}

// verify expected events on final destination
AssetHubPolkadot::execute_with(|| {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
assert_expected_events!(
AssetHubPolkadot,
vec![
// issue KSMs on PAH
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => {
asset_id: *asset_id == bridged_ksm_at_ah_polkadot,
owner: *owner == AssetHubPolkadotReceiver::get(),
},
// message processed successfully
RuntimeEvent::MessageQueue(
pallet_message_queue::Event::Processed { success: true, .. }
) => {},
]
);
});

let sender_ksms_after = <Kusama as Chain>::account_data_of(sender.clone()).free;
let receiver_ksms_after = foreign_balance_on_ah_polkadot(bridged_ksm_at_ah_polkadot, &receiver);
let ksms_in_reserve_on_ahk_after =
<AssetHubKusama as Chain>::account_data_of(sov_ahp_on_ahk.clone()).free;

// Sender's balance is reduced
assert!(sender_ksms_before > sender_ksms_after);
// Reserve balance on KAH increased
assert!(ksms_in_reserve_on_ahk_after > ksms_in_reserve_on_ahk_before);
// Receiver's balance is increased
assert!(receiver_ksms_after > receiver_ksms_before);
}

#[test]
fn send_ksm_from_penpal_kusama_through_asset_hub_kusama_to_asset_hub_polkadot() {
let amount = ASSET_HUB_KUSAMA_ED * 10_000_000;
Expand Down Expand Up @@ -382,12 +462,23 @@ fn send_ksm_from_penpal_kusama_through_asset_hub_kusama_to_asset_hub_polkadot()
assets: Wild(AllCounted(assets.len() as u32)),
beneficiary,
}]);
send_assets_from_penpal_kusama_through_kusama_ah_to_polkadot_ah(
destination,
(assets, asset_transfer_type),
(fees_id, fees_transfer_type),
custom_xcm_on_dest,
);

send_assets_from_kusama_chain_through_kusama_ah_to_polkadot_ah(|| {
// send message over bridge
assert_ok!(PenpalA::execute_with(|| {
let signed_origin = <PenpalA as Chain>::RuntimeOrigin::signed(sender.clone());
<PenpalA as PenpalAPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin,
bx!(destination.into()),
bx!(assets.into()),
bx!(asset_transfer_type),
bx!(fees_id.into()),
bx!(fees_transfer_type),
bx!(VersionedXcm::from(custom_xcm_on_dest)),
WeightLimit::Unlimited,
)
}));
});
}

// process PAH incoming message and check events
Expand Down Expand Up @@ -517,12 +608,22 @@ fn send_back_dot_from_penpal_kusama_through_asset_hub_kusama_to_asset_hub_polkad
let fees_transfer_type = TransferType::DestinationReserve;

// initiate the transfer
send_assets_from_penpal_kusama_through_kusama_ah_to_polkadot_ah(
intermediary_hop,
(assets, asset_transfer_type),
(fees_id, fees_transfer_type),
xcm_on_hop,
);
send_assets_from_kusama_chain_through_kusama_ah_to_polkadot_ah(|| {
// send message over bridge
assert_ok!(PenpalA::execute_with(|| {
let signed_origin = <PenpalA as Chain>::RuntimeOrigin::signed(PenpalASender::get());
<PenpalA as PenpalAPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin,
bx!(intermediary_hop.into()),
bx!(assets.into()),
bx!(asset_transfer_type),
bx!(fees_id.into()),
bx!(fees_transfer_type),
bx!(VersionedXcm::from(xcm_on_hop)),
WeightLimit::Unlimited,
)
}));
});
}

// process PAH incoming message and check events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ pub use kusama_polkadot_system_emulated_network::{
},
PenpalAssetOwner, PenpalBParaPallet as PenpalBPallet,
},
polkadot_emulated_chain::{genesis::ED as POLKADOT_ED, PolkadotRelayPallet as PolkadotPallet},
polkadot_emulated_chain::{
genesis::ED as POLKADOT_ED,
polkadot_runtime::xcm_config::UniversalLocation as PolkadotRelayUniversalLocation,
PolkadotRelayPallet as PolkadotPallet,
},
AssetHubKusamaPara as AssetHubKusama, AssetHubKusamaParaReceiver as AssetHubKusamaReceiver,
AssetHubKusamaParaSender as AssetHubKusamaSender, AssetHubPolkadotPara as AssetHubPolkadot,
AssetHubPolkadotParaReceiver as AssetHubPolkadotReceiver,
Expand Down
Loading
Loading