Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

XCM v3: Bridge infrastructure #4681

Merged
merged 65 commits into from
Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
665bd6c
XCM bridge infrastructure
gavofyork Oct 30, 2021
535980e
Missing bit of cherry-pick
gavofyork Jan 10, 2022
d4376f1
Revamped XCM proc macros; new NetworkIds
gavofyork Oct 31, 2021
f093c55
Fixes
gavofyork Oct 31, 2021
bb939e8
Formatting
gavofyork Oct 31, 2021
ec2b72d
ExportMessage instruction and config type
gavofyork Oct 31, 2021
6878ed3
Add MessageExporter definitions
gavofyork Oct 31, 2021
270b662
Formatting
gavofyork Oct 31, 2021
bba850d
Missing files
gavofyork Oct 31, 2021
73e4758
Fixes
gavofyork Oct 31, 2021
4bef607
Initial bridging config API
gavofyork Oct 31, 2021
c0edea0
Allow for two-stage XCM execution
gavofyork Nov 2, 2021
128363e
Update xcm/src/v3/mod.rs
gavofyork Nov 2, 2021
4eb42d6
XCM crate building again
gavofyork Jan 10, 2022
08c41fa
Initial bridging primitive
gavofyork Jan 17, 2022
562b08b
Docs
gavofyork Jan 17, 2022
83adc05
Merge branch 'gav-xcm-v3' into gav-xcm-v3-bridging
gavofyork Jan 17, 2022
5ac926a
Docs
gavofyork Jan 18, 2022
b2dc3f1
More work
gavofyork Jan 20, 2022
4d8c9a8
More work
gavofyork Jan 20, 2022
a837427
Merge branch 'master' into gav-xcm-v3
gavofyork Jan 22, 2022
cacaf4c
Merge branch 'gav-xcm-v3' into gav-xcm-v3-bridging
gavofyork Jan 22, 2022
4a8fc7f
Merge branch 'gav-xcm-v3' into gav-xcm-v3-bridging
gavofyork Jan 22, 2022
449fe35
Merge branch 'gav-xcm-v3-bridging' of github.com:paritytech/polkadot …
gavofyork Jan 22, 2022
1723ae9
Make build
gavofyork Jan 22, 2022
30fbd39
WithComputedOrigin and SovereignPaidRemoteExporter
gavofyork Jan 23, 2022
f75c343
Remove TODOs
gavofyork Jan 28, 2022
fc9fa04
Merge remote-tracking branch 'origin/gav-xcm-v3' into gav-xcm-v3-brid…
gavofyork Jan 28, 2022
197ec2e
Merge branch 'gav-xcm-v3' into gav-xcm-v3-bridging
gavofyork Jan 31, 2022
8af0a3a
Slim bridge API and tests.
gavofyork Jan 31, 2022
caf33cb
Fixes
gavofyork Jan 31, 2022
347b32e
More work
gavofyork Feb 2, 2022
8ef2b84
First bridge test passing
gavofyork Feb 2, 2022
b459cfc
Formatting
gavofyork Feb 2, 2022
b2d3fdf
Another test
gavofyork Feb 2, 2022
ca031c2
Next round of bridging tests
gavofyork Feb 2, 2022
870b109
Repot tests
gavofyork Feb 2, 2022
c68bbc8
Cleanups
gavofyork Feb 2, 2022
1724115
Paid bridging
gavofyork Feb 2, 2022
cc9c35f
Formatting
gavofyork Feb 2, 2022
ac24184
Tests
gavofyork Feb 4, 2022
b90d041
Spelling
gavofyork Feb 4, 2022
7310377
Formatting
gavofyork Feb 4, 2022
d5b6f27
Fees and refactoring
gavofyork Feb 4, 2022
6537401
Fixes
gavofyork Feb 4, 2022
f2f844e
Formatting
gavofyork Feb 4, 2022
cfed333
Refactor SendXcm to become two-phase
gavofyork Feb 5, 2022
450f529
Fix tests
gavofyork Feb 5, 2022
7525c01
Refactoring of SendXcm and ExportXcm complete
gavofyork Feb 7, 2022
e715ef2
Formatting
gavofyork Feb 7, 2022
59768bd
Rename CannotReachDestination -> NotApplicable
gavofyork Feb 7, 2022
18f1100
Remove XCM v0
gavofyork Feb 7, 2022
087ac70
Minor grumbles
gavofyork Feb 7, 2022
9c9c38f
Formatting
gavofyork Feb 8, 2022
ca0d360
Formatting
gavofyork Feb 8, 2022
c4bc44a
Merge branch 'gav-xcm-v3-bridging' of github.com:paritytech/polkadot …
gavofyork Feb 8, 2022
3570fb4
Fixes
gavofyork Feb 8, 2022
45a697c
Fixes
gavofyork Feb 8, 2022
e28c84c
Cleanup XCM config
gavofyork Feb 9, 2022
5247473
Fee handling
gavofyork Feb 9, 2022
d68d61d
Merge remote-tracking branch 'origin/gav-xcm-v3' into gav-xcm-v3-brid…
gavofyork Feb 14, 2022
6ef1f0e
Fixes
gavofyork Feb 14, 2022
faa7463
Formatting
gavofyork Feb 14, 2022
ad5c941
Fixes
gavofyork Feb 14, 2022
5ed0737
Bump
gavofyork Feb 14, 2022
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
6 changes: 4 additions & 2 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion bridges/primitives/messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
bitvec = { version = "0.20", default-features = false, features = ["alloc"] }
codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ["derive", "bit-vec"] }
impl-trait-for-tuples = "0.2"
impl-trait-for-tuples = "0.2.2"
scale-info = { version = "1.0", default-features = false, features = ["bit-vec", "derive"] }
serde = { version = "1.0", optional = true, features = ["derive"] }

