Files
pezkuwi-subxt/bridges/modules/xcm-bridge-hub/src/lib.rs
T
Francisco Aguirre 8428f678fe XCMv4 (#1230)
# Note for reviewer

Most changes are just syntax changes necessary for the new version.
Most important files should be the ones under the `xcm` folder.

# Description 

Added XCMv4.

## Removed `Multi` prefix
The following types have been renamed:
- MultiLocation -> Location
- MultiAsset -> Asset
- MultiAssets -> Assets
- InteriorMultiLocation -> InteriorLocation
- MultiAssetFilter -> AssetFilter
- VersionedMultiAsset -> VersionedAsset
- WildMultiAsset -> WildAsset
- VersionedMultiLocation -> VersionedLocation

In order to fix a name conflict, the `Assets` in `xcm-executor` were
renamed to `HoldingAssets`, as they represent assets in holding.

## Removed `Abstract` asset id

It was not being used anywhere and this simplifies the code.

Now assets are just constructed as follows:

```rust
let asset: Asset = (AssetId(Location::new(1, Here)), 100u128).into();
```

No need for specifying `Concrete` anymore.

## Outcome is now a named fields struct

Instead of

```rust
pub enum Outcome {
  Complete(Weight),
  Incomplete(Weight, Error),
  Error(Error),
}
```

we now have

```rust
pub enum Outcome {
  Complete { used: Weight },
  Incomplete { used: Weight, error: Error },
  Error { error: Error },
}
```

## Added Reanchorable trait

Now both locations and assets implement this trait, making it easier to
reanchor both.

## New syntax for building locations and junctions

Now junctions are built using the following methods:

```rust
let location = Location {
    parents: 1,
    interior: [Parachain(1000), PalletInstance(50), GeneralIndex(1984)].into()
};
```

or

```rust
let location = Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]);
```

And they are matched like so:

```rust
match location.unpack() {
  (1, [Parachain(id)]) => ...
  (0, Here) => ...,
  (1, [_]) => ...,
}
```

This syntax is mandatory in v4, and has been also implemented for v2 and
v3 for easier migration.

This was needed to make all sizes smaller.

# TODO
- [x] Scaffold v4
- [x] Port github.com/paritytech/polkadot/pull/7236
- [x] Remove `Multi` prefix
- [x] Remove `Abstract` asset id

---------

Co-authored-by: command-bot <>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
2024-01-16 18:18:04 +00:00

119 lines
4.2 KiB
Rust

// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common 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.
// Parity Bridges Common 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 Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Module that adds XCM support to bridge pallets.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
use bridge_runtime_common::messages_xcm_extension::XcmBlobHauler;
use pallet_bridge_messages::Config as BridgeMessagesConfig;
use xcm::prelude::*;
pub use exporter::PalletAsHaulBlobExporter;
pub use pallet::*;
mod exporter;
mod mock;
/// The target that will be used when publishing logs related to this pallet.
pub const LOG_TARGET: &str = "runtime::bridge-xcm";
#[frame_support::pallet]
pub mod pallet {
use super::*;
use bridge_runtime_common::messages_xcm_extension::SenderAndLane;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::BlockNumberFor;
#[pallet::config]
#[pallet::disable_frame_system_supertrait_check]
pub trait Config<I: 'static = ()>:
BridgeMessagesConfig<Self::BridgeMessagesPalletInstance>
{
/// Runtime's universal location.
type UniversalLocation: Get<InteriorLocation>;
// TODO: https://github.com/paritytech/parity-bridges-common/issues/1666 remove `ChainId` and
// replace it with the `NetworkId` - then we'll be able to use
// `T as pallet_bridge_messages::Config<T::BridgeMessagesPalletInstance>::BridgedChain::NetworkId`
/// Bridged network as relative location of bridged `GlobalConsensus`.
#[pallet::constant]
type BridgedNetwork: Get<Location>;
/// Associated messages pallet instance that bridges us with the
/// `BridgedNetworkId` consensus.
type BridgeMessagesPalletInstance: 'static;
/// Price of single message export to the bridged consensus (`Self::BridgedNetworkId`).
type MessageExportPrice: Get<Assets>;
/// Checks the XCM version for the destination.
type DestinationVersion: GetVersion;
/// Get point-to-point links with bridged consensus (`Self::BridgedNetworkId`).
/// (this will be replaced with dynamic on-chain bridges - `Bridges V2`)
type Lanes: Get<sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))>>;
/// Support for point-to-point links
/// (this will be replaced with dynamic on-chain bridges - `Bridges V2`)
type LanesSupport: XcmBlobHauler;
}
#[pallet::pallet]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::hooks]
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
fn integrity_test() {
assert!(
Self::bridged_network_id().is_some(),
"Configured `T::BridgedNetwork`: {:?} does not contain `GlobalConsensus` junction with `NetworkId`",
T::BridgedNetwork::get()
)
}
}
impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Returns dedicated/configured lane identifier.
pub(crate) fn lane_for(
source: &InteriorLocation,
dest: (&NetworkId, &InteriorLocation),
) -> Option<SenderAndLane> {
let source = source.clone().relative_to(&T::UniversalLocation::get());
// Check that we have configured a point-to-point lane for 'source' and `dest`.
T::Lanes::get()
.into_iter()
.find_map(|(lane_source, (lane_dest_network, lane_dest))| {
if lane_source.location == source &&
&lane_dest_network == dest.0 &&
Self::bridged_network_id().as_ref() == Some(dest.0) &&
&lane_dest == dest.1
{
Some(lane_source)
} else {
None
}
})
}
/// Returns some `NetworkId` if contains `GlobalConsensus` junction.
fn bridged_network_id() -> Option<NetworkId> {
match T::BridgedNetwork::get().take_first_interior() {
Some(GlobalConsensus(network)) => Some(network),
_ => None,
}
}
}
}