Skip to content

Commit

Permalink
fix AH transact proxy test
Browse files Browse the repository at this point in the history
  • Loading branch information
acatangiu committed Oct 9, 2024
1 parent 43bab9f commit 8ea5622
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 8 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 @@ -32,6 +32,7 @@ pallet-asset-tx-payment = { workspace = true }
# Polkadot
polkadot-runtime-common = { workspace = true, default-features = true }
xcm = { workspace = true }
xcm-builder = { workspace = true }
xcm-executor = { workspace = true }
pallet-xcm = { workspace = true }
xcm-runtime-apis = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@

use crate::imports::*;
use frame_support::traits::tokens::fungibles::Mutate;
use xcm::DoubleEncoded;
use xcm_builder::{DescribeAllTerminal, DescribeFamily, HashedDescription};
use xcm_executor::traits::ConvertLocation;

/// PenpalA transacts on PenpalB, paying fees using USDT. XCM has to go through Asset Hub as the
/// reserve location of USDT. The original origin `PenpalA/PenpalASender` is proxied by Asset Hub.
fn transfer_and_transact_in_same_xcm(destination: Location, usdt: Asset, beneficiary: Location) {
fn transfer_and_transact_in_same_xcm(
destination: Location,
usdt: Asset,
beneficiary: Location,
call: DoubleEncoded<()>,
) {
let signed_origin = <PenpalA as Chain>::RuntimeOrigin::signed(PenpalASender::get().into());
let context = PenpalUniversalLocation::get();
let asset_hub_location = PenpalA::sibling_location_of(AssetHubWestend::para_id());
Expand All @@ -34,8 +42,11 @@ fn transfer_and_transact_in_same_xcm(destination: Location, usdt: Asset, benefic
let fees_for_ah: Asset = (usdt.id.clone(), ah_fees_amount).into();
let usdt_to_ah_then_onward: Asset = (usdt.id.clone(), usdt_to_ah_then_onward_amount).into();

let require_weight_at_most = Weight::from_parts(1000000000, 200000);
// xcm to be executed at dest
let xcm_on_dest = Xcm(vec![
Transact { require_weight_at_most, origin_kind: OriginKind::Xcm, call },
ExpectTransactStatus(MaybeErrorCode::Success),
// since this is the last hop, we don't need to further use any assets previously
// reserved for fees (there are no further hops to cover transport fees for); we
// RefundSurplus to get back any unspent fees
Expand All @@ -46,7 +57,7 @@ fn transfer_and_transact_in_same_xcm(destination: Location, usdt: Asset, benefic
let xcm_on_ah = Xcm(vec![InitiateTransfer {
destination,
remote_fees: Some(AssetTransferFilter::ReserveDeposit(Wild(All))),
preserve_origin: false,
preserve_origin: true,
assets: vec![],
remote_xcm: xcm_on_dest,
}]);
Expand All @@ -56,7 +67,7 @@ fn transfer_and_transact_in_same_xcm(destination: Location, usdt: Asset, benefic
InitiateTransfer {
destination: asset_hub_location,
remote_fees: Some(AssetTransferFilter::ReserveWithdraw(fees_for_ah.into())),
preserve_origin: false,
preserve_origin: true,
assets: vec![AssetTransferFilter::ReserveWithdraw(usdt_to_ah_then_onward.into())],
remote_xcm: xcm_on_ah,
},
Expand Down Expand Up @@ -268,11 +279,27 @@ fn transact_from_para_to_para_through_asset_hub() {
<ForeignAssets as Inspect<_>>::balance(usdt_from_asset_hub.clone(), &receiver)
});

// Now register a new asset on PenpalB from PenpalA/sender account while paying fees using USDT
// (going through Asset Hub)

let usdt_to_send: Asset = (usdt_from_asset_hub.clone(), fee_amount_to_send).into();
let assets: Assets = usdt_to_send.clone().into();
let asset_location_on_penpal_a =
Location::new(0, [PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())]);
let penpal_a_as_seen_by_penpal_b = PenpalB::sibling_location_of(PenpalA::para_id());
let sender_as_seen_by_penpal_b =
penpal_a_as_seen_by_penpal_b.clone().appended_with(sender.clone()).unwrap();
let foreign_asset_at_penpal_b =
penpal_a_as_seen_by_penpal_b.appended_with(asset_location_on_penpal_a).unwrap();
// Encoded `create_asset` call to be executed in PenpalB
let call = PenpalB::create_foreign_asset_call(
foreign_asset_at_penpal_b.clone(),
ASSET_MIN_BALANCE,
receiver.clone(),
);
PenpalA::execute_with(|| {
// initiate transaction
transfer_and_transact_in_same_xcm(destination, usdt_to_send, receiver.clone().into());
transfer_and_transact_in_same_xcm(destination, usdt_to_send, receiver.clone().into(), call);

// verify expected events;
PenpalA::assert_xcm_pallet_attempted_complete(None);
Expand All @@ -287,7 +314,12 @@ fn transact_from_para_to_para_through_asset_hub() {
asset_hub_hop_assertions(&assets, sov_penpal_a_on_ah, sov_penpal_b_on_ah);
});
PenpalB::execute_with(|| {
PenpalB::assert_xcmp_queue_success(None);
let expected_creator =
HashedDescription::<AccountId, DescribeFamily<DescribeAllTerminal>>::convert_location(
&sender_as_seen_by_penpal_b,
)
.unwrap();
penpal_b_assertions(foreign_asset_at_penpal_b, expected_creator, receiver.clone());
});

// Query final balances
Expand Down Expand Up @@ -333,3 +365,24 @@ fn asset_hub_hop_assertions(assets: &Assets, sender_sa: AccountId, receiver_sa:
);
}
}

fn penpal_b_assertions(
expected_asset: Location,
expected_creator: AccountId,
expected_owner: AccountId,
) {
type RuntimeEvent = <PenpalB as Chain>::RuntimeEvent;
PenpalB::assert_xcmp_queue_success(None);
assert_expected_events!(
PenpalB,
vec![
RuntimeEvent::ForeignAssets(
pallet_assets::Event::Created { asset_id, creator, owner }
) => {
asset_id: *asset_id == expected_asset,
creator: *creator == expected_creator,
owner: *owner == expected_owner,
},
]
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,7 @@ impl<Call> XcmWeightInfo<Call> for AssetHubWestendXcmWeight<Call> {
XcmGeneric::<Runtime>::clear_topic()
}
fn alias_origin(_: &Location) -> Weight {
// XCM Executor does not currently support alias origin operations
Weight::MAX
XcmGeneric::<Runtime>::alias_origin()
}
fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
XcmGeneric::<Runtime>::unpaid_execution()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 698_000 picoseconds.
Weight::from_parts(730_000, 0)
}
pub fn alias_origin() -> Weight {
// TODO: use real benchmark
Weight::from_parts(800_000, 0)
}
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
Expand Down
11 changes: 10 additions & 1 deletion cumulus/parachains/runtimes/testing/penpal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern crate alloc;

use alloc::{vec, vec::Vec};
use assets_common::{
foreign_creators::ForeignCreators,
local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
AssetIdForTrustBackedAssetsConvert,
};
Expand Down Expand Up @@ -94,6 +95,7 @@ use xcm::{
latest::prelude::{AssetId as AssetLocationId, BodyId},
VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
};
use xcm_builder::{DescribeAllTerminal, DescribeFamily, HashedDescription};
use xcm_runtime_apis::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::Error as XcmPaymentApiError,
Expand Down Expand Up @@ -492,7 +494,14 @@ impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
type AssetId = ForeignAssetsAssetId;
type AssetIdParameter = ForeignAssetsAssetId;
type Currency = Balances;
type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
// This is to allow any other remote location to create foreign assets. Used in tests, not
// recommended on real chains.
type CreateOrigin = ForeignCreators<
Everything,
HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
AccountId,
xcm::latest::Location,
>;
type ForceOrigin = EnsureRoot<AccountId>;
type AssetDeposit = ForeignAssetsAssetDeposit;
type MetadataDepositBase = ForeignAssetsMetadataDepositBase;
Expand Down

0 comments on commit 8ea5622

Please sign in to comment.