Skip to content

Commit

Permalink
emulated-test: Send WNDs: PenpalRococo -> AssetHubRococo -> AssetHubW…
Browse files Browse the repository at this point in the history
…estend

Send both ROCs and WNDs, ROCs are only used to pay for transport fees on AHR,
and are not sent over the bridge.
  • Loading branch information
acatangiu committed Jun 24, 2024
1 parent 31a1153 commit d6036dd
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 48 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ pallet-bridge-messages = { workspace = true }
parachains-common = { workspace = true, default-features = true }
testnet-parachains-constants = { features = ["rococo"], workspace = true, default-features = true }
cumulus-pallet-xcmp-queue = { workspace = true }
bridge-hub-rococo-runtime = { workspace = true }
emulated-integration-tests-common = { workspace = true }
asset-hub-rococo-runtime = { workspace = true }
bridge-hub-rococo-runtime = { workspace = true }
penpal-runtime = { workspace = true }
rococo-westend-system-emulated-network = { workspace = true }
rococo-system-emulated-network = { workspace = true }
asset-hub-rococo-runtime = { workspace = true }

# Snowbridge
snowbridge-core = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod imports {
},
};
pub use parachains_common::AccountId;
pub use penpal_runtime::xcm_config::UniversalLocation as PenpalUniversalLocation;
pub use rococo_westend_system_emulated_network::{
asset_hub_rococo_emulated_chain::{
genesis::ED as ASSET_HUB_ROCOCO_ED, AssetHubRococoParaPallet as AssetHubRococoPallet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: Location, amount: u
assert_bridge_hub_westend_message_received();
}

fn send_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
fn send_local_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
id: Location,
transfer_amount: u128,
) {
Expand Down Expand Up @@ -102,6 +102,100 @@ fn send_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
assert_bridge_hub_westend_message_received();
}

fn send_bridged_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
asset: Asset,
// needs to be ROCs
fee: Asset,
) {
let destination = asset_hub_westend_location();
let local_asset_hub: Location = PenpalA::sibling_location_of(AssetHubRococo::para_id());
let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(
AssetHubRococo::sibling_location_of(PenpalA::para_id()),
);
let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
Westend,
AssetHubWestend::para_id(),
);

// fund the AHR's SA on BHR for paying bridge transport fees
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128);

// set XCM versions
PenpalA::force_xcm_version(local_asset_hub.clone(), XCM_VERSION);
AssetHubRococo::force_xcm_version(destination.clone(), XCM_VERSION);
BridgeHubRococo::force_xcm_version(bridge_hub_westend_location(), XCM_VERSION);

// send message over bridge
assert_ok!(PenpalA::execute_with(|| {
let signed_origin = <PenpalA as Chain>::RuntimeOrigin::signed(PenpalASender::get());
let beneficiary: Location =
AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into();

let context = PenpalUniversalLocation::get();
// use WND as fees on the final destination (AHW)
let remote_fees = asset.clone().reanchored(&destination, &context).unwrap();
// buy execution using WNDs, then deposit all remaining WNDs
let xcm_on_final_dest = Xcm::<()>(vec![
BuyExecution { fees: remote_fees.into(), weight_limit: WeightLimit::Unlimited },
DepositAsset { assets: Wild(AllCounted(1)), beneficiary },
]);

// reanchor final dest (Asset Hub Westend) to the view of hop (Asset Hub Rococo)
let mut dest = destination.clone();
dest.reanchor(&local_asset_hub, &context).unwrap();
// on Asset Hub Rococo, forward a request to withdraw reserve on Asset Hub Westend
let xcm_on_hop = Xcm::<()>(vec![InitiateReserveWithdraw {
assets: Definite(asset.clone().into()), // WNDs
reserve: dest, // AHW
xcm: xcm_on_final_dest, // XCM to execute on AHW
}]);

let assets: Assets = vec![asset, fee.clone()].into();
let fees_id: AssetId = fee.id;

// asset transfers:
// - bridged asset (WND):
// 1. reserve-withdraw derivative (wWND) from Penpal's SA on AHR
// 2. reserve-withdraw actual asset (WND) from AHR's SA on AHW
// - fee/local asset (ROC) - doesn't get bridged over, we pay fees with WND on other side:
// 1. reserve-withdraw asset (ROC) from Penpal's SA on AHR (only used to pay for fees on
// AHR, because we didn't have wWND on Penpal)
<PenpalA as PenpalAPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin,
bx!(local_asset_hub.into()),
bx!(assets.clone().into()),
bx!(TransferType::DestinationReserve),
bx!(fees_id.into()),
bx!(TransferType::DestinationReserve),
bx!(VersionedXcm::from(xcm_on_hop)),
WeightLimit::Unlimited,
)
}));
AssetHubRococo::execute_with(|| {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
assert_expected_events!(
AssetHubRococo,
vec![
// Amount to reserve transfer is withdrawn from Penpal's sovereign account
RuntimeEvent::Balances(
pallet_balances::Event::Burned { who, .. }
) => {
who: *who == sov_penpal_on_ahr.clone().into(),
},
// Amount deposited in AHW's sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) => {
who: *who == sov_ahw_on_ahr.clone().into(),
},
RuntimeEvent::XcmpQueue(
cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
) => {},
]
);
});
assert_bridge_hub_rococo_message_accepted(true);
assert_bridge_hub_westend_message_received();
}

