Skip to content

Commit

Permalink
Added Trusted Query API calls (#6039)
Browse files Browse the repository at this point in the history
Implemented is_trusted_reserve and is_trusted_teleporter API methods. 
Tested them with regular and chopstick tests.
Fixes #97

---------

Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
  • Loading branch information
x3c41a and franciscoaguirre authored Oct 17, 2024
1 parent d23a1bb commit 7240b47
Show file tree
Hide file tree
Showing 19 changed files with 424 additions and 3 deletions.
13 changes: 12 additions & 1 deletion cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ use xcm::latest::prelude::{
};
use xcm::{
latest::prelude::{AssetId, BodyId},
VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
};
use xcm_runtime_apis::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
Expand Down Expand Up @@ -1098,6 +1098,8 @@ pub type Executive = frame_executive::Executive<
Migrations,
>;

type XcmTrustedQueryResult = Result<bool, xcm_runtime_apis::trusted_query::Error>;

#[cfg(feature = "runtime-benchmarks")]
mod benches {
frame_benchmarking::define_benchmarks!(
Expand Down Expand Up @@ -1798,6 +1800,15 @@ impl_runtime_apis! {
genesis_config_presets::preset_names()
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> XcmTrustedQueryResult {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> XcmTrustedQueryResult {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
11 changes: 10 additions & 1 deletion cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ use assets_common::{
use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
use xcm::{
latest::prelude::AssetId,
prelude::{VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm},
prelude::{VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm},
};

#[cfg(feature = "runtime-benchmarks")]
Expand Down Expand Up @@ -1894,6 +1894,15 @@ impl_runtime_apis! {
genesis_config_presets::preset_names()
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,15 @@ impl_runtime_apis! {
genesis_config_presets::preset_names()
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

#[cfg(test)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,15 @@ impl_runtime_apis! {
genesis_config_presets::preset_names()
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,15 @@ impl_runtime_apis! {
genesis_config_presets::preset_names()
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,15 @@ impl_runtime_apis! {
vec![]
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,15 @@ impl_runtime_apis! {
vec![]
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,15 @@ impl_runtime_apis! {
vec![]
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
9 changes: 9 additions & 0 deletions cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,15 @@ impl_runtime_apis! {
vec![]
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
9 changes: 9 additions & 0 deletions cumulus/parachains/runtimes/people/people-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,15 @@ impl_runtime_apis! {
vec![]
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
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 @@ -92,7 +92,7 @@ use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
use xcm::{
latest::prelude::{AssetId as AssetLocationId, BodyId},
VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
};
use xcm_runtime_apis::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
Expand Down Expand Up @@ -1143,6 +1143,15 @@ impl_runtime_apis! {
vec![]
}
}

impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_reserve(asset, location)
}
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, xcm_runtime_apis::trusted_query::Error> {
PolkadotXcm::is_trusted_teleporter(asset, location)
}
}
}

cumulus_pallet_parachain_system::register_validate_block! {
Expand Down
52 changes: 52 additions & 0 deletions polkadot/xcm/pallet-xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use xcm_executor::{
use xcm_runtime_apis::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::Error as XcmPaymentApiError,
trusted_query::Error as TrustedQueryApiError,
};

#[cfg(any(feature = "try-runtime", test))]
Expand Down Expand Up @@ -2603,6 +2604,57 @@ impl<T: Config> Pallet<T> {
})
}

/// Given an Asset and a Location, returns if the provided location is a trusted reserve for the
/// given asset.
pub fn is_trusted_reserve(
asset: VersionedAsset,
location: VersionedLocation,
) -> Result<bool, TrustedQueryApiError> {
let location: Location = location.try_into().map_err(|e| {
tracing::debug!(
target: "xcm::pallet_xcm::is_trusted_reserve",
"Asset version conversion failed with error: {:?}",
e,
);
TrustedQueryApiError::VersionedLocationConversionFailed
})?;

let a: Asset = asset.try_into().map_err(|e| {
tracing::debug!(
target: "xcm::pallet_xcm::is_trusted_reserve",
"Location version conversion failed with error: {:?}",
e,
);
TrustedQueryApiError::VersionedAssetConversionFailed
})?;

Ok(<T::XcmExecutor as XcmAssetTransfers>::IsReserve::contains(&a, &location))
}

/// Given an Asset and a Location, returns if the asset can be teleported to provided location.
pub fn is_trusted_teleporter(
asset: VersionedAsset,
location: VersionedLocation,
) -> Result<bool, TrustedQueryApiError> {
let location: Location = location.try_into().map_err(|e| {
tracing::debug!(
target: "xcm::pallet_xcm::is_trusted_teleporter",
"Asset version conversion failed with error: {:?}",
e,
);
TrustedQueryApiError::VersionedLocationConversionFailed
})?;
let a: Asset = asset.try_into().map_err(|e| {
tracing::debug!(
target: "xcm::pallet_xcm::is_trusted_teleporter",
"Location version conversion failed with error: {:?}",
e,
);
TrustedQueryApiError::VersionedAssetConversionFailed
})?;
Ok(<T::XcmExecutor as XcmAssetTransfers>::IsTeleporter::contains(&a, &location))
}

pub fn query_delivery_fees(
destination: VersionedLocation,
message: VersionedXcm<()>,
Expand Down
4 changes: 4 additions & 0 deletions polkadot/xcm/xcm-runtime-apis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ pub mod dry_run;
/// Fee estimation API.
/// Given an XCM program, it will return the fees needed to execute it properly or send it.
pub mod fees;

// Exposes runtime API for querying whether a Location is trusted as a reserve or teleporter for a
// given Asset.
pub mod trusted_query;
49 changes: 49 additions & 0 deletions polkadot/xcm/xcm-runtime-apis/src/trusted_query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! Runtime API definition for checking if given <Asset, Location> is trusted reserve or teleporter.

use codec::{Decode, Encode};
use frame_support::pallet_prelude::TypeInfo;
use xcm::{VersionedAsset, VersionedLocation};

sp_api::decl_runtime_apis! {
// API for querying trusted reserves and trusted teleporters.
pub trait TrustedQueryApi {
/// Returns if the location is a trusted reserve for the asset.
///
/// # Arguments
/// * `asset`: `VersionedAsset`.
/// * `location`: `VersionedLocation`.
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, Error>;
/// Returns if the asset can be teleported to the location.
///
/// # Arguments
/// * `asset`: `VersionedAsset`.
/// * `location`: `VersionedLocation`.
fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, Error>;
}
}

#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)]
pub enum Error {
/// Converting a versioned Asset structure from one version to another failed.
#[codec(index = 1)]
VersionedAssetConversionFailed,
/// Converting a versioned Location structure from one version to another failed.
#[codec(index = 1)]
VersionedLocationConversionFailed,
}
11 changes: 11 additions & 0 deletions polkadot/xcm/xcm-runtime-apis/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use xcm_runtime_apis::{
conversions::{Error as LocationToAccountApiError, LocationToAccountApi},
dry_run::{CallDryRunEffects, DryRunApi, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::{Error as XcmPaymentApiError, XcmPaymentApi},
trusted_query::{Error as TrustedQueryApiError, TrustedQueryApi},
};

construct_runtime! {
Expand Down Expand Up @@ -414,6 +415,16 @@ impl sp_api::ProvideRuntimeApi<Block> for TestClient {
}

sp_api::mock_impl_runtime_apis! {
impl TrustedQueryApi<Block> for RuntimeApi {
fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, TrustedQueryApiError> {
XcmPallet::is_trusted_reserve(asset, location)
}

fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> Result<bool, TrustedQueryApiError> {
XcmPallet::is_trusted_teleporter(asset, location)
}
}

impl LocationToAccountApi<Block, AccountId> for RuntimeApi {
fn convert_location(location: VersionedLocation) -> Result<AccountId, LocationToAccountApiError> {
let location = location.try_into().map_err(|_| LocationToAccountApiError::VersionedConversionFailed)?;
Expand Down
Loading

0 comments on commit 7240b47

Please sign in to comment.