Expand Down
2 changes: 1 addition & 1 deletion runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"

[dependencies]
impl-trait-for-tuples = "0.2.0"
impl-trait-for-tuples = "0.2.2"
bitvec = { version = "0.20.1", default-features = false, features = ["alloc"] }
parity-scale-codec = { version = "2.3.1", default-features = false, features = ["derive"] }
log = { version = "0.4.13", default-features = false }
Expand Down
59 changes: 38 additions & 21 deletions runtime/common/src/xcm_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,50 @@
//! XCM sender for relay chain.

use parity_scale_codec::Encode;
use runtime_parachains::{configuration, dmp};
use sp_std::marker::PhantomData;
use xcm::latest::prelude::*;
use primitives::v1::Id as ParaId;
use runtime_parachains::{
configuration::{self, HostConfiguration},
dmp,
};
use sp_std::{marker::PhantomData, prelude::*};
use xcm::prelude::*;
use SendError::*;

/// XCM sender for relay chain. It only sends downward message.
pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);

impl<T: configuration::Config + dmp::Config, W: xcm::WrapVersion> SendXcm
for ChildParachainRouter<T, W>
{
fn send_xcm(dest: impl Into<MultiLocation>, msg: Xcm<()>) -> SendResult {
let dest = dest.into();
match dest {
MultiLocation { parents: 0, interior: X1(Parachain(id)) } => {
// Downward message passing.
let versioned_xcm =
W::wrap_version(&dest, msg).map_err(|()| SendError::DestinationUnsupported)?;
let config = <configuration::Pallet<T>>::config();
<dmp::Pallet<T>>::queue_downward_message(
&config,
id.into(),
versioned_xcm.encode(),
)
.map_err(Into::<SendError>::into)?;
Ok(())
},
dest => Err(SendError::CannotReachDestination(dest, msg)),
}
type Ticket = (HostConfiguration<T::BlockNumber>, ParaId, Vec<u8>);

fn validate(
dest: &mut Option<MultiLocation>,
msg: &mut Option<Xcm<()>>,
) -> SendResult<(HostConfiguration<T::BlockNumber>, ParaId, Vec<u8>)> {
let d = dest.take().ok_or(MissingArgument)?;
let id = if let MultiLocation { parents: 0, interior: X1(Parachain(id)) } = &d {
*id
} else {
*dest = Some(d);
return Err(NotApplicable)
};

// Downward message passing.
let xcm = msg.take().ok_or(MissingArgument)?;
let config = <configuration::Pallet<T>>::config();
let para = id.into();
let blob = W::wrap_version(&d, xcm).map_err(|()| DestinationUnsupported)?.encode();
<dmp::Pallet<T>>::can_queue_downward_message(&config, &para, &blob)
.map_err(Into::<SendError>::into)?;

Ok(((config, para, blob), MultiAssets::new()))
}

fn deliver(
(config, para, blob): (HostConfiguration<T::BlockNumber>, ParaId, Vec<u8>),
) -> Result<(), SendError> {
<dmp::Pallet<T>>::queue_downward_message(&config, para, blob)
.map_err(|_| SendError::Transport(&"Error placing into DMP queue"))
}
}
2 changes: 1 addition & 1 deletion runtime/kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("kusama"),
impl_name: create_runtime_str!("parity-kusama"),
authoring_version: 2,
spec_version: 9140,
spec_version: 9170,
impl_version: 0,
#[cfg(not(feature = "disable-runtime-api"))]
apis: RUNTIME_API_VERSIONS,
Expand Down
46 changes: 27 additions & 19 deletions runtime/kusama/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,19 @@ use xcm_builder::{
LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
TakeWeightCredit, UsingComponents,
};
use xcm_executor::XcmExecutor;

parameter_types! {
/// The location of the KSM token, from the context of this chain. Since this token is native to this
/// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to
/// the context".
pub const KsmLocation: MultiLocation = Here.into();
pub const TokenLocation: MultiLocation = Here.into_location();
/// The Kusama network ID. This is named.
pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
/// Kusama is a top-level relay-chain, there is no ancestry.
pub const Ancestry: MultiLocation = Here.into();
pub const ThisNetwork: NetworkId = Kusama;
/// Our XCM location ancestry - i.e. our location within the Consensus Universe.
///
/// Since Kusama is a top-level relay-chain with its own consensus, it's just our network ID.
pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into();
/// The check account, which holds any native assets that have been teleported out and not back in (yet).
pub CheckAccount: AccountId = XcmPallet::check_account();
}
Expand All @@ -56,18 +58,18 @@ pub type SovereignAccountOf = (
// We can convert a child parachain using the standard `AccountId` conversion.
ChildParachainConvertsVia<ParaId, AccountId>,
// We can directly alias an `AccountId32` into a local account.
AccountId32Aliases<KusamaNetwork, AccountId>,
AccountId32Aliases<ThisNetwork, AccountId>,
);

/// Our asset transactor. This is what allows us to interest with the runtime facilities from the point of
/// view of XCM-only concepts like `MultiLocation` and `MultiAsset`.
///
/// Ours is only aware of the Balances pallet, which is mapped to `KsmLocation`.
/// Ours is only aware of the Balances pallet, which is mapped to `TokenLocation`.
pub type LocalAssetTransactor = XcmCurrencyAdapter<
// Use this currency:
Balances,
// Use this currency when it is a fungible asset matching the given location or name:
IsConcrete<KsmLocation>,
IsConcrete<TokenLocation>,
// We can convert the MultiLocations with our converter above:
SovereignAccountOf,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
Expand All @@ -76,14 +78,14 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter<
CheckAccount,
>;

/// The means that we convert an the XCM message origin location into a local dispatch origin.
/// The means that we convert the XCM message origin location into a local dispatch origin.
type LocalOriginConverter = (
// A `Signed` origin of the sovereign account that the original location controls.
SovereignSignedViaLocation<SovereignAccountOf, Origin>,
// A child parachain, natively expressed, has the `Parachain` origin.
ChildParachainAsNative<parachains_origin::Origin, Origin>,
// The AccountId32 location type can be expressed natively as a `Signed` origin.
SignedAccountId32AsNative<KusamaNetwork, Origin>,
SignedAccountId32AsNative<ThisNetwork, Origin>,
// A system child parachain, expressed as a Superuser, converts to the `Root` origin.
ChildSystemParachainAsSuperuser<ParaId, Origin>,
);
Expand All @@ -104,13 +106,13 @@ pub type XcmRouter = (
);

parameter_types! {
pub const Kusama: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(KsmLocation::get()) });
pub const KusamaForStatemine: (MultiAssetFilter, MultiLocation) = (Kusama::get(), Parachain(1000).into());
pub const KusamaForEncointer: (MultiAssetFilter, MultiLocation) = (Kusama::get(), Parachain(1001).into());
pub const Ksm: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) });
pub const KsmForStatemine: (MultiAssetFilter, MultiLocation) = (Ksm::get(), Parachain(1000).into_location());
pub const KsmForEncointer: (MultiAssetFilter, MultiLocation) = (Ksm::get(), Parachain(1001).into_location());
pub const MaxAssetsIntoHolding: u32 = 64;
}
pub type TrustedTeleporters =
(xcm_builder::Case<KusamaForStatemine>, xcm_builder::Case<KusamaForEncointer>);
(xcm_builder::Case<KsmForStatemine>, xcm_builder::Case<KsmForEncointer>);