#[test]
fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() {
let roc_at_asset_hub_rococo: v3::Location = v3::Parent.into();
Expand Down Expand Up @@ -290,24 +384,20 @@ fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() {
assert_eq!(wnds_in_reserve_on_ahw_after, wnds_in_reserve_on_ahw_before - amount_to_send);
}

#[test]
fn send_rocs_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend() {
fn set_up_rocs_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend(
amount: u128,
) -> (Location, Location) {
let roc_at_rococo_parachains: Location = Parent.into();
let roc_at_asset_hub_westend = Location::new(2, [Junction::GlobalConsensus(NetworkId::Rococo)]);
let owner: AccountId = AssetHubWestend::account_id_of(ALICE);
let asset_owner: AccountId = AssetHubWestend::account_id_of(ALICE);
AssetHubWestend::force_create_foreign_asset(
roc_at_asset_hub_westend.clone().try_into().unwrap(),
owner,
asset_owner,
true,
ASSET_MIN_BALANCE,
vec![],
);
let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
Westend,
AssetHubWestend::para_id(),
);

let amount = ASSET_HUB_ROCOCO_ED * 10_000_000;
let penpal_location = AssetHubRococo::sibling_location_of(PenpalA::para_id());
let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(penpal_location);
// fund Penpal's sovereign account on AssetHub
Expand All @@ -319,7 +409,19 @@ fn send_rocs_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend()
PenpalASender::get(),
amount * 2,
);
(roc_at_rococo_parachains, roc_at_asset_hub_westend)
}

#[test]
fn send_rocs_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend() {
let amount = ASSET_HUB_ROCOCO_ED * 10_000_000;
let (roc_at_rococo_parachains, roc_at_asset_hub_westend) =
set_up_rocs_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend(amount);

let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
Westend,
AssetHubWestend::para_id(),
);
let rocs_in_reserve_on_ahr_before =
<AssetHubRococo as Chain>::account_data_of(sov_ahw_on_ahr.clone()).free;
let sender_rocs_before = PenpalA::execute_with(|| {
Expand All @@ -336,7 +438,7 @@ fn send_rocs_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend()
&AssetHubWestendReceiver::get(),
)
});
send_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
send_local_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
roc_at_rococo_parachains.clone(),
amount,
);
Expand Down Expand Up @@ -388,7 +490,11 @@ fn send_wnds_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend()
v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]);
let wnd_at_rococo_parachains_latest: Location = wnd_at_rococo_parachains.try_into().unwrap();
let owner: AccountId = AssetHubRococo::account_id_of(ALICE);
println!("🤡 1");
let amount = ASSET_HUB_ROCOCO_ED * 10_000_000;

let (roc_at_rococo_parachains, _) =
set_up_rocs_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend(amount);

