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

Fix delivery fees issue in Kusama #3075

Closed
Closed
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,032 changes: 455 additions & 577 deletions Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ xcm-executor = { package = "staging-xcm-executor", path = "../../../../../../pol
rococo-runtime = { path = "../../../../../../polkadot/runtime/rococo", default-features = false, version = "4.0.0" }

# Cumulus
asset-test-utils = { path = "../../../../runtimes/assets/test-utils", default-features = false, version = "4.0.0" }
parachains-common = { version = "4.0.0", path = "../../../../common" }
asset-hub-rococo-runtime = { version = "0.9.420", path = "../../../../runtimes/assets/asset-hub-rococo" }
asset-test-utils = { path = "../../../../runtimes/assets/test-utils", default-features = false }
parachains-common = { path = "../../../../common" }
asset-hub-rococo-runtime = { path = "../../../../runtimes/assets/asset-hub-rococo" }
penpal-runtime = { path = "../../../../runtimes/testing/penpal" }
cumulus-pallet-dmp-queue = { path = "../../../../../pallets/dmp-queue", default-features = false}
cumulus-pallet-parachain-system = { path = "../../../../../pallets/parachain-system", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../../../../pallets/xcmp-queue", default-features = false}

# Local
xcm-emulator = { path = "../../../../../xcm/xcm-emulator", default-features = false, version = "0.2.0" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pub const ASSETS_PALLET_ID: u8 = 50;
pub type RelayToSystemParaTest = Test<Rococo, AssetHubRococo>;
pub type SystemParaToRelayTest = Test<AssetHubRococo, Rococo>;
pub type SystemParaToParaTest = Test<AssetHubRococo, PenpalRococoA>;
pub type ParaToSystemParaTest = Test<PenpalRococoA, AssetHubRococo>;
pub type ParaToParaTest = Test<PenpalRococoA, PenpalRococoB, Rococo>;

/// Returns a `TestArgs` instance to de used for the Relay Chain accross integraton tests
pub fn relay_test_args(amount: Balance) -> TestArgs {
Expand Down Expand Up @@ -88,5 +90,25 @@ pub fn system_para_test_args(
}
}

/// Returns a `TestArgs` instance to be used by parachains across integration tests
pub fn para_test_args(
dest: MultiLocation,
beneficiary_id: AccountId32,
amount: Balance,
assets: MultiAssets,
asset_id: Option<u32>,
fee_asset_item: u32,
) -> TestArgs {
TestArgs {
dest,
beneficiary: AccountId32Junction { network: None, id: beneficiary_id.into() }.into(),
amount,
assets,
asset_id,
fee_asset_item,
weight_limit: WeightLimit::Unlimited,
}
}

#[cfg(test)]
mod tests;
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use crate::*;
use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig;
use penpal_runtime::xcm_config::XcmConfig as PenpalRococoXcmConfig;
use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig;

fn relay_origin_assertions(t: RelayToSystemParaTest) {
Expand Down Expand Up @@ -99,6 +100,74 @@ fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
);
}

fn para_to_para_sender_assertions(t: ParaToParaTest) {
type RuntimeEvent = <PenpalRococoA as Chain>::RuntimeEvent;
PenpalRococoA::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
864_610_000,
8_799,
)));
assert_expected_events!(
PenpalRococoA,
vec![
// Amount to reserve transfer is transferred to Parachain's Sovereign account
RuntimeEvent::Balances(
pallet_balances::Event::Withdraw { who, amount }
) => {
who: *who == t.sender.account_id,
amount: *amount == t.args.amount,
},
// XCM sent to relay reserve
RuntimeEvent::ParachainSystem(
cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
) => {},
]
);
}

fn para_to_para_relay_hop_assertions(t: ParaToParaTest) {
type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
let sov_penpal_a_on_rococo =
Rococo::sovereign_account_id_of(Rococo::child_location_of(PenpalRococoA::para_id()));
let sov_penpal_b_on_rococo =
Rococo::sovereign_account_id_of(Rococo::child_location_of(PenpalRococoB::para_id()));
println!("Rococo events: {:?}", <Rococo as Chain>::events());
assert_expected_events!(
Rococo,
vec![
// Withdrawn from sender parachain SA
RuntimeEvent::Balances(
pallet_balances::Event::Withdraw { who, amount }
) => {
who: *who == sov_penpal_a_on_rococo,
amount: *amount == t.args.amount,
},
// Deposited to receiver parachain SA
RuntimeEvent::Balances(
pallet_balances::Event::Deposit { who, .. }
) => {
who: *who == sov_penpal_b_on_rococo,
},
// RuntimeEvent::MessageQueue(
// pallet_message_queue::Event::Processed { success: true, .. }
// ) => {},
]
);
}

fn para_to_para_receiver_assertions(_: ParaToParaTest) {
type RuntimeEvent = <PenpalRococoB as Chain>::RuntimeEvent;
println!("PenpalRococoB events: {:?}", <Rococo as Chain>::events());
assert_expected_events!(
PenpalRococoB,
vec![
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
// RuntimeEvent::MessageQueue(
// pallet_message_queue::Event::Processed { success: true, .. }
// ) => {},
]
);
}

