XCM WeightTrader: Swap Fee Asset for Native Asset (#1845)

Implements an XCM executor `WeightTrader`, facilitating fee payments in
any asset that can be exchanged for a native asset.

A few constraints need to be observed:
- `buy_weight` and `refund` operations must be atomic, as another weight
trader implementation might be attempted in case of failure.
- swap credit must be utilized since there isn’t an account to which an
asset of some class can be deposited with a guarantee to meet the
existential deposit requirement. Also, operating with credits enhances
the efficiency of the weight trader -
https://github.com/paritytech/polkadot-sdk/pull/1677

related PRs:
- (depends) https://github.com/paritytech/polkadot-sdk/pull/2031
- (depends) https://github.com/paritytech/polkadot-sdk/pull/1677
- (caused) https://github.com/paritytech/polkadot-sdk/pull/1847
- (caused) https://github.com/paritytech/polkadot-sdk/pull/1876

// DONE: impl `OnUnbalanced` for a `fungible/s` credit
// DONE: make the trader free from a concept of a native currency and
drop few fallible conversions. related issue -
https://github.com/paritytech/polkadot-sdk/issues/1842
// DONE: tests

---------

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>
This commit is contained in:
Muharem
2024-01-16 15:34:48 +08:00
committed by GitHub
parent 4c4963a192
commit 2cb39f8dc9
25 changed files with 1769 additions and 861 deletions
@@ -16,6 +16,7 @@ codec = { package = "parity-scale-codec", version = "3.4.0", default-features =
# Substrate
frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false }
pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false }
pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false }
pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false }
pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" }
sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false }
@@ -55,7 +55,8 @@ pub use rococo_westend_system_emulated_network::{
},
westend_emulated_chain::WestendRelayPallet as WestendPallet,
AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver,
AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver,
AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend,
AssetHubWestendParaReceiver as AssetHubWestendReceiver,
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo,
BridgeHubWestendPara as BridgeHubWestend, BridgeHubWestendParaSender as BridgeHubWestendSender,
WestendRelay as Westend,
@@ -48,6 +48,49 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() {
AssetHubRococo::para_id(),
);
AssetHubRococo::execute_with(|| {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
// setup a pool to pay xcm fees with `wnd_at_asset_hub_rococo` tokens
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::ForeignAssets::mint(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
wnd_at_asset_hub_rococo.into(),
AssetHubRococoSender::get().into(),
3_000_000_000_000,
));
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::create_pool(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
Box::new(Parent.into()),
Box::new(wnd_at_asset_hub_rococo),
));
assert_expected_events!(
AssetHubRococo,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {},
]
);
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::add_liquidity(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
Box::new(Parent.into()),
Box::new(wnd_at_asset_hub_rococo),
1_000_000_000_000,
2_000_000_000_000,
1,
1,
AssetHubRococoSender::get().into()
));
assert_expected_events!(
AssetHubRococo,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {},
]
);
});
let wnds_in_reserve_on_ahw_before =
<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw.clone()).free;
let sender_wnds_before =