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

[stable2409] Backport #5660 #5837

Merged
merged 1 commit into from
Sep 25, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ mod imports {
pub use rococo_system_emulated_network::{
asset_hub_rococo_emulated_chain::{
asset_hub_rococo_runtime::{
self,
xcm_config::{
self as ahr_xcm_config, TokenLocation as RelayLocation,
XcmConfig as AssetHubRococoXcmConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,16 @@ fn transfer_foreign_assets_from_para_to_para_through_asset_hub() {
let sov_of_receiver_on_ah = AssetHubRococo::sovereign_account_id_of(receiver_as_seen_by_ah);
let wnd_to_send = ASSET_HUB_ROCOCO_ED * 10_000_000;

// Configure destination chain to trust AH as reserve of WND
// Configure source and destination chains to trust AH as reserve of WND
PenpalA::execute_with(|| {
assert_ok!(<PenpalA as Chain>::System::set_storage(
<PenpalA as Chain>::RuntimeOrigin::root(),
vec![(
PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
Location::new(2, [GlobalConsensus(Westend)]).encode(),
)],
));
});
PenpalB::execute_with(|| {
assert_ok!(<PenpalB as Chain>::System::set_storage(
<PenpalB as Chain>::RuntimeOrigin::root(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1548,3 +1548,58 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() {
// Receiver's balance is increased
assert!(receiver_assets_after > receiver_assets_before);
}

/// Reserve Withdraw Native Asset from AssetHub to Parachain fails.
#[test]
fn reserve_withdraw_from_untrusted_reserve_fails() {
// Init values for Parachain Origin
let destination = AssetHubRococo::sibling_location_of(PenpalA::para_id());
let signed_origin =
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get().into());
let roc_to_send: Balance = ROCOCO_ED * 10000;
let roc_location = RelayLocation::get();

// Assets to send
let assets: Vec<Asset> = vec![(roc_location.clone(), roc_to_send).into()];
let fee_id: AssetId = roc_location.into();

// this should fail
AssetHubRococo::execute_with(|| {
let result = <AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin.clone(),
bx!(destination.clone().into()),
bx!(assets.clone().into()),
bx!(TransferType::DestinationReserve),
bx!(fee_id.into()),
bx!(TransferType::DestinationReserve),
bx!(VersionedXcm::from(Xcm::<()>::new())),
Unlimited,
);
assert_err!(
result,
DispatchError::Module(sp_runtime::ModuleError {
index: 31,
error: [22, 0, 0, 0],
message: Some("InvalidAssetUnsupportedReserve")
})
);
});

// this should also fail
AssetHubRococo::execute_with(|| {
let xcm: Xcm<asset_hub_rococo_runtime::RuntimeCall> = Xcm(vec![
WithdrawAsset(assets.into()),
InitiateReserveWithdraw {
assets: Wild(All),
reserve: destination,
xcm: Xcm::<()>::new(),
},
]);
let result = <AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::execute(
signed_origin,
bx!(xcm::VersionedXcm::V4(xcm)),
Weight::MAX,
);
assert!(result.is_err());
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,54 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
system_para_to_para_transfer_assets,
);
}

/// Teleport Native Asset from AssetHub to Parachain fails.
#[test]
fn teleport_to_untrusted_chain_fails() {
// Init values for Parachain Origin
let destination = AssetHubRococo::sibling_location_of(PenpalA::para_id());
let signed_origin =
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get().into());
let roc_to_send: Balance = ROCOCO_ED * 10000;
let roc_location = RelayLocation::get();

// Assets to send
let assets: Vec<Asset> = vec![(roc_location.clone(), roc_to_send).into()];
let fee_id: AssetId = roc_location.into();

// this should fail
AssetHubRococo::execute_with(|| {
let result = <AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin.clone(),
bx!(destination.clone().into()),
bx!(assets.clone().into()),
bx!(TransferType::Teleport),
bx!(fee_id.into()),
bx!(TransferType::Teleport),
bx!(VersionedXcm::from(Xcm::<()>::new())),
Unlimited,
);
assert_err!(
result,
DispatchError::Module(sp_runtime::ModuleError {
index: 31,
error: [2, 0, 0, 0],
message: Some("Filtered")
})
);
});

// this should also fail
AssetHubRococo::execute_with(|| {
let xcm: Xcm<asset_hub_rococo_runtime::RuntimeCall> = Xcm(vec![
WithdrawAsset(assets.into()),
InitiateTeleport { assets: Wild(All), dest: destination, xcm: Xcm::<()>::new() },
]);
let result = <AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::execute(
signed_origin,
bx!(xcm::VersionedXcm::V4(xcm)),
Weight::MAX,
);
assert!(result.is_err());
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ mod imports {
pub use westend_system_emulated_network::{
asset_hub_westend_emulated_chain::{
asset_hub_westend_runtime::{
self,
xcm_config::{
self as ahw_xcm_config, WestendLocation as RelayLocation,
XcmConfig as AssetHubWestendXcmConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,16 @@ fn transfer_foreign_assets_from_para_to_para_through_asset_hub() {
let sov_of_receiver_on_ah = AssetHubWestend::sovereign_account_id_of(receiver_as_seen_by_ah);
let roc_to_send = ASSET_HUB_WESTEND_ED * 10_000_000;

// Configure destination chain to trust AH as reserve of ROC
// Configure source and destination chains to trust AH as reserve of ROC
PenpalA::execute_with(|| {
assert_ok!(<PenpalA as Chain>::System::set_storage(
<PenpalA as Chain>::RuntimeOrigin::root(),
vec![(
PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
Location::new(2, [GlobalConsensus(Rococo)]).encode(),
)],
));
});
PenpalB::execute_with(|| {
assert_ok!(<PenpalB as Chain>::System::set_storage(
<PenpalB as Chain>::RuntimeOrigin::root(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1552,3 +1552,58 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() {
// Receiver's balance is increased
assert!(receiver_assets_after > receiver_assets_before);
}

/// Reserve Withdraw Native Asset from AssetHub to Parachain fails.
#[test]
fn reserve_withdraw_from_untrusted_reserve_fails() {
// Init values for Parachain Origin
let destination = AssetHubWestend::sibling_location_of(PenpalA::para_id());
let signed_origin =
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get().into());
let roc_to_send: Balance = WESTEND_ED * 10000;
let roc_location = RelayLocation::get();

// Assets to send
let assets: Vec<Asset> = vec![(roc_location.clone(), roc_to_send).into()];
let fee_id: AssetId = roc_location.into();

// this should fail
AssetHubWestend::execute_with(|| {
let result = <AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin.clone(),
bx!(destination.clone().into()),
bx!(assets.clone().into()),
bx!(TransferType::DestinationReserve),
bx!(fee_id.into()),
bx!(TransferType::DestinationReserve),
bx!(VersionedXcm::from(Xcm::<()>::new())),
Unlimited,
);
assert_err!(
result,
DispatchError::Module(sp_runtime::ModuleError {
index: 31,
error: [22, 0, 0, 0],
message: Some("InvalidAssetUnsupportedReserve")
})
);
});

// this should also fail
AssetHubWestend::execute_with(|| {
let xcm: Xcm<asset_hub_westend_runtime::RuntimeCall> = Xcm(vec![
WithdrawAsset(assets.into()),
InitiateReserveWithdraw {
assets: Wild(All),
reserve: destination,
xcm: Xcm::<()>::new(),
},
]);
let result = <AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::execute(
signed_origin,
bx!(xcm::VersionedXcm::V4(xcm)),
Weight::MAX,
);
assert!(result.is_err());
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,54 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
system_para_to_para_transfer_assets,
);
}

/// Teleport Native Asset from AssetHub to Parachain fails.
#[test]
fn teleport_to_untrusted_chain_fails() {
// Init values for Parachain Origin
let destination = AssetHubWestend::sibling_location_of(PenpalA::para_id());
let signed_origin =
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get().into());
let roc_to_send: Balance = WESTEND_ED * 10000;
let roc_location = RelayLocation::get();

// Assets to send
let assets: Vec<Asset> = vec![(roc_location.clone(), roc_to_send).into()];
let fee_id: AssetId = roc_location.into();

// this should fail
AssetHubWestend::execute_with(|| {
let result = <AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::transfer_assets_using_type_and_then(
signed_origin.clone(),
bx!(destination.clone().into()),
bx!(assets.clone().into()),
bx!(TransferType::Teleport),
bx!(fee_id.into()),
bx!(TransferType::Teleport),
bx!(VersionedXcm::from(Xcm::<()>::new())),
Unlimited,
);
assert_err!(
result,
DispatchError::Module(sp_runtime::ModuleError {
index: 31,
error: [2, 0, 0, 0],
message: Some("Filtered")
})
);
});

// this should also fail
AssetHubWestend::execute_with(|| {
let xcm: Xcm<asset_hub_westend_runtime::RuntimeCall> = Xcm(vec![
WithdrawAsset(assets.into()),
InitiateTeleport { assets: Wild(All), dest: destination, xcm: Xcm::<()>::new() },
]);
let result = <AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::execute(
signed_origin,
bx!(xcm::VersionedXcm::V4(xcm)),
Weight::MAX,
);
assert!(result.is_err());
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#[cfg(test)]
mod imports {
// Substrate
pub use codec::Encode;
pub use frame_support::{assert_err, assert_ok, pallet_prelude::DispatchResult};
pub use sp_runtime::DispatchError;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,16 @@ fn send_back_wnds_from_penpal_rococo_through_asset_hub_rococo_to_asset_hub_weste
ASSET_MIN_BALANCE,
vec![(sender.clone(), amount * 2)],
);
// Configure source Penpal chain to trust local AH as reserve of bridged WND
PenpalA::execute_with(|| {
assert_ok!(<PenpalA as Chain>::System::set_storage(
<PenpalA as Chain>::RuntimeOrigin::root(),
vec![(
PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
wnd_at_rococo_parachains.encode(),
)],
));
});

// 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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#[cfg(test)]
mod imports {
// Substrate
pub use codec::Encode;
pub use frame_support::{assert_err, assert_ok, pallet_prelude::DispatchResult};
pub use sp_runtime::DispatchError;

Expand Down Expand Up @@ -52,7 +53,10 @@ mod imports {
BridgeHubWestendParaPallet as BridgeHubWestendPallet, BridgeHubWestendXcmConfig,
},
penpal_emulated_chain::{
penpal_runtime::xcm_config::UniversalLocation as PenpalUniversalLocation,
penpal_runtime::xcm_config::{
CustomizableAssetFromSystemAssetHub as PenpalCustomizableAssetFromSystemAssetHub,
UniversalLocation as PenpalUniversalLocation,
},
PenpalAssetOwner, PenpalBParaPallet as PenpalBPallet,
},
westend_emulated_chain::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,16 @@ fn send_back_rocs_from_penpal_westend_through_asset_hub_westend_to_asset_hub_roc
ASSET_MIN_BALANCE,
vec![(sender.clone(), amount * 2)],
);
// Configure source Penpal chain to trust local AH as reserve of bridged ROC
PenpalB::execute_with(|| {
assert_ok!(<PenpalB as Chain>::System::set_storage(
<PenpalB as Chain>::RuntimeOrigin::root(),
vec![(
PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
roc_at_westend_parachains.encode(),
)],
));
});

// fund the AHW's SA on AHR with the ROC tokens held in reserve
let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
Expand Down
20 changes: 20 additions & 0 deletions polkadot/xcm/pallet-xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1939,6 +1939,10 @@ impl<T: Config> Pallet<T> {
) -> Result<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>), Error<T>> {
let value = (origin, vec![fees.clone()]);
ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
ensure!(
<T::XcmExecutor as XcmAssetTransfers>::IsReserve::contains(&fees, &dest),
Error::<T>::InvalidAssetUnsupportedReserve
);

let context = T::UniversalLocation::get();
let reanchored_fees = fees
Expand Down Expand Up @@ -1973,6 +1977,12 @@ impl<T: Config> Pallet<T> {
let value = (origin, assets);
ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
let (_, assets) = value;
for asset in assets.iter() {
ensure!(
<T::XcmExecutor as XcmAssetTransfers>::IsReserve::contains(&asset, &dest),
Error::<T>::InvalidAssetUnsupportedReserve
);
}

// max assets is `assets` (+ potentially separately handled fee)
let max_assets =
Expand Down Expand Up @@ -2079,6 +2089,10 @@ impl<T: Config> Pallet<T> {
) -> Result<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>), Error<T>> {
let value = (origin, vec![fees.clone()]);
ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
ensure!(
<T::XcmExecutor as XcmAssetTransfers>::IsTeleporter::contains(&fees, &dest),
Error::<T>::Filtered
);

let context = T::UniversalLocation::get();
let reanchored_fees = fees
Expand Down Expand Up @@ -2134,6 +2148,12 @@ impl<T: Config> Pallet<T> {
let value = (origin, assets);
ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
let (_, assets) = value;
for asset in assets.iter() {
ensure!(
<T::XcmExecutor as XcmAssetTransfers>::IsTeleporter::contains(&asset, &dest),
Error::<T>::Filtered
);
}

// max assets is `assets` (+ potentially separately handled fee)
let max_assets =
Expand Down
Loading
Loading