fn relay_limited_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Rococo as RococoPallet>::XcmPallet::limited_reserve_transfer_assets(
t.signed_origin,
Expand Down Expand Up @@ -162,6 +231,17 @@ fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> Dispa
)
}

fn para_to_para_limited_reserve_transfer_assets(t: ParaToParaTest) -> DispatchResult {
<PenpalRococoA as PenpalRococoAPallet>::PolkadotXcm::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}

/// Limited Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't
/// work
#[test]
Expand Down Expand Up @@ -369,6 +449,55 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
// transfers
}

/// Reserve Transfers of native asset from Parachain to Parachain (through Relay reserve) should
/// work
#[test]
fn reserve_transfer_native_asset_from_para_to_para() {
use integration_tests_common::PenpalRococoBReceiver;
// Init values for Penpal Parachain
let destination = PenpalRococoA::sibling_location_of(PenpalRococoB::para_id());
let beneficiary_id = PenpalRococoBReceiver::get();
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 10000;
let assets = (Parent, amount_to_send).into();

let test_args = TestContext {
sender: PenpalRococoASender::get(),
receiver: PenpalRococoBReceiver::get(),
args: para_test_args(destination, beneficiary_id, amount_to_send, assets, None, 0),
};

let mut test = ParaToParaTest::new(test_args);

let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;

let sender_as_seen_by_relay = Rococo::child_location_of(PenpalRococoA::para_id());
let sov_of_sender_on_relay = Rococo::sovereign_account_id_of(sender_as_seen_by_relay);

// fund the PenpalA's SA on Rococo with the native tokens held in reserve
Rococo::fund_accounts(vec![(sov_of_sender_on_relay.into(), amount_to_send * 2)]);

test.set_assertion::<PenpalRococoA>(para_to_para_sender_assertions);
test.set_assertion::<Rococo>(para_to_para_relay_hop_assertions);
test.set_assertion::<PenpalRococoB>(para_to_para_receiver_assertions);
test.set_dispatchable::<PenpalRococoA>(para_to_para_limited_reserve_transfer_assets);
test.assert();

let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;

let delivery_fees = PenpalRococoA::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
<PenpalRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});

// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}

/// Limited Reserve Transfers of a local asset from System Parachain to Parachain should work
#[test]
fn limited_reserve_transfer_asset_from_system_para_to_para() {
Expand Down
60 changes: 28 additions & 32 deletions cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex,
ConvertedConcreteId, CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry,
EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, IsConcrete, LocalMint, NativeAsset,
ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
ConvertedConcreteId, CurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter,
IsConcrete, LocalMint, NativeAsset, ParentIsPreset, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId,
UsingComponents, WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::{traits::JustTry, XcmExecutor};

Expand Down Expand Up @@ -150,34 +150,29 @@ match_types! {
};
}

pub type Barrier = TrailingSetTopicAsId<
DenyThenTry<
DenyReserveTransferToRelayChain,
pub type Barrier = TrailingSetTopicAsId<(
TakeWeightCredit,
// Expected responses are OK.
AllowKnownQueryResponses<PolkadotXcm>,
// Allow XCMs with some computed origins to pass through.
WithComputedOrigin<
(
TakeWeightCredit,
// Expected responses are OK.
AllowKnownQueryResponses<PolkadotXcm>,
// Allow XCMs with some computed origins to pass through.
WithComputedOrigin<
(
// If the message is one that immediately attempts to pay for execution, then
// allow it.
AllowTopLevelPaidExecutionFrom<Everything>,
// System Assets parachain, parent and its exec plurality get free
// execution
AllowExplicitUnpaidExecutionFrom<(
CommonGoodAssetsParachain,
ParentOrParentsExecutivePlurality,
)>,
// Subscriptions for version tracking are OK.
AllowSubscriptionsFrom<Everything>,
),
UniversalLocation,
ConstU32<8>,
>,
// If the message is one that immediately attempts to pay for execution, then
// allow it.
AllowTopLevelPaidExecutionFrom<Everything>,
// System Assets parachain, parent and its exec plurality get free
// execution
AllowExplicitUnpaidExecutionFrom<(
CommonGoodAssetsParachain,
ParentOrParentsExecutivePlurality,
)>,
// Subscriptions for version tracking are OK.
AllowSubscriptionsFrom<Everything>,
),
UniversalLocation,
ConstU32<8>,
>,
>;
)>;

/// Type alias to conveniently refer to `frame_system`'s `Config::AccountId`.
pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
Expand Down Expand Up @@ -277,8 +272,9 @@ impl xcm_executor::Config for XcmConfig {
// How to withdraw and deposit an asset.
type AssetTransactor = AssetTransactors;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = MultiNativeAsset; // TODO: maybe needed to be replaced by Reserves
type IsTeleporter = NativeAsset;
type IsReserve = Reserves;
// no teleport trust established with other chains
type IsTeleporter = ();
type UniversalLocation = UniversalLocation;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
Expand Down
Loading
Loading