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

XCM v3: Bridge infrastructure #4186

Closed
wants to merge 101 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
4f2a52f
increase ump_service_total_weight's default value (#4127)
GopherJ Oct 30, 2021
ad019dd
differentiate log messages (#4183)
drahnr Oct 30, 2021
fb730e4
remove duplicate Deposit from OnUnbalanced implementation (#4180)
apopiak Oct 30, 2021
a6dd54e
collator-protocol/validator_side: a couple of fixes (#4179)
ordian Oct 30, 2021
0f5cf2d
XCM bridge infrastructure
gavofyork Oct 30, 2021
1a924d3
Revamped XCM proc macros; new NetworkIds
gavofyork Oct 31, 2021
4d6be64
Fixes
gavofyork Oct 31, 2021
1dec6cc
Formatting
gavofyork Oct 31, 2021
d9d5bc6
ExportMessage instruction and config type
gavofyork Oct 31, 2021
2fd3f81
Add MessageExporter definitions
gavofyork Oct 31, 2021
332e9ab
Formatting
gavofyork Oct 31, 2021
9b4975f
Missing files
gavofyork Oct 31, 2021
97104ab
Fixes
gavofyork Oct 31, 2021
89c595c
Initial bridging config API
gavofyork Oct 31, 2021
bbe8b11
bump rococo spec (#4189)
ordian Oct 31, 2021
96673f4
Allow for two-stage XCM execution
gavofyork Nov 2, 2021
fe807f0
Update xcm/src/v3/mod.rs
gavofyork Nov 2, 2021
9c1e709
Implement IntoIterator for Xcm and cargo fmt
KiChjang Nov 2, 2021
5a6b4ef
Bump dlmalloc from 0.2.1 to 0.2.2 (#4205)
dependabot[bot] Nov 2, 2021
4fe4d3f
Update GHA to s3krit/matrix-message-action@v0.0.3 + doc (#4030)
chevdor Nov 2, 2021
dc9a1bb
Bump libc from 0.2.105 to 0.2.106 (#4194)
dependabot[bot] Nov 2, 2021
60d3305
Update SimNet test to the new format (#4051)
radupopa2010 Nov 3, 2021
9ee52bd
Offchain: Disable http requests (#4188)
bkchr Nov 3, 2021
4fdec83
Update CI image to use the latest rustc (#4200)
alvicsam Nov 3, 2021
85ec699
More remote tests for bags-list pallet (#4065)
kianenigma Nov 3, 2021
94243bb
Bump tokio from 1.12.0 to 1.13.0 (#4193)
dependabot[bot] Nov 3, 2021
4685b25
Fix misleading logs in collator protocol. (#4201)
eskimor Nov 4, 2021
6841b72
minor doc chores (#4219)
drahnr Nov 4, 2021
7a53298
implement dispatch_as (#4075)
xlc Nov 4, 2021
81013be
Change path for the tests to master (#4223)
grbIzl Nov 4, 2021
d985794
fix(staking miner): use `StorageKey` in getStorage (#4231)
niklasad1 Nov 6, 2021
e553085
Update `bridge/` codeowners (#4222)
HCastano Nov 8, 2021
15c68e4
Fixes
gavofyork Nov 8, 2021
16bcb44
Fixes
gavofyork Nov 8, 2021
547bc8a
availability recovery type name clarifications (#4203)
drahnr Nov 8, 2021
e91b9d0
Increase maximum chunk size to adjust for small networks. (#4220)
eskimor Nov 9, 2021
174f339
update cargo lock to unbreak dep of a dep (#4245)
gnunicorn Nov 9, 2021
35d93c3
Update `wasmtime` and related dependencies (companion for Substrate#1…
koute Nov 9, 2021
ca8c968
Bump serde_json from 1.0.68 to 1.0.69 (#4236)
dependabot[bot] Nov 9, 2021
5085341
Bump paste from 1.0.5 to 1.0.6 (#4244)
dependabot[bot] Nov 9, 2021
002936b
Bump libc from 0.2.106 to 0.2.107 (#4235)
dependabot[bot] Nov 9, 2021
56d4cde
Bump dlmalloc from 0.2.2 to 0.2.3 (#4250)
dependabot[bot] Nov 9, 2021
f26e523
Bump mick-jaeger from 0.1.4 to 0.1.6 (#4249)
dependabot[bot] Nov 10, 2021
2d583c1
Update dependencies for latest substrate master (#4258)
gnunicorn Nov 10, 2021
5587267
Add more XCM tracing (#4211)
apopiak Nov 11, 2021
0a86997
Companion – Update jsonrpsee to 0.4.1 (#4256)
dvdplm Nov 11, 2021
83e5955
CI: chore (#3957)
TriplEight Nov 11, 2021
9e8b26f
Per subsystem CPU usage tracking (#4239)
sandreim Nov 11, 2021
a2244b6
collator-protocol: do not connect to the next group (#4261)
ordian Nov 11, 2021
dfc0167
Enable full use of pallet-bags-list in westend and kusama runtimes (#…
kianenigma Nov 12, 2021
14be5d5
Remove light client companion (#4191)
arkpar Nov 12, 2021
c18d42d
req/resp: use IfDisconnected::ImmediateError (#4253)
ordian Nov 12, 2021
e26984f
Increment the retired metric instead of spawned (#4269)
pepyakin Nov 12, 2021
db10793
Bump pwasm-utils to 0.18.2 (#4267)
pepyakin Nov 12, 2021
e4f16c5
chore: fmt should print version (#4274)
drahnr Nov 12, 2021
e0f4df5
3x8 update nightly fix fmt (#4241)
TriplEight Nov 12, 2021
0365f3c
Limit the number of PVF workers (#4273)
pepyakin Nov 13, 2021
903c6f2
PVF host prechecking support v2 (#4123)
slumber Nov 13, 2021
12df8e0
Bump hex-literal from 0.3.3 to 0.3.4 (#4264)
dependabot[bot] Nov 13, 2021
414ec0e
Increase preparation timeout (#4270)
pepyakin Nov 15, 2021
13c2695
bump versions (#4285)
s3krit Nov 15, 2021
f26005b
Tweaks to XCM for Benchmarking (#4283)
shawntabrizi Nov 15, 2021
a711993
Update event variants (#4262)
Wizdave97 Nov 16, 2021
f0160fb
Bump serde_json from 1.0.69 to 1.0.70 (#4284)
dependabot[bot] Nov 16, 2021
a6af5c4
Bump async-process from 1.1.0 to 1.3.0 (#4260)
dependabot[bot] Nov 16, 2021
c198d26
move paras inherent filtering to runtime (#4028)
drahnr Nov 16, 2021
e0295ed
Companion for substrate#9878 (#3949)
koushiro Nov 17, 2021
7ea6595
Substrate companion: Authority discovery multiple peer ids (#4295)
bkchr Nov 17, 2021
a26dd2a
Bump tokio from 1.13.0 to 1.14.0 (#4298)
dependabot[bot] Nov 17, 2021
e2ba1ee
Remove sort_unstable_by (#4314)
Lldenaurois Nov 17, 2021
97c3483
Bump strum from 0.22.0 to 0.23.0 (#4308)
dependabot[bot] Nov 17, 2021
d21e86d
Bump serde_json from 1.0.70 to 1.0.71 (#4316)
dependabot[bot] Nov 18, 2021
dba4f1a
Enable BEEFY explicitly (#4320)
andresilva Nov 18, 2021
06642de
prepare worker: Catch unexpected unwinds (#4304)
pepyakin Nov 18, 2021
8b81b13
fix pallet-xcm extrinsic doc comments (#4317)
apopiak Nov 18, 2021
6b8eb91
Use non-empty validation code (#4322)
pepyakin Nov 18, 2021
9d53834
Add missing license header (#4321)
pepyakin Nov 18, 2021
cceb775
export hrmp config (#4324)
GopherJ Nov 19, 2021
9f059fb
Dependabot: Ignore sub-tokens (#4328)
bkchr Nov 19, 2021
d488955
Dispute spam protection (#4134)
eskimor Nov 19, 2021
1ec4819
Log para inherent inputs (#4331)
emostov Nov 19, 2021
71e7670
remove provisioner checks (#4254)
drahnr Nov 19, 2021
16fb469
prefer code upgrades in inherent filtering (#4334)
drahnr Nov 19, 2021
58e4ef8
Companion for Taskmanager: Remove `clean_shutdown` (#4336)
bkchr Nov 19, 2021
cd9929f
Replicate Rob's PR (#4337)
Lldenaurois Nov 20, 2021
2ffb293
introduce malus + zombienet based integration tests (#4131)
pepoviola Nov 20, 2021
0549d9d
Bump libc from 0.2.107 to 0.2.108 (#4343)
dependabot[bot] Nov 22, 2021
7a530d0
use correct gh_dir env for zombienet (#4346)
pepoviola Nov 22, 2021
6fa464b
Add XCM pallet and config to Polkadot runtime (#4313)
NachoPal Nov 22, 2021
8952974
Inherent filtering follow up (#4305)
emostov Nov 23, 2021
ca38b56
add missing feature (#4355)
xlc Nov 24, 2021
f9358cc
Add Provisioner dispute metrics (#4352)
sandreim Nov 24, 2021
49bb226
Fix use of weight limit errors (#4358)
gavofyork Nov 24, 2021
8cd96d9
OCD: Remove ,) in PVF (#4362)
pepyakin Nov 24, 2021
0609dc7
add additional assurances to `create_inherent` (#4349)
drahnr Nov 24, 2021
024a927
fix provisioner metric docs (#4359)
sandreim Nov 24, 2021
b56a7b7
Fix spellcheck (#4363)
sandreim Nov 24, 2021
f6b6250
add disputes to Kusama runtime (#4356)
rphmeier Nov 24, 2021
6da31d0
[ci] Add ssh token for publishing gh-pages (#4347)
alvicsam Nov 25, 2021
745d3bc
Add Statemine as parachain 1000 to rococo trusted teleporters (#4312)
apopiak Nov 25, 2021
ff20f47
Merge remote-tracking branch 'origin/master' into gav-xcm-universal-o…
gavofyork Nov 25, 2021
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
35 changes: 33 additions & 2 deletions xcm/src/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub use multilocation::{
};
pub use traits::{
Error, ExecuteXcm, Outcome, Result, SendError, SendResult, SendXcm, Weight, XcmWeightInfo,
PreparedMessage,
};
// These parts of XCM v2 are unchanged in XCM v3, and are re-imported here.
pub use super::v2::{BodyId, BodyPart, OriginKind, WeightLimit};
Expand Down Expand Up @@ -78,6 +79,24 @@ impl<Call> Xcm<Call> {
self.0.len()
}

/// Return a reference to the inner value.
pub fn inner(&self) -> &Vec<Instruction<Call>> { &self.0 }

/// Return a mutable reference to the inner value.
pub fn inner_mut(&mut self) -> &mut Vec<Instruction<Call>> { &mut self.0 }
gavofyork marked this conversation as resolved.
Show resolved Hide resolved

/// Consume and return the inner value.
pub fn into_inner(self) -> Vec<Instruction<Call>> { self.0 }

/// Return an iterator over references to the items.
pub fn iter(&self) -> impl Iterator<Item=&Instruction<Call>> { self.0.iter() }

/// Return an iterator over mutable references to the items.
pub fn iter_mut(&mut self) -> impl Iterator<Item=&mut Instruction<Call>> { self.0.iter_mut() }

/// Consume and return an iterator over the items.
pub fn into_iter(self) -> impl Iterator<Item=Instruction<Call>> { self.0.into_iter() }
KiChjang marked this conversation as resolved.
Show resolved Hide resolved

/// Consume and either return `self` if it contains some instructions, or if it's empty, then
/// instead return the result of `f`.
pub fn or_else(self, f: impl FnOnce() -> Self) -> Self {
Expand Down Expand Up @@ -118,6 +137,18 @@ impl<Call> Xcm<Call> {
}
}

impl<Call> From<Vec<Instruction<Call>>> for Xcm<Call> {
fn from(c: Vec<Instruction<Call>>) -> Self {
Self(c)
}
}

impl<Call> From<Xcm<Call>> for Vec<Instruction<Call>> {
fn from(c: Xcm<Call>) -> Self {
c.0
}
}

/// A prelude for importing all types typically used when interacting with XCM messages.
pub mod prelude {
mod contents {
Expand All @@ -135,8 +166,8 @@ pub mod prelude {
MultiAssetFilter::{self, *},
MultiAssets, MultiLocation,
NetworkId::{self, *},
OriginKind, Outcome, PalletInfo, Parent, ParentThen, QueryId, QueryResponseInfo,
Response, Result as XcmResult, SendError, SendResult, SendXcm,
OriginKind, Outcome, PalletInfo, Parent, ParentThen, PreparedMessage, QueryId,
QueryResponseInfo, Response, Result as XcmResult, SendError, SendResult, SendXcm,
WeightLimit::{self, *},
WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible},
WildMultiAsset::{self, *},
Expand Down
44 changes: 35 additions & 9 deletions xcm/src/v3/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,20 @@ impl Outcome {
}
}

pub trait PreparedMessage {
fn weight_of(&self) -> Weight;
}

/// Type of XCM message executor.
pub trait ExecuteXcm<Call> {
type Prepared: PreparedMessage;
fn prepare(message: Xcm<Call>) -> result::Result<Self::Prepared, Xcm<Call>>;
fn execute(
origin: impl Into<MultiLocation>,
pre: Self::Prepared,
weight_credit: Weight,
) -> Outcome;

/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The weight limit is
/// a basic hard-limit and the implementation may place further restrictions or requirements on weight and
/// other aspects.
Expand Down Expand Up @@ -244,18 +256,32 @@ pub trait ExecuteXcm<Call> {
message: Xcm<Call>,
weight_limit: Weight,
weight_credit: Weight,
) -> Outcome;
) -> Outcome {
let pre = match Self::prepare(message) {
Ok(x) => x,
Err(_) => return Outcome::Error(Error::WeightNotComputable),
};
let xcm_weight = pre.weight_of();
if xcm_weight > weight_limit {
return Outcome::Error(Error::WeightLimitReached(xcm_weight))
}
Self::execute(origin, pre, weight_credit)
}
}

pub enum Weightless {}
impl PreparedMessage for Weightless {
fn weight_of(&self) -> Weight { unreachable!() }
}

impl<C> ExecuteXcm<C> for () {
fn execute_xcm_in_credit(
_origin: impl Into<MultiLocation>,
_message: Xcm<C>,
_weight_limit: Weight,
_weight_credit: Weight,
) -> Outcome {
Outcome::Error(Error::Unimplemented)
}
type Prepared = Weightless;
fn prepare(message: Xcm<C>) -> result::Result<Self::Prepared, Xcm<C>> { Err(message) }
fn execute(
_: impl Into<MultiLocation>,
_: Self::Prepared,
_: Weight,
) -> Outcome { unreachable!() }
}

/// Error result value when attempting to send an XCM message.
Expand Down
98 changes: 76 additions & 22 deletions xcm/xcm-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,47 +74,36 @@ mod universal_exports {
use xcm_executor::traits::ExportXcm;

fn ensure_is_remote(
ancestry: impl Into<InteriorMultiLocation>,
universal_local: impl Into<InteriorMultiLocation>,
dest: impl Into<MultiLocation>,
) -> Result<(NetworkId, InteriorMultiLocation), MultiLocation> {
) -> Result<(NetworkId, InteriorMultiLocation, NetworkId, InteriorMultiLocation), MultiLocation> {
let dest = dest.into();
let ancestry = ancestry.into();
let local_network = match ancestry.first() {
Some(GlobalConsensus(network)) => network.clone(),
let universal_local = universal_local.into();
let (local_net, local_loc) = match universal_local.clone().split_first() {
(location, Some(GlobalConsensus(network))) => (network, location),
_ => return Err(dest),
};
let universal_destination: InteriorMultiLocation = ancestry
let universal_destination: InteriorMultiLocation = universal_local
.into_location()
.appended_with(dest.clone())
.map_err(|x| x.1)?
.try_into()?;
let (remote_dest, remote_net) = match universal_destination.split_first() {
(d, Some(GlobalConsensus(n))) if n != local_network => (d, n),
(d, Some(GlobalConsensus(n))) if n != local_net => (d, n),
_ => return Err(dest),
};
Ok((remote_net, remote_dest))
}

pub struct LocalExporter<Exporter, Ancestry>(PhantomData<(Exporter, Ancestry)>);
impl<Exporter: ExportXcm, Ancestry: Get<InteriorMultiLocation>> SendXcm for LocalExporter<Exporter, Ancestry> {
fn send_xcm(dest: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult {
let (network, destination) = match ensure_is_remote(Ancestry::get(), dest) {
Ok(x) => x,
Err(dest) => return Err(SendError::CannotReachDestination(dest, message)),
};
Exporter::export_xcm(network, 0, destination, message)
}
Ok((remote_net, remote_dest, local_net, local_loc))
}

#[test]
fn local_exporter_works() {
fn ensure_is_remote_works() {
// A Kusama parachain is remote from the Polkadot Relay.
let x = ensure_is_remote(Polkadot, (Parent, Kusama, Parachain(1000)));
assert_eq!(x, Ok((Kusama, Parachain(1000).into())));
assert_eq!(x, Ok((Kusama, Parachain(1000).into(), Polkadot, Here)));

// Polkadot Relay is remote from a Kusama parachain.
let x = ensure_is_remote((Kusama, Parachain(1000)), (Parent, Parent, Polkadot));
assert_eq!(x, Ok((Polkadot, ().into())));
assert_eq!(x, Ok((Polkadot, Here, Kusama, Parachain(1000).into())));

// Our own parachain is local.
let x = ensure_is_remote(Polkadot, Parachain(1000));
Expand All @@ -128,4 +117,69 @@ mod universal_exports {
let x = ensure_is_remote((), (Parent, Polkadot, Parachain(1000)));
assert_eq!(x, Err((Parent, Polkadot, Parachain(1000)).into()));
}

pub struct LocalUnpaidExporter<Exporter, Ancestry>(PhantomData<(Exporter, Ancestry)>);
impl<Exporter: ExportXcm, Ancestry: Get<InteriorMultiLocation>> SendXcm for LocalUnpaidExporter<Exporter, Ancestry> {
fn send_xcm(dest: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult {
let (network, destination, _, _) = match ensure_is_remote(Ancestry::get(), dest) {
Ok(x) => x,
Err(dest) => return Err(SendError::CannotReachDestination(dest, message)),
};
Exporter::export_xcm(network, 0, destination, message)
}
}

pub struct LocalUnpaidExecutingExporter<
Executer,
Ancestry,
WeightLimit,
Call,
>(PhantomData<(Executer, Ancestry, WeightLimit, Call)>);
impl<
Executer: ExecuteXcm<Call>,
Ancestry: Get<InteriorMultiLocation>,
WeightLimit: Get<u64>,
Call,
> SendXcm for LocalUnpaidExecutingExporter<Executer, Ancestry, WeightLimit, Call> {
fn send_xcm(dest: impl Into<MultiLocation>, mut xcm: Xcm<()>) -> SendResult {
let dest = dest.into();

// TODO: proper matching so we can be sure that it's the only viable send_xcm before we
// attempt and thus can acceptably consume dest & xcm.
let err = Err(SendError::CannotReachDestination(dest.clone(), xcm.clone()));

let devolved = match ensure_is_remote(Ancestry::get(), dest.clone()) {
Ok(x) => x,
Err(dest) => return err,
};
let (remote_network, remote_location, local_network, local_location) = devolved;

let mut inner_xcm: Xcm<()> = vec![
UniversalOrigin(GlobalConsensus(local_network)),
DescendOrigin(local_location),
].into();
inner_xcm.inner_mut().extend(xcm.into_iter());

let message = Xcm(vec![
/* WithdrawAsset((Here, )),
BuyExecution { fees: Wild(AllCounted(1)), weight_limit: Unlimited },
DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() },
*/ ExportMessage { network: remote_network, destination: remote_location, xcm: inner_xcm },
]);
let dest = dest.into();
let pre = match Executer::prepare(message) {
Ok(x) => x,
Err(_) => return err,
};
// We just swallow the weight - it should be constant.
let weight_credit = pre.weight_of();
match Executer::execute(Here, pre, weight_credit) {
Outcome::Complete(_) => Ok(()),
_ => return err,
}
}
}

// TODO: LocalPaidExecutingExporter able to accept from non-Here origins.
// TODO: RemotePaidExecutingExporter which uses `SendXcm`.
}
32 changes: 19 additions & 13 deletions xcm/xcm-executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,36 @@ pub struct XcmExecutor<Config: config::Config> {
_config: PhantomData<Config>,
}

pub struct WeighedMessage<Call>(Weight, Xcm<Call>);
impl<C> PreparedMessage for WeighedMessage<C> {
fn weight_of(&self) -> Weight {
self.0
}
}

impl<Config: config::Config> ExecuteXcm<Config::Call> for XcmExecutor<Config> {
fn execute_xcm_in_credit(
origin: impl Into<MultiLocation>,
type Prepared = WeighedMessage<Config::Call>;
fn prepare(
mut message: Xcm<Config::Call>,
weight_limit: Weight,
) -> Result<Self::Prepared, Xcm<Config::Call>> {
match Config::Weigher::weight(&mut message) {
Ok(weight) => Ok(WeighedMessage(weight, message)),
Err(_) => Err(message),
}
}
fn execute(
origin: impl Into<MultiLocation>,
WeighedMessage(xcm_weight, mut message): WeighedMessage<Config::Call>,
mut weight_credit: Weight,
) -> Outcome {
let origin = origin.into();
log::trace!(
target: "xcm::execute_xcm_in_credit",
"origin: {:?}, message: {:?}, weight_limit: {:?}, weight_credit: {:?}",
"origin: {:?}, message: {:?}, weight_credit: {:?}",
origin,
message,
weight_limit,
weight_credit,
);
let xcm_weight = match Config::Weigher::weight(&mut message) {
Ok(x) => x,
Err(()) => return Outcome::Error(XcmError::WeightNotComputable),
};
if xcm_weight > weight_limit {
return Outcome::Error(XcmError::WeightLimitReached(xcm_weight))
}

if let Err(_) =
Config::Barrier::should_execute(&origin, &mut message, xcm_weight, &mut weight_credit)
{
Expand Down