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

XCM Fee Payment Runtime API #3607

Merged
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c471add
feat(xcm): add `xcm-payment-api`
PraetorP Feb 20, 2024
137d129
doc: `XcmPaymentRuntimeApi`
PraetorP Feb 26, 2024
c4b070b
add prdoc
PraetorP Feb 26, 2024
6bc4e95
refactor: signatures for XcmPaymentRuntimeApi & mpl for roroco Runtime
PraetorP Feb 27, 2024
c649ad2
rename trait to `XcmPaymentApi`
PraetorP Feb 27, 2024
1b93e2a
fix comment
PraetorP Feb 27, 2024
16d9d22
doc: add `Error` description
PraetorP Feb 28, 2024
a8337b9
refactor
PraetorP Feb 28, 2024
7b17ece
format non context diffs
PraetorP Feb 29, 2024
f6201bf
feat: add `XcmPaymentApi` into `Wesend`
PraetorP Feb 29, 2024
55b1a03
fix non context diffs
PraetorP Feb 29, 2024
707f0b0
fix missed feature
PraetorP Feb 29, 2024
a27c70f
refactor
PraetorP Mar 5, 2024
f45f9dd
cargo fmt
PraetorP Mar 7, 2024
18e54e7
feat(xcm-fee-payment-api): add query_delivery_fees function
franciscoaguirre Mar 18, 2024
4caea72
Merge pull request #3 from paritytech/pr3607
PraetorP Mar 20, 2024
e348602
Update polkadot/xcm/xcm-builder/xcm-payment-runtime-api/README.md
PraetorP Mar 20, 2024
fc06767
refactor: add missed imports, fmt, add xcm api errors log
PraetorP Mar 20, 2024
60a88a6
number assigned to the `prdoc`
PraetorP Mar 20, 2024
fee8d7b
remove unused import
PraetorP Mar 20, 2024
cceafd4
Update polkadot/xcm/xcm-builder/xcm-payment-runtime-api/src/lib.rs
PraetorP Mar 20, 2024
618f17f
Update prdoc/pr_3607.prdoc
PraetorP Mar 20, 2024
4a83147
rename crate
PraetorP Mar 20, 2024
e7c752a
revert changes
PraetorP Mar 20, 2024
3ce306f
update doc
PraetorP Mar 20, 2024
ddae561
replace crate
PraetorP Mar 20, 2024
25252b8
fix: feature propagation
franciscoaguirre Mar 22, 2024
3cd6503
Merge pull request #5 from paritytech/pr3607
PraetorP Mar 25, 2024
32ea4f5
fix typos
PraetorP Mar 25, 2024
81b7e39
Update prdoc/pr_3607.prdoc
PraetorP Mar 25, 2024
d706cd0
Update prdoc/pr_3607.prdoc
PraetorP Mar 25, 2024
fc3ca43
fix: remove RuntimeCall from xcm-fee-payment-runtime-api
mrshiposha Mar 25, 2024
f9f3f67
fix: minor doc fix for api error
mrshiposha Mar 25, 2024
6287558
feat: impl IdentifyVersion for VersionedXcm
mrshiposha Mar 25, 2024
4fe5985
fix: remove unneeded package TOML setting
mrshiposha Mar 25, 2024
c04e4d8
refactor: move weight and delivery fee payment stuff to pallet-xcm
mrshiposha Mar 25, 2024
1cc0119
chore: cargo fmt
mrshiposha Mar 25, 2024
ea964fb
chore: taplo format
mrshiposha Mar 25, 2024
01942ea
chore: remove empty README
mrshiposha Mar 26, 2024
d5ed17b
chore: remove readme from Cargo.toml
mrshiposha Mar 26, 2024
faba8a1
Update polkadot/node/service/Cargo.toml
mrshiposha Mar 26, 2024
e02f957
Update polkadot/node/service/Cargo.toml
mrshiposha Mar 26, 2024
01857a4
fix: remove unneeded xcm-builder dep
mrshiposha Mar 26, 2024
806f29d
fix: Cargo.lock
mrshiposha Mar 26, 2024
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
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ members = [
"polkadot/xcm/pallet-xcm-benchmarks",
"polkadot/xcm/procedural",
"polkadot/xcm/xcm-builder",
"polkadot/xcm/xcm-builder/xcm-payment-runtime-api",
"polkadot/xcm/xcm-executor",
"polkadot/xcm/xcm-executor/integration-tests",
"polkadot/xcm/xcm-simulator",
Expand Down
9 changes: 5 additions & 4 deletions polkadot/node/service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ polkadot-node-core-pvf-checker = { path = "../core/pvf-checker", optional = true
polkadot-node-core-runtime-api = { path = "../core/runtime-api", optional = true }
polkadot-statement-distribution = { path = "../network/statement-distribution", optional = true }

xcm = { package = "staging-xcm", path = "../../xcm", default-features = false }
xcm-builder = { package = "staging-xcm-builder", path = "../../xcm/xcm-builder", default-features = false }
xcm-fee-payment-runtime-api = { package = "xcm-fee-payment-runtime-api", path = "../../xcm/xcm-builder/xcm-payment-runtime-api", default-features = false }

[dev-dependencies]
polkadot-test-client = { path = "../test/client" }
polkadot-node-subsystem-test-helpers = { path = "../subsystem-test-helpers" }
Expand Down Expand Up @@ -219,10 +223,7 @@ try-runtime = [
"sp-runtime/try-runtime",
"westend-runtime?/try-runtime",
]
franciscoaguirre marked this conversation as resolved.
Show resolved Hide resolved
fast-runtime = [
"rococo-runtime?/fast-runtime",
"westend-runtime?/fast-runtime",
]
fast-runtime = ["rococo-runtime?/fast-runtime", "westend-runtime?/fast-runtime"]

malus = ["full-node"]
runtime-metrics = [
Expand Down
22 changes: 21 additions & 1 deletion polkadot/node/service/src/fake_runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ use polkadot_primitives::{
ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash,
ValidatorId, ValidatorIndex, ValidatorSignature,
};
use rococo_runtime::RuntimeCall;

use sp_core::OpaqueMetadata;
use sp_runtime::{
traits::Block as BlockT,
Expand All @@ -39,7 +41,7 @@ use sp_runtime::{
use sp_version::RuntimeVersion;
use sp_weights::Weight;
use std::collections::BTreeMap;

use xcm::{VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm};
sp_api::decl_runtime_apis! {
/// This runtime API is only implemented for the test runtime!
pub trait GetLastTimestamp {
Expand Down Expand Up @@ -396,4 +398,22 @@ sp_api::impl_runtime_apis! {
unimplemented!()
}
}

impl xcm_fee_payment_runtime_api::XcmPaymentApi<Block, RuntimeCall> for Runtime {
fn query_acceptable_payment_assets(_: xcm::Version) -> Result<Vec<VersionedAssetId>, xcm_fee_payment_runtime_api::Error> {
unimplemented!()
}

fn query_weight_to_asset_fee(_: Weight, _: VersionedAssetId) -> Result<u128, xcm_fee_payment_runtime_api::Error> {
unimplemented!()
}

fn query_xcm_weight(_: VersionedXcm<RuntimeCall>) -> Result<Weight, xcm_fee_payment_runtime_api::Error> {
unimplemented!()
}

fn query_delivery_fees(_: VersionedLocation, _: VersionedXcm<()>) -> Result<VersionedAssets, xcm_fee_payment_runtime_api::Error> {
unimplemented!()
}
}
}
2 changes: 2 additions & 0 deletions polkadot/runtime/rococo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ polkadot-parachain-primitives = { path = "../../parachain", default-features = f
xcm = { package = "staging-xcm", path = "../../xcm", default-features = false }
xcm-executor = { package = "staging-xcm-executor", path = "../../xcm/xcm-executor", default-features = false }
xcm-builder = { package = "staging-xcm-builder", path = "../../xcm/xcm-builder", default-features = false }
xcm-fee-payment-runtime-api = { package = "xcm-fee-payment-runtime-api", path = "../../xcm/xcm-builder/xcm-payment-runtime-api", default-features = false }

[dev-dependencies]
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
Expand Down Expand Up @@ -209,6 +210,7 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"xcm-fee-payment-runtime-api/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand Down
71 changes: 62 additions & 9 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use frame_support::{
InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage,
ProcessMessageError, StorageMapShim, WithdrawReasons,
},
weights::{ConstantMultiplier, WeightMeter},
weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
PalletId,
};
use frame_system::{EnsureRoot, EnsureSigned};
Expand All @@ -98,7 +98,10 @@ use sp_staking::SessionIndex;
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use xcm::{latest::prelude::*, VersionedLocation};
use xcm::{
latest::prelude::*, IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation,
VersionedXcm,
};
use xcm_builder::PayOverXcm;

pub use frame_system::Call as SystemCall;
Expand All @@ -123,6 +126,8 @@ use governance::{
pallet_custom_origins, AuctionAdmin, Fellows, GeneralAdmin, LeaseAdmin, Treasurer,
TreasurySpender,
};
use xcm_executor::traits::WeightBounds;
use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError;

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -217,7 +222,7 @@ pub struct OriginPrivilegeCmp;
impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {
if left == right {
return Some(Ordering::Equal)
return Some(Ordering::Equal);
}

match (left, right) {
Expand Down Expand Up @@ -1508,11 +1513,11 @@ pub mod migrations {
let now = frame_system::Pallet::<Runtime>::block_number();
let lease = slots::Pallet::<Runtime>::lease(para);
if lease.is_empty() {
return None
return None;
}
// Lease not yet started, ignore:
if lease.iter().any(Option::is_none) {
return None
return None;
}
let (index, _) =
<slots::Pallet<Runtime> as Leaser<BlockNumber>>::lease_period_index(now)?;
Expand Down Expand Up @@ -1574,7 +1579,7 @@ pub mod migrations {
fn pre_upgrade() -> Result<sp_std::vec::Vec<u8>, sp_runtime::TryRuntimeError> {
if System::last_runtime_upgrade_spec_version() > UPGRADE_SESSION_KEYS_FROM_SPEC {
log::warn!(target: "runtime::session_keys", "Skipping session keys migration pre-upgrade check due to spec version (already applied?)");
return Ok(Vec::new())
return Ok(Vec::new());
}

log::info!(target: "runtime::session_keys", "Collecting pre-upgrade session keys state");
Expand Down Expand Up @@ -1603,7 +1608,7 @@ pub mod migrations {
fn on_runtime_upgrade() -> Weight {
if System::last_runtime_upgrade_spec_version() > UPGRADE_SESSION_KEYS_FROM_SPEC {
log::info!("Skipping session keys upgrade: already applied");
return <Runtime as frame_system::Config>::DbWeight::get().reads(1)
return <Runtime as frame_system::Config>::DbWeight::get().reads(1);
}
log::trace!("Upgrading session keys");
Session::upgrade_keys::<OldSessionKeys, _>(transform_session_keys);
Expand All @@ -1616,7 +1621,7 @@ pub mod migrations {
) -> Result<(), sp_runtime::TryRuntimeError> {
if System::last_runtime_upgrade_spec_version() > UPGRADE_SESSION_KEYS_FROM_SPEC {
log::warn!(target: "runtime::session_keys", "Skipping session keys migration post-upgrade check due to spec version (already applied?)");
return Ok(())
return Ok(());
}

let key_ids = SessionKeys::key_ids();
Expand Down Expand Up @@ -1799,6 +1804,54 @@ sp_api::impl_runtime_apis! {
}
}

impl xcm_fee_payment_runtime_api::XcmPaymentApi<Block, RuntimeCall> for Runtime {
fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
if !matches!(xcm_version, 3 | 4) {
return Err(XcmPaymentApiError::UnhandledXcmVersion);
}
Ok([VersionedAssetId::V4(xcm_config::TokenLocation::get().into())]
.into_iter()
.filter_map(|asset| asset.into_version(xcm_version).ok())
.collect())
}

fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
let local_asset = VersionedAssetId::V4(xcm_config::TokenLocation::get().into());
let asset = asset
.into_version(4)
.map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;

if asset != local_asset { return Err(XcmPaymentApiError::AssetNotFound); }

Ok(WeightToFee::weight_to_fee(&weight))
}

fn query_xcm_weight(message: VersionedXcm<RuntimeCall>) -> Result<Weight, XcmPaymentApiError> {
let mut message = message
.try_into()
.map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;
<xcm_config::XcmConfig as xcm_executor::Config>::Weigher::weight(&mut message)
.map_err(|error| {
log::error!("Error when querying XCM weight: {:?}", error);
XcmPaymentApiError::WeightNotComputable
})
}

fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
let destination = destination
.try_into()
.map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;
let message = message
.try_into()
.map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?;
let (_, fees) = xcm_config::XcmRouter::validate(&mut Some(destination), &mut Some(message)).map_err(|error| {
log::error!("Error when querying delivery fees: {:?}", error);
XcmPaymentApiError::Unroutable
})?;
Ok(VersionedAssets::from(fees))
Copy link
Contributor

Choose a reason for hiding this comment

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

A client might not understand the returned XCM version. The returned VersionedAssets should follow the version of one of the inputs. For instance, if the destination and the message are both v3, the returned assets should also be in the v3 form.
The current code will always return the form of the latest XCM version, which might break some clients (no one uses this API at the moment, but IMHO, we need a proper way of handling this for future XCM versions).

For the same reason, we have the xcm_version parameter in the query_acceptable_payment_assets method.

Another question, though: what if the destination and the message are expressed via different XCM versions? What version should the returned assets follow?

The same goes for Westend.

Copy link
Contributor

@acatangiu acatangiu Mar 25, 2024

Choose a reason for hiding this comment

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

The returned VersionedAssets should follow the version of one of the inputs. For instance, if the destination and the message are both v3, the returned assets should also be in the v3 form.

👍

Another question, though: what if the destination and the message are expressed via different XCM versions? What version should the returned assets follow?

use the newest version between them

Copy link
Contributor

Choose a reason for hiding this comment

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

Done. The implementation is located in pallet-xcm, as per the comment below.
I added the IdentifyVersion implementation for VersionedXcm to implement the "use the newest version between them" logic

}
}

impl sp_api::Metadata<Block> for Runtime {
fn metadata() -> OpaqueMetadata {
OpaqueMetadata::new(Runtime::metadata().into())
Expand Down Expand Up @@ -2509,7 +2562,7 @@ mod remote_tests {
#[tokio::test]
async fn run_migrations() {
if var("RUN_MIGRATION_TESTS").is_err() {
return
return;
}

sp_tracing::try_init_simple();
Expand Down
2 changes: 2 additions & 0 deletions polkadot/runtime/westend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parac
xcm = { package = "staging-xcm", path = "../../xcm", default-features = false }
xcm-executor = { package = "staging-xcm-executor", path = "../../xcm/xcm-executor", default-features = false }
xcm-builder = { package = "staging-xcm-builder", path = "../../xcm/xcm-builder", default-features = false }
xcm-fee-payment-runtime-api = { package = "xcm-fee-payment-runtime-api", path = "../../xcm/xcm-builder/xcm-payment-runtime-api", default-features = false }

[dev-dependencies]
hex-literal = "0.4.1"
Expand Down Expand Up @@ -228,6 +229,7 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"xcm-fee-payment-runtime-api/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand Down
Loading
Loading