match_type! {
pub type OnlyParachains: impl Contains<MultiLocation> = {
Expand Down Expand Up @@ -140,17 +142,22 @@ impl xcm_executor::Config for XcmConfig {
type OriginConverter = LocalOriginConverter;
type IsReserve = ();
type IsTeleporter = TrustedTeleporters;
type LocationInverter = LocationInverter<Ancestry>;
type LocationInverter = LocationInverter<UniversalLocation>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;
// The weight trader piggybacks on the existing transaction-fee conversion logic.
type Trader = UsingComponents<WeightToFee, KsmLocation, AccountId, Balances, ToAuthor<Runtime>>;
type Trader =
UsingComponents<WeightToFee, TokenLocation, AccountId, Balances, ToAuthor<Runtime>>;
type ResponseHandler = XcmPallet;
type AssetTrap = XcmPallet;
type AssetClaims = XcmPallet;
type SubscriptionService = XcmPallet;
type PalletInstancesInfo = AllPalletsWithSystem;
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type FeeManager = ();
// No bridges yet...
type MessageExporter = ();
type UniversalAliases = Nothing;
}

parameter_types! {
Expand All @@ -168,8 +175,9 @@ pub type LocalOriginToLocation = (
CouncilBodyId,
>,
// And a usual Signed origin to be used in XCM as a corresponding AccountId32
SignedToAccountId32<Origin, AccountId, KusamaNetwork>,
SignedToAccountId32<Origin, AccountId, ThisNetwork>,
);

impl pallet_xcm::Config for Runtime {
type Event = Event;
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
Expand All @@ -178,11 +186,11 @@ impl pallet_xcm::Config for Runtime {
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
// ...but they must match our filter, which rejects all.
type XcmExecuteFilter = Nothing;
type XcmExecutor = xcm_executor::XcmExecutor<XcmConfig>;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmTeleportFilter = Everything;
type XcmReserveTransferFilter = Everything;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;
type LocationInverter = LocationInverter<Ancestry>;
type LocationInverter = LocationInverter<UniversalLocation>;
type Origin = Origin;
type Call = Call;
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
Expand Down
15 changes: 15 additions & 0 deletions runtime/parachains/src/dmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,21 @@ impl<T: Config> Pallet<T> {
<Self as Store>::DownwardMessageQueueHeads::remove(outgoing_para);
}

/// Determine whether enqueuing a downward message to a specific recipient para would result
/// in an error. If this returns `Ok(())` the caller can be certain that a call to
/// `queue_downward_message` with the same parameters will be successful.
pub fn can_queue_downward_message(
config: &HostConfiguration<T::BlockNumber>,
_para: &ParaId,
msg: &DownwardMessage,
) -> Result<(), QueueDownwardMessageError> {
let serialized_len = msg.len() as u32;
if serialized_len > config.max_downward_message_size {
return Err(QueueDownwardMessageError::ExceedsMaxMessageSize)
}
Ok(())
}

/// Enqueue a downward message to a specific recipient para.
///
/// When encoded, the message should not exceed the `config.max_downward_message_size`.
Expand Down
2 changes: 1 addition & 1 deletion runtime/polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("polkadot"),
impl_name: create_runtime_str!("parity-polkadot"),
authoring_version: 0,
spec_version: 9140,
spec_version: 9170,
impl_version: 0,
#[cfg(not(feature = "disable-runtime-api"))]
apis: RUNTIME_API_VERSIONS,
Expand Down
Loading