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

Add an adapter for configuring AssetExchanger #5130

Merged
merged 19 commits into from
Aug 2, 2024

Conversation

franciscoaguirre
Copy link
Contributor

@franciscoaguirre franciscoaguirre commented Jul 24, 2024

Added a new adapter to xcm-builder, the SingleAssetExchangeAdapter.
This adapter makes it easy to use pallet-asset-conversion for configuring the AssetExchanger XCM config item.

I also took the liberty of adding a new function to the AssetExchange trait, with the following signature:

fn quote_exchange_price(give: &Assets, want: &Assets, maximal: bool) -> Option<Assets>;

The signature is meant to be fairly symmetric to that of exchange_asset.
The way they interact can be seen in the doc comment for it in the AssetExchange trait.

This is a breaking change but is needed for #5131.
Another idea is to create a new trait for this but that would require setting it in the XCM config which is also breaking.

Old PR: #4375.

@franciscoaguirre franciscoaguirre requested review from a team as code owners July 24, 2024 17:43
@franciscoaguirre franciscoaguirre added the T6-XCM This PR/Issue is related to XCM. label Jul 24, 2024
Copy link
Contributor

@gui1117 gui1117 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the trait implementation is good to me

@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: cargo-clippy
Logs: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6854121

@paritytech-review-bot paritytech-review-bot bot requested a review from a team July 30, 2024 10:28
polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs Outdated Show resolved Hide resolved
polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs Outdated Show resolved Hide resolved
prdoc/pr_5130.prdoc Outdated Show resolved Hide resolved
Co-authored-by: Adrian Catangiu <[email protected]>
Comment on lines +57 to +58
/// - quote(give, want, maximal) = resulting_want -> exchange(give, resulting_want, maximal) ✅
/// - quote(give, want, minimal) = required_give -> exchange(required_give_amount, want,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this useful explanation.
would not this be simpler if we do something like:

quote_exchange(give: Assets, want: AssetIds) -> Option<Assets>;
quote_price(give: AssetIds, want: Assets) -> Option<Assets>;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it makes more sense to use AssetId instead of the assets and the amount whenever we don't need the amount.

However, there are two things I like about the API as-is.
One, by specifying the fungibility we get to also specify instances for NFTs.
Two, the addition of maximal even though it's weird it matches better with exchange_asset, so you know which one matches with which one.