AssetHubRococo::force_create_foreign_asset(
wnd_at_rococo_parachains,
owner.clone(),
Expand All @@ -403,8 +509,6 @@ fn send_wnds_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend()
ASSET_MIN_BALANCE,
vec![],
);
let amount = ASSET_HUB_ROCOCO_ED * 10_000_000;
println!("🤡 2");

// fund the AHR's SA on AHW with the WND tokens held in reserve
let sov_ahr_on_ahw = AssetHubWestend::sovereign_account_of_parachain_on_other_global_consensus(
Expand All @@ -413,12 +517,6 @@ fn send_wnds_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend()
);
AssetHubWestend::fund_accounts(vec![(sov_ahr_on_ahw.clone(), amount * 2)]);

let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
NetworkId::Westend,
AssetHubWestend::para_id(),
);
println!("🤡 3");

let penpal_location = AssetHubRococo::sibling_location_of(PenpalA::para_id());
let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(penpal_location);
// fund Penpal's sovereign account on AssetHub
Expand All @@ -428,47 +526,36 @@ fn send_wnds_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend()
sov_penpal_on_ahr,
amount * 2,
);
println!("🤡 4");

// fund Penpal's sender account
PenpalA::mint_foreign_asset(
<PenpalA as Chain>::RuntimeOrigin::signed(PenpalAssetOwner::get()),
wnd_at_rococo_parachains_latest.clone(),
PenpalASender::get(),
amount * 2,
);
println!("🤡 5");

let wnds_in_reserve_on_ahr_before = AssetHubRococo::execute_with(|| {
type Assets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
<Assets as Inspect<_>>::balance(wnd_at_rococo_parachains, &sov_ahw_on_ahr)
});
let sender_wnds_before = PenpalA::execute_with(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
<ForeignAssets as Inspect<_>>::balance(
wnd_at_rococo_parachains_latest.clone().into(),
&PenpalASender::get(),
)
});
println!("🤡 6");

let receiver_wnds_before =
<AssetHubWestend as Chain>::account_data_of(AssetHubWestendReceiver::get()).free;
send_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
wnd_at_rococo_parachains_latest.clone(),
amount,
send_bridged_asset_from_penpal_rococo_through_local_asset_hub_to_westend_asset_hub(
(wnd_at_rococo_parachains_latest.clone(), amount).into(),
(roc_at_rococo_parachains, amount).into(),
);

AssetHubWestend::execute_with(|| {
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
println!("🤡 AHW events: {:?}", <AssetHubWestend as Chain>::events());
assert_expected_events!(
AssetHubWestend,
vec![
// issue ROCs on AHW
// RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => {
// asset_id: *asset_id == roc_at_rococo_parachains,
// owner: *owner == AssetHubWestendReceiver::get(),
// },
RuntimeEvent::Balances(pallet_balances::Event::Issued { .. }) => {},
// message processed successfully
RuntimeEvent::MessageQueue(
pallet_message_queue::Event::Processed { success: true, .. }
Expand All @@ -486,16 +573,10 @@ fn send_wnds_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_westend()
});
let receiver_wnds_after =
<AssetHubWestend as Chain>::account_data_of(AssetHubWestendReceiver::get()).free;
let wnds_in_reserve_on_ahr_after = AssetHubRococo::execute_with(|| {
type Assets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
<Assets as Inspect<_>>::balance(wnd_at_rococo_parachains, &sov_ahw_on_ahr)
});

// Sender's balance is reduced
assert!(sender_wnds_after < sender_wnds_before);
// Receiver's balance is increased
// Sender's balance is reduced by sent "amount"
assert_eq!(sender_wnds_after, sender_wnds_before - amount);
// Receiver's balance is increased by no more than "amount"
assert!(receiver_wnds_after > receiver_wnds_before);
// Reserve balance is increased by sent amount (less fess)
assert!(wnds_in_reserve_on_ahr_after > wnds_in_reserve_on_ahr_before);
assert!(wnds_in_reserve_on_ahr_after <= wnds_in_reserve_on_ahr_before + amount);
assert!(receiver_wnds_after <= receiver_wnds_before + amount);
}

0 comments on commit d6036dd

Please sign in to comment.