@franciscoaguirre franciscoaguirre added this pull request to the merge queue Aug 2, 2024
Merged via the queue into master with commit 8ccb6b3 Aug 2, 2024
124 of 164 checks passed
@franciscoaguirre franciscoaguirre deleted the single-asset-exchange-adapter branch August 2, 2024 13:01
ordian added a commit that referenced this pull request Aug 6, 2024
* master: (51 commits)
  Remove unused feature gated code from the minimal template (#5237)
  make polkadot-parachain startup errors pretty (#5214)
  Coretime auto-renew (#4424)
  network/strategy: Backoff and ban overloaded peers to avoid submitting the same request multiple times (#5029)
  Fix frame crate usage doc (#5222)
  beefy: Tolerate pruned state on runtime API call (#5197)
  rpc: Enable ChainSpec for polkadot-parachain (#5205)
  Add an adapter for configuring AssetExchanger (#5130)
  Replace env_logger with sp_tracing (#5065)
  Adjust sync templates flow to use new release branch (#5182)
  litep2p/discovery: Publish authority records with external addresses only (#5176)
  Run UI tests in CI for some other crates (#5167)
  Remove `pallet::getter` usage from the pallet-balances (#4967)
  pallet-timestamp: `UnixTime::now` implementation logs error only if called at genesis (#5055)
  [CI] Cache try-runtime check (#5179)
  [Backport] version bumps and the prdocs reordering from stable2407 (#5178)
  [subsystem-benchmark] Update availability-distribution-regression-bench baseline after recent subsystem changes (#5180)
  Remove pallet::getter usage from proxy (#4963)
  Remove pallet::getter macro usage from pallet-election-provider-multi-phase (#4487)
  [email protected] (#5177)
  ...
github-merge-queue bot pushed a commit that referenced this pull request Sep 2, 2024
# Context

Fees can already be paid in other assets locally thanks to the Trader
implementations we have.
This doesn't work when sending messages because delivery fees go through
a different mechanism altogether.
The idea is to fix this leveraging the `AssetExchanger` config item
that's able to turn the asset the user wants to pay fees in into the
asset the router expects for delivery fees.

# Main addition

An adapter was needed to use `pallet-asset-conversion` for exchanging
assets in XCM.
This was created in
#5130.

The XCM executor was modified to use `AssetExchanger` (when available)
to swap assets to pay for delivery fees.

## Limitations

We can only pay for delivery fees in different assets in intermediate
hops. We can't pay in different assets locally. The first hop will
always need the native token of the chain (or whatever is specified in
the `XcmRouter`).
This is a byproduct of using the `BuyExecution` instruction to know
which asset should be used for delivery fee payment.
Since this instruction is not present when executing an XCM locally, we
are left with this limitation.
To illustrate this limitation, I'll show two scenarios. All chains
involved have pools.

### Scenario 1

Parachain A --> Parachain B

Here, parachain A can use any asset in a pool with its native asset to
pay for local execution fees.
However, as of now we can't use those for local delivery fees.
This means transfers from A to B need some amount of A's native token to
pay for delivery fees.

### Scenario 2

Parachain A --> Parachain C --> Parachain B

Here, Parachain C's remote delivery fees can be paid with any asset in a
pool with its native asset.
This allows a reserve asset transfer between A and B with C as the
reserve to only need A's native token at the starting hop.
After that, it could all be pool assets.

## Future work

The fact that delivery fees go through a totally different mechanism
results in a lot of bugs and pain points.
Unfortunately, this is not so easy to solve in a backwards compatible
manner.
Delivery fees will be integrated into the language in future XCM
versions, following
polkadot-fellows/xcm-format#53.

Old PR: #4375.
x3c41a added a commit that referenced this pull request Sep 4, 2024
# Context

Fees can already be paid in other assets locally thanks to the Trader
implementations we have.
This doesn't work when sending messages because delivery fees go through
a different mechanism altogether.
The idea is to fix this leveraging the `AssetExchanger` config item
that's able to turn the asset the user wants to pay fees in into the
asset the router expects for delivery fees.

# Main addition

An adapter was needed to use `pallet-asset-conversion` for exchanging
assets in XCM.
This was created in
#5130.

The XCM executor was modified to use `AssetExchanger` (when available)
to swap assets to pay for delivery fees.

## Limitations

We can only pay for delivery fees in different assets in intermediate
hops. We can't pay in different assets locally. The first hop will
always need the native token of the chain (or whatever is specified in
the `XcmRouter`).
This is a byproduct of using the `BuyExecution` instruction to know
which asset should be used for delivery fee payment.
Since this instruction is not present when executing an XCM locally, we
are left with this limitation.
To illustrate this limitation, I'll show two scenarios. All chains
involved have pools.

### Scenario 1

Parachain A --> Parachain B

Here, parachain A can use any asset in a pool with its native asset to
pay for local execution fees.
However, as of now we can't use those for local delivery fees.
This means transfers from A to B need some amount of A's native token to
pay for delivery fees.

### Scenario 2

Parachain A --> Parachain C --> Parachain B

Here, Parachain C's remote delivery fees can be paid with any asset in a
pool with its native asset.
This allows a reserve asset transfer between A and B with C as the
reserve to only need A's native token at the starting hop.
After that, it could all be pool assets.

## Future work

The fact that delivery fees go through a totally different mechanism
results in a lot of bugs and pain points.
Unfortunately, this is not so easy to solve in a backwards compatible
manner.
Delivery fees will be integrated into the language in future XCM
versions, following
polkadot-fellows/xcm-format#53.

Old PR: #4375.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T6-XCM This PR/Issue is related to XCM.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants