From 7bac2e44f5861eb2da7eb820a3e14c1beb15b9ca Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 1 Apr 2021 22:12:37 +0200 Subject: [PATCH 01/40] Remove unused relaying XCM --- xcm/src/v0/mod.rs | 32 +++++--------------------------- xcm/xcm-executor/src/lib.rs | 16 ---------------- 2 files changed, 5 insertions(+), 43 deletions(-) diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index c69093d4f851..fa0ce016f7be 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -17,7 +17,7 @@ //! Version 0 of the Cross-Consensus Message format data structures. use core::{result, convert::TryFrom}; -use alloc::{boxed::Box, vec::Vec}; +use alloc::vec::Vec; use parity_scale_codec::{self, Encode, Decode}; use super::{VersionedXcm, VersionedMultiAsset}; @@ -131,33 +131,11 @@ pub enum Xcm { /// Errors: Transact { origin_type: OriginKind, call: Vec }, - /// Relay an inner message (`inner`) to a locally reachable destination ID `dest`. - /// - /// The message sent to the destination will be wrapped into a `RelayedFrom` message, with the - /// `superorigin` being this location. - /// - /// - `dest: MultiLocation`: The location of the to be relayed into. This may never contain `Parent`, and - /// it must be immediately reachable from the interpreting context. - /// - `inner: VersionedXcm`: The message to be wrapped and relayed. - /// - /// Safety: No concerns. - /// - /// Kind: *Instruction*. - /// - /// Errors: - RelayTo { dest: MultiLocation, inner: Box }, + /// Unused + Unused5, - /// A message (`inner`) was sent to `origin` from `superorigin` with the intention of being relayed. - /// - /// - `superorigin`: The location of the `inner` message origin, **relative to `origin`**. - /// - `inner`: The message sent by the super origin. - /// - /// Safety: `superorigin` must express a sub-consensus only; it may *NEVER* contain a `Parent` junction. - /// - /// Kind: *Trusted Indication*. - /// - /// Errors: - RelayedFrom { superorigin: MultiLocation, inner: Box }, + /// Unused + Unused6, /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the /// relay-chain to a para. diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 2c10a447965a..0967fa1b9041 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -37,18 +37,6 @@ pub struct XcmExecutor(PhantomData); impl ExecuteXcm for XcmExecutor { fn execute_xcm(origin: MultiLocation, msg: Xcm) -> XcmResult { let (mut holding, effects) = match (origin.clone(), msg) { - (origin, Xcm::RelayedFrom { superorigin, inner }) => { - // We ensure that it doesn't contain any `Parent` Junctions which would imply a privilege escalation. - let mut new_origin = origin; - for j in superorigin.into_iter() { - ensure!(j.is_sub_consensus(), XcmError::EscalationOfPrivilege); - new_origin.push(j).map_err(|_| XcmError::MultiLocationFull)?; - } - return Self::execute_xcm( - new_origin, - (*inner).try_into().map_err(|_| XcmError::UnhandledXcmVersion)? - ) - } (origin, Xcm::WithdrawAsset { assets, effects }) => { // Take `assets` from the origin account (on-chain) and place in holding. let mut holding = Assets::default(); @@ -95,10 +83,6 @@ impl ExecuteXcm for XcmExecutor { // message makes sense. return Ok(()); } - (origin, Xcm::RelayTo { dest: MultiLocation::X1(Junction::Parachain { id }), inner }) => { - let msg = Xcm::RelayedFrom { superorigin: origin, inner }.into(); - return Config::XcmSender::send_xcm(Junction::Parachain { id }.into(), msg) - }, _ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message. }; From f2929f66f5b8f1e57ece0717d1426b7d59a1cdd4 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 31 Mar 2021 22:52:39 +0200 Subject: [PATCH 02/40] Aggregate HRMP (XCMP/HMP) messages. Payloads for spambot. --- Cargo.lock | 840 +++++++++++++++-------------------------------------- 1 file changed, 236 insertions(+), 604 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49ee4697f8bd..5eb09f7d03aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,20 +310,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "async-std-resolver" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665c56111e244fe38e7708ee10948a4356ad6a548997c21f5a63a0f4e0edc4d" -dependencies = [ - "async-std", - "async-trait", - "futures-io", - "futures-util", - "pin-utils", - "trust-dns-resolver", -] - [[package]] name = "async-task" version = "4.0.3" @@ -443,67 +429,6 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "beefy-gadget" -version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" -dependencies = [ - "beefy-primitives", - "futures 0.3.13", - "hex", - "log", - "parity-scale-codec", - "parking_lot 0.11.1", - "sc-client-api", - "sc-keystore", - "sc-network", - "sc-network-gossip", - "sp-api", - "sp-application-crypto", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-keystore", - "sp-runtime", - "sp-utils", - "substrate-prometheus-endpoint", - "thiserror", -] - -[[package]] -name = "beefy-gadget-rpc" -version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" -dependencies = [ - "beefy-gadget", - "beefy-primitives", - "futures 0.3.13", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "jsonrpc-pubsub", - "log", - "parity-scale-codec", - "sc-rpc", - "serde", - "serde_json", - "sp-core", - "sp-runtime", -] - -[[package]] -name = "beefy-primitives" -version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" -dependencies = [ - "parity-scale-codec", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-runtime", - "sp-std", -] - [[package]] name = "bincode" version = "1.3.1" @@ -911,15 +836,6 @@ dependencies = [ "generic-array 0.14.4", ] -[[package]] -name = "ckb-merkle-mountain-range" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e486fe53bb9f2ca0f58cb60e8679a5354fd6687a839942ef0a75967250289ca6" -dependencies = [ - "cfg-if 0.1.10", -] - [[package]] name = "clang-sys" version = "0.29.3" @@ -1475,18 +1391,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f" -[[package]] -name = "enum-as-inner" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "enumflags2" version = "0.6.4" @@ -1754,7 +1658,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", ] @@ -1772,7 +1676,7 @@ dependencies = [ [[package]] name = "frame-benchmarking" version = "3.1.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -1791,7 +1695,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "Inflector", "chrono", @@ -1814,7 +1718,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -1827,7 +1731,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -1843,7 +1747,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "13.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "serde", @@ -1854,7 +1758,7 @@ dependencies = [ [[package]] name = "frame-support" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "bitflags", "frame-metadata", @@ -1880,7 +1784,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "Inflector", "frame-support-procedural-tools", @@ -1892,7 +1796,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 1.0.0", @@ -1904,7 +1808,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "proc-macro2", "quote", @@ -1914,7 +1818,7 @@ dependencies = [ [[package]] name = "frame-support-test" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-metadata", "frame-support", @@ -1935,7 +1839,7 @@ dependencies = [ [[package]] name = "frame-system" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -1952,7 +1856,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -1966,7 +1870,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-api", @@ -1975,7 +1879,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "parity-scale-codec", @@ -2480,17 +2384,6 @@ dependencies = [ "hmac 0.7.1", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - [[package]] name = "http" version = "0.1.21" @@ -2609,7 +2502,7 @@ dependencies = [ "httpdate", "itoa", "pin-project 1.0.4", - "socket2 0.3.17", + "socket2", "tokio 0.2.21", "tower-service", "tracing", @@ -2679,9 +2572,9 @@ dependencies = [ [[package]] name = "if-watch" -version = "0.2.0" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6d52908d4ea4ab2bc22474ba149bf1011c8e2c3ebc1ff593ae28ac44f494b6" +checksum = "97b8538953a3f0d0d3868f0a706eb4273535e10d72acb5c82c1c23ae48835c85" dependencies = [ "async-io", "futures 0.3.13", @@ -2796,18 +2689,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ee15951c035f79eddbef745611ec962f63f4558f1dadf98ab723cc603487c6f" -[[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2 0.3.17", - "widestring", - "winapi 0.3.9", - "winreg", -] - [[package]] name = "ipnet" version = "2.3.0" @@ -3078,9 +2959,8 @@ dependencies = [ [[package]] name = "kusama-runtime" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "beefy-primitives", "bitvec", "frame-benchmarking", "frame-executive", @@ -3106,7 +2986,6 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", - "pallet-mmr-primitives", "pallet-multisig", "pallet-nicks", "pallet-offences", @@ -3144,7 +3023,6 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", - "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", @@ -3266,9 +3144,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.36.0" +version = "0.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5759b526f75102829c15e4d8566603b4bf502ed19b5f35920d98113873470d" +checksum = "adc225a49973cf9ab10d0cdd6a4b8f0cda299df9b760824bbb623f15f8f0c95a" dependencies = [ "atomic", "bytes 1.0.1", @@ -3287,7 +3165,6 @@ dependencies = [ "libp2p-ping", "libp2p-plaintext", "libp2p-pnet", - "libp2p-relay", "libp2p-request-response", "libp2p-swarm", "libp2p-swarm-derive", @@ -3305,9 +3182,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.28.1" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e1797734bbd4c453664fefb029628f77c356ffc5bce98f06b18a7db3ebb0f7" +checksum = "8a2d56aadc2c2bf22cd7797f86e56a65b5b3994a0136b65be3106938acae7a26" dependencies = [ "asn1_der", "bs58", @@ -3339,9 +3216,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.28.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2181a641cd15f9b6ba71b1335800f309012a0a97a29ffaabbbf40e9d3d58f08" +checksum = "6d42eed63305f0420736fa487f9acef720c4528bd7852a6a760f5ccde4813345" dependencies = [ "flate2", "futures 0.3.13", @@ -3350,23 +3227,20 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9712eb3e9f7dcc77cc5ca7d943b6a85ce4b1faaf91a67e003442412a26d6d6f8" +checksum = "5153b6db68fd4baa3b304e377db744dd8fea8ff4e4504509ee636abcde88d3e3" dependencies = [ - "async-std-resolver", "futures 0.3.13", "libp2p-core", "log", - "smallvec 1.6.1", - "trust-dns-resolver", ] [[package]] name = "libp2p-floodsub" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897645f99e9b396df256a6aa8ba8c4bc019ac6b7c62556f624b5feea9acc82bb" +checksum = "b3c63dfa06581b24b1d12bf9815b43689a784424be217d6545c800c7c75a207f" dependencies = [ "cuckoofilter", "fnv", @@ -3382,9 +3256,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.29.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794b0c85f5df1acbc1fc38414d37272594811193b6325c76d3931c3e3f5df8c0" +checksum = "502dc5fcbfec4aa1c63ef3f7307ffe20e90c1a1387bf23ed0bec087f2dde58a1" dependencies = [ "asynchronous-codec 0.6.0", "base64 0.13.0", @@ -3408,9 +3282,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88ebc841d744979176ab4b8b294a3e655a7ba4ef26a905d073a52b49ed4dff5" +checksum = "b40fb36a059b7a8cce1514bd8b546fa612e006c9937caa7f5950cb20021fe91e" dependencies = [ "futures 0.3.13", "libp2p-core", @@ -3424,9 +3298,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.29.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb5b90b6bda749023a85f60b49ea74b387c25f17d8df541ae72a3c75dd52e63" +checksum = "cf3da6c9acbcc05f93235d201d7d45ef4e8b88a45d8836f98becd8b4d443f066" dependencies = [ "arrayvec 0.5.2", "asynchronous-codec 0.6.0", @@ -3450,9 +3324,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.29.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be28ca13bb648d249a9baebd750ebc64ce7040ddd5f0ce1035ff1f4549fb596d" +checksum = "0e9e6374814d1b118d97ccabdfc975c8910bd16dc38a8bc058eeb08bf2080fe1" dependencies = [ "async-io", "data-encoding", @@ -3463,17 +3337,17 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "rand 0.8.3", + "rand 0.7.3", "smallvec 1.6.1", - "socket2 0.4.0", + "socket2", "void", ] [[package]] name = "libp2p-mplex" -version = "0.28.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e9b544335d1ed30af71daa96edbefadef6f19c7a55f078b9fc92c87163105d" +checksum = "350ce8b3923594aedabd5d6e3f875d058435052a29c3f32df378bc70d10be464" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.0.1", @@ -3489,9 +3363,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.30.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36db0f0db3b0433f5b9463f1c0cd9eadc0a3734a9170439ce501ff99733a88bd" +checksum = "4aca322b52a0c5136142a7c3971446fb1e9964923a526c9cc6ef3b7c94e57778" dependencies = [ "bytes 1.0.1", "curve25519-dalek 3.0.0", @@ -3511,9 +3385,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea10fc5209260915ea65b78f612d7ff78a29ab288e7aa3250796866af861c45" +checksum = "6f3813276d0708c8db0f500d8beda1bda9ad955723b9cb272c41f4727256f73c" dependencies = [ "futures 0.3.13", "libp2p-core", @@ -3526,9 +3400,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.28.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8c37b4d2a075b4be8442760a5f8c037180f0c8dd5b5734b9978ab868b3aa11" +checksum = "9d58defcadb646ae4b033e130b48d87410bf76394dc3335496cae99dac803e61" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.0.1", @@ -3555,34 +3429,11 @@ dependencies = [ "sha3", ] -[[package]] -name = "libp2p-relay" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff268be6a9d6f3c6cca3b81bbab597b15217f9ad8787c6c40fc548c1af7cd24" -dependencies = [ - "asynchronous-codec 0.6.0", - "bytes 1.0.1", - "futures 0.3.13", - "futures-timer 3.0.2", - "libp2p-core", - "libp2p-swarm", - "log", - "pin-project 1.0.4", - "prost", - "prost-build", - "rand 0.7.3", - "smallvec 1.6.1", - "unsigned-varint 0.7.0", - "void", - "wasm-timer", -] - [[package]] name = "libp2p-request-response" -version = "0.10.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725367dd2318c54c5ab1a6418592e5b01c63b0dedfbbfb8389220b2bcf691899" +checksum = "10e5552827c33d8326502682da73a0ba4bfa40c1b55b216af3c303f32169dd89" dependencies = [ "async-trait", "bytes 1.0.1", @@ -3600,9 +3451,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.28.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c26980cadd7c25d89071cb23e1f7f5df4863128cc91d83c6ddc72338cecafa" +checksum = "7955b973e1fd2bd61ffd43ce261c1223f61f4aacd5bae362a924993f9a25fd98" dependencies = [ "either", "futures 0.3.13", @@ -3626,9 +3477,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.28.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b1a27d21c477951799e99d5c105d78868258502ce092988040a808d5a19bbd9" +checksum = "88a5aef80e519a6cb8e2663605142f97baaaea1a252eecbf8756184765f7471b" dependencies = [ "async-io", "futures 0.3.13", @@ -3638,14 +3489,14 @@ dependencies = [ "libc", "libp2p-core", "log", - "socket2 0.4.0", + "socket2", ] [[package]] name = "libp2p-uds" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffd6564bb3b7ff203661ccbb69003c2b551e34cef974f2d6c6a28306a12170b5" +checksum = "80ac51ce419f60be966e02103c17f67ff5dc4422ba83ba54d251d6c62a4ed487" dependencies = [ "async-std", "futures 0.3.13", @@ -3655,9 +3506,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6df65fc13f6188edf7e6927b086330448b3ca27af86b49748c6d299d7c8d9040" +checksum = "6149c46cb76935c80bc8be6ec6e3ebd5f5e1679765a255fb34331d54610f15dd" dependencies = [ "futures 0.3.13", "js-sys", @@ -3669,9 +3520,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.29.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cace60995ef6f637e4752cccbb2590f6bc358e8741a0d066307636c69a4b3a74" +checksum = "d3b1c6a3431045da8b925ed83384e4c5163e14b990572307fca9c507435d4d22" dependencies = [ "either", "futures 0.3.13", @@ -3687,9 +3538,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.31.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d6144cc94143fb0a8dd1e7c2fbcc32a2808168bcd1d69920635424d5993b7b" +checksum = "4819358c542a86ff95f6ae691efb4b94ddaf477079b01a686f5705b79bfc232a" dependencies = [ "futures 0.3.13", "libp2p-core", @@ -3813,15 +3664,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "mach" version = "0.3.2" @@ -3837,12 +3679,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "matchers" version = "0.0.1" @@ -3967,9 +3803,9 @@ dependencies = [ [[package]] name = "minicbor" -version = "0.8.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea79ce4ab9f445ec6b71833a2290ac0a29c9dde0fa7cae4c481eecae021d9bd9" +checksum = "1c2b2c73f9640fccab53947e2b3474d5071fcbc8f82cac51ddf6c8041a30a9ea" dependencies = [ "minicbor-derive", ] @@ -4066,7 +3902,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" dependencies = [ - "socket2 0.3.17", + "socket2", "winapi 0.3.9", ] @@ -4362,7 +4198,7 @@ checksum = "13370dae44474229701bb69b90b4f4dca6404cb0357a2d50d635f1171dc3aa7b" [[package]] name = "pallet-authority-discovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4378,7 +4214,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4393,7 +4229,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4417,7 +4253,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4429,25 +4265,10 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-beefy" -version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" -dependencies = [ - "beefy-primitives", - "frame-support", - "frame-system", - "pallet-session", - "parity-scale-codec", - "serde", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-bounties" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4462,7 +4283,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4479,7 +4300,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4494,7 +4315,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -4515,7 +4336,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4531,7 +4352,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4553,7 +4374,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4569,7 +4390,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4589,7 +4410,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4606,7 +4427,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4617,62 +4438,10 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-mmr" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" -dependencies = [ - "ckb-merkle-mountain-range", - "frame-benchmarking", - "frame-support", - "frame-system", - "pallet-mmr-primitives", - "parity-scale-codec", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-mmr-primitives" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" -dependencies = [ - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "serde", - "sp-api", - "sp-core", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-mmr-rpc" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" -dependencies = [ - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "pallet-mmr-primitives", - "parity-scale-codec", - "serde", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-rpc", - "sp-runtime", -] - [[package]] name = "pallet-multisig" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4688,7 +4457,7 @@ dependencies = [ [[package]] name = "pallet-nicks" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4702,7 +4471,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4718,7 +4487,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -4740,7 +4509,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4756,7 +4525,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4769,7 +4538,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "enumflags2", "frame-support", @@ -4784,7 +4553,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4800,7 +4569,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4820,7 +4589,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4836,7 +4605,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4850,7 +4619,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -4865,6 +4634,7 @@ dependencies = [ "serde", "sp-application-crypto", "sp-io", + "sp-npos-elections", "sp-runtime", "sp-staking", "sp-std", @@ -4874,7 +4644,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -4885,7 +4655,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4899,7 +4669,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4918,7 +4688,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4933,7 +4703,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-support", "frame-system", @@ -4949,7 +4719,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4966,7 +4736,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -4977,7 +4747,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -4993,7 +4763,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-benchmarking", "frame-support", @@ -5009,7 +4779,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5444,7 +5214,7 @@ checksum = "989d43012e2ca1c4a02507c67282691a0a3207f9dc67cec596b43fe925b3d325" [[package]] name = "polkadot" -version = "0.8.30" +version = "0.8.29" dependencies = [ "assert_cmd", "color-eyre", @@ -5512,7 +5282,6 @@ dependencies = [ "polkadot-erasure-coding", "polkadot-node-core-runtime-api", "polkadot-node-network-protocol", - "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-node-subsystem-util", @@ -5543,7 +5312,6 @@ dependencies = [ "parity-scale-codec", "polkadot-erasure-coding", "polkadot-node-network-protocol", - "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-node-subsystem-util", @@ -5560,7 +5328,7 @@ dependencies = [ [[package]] name = "polkadot-cli" -version = "0.8.30" +version = "0.8.29" dependencies = [ "frame-benchmarking-cli", "futures 0.3.13", @@ -5605,7 +5373,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" -version = "0.8.30" +version = "0.7.30" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -5616,10 +5384,9 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" -version = "0.8.30" +version = "0.8.29" dependencies = [ "parity-scale-codec", - "polkadot-node-primitives", "polkadot-primitives", "reed-solomon-novelpoly", "sp-core", @@ -5636,10 +5403,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-api", - "sp-application-crypto", - "sp-authority-discovery", - "sp-keystore", + "rand 0.8.3", "tracing", ] @@ -5650,7 +5414,6 @@ dependencies = [ "assert_matches", "async-trait", "futures 0.3.13", - "futures-timer 3.0.2", "parity-scale-codec", "parking_lot 0.11.1", "polkadot-node-network-protocol", @@ -5660,7 +5423,6 @@ dependencies = [ "polkadot-primitives", "sc-authority-discovery", "sc-network", - "sp-consensus", "sp-core", "sp-keyring", "strum", @@ -5694,6 +5456,7 @@ dependencies = [ "futures-timer 3.0.2", "kvdb", "kvdb-memorydb", + "kvdb-rocksdb", "maplit", "merlin", "parity-scale-codec", @@ -5711,7 +5474,6 @@ dependencies = [ "schnorrkel", "sp-application-crypto", "sp-blockchain", - "sp-consensus", "sp-consensus-babe", "sp-consensus-slots", "sp-core", @@ -5732,16 +5494,17 @@ dependencies = [ "futures-timer 3.0.2", "kvdb", "kvdb-memorydb", + "kvdb-rocksdb", "log", "parity-scale-codec", "parking_lot 0.11.1", "polkadot-erasure-coding", - "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", + "sc-service", "sp-core", "sp-keyring", "thiserror", @@ -5905,7 +5668,6 @@ dependencies = [ "mick-jaeger", "parity-scale-codec", "parking_lot 0.11.1", - "polkadot-node-primitives", "polkadot-primitives", "sc-network", "sp-core", @@ -5932,18 +5694,15 @@ version = "0.1.0" dependencies = [ "futures 0.3.13", "parity-scale-codec", - "polkadot-parachain", "polkadot-primitives", "polkadot-statement-table", "schnorrkel", - "serde", "sp-application-crypto", "sp-consensus-babe", "sp-consensus-vrf", "sp-core", "sp-runtime", "thiserror", - "zstd", ] [[package]] @@ -6019,7 +5778,6 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-primitives", - "rand 0.8.3", "sc-network", "sp-application-crypto", "sp-core", @@ -6052,7 +5810,7 @@ dependencies = [ [[package]] name = "polkadot-parachain" -version = "0.8.30" +version = "0.8.29" dependencies = [ "derive_more", "futures 0.3.13", @@ -6078,7 +5836,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" -version = "0.8.30" +version = "0.8.29" dependencies = [ "bitvec", "frame-system", @@ -6104,6 +5862,7 @@ dependencies = [ "sp-trie", "sp-version", "thiserror", + "zstd", ] [[package]] @@ -6119,12 +5878,9 @@ dependencies = [ [[package]] name = "polkadot-rpc" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "beefy-gadget", - "beefy-gadget-rpc", "jsonrpc-core", - "pallet-mmr-rpc", "pallet-transaction-payment-rpc", "parity-scale-codec", "polkadot-primitives", @@ -6151,9 +5907,8 @@ dependencies = [ [[package]] name = "polkadot-runtime" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "beefy-primitives", "bitvec", "frame-benchmarking", "frame-executive", @@ -6179,7 +5934,6 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", - "pallet-mmr-primitives", "pallet-multisig", "pallet-nicks", "pallet-offences", @@ -6215,7 +5969,6 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", - "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", @@ -6232,9 +5985,8 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "beefy-primitives", "bitvec", "frame-benchmarking", "frame-support", @@ -6247,8 +5999,6 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", - "pallet-beefy", - "pallet-mmr", "pallet-offences", "pallet-randomness-collective-flip", "pallet-session", @@ -6284,7 +6034,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" -version = "0.8.30" +version = "0.8.0" dependencies = [ "bitvec", "derive_more", @@ -6335,21 +6085,16 @@ dependencies = [ [[package]] name = "polkadot-service" -version = "0.8.30" +version = "0.8.3" dependencies = [ - "beefy-gadget", - "beefy-primitives", "env_logger 0.8.2", "frame-benchmarking", "frame-system-rpc-runtime-api", "futures 0.3.13", "hex-literal", "kusama-runtime", - "kvdb", - "kvdb-rocksdb", "pallet-babe", "pallet-im-online", - "pallet-mmr-primitives", "pallet-staking", "pallet-transaction-payment-rpc-runtime-api", "polkadot-approval-distribution", @@ -6370,7 +6115,6 @@ dependencies = [ "polkadot-node-core-proposer", "polkadot-node-core-provisioner", "polkadot-node-core-runtime-api", - "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-overseer", @@ -6448,7 +6192,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" -version = "0.8.30" +version = "0.8.29" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -6457,9 +6201,8 @@ dependencies = [ [[package]] name = "polkadot-test-client" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "futures 0.3.13", "parity-scale-codec", "polkadot-node-subsystem", "polkadot-primitives", @@ -6483,9 +6226,8 @@ dependencies = [ [[package]] name = "polkadot-test-runtime" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "beefy-primitives", "bitvec", "frame-election-provider-support", "frame-executive", @@ -6501,7 +6243,6 @@ dependencies = [ "pallet-balances", "pallet-grandpa", "pallet-indices", - "pallet-mmr-primitives", "pallet-nicks", "pallet-offences", "pallet-randomness-collective-flip", @@ -6545,7 +6286,7 @@ dependencies = [ [[package]] name = "polkadot-test-service" -version = "0.8.30" +version = "0.8.29" dependencies = [ "frame-benchmarking", "frame-system", @@ -7113,9 +6854,9 @@ dependencies = [ [[package]] name = "reed-solomon-novelpoly" -version = "1.0.0" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd8f48b2066e9f69ab192797d66da804d1935bf22763204ed3675740cb0f221" +checksum = "f11e01a8ef53ec033daf53a9385a1d0bb266155797919096e4134118f45efe82" dependencies = [ "derive_more", "fs-err", @@ -7198,7 +6939,7 @@ dependencies = [ [[package]] name = "remote-externalities" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "env_logger 0.8.2", "hex-literal", @@ -7221,16 +6962,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error 1.2.3", -] - [[package]] name = "retain_mut" version = "0.1.2" @@ -7274,9 +7005,8 @@ dependencies = [ [[package]] name = "rococo-runtime" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "beefy-primitives", "frame-executive", "frame-support", "frame-system", @@ -7287,12 +7017,9 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", - "pallet-beefy", "pallet-grandpa", "pallet-im-online", "pallet-indices", - "pallet-mmr", - "pallet-mmr-primitives", "pallet-offences", "pallet-proxy", "pallet-session", @@ -7471,7 +7198,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "async-trait", "derive_more", @@ -7499,7 +7226,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "futures-timer 3.0.2", @@ -7522,7 +7249,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -7538,7 +7265,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7559,7 +7286,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -7570,7 +7297,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "chrono", "fdlimit", @@ -7608,7 +7335,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "fnv", @@ -7642,7 +7369,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "blake2-rfc", "hash-db", @@ -7672,9 +7399,8 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ - "parking_lot 0.11.1", "sc-client-api", "sp-blockchain", "sp-consensus", @@ -7684,9 +7410,8 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ - "async-trait", "derive_more", "fork-tree", "futures 0.3.13", @@ -7731,7 +7456,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "futures 0.3.13", @@ -7755,12 +7480,12 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "fork-tree", "parity-scale-codec", + "parking_lot 0.11.1", "sc-client-api", - "sc-consensus", "sp-blockchain", "sp-runtime", ] @@ -7768,13 +7493,13 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ - "async-trait", "futures 0.3.13", "futures-timer 3.0.2", "log", "parity-scale-codec", + "parking_lot 0.11.1", "sc-client-api", "sc-telemetry", "sp-api", @@ -7795,7 +7520,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "sc-client-api", @@ -7809,7 +7534,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "lazy_static", @@ -7838,7 +7563,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "parity-scale-codec", @@ -7854,7 +7579,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "parity-scale-codec", @@ -7869,7 +7594,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "parity-scale-codec", @@ -7887,9 +7612,8 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ - "async-trait", "derive_more", "dyn-clone", "finality-grandpa", @@ -7927,7 +7651,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "finality-grandpa", @@ -7951,7 +7675,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-warp-sync" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "futures 0.3.13", @@ -7972,7 +7696,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "ansi_term 0.12.1", "futures 0.3.13", @@ -7990,7 +7714,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "async-trait", "derive_more", @@ -8010,7 +7734,7 @@ dependencies = [ [[package]] name = "sc-light" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "hash-db", "lazy_static", @@ -8029,7 +7753,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "async-std", "async-trait", @@ -8082,7 +7806,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "futures-timer 3.0.2", @@ -8099,7 +7823,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "bytes 0.5.6", "fnv", @@ -8127,7 +7851,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "libp2p", @@ -8140,7 +7864,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -8149,7 +7873,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "hash-db", @@ -8183,7 +7907,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "futures 0.3.13", @@ -8207,7 +7931,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.1.29", "jsonrpc-core", @@ -8225,9 +7949,8 @@ dependencies = [ [[package]] name = "sc-service" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ - "async-trait", "directories", "exit-future", "futures 0.1.29", @@ -8289,7 +8012,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "parity-scale-codec", @@ -8304,7 +8027,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -8324,7 +8047,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "chrono", "futures 0.3.13", @@ -8344,7 +8067,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "ansi_term 0.12.1", "atty", @@ -8371,7 +8094,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -8382,7 +8105,7 @@ dependencies = [ [[package]] name = "sc-transaction-graph" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "futures 0.3.13", @@ -8404,7 +8127,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "futures-diagnose", @@ -8594,18 +8317,18 @@ checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" [[package]] name = "serde" -version = "1.0.125" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" dependencies = [ "proc-macro2", "quote", @@ -8614,9 +8337,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" dependencies = [ "itoa", "ryu", @@ -8791,16 +8514,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "socket2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" -dependencies = [ - "libc", - "winapi 0.3.9", -] - [[package]] name = "soketto" version = "0.4.1" @@ -8820,7 +8533,7 @@ dependencies = [ [[package]] name = "sp-allocator" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "sp-core", @@ -8832,7 +8545,7 @@ dependencies = [ [[package]] name = "sp-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "hash-db", "log", @@ -8849,7 +8562,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "blake2-rfc", "proc-macro-crate 1.0.0", @@ -8861,7 +8574,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "serde", @@ -8873,7 +8586,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "integer-sqrt", "num-traits", @@ -8886,7 +8599,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-api", @@ -8898,7 +8611,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -8909,7 +8622,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-api", @@ -8921,7 +8634,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "log", @@ -8939,7 +8652,7 @@ dependencies = [ [[package]] name = "sp-chain-spec" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "serde", "serde_json", @@ -8948,9 +8661,8 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ - "async-trait", "futures 0.3.13", "futures-timer 3.0.2", "libp2p", @@ -8975,7 +8687,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "merlin", "parity-scale-codec", @@ -8996,7 +8708,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-arithmetic", @@ -9006,7 +8718,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -9018,7 +8730,7 @@ dependencies = [ [[package]] name = "sp-core" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "base58", "blake2-rfc", @@ -9062,7 +8774,7 @@ dependencies = [ [[package]] name = "sp-database" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "kvdb", "parking_lot 0.11.1", @@ -9071,7 +8783,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "proc-macro2", "quote", @@ -9081,7 +8793,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "environmental", "parity-scale-codec", @@ -9092,7 +8804,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "finality-grandpa", "log", @@ -9109,7 +8821,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "parking_lot 0.11.1", @@ -9121,7 +8833,7 @@ dependencies = [ [[package]] name = "sp-io" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "hash-db", @@ -9145,7 +8857,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "lazy_static", "sp-core", @@ -9156,7 +8868,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "async-trait", "derive_more", @@ -9173,7 +8885,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "serde", @@ -9186,7 +8898,7 @@ dependencies = [ [[package]] name = "sp-npos-elections-compact" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -9197,7 +8909,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "sp-api", "sp-core", @@ -9207,7 +8919,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "backtrace", ] @@ -9215,7 +8927,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "serde", "sp-core", @@ -9224,7 +8936,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "either", "hash256-std-hasher", @@ -9245,7 +8957,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -9262,7 +8974,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "Inflector", "proc-macro-crate 1.0.0", @@ -9274,7 +8986,7 @@ dependencies = [ [[package]] name = "sp-serializer" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "serde", "serde_json", @@ -9283,7 +8995,7 @@ dependencies = [ [[package]] name = "sp-session" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-api", @@ -9296,7 +9008,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -9306,7 +9018,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "hash-db", "log", @@ -9328,12 +9040,12 @@ dependencies = [ [[package]] name = "sp-std" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" [[package]] name = "sp-storage" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "impl-serde", "parity-scale-codec", @@ -9346,7 +9058,7 @@ dependencies = [ [[package]] name = "sp-tasks" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "sp-core", @@ -9359,7 +9071,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "parity-scale-codec", "sp-api", @@ -9372,7 +9084,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "log", "parity-scale-codec", @@ -9385,7 +9097,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "derive_more", "futures 0.3.13", @@ -9401,7 +9113,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "hash-db", "memory-db", @@ -9415,7 +9127,7 @@ dependencies = [ [[package]] name = "sp-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "futures-core", @@ -9427,7 +9139,7 @@ dependencies = [ [[package]] name = "sp-version" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "impl-serde", "parity-scale-codec", @@ -9439,7 +9151,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -9596,7 +9308,7 @@ dependencies = [ [[package]] name = "substrate-browser-utils" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "chrono", "console_error_panic_hook", @@ -9622,7 +9334,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "platforms", ] @@ -9630,7 +9342,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.13", @@ -9653,7 +9365,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "async-std", "derive_more", @@ -9667,9 +9379,8 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.1" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ - "async-trait", "futures 0.1.29", "futures 0.3.13", "hash-db", @@ -9696,7 +9407,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "futures 0.3.13", "substrate-test-utils-derive", @@ -9706,7 +9417,7 @@ dependencies = [ [[package]] name = "substrate-test-utils-derive" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "proc-macro-crate 1.0.0", "quote", @@ -9807,7 +9518,7 @@ dependencies = [ [[package]] name = "test-parachain-adder" -version = "0.8.30" +version = "0.8.29" dependencies = [ "dlmalloc", "parity-scale-codec", @@ -9820,7 +9531,7 @@ dependencies = [ [[package]] name = "test-parachain-adder-collator" -version = "0.8.30" +version = "0.7.26" dependencies = [ "futures 0.3.13", "futures-timer 3.0.2", @@ -9846,14 +9557,14 @@ dependencies = [ [[package]] name = "test-parachain-halt" -version = "0.8.30" +version = "0.8.29" dependencies = [ "substrate-wasm-builder", ] [[package]] name = "test-parachains" -version = "0.8.30" +version = "0.7.22" dependencies = [ "parity-scale-codec", "polkadot-parachain", @@ -9966,21 +9677,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" -[[package]] -name = "tinyvec" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - [[package]] name = "tokio" version = "0.1.22" @@ -10395,49 +10091,6 @@ dependencies = [ "hash-db", ] -[[package]] -name = "trust-dns-proto" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d57e219ba600dd96c2f6d82eb79645068e14edbc5c7e27514af40436b88150c" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.0", - "ipnet", - "lazy_static", - "log", - "rand 0.8.3", - "smallvec 1.6.1", - "thiserror", - "tinyvec 1.1.1", - "url 2.2.0", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0437eea3a6da51acc1e946545ff53d5b8fb2611ff1c3bed58522dde100536ae" -dependencies = [ - "cfg-if 1.0.0", - "futures-util", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "parking_lot 0.11.1", - "resolv-conf", - "smallvec 1.6.1", - "thiserror", - "trust-dns-proto", -] - [[package]] name = "try-lock" version = "0.2.2" @@ -10447,7 +10100,7 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "try-runtime-cli" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" dependencies = [ "frame-try-runtime", "log", @@ -10537,7 +10190,7 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ - "tinyvec 0.3.3", + "tinyvec", ] [[package]] @@ -11093,9 +10746,8 @@ dependencies = [ [[package]] name = "westend-runtime" -version = "0.8.30" +version = "0.8.29" dependencies = [ - "beefy-primitives", "bitvec", "frame-benchmarking", "frame-executive", @@ -11111,7 +10763,6 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", - "pallet-beefy", "pallet-collective", "pallet-democracy", "pallet-election-provider-multi-phase", @@ -11121,8 +10772,6 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", - "pallet-mmr", - "pallet-mmr-primitives", "pallet-multisig", "pallet-nicks", "pallet-offences", @@ -11161,7 +10810,6 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", - "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", @@ -11194,12 +10842,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - [[package]] name = "winapi" version = "0.2.8" @@ -11243,15 +10885,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -11292,17 +10925,16 @@ dependencies = [ [[package]] name = "xcm" -version = "0.8.30" +version = "0.8.22" dependencies = [ "parity-scale-codec", ] [[package]] name = "xcm-builder" -version = "0.8.30" +version = "0.8.22" dependencies = [ "frame-support", - "impl-trait-for-tuples", "parity-scale-codec", "polkadot-parachain", "sp-arithmetic", @@ -11315,7 +10947,7 @@ dependencies = [ [[package]] name = "xcm-executor" -version = "0.8.30" +version = "0.8.22" dependencies = [ "frame-support", "impl-trait-for-tuples", From 3aae1077ba21e5ce63e0a3b583ad875814d2fd7b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 1 Apr 2021 22:27:18 +0200 Subject: [PATCH 03/40] Revert lock --- Cargo.lock | 840 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 604 insertions(+), 236 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5eb09f7d03aa..49ee4697f8bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,6 +310,20 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "async-std-resolver" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665c56111e244fe38e7708ee10948a4356ad6a548997c21f5a63a0f4e0edc4d" +dependencies = [ + "async-std", + "async-trait", + "futures-io", + "futures-util", + "pin-utils", + "trust-dns-resolver", +] + [[package]] name = "async-task" version = "4.0.3" @@ -429,6 +443,67 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "beefy-gadget" +version = "0.1.0" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" +dependencies = [ + "beefy-primitives", + "futures 0.3.13", + "hex", + "log", + "parity-scale-codec", + "parking_lot 0.11.1", + "sc-client-api", + "sc-keystore", + "sc-network", + "sc-network-gossip", + "sp-api", + "sp-application-crypto", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-utils", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "beefy-gadget-rpc" +version = "0.1.0" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" +dependencies = [ + "beefy-gadget", + "beefy-primitives", + "futures 0.3.13", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "jsonrpc-pubsub", + "log", + "parity-scale-codec", + "sc-rpc", + "serde", + "serde_json", + "sp-core", + "sp-runtime", +] + +[[package]] +name = "beefy-primitives" +version = "0.1.0" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" +dependencies = [ + "parity-scale-codec", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "bincode" version = "1.3.1" @@ -836,6 +911,15 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e486fe53bb9f2ca0f58cb60e8679a5354fd6687a839942ef0a75967250289ca6" +dependencies = [ + "cfg-if 0.1.10", +] + [[package]] name = "clang-sys" version = "0.29.3" @@ -1391,6 +1475,18 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f" +[[package]] +name = "enum-as-inner" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "enumflags2" version = "0.6.4" @@ -1658,7 +1754,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", ] @@ -1676,7 +1772,7 @@ dependencies = [ [[package]] name = "frame-benchmarking" version = "3.1.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -1695,7 +1791,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "Inflector", "chrono", @@ -1718,7 +1814,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -1731,7 +1827,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -1747,7 +1843,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "13.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "serde", @@ -1758,7 +1854,7 @@ dependencies = [ [[package]] name = "frame-support" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "bitflags", "frame-metadata", @@ -1784,7 +1880,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "Inflector", "frame-support-procedural-tools", @@ -1796,7 +1892,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 1.0.0", @@ -1808,7 +1904,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "proc-macro2", "quote", @@ -1818,7 +1914,7 @@ dependencies = [ [[package]] name = "frame-support-test" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-metadata", "frame-support", @@ -1839,7 +1935,7 @@ dependencies = [ [[package]] name = "frame-system" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -1856,7 +1952,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -1870,7 +1966,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-api", @@ -1879,7 +1975,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "parity-scale-codec", @@ -2384,6 +2480,17 @@ dependencies = [ "hmac 0.7.1", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi 0.3.9", +] + [[package]] name = "http" version = "0.1.21" @@ -2502,7 +2609,7 @@ dependencies = [ "httpdate", "itoa", "pin-project 1.0.4", - "socket2", + "socket2 0.3.17", "tokio 0.2.21", "tower-service", "tracing", @@ -2572,9 +2679,9 @@ dependencies = [ [[package]] name = "if-watch" -version = "0.1.8" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b8538953a3f0d0d3868f0a706eb4273535e10d72acb5c82c1c23ae48835c85" +checksum = "6a6d52908d4ea4ab2bc22474ba149bf1011c8e2c3ebc1ff593ae28ac44f494b6" dependencies = [ "async-io", "futures 0.3.13", @@ -2689,6 +2796,18 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ee15951c035f79eddbef745611ec962f63f4558f1dadf98ab723cc603487c6f" +[[package]] +name = "ipconfig" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" +dependencies = [ + "socket2 0.3.17", + "widestring", + "winapi 0.3.9", + "winreg", +] + [[package]] name = "ipnet" version = "2.3.0" @@ -2959,8 +3078,9 @@ dependencies = [ [[package]] name = "kusama-runtime" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "beefy-primitives", "bitvec", "frame-benchmarking", "frame-executive", @@ -2986,6 +3106,7 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", + "pallet-mmr-primitives", "pallet-multisig", "pallet-nicks", "pallet-offences", @@ -3023,6 +3144,7 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", + "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", @@ -3144,9 +3266,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.35.1" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc225a49973cf9ab10d0cdd6a4b8f0cda299df9b760824bbb623f15f8f0c95a" +checksum = "fe5759b526f75102829c15e4d8566603b4bf502ed19b5f35920d98113873470d" dependencies = [ "atomic", "bytes 1.0.1", @@ -3165,6 +3287,7 @@ dependencies = [ "libp2p-ping", "libp2p-plaintext", "libp2p-pnet", + "libp2p-relay", "libp2p-request-response", "libp2p-swarm", "libp2p-swarm-derive", @@ -3182,9 +3305,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.27.1" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2d56aadc2c2bf22cd7797f86e56a65b5b3994a0136b65be3106938acae7a26" +checksum = "c1e1797734bbd4c453664fefb029628f77c356ffc5bce98f06b18a7db3ebb0f7" dependencies = [ "asn1_der", "bs58", @@ -3216,9 +3339,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d42eed63305f0420736fa487f9acef720c4528bd7852a6a760f5ccde4813345" +checksum = "a2181a641cd15f9b6ba71b1335800f309012a0a97a29ffaabbbf40e9d3d58f08" dependencies = [ "flate2", "futures 0.3.13", @@ -3227,20 +3350,23 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5153b6db68fd4baa3b304e377db744dd8fea8ff4e4504509ee636abcde88d3e3" +checksum = "9712eb3e9f7dcc77cc5ca7d943b6a85ce4b1faaf91a67e003442412a26d6d6f8" dependencies = [ + "async-std-resolver", "futures 0.3.13", "libp2p-core", "log", + "smallvec 1.6.1", + "trust-dns-resolver", ] [[package]] name = "libp2p-floodsub" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c63dfa06581b24b1d12bf9815b43689a784424be217d6545c800c7c75a207f" +checksum = "897645f99e9b396df256a6aa8ba8c4bc019ac6b7c62556f624b5feea9acc82bb" dependencies = [ "cuckoofilter", "fnv", @@ -3256,9 +3382,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502dc5fcbfec4aa1c63ef3f7307ffe20e90c1a1387bf23ed0bec087f2dde58a1" +checksum = "794b0c85f5df1acbc1fc38414d37272594811193b6325c76d3931c3e3f5df8c0" dependencies = [ "asynchronous-codec 0.6.0", "base64 0.13.0", @@ -3282,9 +3408,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b40fb36a059b7a8cce1514bd8b546fa612e006c9937caa7f5950cb20021fe91e" +checksum = "f88ebc841d744979176ab4b8b294a3e655a7ba4ef26a905d073a52b49ed4dff5" dependencies = [ "futures 0.3.13", "libp2p-core", @@ -3298,9 +3424,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3da6c9acbcc05f93235d201d7d45ef4e8b88a45d8836f98becd8b4d443f066" +checksum = "bbb5b90b6bda749023a85f60b49ea74b387c25f17d8df541ae72a3c75dd52e63" dependencies = [ "arrayvec 0.5.2", "asynchronous-codec 0.6.0", @@ -3324,9 +3450,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9e6374814d1b118d97ccabdfc975c8910bd16dc38a8bc058eeb08bf2080fe1" +checksum = "be28ca13bb648d249a9baebd750ebc64ce7040ddd5f0ce1035ff1f4549fb596d" dependencies = [ "async-io", "data-encoding", @@ -3337,17 +3463,17 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "rand 0.7.3", + "rand 0.8.3", "smallvec 1.6.1", - "socket2", + "socket2 0.4.0", "void", ] [[package]] name = "libp2p-mplex" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350ce8b3923594aedabd5d6e3f875d058435052a29c3f32df378bc70d10be464" +checksum = "85e9b544335d1ed30af71daa96edbefadef6f19c7a55f078b9fc92c87163105d" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.0.1", @@ -3363,9 +3489,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aca322b52a0c5136142a7c3971446fb1e9964923a526c9cc6ef3b7c94e57778" +checksum = "36db0f0db3b0433f5b9463f1c0cd9eadc0a3734a9170439ce501ff99733a88bd" dependencies = [ "bytes 1.0.1", "curve25519-dalek 3.0.0", @@ -3385,9 +3511,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3813276d0708c8db0f500d8beda1bda9ad955723b9cb272c41f4727256f73c" +checksum = "dea10fc5209260915ea65b78f612d7ff78a29ab288e7aa3250796866af861c45" dependencies = [ "futures 0.3.13", "libp2p-core", @@ -3400,9 +3526,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d58defcadb646ae4b033e130b48d87410bf76394dc3335496cae99dac803e61" +checksum = "0c8c37b4d2a075b4be8442760a5f8c037180f0c8dd5b5734b9978ab868b3aa11" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.0.1", @@ -3429,11 +3555,34 @@ dependencies = [ "sha3", ] +[[package]] +name = "libp2p-relay" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff268be6a9d6f3c6cca3b81bbab597b15217f9ad8787c6c40fc548c1af7cd24" +dependencies = [ + "asynchronous-codec 0.6.0", + "bytes 1.0.1", + "futures 0.3.13", + "futures-timer 3.0.2", + "libp2p-core", + "libp2p-swarm", + "log", + "pin-project 1.0.4", + "prost", + "prost-build", + "rand 0.7.3", + "smallvec 1.6.1", + "unsigned-varint 0.7.0", + "void", + "wasm-timer", +] + [[package]] name = "libp2p-request-response" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10e5552827c33d8326502682da73a0ba4bfa40c1b55b216af3c303f32169dd89" +checksum = "725367dd2318c54c5ab1a6418592e5b01c63b0dedfbbfb8389220b2bcf691899" dependencies = [ "async-trait", "bytes 1.0.1", @@ -3451,9 +3600,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7955b973e1fd2bd61ffd43ce261c1223f61f4aacd5bae362a924993f9a25fd98" +checksum = "75c26980cadd7c25d89071cb23e1f7f5df4863128cc91d83c6ddc72338cecafa" dependencies = [ "either", "futures 0.3.13", @@ -3477,9 +3626,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a5aef80e519a6cb8e2663605142f97baaaea1a252eecbf8756184765f7471b" +checksum = "2b1a27d21c477951799e99d5c105d78868258502ce092988040a808d5a19bbd9" dependencies = [ "async-io", "futures 0.3.13", @@ -3489,14 +3638,14 @@ dependencies = [ "libc", "libp2p-core", "log", - "socket2", + "socket2 0.4.0", ] [[package]] name = "libp2p-uds" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80ac51ce419f60be966e02103c17f67ff5dc4422ba83ba54d251d6c62a4ed487" +checksum = "ffd6564bb3b7ff203661ccbb69003c2b551e34cef974f2d6c6a28306a12170b5" dependencies = [ "async-std", "futures 0.3.13", @@ -3506,9 +3655,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6149c46cb76935c80bc8be6ec6e3ebd5f5e1679765a255fb34331d54610f15dd" +checksum = "6df65fc13f6188edf7e6927b086330448b3ca27af86b49748c6d299d7c8d9040" dependencies = [ "futures 0.3.13", "js-sys", @@ -3520,9 +3669,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b1c6a3431045da8b925ed83384e4c5163e14b990572307fca9c507435d4d22" +checksum = "cace60995ef6f637e4752cccbb2590f6bc358e8741a0d066307636c69a4b3a74" dependencies = [ "either", "futures 0.3.13", @@ -3538,9 +3687,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.30.1" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4819358c542a86ff95f6ae691efb4b94ddaf477079b01a686f5705b79bfc232a" +checksum = "96d6144cc94143fb0a8dd1e7c2fbcc32a2808168bcd1d69920635424d5993b7b" dependencies = [ "futures 0.3.13", "libp2p-core", @@ -3664,6 +3813,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "mach" version = "0.3.2" @@ -3679,6 +3837,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matchers" version = "0.0.1" @@ -3803,9 +3967,9 @@ dependencies = [ [[package]] name = "minicbor" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c2b2c73f9640fccab53947e2b3474d5071fcbc8f82cac51ddf6c8041a30a9ea" +checksum = "ea79ce4ab9f445ec6b71833a2290ac0a29c9dde0fa7cae4c481eecae021d9bd9" dependencies = [ "minicbor-derive", ] @@ -3902,7 +4066,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" dependencies = [ - "socket2", + "socket2 0.3.17", "winapi 0.3.9", ] @@ -4198,7 +4362,7 @@ checksum = "13370dae44474229701bb69b90b4f4dca6404cb0357a2d50d635f1171dc3aa7b" [[package]] name = "pallet-authority-discovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4214,7 +4378,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4229,7 +4393,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4253,7 +4417,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4265,10 +4429,25 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-beefy" +version = "0.1.0" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget#8213c08e3dcf7fc732b3be6c73f8c6d3619abae2" +dependencies = [ + "beefy-primitives", + "frame-support", + "frame-system", + "pallet-session", + "parity-scale-codec", + "serde", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-bounties" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4283,7 +4462,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4300,7 +4479,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4315,7 +4494,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -4336,7 +4515,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4352,7 +4531,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4374,7 +4553,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4390,7 +4569,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4410,7 +4589,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4427,7 +4606,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4438,10 +4617,62 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-mmr" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +dependencies = [ + "ckb-merkle-mountain-range", + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-mmr-primitives", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-mmr-primitives" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +dependencies = [ + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "serde", + "sp-api", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-mmr-rpc" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" +dependencies = [ + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "pallet-mmr-primitives", + "parity-scale-codec", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", +] + [[package]] name = "pallet-multisig" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4457,7 +4688,7 @@ dependencies = [ [[package]] name = "pallet-nicks" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4471,7 +4702,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4487,7 +4718,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -4509,7 +4740,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4525,7 +4756,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4538,7 +4769,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "enumflags2", "frame-support", @@ -4553,7 +4784,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4569,7 +4800,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4589,7 +4820,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4605,7 +4836,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4619,7 +4850,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -4634,7 +4865,6 @@ dependencies = [ "serde", "sp-application-crypto", "sp-io", - "sp-npos-elections", "sp-runtime", "sp-staking", "sp-std", @@ -4644,7 +4874,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -4655,7 +4885,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4669,7 +4899,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4688,7 +4918,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4703,7 +4933,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-support", "frame-system", @@ -4719,7 +4949,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4736,7 +4966,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -4747,7 +4977,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4763,7 +4993,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-benchmarking", "frame-support", @@ -4779,7 +5009,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5214,7 +5444,7 @@ checksum = "989d43012e2ca1c4a02507c67282691a0a3207f9dc67cec596b43fe925b3d325" [[package]] name = "polkadot" -version = "0.8.29" +version = "0.8.30" dependencies = [ "assert_cmd", "color-eyre", @@ -5282,6 +5512,7 @@ dependencies = [ "polkadot-erasure-coding", "polkadot-node-core-runtime-api", "polkadot-node-network-protocol", + "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-node-subsystem-util", @@ -5312,6 +5543,7 @@ dependencies = [ "parity-scale-codec", "polkadot-erasure-coding", "polkadot-node-network-protocol", + "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-node-subsystem-util", @@ -5328,7 +5560,7 @@ dependencies = [ [[package]] name = "polkadot-cli" -version = "0.8.29" +version = "0.8.30" dependencies = [ "frame-benchmarking-cli", "futures 0.3.13", @@ -5373,7 +5605,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" -version = "0.7.30" +version = "0.8.30" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -5384,9 +5616,10 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" -version = "0.8.29" +version = "0.8.30" dependencies = [ "parity-scale-codec", + "polkadot-node-primitives", "polkadot-primitives", "reed-solomon-novelpoly", "sp-core", @@ -5403,7 +5636,10 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.3", + "sp-api", + "sp-application-crypto", + "sp-authority-discovery", + "sp-keystore", "tracing", ] @@ -5414,6 +5650,7 @@ dependencies = [ "assert_matches", "async-trait", "futures 0.3.13", + "futures-timer 3.0.2", "parity-scale-codec", "parking_lot 0.11.1", "polkadot-node-network-protocol", @@ -5423,6 +5660,7 @@ dependencies = [ "polkadot-primitives", "sc-authority-discovery", "sc-network", + "sp-consensus", "sp-core", "sp-keyring", "strum", @@ -5456,7 +5694,6 @@ dependencies = [ "futures-timer 3.0.2", "kvdb", "kvdb-memorydb", - "kvdb-rocksdb", "maplit", "merlin", "parity-scale-codec", @@ -5474,6 +5711,7 @@ dependencies = [ "schnorrkel", "sp-application-crypto", "sp-blockchain", + "sp-consensus", "sp-consensus-babe", "sp-consensus-slots", "sp-core", @@ -5494,17 +5732,16 @@ dependencies = [ "futures-timer 3.0.2", "kvdb", "kvdb-memorydb", - "kvdb-rocksdb", "log", "parity-scale-codec", "parking_lot 0.11.1", "polkadot-erasure-coding", + "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", - "sc-service", "sp-core", "sp-keyring", "thiserror", @@ -5668,6 +5905,7 @@ dependencies = [ "mick-jaeger", "parity-scale-codec", "parking_lot 0.11.1", + "polkadot-node-primitives", "polkadot-primitives", "sc-network", "sp-core", @@ -5694,15 +5932,18 @@ version = "0.1.0" dependencies = [ "futures 0.3.13", "parity-scale-codec", + "polkadot-parachain", "polkadot-primitives", "polkadot-statement-table", "schnorrkel", + "serde", "sp-application-crypto", "sp-consensus-babe", "sp-consensus-vrf", "sp-core", "sp-runtime", "thiserror", + "zstd", ] [[package]] @@ -5778,6 +6019,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", "polkadot-primitives", + "rand 0.8.3", "sc-network", "sp-application-crypto", "sp-core", @@ -5810,7 +6052,7 @@ dependencies = [ [[package]] name = "polkadot-parachain" -version = "0.8.29" +version = "0.8.30" dependencies = [ "derive_more", "futures 0.3.13", @@ -5836,7 +6078,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" -version = "0.8.29" +version = "0.8.30" dependencies = [ "bitvec", "frame-system", @@ -5862,7 +6104,6 @@ dependencies = [ "sp-trie", "sp-version", "thiserror", - "zstd", ] [[package]] @@ -5878,9 +6119,12 @@ dependencies = [ [[package]] name = "polkadot-rpc" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "beefy-gadget", + "beefy-gadget-rpc", "jsonrpc-core", + "pallet-mmr-rpc", "pallet-transaction-payment-rpc", "parity-scale-codec", "polkadot-primitives", @@ -5907,8 +6151,9 @@ dependencies = [ [[package]] name = "polkadot-runtime" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "beefy-primitives", "bitvec", "frame-benchmarking", "frame-executive", @@ -5934,6 +6179,7 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", + "pallet-mmr-primitives", "pallet-multisig", "pallet-nicks", "pallet-offences", @@ -5969,6 +6215,7 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", + "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", @@ -5985,8 +6232,9 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "beefy-primitives", "bitvec", "frame-benchmarking", "frame-support", @@ -5999,6 +6247,8 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", + "pallet-beefy", + "pallet-mmr", "pallet-offences", "pallet-randomness-collective-flip", "pallet-session", @@ -6034,7 +6284,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" -version = "0.8.0" +version = "0.8.30" dependencies = [ "bitvec", "derive_more", @@ -6085,16 +6335,21 @@ dependencies = [ [[package]] name = "polkadot-service" -version = "0.8.3" +version = "0.8.30" dependencies = [ + "beefy-gadget", + "beefy-primitives", "env_logger 0.8.2", "frame-benchmarking", "frame-system-rpc-runtime-api", "futures 0.3.13", "hex-literal", "kusama-runtime", + "kvdb", + "kvdb-rocksdb", "pallet-babe", "pallet-im-online", + "pallet-mmr-primitives", "pallet-staking", "pallet-transaction-payment-rpc-runtime-api", "polkadot-approval-distribution", @@ -6115,6 +6370,7 @@ dependencies = [ "polkadot-node-core-proposer", "polkadot-node-core-provisioner", "polkadot-node-core-runtime-api", + "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-overseer", @@ -6192,7 +6448,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" -version = "0.8.29" +version = "0.8.30" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -6201,8 +6457,9 @@ dependencies = [ [[package]] name = "polkadot-test-client" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "futures 0.3.13", "parity-scale-codec", "polkadot-node-subsystem", "polkadot-primitives", @@ -6226,8 +6483,9 @@ dependencies = [ [[package]] name = "polkadot-test-runtime" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "beefy-primitives", "bitvec", "frame-election-provider-support", "frame-executive", @@ -6243,6 +6501,7 @@ dependencies = [ "pallet-balances", "pallet-grandpa", "pallet-indices", + "pallet-mmr-primitives", "pallet-nicks", "pallet-offences", "pallet-randomness-collective-flip", @@ -6286,7 +6545,7 @@ dependencies = [ [[package]] name = "polkadot-test-service" -version = "0.8.29" +version = "0.8.30" dependencies = [ "frame-benchmarking", "frame-system", @@ -6854,9 +7113,9 @@ dependencies = [ [[package]] name = "reed-solomon-novelpoly" -version = "0.0.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11e01a8ef53ec033daf53a9385a1d0bb266155797919096e4134118f45efe82" +checksum = "3bd8f48b2066e9f69ab192797d66da804d1935bf22763204ed3675740cb0f221" dependencies = [ "derive_more", "fs-err", @@ -6939,7 +7198,7 @@ dependencies = [ [[package]] name = "remote-externalities" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "env_logger 0.8.2", "hex-literal", @@ -6962,6 +7221,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error 1.2.3", +] + [[package]] name = "retain_mut" version = "0.1.2" @@ -7005,8 +7274,9 @@ dependencies = [ [[package]] name = "rococo-runtime" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "beefy-primitives", "frame-executive", "frame-support", "frame-system", @@ -7017,9 +7287,12 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", + "pallet-beefy", "pallet-grandpa", "pallet-im-online", "pallet-indices", + "pallet-mmr", + "pallet-mmr-primitives", "pallet-offences", "pallet-proxy", "pallet-session", @@ -7198,7 +7471,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "async-trait", "derive_more", @@ -7226,7 +7499,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "futures-timer 3.0.2", @@ -7249,7 +7522,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -7265,7 +7538,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7286,7 +7559,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -7297,7 +7570,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "chrono", "fdlimit", @@ -7335,7 +7608,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "fnv", @@ -7369,7 +7642,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "blake2-rfc", "hash-db", @@ -7399,8 +7672,9 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ + "parking_lot 0.11.1", "sc-client-api", "sp-blockchain", "sp-consensus", @@ -7410,8 +7684,9 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ + "async-trait", "derive_more", "fork-tree", "futures 0.3.13", @@ -7456,7 +7731,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "futures 0.3.13", @@ -7480,12 +7755,12 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "fork-tree", "parity-scale-codec", - "parking_lot 0.11.1", "sc-client-api", + "sc-consensus", "sp-blockchain", "sp-runtime", ] @@ -7493,13 +7768,13 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ + "async-trait", "futures 0.3.13", "futures-timer 3.0.2", "log", "parity-scale-codec", - "parking_lot 0.11.1", "sc-client-api", "sc-telemetry", "sp-api", @@ -7520,7 +7795,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "sc-client-api", @@ -7534,7 +7809,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "lazy_static", @@ -7563,7 +7838,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "parity-scale-codec", @@ -7579,7 +7854,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "parity-scale-codec", @@ -7594,7 +7869,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "parity-scale-codec", @@ -7612,8 +7887,9 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ + "async-trait", "derive_more", "dyn-clone", "finality-grandpa", @@ -7651,7 +7927,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "finality-grandpa", @@ -7675,7 +7951,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-warp-sync" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "futures 0.3.13", @@ -7696,7 +7972,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "ansi_term 0.12.1", "futures 0.3.13", @@ -7714,7 +7990,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "async-trait", "derive_more", @@ -7734,7 +8010,7 @@ dependencies = [ [[package]] name = "sc-light" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "hash-db", "lazy_static", @@ -7753,7 +8029,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "async-std", "async-trait", @@ -7806,7 +8082,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "futures-timer 3.0.2", @@ -7823,7 +8099,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "bytes 0.5.6", "fnv", @@ -7851,7 +8127,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "libp2p", @@ -7864,7 +8140,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7873,7 +8149,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "hash-db", @@ -7907,7 +8183,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "futures 0.3.13", @@ -7931,7 +8207,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.1.29", "jsonrpc-core", @@ -7949,8 +8225,9 @@ dependencies = [ [[package]] name = "sc-service" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ + "async-trait", "directories", "exit-future", "futures 0.1.29", @@ -8012,7 +8289,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "parity-scale-codec", @@ -8027,7 +8304,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -8047,7 +8324,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "chrono", "futures 0.3.13", @@ -8067,7 +8344,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "ansi_term 0.12.1", "atty", @@ -8094,7 +8371,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -8105,7 +8382,7 @@ dependencies = [ [[package]] name = "sc-transaction-graph" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "futures 0.3.13", @@ -8127,7 +8404,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "futures-diagnose", @@ -8317,18 +8594,18 @@ checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" [[package]] name = "serde" -version = "1.0.123" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.123" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2", "quote", @@ -8337,9 +8614,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ "itoa", "ryu", @@ -8514,6 +8791,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "soketto" version = "0.4.1" @@ -8533,7 +8820,7 @@ dependencies = [ [[package]] name = "sp-allocator" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "sp-core", @@ -8545,7 +8832,7 @@ dependencies = [ [[package]] name = "sp-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "hash-db", "log", @@ -8562,7 +8849,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "blake2-rfc", "proc-macro-crate 1.0.0", @@ -8574,7 +8861,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "serde", @@ -8586,7 +8873,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "integer-sqrt", "num-traits", @@ -8599,7 +8886,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-api", @@ -8611,7 +8898,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -8622,7 +8909,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-api", @@ -8634,7 +8921,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "log", @@ -8652,7 +8939,7 @@ dependencies = [ [[package]] name = "sp-chain-spec" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "serde", "serde_json", @@ -8661,8 +8948,9 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ + "async-trait", "futures 0.3.13", "futures-timer 3.0.2", "libp2p", @@ -8687,7 +8975,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "merlin", "parity-scale-codec", @@ -8708,7 +8996,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-arithmetic", @@ -8718,7 +9006,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -8730,7 +9018,7 @@ dependencies = [ [[package]] name = "sp-core" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "base58", "blake2-rfc", @@ -8774,7 +9062,7 @@ dependencies = [ [[package]] name = "sp-database" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "kvdb", "parking_lot 0.11.1", @@ -8783,7 +9071,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "proc-macro2", "quote", @@ -8793,7 +9081,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "environmental", "parity-scale-codec", @@ -8804,7 +9092,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "finality-grandpa", "log", @@ -8821,7 +9109,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "parking_lot 0.11.1", @@ -8833,7 +9121,7 @@ dependencies = [ [[package]] name = "sp-io" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "hash-db", @@ -8857,7 +9145,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "lazy_static", "sp-core", @@ -8868,7 +9156,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "async-trait", "derive_more", @@ -8885,7 +9173,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "serde", @@ -8898,7 +9186,7 @@ dependencies = [ [[package]] name = "sp-npos-elections-compact" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -8909,7 +9197,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "sp-api", "sp-core", @@ -8919,7 +9207,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "backtrace", ] @@ -8927,7 +9215,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "serde", "sp-core", @@ -8936,7 +9224,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "either", "hash256-std-hasher", @@ -8957,7 +9245,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -8974,7 +9262,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "Inflector", "proc-macro-crate 1.0.0", @@ -8986,7 +9274,7 @@ dependencies = [ [[package]] name = "sp-serializer" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "serde", "serde_json", @@ -8995,7 +9283,7 @@ dependencies = [ [[package]] name = "sp-session" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-api", @@ -9008,7 +9296,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -9018,7 +9306,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "hash-db", "log", @@ -9040,12 +9328,12 @@ dependencies = [ [[package]] name = "sp-std" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" [[package]] name = "sp-storage" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "impl-serde", "parity-scale-codec", @@ -9058,7 +9346,7 @@ dependencies = [ [[package]] name = "sp-tasks" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "sp-core", @@ -9071,7 +9359,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "parity-scale-codec", "sp-api", @@ -9084,7 +9372,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "log", "parity-scale-codec", @@ -9097,7 +9385,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "derive_more", "futures 0.3.13", @@ -9113,7 +9401,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "hash-db", "memory-db", @@ -9127,7 +9415,7 @@ dependencies = [ [[package]] name = "sp-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "futures-core", @@ -9139,7 +9427,7 @@ dependencies = [ [[package]] name = "sp-version" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "impl-serde", "parity-scale-codec", @@ -9151,7 +9439,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -9308,7 +9596,7 @@ dependencies = [ [[package]] name = "substrate-browser-utils" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "chrono", "console_error_panic_hook", @@ -9334,7 +9622,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "platforms", ] @@ -9342,7 +9630,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.13", @@ -9365,7 +9653,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "async-std", "derive_more", @@ -9379,8 +9667,9 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.1" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ + "async-trait", "futures 0.1.29", "futures 0.3.13", "hash-db", @@ -9407,7 +9696,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "futures 0.3.13", "substrate-test-utils-derive", @@ -9417,7 +9706,7 @@ dependencies = [ [[package]] name = "substrate-test-utils-derive" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "proc-macro-crate 1.0.0", "quote", @@ -9518,7 +9807,7 @@ dependencies = [ [[package]] name = "test-parachain-adder" -version = "0.8.29" +version = "0.8.30" dependencies = [ "dlmalloc", "parity-scale-codec", @@ -9531,7 +9820,7 @@ dependencies = [ [[package]] name = "test-parachain-adder-collator" -version = "0.7.26" +version = "0.8.30" dependencies = [ "futures 0.3.13", "futures-timer 3.0.2", @@ -9557,14 +9846,14 @@ dependencies = [ [[package]] name = "test-parachain-halt" -version = "0.8.29" +version = "0.8.30" dependencies = [ "substrate-wasm-builder", ] [[package]] name = "test-parachains" -version = "0.7.22" +version = "0.8.30" dependencies = [ "parity-scale-codec", "polkadot-parachain", @@ -9677,6 +9966,21 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" +[[package]] +name = "tinyvec" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + [[package]] name = "tokio" version = "0.1.22" @@ -10091,6 +10395,49 @@ dependencies = [ "hash-db", ] +[[package]] +name = "trust-dns-proto" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d57e219ba600dd96c2f6d82eb79645068e14edbc5c7e27514af40436b88150c" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.0", + "ipnet", + "lazy_static", + "log", + "rand 0.8.3", + "smallvec 1.6.1", + "thiserror", + "tinyvec 1.1.1", + "url 2.2.0", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0437eea3a6da51acc1e946545ff53d5b8fb2611ff1c3bed58522dde100536ae" +dependencies = [ + "cfg-if 1.0.0", + "futures-util", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "parking_lot 0.11.1", + "resolv-conf", + "smallvec 1.6.1", + "thiserror", + "trust-dns-proto", +] + [[package]] name = "try-lock" version = "0.2.2" @@ -10100,7 +10447,7 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "try-runtime-cli" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=rococo-v1#401c24e8a62cdf058882b0e92815faef966d9fa1" +source = "git+https://github.com/paritytech/substrate#b5978187b9c9fbfcf535ab96161a92c0b330540b" dependencies = [ "frame-try-runtime", "log", @@ -10190,7 +10537,7 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ - "tinyvec", + "tinyvec 0.3.3", ] [[package]] @@ -10746,8 +11093,9 @@ dependencies = [ [[package]] name = "westend-runtime" -version = "0.8.29" +version = "0.8.30" dependencies = [ + "beefy-primitives", "bitvec", "frame-benchmarking", "frame-executive", @@ -10763,6 +11111,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", + "pallet-beefy", "pallet-collective", "pallet-democracy", "pallet-election-provider-multi-phase", @@ -10772,6 +11121,8 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", + "pallet-mmr", + "pallet-mmr-primitives", "pallet-multisig", "pallet-nicks", "pallet-offences", @@ -10810,6 +11161,7 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", + "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", @@ -10842,6 +11194,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + [[package]] name = "winapi" version = "0.2.8" @@ -10885,6 +11243,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winreg" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -10925,16 +11292,17 @@ dependencies = [ [[package]] name = "xcm" -version = "0.8.22" +version = "0.8.30" dependencies = [ "parity-scale-codec", ] [[package]] name = "xcm-builder" -version = "0.8.22" +version = "0.8.30" dependencies = [ "frame-support", + "impl-trait-for-tuples", "parity-scale-codec", "polkadot-parachain", "sp-arithmetic", @@ -10947,7 +11315,7 @@ dependencies = [ [[package]] name = "xcm-executor" -version = "0.8.22" +version = "0.8.30" dependencies = [ "frame-support", "impl-trait-for-tuples", From 016c7858b4baf44cafcacd8f6dfac6138d63c82b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 1 Apr 2021 22:57:02 +0200 Subject: [PATCH 04/40] Fix --- xcm/xcm-executor/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 0967fa1b9041..e056035e82f0 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -16,12 +16,12 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::{prelude::*, marker::PhantomData, convert::TryInto}; -use frame_support::{ensure, dispatch::Dispatchable}; +use sp_std::{prelude::*, marker::PhantomData}; +use frame_support::dispatch::Dispatchable; use parity_scale_codec::Decode; use xcm::v0::{ Xcm, Order, ExecuteXcm, SendXcm, Error as XcmError, Result as XcmResult, - MultiLocation, MultiAsset, Junction, + MultiLocation, MultiAsset, }; pub mod traits; From 0be98c31f1a536d3711208862a0ab72df00d86a5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 2 Apr 2021 22:38:02 +0200 Subject: [PATCH 05/40] Broken example --- xcm/src/double_encoded.rs | 60 ++++++++++++ xcm/src/lib.rs | 9 +- xcm/src/v0/mod.rs | 92 +++++++++++++----- xcm/src/v0/order.rs | 40 +++++++- xcm/xcm-executor/src/assets.rs | 129 ++++++++++++++++++++++++- xcm/xcm-executor/src/config.rs | 171 ++++++++++++++++++++++++++++++++- xcm/xcm-executor/src/lib.rs | 99 +++++++++++++------ 7 files changed, 535 insertions(+), 65 deletions(-) create mode 100644 xcm/src/double_encoded.rs diff --git a/xcm/src/double_encoded.rs b/xcm/src/double_encoded.rs new file mode 100644 index 000000000000..ceec6e217d55 --- /dev/null +++ b/xcm/src/double_encoded.rs @@ -0,0 +1,60 @@ +// Copyright 2020 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 . + +use alloc::vec::Vec; +use parity_scale_codec::{Encode, Decode}; + +#[derive(Eq, PartialEq, Clone, Encode, Decode, Debug)] +pub struct DoubleEncoded { + encoded: Vec, + #[codec(skip)] + decoded: Option, +} + +impl From> for DoubleEncoded { + fn from(encoded: Vec) -> Self { + Self { encoded, decoded: None } + } +} + +impl DoubleEncoded { + pub fn into(self) -> DoubleEncoded { DoubleEncoded::from(self) } + pub fn from(e: DoubleEncoded) -> Self { + Self { + encoded: e.encoded, + decoded: None, + } + } + pub fn as_ref(&self) -> Option<&T> { + self.decoded.as_ref() + } +} + +impl DoubleEncoded { + pub fn ensure_decoded(&mut self) -> Result<&T, ()> { + if self.decoded.is_none() { + self.decoded = T::decode(&mut &self.encoded[..]).ok(); + } + self.decoded.as_ref().ok_or(()) + } + pub fn take_decoded(&mut self) -> Result { + self.decoded.take().or_else(|| T::decode(&mut &self.encoded[..]).ok()).ok_or(()) + } + pub fn try_into(mut self) -> Result { + self.ensure_decoded(); + self.decoded.ok_or(()) + } +} diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs index 3dc99e07c705..cc21db22f54a 100644 --- a/xcm/src/lib.rs +++ b/xcm/src/lib.rs @@ -26,13 +26,18 @@ extern crate alloc; use parity_scale_codec::{Encode, Decode}; pub mod v0; +mod double_encoded; +pub use double_encoded::DoubleEncoded; /// A single XCM message, together with its version code. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] -pub enum VersionedXcm { - V0(v0::Xcm), +pub enum VersionedXcmGeneric { + V0(v0::XcmGeneric), } +/// The basic VersionedXcm type which just uses the `Vec` as an encoded call. +pub type VersionedXcm = VersionedXcmGeneric<()>; + /// A versioned multi-location, a relative location of a cross-consensus system identifier. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] pub enum VersionedMultiLocation { diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index fa0ce016f7be..feb1929e0822 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -16,11 +16,10 @@ //! Version 0 of the Cross-Consensus Message format data structures. -use core::{result, convert::TryFrom}; +use core::{result, convert::TryFrom, fmt::Debug}; use alloc::vec::Vec; - use parity_scale_codec::{self, Encode, Decode}; -use super::{VersionedXcm, VersionedMultiAsset}; +use super::{VersionedXcmGeneric, VersionedMultiAsset, DoubleEncoded}; mod junction; mod multi_asset; @@ -61,7 +60,7 @@ pub enum OriginKind { /// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer /// XCM format, known as `VersionedXcm`. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] -pub enum Xcm { +pub enum XcmGeneric { /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into `holding`. Execute the /// orders (`effects`). /// @@ -71,7 +70,7 @@ pub enum Xcm { /// Kind: *Instruction*. /// /// Errors: - WithdrawAsset { assets: Vec, effects: Vec }, + WithdrawAsset { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system. /// @@ -87,7 +86,7 @@ pub enum Xcm { /// Kind: *Trusted Indication*. /// /// Errors: - ReserveAssetDeposit { assets: Vec, effects: Vec }, + ReserveAssetDeposit { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be /// created on this system. @@ -104,7 +103,7 @@ pub enum Xcm { /// Kind: *Trusted Indication*. /// /// Errors: - TeleportAsset { assets: Vec, effects: Vec }, + TeleportAsset { assets: Vec, effects: Vec> }, /// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`. /// @@ -118,18 +117,7 @@ pub enum Xcm { /// Errors: Balances { #[codec(compact)] query_id: u64, assets: Vec }, - /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind - /// of origin `origin_type`. - /// - /// - `origin_type`: The means of expressing the message origin as a dispatch origin. - /// - `call`: The encoded transaction to be applied. - /// - /// Safety: No concerns. - /// - /// Kind: *Instruction*. - /// - /// Errors: - Transact { origin_type: OriginKind, call: Vec }, + Unused4, /// Unused Unused5, @@ -181,19 +169,73 @@ pub enum Xcm { #[codec(compact)] sender: u32, #[codec(compact)] recipient: u32, }, + + /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind + /// of origin `origin_type`. + /// + /// - `origin_type`: The means of expressing the message origin as a dispatch origin. + /// - `max_weight`: The weight of `call`; this should be at least the chain's calculated weight and will + /// be used in the weight determination arithmetic. + /// - `call`: The encoded transaction to be applied. + /// + /// Safety: No concerns. + /// + /// Kind: *Instruction*. + /// + /// Errors: + Transact { origin_type: OriginKind, max_weight: u64, call: DoubleEncoded }, } -impl From for VersionedXcm { - fn from(x: Xcm) -> Self { - VersionedXcm::V0(x) +/// The basic concrete type of `XcmGeneric`, which doesn't make any assumptions about the format of a +/// call other than it is pre-encoded. +pub type Xcm = XcmGeneric<()>; + +impl< + Call: Clone + Eq + PartialEq + Encode + Decode + Debug +> From> for VersionedXcmGeneric { + fn from(x: XcmGeneric) -> Self { + VersionedXcmGeneric::V0(x) } } -impl TryFrom for Xcm { +impl< + Call: Clone + Eq + PartialEq + Encode + Decode + Debug +> TryFrom> for XcmGeneric { type Error = (); - fn try_from(x: VersionedXcm) -> result::Result { + fn try_from(x: VersionedXcmGeneric) -> result::Result { match x { - VersionedXcm::V0(x) => Ok(x), + VersionedXcmGeneric::V0(x) => Ok(x), + } + } +} + +impl XcmGeneric { + pub fn into(self) -> XcmGeneric { XcmGeneric::from(self) } + pub fn from(xcm: XcmGeneric) -> Self { + use XcmGeneric::*; + match xcm { + WithdrawAsset { assets, effects } + => WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, + ReserveAssetDeposit { assets, effects } + => ReserveAssetDeposit { assets, effects: effects.into_iter().map(Order::into).collect() }, + TeleportAsset { assets, effects } + => TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, + Balances { query_id: u64, assets } + => Balances { query_id: u64, assets }, + Unused4 + => Unused4, + Unused5 + => Unused5, + Unused6 + => Unused6, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity} + => HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}, + HrmpChannelAccepted { recipient} + => HrmpChannelAccepted { recipient}, + HrmpChannelClosing { initiator, sender, recipient} + => HrmpChannelClosing { initiator, sender, recipient}, + Transact { origin_type, max_weight, call} + => Transact { origin_type, max_weight, call: call.into() } } } } diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs index df7a215015ec..71d7ab814663 100644 --- a/xcm/src/v0/order.rs +++ b/xcm/src/v0/order.rs @@ -18,11 +18,11 @@ use alloc::vec::Vec; use parity_scale_codec::{self, Encode, Decode}; -use super::{MultiAsset, MultiLocation}; +use super::{MultiAsset, MultiLocation, XcmGeneric}; /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] -pub enum Order { +pub enum Order { /// Do nothing. Not generally used. Null, @@ -46,7 +46,7 @@ pub enum Order { /// `dest. /// /// Errors: - DepositReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec }, + DepositReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec> }, /// Remove the asset(s) (`give`) from holding and replace them with alternative assets. /// @@ -68,7 +68,7 @@ pub enum Order { /// - `effects`: The orders to execute on the assets once withdrawn *on the reserve location*. /// /// Errors: - InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec }, + InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec> }, /// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location. /// @@ -77,7 +77,7 @@ pub enum Order { /// - `effects`: The orders to execute on the assets once arrived *on the destination location*. /// /// Errors: - InitiateTeleport { assets: Vec, dest: MultiLocation, effects: Vec }, + InitiateTeleport { assets: Vec, dest: MultiLocation, effects: Vec> }, /// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof. /// @@ -89,4 +89,34 @@ pub enum Order { /// /// Errors: QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: Vec }, + + /// Pay for the execution of some Xcm with up to `weight` ps of execution time, paying for this with + /// up to `fees` from the holding account. + /// + /// Errors: + BuyExecution { fees: MultiAsset, weight: u64, halt_on_error: bool, xcm: Vec> }, +} + +impl Order { + pub fn into(self) -> Order { Order::from(self) } + pub fn from(xcm: Order) -> Self { + use Order::*; + match xcm { + Null => Null, + DepositAsset { assets, dest } + => DepositAsset { assets, dest }, + DepositReserveAsset { assets, dest, effects } + => DepositReserveAsset { assets, dest, effects: effects.map(Order::from) }, + ExchangeAsset { give, receive } + => ExchangeAsset { give, receive }, + InitiateReserveWithdraw { assets, reserve, effects } + => InitiateReserveWithdraw { assets, reserve, effects: effects.map(Order::from) }, + InitiateTeleport { assets, dest, effects } + => InitiateTeleport { assets, dest, effects }, + QueryHolding { query_id, dest, assets } + => QueryHolding { query_id, dest, assets }, + BuyExecution { fees, weight, halt_on_error, xcm } + => BuyExecution { fees, weight, halt_on_error, xcm: xcm.map(XcmGeneric::from) }, + } + } } diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs index 1f37c28d9be3..d7acf86369e2 100644 --- a/xcm/xcm-executor/src/assets.rs +++ b/xcm/xcm-executor/src/assets.rs @@ -33,12 +33,27 @@ impl AssetId { } Ok(()) } + pub fn into_fungible_multiasset(self, amount: u128) -> MultiAsset { + match self { + AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount }, + AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount }, + } + } + pub fn into_non_fungible_multiasset(self, instance: AssetInstance) -> MultiAsset { + match self { + AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance }, + AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance }, + } + } } /// List of concretely identified fungible and non-fungible assets. -#[derive(Default, Clone, RuntimeDebug)] +#[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)] pub struct Assets { pub fungible: BTreeMap, + + // OPTIMIZE: Consider BTreeMap> + // or even BTreeMap> pub non_fungible: BTreeSet<(AssetId, AssetInstance)>, } @@ -58,7 +73,17 @@ impl From for Vec { } } +impl From for Assets { + fn from(asset: MultiAsset) -> Assets { + let mut result = Self::default(); + result.saturating_subsume(asset); + result + } +} + impl Assets { + pub fn new() -> Self { Self::default() } + /// An iterator over the fungible assets. pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator + 'a { self.fungible.iter() @@ -99,6 +124,14 @@ impl Assets { fungible.chain(non_fungible) } + pub fn saturating_subsume_all(&mut self, assets: Assets) { + // OPTIMIZE: Could be done with a much faster btree entry merge and only sum the entries with the + // same key. + for asset in assets.into_assets_iter() { + self.saturating_subsume(asset) + } + } + /// Modify `self` to include a `MultiAsset`, saturating if necessary. /// Only works on concretely identified assets; wildcards will be swallowed without error. pub fn saturating_subsume(&mut self, asset: MultiAsset) { @@ -119,6 +152,100 @@ impl Assets { } } + /// Consumes `self` and returns `Ok` iff it contains at least `asset`. + /// + /// Wildcard assets in `self` are not supported and will result in an error. + /// + /// `asset` may be a wildcard. + /// + /// Returns `Ok` with the `self` minus `asset` and the non-wildcard equivalence of `asset` taken if `self` + /// contains `asset`, and `Err` with `self` otherwise. + pub fn checked_sub(mut self, asset: MultiAsset) -> Result<(Self, Assets), Self> { + match self.checked_sub_assign(asset) { + Ok(taken) => Ok((self, taken)), + Err(()) => Err(self), + } + } + + /// Mutates `self` and returns `true` iff it contains at least `asset`. + /// + /// Wildcard assets in `self` are not supported and will result in an error. + /// + /// `asset` may be a wildcard. + /// + /// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus + /// `asset` if `self` contains `asset`, and return `Err` otherwise. + pub fn checked_sub_assign(&mut self, asset: MultiAsset) -> Result { + match asset { + MultiAsset::None => Ok(Assets::new()), + MultiAsset::ConcreteFungible { id, amount } => self.try_take_fungible(AssetId::Concrete(id), amount), + MultiAsset::AbstractFungible { id, amount } => self.try_take_fungible(AssetId::Abstract(id), amount), + MultiAsset::ConcreteNonFungible { class, instance} => self.try_take_non_fungible(AssetId::Concrete(class), instance), + MultiAsset::AbstractNonFungible { class, instance} => self.try_take_non_fungible(AssetId::Abstract(class), instance), + MultiAsset::AllAbstractFungible { id } => Ok(self.take_fungible(&AssetId::Abstract(id))), + MultiAsset::AllConcreteFungible { id } => Ok(self.take_fungible(&AssetId::Concrete(id))), + MultiAsset::AllAbstractNonFungible { class } => Ok(self.take_non_fungible(&AssetId::Abstract(class))), + MultiAsset::AllConcreteNonFungible { class } => Ok(self.take_non_fungible(&AssetId::Concrete(class))), + MultiAsset::AllFungible => { + let mut taken = Assets::new(); + mem::swap(&mut self.fungible, &mut taken.fungible); + Ok(taken) + }, + MultiAsset::AllNonFungible => { + let mut taken = Assets::new(); + mem::swap(&mut self.non_fungible, &mut taken.non_fungible); + Ok(taken) + }, + MultiAsset::All => Ok(self.swapped(Assets::new())), + } + } + + pub fn try_take_fungible(&mut self, id: AssetId, amount: u128) -> Result { + self.checked_sub_assign_fungible(&id, amount)?; + Ok(id.into_fungible_multiasset(amount).into()) + } + + pub fn try_take_non_fungible(&mut self, id: AssetId, instance: AssetInstance) -> Result { + let asset_id_instance = (id, instance); + self.checked_sub_assign_non_fungible(&asset_id_instance)?; + let (asset_id, instance) = asset_id_instance; + Ok(asset_id.into_non_fungible_multiasset(instance).into()) + } + + pub fn take_fungible(&mut self, id: &AssetId) -> Assets { + let mut taken = Assets::new(); + if let Some((id, amount)) = self.fungible.remove_entry(&id) { + taken.fungible.insert(id, amount); + } + taken + } + + pub fn take_non_fungible(&mut self, id: &AssetId) -> Assets { + let mut taken = Assets::new(); + let non_fungible = mem::replace(&mut self.non_fungible, Default::default()); + non_fungible.into_iter().for_each(|(c, instance)| { + if &c == id { + taken.non_fungible.insert((c, instance)); + } else { + self.non_fungible.insert((c, instance)); + } + }); + taken + } + + pub fn checked_sub_assign_fungible(&mut self, id: &AssetId, amount: u128) -> Result<(), ()> { + let self_amount = self.fungible.get_mut(&id).ok_or(())?; + *self_amount = self_amount.checked_sub(amount).ok_or(())?; + Ok(()) + } + + pub fn checked_sub_assign_non_fungible(&mut self, class_instance: &(AssetId, AssetInstance)) -> Result<(), ()> { + match self.non_fungible.remove(class_instance) { + true => Ok(()), + false => Err(()), + } + } + /// Modify `self` to include a new fungible asset by `id` and `amount`, /// saturating if necessary. pub fn saturating_subsume_fungible(&mut self, id: AssetId, amount: u128) { diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index e1008c5563b1..2b4733bd8a95 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -14,14 +14,170 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use xcm::v0::SendXcm; -use frame_support::dispatch::{Dispatchable, Parameter}; +use sp_std::marker::PhantomData; +use xcm::v0::{Xcm, SendXcm, MultiLocation, MultiAsset, Order, XcmGeneric}; +use frame_support::{ + ensure, dispatch::{Dispatchable, Parameter, Weight}, weights::{PostDispatchInfo, GetDispatchInfo} +}; +use frame_support::traits::{Get, Contains}; use crate::traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; +use crate::assets::Assets; + +/// Determine the weight of an XCM message. +pub trait WeightOf { + /// Return the weight of `message`. + fn weight_of(message: &mut XcmGeneric) -> Result; +} + +pub struct FixedWeightOf(PhantomData<(T, C)>); +impl, C: GetDispatchInfo> WeightOf for FixedWeightOf { + fn weight_of(message: &mut XcmGeneric) -> Result { + Ok(match message { + XcmGeneric::Transact { call, .. } => { + call.ensure_decoded()?; + call.as_ref().get_dispatch_info().weight + T::get() + } + XcmGeneric::WithdrawAsset { effects, .. } + | XcmGeneric::ReserveAssetDeposit { effects, .. } + | XcmGeneric::TeleportAsset { effects, .. } => { + let mut total = 0; + for effect in effects.iter_mut() { + match effect { + Order::BuyExecution { xcm, .. } => { + for xcm in xcm.iter_mut() { + total = total.checked_add(Self::weight_of(xcm)?).ok_or(())? + } + } + _ => total = total.checked_add(T::get()) + } + } + total + } + _ => T::get(), + }) + } +} + +/// Charge the for a given XCM message. +pub trait BuyWeight { + /// Purchase execution weight credit in return for up to a given `fee`. If less of the fee is required + /// then the surplus is returned. If the `fee` cannot be used to pay for the `weight`, then an error is + /// returned. + fn buy_weight(weight: Weight, payment: Assets) -> Result; +} + +/// Simple fee calculator that requires payment in a single concrete fungible at a fixed rate. +/// +/// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for +/// one second of weight. +pub struct FixedRateOfConcreteFungible(PhantomData); +impl> BuyWeight for FixedRateOfConcreteFungible { + fn buy_weight(weight: Weight, payment: Assets) -> Result { + let (required_id, units_per_second) = T::get(); + let required_amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; + let required = MultiAsset::ConcreteFungible { amount: required_amount, id: required_id }; + Ok(payment.checked_sub(required).map_err(|_| ())?.0) + } +} + +/// Trait to determine whether the execution engine should actually execute a given XCM. +pub trait ShouldExecute { + /// Returns `true` if the given `message` may be executed. + /// + /// - `origin`: The origin (sender) of the message. + /// - `top_level`: `true`` indicates the initial XCM coming from the `origin`, `false` indicates an embedded + /// XCM executed internally as part of another message or an `Order`. + /// - `message`: The message itself. + /// - `message_weight`: The weight of the message; the actual weight of the message is guaranteed to be + /// no greater than this. + /// - `weight_credit`: The pre-established amount of weight that the system has determined this message + /// may utilise in its execution. Typically non-zero only because of prior fee payment, but could + /// in principle be due to other factors. + fn should_execute( + origin: &MultiLocation, + top_level: bool, + message: &Xcm, + message_weight: Weight, + weight_credit: &mut Weight, + ) -> Result<(), ()>; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ShouldExecute for Tuple { + fn should_execute( + origin: &MultiLocation, + top_level: bool, + message: &Xcm, + message_weight: Weight, + weight_credit: &mut Weight, + ) -> Result<(), ()> { + for_tuples!( #( + match Tuple::should_execute(origin, top_level, message, message_weight, weight_credit) { + o @ Ok(()) => return o, + _ => (), + } + )* ); + Err(()) + } +} + +pub struct TakeWeightCredit; +impl ShouldExecute for TakeWeightCredit { + fn should_execute( + _origin: &MultiLocation, + _top_level: bool, + _message: &Xcm, + message_weight: Weight, + weight_credit: &mut Weight, + ) -> Result<(), ()> { + *weight_credit = weight_credit.checked_sub(message_weight).ok_or(())?; + Ok(()) + } +} + +pub struct AllowTopLevelPaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + top_level: bool, + message: &Xcm, + message_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + ensure!(T::contains(origin), ()); + ensure!(top_level, ()); + match message { + Xcm::TeleportAsset { effects, .. } + | Xcm::WithdrawAsset { effects, ..} + | Xcm::ReserveAssetDeposit { effects, ..} + if matches!( + effects.first(), + Some(Order::BuyExecution { weight, ..}) if *weight >= message_weight + ) + => Ok(()), + _ => Err(()), + } + } +} + +pub struct AllowUnpaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowUnpaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + _top_level: bool, + _message: &Xcm, + _message_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + ensure!(T::contains(origin), ()); + Ok(()) + } +} /// The trait to parametrize the `XcmExecutor`. pub trait Config { /// The outer call dispatch type. - type Call: Parameter + Dispatchable; + type Call: Parameter + Dispatchable + GetDispatchInfo; /// How to send an onward XCM message. type XcmSender: SendXcm; @@ -40,4 +196,13 @@ pub trait Config { /// Means of inverting a location. type LocationInverter: InvertLocation; + + /// Whether we should execute the given XCM at all. + type Barrier: ShouldExecute; + + /// The means of determining an XCM message's weight. + type Weigher: WeightOf; + + /// The means of purchasing weight credit for XCM execution. + type Sale: BuyWeight; } diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index e056035e82f0..cbcb2d23df5a 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -17,26 +17,52 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::{prelude::*, marker::PhantomData}; -use frame_support::dispatch::Dispatchable; -use parity_scale_codec::Decode; +use frame_support::{ + ensure, weights::GetDispatchInfo, + dispatch::{Weight, Dispatchable} +}; +use parity_scale_codec::{self as codec, Encode, Decode}; use xcm::v0::{ Xcm, Order, ExecuteXcm, SendXcm, Error as XcmError, Result as XcmResult, - MultiLocation, MultiAsset, + MultiLocation, MultiAsset, XcmGeneric, }; pub mod traits; -mod assets; -mod config; - use traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; + +mod assets; pub use assets::{Assets, AssetId}; -pub use config::Config; +mod config; +pub use config::{Config, WeightOf, BuyWeight, ShouldExecute}; pub struct XcmExecutor(PhantomData); +// TODO: Introduce max_weight and return used_weight. +// TODO: Use XcmGeneric/VersionedXcmGeneric and a new `EncodedCall` type which can decode when needed for weight. + impl ExecuteXcm for XcmExecutor { fn execute_xcm(origin: MultiLocation, msg: Xcm) -> XcmResult { - let (mut holding, effects) = match (origin.clone(), msg) { + Self::do_execute_xcm(origin, true, msg, &mut 0) + } +} + +impl XcmExecutor { + fn reanchored(mut assets: Assets, dest: &MultiLocation) -> Vec { + let inv_dest = Config::LocationInverter::invert_location(&dest); + assets.reanchor(&inv_dest); + assets.into_assets_iter().collect::>() + } + + fn do_execute_xcm(origin: MultiLocation, top_level: bool, message: Xcm, weight_credit: &mut Weight) -> XcmResult { + let message = XcmGeneric::::from(message); + + let weight = Config::Weigher::weight_of(&mut message) + .map_err(|_| XcmError::Undefined)?; + + Config::Barrier::should_execute(&origin, top_level, &message,weight, weight_credit) + .map_err(|()| XcmError::Undefined)?; + + let (mut holding, effects) = match (origin.clone(), message) { (origin, Xcm::WithdrawAsset { assets, effects }) => { // Take `assets` from the origin account (on-chain) and place in holding. let mut holding = Assets::default(); @@ -68,45 +94,42 @@ impl ExecuteXcm for XcmExecutor { Err(XcmError::UntrustedTeleportLocation)? } } - (origin, Xcm::Transact { origin_type, call }) => { + (origin, Xcm::Transact { origin_type, max_weight, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. - // TODO: Weight fees should be paid. - // TODO: allow this to be configurable in the trait. // TODO: allow the trait to issue filters for the relay-chain - let message_call = Config::Call::decode(&mut &call[..]).map_err(|_| XcmError::FailedToDecode)?; + let message_call = call.take_decoded().map_err(|_| XcmError::FailedToDecode)?; let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_type) .map_err(|_| XcmError::BadOrigin)?; - let _ok = message_call.dispatch(dispatch_origin).is_ok(); - // Not much to do with the result as it is. It's up to the parachain to ensure that the - // message makes sense. + let weight = message_call.get_dispatch_info().weight; + ensure!(max_weight >= weight, XcmError::Undefined); + let actual_weight = match message_call.dispatch(dispatch_origin) { + Ok(post_info) => post_info.actual_weight, + Err(error_and_info) => { + // Not much to do with the result as it is. It's up to the parachain to ensure that the + // message makes sense. + error_and_info.post_info.actual_weight + } + }.unwrap_or(weight); + let _surplus_weight = max_weight - actual_weight; + + // TODO: reduce used_weight by surplus_weight. + // FUTURE: Here is where we could provide surplus_weight to Config::Barrier if we wanted to + // support transact weight surplus crediting. return Ok(()); } _ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message. }; - // TODO: stuff that should happen after holding is populated but before effects, - // including depositing fees for effects from holding account. - for effect in effects.into_iter() { let _ = Self::execute_effects(&origin, &mut holding, effect)?; } - // TODO: stuff that should happen after effects including refunding unused fees. - Ok(()) } -} - -impl XcmExecutor { - fn reanchored(mut assets: Assets, dest: &MultiLocation) -> Vec { - let inv_dest = Config::LocationInverter::invert_location(&dest); - assets.reanchor(&inv_dest); - assets.into_assets_iter().collect::>() - } - fn execute_effects(_origin: &MultiLocation, holding: &mut Assets, effect: Order) -> XcmResult { + fn execute_effects(origin: &MultiLocation, holding: &mut Assets, effect: Order) -> XcmResult { match effect { Order::DepositAsset { assets, dest } => { let deposited = holding.saturating_take(assets); @@ -135,6 +158,24 @@ impl XcmExecutor { let assets = Self::reanchored(holding.min(assets.iter()), &dest); Config::XcmSender::send_xcm(dest, Xcm::Balances { query_id, assets }) } + Order::BuyExecution { fees, weight, halt_on_error, xcm } => { + // pay for `weight` using up to `fees` of the holding account. + let desired_weight = Weight::from(weight); + let max_fee = holding.checked_sub_assign(fees).map_err(|()| XcmError::Undefined)?; + let surplus = Config::Sale::buy_weight(desired_weight, max_fee)?; + holding.saturating_subsume_all(surplus); + let mut remaining_weight= desired_weight; + for message in xcm.into_iter() { + match Self::do_execute_xcm(origin.clone(), false, message, &mut remaining_weight) { + Err(e) if halt_on_error => return Err(e), + _ => {} + } + } + Ok(()) + + // FUTURE: Here is where we would provide surplus_weight to Config::Barrier if we wanted to + // support weight refunding + } _ => Err(XcmError::UnhandledEffect)?, } } From b908c5b965d448a47cd0533dc03b4b3d8841826c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 2 Apr 2021 23:18:29 +0200 Subject: [PATCH 06/40] Introduce fee payment mechanics into XCM. --- xcm/src/v0/mod.rs | 14 ++++----- xcm/src/v0/order.rs | 33 ++++++++++++--------- xcm/xcm-executor/src/config.rs | 52 ++++++++++++++-------------------- xcm/xcm-executor/src/lib.rs | 47 +++++++++++++++++------------- 4 files changed, 75 insertions(+), 71 deletions(-) diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index feb1929e0822..6b6d709bc339 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -29,7 +29,7 @@ mod traits; pub use junction::{Junction, NetworkId}; pub use multi_asset::{MultiAsset, AssetInstance}; pub use multi_location::MultiLocation; -pub use order::Order; +pub use order::{Order, OrderGeneric}; pub use traits::{Error, Result, SendXcm, ExecuteXcm}; // TODO: Efficient encodings for Vec, Vec, using initial byte values 128+ to encode the number of @@ -70,7 +70,7 @@ pub enum XcmGeneric { /// Kind: *Instruction*. /// /// Errors: - WithdrawAsset { assets: Vec, effects: Vec> }, + WithdrawAsset { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system. /// @@ -86,7 +86,7 @@ pub enum XcmGeneric { /// Kind: *Trusted Indication*. /// /// Errors: - ReserveAssetDeposit { assets: Vec, effects: Vec> }, + ReserveAssetDeposit { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be /// created on this system. @@ -103,7 +103,7 @@ pub enum XcmGeneric { /// Kind: *Trusted Indication*. /// /// Errors: - TeleportAsset { assets: Vec, effects: Vec> }, + TeleportAsset { assets: Vec, effects: Vec> }, /// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`. /// @@ -215,11 +215,11 @@ impl XcmGeneric { use XcmGeneric::*; match xcm { WithdrawAsset { assets, effects } - => WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, + => WithdrawAsset { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, ReserveAssetDeposit { assets, effects } - => ReserveAssetDeposit { assets, effects: effects.into_iter().map(Order::into).collect() }, + => ReserveAssetDeposit { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, TeleportAsset { assets, effects } - => TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, + => TeleportAsset { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, Balances { query_id: u64, assets } => Balances { query_id: u64, assets }, Unused4 diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs index 71d7ab814663..398947857e6a 100644 --- a/xcm/src/v0/order.rs +++ b/xcm/src/v0/order.rs @@ -22,7 +22,8 @@ use super::{MultiAsset, MultiLocation, XcmGeneric}; /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] -pub enum Order { +#[codec(dumb_trait_bound)] +pub enum OrderGeneric { /// Do nothing. Not generally used. Null, @@ -46,7 +47,7 @@ pub enum Order { /// `dest. /// /// Errors: - DepositReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec> }, + DepositReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec }, /// Remove the asset(s) (`give`) from holding and replace them with alternative assets. /// @@ -68,7 +69,7 @@ pub enum Order { /// - `effects`: The orders to execute on the assets once withdrawn *on the reserve location*. /// /// Errors: - InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec> }, + InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec }, /// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location. /// @@ -77,7 +78,7 @@ pub enum Order { /// - `effects`: The orders to execute on the assets once arrived *on the destination location*. /// /// Errors: - InitiateTeleport { assets: Vec, dest: MultiLocation, effects: Vec> }, + InitiateTeleport { assets: Vec, dest: MultiLocation, effects: Vec }, /// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof. /// @@ -94,29 +95,33 @@ pub enum Order { /// up to `fees` from the holding account. /// /// Errors: - BuyExecution { fees: MultiAsset, weight: u64, halt_on_error: bool, xcm: Vec> }, + BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec> }, } -impl Order { - pub fn into(self) -> Order { Order::from(self) } - pub fn from(xcm: Order) -> Self { - use Order::*; - match xcm { +pub type Order = OrderGeneric<()>; + +impl OrderGeneric { + pub fn into(self) -> OrderGeneric { OrderGeneric::from(self) } + pub fn from(order: OrderGeneric) -> Self { + use OrderGeneric::*; + match order { Null => Null, DepositAsset { assets, dest } => DepositAsset { assets, dest }, DepositReserveAsset { assets, dest, effects } - => DepositReserveAsset { assets, dest, effects: effects.map(Order::from) }, + => DepositReserveAsset { assets, dest, effects }, ExchangeAsset { give, receive } => ExchangeAsset { give, receive }, InitiateReserveWithdraw { assets, reserve, effects } - => InitiateReserveWithdraw { assets, reserve, effects: effects.map(Order::from) }, + => InitiateReserveWithdraw { assets, reserve, effects }, InitiateTeleport { assets, dest, effects } => InitiateTeleport { assets, dest, effects }, QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest, assets }, - BuyExecution { fees, weight, halt_on_error, xcm } - => BuyExecution { fees, weight, halt_on_error, xcm: xcm.map(XcmGeneric::from) }, + BuyExecution { fees, weight, debt, halt_on_error, xcm } => { + let xcm = xcm.into_iter().map(XcmGeneric::from).collect(); + BuyExecution { fees, weight, debt, halt_on_error, xcm } + }, } } } diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index 2b4733bd8a95..0791aa4f1d76 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -15,7 +15,8 @@ // along with Polkadot. If not, see . use sp_std::marker::PhantomData; -use xcm::v0::{Xcm, SendXcm, MultiLocation, MultiAsset, Order, XcmGeneric}; +use parity_scale_codec::Decode; +use xcm::v0::{Xcm, SendXcm, MultiLocation, MultiAsset, Order, XcmGeneric, OrderGeneric}; use frame_support::{ ensure, dispatch::{Dispatchable, Parameter, Weight}, weights::{PostDispatchInfo, GetDispatchInfo} }; @@ -30,28 +31,19 @@ pub trait WeightOf { } pub struct FixedWeightOf(PhantomData<(T, C)>); -impl, C: GetDispatchInfo> WeightOf for FixedWeightOf { +impl, C: Decode + GetDispatchInfo> WeightOf for FixedWeightOf { fn weight_of(message: &mut XcmGeneric) -> Result { Ok(match message { XcmGeneric::Transact { call, .. } => { - call.ensure_decoded()?; - call.as_ref().get_dispatch_info().weight + T::get() + call.ensure_decoded()?.get_dispatch_info().weight + T::get() } XcmGeneric::WithdrawAsset { effects, .. } | XcmGeneric::ReserveAssetDeposit { effects, .. } | XcmGeneric::TeleportAsset { effects, .. } => { - let mut total = 0; - for effect in effects.iter_mut() { - match effect { - Order::BuyExecution { xcm, .. } => { - for xcm in xcm.iter_mut() { - total = total.checked_add(Self::weight_of(xcm)?).ok_or(())? - } - } - _ => total = total.checked_add(T::get()) - } - } - total + effects.iter() + .map(|effect| match effect { + _ => T::get(), + }).sum() } _ => T::get(), }) @@ -93,10 +85,10 @@ pub trait ShouldExecute { /// - `weight_credit`: The pre-established amount of weight that the system has determined this message /// may utilise in its execution. Typically non-zero only because of prior fee payment, but could /// in principle be due to other factors. - fn should_execute( + fn should_execute( origin: &MultiLocation, top_level: bool, - message: &Xcm, + message: &XcmGeneric, message_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()>; @@ -104,10 +96,10 @@ pub trait ShouldExecute { #[impl_trait_for_tuples::impl_for_tuples(30)] impl ShouldExecute for Tuple { - fn should_execute( + fn should_execute( origin: &MultiLocation, top_level: bool, - message: &Xcm, + message: &XcmGeneric, message_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { @@ -123,10 +115,10 @@ impl ShouldExecute for Tuple { pub struct TakeWeightCredit; impl ShouldExecute for TakeWeightCredit { - fn should_execute( + fn should_execute( _origin: &MultiLocation, _top_level: bool, - _message: &Xcm, + _message: &XcmGeneric, message_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { @@ -137,22 +129,22 @@ impl ShouldExecute for TakeWeightCredit { pub struct AllowTopLevelPaidExecutionFrom(PhantomData); impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { - fn should_execute( + fn should_execute( origin: &MultiLocation, top_level: bool, - message: &Xcm, + message: &XcmGeneric, message_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { ensure!(T::contains(origin), ()); ensure!(top_level, ()); match message { - Xcm::TeleportAsset { effects, .. } - | Xcm::WithdrawAsset { effects, ..} - | Xcm::ReserveAssetDeposit { effects, ..} + XcmGeneric::TeleportAsset { effects, .. } + | XcmGeneric::WithdrawAsset { effects, ..} + | XcmGeneric::ReserveAssetDeposit { effects, ..} if matches!( effects.first(), - Some(Order::BuyExecution { weight, ..}) if *weight >= message_weight + Some(OrderGeneric::BuyExecution { debt, ..}) if *debt >= message_weight ) => Ok(()), _ => Err(()), @@ -162,10 +154,10 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro pub struct AllowUnpaidExecutionFrom(PhantomData); impl> ShouldExecute for AllowUnpaidExecutionFrom { - fn should_execute( + fn should_execute( origin: &MultiLocation, _top_level: bool, - _message: &Xcm, + _message: &XcmGeneric, _message_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index cbcb2d23df5a..d96e295091a8 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -24,7 +24,7 @@ use frame_support::{ use parity_scale_codec::{self as codec, Encode, Decode}; use xcm::v0::{ Xcm, Order, ExecuteXcm, SendXcm, Error as XcmError, Result as XcmResult, - MultiLocation, MultiAsset, XcmGeneric, + MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, }; pub mod traits; @@ -41,8 +41,10 @@ pub struct XcmExecutor(PhantomData); // TODO: Use XcmGeneric/VersionedXcmGeneric and a new `EncodedCall` type which can decode when needed for weight. impl ExecuteXcm for XcmExecutor { - fn execute_xcm(origin: MultiLocation, msg: Xcm) -> XcmResult { - Self::do_execute_xcm(origin, true, msg, &mut 0) + fn execute_xcm(origin: MultiLocation, message: Xcm) -> XcmResult { + // TODO: We should identify recursive bombs here and bail. + let message = XcmGeneric::::from(message); + Self::do_execute_xcm(origin, true, message, &mut 0) } } @@ -53,17 +55,22 @@ impl XcmExecutor { assets.into_assets_iter().collect::>() } - fn do_execute_xcm(origin: MultiLocation, top_level: bool, message: Xcm, weight_credit: &mut Weight) -> XcmResult { - let message = XcmGeneric::::from(message); - - let weight = Config::Weigher::weight_of(&mut message) + fn do_execute_xcm( + origin: MultiLocation, + top_level: bool, + mut message: XcmGeneric, + weight_credit: &mut Weight, + ) -> XcmResult { + // This is the weight of everything that cannot be paid for. This basically means all computation + // except any XCM which is behind an Order::BuyExecution. + let unpaid_weight = Config::Weigher::weight_of(&mut message) .map_err(|_| XcmError::Undefined)?; - Config::Barrier::should_execute(&origin, top_level, &message,weight, weight_credit) + Config::Barrier::should_execute(&origin, top_level, &message,unpaid_weight, weight_credit) .map_err(|()| XcmError::Undefined)?; let (mut holding, effects) = match (origin.clone(), message) { - (origin, Xcm::WithdrawAsset { assets, effects }) => { + (origin, XcmGeneric::WithdrawAsset { assets, effects }) => { // Take `assets` from the origin account (on-chain) and place in holding. let mut holding = Assets::default(); for asset in assets { @@ -72,7 +79,7 @@ impl XcmExecutor { } (holding, effects) } - (origin, Xcm::ReserveAssetDeposit { assets, effects }) => { + (origin, XcmGeneric::ReserveAssetDeposit { assets, effects }) => { // check whether we trust origin to be our reserve location for this asset. if assets.iter().all(|asset| Config::IsReserve::filter_asset_location(asset, &origin)) { // We only trust the origin to send us assets that they identify as their @@ -82,7 +89,7 @@ impl XcmExecutor { Err(XcmError::UntrustedReserveLocation)? } } - (origin, Xcm::TeleportAsset { assets, effects }) => { + (origin, XcmGeneric::TeleportAsset { assets, effects }) => { // check whether we trust origin to teleport this asset to us via config trait. // TODO: should de-wildcard `assets` before passing in. log::debug!(target: "runtime::xcm-executor", "Teleport from {:?}", origin); @@ -94,7 +101,7 @@ impl XcmExecutor { Err(XcmError::UntrustedTeleportLocation)? } } - (origin, Xcm::Transact { origin_type, max_weight, mut call }) => { + (origin, XcmGeneric::Transact { origin_type, max_weight, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. // TODO: allow this to be configurable in the trait. @@ -129,16 +136,16 @@ impl XcmExecutor { Ok(()) } - fn execute_effects(origin: &MultiLocation, holding: &mut Assets, effect: Order) -> XcmResult { + fn execute_effects(origin: &MultiLocation, holding: &mut Assets, effect: OrderGeneric) -> XcmResult { match effect { - Order::DepositAsset { assets, dest } => { + OrderGeneric::DepositAsset { assets, dest } => { let deposited = holding.saturating_take(assets); for asset in deposited.into_assets_iter() { Config::AssetTransactor::deposit_asset(&asset, &dest)?; } Ok(()) }, - Order::DepositReserveAsset { assets, dest, effects } => { + OrderGeneric::DepositReserveAsset { assets, dest, effects } => { let deposited = holding.saturating_take(assets); for asset in deposited.assets_iter() { Config::AssetTransactor::deposit_asset(&asset, &dest)?; @@ -146,21 +153,21 @@ impl XcmExecutor { let assets = Self::reanchored(deposited, &dest); Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects }) }, - Order::InitiateReserveWithdraw { assets, reserve, effects} => { + OrderGeneric::InitiateReserveWithdraw { assets, reserve, effects} => { let assets = Self::reanchored(holding.saturating_take(assets), &reserve); Config::XcmSender::send_xcm(reserve, Xcm::WithdrawAsset { assets, effects }) } - Order::InitiateTeleport { assets, dest, effects} => { + OrderGeneric::InitiateTeleport { assets, dest, effects} => { let assets = Self::reanchored(holding.saturating_take(assets), &dest); Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects }) } - Order::QueryHolding { query_id, dest, assets } => { + OrderGeneric::QueryHolding { query_id, dest, assets } => { let assets = Self::reanchored(holding.min(assets.iter()), &dest); Config::XcmSender::send_xcm(dest, Xcm::Balances { query_id, assets }) } - Order::BuyExecution { fees, weight, halt_on_error, xcm } => { + OrderGeneric::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { // pay for `weight` using up to `fees` of the holding account. - let desired_weight = Weight::from(weight); + let desired_weight = Weight::from(weight + debt); let max_fee = holding.checked_sub_assign(fees).map_err(|()| XcmError::Undefined)?; let surplus = Config::Sale::buy_weight(desired_weight, max_fee)?; holding.saturating_subsume_all(surplus); From 03fa34c66cd6fef5211b100734be9fadf52d0441 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 3 Apr 2021 18:57:55 +0200 Subject: [PATCH 07/40] Weight limitations on XCM execution --- xcm/src/double_encoded.rs | 2 +- xcm/src/v0/mod.rs | 6 +- xcm/src/v0/multi_asset.rs | 12 ++++ xcm/src/v0/order.rs | 2 +- xcm/src/v0/traits.rs | 6 +- xcm/xcm-executor/src/assets.rs | 52 ++++++++++----- xcm/xcm-executor/src/config.rs | 113 +++++++++++++++++++++++--------- xcm/xcm-executor/src/lib.rs | 114 +++++++++++++++++++-------------- 8 files changed, 207 insertions(+), 100 deletions(-) diff --git a/xcm/src/double_encoded.rs b/xcm/src/double_encoded.rs index ceec6e217d55..02b2117d457f 100644 --- a/xcm/src/double_encoded.rs +++ b/xcm/src/double_encoded.rs @@ -54,7 +54,7 @@ impl DoubleEncoded { self.decoded.take().or_else(|| T::decode(&mut &self.encoded[..]).ok()).ok_or(()) } pub fn try_into(mut self) -> Result { - self.ensure_decoded(); + self.ensure_decoded()?; self.decoded.ok_or(()) } } diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 6b6d709bc339..4c075371a1d4 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -183,7 +183,7 @@ pub enum XcmGeneric { /// Kind: *Instruction*. /// /// Errors: - Transact { origin_type: OriginKind, max_weight: u64, call: DoubleEncoded }, + Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded }, } /// The basic concrete type of `XcmGeneric`, which doesn't make any assumptions about the format of a @@ -234,8 +234,8 @@ impl XcmGeneric { => HrmpChannelAccepted { recipient}, HrmpChannelClosing { initiator, sender, recipient} => HrmpChannelClosing { initiator, sender, recipient}, - Transact { origin_type, max_weight, call} - => Transact { origin_type, max_weight, call: call.into() } + Transact { origin_type, require_weight_at_most, call} + => Transact { origin_type, require_weight_at_most, call: call.into() } } } } diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs index 700bc78d60ba..ee0424c58a02 100644 --- a/xcm/src/v0/multi_asset.rs +++ b/xcm/src/v0/multi_asset.rs @@ -146,6 +146,18 @@ pub enum MultiAsset { ConcreteNonFungible { class: MultiLocation, instance: AssetInstance }, } +impl MultiAsset { + pub fn is_wildcard(&self) -> bool { + use MultiAsset::*; + match self { + None | AbstractFungible {..} | AbstractNonFungible {..} + | ConcreteFungible {..} | ConcreteNonFungible {..} => false, + All | AllFungible | AllNonFungible | AllAbstractFungible {..} | AllConcreteFungible {..} + | AllAbstractNonFungible {..} | AllConcreteNonFungible {..} => true, + } + } +} + impl From for VersionedMultiAsset { fn from(x: MultiAsset) -> Self { VersionedMultiAsset::V0(x) diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs index 398947857e6a..6795665acb68 100644 --- a/xcm/src/v0/order.rs +++ b/xcm/src/v0/order.rs @@ -91,7 +91,7 @@ pub enum OrderGeneric { /// Errors: QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: Vec }, - /// Pay for the execution of some Xcm with up to `weight` ps of execution time, paying for this with + /// Pay for the execution of some Xcm with up to `weight` picoseconds of execution time, paying for this with /// up to `fees` from the holding account. /// /// Errors: diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs index 542db15dd031..60d689d80d7a 100644 --- a/xcm/src/v0/traits.rs +++ b/xcm/src/v0/traits.rs @@ -38,6 +38,8 @@ pub enum Error { BadOrigin, ExceedsMaxMessageSize, FailedToTransactAsset(#[codec(skip)] &'static str), + WeightLimitReached, + Wildcard, } impl From<()> for Error { @@ -49,11 +51,11 @@ impl From<()> for Error { pub type Result = result::Result<(), Error>; pub trait ExecuteXcm { - fn execute_xcm(origin: MultiLocation, msg: Xcm) -> Result; + fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: u64) -> result::Result; } impl ExecuteXcm for () { - fn execute_xcm(_origin: MultiLocation, _msg: Xcm) -> Result { + fn execute_xcm(_origin: MultiLocation, _message: Xcm, _weight_limit: u64) -> result::Result { Err(Error::Unimplemented) } } diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs index d7acf86369e2..beff9027d9d6 100644 --- a/xcm/xcm-executor/src/assets.rs +++ b/xcm/xcm-executor/src/assets.rs @@ -33,12 +33,18 @@ impl AssetId { } Ok(()) } + + /// Use the value of `self` along with an `amount to create the corresponding `MultiAsset` value for a + /// fungible asset. pub fn into_fungible_multiasset(self, amount: u128) -> MultiAsset { match self { AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount }, AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount }, } } + + /// Use the value of `self` along with an `instance to create the corresponding `MultiAsset` value for a + /// non-fungible asset. pub fn into_non_fungible_multiasset(self, instance: AssetInstance) -> MultiAsset { match self { AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance }, @@ -47,11 +53,13 @@ impl AssetId { } } -/// List of concretely identified fungible and non-fungible assets. +/// List of non-wildcard fungible and non-fungible assets. #[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)] pub struct Assets { + /// The fungible assets. pub fungible: BTreeMap, + /// The non-fungible assets. // OPTIMIZE: Consider BTreeMap> // or even BTreeMap> pub non_fungible: BTreeSet<(AssetId, AssetInstance)>, @@ -82,8 +90,16 @@ impl From for Assets { } impl Assets { + /// New value, containing no assets. pub fn new() -> Self { Self::default() } + /// Substitute all abstract `MultiAsset` values for equivalent concrete values. + /// + /// If at least one of the values cannot be substituted, then return Err. + pub fn concretize(&mut self) -> Result<(), ()> { + todo!(); + } + /// An iterator over the fungible assets. pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator + 'a { self.fungible.iter() @@ -124,6 +140,9 @@ impl Assets { fungible.chain(non_fungible) } + /// Mutate `self` to contain all given `assets`, saturating if necessary. + /// + /// Wildcards in `assets` are ignored. pub fn saturating_subsume_all(&mut self, assets: Assets) { // OPTIMIZE: Could be done with a much faster btree entry merge and only sum the entries with the // same key. @@ -132,8 +151,9 @@ impl Assets { } } - /// Modify `self` to include a `MultiAsset`, saturating if necessary. - /// Only works on concretely identified assets; wildcards will be swallowed without error. + /// Mutate `self` to contain the given `asset`, saturating if necessary. + /// + /// Wildcard values of `asset` do nothing. pub fn saturating_subsume(&mut self, asset: MultiAsset) { match asset { MultiAsset::ConcreteFungible { id, amount } => { @@ -152,30 +172,30 @@ impl Assets { } } - /// Consumes `self` and returns `Ok` iff it contains at least `asset`. + /// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`. /// - /// Wildcard assets in `self` are not supported and will result in an error. + /// Wildcard assets in `self` will result in an error. /// - /// `asset` may be a wildcard. + /// `asset` may be a wildcard and are evaluated in the context of `self`. /// /// Returns `Ok` with the `self` minus `asset` and the non-wildcard equivalence of `asset` taken if `self` /// contains `asset`, and `Err` with `self` otherwise. - pub fn checked_sub(mut self, asset: MultiAsset) -> Result<(Self, Assets), Self> { - match self.checked_sub_assign(asset) { + pub fn less(mut self, asset: MultiAsset) -> Result<(Self, Assets), Self> { + match self.try_take(asset) { Ok(taken) => Ok((self, taken)), Err(()) => Err(self), } } - /// Mutates `self` and returns `true` iff it contains at least `asset`. + /// Mutates `self` to its original value less `asset` and returns `true` iff it contains at least `asset`. /// - /// Wildcard assets in `self` are not supported and will result in an error. + /// Wildcard assets in `self` will result in an error. /// - /// `asset` may be a wildcard. + /// `asset` may be a wildcard and are evaluated in the context of `self`. /// /// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus /// `asset` if `self` contains `asset`, and return `Err` otherwise. - pub fn checked_sub_assign(&mut self, asset: MultiAsset) -> Result { + pub fn try_take(&mut self, asset: MultiAsset) -> Result { match asset { MultiAsset::None => Ok(Assets::new()), MultiAsset::ConcreteFungible { id, amount } => self.try_take_fungible(AssetId::Concrete(id), amount), @@ -201,13 +221,13 @@ impl Assets { } pub fn try_take_fungible(&mut self, id: AssetId, amount: u128) -> Result { - self.checked_sub_assign_fungible(&id, amount)?; + self.try_remove_fungible(&id, amount)?; Ok(id.into_fungible_multiasset(amount).into()) } pub fn try_take_non_fungible(&mut self, id: AssetId, instance: AssetInstance) -> Result { let asset_id_instance = (id, instance); - self.checked_sub_assign_non_fungible(&asset_id_instance)?; + self.try_remove_non_fungible(&asset_id_instance)?; let (asset_id, instance) = asset_id_instance; Ok(asset_id.into_non_fungible_multiasset(instance).into()) } @@ -233,13 +253,13 @@ impl Assets { taken } - pub fn checked_sub_assign_fungible(&mut self, id: &AssetId, amount: u128) -> Result<(), ()> { + pub fn try_remove_fungible(&mut self, id: &AssetId, amount: u128) -> Result<(), ()> { let self_amount = self.fungible.get_mut(&id).ok_or(())?; *self_amount = self_amount.checked_sub(amount).ok_or(())?; Ok(()) } - pub fn checked_sub_assign_non_fungible(&mut self, class_instance: &(AssetId, AssetInstance)) -> Result<(), ()> { + pub fn try_remove_non_fungible(&mut self, class_instance: &(AssetId, AssetInstance)) -> Result<(), ()> { match self.non_fungible.remove(class_instance) { true => Ok(()), false => Err(()), diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index 0791aa4f1d76..d26ab6ee8474 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -16,7 +16,7 @@ use sp_std::marker::PhantomData; use parity_scale_codec::Decode; -use xcm::v0::{Xcm, SendXcm, MultiLocation, MultiAsset, Order, XcmGeneric, OrderGeneric}; +use xcm::v0::{SendXcm, MultiLocation, MultiAsset, XcmGeneric, OrderGeneric}; use frame_support::{ ensure, dispatch::{Dispatchable, Parameter, Weight}, weights::{PostDispatchInfo, GetDispatchInfo} }; @@ -25,37 +25,91 @@ use crate::traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLoc use crate::assets::Assets; /// Determine the weight of an XCM message. -pub trait WeightOf { - /// Return the weight of `message`. - fn weight_of(message: &mut XcmGeneric) -> Result; +pub trait WeightBounds { + /// Return the minimum amount of weight that an attempted execution of this message would definitely + /// consume. + /// + /// This is useful to gauge how many fees should be paid up front to begin execution of the message. + /// It is not useful for determining whether execution should begin lest it result in surpassing weight + /// limits - in that case `deep` is the function to use. + fn immediate(message: &mut XcmGeneric) -> Result; + + /// Return the additional amount of weight, over `shallow` that complete and successful execution of + /// `message` would incur. + /// + /// This is perhaps overly pessimistic for determining how many fees should be paid for up-front since + /// fee payment (or any other way of offsetting the execution costs such as an voucher-style NFT) may + /// happen in stages throughout execution of the XCM. + fn additional(message: &mut XcmGeneric) -> Result; } -pub struct FixedWeightOf(PhantomData<(T, C)>); -impl, C: Decode + GetDispatchInfo> WeightOf for FixedWeightOf { - fn weight_of(message: &mut XcmGeneric) -> Result { - Ok(match message { +pub struct FixedWeightBounds(PhantomData<(T, C)>); +impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeightBounds { + fn immediate(message: &mut XcmGeneric) -> Result { + let min = match message { XcmGeneric::Transact { call, .. } => { call.ensure_decoded()?.get_dispatch_info().weight + T::get() } XcmGeneric::WithdrawAsset { effects, .. } | XcmGeneric::ReserveAssetDeposit { effects, .. } | XcmGeneric::TeleportAsset { effects, .. } => { - effects.iter() + let inner: Weight = effects.iter_mut() .map(|effect| match effect { + OrderGeneric::BuyExecution { .. } => { + // On success, execution of this will result in more weight being consumed but + // we don't count it here since this is only the *immediate*, non-negotiable weight + // spend and doesn't count weight placed behind a `BuyExecution` since it will not + // be definitely consumed from any existing weight credit if execution of the message + // is attempted. + T::get() + }, _ => T::get(), - }).sum() + }).sum(); + T::get() + inner } _ => T::get(), - }) + }; + Ok(min) + } + fn additional(message: &mut XcmGeneric) -> Result { + let mut extra = 0; + match message { + XcmGeneric::Transact { .. } => {} + XcmGeneric::WithdrawAsset { effects, .. } + | XcmGeneric::ReserveAssetDeposit { effects, .. } + | XcmGeneric::TeleportAsset { effects, .. } => { + for effect in effects.iter_mut() { + match effect { + OrderGeneric::BuyExecution { xcm, .. } => { + for message in xcm.iter_mut() { + extra += Self::immediate(message)? + Self::additional(message)?; + } + }, + _ => {} + } + } + } + _ => {} + }; + Ok(extra) } } -/// Charge the for a given XCM message. -pub trait BuyWeight { +/// Charge for weight in order to execute XCM. +pub trait WeightTrader { + /// Create a new trader instance. + fn new() -> Self; + /// Purchase execution weight credit in return for up to a given `fee`. If less of the fee is required /// then the surplus is returned. If the `fee` cannot be used to pay for the `weight`, then an error is /// returned. - fn buy_weight(weight: Weight, payment: Assets) -> Result; + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result; + + /// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight was + /// purchased using `buy_weight`. + /// + /// Default implementation refunds nothing. + fn refund_weight(&mut self, _weight: Weight) -> MultiAsset { MultiAsset::None } } /// Simple fee calculator that requires payment in a single concrete fungible at a fixed rate. @@ -63,12 +117,13 @@ pub trait BuyWeight { /// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for /// one second of weight. pub struct FixedRateOfConcreteFungible(PhantomData); -impl> BuyWeight for FixedRateOfConcreteFungible { - fn buy_weight(weight: Weight, payment: Assets) -> Result { +impl> WeightTrader for FixedRateOfConcreteFungible { + fn new() -> Self { Self(PhantomData) } + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { let (required_id, units_per_second) = T::get(); let required_amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; let required = MultiAsset::ConcreteFungible { amount: required_amount, id: required_id }; - Ok(payment.checked_sub(required).map_err(|_| ())?.0) + Ok(payment.less(required).map_err(|_| ())?.0) } } @@ -80,8 +135,8 @@ pub trait ShouldExecute { /// - `top_level`: `true`` indicates the initial XCM coming from the `origin`, `false` indicates an embedded /// XCM executed internally as part of another message or an `Order`. /// - `message`: The message itself. - /// - `message_weight`: The weight of the message; the actual weight of the message is guaranteed to be - /// no greater than this. + /// - `immediate_weight`: The weight of the non-negotiable execution of the message. This does not include any + /// embedded XCMs sat behind mechanisms like `BuyExecution` which would need to answer for their own weight. /// - `weight_credit`: The pre-established amount of weight that the system has determined this message /// may utilise in its execution. Typically non-zero only because of prior fee payment, but could /// in principle be due to other factors. @@ -89,7 +144,7 @@ pub trait ShouldExecute { origin: &MultiLocation, top_level: bool, message: &XcmGeneric, - message_weight: Weight, + immediate_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()>; } @@ -100,11 +155,11 @@ impl ShouldExecute for Tuple { origin: &MultiLocation, top_level: bool, message: &XcmGeneric, - message_weight: Weight, + immediate_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { for_tuples!( #( - match Tuple::should_execute(origin, top_level, message, message_weight, weight_credit) { + match Tuple::should_execute(origin, top_level, message, immediate_weight, weight_credit) { o @ Ok(()) => return o, _ => (), } @@ -119,10 +174,10 @@ impl ShouldExecute for TakeWeightCredit { _origin: &MultiLocation, _top_level: bool, _message: &XcmGeneric, - message_weight: Weight, + immediate_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { - *weight_credit = weight_credit.checked_sub(message_weight).ok_or(())?; + *weight_credit = weight_credit.checked_sub(immediate_weight).ok_or(())?; Ok(()) } } @@ -133,7 +188,7 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro origin: &MultiLocation, top_level: bool, message: &XcmGeneric, - message_weight: Weight, + immediate_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { ensure!(T::contains(origin), ()); @@ -144,7 +199,7 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro | XcmGeneric::ReserveAssetDeposit { effects, ..} if matches!( effects.first(), - Some(OrderGeneric::BuyExecution { debt, ..}) if *debt >= message_weight + Some(OrderGeneric::BuyExecution { debt, ..}) if *debt >= immediate_weight ) => Ok(()), _ => Err(()), @@ -158,7 +213,7 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { origin: &MultiLocation, _top_level: bool, _message: &XcmGeneric, - _message_weight: Weight, + _immediate_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { ensure!(T::contains(origin), ()); @@ -193,8 +248,8 @@ pub trait Config { type Barrier: ShouldExecute; /// The means of determining an XCM message's weight. - type Weigher: WeightOf; + type Weigher: WeightBounds; /// The means of purchasing weight credit for XCM execution. - type Sale: BuyWeight; + type Trader: WeightTrader; } diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index d96e295091a8..6a797e2e3e95 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -21,9 +21,8 @@ use frame_support::{ ensure, weights::GetDispatchInfo, dispatch::{Weight, Dispatchable} }; -use parity_scale_codec::{self as codec, Encode, Decode}; use xcm::v0::{ - Xcm, Order, ExecuteXcm, SendXcm, Error as XcmError, Result as XcmResult, + Xcm, ExecuteXcm, SendXcm, Error as XcmError, MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, }; @@ -33,18 +32,22 @@ use traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; mod assets; pub use assets::{Assets, AssetId}; mod config; -pub use config::{Config, WeightOf, BuyWeight, ShouldExecute}; +pub use config::{Config, WeightBounds, WeightTrader, ShouldExecute}; pub struct XcmExecutor(PhantomData); -// TODO: Introduce max_weight and return used_weight. -// TODO: Use XcmGeneric/VersionedXcmGeneric and a new `EncodedCall` type which can decode when needed for weight. - impl ExecuteXcm for XcmExecutor { - fn execute_xcm(origin: MultiLocation, message: Xcm) -> XcmResult { + fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Result { // TODO: We should identify recursive bombs here and bail. - let message = XcmGeneric::::from(message); - Self::do_execute_xcm(origin, true, message, &mut 0) + let mut message = XcmGeneric::::from(message); + let immediate_weight = Config::Weigher::immediate(&mut message)?; + let additional_weight = Config::Weigher::additional(&mut message)?; + let maximum_weight = immediate_weight.checked_add(additional_weight) + .ok_or(XcmError::WeightLimitReached)?; + ensure!(maximum_weight <= weight_limit, XcmError::WeightLimitReached); + let mut trader = Config::Trader::new(); + let surplus = Self::do_execute_xcm(origin, true, message, &mut 0, Some(immediate_weight), &mut trader)?; + Ok(maximum_weight.saturating_sub(surplus)) } } @@ -55,25 +58,35 @@ impl XcmExecutor { assets.into_assets_iter().collect::>() } + /// Execute the XCM and return any unexpected and unknowable surplus weight. fn do_execute_xcm( origin: MultiLocation, top_level: bool, mut message: XcmGeneric, weight_credit: &mut Weight, - ) -> XcmResult { + maybe_immediate_weight: Option, + trader: &mut Config::Trader, + ) -> Result { // This is the weight of everything that cannot be paid for. This basically means all computation // except any XCM which is behind an Order::BuyExecution. - let unpaid_weight = Config::Weigher::weight_of(&mut message) - .map_err(|_| XcmError::Undefined)?; + let immediate_weight = maybe_immediate_weight + .or_else(|| Config::Weigher::immediate(&mut message).ok()) + .ok_or(XcmError::Undefined)?; - Config::Barrier::should_execute(&origin, top_level, &message,unpaid_weight, weight_credit) + Config::Barrier::should_execute(&origin, top_level, &message, immediate_weight, weight_credit) .map_err(|()| XcmError::Undefined)?; + // The surplus weight, defined as the amount by which `immediate_weight` plus all nested + // `immediate_weight` values (ensuring no double-counting) is an overestimate of the actual weight + // consumed. + let mut total_surplus = 0; + let (mut holding, effects) = match (origin.clone(), message) { (origin, XcmGeneric::WithdrawAsset { assets, effects }) => { // Take `assets` from the origin account (on-chain) and place in holding. let mut holding = Assets::default(); for asset in assets { + ensure!(!asset.is_wildcard(), XcmError::Wildcard); let withdrawn = Config::AssetTransactor::withdraw_asset(&asset, &origin)?; holding.saturating_subsume(withdrawn); } @@ -81,27 +94,25 @@ impl XcmExecutor { } (origin, XcmGeneric::ReserveAssetDeposit { assets, effects }) => { // check whether we trust origin to be our reserve location for this asset. - if assets.iter().all(|asset| Config::IsReserve::filter_asset_location(asset, &origin)) { + for asset in assets.iter() { + ensure!(!asset.is_wildcard(), XcmError::Wildcard); // We only trust the origin to send us assets that they identify as their // sovereign assets. - (Assets::from(assets), effects) - } else { - Err(XcmError::UntrustedReserveLocation)? + ensure!(Config::IsTeleporter::filter_asset_location(asset, &origin), XcmError::UntrustedTeleportLocation); } + (Assets::from(assets), effects) } (origin, XcmGeneric::TeleportAsset { assets, effects }) => { // check whether we trust origin to teleport this asset to us via config trait. - // TODO: should de-wildcard `assets` before passing in. - log::debug!(target: "runtime::xcm-executor", "Teleport from {:?}", origin); - if assets.iter().all(|asset| Config::IsTeleporter::filter_asset_location(asset, &origin)) { + for asset in assets.iter() { + ensure!(!asset.is_wildcard(), XcmError::Wildcard); // We only trust the origin to send us assets that they identify as their // sovereign assets. - (Assets::from(assets), effects) - } else { - Err(XcmError::UntrustedTeleportLocation)? + ensure!(Config::IsTeleporter::filter_asset_location(asset, &origin), XcmError::UntrustedTeleportLocation); } + (Assets::from(assets), effects) } - (origin, XcmGeneric::Transact { origin_type, max_weight, mut call }) => { + (origin, XcmGeneric::Transact { origin_type, require_weight_at_most, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. // TODO: allow this to be configurable in the trait. @@ -110,7 +121,7 @@ impl XcmExecutor { let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_type) .map_err(|_| XcmError::BadOrigin)?; let weight = message_call.get_dispatch_info().weight; - ensure!(max_weight >= weight, XcmError::Undefined); + ensure!(weight <= require_weight_at_most, XcmError::Undefined); let actual_weight = match message_call.dispatch(dispatch_origin) { Ok(post_info) => post_info.actual_weight, Err(error_and_info) => { @@ -119,31 +130,39 @@ impl XcmExecutor { error_and_info.post_info.actual_weight } }.unwrap_or(weight); - let _surplus_weight = max_weight - actual_weight; - - // TODO: reduce used_weight by surplus_weight. - // FUTURE: Here is where we could provide surplus_weight to Config::Barrier if we wanted to - // support transact weight surplus crediting. - return Ok(()); + let surplus = weight.saturating_sub(actual_weight); + // Credit any surplus weight that we bought. This should be safe since it's work we + // didn't realise that we didn't have to do. + // It works because we assume that the `Config::Weigher` will always count the `call`'s + // `get_dispatch_info` weight into its `immediate` estimate. + *weight_credit += surplus; + // Return the overestimated amount so we can adjust our expectations on how much this entire + // execution has taken. + return Ok(surplus); } _ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message. }; for effect in effects.into_iter() { - let _ = Self::execute_effects(&origin, &mut holding, effect)?; + total_surplus += Self::execute_effects(&origin, &mut holding, effect, trader)?; } - Ok(()) + Ok(total_surplus) } - fn execute_effects(origin: &MultiLocation, holding: &mut Assets, effect: OrderGeneric) -> XcmResult { + fn execute_effects( + origin: &MultiLocation, + holding: &mut Assets, + effect: OrderGeneric, + trader: &mut Config::Trader, + ) -> Result { + let mut total_surplus = 0; match effect { OrderGeneric::DepositAsset { assets, dest } => { let deposited = holding.saturating_take(assets); for asset in deposited.into_assets_iter() { Config::AssetTransactor::deposit_asset(&asset, &dest)?; } - Ok(()) }, OrderGeneric::DepositReserveAsset { assets, dest, effects } => { let deposited = holding.saturating_take(assets); @@ -151,39 +170,38 @@ impl XcmExecutor { Config::AssetTransactor::deposit_asset(&asset, &dest)?; } let assets = Self::reanchored(deposited, &dest); - Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects }) + Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; }, OrderGeneric::InitiateReserveWithdraw { assets, reserve, effects} => { let assets = Self::reanchored(holding.saturating_take(assets), &reserve); - Config::XcmSender::send_xcm(reserve, Xcm::WithdrawAsset { assets, effects }) + Config::XcmSender::send_xcm(reserve, Xcm::WithdrawAsset { assets, effects })?; } OrderGeneric::InitiateTeleport { assets, dest, effects} => { let assets = Self::reanchored(holding.saturating_take(assets), &dest); - Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects }) + Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects })?; } OrderGeneric::QueryHolding { query_id, dest, assets } => { let assets = Self::reanchored(holding.min(assets.iter()), &dest); - Config::XcmSender::send_xcm(dest, Xcm::Balances { query_id, assets }) + Config::XcmSender::send_xcm(dest, Xcm::Balances { query_id, assets })?; } OrderGeneric::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { // pay for `weight` using up to `fees` of the holding account. let desired_weight = Weight::from(weight + debt); - let max_fee = holding.checked_sub_assign(fees).map_err(|()| XcmError::Undefined)?; - let surplus = Config::Sale::buy_weight(desired_weight, max_fee)?; + let max_fee = holding.try_take(fees).map_err(|()| XcmError::Undefined)?; + let surplus = trader.buy_weight(desired_weight, max_fee)?; holding.saturating_subsume_all(surplus); let mut remaining_weight= desired_weight; for message in xcm.into_iter() { - match Self::do_execute_xcm(origin.clone(), false, message, &mut remaining_weight) { + match Self::do_execute_xcm(origin.clone(), false, message, &mut remaining_weight, None, trader) { Err(e) if halt_on_error => return Err(e), - _ => {} + Err(_) => {} + Ok(surplus) => { total_surplus += surplus } } } - Ok(()) - - // FUTURE: Here is where we would provide surplus_weight to Config::Barrier if we wanted to - // support weight refunding + holding.saturating_subsume(trader.refund_weight(remaining_weight)); } - _ => Err(XcmError::UnhandledEffect)?, + _ => return Err(XcmError::UnhandledEffect)?, } + Ok(total_surplus) } } From 92ec3c4065d76431e263617c4f1c31ec0fafd617 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 4 Apr 2021 00:57:42 +0200 Subject: [PATCH 08/40] Mock environment for tests and the first test --- xcm/src/v0/multi_asset.rs | 137 ++++++++++++++++++++- xcm/xcm-builder/src/lib.rs | 21 +--- xcm/xcm-executor/src/assets.rs | 32 +++++ xcm/xcm-executor/src/lib.rs | 9 +- xcm/xcm-executor/src/mock.rs | 217 +++++++++++++++++++++++++++++++++ xcm/xcm-executor/src/tests.rs | 44 +++++++ xcm/xcm-executor/src/traits.rs | 37 +++++- 7 files changed, 466 insertions(+), 31 deletions(-) create mode 100644 xcm/xcm-executor/src/mock.rs create mode 100644 xcm/xcm-executor/src/tests.rs diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs index ee0424c58a02..a56660de3830 100644 --- a/xcm/src/v0/multi_asset.rs +++ b/xcm/src/v0/multi_asset.rs @@ -148,12 +148,141 @@ pub enum MultiAsset { impl MultiAsset { pub fn is_wildcard(&self) -> bool { + match self { + MultiAsset::None + | MultiAsset::AbstractFungible {..} + | MultiAsset::AbstractNonFungible {..} + | MultiAsset::ConcreteFungible {..} + | MultiAsset::ConcreteNonFungible {..} + => false, + + MultiAsset::All + | MultiAsset::AllFungible + | MultiAsset::AllNonFungible + | MultiAsset::AllAbstractFungible {..} + | MultiAsset::AllConcreteFungible {..} + | MultiAsset::AllAbstractNonFungible {..} + | MultiAsset::AllConcreteNonFungible {..} + => true, + } + } + + fn is_none(&self) -> bool { + match self { + MultiAsset::None + | MultiAsset::AbstractFungible { amount: 0, .. } + | MultiAsset::ConcreteFungible { amount: 0, .. } + => true, + + _ => false, + } + } + + fn is_fungible(&self) -> bool { + match self { + MultiAsset::All + | MultiAsset::AllFungible + | MultiAsset::AllAbstractFungible {..} + | MultiAsset::AllConcreteFungible {..} + | MultiAsset::AbstractFungible {..} + | MultiAsset::ConcreteFungible {..} + => true, + + _ => false, + } + } + + fn is_non_fungible(&self) -> bool { + match self { + MultiAsset::All + | MultiAsset::AllNonFungible + | MultiAsset::AllAbstractNonFungible {..} + | MultiAsset::AllConcreteNonFungible {..} + | MultiAsset::AbstractNonFungible {..} + | MultiAsset::ConcreteNonFungible {..} + => true, + + _ => false, + } + } + + fn is_concrete_fungible(&self, id: &MultiLocation) -> bool { + match self { + MultiAsset::AllFungible => true, + + MultiAsset::AllConcreteFungible { id: i } + | MultiAsset::ConcreteFungible { id: i, .. } + => i == id, + + _ => false, + } + } + + fn is_abstract_fungible(&self, id: &[u8]) -> bool { + match self { + MultiAsset::AllFungible => true, + MultiAsset::AllAbstractFungible { id: i } + | MultiAsset::AbstractFungible { id: i, .. } + => i == id, + _ => false, + } + } + + fn is_concrete_non_fungible(&self, class: &MultiLocation) -> bool { + match self { + MultiAsset::AllNonFungible => true, + MultiAsset::AllConcreteNonFungible { class: i } + | MultiAsset::ConcreteNonFungible { class: i, .. } + => i == class, + _ => false, + } + } + + fn is_abstract_non_fungible(&self, class: &[u8]) -> bool { + match self { + MultiAsset::AllNonFungible => true, + MultiAsset::AllAbstractNonFungible { class: i } + | MultiAsset::AbstractNonFungible { class: i, .. } + => i == class, + _ => false, + } + } + + fn is_all(&self) -> bool { matches!(self, MultiAsset::All) } + + pub fn contains(&self, inner: &MultiAsset) -> bool { use MultiAsset::*; + // Inner cannot be wild + if inner.is_wildcard() { return false } + // Everything contains nothing. + if inner.is_none() { return true } + + // Everything contains anything. + if self.is_all() { return true } + // Nothing contains nothing. + if self.is_none() { return false } + match self { - None | AbstractFungible {..} | AbstractNonFungible {..} - | ConcreteFungible {..} | ConcreteNonFungible {..} => false, - All | AllFungible | AllNonFungible | AllAbstractFungible {..} | AllConcreteFungible {..} - | AllAbstractNonFungible {..} | AllConcreteNonFungible {..} => true, + // Anything fungible contains "all fungibles" + AllFungible => inner.is_fungible(), + // Anything non-fungible contains "all non-fungibles" + AllNonFungible => inner.is_non_fungible(), + + AllConcreteFungible { id } => inner.is_concrete_fungible(id), + AllAbstractFungible { id } => inner.is_abstract_fungible(id), + AllConcreteNonFungible { class } => inner.is_concrete_non_fungible(class), + AllAbstractNonFungible { class } => inner.is_abstract_non_fungible(class), + + ConcreteFungible { id, amount } + => matches!(inner, ConcreteFungible { id: i , amount: a } if i == id && a >= amount), + AbstractFungible { id, amount } + => matches!(inner, AbstractFungible { id: i , amount: a } if i == id && a >= amount), + ConcreteNonFungible { class, instance } + => matches!(inner, ConcreteNonFungible { class: i , instance: a } if i == class && a == instance), + AbstractNonFungible { class, instance } + => matches!(inner, AbstractNonFungible { class: i , instance: a } if i == class && a == instance), + + _ => false, } } } diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs index 7813c4799da8..0f12762e8864 100644 --- a/xcm/xcm-builder/src/lib.rs +++ b/xcm/xcm-builder/src/lib.rs @@ -37,22 +37,5 @@ use xcm_executor::traits::InvertLocation; use xcm::v0::{MultiLocation, Junction}; use frame_support::traits::Get; -/// Simple location inverter; give it this location's ancestry and it'll -pub struct LocationInverter(PhantomData); - -impl> InvertLocation for LocationInverter { - fn invert_location(location: &MultiLocation) -> MultiLocation { - let mut ancestry = Ancestry::get(); - let mut result = location.clone(); - for (i, j) in location.iter_rev() - .map(|j| match j { - Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild), - _ => Junction::Parent, - }) - .enumerate() - { - *result.at_mut(i).expect("location and result begin equal; same size; qed") = j; - } - result - } -} +#[deprecated("use `xcm-executor::traits::LocationInverter` instead")] +pub use xcm_executor::traits::LocationInverter; diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs index beff9027d9d6..8dc1b9d5f291 100644 --- a/xcm/xcm-executor/src/assets.rs +++ b/xcm/xcm-executor/src/assets.rs @@ -25,6 +25,34 @@ pub enum AssetId { Abstract(Vec), } +/// Classification of whether an asset is fungible or not, along with an optional amount or instance. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] +pub enum Fungibility { + Fungible(Option), + NonFungible(Option), +} + +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] +pub struct AssetParts(Option, Fungibility); + +impl From for MultiAsset { + fn from(a: AssetParts) -> Self { + use {AssetId::*, Fungibility::*}; + match (a.0, a.1) { + (Some(Concrete(id)), Fungible(Some(amount))) => MultiAsset::ConcreteFungible { id, amount }, + (Some(Abstract(id)), Fungible(Some(amount))) => MultiAsset::AbstractFungible { id, amount }, + (Some(Concrete(class)), NonFungible(Some(instance))) => MultiAsset::ConcreteNonFungible { class, instance }, + (Some(Abstract(class)), NonFungible(Some(instance))) => MultiAsset::AbstractNonFungible { class, instance }, + (Some(Concrete(id)), Fungible(None)) => MultiAsset::AllConcreteFungible { id }, + (Some(Abstract(id)), Fungible(None)) => MultiAsset::AllAbstractFungible { id }, + (Some(Concrete(class)), NonFungible(None)) => MultiAsset::AllConcreteNonFungible { class }, + (Some(Abstract(class)), NonFungible(None)) => MultiAsset::AllAbstractNonFungible { class }, + (None, Fungible(_)) => MultiAsset::AllFungible, + (None, NonFungible(_)) => MultiAsset::AllNonFungible, + } + } +} + impl AssetId { /// Prepend a MultiLocation to a concrete asset, giving it a new root location. pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> { @@ -51,6 +79,10 @@ impl AssetId { AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance }, } } + + pub fn into_multiasset(self, f: Fungibility) -> MultiAsset { + AssetParts(Some(self), f).into() + } } /// List of non-wildcard fungible and non-fungible assets. diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 6a797e2e3e95..b44712a89a3f 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -26,6 +26,11 @@ use xcm::v0::{ MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, }; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + pub mod traits; use traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; @@ -88,7 +93,7 @@ impl XcmExecutor { for asset in assets { ensure!(!asset.is_wildcard(), XcmError::Wildcard); let withdrawn = Config::AssetTransactor::withdraw_asset(&asset, &origin)?; - holding.saturating_subsume(withdrawn); + holding.saturating_subsume_all(withdrawn); } (holding, effects) } @@ -98,7 +103,7 @@ impl XcmExecutor { ensure!(!asset.is_wildcard(), XcmError::Wildcard); // We only trust the origin to send us assets that they identify as their // sovereign assets. - ensure!(Config::IsTeleporter::filter_asset_location(asset, &origin), XcmError::UntrustedTeleportLocation); + ensure!(Config::IsReserve::filter_asset_location(asset, &origin), XcmError::UntrustedReserveLocation); } (Assets::from(assets), effects) } diff --git a/xcm/xcm-executor/src/mock.rs b/xcm/xcm-executor/src/mock.rs new file mode 100644 index 000000000000..0ae34ffde09e --- /dev/null +++ b/xcm/xcm-executor/src/mock.rs @@ -0,0 +1,217 @@ +// Copyright 2020 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 . + +use super::*; +pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell}; +pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; +pub use parity_scale_codec::{Encode, Decode}; +pub use xcm::v0::{ + SendXcm, MultiLocation::*, Junction::*, MultiAsset, XcmGeneric, OrderGeneric, Result as XcmResult, Error, + OriginKind, MultiLocation, Junction, +}; +pub use frame_support::{ + ensure, parameter_types, + dispatch::{Dispatchable, Parameter, Weight, DispatchError, DispatchResultWithPostInfo, DispatchInfo}, + weights::{PostDispatchInfo, GetDispatchInfo}, + sp_runtime::DispatchErrorWithPostInfo, + traits::{Get, Contains}, +}; +pub use crate::traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, LocationInverter}; +pub use crate::config::{ + TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds, + FixedRateOfConcreteFungible, +}; + +pub enum TestOrigin { Root, Signed(u64), Parachain(u32) } + +#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone, Copy)] +pub enum TestCall { + OnlyRoot(Weight, Option), + OnlyParachain(Weight, Option, Option), + OnlySigned(Weight, Option, Option), + Any(Weight, Option), +} +impl Dispatchable for TestCall { + type Origin = TestOrigin; + type Config = (); + type Info = (); + type PostInfo = PostDispatchInfo; + fn dispatch(self, origin: Self::Origin) -> DispatchResultWithPostInfo { + let mut post_info = PostDispatchInfo::default(); + post_info.actual_weight = match self { + TestCall::OnlyRoot(_, maybe_actual) + | TestCall::OnlySigned(_, maybe_actual, _) + | TestCall::OnlyParachain(_, maybe_actual, _) + | TestCall::Any(_, maybe_actual) + => maybe_actual, + }; + if match (&origin, &self) { + (TestOrigin::Parachain(i), TestCall::OnlyParachain(_, _, Some(j))) + => i == j, + (TestOrigin::Signed(i), TestCall::OnlySigned(_, _, Some(j))) + => i == j, + + (TestOrigin::Root, TestCall::OnlyRoot(..)) + | (TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None)) + | (TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None)) + | (_, TestCall::Any(..)) + => true, + + _ => false, + } { + Ok(post_info) + } else { + Err(DispatchErrorWithPostInfo { error: DispatchError::BadOrigin, post_info }) + } + } +} + +impl GetDispatchInfo for TestCall { + fn get_dispatch_info(&self) -> DispatchInfo { + let weight = *match self { + TestCall::OnlyRoot(estimate, ..) + | TestCall::OnlyParachain(estimate, ..) + | TestCall::OnlySigned(estimate, ..) + | TestCall::Any(estimate, ..) + => estimate, + }; + DispatchInfo { weight, .. Default::default() } + } +} + +thread_local! { + pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); +} +pub struct TestSendXcm; +impl SendXcm for TestSendXcm { + fn send_xcm(dest: MultiLocation, msg: Xcm) -> XcmResult { + SENT_XCM.with(|q| q.borrow_mut().push((dest, msg))); + Ok(()) + } +} + +thread_local! { + pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); +} +pub fn assets(who: MultiLocation) -> Vec { + ASSETS.with(|a| a.borrow().get(&who).map_or(vec![], |a| a.clone().into())) +} +pub struct TestAssetTransactor; +impl TransactAsset for TestAssetTransactor { + fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result<(), XcmError> { + ASSETS.with(|a| a.borrow_mut() + .entry(who.clone()) + .or_insert(Assets::new()) + .saturating_subsume(what.clone()) + ); + Ok(()) + } + + fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { + ASSETS.with(|a| a.borrow_mut() + .get_mut(who) + .ok_or(XcmError::Undefined)? + .try_take(what.clone()) + .map_err(|()| XcmError::Undefined) + ) + } +} + +pub struct TestOriginConverter; +impl ConvertOrigin for TestOriginConverter { + fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { + use {OriginKind::*}; + match (kind, origin) { + (Superuser, _) => Ok(TestOrigin::Root), + (SovereignAccount, X2(Parent, Parachain { id })) => Ok(TestOrigin::Signed(2000 + id as u64)), + (SovereignAccount, X1(AccountIndex64 { index, .. })) => Ok(TestOrigin::Signed(index)), + (SovereignAccount, X1(Parachain { id })) => Ok(TestOrigin::Signed(1000 + id as u64)), + (SovereignAccount, Null) => Ok(TestOrigin::Signed(3000)), + (Native, X1(Parachain { id })) => Ok(TestOrigin::Parachain(id)), + (_, origin) => Err(origin), + } + } +} + +thread_local! { + pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); + pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); +} + +pub fn add_reserve(from: MultiLocation, asset: MultiAsset) { + IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); +} +pub fn add_teleporter(from: MultiLocation, asset: MultiAsset) { + IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); +} + +pub struct TestIsReserve; +impl FilterAssetLocation for TestIsReserve { + /// A filter to distinguish between asset/location pairs. + fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { + let r = IS_RESERVE.with(|r| r.borrow().get(origin) + .map_or(false, |v| v.iter().any(|a| a.contains(asset))) + ); + println!("FAL: {:?}, {:?} => {}", asset, origin, r); + r + } +} +pub struct TestIsTeleporter; +impl FilterAssetLocation for TestIsTeleporter { + /// A filter to distinguish between asset/location pairs. + fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { + IS_TELEPORTER.with(|r| r.borrow().get(origin) + .map_or(false, |v| v.iter().any(|a| a.contains(asset))) + ) + } +} + +parameter_types! { + pub TestAncestry: MultiLocation = X1(Parachain{id: 42}); + pub AllowPaidFrom: Vec = vec![ + Null, // this chain + X1(Parent), // the relay chain + X2(Parent, Parachain{id: 69}), // our sibling chain 69 + ]; + pub AllowUnpaidFrom: Vec = vec![X1(Parent)]; + pub UnitWeightCost: Weight = 10; + pub WeightPrice: (MultiLocation, u128) = (X1(Parent), 1_000_000_000_000); +} + +pub struct IsInVec(PhantomData); +impl>> Contains for IsInVec { + fn sorted_members() -> Vec { let mut r = T::get(); r.sort(); r } +} + +pub type TestBarrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom>, + AllowUnpaidExecutionFrom>, +); + +pub struct TestConfig; +impl Config for TestConfig { + type Call = TestCall; + type XcmSender = TestSendXcm; + type AssetTransactor = TestAssetTransactor; + type OriginConverter = TestOriginConverter; + type IsReserve = TestIsReserve; + type IsTeleporter = TestIsTeleporter; + type LocationInverter = LocationInverter; + type Barrier = TestBarrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfConcreteFungible; +} diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-executor/src/tests.rs new file mode 100644 index 000000000000..ff9944606020 --- /dev/null +++ b/xcm/xcm-executor/src/tests.rs @@ -0,0 +1,44 @@ +// Copyright 2020 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 . + +use super::*; +use super::mock::*; +use MultiAsset::*; +use xcm::v0::Order; + +#[test] +fn basic_setup_works() { + add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); + assert!(::IsReserve::filter_asset_location( + &ConcreteFungible { id: X1(Parent), amount: 100 }, + &X1(Parent), + )); +} + +#[test] +fn basic_execution_should_work() { + add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); + let r = XcmExecutor::::execute_xcm( + X1(Parent), + Xcm::ReserveAssetDeposit { + assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], + effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: Null } ], + }, + 50, + ); + assert_eq!(r, Ok(20)); + assert_eq!(assets(Null), vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]); +} diff --git a/xcm/xcm-executor/src/traits.rs b/xcm/xcm-executor/src/traits.rs index bae501731a1c..ee9e3ae4f45d 100644 --- a/xcm/xcm-executor/src/traits.rs +++ b/xcm/xcm-executor/src/traits.rs @@ -16,8 +16,9 @@ use sp_std::{result::Result, marker::PhantomData, convert::TryFrom}; use sp_runtime::traits::CheckedConversion; -use xcm::v0::{Error as XcmError, Result as XcmResult, MultiAsset, MultiLocation, OriginKind}; +use xcm::v0::{Error as XcmError, Result as XcmResult, MultiAsset, MultiLocation, Junction, OriginKind}; use frame_support::traits::Get; +use super::Assets; pub trait FilterAssetLocation { /// A filter to distinguish between asset/location pairs. @@ -61,18 +62,20 @@ pub trait TransactAsset { /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> XcmResult; - /// Withdraw the given asset from the consensus system. Return the actual asset withdrawn. In + /// Withdraw the given asset from the consensus system. Return the actual asset(s) withdrawn. In /// the case of `what` being a wildcard, this may be something more specific. /// /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. - fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result; + fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result; /// Move an `asset` `from` one location in `to` another location. /// /// Returns `XcmError::FailedToTransactAsset` if transfer failed. - fn transfer_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { + fn transfer_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { let withdrawn = Self::withdraw_asset(asset, from)?; - Self::deposit_asset(&withdrawn, to)?; + for asset in withdrawn.assets_iter() { + Self::deposit_asset(&asset, to)?; + } Ok(withdrawn) } } @@ -85,7 +88,7 @@ impl TransactAsset for Tuple { )* ); Err(XcmError::Unimplemented) } - fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { + fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { for_tuples!( #( match Tuple::withdraw_asset(what, who) { o @ Ok(_) => return o, _ => () } )* ); @@ -165,6 +168,28 @@ impl ConvertOrigin for Tuple { } } +/// Means of inverting a location: given a location which describes a `target` interpreted from the `source`, this +/// will provide the corresponding location which describes the `source` pub trait InvertLocation { fn invert_location(l: &MultiLocation) -> MultiLocation; } + +/// Simple location inverter; give it this location's ancestry and it'll figure out the inverted location. +pub struct LocationInverter(PhantomData); +impl> InvertLocation for LocationInverter { + fn invert_location(location: &MultiLocation) -> MultiLocation { + let mut ancestry = Ancestry::get(); + let mut result = location.clone(); + for (i, j) in location.iter_rev() + .map(|j| match j { + Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild), + _ => Junction::Parent, + }) + .enumerate() + { + *result.at_mut(i).expect("location and result begin equal; same size; qed") = j; + } + result + } +} + From 8b5b67e5e47314d417262c659ce99246fb069ba5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 4 Apr 2021 17:29:14 +0200 Subject: [PATCH 09/40] Tests for XCM and a few refactors. --- xcm/src/v0/junction.rs | 6 +- xcm/src/v0/mod.rs | 54 +++++++-- xcm/src/v0/multi_asset.rs | 12 ++ xcm/src/v0/order.rs | 10 +- xcm/src/v0/traits.rs | 27 +++++ xcm/xcm-executor/src/assets.rs | 83 ++++++++++--- xcm/xcm-executor/src/config.rs | 39 +++--- xcm/xcm-executor/src/lib.rs | 65 ++++++---- xcm/xcm-executor/src/mock.rs | 72 ++++++----- xcm/xcm-executor/src/tests.rs | 211 +++++++++++++++++++++++++++++++-- 10 files changed, 473 insertions(+), 106 deletions(-) diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs index df11ab3fdede..b5493cd31fe0 100644 --- a/xcm/src/v0/junction.rs +++ b/xcm/src/v0/junction.rs @@ -45,6 +45,10 @@ pub enum Junction { /// An indexed parachain belonging to and operated by the context. /// /// Generally used when the context is a Polkadot Relay-chain. + /// + /// There is also `Parachain` which can be used in tests to avoid the faffy `{ id: ... }` syntax. Production + /// code should use this. + // TODO: parity-scale-codec#262: Change to be `Parachain(#[codec(compact)] u32)` Parachain { #[codec(compact)] id: u32 }, /// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within /// the context. @@ -64,7 +68,7 @@ pub enum Junction { /// An instanced, indexed pallet that forms a constituent part of the context. /// /// Generally used when the context is a Frame-based chain. - PalletInstance { id: u8 }, + PalletInstance(u8), /// A non-descript index within the context location. /// /// Usage will vary widely owing to its generality. diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 4c075371a1d4..3804c5093f54 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -70,6 +70,7 @@ pub enum XcmGeneric { /// Kind: *Instruction*. /// /// Errors: + #[codec(index = 0)] WithdrawAsset { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system. @@ -86,6 +87,7 @@ pub enum XcmGeneric { /// Kind: *Trusted Indication*. /// /// Errors: + #[codec(index = 1)] ReserveAssetDeposit { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be @@ -103,6 +105,7 @@ pub enum XcmGeneric { /// Kind: *Trusted Indication*. /// /// Errors: + #[codec(index = 2)] TeleportAsset { assets: Vec, effects: Vec> }, /// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`. @@ -115,15 +118,40 @@ pub enum XcmGeneric { /// Kind: *Information*. /// /// Errors: + #[codec(index = 3)] Balances { #[codec(compact)] query_id: u64, assets: Vec }, - Unused4, - - /// Unused - Unused5, + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the + /// ownership of `dest` within this consensus system. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `dest`: The new owner for the assets. + /// + /// Safety: No concerns. + /// + /// Kind: *Instruction*. + /// + /// Errors: + #[codec(index = 4)] + TransferAsset { assets: Vec, dest: MultiLocation }, - /// Unused - Unused6, + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the + /// ownership of `dest` within this consensus system. + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `dest`: The new owner for the assets. + /// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to + /// `dest. + /// + /// Safety: No concerns. + /// + /// Kind: *Instruction*. + /// + /// Errors: + #[codec(index = 5)] + TransferReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec }, /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the /// relay-chain to a para. @@ -135,6 +163,7 @@ pub enum XcmGeneric { /// Safety: The message should originate directly from the relay-chain. /// /// Kind: *System Notification* + #[codec(index = 7)] HrmpNewChannelOpenRequest { #[codec(compact)] sender: u32, #[codec(compact)] max_message_size: u32, @@ -150,6 +179,7 @@ pub enum XcmGeneric { /// Kind: *System Notification* /// /// Errors: + #[codec(index = 8)] HrmpChannelAccepted { #[codec(compact)] recipient: u32, }, @@ -164,6 +194,7 @@ pub enum XcmGeneric { /// Kind: *System Notification* /// /// Errors: + #[codec(index = 9)] HrmpChannelClosing { #[codec(compact)] initiator: u32, #[codec(compact)] sender: u32, @@ -183,6 +214,7 @@ pub enum XcmGeneric { /// Kind: *Instruction*. /// /// Errors: + #[codec(index = 10)] Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded }, } @@ -222,12 +254,10 @@ impl XcmGeneric { => TeleportAsset { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, Balances { query_id: u64, assets } => Balances { query_id: u64, assets }, - Unused4 - => Unused4, - Unused5 - => Unused5, - Unused6 - => Unused6, + TransferAsset { assets, dest } + => TransferAsset { assets, dest }, + TransferReserveAsset { assets, dest, effects } + => TransferReserveAsset { assets, dest, effects }, HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity} => HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}, HrmpChannelAccepted { recipient} diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs index a56660de3830..216745217588 100644 --- a/xcm/src/v0/multi_asset.rs +++ b/xcm/src/v0/multi_asset.rs @@ -285,6 +285,18 @@ impl MultiAsset { _ => false, } } + + pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> { + use MultiAsset::*; + match self { + AllConcreteFungible { ref mut id } + | AllConcreteNonFungible { class: ref mut id } + | ConcreteFungible { ref mut id, .. } + | ConcreteNonFungible { class: ref mut id, .. } + => id.prepend_with(prepend.clone()).map_err(|_| ()), + _ => Ok(()), + } + } } impl From for VersionedMultiAsset { diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs index 6795665acb68..6631bfb2f502 100644 --- a/xcm/src/v0/order.rs +++ b/xcm/src/v0/order.rs @@ -25,6 +25,7 @@ use super::{MultiAsset, MultiLocation, XcmGeneric}; #[codec(dumb_trait_bound)] pub enum OrderGeneric { /// Do nothing. Not generally used. + #[codec(index = 0)] Null, /// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within @@ -34,12 +35,13 @@ pub enum OrderGeneric { /// - `dest`: The new owner for the assets. /// /// Errors: + #[codec(index = 1)] DepositAsset { assets: Vec, dest: MultiLocation }, /// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within /// this consensus system. /// - /// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the + /// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`. /// /// - `assets`: The asset(s) to remove from holding. /// - `dest`: The new owner for the assets. @@ -47,6 +49,7 @@ pub enum OrderGeneric { /// `dest. /// /// Errors: + #[codec(index = 2)] DepositReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec }, /// Remove the asset(s) (`give`) from holding and replace them with alternative assets. @@ -58,6 +61,7 @@ pub enum OrderGeneric { /// is undefined and they should be not be used. /// /// Errors: + #[codec(index = 3)] ExchangeAsset { give: Vec, receive: Vec }, /// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a reserve location. @@ -69,6 +73,7 @@ pub enum OrderGeneric { /// - `effects`: The orders to execute on the assets once withdrawn *on the reserve location*. /// /// Errors: + #[codec(index = 4)] InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec }, /// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location. @@ -78,6 +83,7 @@ pub enum OrderGeneric { /// - `effects`: The orders to execute on the assets once arrived *on the destination location*. /// /// Errors: + #[codec(index = 5)] InitiateTeleport { assets: Vec, dest: MultiLocation, effects: Vec }, /// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof. @@ -89,12 +95,14 @@ pub enum OrderGeneric { /// back. /// /// Errors: + #[codec(index = 6)] QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: Vec }, /// Pay for the execution of some Xcm with up to `weight` picoseconds of execution time, paying for this with /// up to `fees` from the holding account. /// /// Errors: + #[codec(index = 7)] BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec> }, } diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs index 60d689d80d7a..96f2a4bda90a 100644 --- a/xcm/src/v0/traits.rs +++ b/xcm/src/v0/traits.rs @@ -40,6 +40,33 @@ pub enum Error { FailedToTransactAsset(#[codec(skip)] &'static str), WeightLimitReached, Wildcard, + /// The case where an XCM message has specified a optional weight limit and the weight required for + /// processing is too great. + /// + /// Used by: + /// - `Transact` + TooMuchWeightRequired, + /// The fees specified by the XCM message were not found in the holding account. + /// + /// Used by: + /// - `BuyExecution` + NotHoldingFees, + /// The weight of an XCM message is not computable ahead of execution. This generally means at least part + /// of the message is invalid, which could be due to it containing overly nested structures or an invalid + /// nested data segment (e.g. for the call in `Transact`). + WeightNotComputable, + /// The XCM did noto pass the barrier condition for execution. The barrier condition differs on different + /// chains and in different circumstances, but generally it means that the conditions surrounding the message + /// were not such that the chain considers the message worth spending time executing. Since most chains + /// lift the barrier to execution on apropriate payment, presentation of an NFT voucher, or based on the + /// message origin, it means that none of those were the case. + Barrier, + /// Indicates that it is not possible for a location to have an asset be withdrawn or transferred from its + /// ownership. This probably means it doesn't own (enough of) it, but may also indicate that it is under a + /// lock, hold, freeze or is otherwise unavailable. + NotWithdrawable, + /// Indicates that the consensus system cannot deposit an asset under the ownership of a particular location. + LocationCannotHold, } impl From<()> for Error { diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs index 8dc1b9d5f291..efbf287cdbae 100644 --- a/xcm/xcm-executor/src/assets.rs +++ b/xcm/xcm-executor/src/assets.rs @@ -15,6 +15,7 @@ // along with Polkadot. If not, see . use sp_std::{prelude::*, mem, collections::{btree_map::BTreeMap, btree_set::BTreeSet}}; +use parity_scale_codec::{Encode, Decode, Input}; use xcm::v0::{MultiAsset, MultiLocation, AssetInstance}; use sp_runtime::RuntimeDebug; @@ -33,22 +34,68 @@ pub enum Fungibility { } #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] -pub struct AssetParts(Option, Fungibility); - -impl From for MultiAsset { - fn from(a: AssetParts) -> Self { - use {AssetId::*, Fungibility::*}; - match (a.0, a.1) { - (Some(Concrete(id)), Fungible(Some(amount))) => MultiAsset::ConcreteFungible { id, amount }, - (Some(Abstract(id)), Fungible(Some(amount))) => MultiAsset::AbstractFungible { id, amount }, - (Some(Concrete(class)), NonFungible(Some(instance))) => MultiAsset::ConcreteNonFungible { class, instance }, - (Some(Abstract(class)), NonFungible(Some(instance))) => MultiAsset::AbstractNonFungible { class, instance }, - (Some(Concrete(id)), Fungible(None)) => MultiAsset::AllConcreteFungible { id }, - (Some(Abstract(id)), Fungible(None)) => MultiAsset::AllAbstractFungible { id }, - (Some(Concrete(class)), NonFungible(None)) => MultiAsset::AllConcreteNonFungible { class }, - (Some(Abstract(class)), NonFungible(None)) => MultiAsset::AllAbstractNonFungible { class }, - (None, Fungible(_)) => MultiAsset::AllFungible, - (None, NonFungible(_)) => MultiAsset::AllNonFungible, +pub enum MultiAsset2 { + None, + Asset(Fungibility, Option), + All, +} + +impl Encode for MultiAsset2 { + fn encode(&self) -> Vec { + MultiAsset::from(self.clone()).encode() + } +} + +impl Decode for MultiAsset2 { + fn decode(input: &mut I) -> Result { + MultiAsset::decode(input).map(Into::into) + } +} + +impl From for MultiAsset { + fn from(a: MultiAsset2) -> Self { + use {AssetId::*, Fungibility::*, MultiAsset::*, MultiAsset2::Asset}; + use Option::None; + match a { + MultiAsset2::None => MultiAsset::None, + MultiAsset2::All => All, + + Asset(Fungible(_), None) => AllFungible, + Asset(NonFungible(_), None) => AllNonFungible, + + Asset(Fungible(None), Some(Concrete(id))) => AllConcreteFungible { id }, + Asset(Fungible(None), Some(Abstract(id))) => AllAbstractFungible { id }, + Asset(NonFungible(None), Some(Concrete(class))) => AllConcreteNonFungible { class }, + Asset(NonFungible(None), Some(Abstract(class))) => AllAbstractNonFungible { class }, + + Asset(Fungible(Some(amount)), Some(Concrete(id))) => ConcreteFungible { id, amount }, + Asset(Fungible(Some(amount)), Some(Abstract(id))) => AbstractFungible { id, amount }, + Asset(NonFungible(Some(instance)), Some(Concrete(class))) => ConcreteNonFungible { class, instance }, + Asset(NonFungible(Some(instance)), Some(Abstract(class))) => AbstractNonFungible { class, instance }, + } + } +} + +impl From for MultiAsset2 { + fn from(a: MultiAsset) -> Self { + use {AssetId::*, Fungibility::*, MultiAsset::*, MultiAsset2::Asset}; + use Option::None; + match a { + MultiAsset::None => MultiAsset2::None, + All => MultiAsset2::All, + + AllFungible => Asset(Fungible(None), None), + AllNonFungible => Asset(NonFungible(None), None), + + AllConcreteFungible { id } => Asset(Fungible(None), Some(Concrete(id))), + AllAbstractFungible { id } => Asset(Fungible(None), Some(Abstract(id))), + AllConcreteNonFungible { class } => Asset(NonFungible(None), Some(Concrete(class))), + AllAbstractNonFungible { class } => Asset(NonFungible(None), Some(Abstract(class))), + + ConcreteFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Concrete(id))), + AbstractFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Abstract(id))), + ConcreteNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Concrete(class))), + AbstractNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Abstract(class))), } } } @@ -80,8 +127,8 @@ impl AssetId { } } - pub fn into_multiasset(self, f: Fungibility) -> MultiAsset { - AssetParts(Some(self), f).into() + pub fn into_multiasset(self, f: Fungibility) -> MultiAsset2 { + MultiAsset2::Asset(f, Some(self)) } } diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index d26ab6ee8474..c65b5f0ba692 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -32,20 +32,27 @@ pub trait WeightBounds { /// This is useful to gauge how many fees should be paid up front to begin execution of the message. /// It is not useful for determining whether execution should begin lest it result in surpassing weight /// limits - in that case `deep` is the function to use. - fn immediate(message: &mut XcmGeneric) -> Result; + fn shallow(message: &mut XcmGeneric) -> Result; - /// Return the additional amount of weight, over `shallow` that complete and successful execution of + /// Return the deep amount of weight, over `shallow` that complete, successful and worst-case execution of /// `message` would incur. /// /// This is perhaps overly pessimistic for determining how many fees should be paid for up-front since /// fee payment (or any other way of offsetting the execution costs such as an voucher-style NFT) may /// happen in stages throughout execution of the XCM. - fn additional(message: &mut XcmGeneric) -> Result; + /// + /// A reminder: if it is possible that `message` may have alternative means of successful completion + /// (perhaps a conditional path), then the *worst case* weight must be reported. + /// + /// This is guaranteed equal to the eventual sum of all `shallow` XCM messages that get executed through + /// any internal effects. Inner XCM messages may be executed by: + /// - Order::BuyExecution + fn deep(message: &mut XcmGeneric) -> Result; } pub struct FixedWeightBounds(PhantomData<(T, C)>); impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeightBounds { - fn immediate(message: &mut XcmGeneric) -> Result { + fn shallow(message: &mut XcmGeneric) -> Result { let min = match message { XcmGeneric::Transact { call, .. } => { call.ensure_decoded()?.get_dispatch_info().weight + T::get() @@ -57,7 +64,7 @@ impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeigh .map(|effect| match effect { OrderGeneric::BuyExecution { .. } => { // On success, execution of this will result in more weight being consumed but - // we don't count it here since this is only the *immediate*, non-negotiable weight + // we don't count it here since this is only the *shallow*, non-negotiable weight // spend and doesn't count weight placed behind a `BuyExecution` since it will not // be definitely consumed from any existing weight credit if execution of the message // is attempted. @@ -71,7 +78,7 @@ impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeigh }; Ok(min) } - fn additional(message: &mut XcmGeneric) -> Result { + fn deep(message: &mut XcmGeneric) -> Result { let mut extra = 0; match message { XcmGeneric::Transact { .. } => {} @@ -82,7 +89,7 @@ impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeigh match effect { OrderGeneric::BuyExecution { xcm, .. } => { for message in xcm.iter_mut() { - extra += Self::immediate(message)? + Self::additional(message)?; + extra += Self::shallow(message)? + Self::deep(message)?; } }, _ => {} @@ -135,7 +142,7 @@ pub trait ShouldExecute { /// - `top_level`: `true`` indicates the initial XCM coming from the `origin`, `false` indicates an embedded /// XCM executed internally as part of another message or an `Order`. /// - `message`: The message itself. - /// - `immediate_weight`: The weight of the non-negotiable execution of the message. This does not include any + /// - `shallow_weight`: The weight of the non-negotiable execution of the message. This does not include any /// embedded XCMs sat behind mechanisms like `BuyExecution` which would need to answer for their own weight. /// - `weight_credit`: The pre-established amount of weight that the system has determined this message /// may utilise in its execution. Typically non-zero only because of prior fee payment, but could @@ -144,7 +151,7 @@ pub trait ShouldExecute { origin: &MultiLocation, top_level: bool, message: &XcmGeneric, - immediate_weight: Weight, + shallow_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()>; } @@ -155,11 +162,11 @@ impl ShouldExecute for Tuple { origin: &MultiLocation, top_level: bool, message: &XcmGeneric, - immediate_weight: Weight, + shallow_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { for_tuples!( #( - match Tuple::should_execute(origin, top_level, message, immediate_weight, weight_credit) { + match Tuple::should_execute(origin, top_level, message, shallow_weight, weight_credit) { o @ Ok(()) => return o, _ => (), } @@ -174,10 +181,10 @@ impl ShouldExecute for TakeWeightCredit { _origin: &MultiLocation, _top_level: bool, _message: &XcmGeneric, - immediate_weight: Weight, + shallow_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { - *weight_credit = weight_credit.checked_sub(immediate_weight).ok_or(())?; + *weight_credit = weight_credit.checked_sub(shallow_weight).ok_or(())?; Ok(()) } } @@ -188,7 +195,7 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro origin: &MultiLocation, top_level: bool, message: &XcmGeneric, - immediate_weight: Weight, + shallow_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { ensure!(T::contains(origin), ()); @@ -199,7 +206,7 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro | XcmGeneric::ReserveAssetDeposit { effects, ..} if matches!( effects.first(), - Some(OrderGeneric::BuyExecution { debt, ..}) if *debt >= immediate_weight + Some(OrderGeneric::BuyExecution { debt, ..}) if *debt >= shallow_weight ) => Ok(()), _ => Err(()), @@ -213,7 +220,7 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { origin: &MultiLocation, _top_level: bool, _message: &XcmGeneric, - _immediate_weight: Weight, + _shallow_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { ensure!(T::contains(origin), ()); diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index b44712a89a3f..fc66ab92f963 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -45,13 +45,13 @@ impl ExecuteXcm for XcmExecutor { fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Result { // TODO: We should identify recursive bombs here and bail. let mut message = XcmGeneric::::from(message); - let immediate_weight = Config::Weigher::immediate(&mut message)?; - let additional_weight = Config::Weigher::additional(&mut message)?; - let maximum_weight = immediate_weight.checked_add(additional_weight) + let shallow_weight = Config::Weigher::shallow(&mut message)?; + let deep_weight = Config::Weigher::deep(&mut message)?; + let maximum_weight = shallow_weight.checked_add(deep_weight) .ok_or(XcmError::WeightLimitReached)?; ensure!(maximum_weight <= weight_limit, XcmError::WeightLimitReached); let mut trader = Config::Trader::new(); - let surplus = Self::do_execute_xcm(origin, true, message, &mut 0, Some(immediate_weight), &mut trader)?; + let surplus = Self::do_execute_xcm(origin, true, message, &mut 0, Some(shallow_weight), &mut trader)?; Ok(maximum_weight.saturating_sub(surplus)) } } @@ -69,24 +69,24 @@ impl XcmExecutor { top_level: bool, mut message: XcmGeneric, weight_credit: &mut Weight, - maybe_immediate_weight: Option, + maybe_shallow_weight: Option, trader: &mut Config::Trader, ) -> Result { // This is the weight of everything that cannot be paid for. This basically means all computation // except any XCM which is behind an Order::BuyExecution. - let immediate_weight = maybe_immediate_weight - .or_else(|| Config::Weigher::immediate(&mut message).ok()) - .ok_or(XcmError::Undefined)?; + let shallow_weight = maybe_shallow_weight + .or_else(|| Config::Weigher::shallow(&mut message).ok()) + .ok_or(XcmError::WeightNotComputable)?; - Config::Barrier::should_execute(&origin, top_level, &message, immediate_weight, weight_credit) - .map_err(|()| XcmError::Undefined)?; + Config::Barrier::should_execute(&origin, top_level, &message, shallow_weight, weight_credit) + .map_err(|()| XcmError::Barrier)?; - // The surplus weight, defined as the amount by which `immediate_weight` plus all nested - // `immediate_weight` values (ensuring no double-counting) is an overestimate of the actual weight + // The surplus weight, defined as the amount by which `shallow_weight` plus all nested + // `shallow_weight` values (ensuring no double-counting) is an overestimate of the actual weight // consumed. let mut total_surplus = 0; - let (mut holding, effects) = match (origin.clone(), message) { + let maybe_holding_effects = match (origin.clone(), message) { (origin, XcmGeneric::WithdrawAsset { assets, effects }) => { // Take `assets` from the origin account (on-chain) and place in holding. let mut holding = Assets::default(); @@ -95,7 +95,7 @@ impl XcmExecutor { let withdrawn = Config::AssetTransactor::withdraw_asset(&asset, &origin)?; holding.saturating_subsume_all(withdrawn); } - (holding, effects) + Some((holding, effects)) } (origin, XcmGeneric::ReserveAssetDeposit { assets, effects }) => { // check whether we trust origin to be our reserve location for this asset. @@ -105,7 +105,26 @@ impl XcmExecutor { // sovereign assets. ensure!(Config::IsReserve::filter_asset_location(asset, &origin), XcmError::UntrustedReserveLocation); } - (Assets::from(assets), effects) + Some((Assets::from(assets), effects)) + } + (origin, XcmGeneric::TransferAsset { assets, dest }) => { + // Take `assets` from the origin account (on-chain) and place into dest account. + for asset in assets { + ensure!(!asset.is_wildcard(), XcmError::Wildcard); + Config::AssetTransactor::transfer_asset(&asset, &origin, &dest)?; + } + None + } + (origin, XcmGeneric::TransferReserveAsset { mut assets, dest, effects }) => { + // Take `assets` from the origin account (on-chain) and place into dest account. + let inv_dest = Config::LocationInverter::invert_location(&dest); + for asset in assets.iter_mut() { + ensure!(!asset.is_wildcard(), XcmError::Wildcard); + Config::AssetTransactor::transfer_asset(&asset, &origin, &dest)?; + asset.reanchor(&dest)?; + } + Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; + None } (origin, XcmGeneric::TeleportAsset { assets, effects }) => { // check whether we trust origin to teleport this asset to us via config trait. @@ -115,7 +134,7 @@ impl XcmExecutor { // sovereign assets. ensure!(Config::IsTeleporter::filter_asset_location(asset, &origin), XcmError::UntrustedTeleportLocation); } - (Assets::from(assets), effects) + Some((Assets::from(assets), effects)) } (origin, XcmGeneric::Transact { origin_type, require_weight_at_most, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. @@ -126,7 +145,7 @@ impl XcmExecutor { let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_type) .map_err(|_| XcmError::BadOrigin)?; let weight = message_call.get_dispatch_info().weight; - ensure!(weight <= require_weight_at_most, XcmError::Undefined); + ensure!(weight <= require_weight_at_most, XcmError::TooMuchWeightRequired); let actual_weight = match message_call.dispatch(dispatch_origin) { Ok(post_info) => post_info.actual_weight, Err(error_and_info) => { @@ -139,17 +158,19 @@ impl XcmExecutor { // Credit any surplus weight that we bought. This should be safe since it's work we // didn't realise that we didn't have to do. // It works because we assume that the `Config::Weigher` will always count the `call`'s - // `get_dispatch_info` weight into its `immediate` estimate. + // `get_dispatch_info` weight into its `shallow` estimate. *weight_credit += surplus; // Return the overestimated amount so we can adjust our expectations on how much this entire // execution has taken. - return Ok(surplus); + None } _ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message. }; - for effect in effects.into_iter() { - total_surplus += Self::execute_effects(&origin, &mut holding, effect, trader)?; + if let Some((mut holding, effects)) = maybe_holding_effects { + for effect in effects.into_iter() { + total_surplus += Self::execute_effects(&origin, &mut holding, effect, trader)?; + } } Ok(total_surplus) @@ -192,7 +213,7 @@ impl XcmExecutor { OrderGeneric::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { // pay for `weight` using up to `fees` of the holding account. let desired_weight = Weight::from(weight + debt); - let max_fee = holding.try_take(fees).map_err(|()| XcmError::Undefined)?; + let max_fee = holding.try_take(fees).map_err(|()| XcmError::NotHoldingFees)?; let surplus = trader.buy_weight(desired_weight, max_fee)?; holding.saturating_subsume_all(surplus); let mut remaining_weight= desired_weight; diff --git a/xcm/xcm-executor/src/mock.rs b/xcm/xcm-executor/src/mock.rs index 0ae34ffde09e..28062be4285f 100644 --- a/xcm/xcm-executor/src/mock.rs +++ b/xcm/xcm-executor/src/mock.rs @@ -95,6 +95,9 @@ impl GetDispatchInfo for TestCall { thread_local! { pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); } +pub fn sent_xcm() -> Vec<(MultiLocation, Xcm)> { + SENT_XCM.with(|q| (*q.borrow()).clone()) +} pub struct TestSendXcm; impl SendXcm for TestSendXcm { fn send_xcm(dest: MultiLocation, msg: Xcm) -> XcmResult { @@ -104,42 +107,59 @@ impl SendXcm for TestSendXcm { } thread_local! { - pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); } -pub fn assets(who: MultiLocation) -> Vec { +pub fn assets(who: u64) -> Vec { ASSETS.with(|a| a.borrow().get(&who).map_or(vec![], |a| a.clone().into())) } +pub fn add_asset(who: u64, what: MultiAsset) { + ASSETS.with(|a| a.borrow_mut() + .entry(who) + .or_insert(Assets::new()) + .saturating_subsume(what) + ); +} + pub struct TestAssetTransactor; impl TransactAsset for TestAssetTransactor { fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result<(), XcmError> { - ASSETS.with(|a| a.borrow_mut() - .entry(who.clone()) - .or_insert(Assets::new()) - .saturating_subsume(what.clone()) - ); + let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?; + add_asset(who, what.clone()); Ok(()) } fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { + let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?; ASSETS.with(|a| a.borrow_mut() - .get_mut(who) - .ok_or(XcmError::Undefined)? + .get_mut(&who) + .ok_or(XcmError::NotWithdrawable)? .try_take(what.clone()) - .map_err(|()| XcmError::Undefined) + .map_err(|()| XcmError::NotWithdrawable) ) } } +pub fn to_account(l: MultiLocation) -> Result { + Ok(match l { + // Siblings at 2000+id + X2(Parent, Parachain { id }) => 2000 + id as u64, + // Accounts are their number + X1(AccountIndex64 { index, .. }) => index, + // Children at 1000+id + X1(Parachain { id }) => 1000 + id as u64, + // Self at 3000 + Null => 3000, + l => return Err(l), + }) +} + pub struct TestOriginConverter; impl ConvertOrigin for TestOriginConverter { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { use {OriginKind::*}; match (kind, origin) { (Superuser, _) => Ok(TestOrigin::Root), - (SovereignAccount, X2(Parent, Parachain { id })) => Ok(TestOrigin::Signed(2000 + id as u64)), - (SovereignAccount, X1(AccountIndex64 { index, .. })) => Ok(TestOrigin::Signed(index)), - (SovereignAccount, X1(Parachain { id })) => Ok(TestOrigin::Signed(1000 + id as u64)), - (SovereignAccount, Null) => Ok(TestOrigin::Signed(3000)), + (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), (Native, X1(Parachain { id })) => Ok(TestOrigin::Parachain(id)), (_, origin) => Err(origin), } @@ -150,28 +170,22 @@ thread_local! { pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); } - pub fn add_reserve(from: MultiLocation, asset: MultiAsset) { IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } pub fn add_teleporter(from: MultiLocation, asset: MultiAsset) { IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } - pub struct TestIsReserve; impl FilterAssetLocation for TestIsReserve { - /// A filter to distinguish between asset/location pairs. fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { - let r = IS_RESERVE.with(|r| r.borrow().get(origin) + IS_RESERVE.with(|r| r.borrow().get(origin) .map_or(false, |v| v.iter().any(|a| a.contains(asset))) - ); - println!("FAL: {:?}, {:?} => {}", asset, origin, r); - r + ) } } pub struct TestIsTeleporter; impl FilterAssetLocation for TestIsTeleporter { - /// A filter to distinguish between asset/location pairs. fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { IS_TELEPORTER.with(|r| r.borrow().get(origin) .map_or(false, |v| v.iter().any(|a| a.contains(asset))) @@ -181,14 +195,14 @@ impl FilterAssetLocation for TestIsTeleporter { parameter_types! { pub TestAncestry: MultiLocation = X1(Parachain{id: 42}); - pub AllowPaidFrom: Vec = vec![ - Null, // this chain - X1(Parent), // the relay chain - X2(Parent, Parachain{id: 69}), // our sibling chain 69 - ]; - pub AllowUnpaidFrom: Vec = vec![X1(Parent)]; pub UnitWeightCost: Weight = 10; - pub WeightPrice: (MultiLocation, u128) = (X1(Parent), 1_000_000_000_000); +} +parameter_types! { + // Nothing is allowed to be paid/unpaid by default. + pub static AllowUnpaidFrom: Vec = vec![]; + pub static AllowPaidFrom: Vec = vec![]; + // 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight. + pub static WeightPrice: (MultiLocation, u128) = (Null, 1_000_000_000_000); } pub struct IsInVec(PhantomData); diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-executor/src/tests.rs index ff9944606020..6eee1349cd71 100644 --- a/xcm/xcm-executor/src/tests.rs +++ b/xcm/xcm-executor/src/tests.rs @@ -18,6 +18,7 @@ use super::*; use super::mock::*; use MultiAsset::*; use xcm::v0::Order; +use xcm::v0::NetworkId::Any; #[test] fn basic_setup_works() { @@ -26,19 +27,215 @@ fn basic_setup_works() { &ConcreteFungible { id: X1(Parent), amount: 100 }, &X1(Parent), )); + + assert_eq!(to_account(X1(Parachain{id:1})), Ok(1001)); + assert_eq!(to_account(X1(Parachain{id:50})), Ok(1050)); + assert_eq!(to_account(X2(Parent, Parachain{id:1})), Ok(2001)); + assert_eq!(to_account(X2(Parent, Parachain{id:50})), Ok(2050)); + assert_eq!(to_account(X1(AccountIndex64{index:1, network:Any})), Ok(1)); + assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any})), Ok(42)); + assert_eq!(to_account(Null), Ok(3000)); +} + +#[test] +fn weigher_should_work() { + let mut message = Xcm::ReserveAssetDeposit { + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], + effects: vec![ + Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, + Order::DepositAsset { assets: vec![All], dest: Null }, + ], + }.into(); + assert_eq!(::Weigher::shallow(&mut message), Ok(30)); +} + +#[test] +fn take_weight_credit_barrier_should_work() { + let mut message = Xcm::TransferAsset { + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], + dest: Null, + }; + + let mut weight_credit = 10; + let r = TakeWeightCredit::should_execute( + &X1(Parent), + true, + &mut message, + 10, + &mut weight_credit, + ); + assert_eq!(r, Ok(())); + assert_eq!(weight_credit, 0); + + let r = TakeWeightCredit::should_execute( + &X1(Parent), + true, + &mut message, + 10, + &mut weight_credit, + ); + assert_eq!(r, Err(())); + assert_eq!(weight_credit, 0); +} + +#[test] +fn allow_unpaid_should_work() { + let mut message = Xcm::TransferAsset { + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], + dest: Null, + }; + + AllowUnpaidFrom::set(vec![ X1(Parent) ]); + + let r = AllowUnpaidExecutionFrom::>::should_execute( + &X1(Parachain { id: 1 }), + true, + &mut message, + 10, + &mut 0, + ); + assert_eq!(r, Err(())); + + let r = AllowUnpaidExecutionFrom::>::should_execute( + &X1(Parent), + true, + &mut message, + 10, + &mut 0, + ); + assert_eq!(r, Ok(())); +} + +#[test] +fn allow_paid_should_work() { + AllowPaidFrom::set(vec![ X1(Parent) ]); + + let mut message = Xcm::TransferAsset { + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], + dest: Null, + }; + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &X1(Parachain { id: 1 }), + true, + &mut message, + 10, + &mut 0, + ); + assert_eq!(r, Err(())); + + let mut underpaying_message = Xcm::ReserveAssetDeposit { + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], + effects: vec![ + Order::BuyExecution { fees: All, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] }, + Order::DepositAsset { assets: vec![All], dest: Null }, + ], + }; + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &X1(Parachain { id: 1 }), + true, + &mut underpaying_message, + 30, + &mut 0, + ); + assert_eq!(r, Err(())); + + let mut paying_message = Xcm::ReserveAssetDeposit { + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], + effects: vec![ + Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, + Order::DepositAsset { assets: vec![All], dest: Null }, + ], + }; + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &X1(Parachain { id: 1 }), + true, + &mut paying_message, + 30, + &mut 0, + ); + assert_eq!(r, Err(())); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &X1(Parent), + true, + &mut paying_message, + 30, + &mut 0, + ); + assert_eq!(r, Ok(())); } #[test] -fn basic_execution_should_work() { +fn paying_reserve_deposit_should_work() { add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); + AllowPaidFrom::set(vec![ X1(Parent) ]); + WeightPrice::set((X1(Parent), 1_000_000_000_000)); + + let origin = X1(Parent); + let message = Xcm::ReserveAssetDeposit { + assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], + effects: vec![ + Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, + Order::DepositAsset { assets: vec![ All ], dest: Null }, + ], + }; + let weight_limit = 50; + let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); + assert_eq!(r, Ok(30)); + assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]); +} + +#[test] +fn transfer_should_work() { + // we'll let them have message execution for free. + AllowUnpaidFrom::set(vec![ X1(Parachain{id:1}) ]); + // Child parachain #1 owns 1000 tokens held by us in reserve. + add_asset(1001, ConcreteFungible { id: Null, amount: 1000 }); + // They want to transfer 100 of them to their sibling parachain #2 let r = XcmExecutor::::execute_xcm( - X1(Parent), - Xcm::ReserveAssetDeposit { - assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], - effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: Null } ], + X1(Parachain{id:1}), + Xcm::TransferAsset { + assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], + dest: X1(AccountIndex64{index:3, network:Any}), }, 50, ); - assert_eq!(r, Ok(20)); - assert_eq!(assets(Null), vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]); + assert_eq!(r, Ok(10)); + assert_eq!(assets(3), vec![ ConcreteFungible { id: Null, amount: 100 } ]); + assert_eq!(assets(1001), vec![ ConcreteFungible { id: Null, amount: 900 } ]); + assert_eq!(sent_xcm(), vec![]); +} + +#[test] +fn reserve_transfer_should_work() { + AllowUnpaidFrom::set(vec![ X1(Parachain{id:1}) ]); + // Child parachain #1 owns 1000 tokens held by us in reserve. + add_asset(1001, ConcreteFungible { id: Null, amount: 1000 }); + // The remote account owned by gav. + let three = X1(AccountIndex64{index:3, network:Any}); + + // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 + // and let them know to hand it to account #3. + let r = XcmExecutor::::execute_xcm( + X1(Parachain{id:1}), + Xcm::TransferReserveAsset { + assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], + dest: X1(Parachain{id:2}), + effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three.clone() } ], + }, + 50, + ); + assert_eq!(r, Ok(10)); + + assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]); + assert_eq!(sent_xcm(), vec![( + X1(Parachain { id: 2 }), + Xcm::ReserveAssetDeposit { + assets: vec![ ConcreteFungible { id: X1(Parachain { id: 2 }), amount: 100 } ], + effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ], + }) + ]); } From cd713bff53555e2ebc178bd02141a9a64f4e7aa7 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 4 Apr 2021 17:34:46 +0200 Subject: [PATCH 10/40] Remove code that's not ready --- xcm/xcm-executor/src/assets.rs | 78 ---------------------------------- 1 file changed, 78 deletions(-) diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs index efbf287cdbae..8dbabe2db86f 100644 --- a/xcm/xcm-executor/src/assets.rs +++ b/xcm/xcm-executor/src/assets.rs @@ -26,80 +26,6 @@ pub enum AssetId { Abstract(Vec), } -/// Classification of whether an asset is fungible or not, along with an optional amount or instance. -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] -pub enum Fungibility { - Fungible(Option), - NonFungible(Option), -} - -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] -pub enum MultiAsset2 { - None, - Asset(Fungibility, Option), - All, -} - -impl Encode for MultiAsset2 { - fn encode(&self) -> Vec { - MultiAsset::from(self.clone()).encode() - } -} - -impl Decode for MultiAsset2 { - fn decode(input: &mut I) -> Result { - MultiAsset::decode(input).map(Into::into) - } -} - -impl From for MultiAsset { - fn from(a: MultiAsset2) -> Self { - use {AssetId::*, Fungibility::*, MultiAsset::*, MultiAsset2::Asset}; - use Option::None; - match a { - MultiAsset2::None => MultiAsset::None, - MultiAsset2::All => All, - - Asset(Fungible(_), None) => AllFungible, - Asset(NonFungible(_), None) => AllNonFungible, - - Asset(Fungible(None), Some(Concrete(id))) => AllConcreteFungible { id }, - Asset(Fungible(None), Some(Abstract(id))) => AllAbstractFungible { id }, - Asset(NonFungible(None), Some(Concrete(class))) => AllConcreteNonFungible { class }, - Asset(NonFungible(None), Some(Abstract(class))) => AllAbstractNonFungible { class }, - - Asset(Fungible(Some(amount)), Some(Concrete(id))) => ConcreteFungible { id, amount }, - Asset(Fungible(Some(amount)), Some(Abstract(id))) => AbstractFungible { id, amount }, - Asset(NonFungible(Some(instance)), Some(Concrete(class))) => ConcreteNonFungible { class, instance }, - Asset(NonFungible(Some(instance)), Some(Abstract(class))) => AbstractNonFungible { class, instance }, - } - } -} - -impl From for MultiAsset2 { - fn from(a: MultiAsset) -> Self { - use {AssetId::*, Fungibility::*, MultiAsset::*, MultiAsset2::Asset}; - use Option::None; - match a { - MultiAsset::None => MultiAsset2::None, - All => MultiAsset2::All, - - AllFungible => Asset(Fungible(None), None), - AllNonFungible => Asset(NonFungible(None), None), - - AllConcreteFungible { id } => Asset(Fungible(None), Some(Concrete(id))), - AllAbstractFungible { id } => Asset(Fungible(None), Some(Abstract(id))), - AllConcreteNonFungible { class } => Asset(NonFungible(None), Some(Concrete(class))), - AllAbstractNonFungible { class } => Asset(NonFungible(None), Some(Abstract(class))), - - ConcreteFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Concrete(id))), - AbstractFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Abstract(id))), - ConcreteNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Concrete(class))), - AbstractNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Abstract(class))), - } - } -} - impl AssetId { /// Prepend a MultiLocation to a concrete asset, giving it a new root location. pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> { @@ -126,10 +52,6 @@ impl AssetId { AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance }, } } - - pub fn into_multiasset(self, f: Fungibility) -> MultiAsset2 { - MultiAsset2::Asset(f, Some(self)) - } } /// List of non-wildcard fungible and non-fungible assets. From b1ff9f613f106c22a434df83ee45b4b87ab54a77 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 4 Apr 2021 18:33:52 +0200 Subject: [PATCH 11/40] Fix for an XCM and an additional test --- xcm/xcm-executor/src/assets.rs | 11 ++++----- xcm/xcm-executor/src/lib.rs | 4 +-- xcm/xcm-executor/src/mock.rs | 4 ++- xcm/xcm-executor/src/tests.rs | 45 ++++++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs index 8dbabe2db86f..c676259a853d 100644 --- a/xcm/xcm-executor/src/assets.rs +++ b/xcm/xcm-executor/src/assets.rs @@ -15,7 +15,6 @@ // along with Polkadot. If not, see . use sp_std::{prelude::*, mem, collections::{btree_map::BTreeMap, btree_set::BTreeSet}}; -use parity_scale_codec::{Encode, Decode, Input}; use xcm::v0::{MultiAsset, MultiLocation, AssetInstance}; use sp_runtime::RuntimeDebug; @@ -28,7 +27,7 @@ pub enum AssetId { impl AssetId { /// Prepend a MultiLocation to a concrete asset, giving it a new root location. - pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> { + pub fn prepend_location(&mut self, prepend: &MultiLocation) -> Result<(), ()> { if let AssetId::Concrete(ref mut l) = self { l.prepend_with(prepend.clone()).map_err(|_| ())?; } @@ -281,20 +280,20 @@ impl Assets { self.non_fungible.insert((class, instance)); } - /// Alter any concretely identified assets according to the given `MultiLocation`. + /// Alter any concretely identified assets by prepending the given `MultiLocation`. /// /// WARNING: For now we consider this infallible and swallow any errors. It is thus the caller's responsibility to /// ensure that any internal asset IDs are able to be prepended without overflow. - pub fn reanchor(&mut self, prepend: &MultiLocation) { + pub fn prepend_location(&mut self, prepend: &MultiLocation) { let mut fungible = Default::default(); mem::swap(&mut self.fungible, &mut fungible); self.fungible = fungible.into_iter() - .map(|(mut id, amount)| { let _ = id.reanchor(prepend); (id, amount) }) + .map(|(mut id, amount)| { let _ = id.prepend_location(prepend); (id, amount) }) .collect(); let mut non_fungible = Default::default(); mem::swap(&mut self.non_fungible, &mut non_fungible); self.non_fungible = non_fungible.into_iter() - .map(|(mut class, inst)| { let _ = class.reanchor(prepend); (class, inst) }) + .map(|(mut class, inst)| { let _ = class.prepend_location(prepend); (class, inst) }) .collect(); } diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index fc66ab92f963..903eae3331be 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -59,7 +59,7 @@ impl ExecuteXcm for XcmExecutor { impl XcmExecutor { fn reanchored(mut assets: Assets, dest: &MultiLocation) -> Vec { let inv_dest = Config::LocationInverter::invert_location(&dest); - assets.reanchor(&inv_dest); + assets.prepend_location(&inv_dest); assets.into_assets_iter().collect::>() } @@ -121,7 +121,7 @@ impl XcmExecutor { for asset in assets.iter_mut() { ensure!(!asset.is_wildcard(), XcmError::Wildcard); Config::AssetTransactor::transfer_asset(&asset, &origin, &dest)?; - asset.reanchor(&dest)?; + asset.reanchor(&inv_dest)?; } Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; None diff --git a/xcm/xcm-executor/src/mock.rs b/xcm/xcm-executor/src/mock.rs index 28062be4285f..a0b10d267b85 100644 --- a/xcm/xcm-executor/src/mock.rs +++ b/xcm/xcm-executor/src/mock.rs @@ -35,7 +35,7 @@ pub use crate::config::{ FixedRateOfConcreteFungible, }; -pub enum TestOrigin { Root, Signed(u64), Parachain(u32) } +pub enum TestOrigin { Root, Relay, Signed(u64), Parachain(u32) } #[derive(Debug, Encode, Decode, Eq, PartialEq, Clone, Copy)] pub enum TestCall { @@ -161,6 +161,7 @@ impl ConvertOrigin for TestOriginConverter { (Superuser, _) => Ok(TestOrigin::Root), (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), (Native, X1(Parachain { id })) => Ok(TestOrigin::Parachain(id)), + (Native, X1(Parent)) => Ok(TestOrigin::Relay), (_, origin) => Err(origin), } } @@ -173,6 +174,7 @@ thread_local! { pub fn add_reserve(from: MultiLocation, asset: MultiAsset) { IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } +#[allow(dead_code)] pub fn add_teleporter(from: MultiLocation, asset: MultiAsset) { IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-executor/src/tests.rs index 6eee1349cd71..981e0834f476 100644 --- a/xcm/xcm-executor/src/tests.rs +++ b/xcm/xcm-executor/src/tests.rs @@ -170,8 +170,8 @@ fn allow_paid_should_work() { #[test] fn paying_reserve_deposit_should_work() { - add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); AllowPaidFrom::set(vec![ X1(Parent) ]); + add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); WeightPrice::set((X1(Parent), 1_000_000_000_000)); let origin = X1(Parent); @@ -234,8 +234,49 @@ fn reserve_transfer_should_work() { assert_eq!(sent_xcm(), vec![( X1(Parachain { id: 2 }), Xcm::ReserveAssetDeposit { - assets: vec![ ConcreteFungible { id: X1(Parachain { id: 2 }), amount: 100 } ], + assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ], }) ]); } + +#[test] +fn transacting_should_work() { + AllowUnpaidFrom::set(vec![ X1(Parent) ]); + + let origin = X1(Parent); + let message = Xcm::Transact { + origin_type: OriginKind::Native, + require_weight_at_most: 50, + call: TestCall::Any(50, Option::None).encode().into(), + }; + let weight_limit = 60; + let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); + assert_eq!(r, Ok(60)); +} +/* +#[test] +fn paid_transacting_should_work() { + AllowPaidFrom::set(vec![ X1(Parent) ]); + add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); + WeightPrice::set((X1(Parent), 1_000_000_000_000)); + + let origin = X1(Parent); + let message = Xcm::ReserveAssetDeposit { + assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], + effects: vec![ + Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![ + Xcm::Transact() + ] }, + Order::DepositAsset { assets: vec![ All ], dest: X1(Parent) }, + ], + }; + let weight_limit = 50; + let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); + assert_eq!(r, Ok(30)); + assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]); +} +*/ + +// TODO: Return path weight payment vouchers (NFT allowing free passage for an origin if the message is in +// a particular format). From 9947a81afde92d706b52d8fdc88fb0354000b76e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 4 Apr 2021 23:03:46 +0200 Subject: [PATCH 12/40] Query response system --- xcm/src/v0/mod.rs | 13 ++++- xcm/xcm-executor/src/config.rs | 56 +++++++++++++++--- xcm/xcm-executor/src/lib.rs | 22 +++++--- xcm/xcm-executor/src/mock.rs | 51 ++++++++++++++++- xcm/xcm-executor/src/tests.rs | 100 +++++++++++++++++++++++++++------ 5 files changed, 205 insertions(+), 37 deletions(-) diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 3804c5093f54..72d1fb2108b6 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -51,6 +51,13 @@ pub enum OriginKind { Superuser, } +/// Response data to a query. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +pub enum Response { + /// Some assets. + Assets(Vec), +} + /// Cross-Consensus Message: A message from one consensus system to another. /// /// Consensus systems that may send and receive messages include blockchains and smart contracts. @@ -119,7 +126,7 @@ pub enum XcmGeneric { /// /// Errors: #[codec(index = 3)] - Balances { #[codec(compact)] query_id: u64, assets: Vec }, + QueryResponse { #[codec(compact)] query_id: u64, response: Response }, /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the /// ownership of `dest` within this consensus system. @@ -252,8 +259,8 @@ impl XcmGeneric { => ReserveAssetDeposit { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, TeleportAsset { assets, effects } => TeleportAsset { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, - Balances { query_id: u64, assets } - => Balances { query_id: u64, assets }, + QueryResponse { query_id: u64, response } + => QueryResponse { query_id: u64, response }, TransferAsset { assets, dest } => TransferAsset { assets, dest }, TransferReserveAsset { assets, dest, effects } diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index c65b5f0ba692..71ddc7ad48c7 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -15,8 +15,8 @@ // along with Polkadot. If not, see . use sp_std::marker::PhantomData; -use parity_scale_codec::Decode; -use xcm::v0::{SendXcm, MultiLocation, MultiAsset, XcmGeneric, OrderGeneric}; +use parity_scale_codec::{Encode, Decode}; +use xcm::v0::{SendXcm, MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, Response}; use frame_support::{ ensure, dispatch::{Dispatchable, Parameter, Weight}, weights::{PostDispatchInfo, GetDispatchInfo} }; @@ -123,14 +123,25 @@ pub trait WeightTrader { /// /// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for /// one second of weight. -pub struct FixedRateOfConcreteFungible(PhantomData); +pub struct FixedRateOfConcreteFungible(Weight, PhantomData); impl> WeightTrader for FixedRateOfConcreteFungible { - fn new() -> Self { Self(PhantomData) } + fn new() -> Self { Self(0, PhantomData) } fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { - let (required_id, units_per_second) = T::get(); - let required_amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; - let required = MultiAsset::ConcreteFungible { amount: required_amount, id: required_id }; - Ok(payment.less(required).map_err(|_| ())?.0) + let (id, units_per_second) = T::get(); + let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; + let required = MultiAsset::ConcreteFungible { amount, id }; + let (used, _) = payment.less(required).map_err(|_| ())?; + self.0 = self.0.saturating_add(weight); + Ok(used) + } + fn refund_weight(&mut self, weight: Weight) -> MultiAsset { + let weight = weight.min(self.0); + self.0 -= weight; + let (id, units_per_second) = T::get(); + let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; + let result = MultiAsset::ConcreteFungible { amount, id }; + println!("refunding {:?} for {:?} unused weight", result, weight); + result } } @@ -228,6 +239,32 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { } } +pub trait OnResponse { + fn expecting_response(origin: &MultiLocation, query_id: u64) -> bool; + fn on_response(origin: MultiLocation, query_id: u64, response: Response) -> Weight; +} +impl OnResponse for () { + fn expecting_response(_origin: &MultiLocation, _query_id: u64) -> bool { false } + fn on_response(_origin: MultiLocation, _query_id: u64, _response: Response) -> Weight { 0 } +} + +pub struct AllowKnownQueryResponses(PhantomData); +impl ShouldExecute for AllowKnownQueryResponses { + fn should_execute( + origin: &MultiLocation, + _top_level: bool, + message: &XcmGeneric, + _shallow_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + match message { + XcmGeneric::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id) + => Ok(()), + _ => Err(()), + } + } +} + /// The trait to parametrize the `XcmExecutor`. pub trait Config { /// The outer call dispatch type. @@ -259,4 +296,7 @@ pub trait Config { /// The means of purchasing weight credit for XCM execution. type Trader: WeightTrader; + + /// What to do when a response of a query is found. + type ResponseHandler: OnResponse; } diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 903eae3331be..70f5066afc2f 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -23,7 +23,7 @@ use frame_support::{ }; use xcm::v0::{ Xcm, ExecuteXcm, SendXcm, Error as XcmError, - MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, + MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, Response, }; #[cfg(test)] @@ -37,7 +37,7 @@ use traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; mod assets; pub use assets::{Assets, AssetId}; mod config; -pub use config::{Config, WeightBounds, WeightTrader, ShouldExecute}; +pub use config::{Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse}; pub struct XcmExecutor(PhantomData); @@ -160,10 +160,17 @@ impl XcmExecutor { // It works because we assume that the `Config::Weigher` will always count the `call`'s // `get_dispatch_info` weight into its `shallow` estimate. *weight_credit += surplus; + // Do the same for the total surplus, which is reported to the caller and eventually makes its way + // back up the stack to be subtracted from the deep-weight. + total_surplus += surplus; // Return the overestimated amount so we can adjust our expectations on how much this entire // execution has taken. None } + (origin, XcmGeneric::QueryResponse { query_id, response }) => { + Config::ResponseHandler::on_response(origin, query_id, response); + None + } _ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message. }; @@ -208,15 +215,16 @@ impl XcmExecutor { } OrderGeneric::QueryHolding { query_id, dest, assets } => { let assets = Self::reanchored(holding.min(assets.iter()), &dest); - Config::XcmSender::send_xcm(dest, Xcm::Balances { query_id, assets })?; + Config::XcmSender::send_xcm(dest, Xcm::QueryResponse { query_id, response: Response::Assets(assets) })?; } OrderGeneric::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { // pay for `weight` using up to `fees` of the holding account. - let desired_weight = Weight::from(weight + debt); + let purchasing_weight = Weight::from(weight + debt); let max_fee = holding.try_take(fees).map_err(|()| XcmError::NotHoldingFees)?; - let surplus = trader.buy_weight(desired_weight, max_fee)?; - holding.saturating_subsume_all(surplus); - let mut remaining_weight= desired_weight; + let unspent = trader.buy_weight(purchasing_weight, max_fee)?; + holding.saturating_subsume_all(unspent); + + let mut remaining_weight = weight; for message in xcm.into_iter() { match Self::do_execute_xcm(origin.clone(), false, message, &mut remaining_weight, None, trader) { Err(e) if halt_on_error => return Err(e), diff --git a/xcm/xcm-executor/src/mock.rs b/xcm/xcm-executor/src/mock.rs index a0b10d267b85..372790d08510 100644 --- a/xcm/xcm-executor/src/mock.rs +++ b/xcm/xcm-executor/src/mock.rs @@ -32,7 +32,7 @@ pub use frame_support::{ pub use crate::traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, LocationInverter}; pub use crate::config::{ TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds, - FixedRateOfConcreteFungible, + FixedRateOfConcreteFungible, AllowKnownQueryResponses }; pub enum TestOrigin { Root, Relay, Signed(u64), Parachain(u32) } @@ -123,12 +123,14 @@ pub fn add_asset(who: u64, what: MultiAsset) { pub struct TestAssetTransactor; impl TransactAsset for TestAssetTransactor { fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result<(), XcmError> { + dbg!(what, who); let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?; add_asset(who, what.clone()); Ok(()) } fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { + dbg!(what, who); let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?; ASSETS.with(|a| a.borrow_mut() .get_mut(&who) @@ -149,6 +151,8 @@ pub fn to_account(l: MultiLocation) -> Result { X1(Parachain { id }) => 1000 + id as u64, // Self at 3000 Null => 3000, + // Parent at 3000 + X1(Parent) => 3001, l => return Err(l), }) } @@ -162,6 +166,7 @@ impl ConvertOrigin for TestOriginConverter { (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), (Native, X1(Parachain { id })) => Ok(TestOrigin::Parachain(id)), (Native, X1(Parent)) => Ok(TestOrigin::Relay), + (Native, X1(AccountIndex64 {index, ..})) => Ok(TestOrigin::Signed(index)), (_, origin) => Err(origin), } } @@ -195,6 +200,48 @@ impl FilterAssetLocation for TestIsTeleporter { } } +use xcm::v0::Response; +pub enum ResponseSlot { + Expecting(MultiLocation), + Received(Response), +} +thread_local! { + pub static QUERIES: RefCell> = RefCell::new(BTreeMap::new()); +} +pub struct TestResponseHandler; +impl OnResponse for TestResponseHandler { + fn expecting_response(origin: &MultiLocation, query_id: u64) -> bool { + QUERIES.with(|q| match q.borrow().get(&query_id) { + Some(ResponseSlot::Expecting(ref l)) => l == origin, + _ => false, + }) + } + fn on_response(origin: MultiLocation, query_id: u64, response: xcm::v0::Response) -> Weight { + QUERIES.with(|q| { + q.borrow_mut() + .entry(query_id) + .and_modify(|v| if matches!(*v, ResponseSlot::Expecting(..)) { + *v = ResponseSlot::Received(response); + }); + }); + 10 + } +} +pub fn expect_response(query_id: u64, from: MultiLocation) { + QUERIES.with(|q| q.borrow_mut() + .insert(query_id, ResponseSlot::Expecting(from)) + ); +} +pub fn response(query_id: u64) -> Option { + QUERIES.with(|q| q.borrow() + .get(&query_id) + .and_then(|v| match v { + ResponseSlot::Received(r) => Some(r.clone()), + _ => None, + }) + ) +} + parameter_types! { pub TestAncestry: MultiLocation = X1(Parachain{id: 42}); pub UnitWeightCost: Weight = 10; @@ -214,6 +261,7 @@ impl>> Contains for IsInVec { pub type TestBarrier = ( TakeWeightCredit, + AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom>, AllowUnpaidExecutionFrom>, ); @@ -230,4 +278,5 @@ impl Config for TestConfig { type Barrier = TestBarrier; type Weigher = FixedWeightBounds; type Trader = FixedRateOfConcreteFungible; + type ResponseHandler = TestResponseHandler; } diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-executor/src/tests.rs index 981e0834f476..e0ecb9f7e839 100644 --- a/xcm/xcm-executor/src/tests.rs +++ b/xcm/xcm-executor/src/tests.rs @@ -16,7 +16,7 @@ use super::*; use super::mock::*; -use MultiAsset::*; +use {MultiAsset::*, Option::None}; use xcm::v0::Order; use xcm::v0::NetworkId::Any; @@ -248,35 +248,99 @@ fn transacting_should_work() { let message = Xcm::Transact { origin_type: OriginKind::Native, require_weight_at_most: 50, - call: TestCall::Any(50, Option::None).encode().into(), + call: TestCall::Any(50, None).encode().into(), }; let weight_limit = 60; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); assert_eq!(r, Ok(60)); } -/* + #[test] -fn paid_transacting_should_work() { - AllowPaidFrom::set(vec![ X1(Parent) ]); - add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); - WeightPrice::set((X1(Parent), 1_000_000_000_000)); +fn transacting_should_respect_max_weight_requirement() { + AllowUnpaidFrom::set(vec![ X1(Parent) ]); let origin = X1(Parent); - let message = Xcm::ReserveAssetDeposit { - assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], + let message = Xcm::Transact { + origin_type: OriginKind::Native, + require_weight_at_most: 40, + call: TestCall::Any(50, None).encode().into(), + }; + let weight_limit = 60; + let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); + assert_eq!(r, Err(XcmError::TooMuchWeightRequired)); +} + +#[test] +fn transacting_should_refund_weight() { + AllowUnpaidFrom::set(vec![ X1(Parent) ]); + + let origin = X1(Parent); + let message = Xcm::Transact { + origin_type: OriginKind::Native, + require_weight_at_most: 50, + call: TestCall::Any(50, Some(30)).encode().into(), + }; + let weight_limit = 60; + let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); + assert_eq!(r, Ok(40)); +} + +#[test] +fn paid_transacting_should_refund_payment_for_unused_weight() { + let one = X1(AccountIndex64{index:1, network:Any}); + AllowPaidFrom::set(vec![ one.clone() ]); + add_asset(1, ConcreteFungible { id: X1(Parent), amount: 100 }); + WeightPrice::set((X1(Parent), 1_000_000_000_000)); + + let origin = one.clone(); + let message = Xcm::WithdrawAsset { + assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], // enough for 100 units of weight. effects: vec![ - Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![ - Xcm::Transact() + Order::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![ + Xcm::Transact { + origin_type: OriginKind::Native, + require_weight_at_most: 60, + // call estimated at 70 but only takes 10. + call: TestCall::Any(60, Some(10)).encode().into(), + } ] }, - Order::DepositAsset { assets: vec![ All ], dest: X1(Parent) }, + Order::DepositAsset { assets: vec![ All ], dest: one.clone() }, ], }; - let weight_limit = 50; + let weight_limit = 100; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); - assert_eq!(r, Ok(30)); - assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]); + assert_eq!(r, Ok(50)); + assert_eq!(assets(1), vec![ ConcreteFungible { id: X1(Parent), amount: 50 } ]); } -*/ -// TODO: Return path weight payment vouchers (NFT allowing free passage for an origin if the message is in -// a particular format). +#[test] +fn prepaid_result_of_query_should_get_free_execution() { + let query_id = 33; + let origin = X1(Parent); + expect_response(query_id, origin.clone()); + + let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]); + let message = Xcm::QueryResponse { + query_id, + response: the_response.clone(), + }; + let weight_limit = 10; + + // First time the response gets through since we're expecting it... + let r = XcmExecutor::::execute_xcm(origin.clone(), message.clone(), weight_limit); + assert_eq!(r, Ok(10)); + assert_eq!(response(query_id).unwrap(), the_response); + + // Second time it doesn't, since we're not. + let r = XcmExecutor::::execute_xcm(origin.clone(), message.clone(), weight_limit); + assert_eq!(r, Err(XcmError::Barrier)); +} + +// TODO: General ResponseMap of (QueryId, Origin) -> EitherOr> which +// allows free execution of the message and then either stores the result or calls a dispatch - in this case +// it could go overweight be up to the weight of whatever dispatch is in there. It should be added on and +// checked before executing any further XCMs. + +// TODO: Ordering flag per message fragment in an aggregate message. + +// TODO: Test transact execution origins. From 31b851ef277b56be23916e97259f9c7f102f1f12 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 5 Apr 2021 22:48:00 +0200 Subject: [PATCH 13/40] XCMP message dispatch system reimagining - Moved most of the logic into xcm-handler pallet - Altered the outgoing XCMP API from push to pull - Changed underlying outgoing queue data structures to avoid multi-page read/writes - Introduced queuing for incoming messages - Introduced signal messages as a flow-control sub-stream - Introduced flow-control with basic threshold back-pressure - Introduced overall weight limitation on messages executed - Additonal alterations to XCM APIs for the new system --- xcm/src/v0/mod.rs | 2 +- xcm/src/v0/traits.rs | 56 +++++++++++++++++++----- xcm/xcm-builder/src/currency_adapter.rs | 5 ++- xcm/xcm-builder/src/fungibles_adapter.rs | 6 ++- xcm/xcm-builder/src/lib.rs | 2 +- xcm/xcm-executor/src/lib.rs | 32 ++++++++++---- xcm/xcm-executor/src/tests.rs | 5 +++ 7 files changed, 82 insertions(+), 26 deletions(-) diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 72d1fb2108b6..1cb78fbb47e1 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -30,7 +30,7 @@ pub use junction::{Junction, NetworkId}; pub use multi_asset::{MultiAsset, AssetInstance}; pub use multi_location::MultiLocation; pub use order::{Order, OrderGeneric}; -pub use traits::{Error, Result, SendXcm, ExecuteXcm}; +pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome}; // TODO: Efficient encodings for Vec, Vec, using initial byte values 128+ to encode the number of // items in the vector. diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs index 96f2a4bda90a..190c7dccf7f1 100644 --- a/xcm/src/v0/traits.rs +++ b/xcm/src/v0/traits.rs @@ -19,7 +19,7 @@ use core::result; use parity_scale_codec::{Encode, Decode}; -use super::{MultiLocation, Xcm}; +use super::{MultiLocation, Xcm, XcmGeneric}; #[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, Debug)] pub enum Error { @@ -77,22 +77,56 @@ impl From<()> for Error { pub type Result = result::Result<(), Error>; -pub trait ExecuteXcm { - fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: u64) -> result::Result; +/// Local weight type; execution time in picoseconds. +pub type Weight = u64; + +/// Outcome of an XCM excution. +pub enum Outcome { + /// Execution completed successfully; given weight was used. + Complete(Weight), + /// Execution started, but did not complete successfully due to the given error; given weight was used. + Incomplete(Weight, Error), + /// Execution did not start due to the given error. + Error(Error), +} + +impl From for Result { + fn from(o: Outcome) -> Self { + match o { + Outcome::Complete(_) => Ok(()), + Outcome::Incomplete(_, e) => Err(e), + Outcome::Error(e) => Err(e), + } + } +} + +impl Outcome { + /// How much weight was used by the XCM execution attempt. + fn weight_used(&self) -> Weight { + match self { + Outcome::Complete(w) => w, + Outcome::Incomplete(w, _) => w, + Outcome::Error(_) => 0, + } + } +} + +pub trait ExecuteXcm { + fn execute_xcm(origin: MultiLocation, message: XcmGeneric, weight_limit: Weight) -> Outcome; } -impl ExecuteXcm for () { - fn execute_xcm(_origin: MultiLocation, _message: Xcm, _weight_limit: u64) -> result::Result { - Err(Error::Unimplemented) +impl ExecuteXcm for () { + fn execute_xcm(_origin: MultiLocation, _message: XcmGeneric, _weight_limit: Weight) -> Outcome { + Outcome::Error(Error::Unimplemented) } } -pub trait SendXcm { - fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result; +pub trait SendXcm { + fn send_xcm(dest: MultiLocation, msg: XcmGeneric, weight_limit: Weight) -> Outcome; } -impl SendXcm for () { - fn send_xcm(_dest: MultiLocation, _msg: Xcm) -> Result { - Err(Error::Unimplemented) +impl SendXcm for () { + fn send_xcm(_dest: MultiLocation, _msg: XcmGeneric, _weight_limit: Weight) -> Outcome { + Outcome::Error(Error::Unimplemented) } } diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs index 1a3b1f549953..259ea6354f7d 100644 --- a/xcm/xcm-builder/src/currency_adapter.rs +++ b/xcm/xcm-builder/src/currency_adapter.rs @@ -19,6 +19,7 @@ use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation}; use sp_runtime::traits::SaturatedConversion; use frame_support::traits::{ExistenceRequirement::AllowDeath, WithdrawReasons}; use xcm_executor::traits::{MatchesFungible, LocationConversion, TransactAsset}; +use xcm_executor::Assets; /// Asset transaction errors. enum Error { @@ -70,7 +71,7 @@ impl< fn withdraw_asset( what: &MultiAsset, who: &MultiLocation - ) -> result::Result { + ) -> result::Result { // Check we handle this asset. let amount: u128 = Matcher::matches_fungible(what) .ok_or(Error::AssetNotFound)? @@ -82,6 +83,6 @@ impl< .map_err(|_| Error::AmountToBalanceConversionFailed)?; Currency::withdraw(&who, balance_amount, WithdrawReasons::TRANSFER, AllowDeath) .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; - Ok(what.clone()) + Ok(what.clone().into()) } } diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs index 3c4009a776fd..a95cf92d62a1 100644 --- a/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/xcm/xcm-builder/src/fungibles_adapter.rs @@ -255,13 +255,15 @@ impl< fn withdraw_asset( what: &MultiAsset, who: &MultiLocation - ) -> result::Result { + ) -> result::Result { // Check we handle this asset. let (asset_id, amount) = Matcher::matches_fungibles(what)?; let who = AccountIdConverter::from_location(who) .ok_or(Error::AccountIdConversionFailed)?; Assets::burn_from(asset_id, &who, amount) .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; - Ok(what.clone()) + Ok(what.clone().into()) } + + // TODO: implement transfer_asset, but should move it into a different trait. } diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs index 0f12762e8864..d9cbedf8b641 100644 --- a/xcm/xcm-builder/src/lib.rs +++ b/xcm/xcm-builder/src/lib.rs @@ -37,5 +37,5 @@ use xcm_executor::traits::InvertLocation; use xcm::v0::{MultiLocation, Junction}; use frame_support::traits::Get; -#[deprecated("use `xcm-executor::traits::LocationInverter` instead")] +#[deprecated="use `xcm-executor::traits::LocationInverter` instead"] pub use xcm_executor::traits::LocationInverter; diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 70f5066afc2f..94408c15acfe 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -22,7 +22,7 @@ use frame_support::{ dispatch::{Weight, Dispatchable} }; use xcm::v0::{ - Xcm, ExecuteXcm, SendXcm, Error as XcmError, + Xcm, ExecuteXcm, SendXcm, Error as XcmError, Outcome, MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, Response, }; @@ -42,17 +42,31 @@ pub use config::{Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse}; pub struct XcmExecutor(PhantomData); impl ExecuteXcm for XcmExecutor { - fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Result { + fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Outcome { // TODO: We should identify recursive bombs here and bail. let mut message = XcmGeneric::::from(message); - let shallow_weight = Config::Weigher::shallow(&mut message)?; - let deep_weight = Config::Weigher::deep(&mut message)?; - let maximum_weight = shallow_weight.checked_add(deep_weight) - .ok_or(XcmError::WeightLimitReached)?; - ensure!(maximum_weight <= weight_limit, XcmError::WeightLimitReached); + let shallow_weight = match Config::Weigher::shallow(&mut message) { + Ok(x) => x, + Err(r) => return Outcome::Error(e), + }; + let deep_weight = match Config::Weigher::deep(&mut message) { + Ok(x) => x, + Err(r) => return Outcome::Error(e), + }; + let maximum_weight = match shallow_weight.checked_add(deep_weight) { + Some(x) => x, + None => return Outcome::Error(XcmError::WeightLimitReached), + }; + if maximum_weight > weight_limit { + return Outcome::Error(XcmError::WeightLimitReached); + } let mut trader = Config::Trader::new(); - let surplus = Self::do_execute_xcm(origin, true, message, &mut 0, Some(shallow_weight), &mut trader)?; - Ok(maximum_weight.saturating_sub(surplus)) + match Self::do_execute_xcm(origin, true, message, &mut 0, Some(shallow_weight), &mut trader) { + Ok(surplus) => Outcome::Complete(maximum_weight.saturating_sub(surplus)), + // TODO: We can do better than returning `maximum_weight` here, and we should otherwise we'll + // needlessly be disregarding block execution time. + Err(e) => Outcome::Incomplete(maximum_weight.saturating_sub(surplus), maximum_weight), + } } } diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-executor/src/tests.rs index e0ecb9f7e839..e9aaf068d0d3 100644 --- a/xcm/xcm-executor/src/tests.rs +++ b/xcm/xcm-executor/src/tests.rs @@ -317,6 +317,7 @@ fn paid_transacting_should_refund_payment_for_unused_weight() { fn prepaid_result_of_query_should_get_free_execution() { let query_id = 33; let origin = X1(Parent); + // We put this in manually here, but normally this would be done at the point of crafting the message. expect_response(query_id, origin.clone()); let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]); @@ -341,6 +342,10 @@ fn prepaid_result_of_query_should_get_free_execution() { // it could go overweight be up to the weight of whatever dispatch is in there. It should be added on and // checked before executing any further XCMs. +// TODO: Integrate into the XCM dispatch system in the runtimes + // TODO: Ordering flag per message fragment in an aggregate message. // TODO: Test transact execution origins. + +// TODO: Don't just burn fees - send them somewhere, and test that we get them! From 24e5dcc3e1a858938057557d19ec29a8c848da74 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 6 Apr 2021 14:01:36 +0200 Subject: [PATCH 14/40] Some build fixes --- xcm/src/double_encoded.rs | 1 + xcm/src/lib.rs | 1 + xcm/src/v0/mod.rs | 1 + xcm/src/v0/traits.rs | 38 ++++++++++++++++++++-------------- xcm/xcm-builder/src/lib.rs | 5 ----- xcm/xcm-executor/src/config.rs | 2 +- xcm/xcm-executor/src/lib.rs | 10 ++++----- 7 files changed, 32 insertions(+), 26 deletions(-) diff --git a/xcm/src/double_encoded.rs b/xcm/src/double_encoded.rs index 02b2117d457f..eaa07c16feee 100644 --- a/xcm/src/double_encoded.rs +++ b/xcm/src/double_encoded.rs @@ -18,6 +18,7 @@ use alloc::vec::Vec; use parity_scale_codec::{Encode, Decode}; #[derive(Eq, PartialEq, Clone, Encode, Decode, Debug)] +#[codec(dumb_trait_bound)] pub struct DoubleEncoded { encoded: Vec, #[codec(skip)] diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs index cc21db22f54a..319bd78f6545 100644 --- a/xcm/src/lib.rs +++ b/xcm/src/lib.rs @@ -31,6 +31,7 @@ pub use double_encoded::DoubleEncoded; /// A single XCM message, together with its version code. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +#[codec(dumb_trait_bound)] pub enum VersionedXcmGeneric { V0(v0::XcmGeneric), } diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 1cb78fbb47e1..52da53496b8c 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -67,6 +67,7 @@ pub enum Response { /// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer /// XCM format, known as `VersionedXcm`. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +#[codec(dumb_trait_bound)] pub enum XcmGeneric { /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into `holding`. Execute the /// orders (`effects`). diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs index 190c7dccf7f1..a4ad17ab2ab4 100644 --- a/xcm/src/v0/traits.rs +++ b/xcm/src/v0/traits.rs @@ -32,7 +32,7 @@ pub enum Error { UntrustedReserveLocation, UntrustedTeleportLocation, DestinationBufferOverflow, - CannotReachDestination, + CannotReachDestination(#[codec(skip)] &'static str), MultiLocationFull, FailedToDecode, BadOrigin, @@ -67,6 +67,9 @@ pub enum Error { NotWithdrawable, /// Indicates that the consensus system cannot deposit an asset under the ownership of a particular location. LocationCannotHold, + /// We attempted to send an XCM to the local consensus system. Execution was not possible probably due to + /// no execution weight being assigned. + DestinationIsLocal, } impl From<()> for Error { @@ -81,6 +84,7 @@ pub type Result = result::Result<(), Error>; pub type Weight = u64; /// Outcome of an XCM excution. +#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug)] pub enum Outcome { /// Execution completed successfully; given weight was used. Complete(Weight), @@ -90,22 +94,26 @@ pub enum Outcome { Error(Error), } -impl From for Result { - fn from(o: Outcome) -> Self { - match o { +impl Outcome { + pub fn ensure_complete(self) -> Result { + match self { Outcome::Complete(_) => Ok(()), Outcome::Incomplete(_, e) => Err(e), Outcome::Error(e) => Err(e), } } -} - -impl Outcome { + pub fn ensure_execution(self) -> result::Result { + match self { + Outcome::Complete(w) => Ok(w), + Outcome::Incomplete(w, _) => Ok(w), + Outcome::Error(e) => Err(e), + } + } /// How much weight was used by the XCM execution attempt. - fn weight_used(&self) -> Weight { + pub fn weight_used(&self) -> Weight { match self { - Outcome::Complete(w) => w, - Outcome::Incomplete(w, _) => w, + Outcome::Complete(w) => *w, + Outcome::Incomplete(w, _) => *w, Outcome::Error(_) => 0, } } @@ -121,12 +129,12 @@ impl ExecuteXcm for () { } } -pub trait SendXcm { - fn send_xcm(dest: MultiLocation, msg: XcmGeneric, weight_limit: Weight) -> Outcome; +pub trait SendXcm { + fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result; } -impl SendXcm for () { - fn send_xcm(_dest: MultiLocation, _msg: XcmGeneric, _weight_limit: Weight) -> Outcome { - Outcome::Error(Error::Unimplemented) +impl SendXcm for () { + fn send_xcm(_dest: MultiLocation, _msg: Xcm) -> Result { + Err(Error::Unimplemented) } } diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs index d9cbedf8b641..79f1bb49b757 100644 --- a/xcm/xcm-builder/src/lib.rs +++ b/xcm/xcm-builder/src/lib.rs @@ -32,10 +32,5 @@ mod fungibles_adapter; pub use currency_adapter::CurrencyAdapter; pub use fungibles_adapter::FungiblesAdapter; -use sp_std::marker::PhantomData; -use xcm_executor::traits::InvertLocation; -use xcm::v0::{MultiLocation, Junction}; -use frame_support::traits::Get; - #[deprecated="use `xcm-executor::traits::LocationInverter` instead"] pub use xcm_executor::traits::LocationInverter; diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index 71ddc7ad48c7..b572e6ff0f2a 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -15,7 +15,7 @@ // along with Polkadot. If not, see . use sp_std::marker::PhantomData; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::Decode; use xcm::v0::{SendXcm, MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, Response}; use frame_support::{ ensure, dispatch::{Dispatchable, Parameter, Weight}, weights::{PostDispatchInfo, GetDispatchInfo} diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 94408c15acfe..68c72ca43d26 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -41,17 +41,17 @@ pub use config::{Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse}; pub struct XcmExecutor(PhantomData); -impl ExecuteXcm for XcmExecutor { - fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Outcome { +impl ExecuteXcm for XcmExecutor { + fn execute_xcm(origin: MultiLocation, message: XcmGeneric, weight_limit: Weight) -> Outcome { // TODO: We should identify recursive bombs here and bail. let mut message = XcmGeneric::::from(message); let shallow_weight = match Config::Weigher::shallow(&mut message) { Ok(x) => x, - Err(r) => return Outcome::Error(e), + Err(()) => return Outcome::Error(XcmError::WeightNotComputable), }; let deep_weight = match Config::Weigher::deep(&mut message) { Ok(x) => x, - Err(r) => return Outcome::Error(e), + Err(()) => return Outcome::Error(XcmError::WeightNotComputable), }; let maximum_weight = match shallow_weight.checked_add(deep_weight) { Some(x) => x, @@ -65,7 +65,7 @@ impl ExecuteXcm for XcmExecutor { Ok(surplus) => Outcome::Complete(maximum_weight.saturating_sub(surplus)), // TODO: We can do better than returning `maximum_weight` here, and we should otherwise we'll // needlessly be disregarding block execution time. - Err(e) => Outcome::Incomplete(maximum_weight.saturating_sub(surplus), maximum_weight), + Err(e) => Outcome::Incomplete(maximum_weight, e), } } } From 2c53ffe2ed2b040d0056407a3e0ad7ba973a1e3b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 6 Apr 2021 19:16:55 +0200 Subject: [PATCH 15/40] Remove the Encode bounds sprayed around --- xcm/src/lib.rs | 1 - xcm/src/v0/mod.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs index 319bd78f6545..cc21db22f54a 100644 --- a/xcm/src/lib.rs +++ b/xcm/src/lib.rs @@ -31,7 +31,6 @@ pub use double_encoded::DoubleEncoded; /// A single XCM message, together with its version code. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] -#[codec(dumb_trait_bound)] pub enum VersionedXcmGeneric { V0(v0::XcmGeneric), } diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 52da53496b8c..29173e6ccfb2 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -239,7 +239,7 @@ impl< } impl< - Call: Clone + Eq + PartialEq + Encode + Decode + Debug + Call: Encode > TryFrom> for XcmGeneric { type Error = (); fn try_from(x: VersionedXcmGeneric) -> result::Result { From 84826e8ecd209f2eb994bff67b2f5dcf78f747ad Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 6 Apr 2021 19:26:59 +0200 Subject: [PATCH 16/40] More faff --- xcm/src/v0/mod.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 29173e6ccfb2..b822aa086a56 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -230,17 +230,13 @@ pub enum XcmGeneric { /// call other than it is pre-encoded. pub type Xcm = XcmGeneric<()>; -impl< - Call: Clone + Eq + PartialEq + Encode + Decode + Debug -> From> for VersionedXcmGeneric { +impl From> for VersionedXcmGeneric { fn from(x: XcmGeneric) -> Self { VersionedXcmGeneric::V0(x) } } -impl< - Call: Encode -> TryFrom> for XcmGeneric { +impl TryFrom> for XcmGeneric { type Error = (); fn try_from(x: VersionedXcmGeneric) -> result::Result { match x { From d0a5148236db6939b6d1312f5aa28dd2ceefe86b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 6 Apr 2021 19:58:57 +0200 Subject: [PATCH 17/40] Fix bounds amek use latest scale codec. --- Cargo.lock | 16 +++++++++++----- xcm/src/double_encoded.rs | 3 ++- xcm/src/lib.rs | 2 ++ xcm/src/v0/mod.rs | 3 ++- xcm/src/v0/order.rs | 3 ++- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffa8f21cec50..78f883c0b2cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,6 +160,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7" + [[package]] name = "asn1_der" version = "0.6.3" @@ -5054,11 +5060,11 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c823fdae1bb5ff5708ee61a62697e6296175dc671710876871c853f48592b3" +checksum = "731f4d179ed52b1c7eeb29baf29c604ea9301b889b23ce93660220a5465d5c6f" dependencies = [ - "arrayvec 0.5.2", + "arrayvec 0.7.0", "bitvec", "byte-slice-cast", "parity-scale-codec-derive", @@ -5067,9 +5073,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9029e65297c7fd6d7013f0579e193ec2b34ae78eabca854c9417504ad8a2d214" +checksum = "f44c5f94427bd0b5076e8f7e15ca3f60a4d8ac0077e4793884e6fdfd8915344e" dependencies = [ "proc-macro-crate 0.1.5", "proc-macro2", diff --git a/xcm/src/double_encoded.rs b/xcm/src/double_encoded.rs index eaa07c16feee..385610e75eac 100644 --- a/xcm/src/double_encoded.rs +++ b/xcm/src/double_encoded.rs @@ -18,7 +18,8 @@ use alloc::vec::Vec; use parity_scale_codec::{Encode, Decode}; #[derive(Eq, PartialEq, Clone, Encode, Decode, Debug)] -#[codec(dumb_trait_bound)] +#[codec(encode_bound())] +#[codec(decode_bound())] pub struct DoubleEncoded { encoded: Vec, #[codec(skip)] diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs index cc21db22f54a..abcb03be7289 100644 --- a/xcm/src/lib.rs +++ b/xcm/src/lib.rs @@ -31,6 +31,8 @@ pub use double_encoded::DoubleEncoded; /// A single XCM message, together with its version code. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +#[codec(encode_bound())] +#[codec(decode_bound())] pub enum VersionedXcmGeneric { V0(v0::XcmGeneric), } diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index b822aa086a56..872ae2e6661c 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -67,7 +67,8 @@ pub enum Response { /// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer /// XCM format, known as `VersionedXcm`. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] -#[codec(dumb_trait_bound)] +#[codec(encode_bound())] +#[codec(decode_bound())] pub enum XcmGeneric { /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into `holding`. Execute the /// orders (`effects`). diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs index 6631bfb2f502..042a10f3c6f4 100644 --- a/xcm/src/v0/order.rs +++ b/xcm/src/v0/order.rs @@ -22,7 +22,8 @@ use super::{MultiAsset, MultiLocation, XcmGeneric}; /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] -#[codec(dumb_trait_bound)] +#[codec(encode_bound())] +#[codec(decode_bound())] pub enum OrderGeneric { /// Do nothing. Not generally used. #[codec(index = 0)] From f1515bf1c54c6b551d90289e1273567728a295d5 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 6 Apr 2021 19:36:00 +0200 Subject: [PATCH 18/40] remove println --- xcm/xcm-executor/src/config.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index b572e6ff0f2a..b59bb391fe9b 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -140,7 +140,6 @@ impl> WeightTrader for FixedRateOfConcreteFungible let (id, units_per_second) = T::get(); let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; let result = MultiAsset::ConcreteFungible { amount, id }; - println!("refunding {:?} for {:?} unused weight", result, weight); result } } From df6a667c96c0970df3b07d88cccd28235d156dd7 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 6 Apr 2021 19:33:16 +0200 Subject: [PATCH 19/40] fixes --- runtime/common/src/xcm_sender.rs | 2 +- runtime/parachains/src/ump.rs | 24 +++++++++++++++--------- runtime/rococo/src/lib.rs | 11 ++++++++++- xcm/xcm-executor/src/lib.rs | 6 +++++- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index 3b81516c7fb7..0962c070c6e4 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -36,7 +36,7 @@ impl SendXcm for RelayChainXcmSender ).map_err(Into::::into)?; Ok(()) } else { - Err(Error::CannotReachDestination) + Err(Error::CannotReachDestination("TODO: `dest` to string")) } } } diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 4a8c194a62b3..c05378768bd4 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -20,6 +20,7 @@ use crate::{ }; use sp_std::{fmt, prelude::*}; use sp_std::collections::{btree_map::BTreeMap, vec_deque::VecDeque}; +use sp_runtime::traits::Zero; use frame_support::{decl_module, decl_storage, StorageMap, StorageValue, weights::Weight, traits::Get}; use primitives::v1::{Id as ParaId, UpwardMessage}; @@ -61,19 +62,23 @@ pub struct XcmSink(sp_std::marker::PhantomData); impl UmpSink for XcmSink { fn process_upward_message(origin: ParaId, msg: Vec) -> Weight { use parity_scale_codec::Decode; - use xcm::VersionedXcm; - use xcm::v0::{Junction, MultiLocation, ExecuteXcm}; + use xcm::VersionedXcmGeneric; + use xcm::v0::{Junction, MultiLocation, ExecuteXcm, Outcome}; use xcm_executor::XcmExecutor; - let weight: Weight = 0; - - if let Ok(versioned_xcm_message) = VersionedXcm::decode(&mut &msg[..]) { + // TODO: Get a proper weight limit here. Probably from Relay Chain Config + let weight_limit = Weight::max_value(); + let weight = if let Ok(versioned_xcm_message) = VersionedXcmGeneric::decode(&mut &msg[..]) { match versioned_xcm_message { - VersionedXcm::V0(xcm_message) => { + VersionedXcmGeneric::V0(xcm_message) => { let xcm_junction: Junction = Junction::Parachain { id: origin.into() }; let xcm_location: MultiLocation = xcm_junction.into(); - // TODO: Do something with result. - let _result = XcmExecutor::::execute_xcm(xcm_location, xcm_message); + let result = XcmExecutor::::execute_xcm(xcm_location, xcm_message, weight_limit); + match result { + Outcome::Complete(weight) => weight, + Outcome::Incomplete(weight, _e) => weight, + Outcome::Error(_e) => Weight::zero(), + } } } } else { @@ -81,7 +86,8 @@ impl UmpSink for XcmSink { target: LOG_TARGET, "Failed to decode versioned XCM from upward message.", ); - } + Weight::zero() + }; // TODO: to be sound, this implementation must ensure that returned (and thus consumed) // weight is limited to some small portion of the total block weight (as a ballpark, 1/4, 1/8 diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 11b03b069021..5c61cb7084c3 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -81,7 +81,7 @@ pub use pallet_balances::Call as BalancesCall; use polkadot_parachain::primitives::Id as ParaId; use xcm::v0::{MultiLocation, NetworkId}; -use xcm_executor::traits::IsConcrete; +use xcm_executor::{traits::IsConcrete, FixedWeightBounds, FixedRateOfConcreteFungible}; use xcm_builder::{ AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative, @@ -616,6 +616,11 @@ type LocalOriginConverter = ( ChildSystemParachainAsSuperuser, ); +parameter_types! { + pub const BaseXcmWeight: Weight = 100_000; + pub const RocFee: (MultiLocation, u128) = (RocLocation::get(), 1 * CENTS); +} + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type Call = Call; @@ -625,6 +630,10 @@ impl xcm_executor::Config for XcmConfig { type IsReserve = (); type IsTeleporter = (); type LocationInverter = LocationInverter; + type Barrier = (); + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfConcreteFungible; + type ResponseHandler = (); } impl parachains_session_info::Config for Runtime {} diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 68c72ca43d26..05ad5e9b7e52 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -37,7 +37,11 @@ use traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; mod assets; pub use assets::{Assets, AssetId}; mod config; -pub use config::{Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse}; +pub use config::{ + Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse, FixedWeightBounds, + FixedRateOfConcreteFungible, AllowTopLevelPaidExecutionFrom, TakeWeightCredit, + AllowUnpaidExecutionFrom, AllowKnownQueryResponses, +}; pub struct XcmExecutor(PhantomData); From 9051563d3f7e0c47156a52bab266b62adfb63ee4 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 6 Apr 2021 19:33:16 +0200 Subject: [PATCH 20/40] Fix XcmExecutor Tests --- xcm/xcm-executor/src/mock.rs | 2 +- xcm/xcm-executor/src/tests.rs | 46 +++++++++++++++++------------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/xcm/xcm-executor/src/mock.rs b/xcm/xcm-executor/src/mock.rs index 372790d08510..5cc49ae27d8e 100644 --- a/xcm/xcm-executor/src/mock.rs +++ b/xcm/xcm-executor/src/mock.rs @@ -216,7 +216,7 @@ impl OnResponse for TestResponseHandler { _ => false, }) } - fn on_response(origin: MultiLocation, query_id: u64, response: xcm::v0::Response) -> Weight { + fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::v0::Response) -> Weight { QUERIES.with(|q| { q.borrow_mut() .entry(query_id) diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-executor/src/tests.rs index e9aaf068d0d3..44b74e507862 100644 --- a/xcm/xcm-executor/src/tests.rs +++ b/xcm/xcm-executor/src/tests.rs @@ -175,16 +175,16 @@ fn paying_reserve_deposit_should_work() { WeightPrice::set((X1(Parent), 1_000_000_000_000)); let origin = X1(Parent); - let message = Xcm::ReserveAssetDeposit { + let message = XcmGeneric::::ReserveAssetDeposit { assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], effects: vec![ - Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, - Order::DepositAsset { assets: vec![ All ], dest: Null }, + OrderGeneric::::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, + OrderGeneric::::DepositAsset { assets: vec![ All ], dest: Null }, ], }; let weight_limit = 50; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); - assert_eq!(r, Ok(30)); + assert_eq!(r, Outcome::Complete(30)); assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]); } @@ -197,13 +197,13 @@ fn transfer_should_work() { // They want to transfer 100 of them to their sibling parachain #2 let r = XcmExecutor::::execute_xcm( X1(Parachain{id:1}), - Xcm::TransferAsset { + XcmGeneric::TransferAsset { assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], dest: X1(AccountIndex64{index:3, network:Any}), }, 50, ); - assert_eq!(r, Ok(10)); + assert_eq!(r, Outcome::Complete(10)); assert_eq!(assets(3), vec![ ConcreteFungible { id: Null, amount: 100 } ]); assert_eq!(assets(1001), vec![ ConcreteFungible { id: Null, amount: 900 } ]); assert_eq!(sent_xcm(), vec![]); @@ -221,19 +221,19 @@ fn reserve_transfer_should_work() { // and let them know to hand it to account #3. let r = XcmExecutor::::execute_xcm( X1(Parachain{id:1}), - Xcm::TransferReserveAsset { + XcmGeneric::TransferReserveAsset { assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], dest: X1(Parachain{id:2}), effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three.clone() } ], }, 50, ); - assert_eq!(r, Ok(10)); + assert_eq!(r, Outcome::Complete(10)); assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]); assert_eq!(sent_xcm(), vec![( X1(Parachain { id: 2 }), - Xcm::ReserveAssetDeposit { + XcmGeneric::ReserveAssetDeposit { assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ], }) @@ -245,14 +245,14 @@ fn transacting_should_work() { AllowUnpaidFrom::set(vec![ X1(Parent) ]); let origin = X1(Parent); - let message = Xcm::Transact { + let message = XcmGeneric::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 50, call: TestCall::Any(50, None).encode().into(), }; let weight_limit = 60; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); - assert_eq!(r, Ok(60)); + assert_eq!(r, Outcome::Complete(60)); } #[test] @@ -260,14 +260,14 @@ fn transacting_should_respect_max_weight_requirement() { AllowUnpaidFrom::set(vec![ X1(Parent) ]); let origin = X1(Parent); - let message = Xcm::Transact { + let message = XcmGeneric::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 40, call: TestCall::Any(50, None).encode().into(), }; let weight_limit = 60; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); - assert_eq!(r, Err(XcmError::TooMuchWeightRequired)); + assert_eq!(r, Outcome::Incomplete(60, XcmError::TooMuchWeightRequired)); } #[test] @@ -275,14 +275,14 @@ fn transacting_should_refund_weight() { AllowUnpaidFrom::set(vec![ X1(Parent) ]); let origin = X1(Parent); - let message = Xcm::Transact { + let message = XcmGeneric::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 50, call: TestCall::Any(50, Some(30)).encode().into(), }; let weight_limit = 60; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); - assert_eq!(r, Ok(40)); + assert_eq!(r, Outcome::Complete(40)); } #[test] @@ -293,23 +293,23 @@ fn paid_transacting_should_refund_payment_for_unused_weight() { WeightPrice::set((X1(Parent), 1_000_000_000_000)); let origin = one.clone(); - let message = Xcm::WithdrawAsset { + let message = XcmGeneric::::WithdrawAsset { assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], // enough for 100 units of weight. effects: vec![ - Order::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![ - Xcm::Transact { + OrderGeneric::::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![ + XcmGeneric::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 60, // call estimated at 70 but only takes 10. call: TestCall::Any(60, Some(10)).encode().into(), } ] }, - Order::DepositAsset { assets: vec![ All ], dest: one.clone() }, + OrderGeneric::::DepositAsset { assets: vec![ All ], dest: one.clone() }, ], }; let weight_limit = 100; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); - assert_eq!(r, Ok(50)); + assert_eq!(r, Outcome::Complete(50)); assert_eq!(assets(1), vec![ ConcreteFungible { id: X1(Parent), amount: 50 } ]); } @@ -321,7 +321,7 @@ fn prepaid_result_of_query_should_get_free_execution() { expect_response(query_id, origin.clone()); let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]); - let message = Xcm::QueryResponse { + let message = XcmGeneric::::QueryResponse { query_id, response: the_response.clone(), }; @@ -329,12 +329,12 @@ fn prepaid_result_of_query_should_get_free_execution() { // First time the response gets through since we're expecting it... let r = XcmExecutor::::execute_xcm(origin.clone(), message.clone(), weight_limit); - assert_eq!(r, Ok(10)); + assert_eq!(r, Outcome::Complete(10)); assert_eq!(response(query_id).unwrap(), the_response); // Second time it doesn't, since we're not. let r = XcmExecutor::::execute_xcm(origin.clone(), message.clone(), weight_limit); - assert_eq!(r, Err(XcmError::Barrier)); + assert_eq!(r, Outcome::Incomplete(10, XcmError::Barrier)); } // TODO: General ResponseMap of (QueryId, Origin) -> EitherOr> which From 54fd8003855a7e68cbb5e8482a211c10d16b7489 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 6 Apr 2021 22:58:57 +0200 Subject: [PATCH 21/40] Fix XCM bounds using derivative crate --- Cargo.lock | 12 ++++++++++++ xcm/Cargo.toml | 1 + xcm/src/double_encoded.rs | 14 +++++++++++++- xcm/src/lib.rs | 4 +++- xcm/src/v0/mod.rs | 4 +++- xcm/src/v0/order.rs | 4 +++- xcm/xcm-executor/src/lib.rs | 6 +++++- 7 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78f883c0b2cb..45bd7702fb7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1326,6 +1326,17 @@ dependencies = [ "syn", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive_more" version = "0.99.11" @@ -11311,6 +11322,7 @@ dependencies = [ name = "xcm" version = "0.8.30" dependencies = [ + "derivative", "parity-scale-codec", ] diff --git a/xcm/Cargo.toml b/xcm/Cargo.toml index 91cbc5b21874..660c29476b7c 100644 --- a/xcm/Cargo.toml +++ b/xcm/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] parity-scale-codec = { version = "2.0.0", default-features = false, features = [ "derive" ] } +derivative = {version = "2.2.0", default-features = false, features = [ "use_core" ] } [features] default = ["std"] diff --git a/xcm/src/double_encoded.rs b/xcm/src/double_encoded.rs index 385610e75eac..fd6d10054f05 100644 --- a/xcm/src/double_encoded.rs +++ b/xcm/src/double_encoded.rs @@ -17,7 +17,7 @@ use alloc::vec::Vec; use parity_scale_codec::{Encode, Decode}; -#[derive(Eq, PartialEq, Clone, Encode, Decode, Debug)] +#[derive(Encode, Decode)] #[codec(encode_bound())] #[codec(decode_bound())] pub struct DoubleEncoded { @@ -26,6 +26,18 @@ pub struct DoubleEncoded { decoded: Option, } +impl Clone for DoubleEncoded { + fn clone(&self) -> Self { Self { encoded: self.encoded.clone(), decoded: None } } +} +impl Eq for DoubleEncoded { +} +impl PartialEq for DoubleEncoded { + fn eq(&self, other: &Self) -> bool { self.encoded.eq(&other.encoded) } +} +impl core::fmt::Debug for DoubleEncoded { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.encoded.fmt(f) } +} + impl From> for DoubleEncoded { fn from(encoded: Vec) -> Self { Self { encoded, decoded: None } diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs index abcb03be7289..b4e49ed59fe2 100644 --- a/xcm/src/lib.rs +++ b/xcm/src/lib.rs @@ -24,13 +24,15 @@ extern crate alloc; use parity_scale_codec::{Encode, Decode}; +use derivative::Derivative; pub mod v0; mod double_encoded; pub use double_encoded::DoubleEncoded; /// A single XCM message, together with its version code. -#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +#[derive(Derivative, Encode, Decode)] +#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] #[codec(encode_bound())] #[codec(decode_bound())] pub enum VersionedXcmGeneric { diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 872ae2e6661c..8bf3f0a9dd26 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -17,6 +17,7 @@ //! Version 0 of the Cross-Consensus Message format data structures. use core::{result, convert::TryFrom, fmt::Debug}; +use derivative::Derivative; use alloc::vec::Vec; use parity_scale_codec::{self, Encode, Decode}; use super::{VersionedXcmGeneric, VersionedMultiAsset, DoubleEncoded}; @@ -66,7 +67,8 @@ pub enum Response { /// /// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer /// XCM format, known as `VersionedXcm`. -#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +#[derive(Derivative, Encode, Decode)] +#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] #[codec(encode_bound())] #[codec(decode_bound())] pub enum XcmGeneric { diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs index 042a10f3c6f4..c5f3049d89b5 100644 --- a/xcm/src/v0/order.rs +++ b/xcm/src/v0/order.rs @@ -17,11 +17,13 @@ //! Version 0 of the Cross-Consensus Message format data structures. use alloc::vec::Vec; +use derivative::Derivative; use parity_scale_codec::{self, Encode, Decode}; use super::{MultiAsset, MultiLocation, XcmGeneric}; /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages. -#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +#[derive(Derivative, Encode, Decode)] +#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] #[codec(encode_bound())] #[codec(decode_bound())] pub enum OrderGeneric { diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 68c72ca43d26..4ecddfaf6aae 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -37,7 +37,11 @@ use traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; mod assets; pub use assets::{Assets, AssetId}; mod config; -pub use config::{Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse}; +pub use config::{ + Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse, AllowKnownQueryResponses, + AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, + FixedRateOfConcreteFungible, +}; pub struct XcmExecutor(PhantomData); From a959601dd9ca39c35366f5a9700b324d1b09f6f5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 11:59:46 +0200 Subject: [PATCH 22/40] Refactor names of XcmGeneric &c into Xcm --- runtime/common/src/paras_sudo_wrapper.rs | 2 +- runtime/common/src/xcm_sender.rs | 2 +- runtime/parachains/src/hrmp.rs | 6 +-- runtime/parachains/src/ump.rs | 6 +-- xcm/src/lib.rs | 19 +++++-- xcm/src/v0/mod.rs | 68 +++++++++++++----------- xcm/src/v0/order.rs | 26 ++++----- xcm/src/v0/traits.rs | 10 ++-- xcm/xcm-executor/src/config.rs | 52 +++++++++--------- xcm/xcm-executor/src/lib.rs | 38 ++++++------- xcm/xcm-executor/src/mock.rs | 2 +- xcm/xcm-executor/src/tests.rs | 28 +++++----- 12 files changed, 138 insertions(+), 121 deletions(-) diff --git a/runtime/common/src/paras_sudo_wrapper.rs b/runtime/common/src/paras_sudo_wrapper.rs index 80bf0b3e35fb..a58d95548d9c 100644 --- a/runtime/common/src/paras_sudo_wrapper.rs +++ b/runtime/common/src/paras_sudo_wrapper.rs @@ -113,7 +113,7 @@ decl_module! { /// The given parachain should exist and the payload should not exceed the preconfigured size /// `config.max_downward_message_size`. #[weight = (1_000, DispatchClass::Operational)] - pub fn sudo_queue_downward_xcm(origin, id: ParaId, xcm: xcm::VersionedXcm) -> DispatchResult { + pub fn sudo_queue_downward_xcm(origin, id: ParaId, xcm: xcm::opaque::VersionedXcm) -> DispatchResult { ensure_root(origin)?; ensure!(>::is_valid_para(id), Error::::ParaDoesntExist); let config = >::config(); diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index 0962c070c6e4..5b5d126d1647 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -18,7 +18,7 @@ use parity_scale_codec::Encode; use sp_std::marker::PhantomData; -use xcm::{VersionedXcm, v0::{SendXcm, MultiLocation, Junction, Xcm, Result, Error}}; +use xcm::opaque::{VersionedXcm, v0::{SendXcm, MultiLocation, Junction, Xcm, Result, Error}}; use runtime_parachains::{configuration, dmp}; /// Xcm sender for relay chain. It only sends downward message. diff --git a/runtime/parachains/src/hrmp.rs b/runtime/parachains/src/hrmp.rs index e7116ebecc15..dc130f99e92f 100644 --- a/runtime/parachains/src/hrmp.rs +++ b/runtime/parachains/src/hrmp.rs @@ -959,7 +959,7 @@ impl Module { ::HrmpOpenChannelRequestsList::append(channel_id); let notification_bytes = { - use xcm::{v0::Xcm, VersionedXcm}; + use xcm::opaque::{v0::Xcm, VersionedXcm}; use parity_scale_codec::Encode as _; VersionedXcm::from(Xcm::HrmpNewChannelOpenRequest { @@ -1025,7 +1025,7 @@ impl Module { let notification_bytes = { use parity_scale_codec::Encode as _; - use xcm::{v0::Xcm, VersionedXcm}; + use xcm::opaque::{v0::Xcm, VersionedXcm}; VersionedXcm::from(Xcm::HrmpChannelAccepted { recipient: u32::from(origin), @@ -1068,7 +1068,7 @@ impl Module { let config = >::config(); let notification_bytes = { use parity_scale_codec::Encode as _; - use xcm::{v0::Xcm, VersionedXcm}; + use xcm::opaque::{v0::Xcm, VersionedXcm}; VersionedXcm::from(Xcm::HrmpChannelClosing { initiator: u32::from(origin), diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index c05378768bd4..44475bce54c6 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -62,15 +62,15 @@ pub struct XcmSink(sp_std::marker::PhantomData); impl UmpSink for XcmSink { fn process_upward_message(origin: ParaId, msg: Vec) -> Weight { use parity_scale_codec::Decode; - use xcm::VersionedXcmGeneric; + use xcm::VersionedXcm; use xcm::v0::{Junction, MultiLocation, ExecuteXcm, Outcome}; use xcm_executor::XcmExecutor; // TODO: Get a proper weight limit here. Probably from Relay Chain Config let weight_limit = Weight::max_value(); - let weight = if let Ok(versioned_xcm_message) = VersionedXcmGeneric::decode(&mut &msg[..]) { + let weight = if let Ok(versioned_xcm_message) = VersionedXcm::decode(&mut &msg[..]) { match versioned_xcm_message { - VersionedXcmGeneric::V0(xcm_message) => { + VersionedXcm::V0(xcm_message) => { let xcm_junction: Junction = Junction::Parachain { id: origin.into() }; let xcm_location: MultiLocation = xcm_junction.into(); let result = XcmExecutor::::execute_xcm(xcm_location, xcm_message, weight_limit); diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs index b4e49ed59fe2..25c8ed54f912 100644 --- a/xcm/src/lib.rs +++ b/xcm/src/lib.rs @@ -27,6 +27,7 @@ use parity_scale_codec::{Encode, Decode}; use derivative::Derivative; pub mod v0; + mod double_encoded; pub use double_encoded::DoubleEncoded; @@ -35,12 +36,22 @@ pub use double_encoded::DoubleEncoded; #[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] #[codec(encode_bound())] #[codec(decode_bound())] -pub enum VersionedXcmGeneric { - V0(v0::XcmGeneric), +pub enum VersionedXcm { + V0(v0::Xcm), +} + +pub mod opaque { + pub mod v0 { + // Everything from v0 + pub use crate::v0::*; + // Then override with the opaque types in v0 + pub use crate::v0::opaque::{Xcm, Order}; + } + + /// The basic VersionedXcm type which just uses the `Vec` as an encoded call. + pub type VersionedXcm = super::VersionedXcm<()>; } -/// The basic VersionedXcm type which just uses the `Vec` as an encoded call. -pub type VersionedXcm = VersionedXcmGeneric<()>; /// A versioned multi-location, a relative location of a cross-consensus system identifier. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 8bf3f0a9dd26..4440d3769e8f 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -20,7 +20,7 @@ use core::{result, convert::TryFrom, fmt::Debug}; use derivative::Derivative; use alloc::vec::Vec; use parity_scale_codec::{self, Encode, Decode}; -use super::{VersionedXcmGeneric, VersionedMultiAsset, DoubleEncoded}; +use crate::{VersionedMultiAsset, DoubleEncoded, VersionedXcm}; mod junction; mod multi_asset; @@ -30,7 +30,7 @@ mod traits; pub use junction::{Junction, NetworkId}; pub use multi_asset::{MultiAsset, AssetInstance}; pub use multi_location::MultiLocation; -pub use order::{Order, OrderGeneric}; +pub use order::Order; pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome}; // TODO: Efficient encodings for Vec, Vec, using initial byte values 128+ to encode the number of @@ -68,10 +68,10 @@ pub enum Response { /// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer /// XCM format, known as `VersionedXcm`. #[derive(Derivative, Encode, Decode)] -#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] #[codec(encode_bound())] #[codec(decode_bound())] -pub enum XcmGeneric { +pub enum Xcm { /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into `holding`. Execute the /// orders (`effects`). /// @@ -82,7 +82,7 @@ pub enum XcmGeneric { /// /// Errors: #[codec(index = 0)] - WithdrawAsset { assets: Vec, effects: Vec> }, + WithdrawAsset { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system. /// @@ -99,7 +99,7 @@ pub enum XcmGeneric { /// /// Errors: #[codec(index = 1)] - ReserveAssetDeposit { assets: Vec, effects: Vec> }, + ReserveAssetDeposit { assets: Vec, effects: Vec> }, /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be /// created on this system. @@ -117,7 +117,7 @@ pub enum XcmGeneric { /// /// Errors: #[codec(index = 2)] - TeleportAsset { assets: Vec, effects: Vec> }, + TeleportAsset { assets: Vec, effects: Vec> }, /// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`. /// @@ -162,7 +162,7 @@ pub enum XcmGeneric { /// /// Errors: #[codec(index = 5)] - TransferReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec }, + TransferReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec> }, /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the /// relay-chain to a para. @@ -229,50 +229,54 @@ pub enum XcmGeneric { Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded }, } -/// The basic concrete type of `XcmGeneric`, which doesn't make any assumptions about the format of a -/// call other than it is pre-encoded. -pub type Xcm = XcmGeneric<()>; - -impl From> for VersionedXcmGeneric { - fn from(x: XcmGeneric) -> Self { - VersionedXcmGeneric::V0(x) +impl From> for VersionedXcm { + fn from(x: Xcm) -> Self { + VersionedXcm::V0(x) } } -impl TryFrom> for XcmGeneric { +impl TryFrom> for Xcm { type Error = (); - fn try_from(x: VersionedXcmGeneric) -> result::Result { + fn try_from(x: VersionedXcm) -> result::Result { match x { - VersionedXcmGeneric::V0(x) => Ok(x), + VersionedXcm::V0(x) => Ok(x), } } } -impl XcmGeneric { - pub fn into(self) -> XcmGeneric { XcmGeneric::from(self) } - pub fn from(xcm: XcmGeneric) -> Self { - use XcmGeneric::*; +impl Xcm { + pub fn into(self) -> Xcm { Xcm::from(self) } + pub fn from(xcm: Xcm) -> Self { + use Xcm::*; match xcm { WithdrawAsset { assets, effects } - => WithdrawAsset { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, + => WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, ReserveAssetDeposit { assets, effects } - => ReserveAssetDeposit { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, + => ReserveAssetDeposit { assets, effects: effects.into_iter().map(Order::into).collect() }, TeleportAsset { assets, effects } - => TeleportAsset { assets, effects: effects.into_iter().map(OrderGeneric::into).collect() }, + => TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, QueryResponse { query_id: u64, response } - => QueryResponse { query_id: u64, response }, + => QueryResponse { query_id: u64, response }, TransferAsset { assets, dest } - => TransferAsset { assets, dest }, + => TransferAsset { assets, dest }, TransferReserveAsset { assets, dest, effects } - => TransferReserveAsset { assets, dest, effects }, + => TransferReserveAsset { assets, dest, effects }, HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity} - => HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}, + => HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}, HrmpChannelAccepted { recipient} - => HrmpChannelAccepted { recipient}, + => HrmpChannelAccepted { recipient}, HrmpChannelClosing { initiator, sender, recipient} - => HrmpChannelClosing { initiator, sender, recipient}, + => HrmpChannelClosing { initiator, sender, recipient}, Transact { origin_type, require_weight_at_most, call} - => Transact { origin_type, require_weight_at_most, call: call.into() } + => Transact { origin_type, require_weight_at_most, call: call.into() } } } } + +pub mod opaque { + /// The basic concrete type of `generic::Xcm`, which doesn't make any assumptions about the format of a + /// call other than it is pre-encoded. + pub type Xcm = super::Xcm<()>; + + pub use super::order::opaque::*; +} diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs index c5f3049d89b5..a1c8339ecb25 100644 --- a/xcm/src/v0/order.rs +++ b/xcm/src/v0/order.rs @@ -19,14 +19,14 @@ use alloc::vec::Vec; use derivative::Derivative; use parity_scale_codec::{self, Encode, Decode}; -use super::{MultiAsset, MultiLocation, XcmGeneric}; +use super::{MultiAsset, MultiLocation, Xcm}; /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages. #[derive(Derivative, Encode, Decode)] #[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] #[codec(encode_bound())] #[codec(decode_bound())] -pub enum OrderGeneric { +pub enum Order { /// Do nothing. Not generally used. #[codec(index = 0)] Null, @@ -53,7 +53,7 @@ pub enum OrderGeneric { /// /// Errors: #[codec(index = 2)] - DepositReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec }, + DepositReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec> }, /// Remove the asset(s) (`give`) from holding and replace them with alternative assets. /// @@ -77,7 +77,7 @@ pub enum OrderGeneric { /// /// Errors: #[codec(index = 4)] - InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec }, + InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec> }, /// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location. /// @@ -87,7 +87,7 @@ pub enum OrderGeneric { /// /// Errors: #[codec(index = 5)] - InitiateTeleport { assets: Vec, dest: MultiLocation, effects: Vec }, + InitiateTeleport { assets: Vec, dest: MultiLocation, effects: Vec> }, /// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof. /// @@ -106,15 +106,17 @@ pub enum OrderGeneric { /// /// Errors: #[codec(index = 7)] - BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec> }, + BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec> }, } -pub type Order = OrderGeneric<()>; +pub mod opaque { + pub type Order = super::Order<()>; +} -impl OrderGeneric { - pub fn into(self) -> OrderGeneric { OrderGeneric::from(self) } - pub fn from(order: OrderGeneric) -> Self { - use OrderGeneric::*; +impl Order { + pub fn into(self) -> Order { Order::from(self) } + pub fn from(order: Order) -> Self { + use Order::*; match order { Null => Null, DepositAsset { assets, dest } @@ -130,7 +132,7 @@ impl OrderGeneric { QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest, assets }, BuyExecution { fees, weight, debt, halt_on_error, xcm } => { - let xcm = xcm.into_iter().map(XcmGeneric::from).collect(); + let xcm = xcm.into_iter().map(Xcm::from).collect(); BuyExecution { fees, weight, debt, halt_on_error, xcm } }, } diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs index a4ad17ab2ab4..0a8041d87036 100644 --- a/xcm/src/v0/traits.rs +++ b/xcm/src/v0/traits.rs @@ -19,7 +19,7 @@ use core::result; use parity_scale_codec::{Encode, Decode}; -use super::{MultiLocation, Xcm, XcmGeneric}; +use super::{MultiLocation, Xcm}; #[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, Debug)] pub enum Error { @@ -120,21 +120,21 @@ impl Outcome { } pub trait ExecuteXcm { - fn execute_xcm(origin: MultiLocation, message: XcmGeneric, weight_limit: Weight) -> Outcome; + fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Outcome; } impl ExecuteXcm for () { - fn execute_xcm(_origin: MultiLocation, _message: XcmGeneric, _weight_limit: Weight) -> Outcome { + fn execute_xcm(_origin: MultiLocation, _message: Xcm, _weight_limit: Weight) -> Outcome { Outcome::Error(Error::Unimplemented) } } pub trait SendXcm { - fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result; + fn send_xcm(dest: MultiLocation, msg: Xcm<()>) -> Result; } impl SendXcm for () { - fn send_xcm(_dest: MultiLocation, _msg: Xcm) -> Result { + fn send_xcm(_dest: MultiLocation, _msg: Xcm<()>) -> Result { Err(Error::Unimplemented) } } diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index b59bb391fe9b..5ce870da7348 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -16,7 +16,7 @@ use sp_std::marker::PhantomData; use parity_scale_codec::Decode; -use xcm::v0::{SendXcm, MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, Response}; +use xcm::v0::{SendXcm, MultiLocation, MultiAsset, Xcm, Order, Response}; use frame_support::{ ensure, dispatch::{Dispatchable, Parameter, Weight}, weights::{PostDispatchInfo, GetDispatchInfo} }; @@ -32,7 +32,7 @@ pub trait WeightBounds { /// This is useful to gauge how many fees should be paid up front to begin execution of the message. /// It is not useful for determining whether execution should begin lest it result in surpassing weight /// limits - in that case `deep` is the function to use. - fn shallow(message: &mut XcmGeneric) -> Result; + fn shallow(message: &mut Xcm) -> Result; /// Return the deep amount of weight, over `shallow` that complete, successful and worst-case execution of /// `message` would incur. @@ -47,22 +47,22 @@ pub trait WeightBounds { /// This is guaranteed equal to the eventual sum of all `shallow` XCM messages that get executed through /// any internal effects. Inner XCM messages may be executed by: /// - Order::BuyExecution - fn deep(message: &mut XcmGeneric) -> Result; + fn deep(message: &mut Xcm) -> Result; } pub struct FixedWeightBounds(PhantomData<(T, C)>); impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeightBounds { - fn shallow(message: &mut XcmGeneric) -> Result { + fn shallow(message: &mut Xcm) -> Result { let min = match message { - XcmGeneric::Transact { call, .. } => { + Xcm::Transact { call, .. } => { call.ensure_decoded()?.get_dispatch_info().weight + T::get() } - XcmGeneric::WithdrawAsset { effects, .. } - | XcmGeneric::ReserveAssetDeposit { effects, .. } - | XcmGeneric::TeleportAsset { effects, .. } => { + Xcm::WithdrawAsset { effects, .. } + | Xcm::ReserveAssetDeposit { effects, .. } + | Xcm::TeleportAsset { effects, .. } => { let inner: Weight = effects.iter_mut() .map(|effect| match effect { - OrderGeneric::BuyExecution { .. } => { + Order::BuyExecution { .. } => { // On success, execution of this will result in more weight being consumed but // we don't count it here since this is only the *shallow*, non-negotiable weight // spend and doesn't count weight placed behind a `BuyExecution` since it will not @@ -78,16 +78,16 @@ impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeigh }; Ok(min) } - fn deep(message: &mut XcmGeneric) -> Result { + fn deep(message: &mut Xcm) -> Result { let mut extra = 0; match message { - XcmGeneric::Transact { .. } => {} - XcmGeneric::WithdrawAsset { effects, .. } - | XcmGeneric::ReserveAssetDeposit { effects, .. } - | XcmGeneric::TeleportAsset { effects, .. } => { + Xcm::Transact { .. } => {} + Xcm::WithdrawAsset { effects, .. } + | Xcm::ReserveAssetDeposit { effects, .. } + | Xcm::TeleportAsset { effects, .. } => { for effect in effects.iter_mut() { match effect { - OrderGeneric::BuyExecution { xcm, .. } => { + Order::BuyExecution { xcm, .. } => { for message in xcm.iter_mut() { extra += Self::shallow(message)? + Self::deep(message)?; } @@ -160,7 +160,7 @@ pub trait ShouldExecute { fn should_execute( origin: &MultiLocation, top_level: bool, - message: &XcmGeneric, + message: &Xcm, shallow_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()>; @@ -171,7 +171,7 @@ impl ShouldExecute for Tuple { fn should_execute( origin: &MultiLocation, top_level: bool, - message: &XcmGeneric, + message: &Xcm, shallow_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { @@ -190,7 +190,7 @@ impl ShouldExecute for TakeWeightCredit { fn should_execute( _origin: &MultiLocation, _top_level: bool, - _message: &XcmGeneric, + _message: &Xcm, shallow_weight: Weight, weight_credit: &mut Weight, ) -> Result<(), ()> { @@ -204,19 +204,19 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro fn should_execute( origin: &MultiLocation, top_level: bool, - message: &XcmGeneric, + message: &Xcm, shallow_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { ensure!(T::contains(origin), ()); ensure!(top_level, ()); match message { - XcmGeneric::TeleportAsset { effects, .. } - | XcmGeneric::WithdrawAsset { effects, ..} - | XcmGeneric::ReserveAssetDeposit { effects, ..} + Xcm::TeleportAsset { effects, .. } + | Xcm::WithdrawAsset { effects, ..} + | Xcm::ReserveAssetDeposit { effects, ..} if matches!( effects.first(), - Some(OrderGeneric::BuyExecution { debt, ..}) if *debt >= shallow_weight + Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight ) => Ok(()), _ => Err(()), @@ -229,7 +229,7 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { fn should_execute( origin: &MultiLocation, _top_level: bool, - _message: &XcmGeneric, + _message: &Xcm, _shallow_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { @@ -252,12 +252,12 @@ impl ShouldExecute for AllowKnownQueryResponses( origin: &MultiLocation, _top_level: bool, - message: &XcmGeneric, + message: &Xcm, _shallow_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { match message { - XcmGeneric::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id) + Xcm::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id) => Ok(()), _ => Err(()), } diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 4ecddfaf6aae..d75074e4c8a3 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -22,8 +22,8 @@ use frame_support::{ dispatch::{Weight, Dispatchable} }; use xcm::v0::{ - Xcm, ExecuteXcm, SendXcm, Error as XcmError, Outcome, - MultiLocation, MultiAsset, XcmGeneric, OrderGeneric, Response, + ExecuteXcm, SendXcm, Error as XcmError, Outcome, + MultiLocation, MultiAsset, Xcm, Order, Response, }; #[cfg(test)] @@ -46,9 +46,9 @@ pub use config::{ pub struct XcmExecutor(PhantomData); impl ExecuteXcm for XcmExecutor { - fn execute_xcm(origin: MultiLocation, message: XcmGeneric, weight_limit: Weight) -> Outcome { + fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Outcome { // TODO: We should identify recursive bombs here and bail. - let mut message = XcmGeneric::::from(message); + let mut message = Xcm::::from(message); let shallow_weight = match Config::Weigher::shallow(&mut message) { Ok(x) => x, Err(()) => return Outcome::Error(XcmError::WeightNotComputable), @@ -85,7 +85,7 @@ impl XcmExecutor { fn do_execute_xcm( origin: MultiLocation, top_level: bool, - mut message: XcmGeneric, + mut message: Xcm, weight_credit: &mut Weight, maybe_shallow_weight: Option, trader: &mut Config::Trader, @@ -105,7 +105,7 @@ impl XcmExecutor { let mut total_surplus = 0; let maybe_holding_effects = match (origin.clone(), message) { - (origin, XcmGeneric::WithdrawAsset { assets, effects }) => { + (origin, Xcm::WithdrawAsset { assets, effects }) => { // Take `assets` from the origin account (on-chain) and place in holding. let mut holding = Assets::default(); for asset in assets { @@ -115,7 +115,7 @@ impl XcmExecutor { } Some((holding, effects)) } - (origin, XcmGeneric::ReserveAssetDeposit { assets, effects }) => { + (origin, Xcm::ReserveAssetDeposit { assets, effects }) => { // check whether we trust origin to be our reserve location for this asset. for asset in assets.iter() { ensure!(!asset.is_wildcard(), XcmError::Wildcard); @@ -125,7 +125,7 @@ impl XcmExecutor { } Some((Assets::from(assets), effects)) } - (origin, XcmGeneric::TransferAsset { assets, dest }) => { + (origin, Xcm::TransferAsset { assets, dest }) => { // Take `assets` from the origin account (on-chain) and place into dest account. for asset in assets { ensure!(!asset.is_wildcard(), XcmError::Wildcard); @@ -133,7 +133,7 @@ impl XcmExecutor { } None } - (origin, XcmGeneric::TransferReserveAsset { mut assets, dest, effects }) => { + (origin, Xcm::TransferReserveAsset { mut assets, dest, effects }) => { // Take `assets` from the origin account (on-chain) and place into dest account. let inv_dest = Config::LocationInverter::invert_location(&dest); for asset in assets.iter_mut() { @@ -144,7 +144,7 @@ impl XcmExecutor { Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; None } - (origin, XcmGeneric::TeleportAsset { assets, effects }) => { + (origin, Xcm::TeleportAsset { assets, effects }) => { // check whether we trust origin to teleport this asset to us via config trait. for asset in assets.iter() { ensure!(!asset.is_wildcard(), XcmError::Wildcard); @@ -154,7 +154,7 @@ impl XcmExecutor { } Some((Assets::from(assets), effects)) } - (origin, XcmGeneric::Transact { origin_type, require_weight_at_most, mut call }) => { + (origin, Xcm::Transact { origin_type, require_weight_at_most, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. // TODO: allow this to be configurable in the trait. @@ -185,7 +185,7 @@ impl XcmExecutor { // execution has taken. None } - (origin, XcmGeneric::QueryResponse { query_id, response }) => { + (origin, Xcm::QueryResponse { query_id, response }) => { Config::ResponseHandler::on_response(origin, query_id, response); None } @@ -204,18 +204,18 @@ impl XcmExecutor { fn execute_effects( origin: &MultiLocation, holding: &mut Assets, - effect: OrderGeneric, + effect: Order, trader: &mut Config::Trader, ) -> Result { let mut total_surplus = 0; match effect { - OrderGeneric::DepositAsset { assets, dest } => { + Order::DepositAsset { assets, dest } => { let deposited = holding.saturating_take(assets); for asset in deposited.into_assets_iter() { Config::AssetTransactor::deposit_asset(&asset, &dest)?; } }, - OrderGeneric::DepositReserveAsset { assets, dest, effects } => { + Order::DepositReserveAsset { assets, dest, effects } => { let deposited = holding.saturating_take(assets); for asset in deposited.assets_iter() { Config::AssetTransactor::deposit_asset(&asset, &dest)?; @@ -223,19 +223,19 @@ impl XcmExecutor { let assets = Self::reanchored(deposited, &dest); Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; }, - OrderGeneric::InitiateReserveWithdraw { assets, reserve, effects} => { + Order::InitiateReserveWithdraw { assets, reserve, effects} => { let assets = Self::reanchored(holding.saturating_take(assets), &reserve); Config::XcmSender::send_xcm(reserve, Xcm::WithdrawAsset { assets, effects })?; } - OrderGeneric::InitiateTeleport { assets, dest, effects} => { + Order::InitiateTeleport { assets, dest, effects} => { let assets = Self::reanchored(holding.saturating_take(assets), &dest); Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects })?; } - OrderGeneric::QueryHolding { query_id, dest, assets } => { + Order::QueryHolding { query_id, dest, assets } => { let assets = Self::reanchored(holding.min(assets.iter()), &dest); Config::XcmSender::send_xcm(dest, Xcm::QueryResponse { query_id, response: Response::Assets(assets) })?; } - OrderGeneric::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { + Order::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { // pay for `weight` using up to `fees` of the holding account. let purchasing_weight = Weight::from(weight + debt); let max_fee = holding.try_take(fees).map_err(|()| XcmError::NotHoldingFees)?; diff --git a/xcm/xcm-executor/src/mock.rs b/xcm/xcm-executor/src/mock.rs index 5cc49ae27d8e..1eb2a83cc626 100644 --- a/xcm/xcm-executor/src/mock.rs +++ b/xcm/xcm-executor/src/mock.rs @@ -19,7 +19,7 @@ pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell}; pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; pub use parity_scale_codec::{Encode, Decode}; pub use xcm::v0::{ - SendXcm, MultiLocation::*, Junction::*, MultiAsset, XcmGeneric, OrderGeneric, Result as XcmResult, Error, + SendXcm, MultiLocation::*, Junction::*, MultiAsset, Xcm, Order, Result as XcmResult, Error, OriginKind, MultiLocation, Junction, }; pub use frame_support::{ diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-executor/src/tests.rs index 44b74e507862..03461797cd91 100644 --- a/xcm/xcm-executor/src/tests.rs +++ b/xcm/xcm-executor/src/tests.rs @@ -175,11 +175,11 @@ fn paying_reserve_deposit_should_work() { WeightPrice::set((X1(Parent), 1_000_000_000_000)); let origin = X1(Parent); - let message = XcmGeneric::::ReserveAssetDeposit { + let message = Xcm::::ReserveAssetDeposit { assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], effects: vec![ - OrderGeneric::::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, - OrderGeneric::::DepositAsset { assets: vec![ All ], dest: Null }, + Order::::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, + Order::::DepositAsset { assets: vec![ All ], dest: Null }, ], }; let weight_limit = 50; @@ -197,7 +197,7 @@ fn transfer_should_work() { // They want to transfer 100 of them to their sibling parachain #2 let r = XcmExecutor::::execute_xcm( X1(Parachain{id:1}), - XcmGeneric::TransferAsset { + Xcm::TransferAsset { assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], dest: X1(AccountIndex64{index:3, network:Any}), }, @@ -221,7 +221,7 @@ fn reserve_transfer_should_work() { // and let them know to hand it to account #3. let r = XcmExecutor::::execute_xcm( X1(Parachain{id:1}), - XcmGeneric::TransferReserveAsset { + Xcm::TransferReserveAsset { assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], dest: X1(Parachain{id:2}), effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three.clone() } ], @@ -233,7 +233,7 @@ fn reserve_transfer_should_work() { assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]); assert_eq!(sent_xcm(), vec![( X1(Parachain { id: 2 }), - XcmGeneric::ReserveAssetDeposit { + Xcm::ReserveAssetDeposit { assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ], }) @@ -245,7 +245,7 @@ fn transacting_should_work() { AllowUnpaidFrom::set(vec![ X1(Parent) ]); let origin = X1(Parent); - let message = XcmGeneric::::Transact { + let message = Xcm::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 50, call: TestCall::Any(50, None).encode().into(), @@ -260,7 +260,7 @@ fn transacting_should_respect_max_weight_requirement() { AllowUnpaidFrom::set(vec![ X1(Parent) ]); let origin = X1(Parent); - let message = XcmGeneric::::Transact { + let message = Xcm::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 40, call: TestCall::Any(50, None).encode().into(), @@ -275,7 +275,7 @@ fn transacting_should_refund_weight() { AllowUnpaidFrom::set(vec![ X1(Parent) ]); let origin = X1(Parent); - let message = XcmGeneric::::Transact { + let message = Xcm::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 50, call: TestCall::Any(50, Some(30)).encode().into(), @@ -293,18 +293,18 @@ fn paid_transacting_should_refund_payment_for_unused_weight() { WeightPrice::set((X1(Parent), 1_000_000_000_000)); let origin = one.clone(); - let message = XcmGeneric::::WithdrawAsset { + let message = Xcm::::WithdrawAsset { assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], // enough for 100 units of weight. effects: vec![ - OrderGeneric::::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![ - XcmGeneric::::Transact { + Order::::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![ + Xcm::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 60, // call estimated at 70 but only takes 10. call: TestCall::Any(60, Some(10)).encode().into(), } ] }, - OrderGeneric::::DepositAsset { assets: vec![ All ], dest: one.clone() }, + Order::::DepositAsset { assets: vec![ All ], dest: one.clone() }, ], }; let weight_limit = 100; @@ -321,7 +321,7 @@ fn prepaid_result_of_query_should_get_free_execution() { expect_response(query_id, origin.clone()); let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]); - let message = XcmGeneric::::QueryResponse { + let message = Xcm::::QueryResponse { query_id, response: the_response.clone(), }; From b7c4a30d4973b340b928a9d3c8889f65d132b379 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 13:42:53 +0200 Subject: [PATCH 23/40] Repot the xcm-executor into xcm-builder --- xcm/xcm-builder/src/barriers.rs | 90 +++++++ xcm/xcm-builder/src/filter_asset_location.rs | 36 +++ xcm/xcm-builder/src/lib.rs | 29 +- xcm/xcm-builder/src/location_conversion.rs | 22 +- xcm/xcm-builder/src/matches_fungible.rs | 42 +++ xcm/{xcm-executor => xcm-builder}/src/mock.rs | 21 +- .../src/tests.rs | 16 +- xcm/xcm-builder/src/weight.rs | 98 +++++++ xcm/xcm-executor/src/config.rs | 254 +----------------- xcm/xcm-executor/src/lib.rs | 16 +- xcm/xcm-executor/src/traits.rs | 195 -------------- xcm/xcm-executor/src/traits/conversion.rs | 65 +++++ .../src/traits/filter_asset_location.rs | 32 +++ .../src/traits/matches_fungible.rs | 28 ++ xcm/xcm-executor/src/traits/mod.rs | 32 +++ xcm/xcm-executor/src/traits/on_response.rs | 27 ++ xcm/xcm-executor/src/traits/should_execute.rs | 60 +++++ xcm/xcm-executor/src/traits/transact_asset.rs | 64 +++++ xcm/xcm-executor/src/traits/weight.rs | 63 +++++ 19 files changed, 710 insertions(+), 480 deletions(-) create mode 100644 xcm/xcm-builder/src/barriers.rs create mode 100644 xcm/xcm-builder/src/filter_asset_location.rs create mode 100644 xcm/xcm-builder/src/matches_fungible.rs rename xcm/{xcm-executor => xcm-builder}/src/mock.rs (94%) rename xcm/{xcm-executor => xcm-builder}/src/tests.rs (96%) create mode 100644 xcm/xcm-builder/src/weight.rs delete mode 100644 xcm/xcm-executor/src/traits.rs create mode 100644 xcm/xcm-executor/src/traits/conversion.rs create mode 100644 xcm/xcm-executor/src/traits/filter_asset_location.rs create mode 100644 xcm/xcm-executor/src/traits/matches_fungible.rs create mode 100644 xcm/xcm-executor/src/traits/mod.rs create mode 100644 xcm/xcm-executor/src/traits/on_response.rs create mode 100644 xcm/xcm-executor/src/traits/should_execute.rs create mode 100644 xcm/xcm-executor/src/traits/transact_asset.rs create mode 100644 xcm/xcm-executor/src/traits/weight.rs diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs new file mode 100644 index 000000000000..770104ec6092 --- /dev/null +++ b/xcm/xcm-builder/src/barriers.rs @@ -0,0 +1,90 @@ +// Copyright 2020 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 . + +use sp_std::{result::Result, marker::PhantomData}; +use xcm::v0::{Xcm, Order, MultiLocation}; +use frame_support::{ensure, traits::Contains, weights::Weight}; +use xcm_executor::traits::{OnResponse, ShouldExecute}; + +pub struct TakeWeightCredit; +impl ShouldExecute for TakeWeightCredit { + fn should_execute( + _origin: &MultiLocation, + _top_level: bool, + _message: &Xcm, + shallow_weight: Weight, + weight_credit: &mut Weight, + ) -> Result<(), ()> { + *weight_credit = weight_credit.checked_sub(shallow_weight).ok_or(())?; + Ok(()) + } +} + +pub struct AllowTopLevelPaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + top_level: bool, + message: &Xcm, + shallow_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + ensure!(T::contains(origin), ()); + ensure!(top_level, ()); + match message { + Xcm::TeleportAsset { effects, .. } + | Xcm::WithdrawAsset { effects, ..} + | Xcm::ReserveAssetDeposit { effects, ..} + if matches!( + effects.first(), + Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight + ) + => Ok(()), + _ => Err(()), + } + } +} + +pub struct AllowUnpaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowUnpaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + _top_level: bool, + _message: &Xcm, + _shallow_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + ensure!(T::contains(origin), ()); + Ok(()) + } +} + +pub struct AllowKnownQueryResponses(PhantomData); +impl ShouldExecute for AllowKnownQueryResponses { + fn should_execute( + origin: &MultiLocation, + _top_level: bool, + message: &Xcm, + _shallow_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + match message { + Xcm::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id) + => Ok(()), + _ => Err(()), + } + } +} diff --git a/xcm/xcm-builder/src/filter_asset_location.rs b/xcm/xcm-builder/src/filter_asset_location.rs new file mode 100644 index 000000000000..ffd334ff7562 --- /dev/null +++ b/xcm/xcm-builder/src/filter_asset_location.rs @@ -0,0 +1,36 @@ +// Copyright 2020 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 . + +use sp_std::marker::PhantomData; +use xcm::v0::{MultiAsset, MultiLocation}; +use frame_support::traits::Get; +use xcm_executor::traits::FilterAssetLocation; + +pub struct NativeAsset; +impl FilterAssetLocation for NativeAsset { + fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { + matches!(asset, MultiAsset::ConcreteFungible { ref id, .. } if id == origin) + } +} + + +pub struct Case(PhantomData); +impl> FilterAssetLocation for Case { + fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { + let (a, o) = T::get(); + &a == asset && &o == origin + } +} diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs index 79f1bb49b757..5cfc7249fa9b 100644 --- a/xcm/xcm-builder/src/lib.rs +++ b/xcm/xcm-builder/src/lib.rs @@ -16,21 +16,40 @@ #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + mod location_conversion; pub use location_conversion::{ - Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases, AccountKey20Aliases, + Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases, + AccountKey20Aliases, LocationInverter, }; mod origin_conversion; pub use origin_conversion::{ SovereignSignedViaLocation, ParentAsSuperuser, ChildSystemParachainAsSuperuser, SiblingSystemParachainAsSuperuser, - ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative, SignedAccountKey20AsNative, + ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative, + SignedAccountKey20AsNative, +}; + +mod barriers; +pub use barriers::{ + TakeWeightCredit, AllowUnpaidExecutionFrom, AllowTopLevelPaidExecutionFrom, AllowKnownQueryResponses, }; mod currency_adapter; -mod fungibles_adapter; pub use currency_adapter::CurrencyAdapter; + +mod fungibles_adapter; pub use fungibles_adapter::FungiblesAdapter; -#[deprecated="use `xcm-executor::traits::LocationInverter` instead"] -pub use xcm_executor::traits::LocationInverter; +mod weight; +pub use weight::{FixedRateOfConcreteFungible, FixedWeightBounds}; + +mod matches_fungible; +pub use matches_fungible::{IsAbstract, IsConcrete}; + +mod filter_asset_location; +pub use filter_asset_location::{Case, NativeAsset}; diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs index be563448e346..5f4af1fcf31c 100644 --- a/xcm/xcm-builder/src/location_conversion.rs +++ b/xcm/xcm-builder/src/location_conversion.rs @@ -20,7 +20,7 @@ use sp_runtime::traits::AccountIdConversion; use frame_support::traits::Get; use parity_scale_codec::Encode; use xcm::v0::{MultiLocation, NetworkId, Junction}; -use xcm_executor::traits::LocationConversion; +use xcm_executor::traits::{InvertLocation, LocationConversion}; pub struct Account32Hash(PhantomData<(Network, AccountId)>); @@ -126,7 +126,6 @@ impl< } pub struct AccountKey20Aliases(PhantomData<(Network, AccountId)>); - impl< Network: Get, AccountId: From<[u8; 20]> + Into<[u8; 20]> @@ -148,3 +147,22 @@ impl< .into()) } } + +/// Simple location inverter; give it this location's ancestry and it'll figure out the inverted location. +pub struct LocationInverter(PhantomData); +impl> InvertLocation for LocationInverter { + fn invert_location(location: &MultiLocation) -> MultiLocation { + let mut ancestry = Ancestry::get(); + let mut result = location.clone(); + for (i, j) in location.iter_rev() + .map(|j| match j { + Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild), + _ => Junction::Parent, + }) + .enumerate() + { + *result.at_mut(i).expect("location and result begin equal; same size; qed") = j; + } + result + } +} diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs new file mode 100644 index 000000000000..3053bbcdb9e5 --- /dev/null +++ b/xcm/xcm-builder/src/matches_fungible.rs @@ -0,0 +1,42 @@ +// Copyright 2020 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 . + +use sp_std::{marker::PhantomData, convert::TryFrom}; +use sp_runtime::traits::CheckedConversion; +use xcm::v0::{MultiAsset, MultiLocation}; +use frame_support::traits::Get; +use xcm_executor::traits::MatchesFungible; + +pub struct IsConcrete(PhantomData); +impl, B: TryFrom> MatchesFungible for IsConcrete { + fn matches_fungible(a: &MultiAsset) -> Option { + match a { + MultiAsset::ConcreteFungible { id, amount } if id == &T::get() => + CheckedConversion::checked_from(*amount), + _ => None, + } + } +} +pub struct IsAbstract(PhantomData); +impl, B: TryFrom> MatchesFungible for IsAbstract { + fn matches_fungible(a: &MultiAsset) -> Option { + match a { + MultiAsset::AbstractFungible { id, amount } if &id[..] == T::get() => + CheckedConversion::checked_from(*amount), + _ => None, + } + } +} diff --git a/xcm/xcm-executor/src/mock.rs b/xcm/xcm-builder/src/mock.rs similarity index 94% rename from xcm/xcm-executor/src/mock.rs rename to xcm/xcm-builder/src/mock.rs index 1eb2a83cc626..47e9e156dc9f 100644 --- a/xcm/xcm-executor/src/mock.rs +++ b/xcm/xcm-builder/src/mock.rs @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use super::*; pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell}; pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; pub use parity_scale_codec::{Encode, Decode}; pub use xcm::v0::{ - SendXcm, MultiLocation::*, Junction::*, MultiAsset, Xcm, Order, Result as XcmResult, Error, - OriginKind, MultiLocation, Junction, + SendXcm, MultiLocation::*, Junction::*, MultiAsset, Xcm, Order, Result as XcmResult, Error as XcmError, + OriginKind, MultiLocation, Junction, opaque, }; pub use frame_support::{ ensure, parameter_types, @@ -29,10 +28,12 @@ pub use frame_support::{ sp_runtime::DispatchErrorWithPostInfo, traits::{Get, Contains}, }; -pub use crate::traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, LocationInverter}; -pub use crate::config::{ +pub use xcm_executor::{ + Assets, Config, traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse} +}; +pub use crate::{ TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds, - FixedRateOfConcreteFungible, AllowKnownQueryResponses + FixedRateOfConcreteFungible, AllowKnownQueryResponses, LocationInverter, }; pub enum TestOrigin { Root, Relay, Signed(u64), Parachain(u32) } @@ -93,14 +94,14 @@ impl GetDispatchInfo for TestCall { } thread_local! { - pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); } -pub fn sent_xcm() -> Vec<(MultiLocation, Xcm)> { +pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } pub struct TestSendXcm; impl SendXcm for TestSendXcm { - fn send_xcm(dest: MultiLocation, msg: Xcm) -> XcmResult { + fn send_xcm(dest: MultiLocation, msg: opaque::Xcm) -> XcmResult { SENT_XCM.with(|q| q.borrow_mut().push((dest, msg))); Ok(()) } @@ -123,14 +124,12 @@ pub fn add_asset(who: u64, what: MultiAsset) { pub struct TestAssetTransactor; impl TransactAsset for TestAssetTransactor { fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result<(), XcmError> { - dbg!(what, who); let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?; add_asset(who, what.clone()); Ok(()) } fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { - dbg!(what, who); let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?; ASSETS.with(|a| a.borrow_mut() .get_mut(&who) diff --git a/xcm/xcm-executor/src/tests.rs b/xcm/xcm-builder/src/tests.rs similarity index 96% rename from xcm/xcm-executor/src/tests.rs rename to xcm/xcm-builder/src/tests.rs index 03461797cd91..fb2a5afb884c 100644 --- a/xcm/xcm-executor/src/tests.rs +++ b/xcm/xcm-builder/src/tests.rs @@ -17,8 +17,8 @@ use super::*; use super::mock::*; use {MultiAsset::*, Option::None}; -use xcm::v0::Order; -use xcm::v0::NetworkId::Any; +use xcm::v0::{Order, NetworkId::Any, Outcome, Response, ExecuteXcm}; +use xcm_executor::{XcmExecutor, Config, traits::*}; #[test] fn basic_setup_works() { @@ -39,7 +39,7 @@ fn basic_setup_works() { #[test] fn weigher_should_work() { - let mut message = Xcm::ReserveAssetDeposit { + let mut message = opaque::Xcm::ReserveAssetDeposit { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], effects: vec![ Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, @@ -51,7 +51,7 @@ fn weigher_should_work() { #[test] fn take_weight_credit_barrier_should_work() { - let mut message = Xcm::TransferAsset { + let mut message = opaque::Xcm::TransferAsset { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], dest: Null, }; @@ -80,7 +80,7 @@ fn take_weight_credit_barrier_should_work() { #[test] fn allow_unpaid_should_work() { - let mut message = Xcm::TransferAsset { + let mut message = opaque::Xcm::TransferAsset { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], dest: Null, }; @@ -110,7 +110,7 @@ fn allow_unpaid_should_work() { fn allow_paid_should_work() { AllowPaidFrom::set(vec![ X1(Parent) ]); - let mut message = Xcm::TransferAsset { + let mut message = opaque::Xcm::TransferAsset { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], dest: Null, }; @@ -124,7 +124,7 @@ fn allow_paid_should_work() { ); assert_eq!(r, Err(())); - let mut underpaying_message = Xcm::ReserveAssetDeposit { + let mut underpaying_message = opaque::Xcm::ReserveAssetDeposit { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], effects: vec![ Order::BuyExecution { fees: All, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] }, @@ -141,7 +141,7 @@ fn allow_paid_should_work() { ); assert_eq!(r, Err(())); - let mut paying_message = Xcm::ReserveAssetDeposit { + let mut paying_message = opaque::Xcm::ReserveAssetDeposit { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], effects: vec![ Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs new file mode 100644 index 000000000000..53044b008947 --- /dev/null +++ b/xcm/xcm-builder/src/weight.rs @@ -0,0 +1,98 @@ +// Copyright 2020 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 . + +use sp_std::{result::Result, marker::PhantomData}; +use parity_scale_codec::Decode; +use xcm::v0::{Xcm, Order, MultiAsset, MultiLocation}; +use frame_support::{traits::Get, weights::{Weight, GetDispatchInfo}}; +use xcm_executor::{Assets, traits::{WeightBounds, WeightTrader}}; + +pub struct FixedWeightBounds(PhantomData<(T, C)>); +impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeightBounds { + fn shallow(message: &mut Xcm) -> Result { + let min = match message { + Xcm::Transact { call, .. } => { + call.ensure_decoded()?.get_dispatch_info().weight + T::get() + } + Xcm::WithdrawAsset { effects, .. } + | Xcm::ReserveAssetDeposit { effects, .. } + | Xcm::TeleportAsset { effects, .. } => { + let inner: Weight = effects.iter_mut() + .map(|effect| match effect { + Order::BuyExecution { .. } => { + // On success, execution of this will result in more weight being consumed but + // we don't count it here since this is only the *shallow*, non-negotiable weight + // spend and doesn't count weight placed behind a `BuyExecution` since it will not + // be definitely consumed from any existing weight credit if execution of the message + // is attempted. + T::get() + }, + _ => T::get(), + }).sum(); + T::get() + inner + } + _ => T::get(), + }; + Ok(min) + } + fn deep(message: &mut Xcm) -> Result { + let mut extra = 0; + match message { + Xcm::Transact { .. } => {} + Xcm::WithdrawAsset { effects, .. } + | Xcm::ReserveAssetDeposit { effects, .. } + | Xcm::TeleportAsset { effects, .. } => { + for effect in effects.iter_mut() { + match effect { + Order::BuyExecution { xcm, .. } => { + for message in xcm.iter_mut() { + extra += Self::shallow(message)? + Self::deep(message)?; + } + }, + _ => {} + } + } + } + _ => {} + }; + Ok(extra) + } +} + +/// Simple fee calculator that requires payment in a single concrete fungible at a fixed rate. +/// +/// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for +/// one second of weight. +pub struct FixedRateOfConcreteFungible(Weight, PhantomData); +impl> WeightTrader for FixedRateOfConcreteFungible { + fn new() -> Self { Self(0, PhantomData) } + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { + let (id, units_per_second) = T::get(); + let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; + let required = MultiAsset::ConcreteFungible { amount, id }; + let (used, _) = payment.less(required).map_err(|_| ())?; + self.0 = self.0.saturating_add(weight); + Ok(used) + } + fn refund_weight(&mut self, weight: Weight) -> MultiAsset { + let weight = weight.min(self.0); + self.0 -= weight; + let (id, units_per_second) = T::get(); + let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; + let result = MultiAsset::ConcreteFungible { amount, id }; + result + } +} diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs index 5ce870da7348..7fa571177fb8 100644 --- a/xcm/xcm-executor/src/config.rs +++ b/xcm/xcm-executor/src/config.rs @@ -14,255 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::marker::PhantomData; -use parity_scale_codec::Decode; -use xcm::v0::{SendXcm, MultiLocation, MultiAsset, Xcm, Order, Response}; -use frame_support::{ - ensure, dispatch::{Dispatchable, Parameter, Weight}, weights::{PostDispatchInfo, GetDispatchInfo} +use xcm::v0::SendXcm; +use frame_support::dispatch::{Dispatchable, Parameter}; +use frame_support::weights::{PostDispatchInfo, GetDispatchInfo}; +use crate::traits::{ + TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, ShouldExecute, WeightTrader, WeightBounds, + OnResponse, }; -use frame_support::traits::{Get, Contains}; -use crate::traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; -use crate::assets::Assets; - -/// Determine the weight of an XCM message. -pub trait WeightBounds { - /// Return the minimum amount of weight that an attempted execution of this message would definitely - /// consume. - /// - /// This is useful to gauge how many fees should be paid up front to begin execution of the message. - /// It is not useful for determining whether execution should begin lest it result in surpassing weight - /// limits - in that case `deep` is the function to use. - fn shallow(message: &mut Xcm) -> Result; - - /// Return the deep amount of weight, over `shallow` that complete, successful and worst-case execution of - /// `message` would incur. - /// - /// This is perhaps overly pessimistic for determining how many fees should be paid for up-front since - /// fee payment (or any other way of offsetting the execution costs such as an voucher-style NFT) may - /// happen in stages throughout execution of the XCM. - /// - /// A reminder: if it is possible that `message` may have alternative means of successful completion - /// (perhaps a conditional path), then the *worst case* weight must be reported. - /// - /// This is guaranteed equal to the eventual sum of all `shallow` XCM messages that get executed through - /// any internal effects. Inner XCM messages may be executed by: - /// - Order::BuyExecution - fn deep(message: &mut Xcm) -> Result; -} - -pub struct FixedWeightBounds(PhantomData<(T, C)>); -impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeightBounds { - fn shallow(message: &mut Xcm) -> Result { - let min = match message { - Xcm::Transact { call, .. } => { - call.ensure_decoded()?.get_dispatch_info().weight + T::get() - } - Xcm::WithdrawAsset { effects, .. } - | Xcm::ReserveAssetDeposit { effects, .. } - | Xcm::TeleportAsset { effects, .. } => { - let inner: Weight = effects.iter_mut() - .map(|effect| match effect { - Order::BuyExecution { .. } => { - // On success, execution of this will result in more weight being consumed but - // we don't count it here since this is only the *shallow*, non-negotiable weight - // spend and doesn't count weight placed behind a `BuyExecution` since it will not - // be definitely consumed from any existing weight credit if execution of the message - // is attempted. - T::get() - }, - _ => T::get(), - }).sum(); - T::get() + inner - } - _ => T::get(), - }; - Ok(min) - } - fn deep(message: &mut Xcm) -> Result { - let mut extra = 0; - match message { - Xcm::Transact { .. } => {} - Xcm::WithdrawAsset { effects, .. } - | Xcm::ReserveAssetDeposit { effects, .. } - | Xcm::TeleportAsset { effects, .. } => { - for effect in effects.iter_mut() { - match effect { - Order::BuyExecution { xcm, .. } => { - for message in xcm.iter_mut() { - extra += Self::shallow(message)? + Self::deep(message)?; - } - }, - _ => {} - } - } - } - _ => {} - }; - Ok(extra) - } -} - -/// Charge for weight in order to execute XCM. -pub trait WeightTrader { - /// Create a new trader instance. - fn new() -> Self; - - /// Purchase execution weight credit in return for up to a given `fee`. If less of the fee is required - /// then the surplus is returned. If the `fee` cannot be used to pay for the `weight`, then an error is - /// returned. - fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result; - - /// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight was - /// purchased using `buy_weight`. - /// - /// Default implementation refunds nothing. - fn refund_weight(&mut self, _weight: Weight) -> MultiAsset { MultiAsset::None } -} - -/// Simple fee calculator that requires payment in a single concrete fungible at a fixed rate. -/// -/// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for -/// one second of weight. -pub struct FixedRateOfConcreteFungible(Weight, PhantomData); -impl> WeightTrader for FixedRateOfConcreteFungible { - fn new() -> Self { Self(0, PhantomData) } - fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { - let (id, units_per_second) = T::get(); - let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; - let required = MultiAsset::ConcreteFungible { amount, id }; - let (used, _) = payment.less(required).map_err(|_| ())?; - self.0 = self.0.saturating_add(weight); - Ok(used) - } - fn refund_weight(&mut self, weight: Weight) -> MultiAsset { - let weight = weight.min(self.0); - self.0 -= weight; - let (id, units_per_second) = T::get(); - let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128; - let result = MultiAsset::ConcreteFungible { amount, id }; - result - } -} - -/// Trait to determine whether the execution engine should actually execute a given XCM. -pub trait ShouldExecute { - /// Returns `true` if the given `message` may be executed. - /// - /// - `origin`: The origin (sender) of the message. - /// - `top_level`: `true`` indicates the initial XCM coming from the `origin`, `false` indicates an embedded - /// XCM executed internally as part of another message or an `Order`. - /// - `message`: The message itself. - /// - `shallow_weight`: The weight of the non-negotiable execution of the message. This does not include any - /// embedded XCMs sat behind mechanisms like `BuyExecution` which would need to answer for their own weight. - /// - `weight_credit`: The pre-established amount of weight that the system has determined this message - /// may utilise in its execution. Typically non-zero only because of prior fee payment, but could - /// in principle be due to other factors. - fn should_execute( - origin: &MultiLocation, - top_level: bool, - message: &Xcm, - shallow_weight: Weight, - weight_credit: &mut Weight, - ) -> Result<(), ()>; -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl ShouldExecute for Tuple { - fn should_execute( - origin: &MultiLocation, - top_level: bool, - message: &Xcm, - shallow_weight: Weight, - weight_credit: &mut Weight, - ) -> Result<(), ()> { - for_tuples!( #( - match Tuple::should_execute(origin, top_level, message, shallow_weight, weight_credit) { - o @ Ok(()) => return o, - _ => (), - } - )* ); - Err(()) - } -} - -pub struct TakeWeightCredit; -impl ShouldExecute for TakeWeightCredit { - fn should_execute( - _origin: &MultiLocation, - _top_level: bool, - _message: &Xcm, - shallow_weight: Weight, - weight_credit: &mut Weight, - ) -> Result<(), ()> { - *weight_credit = weight_credit.checked_sub(shallow_weight).ok_or(())?; - Ok(()) - } -} - -pub struct AllowTopLevelPaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { - fn should_execute( - origin: &MultiLocation, - top_level: bool, - message: &Xcm, - shallow_weight: Weight, - _weight_credit: &mut Weight, - ) -> Result<(), ()> { - ensure!(T::contains(origin), ()); - ensure!(top_level, ()); - match message { - Xcm::TeleportAsset { effects, .. } - | Xcm::WithdrawAsset { effects, ..} - | Xcm::ReserveAssetDeposit { effects, ..} - if matches!( - effects.first(), - Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight - ) - => Ok(()), - _ => Err(()), - } - } -} - -pub struct AllowUnpaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowUnpaidExecutionFrom { - fn should_execute( - origin: &MultiLocation, - _top_level: bool, - _message: &Xcm, - _shallow_weight: Weight, - _weight_credit: &mut Weight, - ) -> Result<(), ()> { - ensure!(T::contains(origin), ()); - Ok(()) - } -} - -pub trait OnResponse { - fn expecting_response(origin: &MultiLocation, query_id: u64) -> bool; - fn on_response(origin: MultiLocation, query_id: u64, response: Response) -> Weight; -} -impl OnResponse for () { - fn expecting_response(_origin: &MultiLocation, _query_id: u64) -> bool { false } - fn on_response(_origin: MultiLocation, _query_id: u64, _response: Response) -> Weight { 0 } -} - -pub struct AllowKnownQueryResponses(PhantomData); -impl ShouldExecute for AllowKnownQueryResponses { - fn should_execute( - origin: &MultiLocation, - _top_level: bool, - message: &Xcm, - _shallow_weight: Weight, - _weight_credit: &mut Weight, - ) -> Result<(), ()> { - match message { - Xcm::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id) - => Ok(()), - _ => Err(()), - } - } -} /// The trait to parametrize the `XcmExecutor`. pub trait Config { diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index d75074e4c8a3..ee738518d15e 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -26,22 +26,16 @@ use xcm::v0::{ MultiLocation, MultiAsset, Xcm, Order, Response, }; -#[cfg(test)] -mod mock; -#[cfg(test)] -mod tests; - pub mod traits; -use traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation}; +use traits::{ + TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, WeightBounds, WeightTrader, ShouldExecute, + OnResponse +}; mod assets; pub use assets::{Assets, AssetId}; mod config; -pub use config::{ - Config, WeightBounds, WeightTrader, ShouldExecute, OnResponse, AllowKnownQueryResponses, - AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, - FixedRateOfConcreteFungible, -}; +pub use config::Config; pub struct XcmExecutor(PhantomData); diff --git a/xcm/xcm-executor/src/traits.rs b/xcm/xcm-executor/src/traits.rs deleted file mode 100644 index ee9e3ae4f45d..000000000000 --- a/xcm/xcm-executor/src/traits.rs +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2020 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 . - -use sp_std::{result::Result, marker::PhantomData, convert::TryFrom}; -use sp_runtime::traits::CheckedConversion; -use xcm::v0::{Error as XcmError, Result as XcmResult, MultiAsset, MultiLocation, Junction, OriginKind}; -use frame_support::traits::Get; -use super::Assets; - -pub trait FilterAssetLocation { - /// A filter to distinguish between asset/location pairs. - fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool; -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl FilterAssetLocation for Tuple { - fn filter_asset_location(what: &MultiAsset, origin: &MultiLocation) -> bool { - for_tuples!( #( - if Tuple::filter_asset_location(what, origin) { return true } - )* ); - false - } -} - -pub struct NativeAsset; -impl FilterAssetLocation for NativeAsset { - fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { - matches!(asset, MultiAsset::ConcreteFungible { ref id, .. } if id == origin) - } -} - - -pub struct Case(PhantomData); -impl> FilterAssetLocation for Case { - fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { - let (a, o) = T::get(); - &a == asset && &o == origin - } -} - -/// Facility for asset transacting. -/// -/// This should work with as many asset/location combinations as possible. Locations to support may include non- -/// account locations such as a `MultiLocation::X1(Junction::Parachain)`. Different chains may handle them in -/// different ways. -pub trait TransactAsset { - /// Deposit the `what` asset into the account of `who`. - /// - /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. - fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> XcmResult; - - /// Withdraw the given asset from the consensus system. Return the actual asset(s) withdrawn. In - /// the case of `what` being a wildcard, this may be something more specific. - /// - /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. - fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result; - - /// Move an `asset` `from` one location in `to` another location. - /// - /// Returns `XcmError::FailedToTransactAsset` if transfer failed. - fn transfer_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { - let withdrawn = Self::withdraw_asset(asset, from)?; - for asset in withdrawn.assets_iter() { - Self::deposit_asset(&asset, to)?; - } - Ok(withdrawn) - } -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl TransactAsset for Tuple { - fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> XcmResult { - for_tuples!( #( - match Tuple::deposit_asset(what, who) { o @ Ok(_) => return o, _ => () } - )* ); - Err(XcmError::Unimplemented) - } - fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { - for_tuples!( #( - match Tuple::withdraw_asset(what, who) { o @ Ok(_) => return o, _ => () } - )* ); - Err(XcmError::Unimplemented) - } -} - - -pub trait MatchesFungible { - fn matches_fungible(a: &MultiAsset) -> Option; -} -pub struct IsConcrete(PhantomData); -impl, B: TryFrom> MatchesFungible for IsConcrete { - fn matches_fungible(a: &MultiAsset) -> Option { - match a { - MultiAsset::ConcreteFungible { id, amount } if id == &T::get() => - CheckedConversion::checked_from(*amount), - _ => None, - } - } -} -pub struct IsAbstract(PhantomData); -impl, B: TryFrom> MatchesFungible for IsAbstract { - fn matches_fungible(a: &MultiAsset) -> Option { - match a { - MultiAsset::AbstractFungible { id, amount } if &id[..] == T::get() => - CheckedConversion::checked_from(*amount), - _ => None, - } - } -} -// TODO: impl for tuples -impl, X: MatchesFungible, Y: MatchesFungible> MatchesFungible for (X, Y) { - fn matches_fungible(a: &MultiAsset) -> Option { - X::matches_fungible(a).or_else(|| Y::matches_fungible(a)) - } -} - -// TODO: change to use Convert trait. -/// Attempt to convert a location into some value of type `T`, or vice-versa. -pub trait LocationConversion { - /// Convert `location` into `Some` value of `T`, or `None` if not possible. - // TODO: consider returning Result instead. - fn from_location(location: &MultiLocation) -> Option; - /// Convert some value `value` into a `location`, `Err`oring with the original `value` if not possible. - // TODO: consider renaming `into_location` - fn try_into_location(value: T) -> Result; -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl LocationConversion for Tuple { - fn from_location(location: &MultiLocation) -> Option { - for_tuples!( #( - if let Some(result) = Tuple::from_location(location) { return Some(result) } - )* ); - None - } - fn try_into_location(who: AccountId) -> Result { - for_tuples!( #( - let who = match Tuple::try_into_location(who) { Err(w) => w, r => return r }; - )* ); - Err(who) - } -} - -pub trait ConvertOrigin { - fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result; -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl ConvertOrigin for Tuple { - fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { - for_tuples!( #( - let origin = match Tuple::convert_origin(origin, kind) { Err(o) => o, r => return r }; - )* ); - Err(origin) - } -} - -/// Means of inverting a location: given a location which describes a `target` interpreted from the `source`, this -/// will provide the corresponding location which describes the `source` -pub trait InvertLocation { - fn invert_location(l: &MultiLocation) -> MultiLocation; -} - -/// Simple location inverter; give it this location's ancestry and it'll figure out the inverted location. -pub struct LocationInverter(PhantomData); -impl> InvertLocation for LocationInverter { - fn invert_location(location: &MultiLocation) -> MultiLocation { - let mut ancestry = Ancestry::get(); - let mut result = location.clone(); - for (i, j) in location.iter_rev() - .map(|j| match j { - Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild), - _ => Junction::Parent, - }) - .enumerate() - { - *result.at_mut(i).expect("location and result begin equal; same size; qed") = j; - } - result - } -} - diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs new file mode 100644 index 000000000000..08afc2e0eb54 --- /dev/null +++ b/xcm/xcm-executor/src/traits/conversion.rs @@ -0,0 +1,65 @@ +// Copyright 2020 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 . + +use sp_std::result::Result; +use xcm::v0::{MultiLocation, OriginKind}; + +// TODO: change to use Convert trait. +/// Attempt to convert a location into some value of type `T`, or vice-versa. +pub trait LocationConversion { + /// Convert `location` into `Some` value of `T`, or `None` if not possible. + // TODO: consider returning Result instead. + fn from_location(location: &MultiLocation) -> Option; + /// Convert some value `value` into a `location`, `Err`oring with the original `value` if not possible. + // TODO: consider renaming `into_location` + fn try_into_location(value: T) -> Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl LocationConversion for Tuple { + fn from_location(location: &MultiLocation) -> Option { + for_tuples!( #( + if let Some(result) = Tuple::from_location(location) { return Some(result) } + )* ); + None + } + fn try_into_location(who: AccountId) -> Result { + for_tuples!( #( + let who = match Tuple::try_into_location(who) { Err(w) => w, r => return r }; + )* ); + Err(who) + } +} + +pub trait ConvertOrigin { + fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ConvertOrigin for Tuple { + fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { + for_tuples!( #( + let origin = match Tuple::convert_origin(origin, kind) { Err(o) => o, r => return r }; + )* ); + Err(origin) + } +} + +/// Means of inverting a location: given a location which describes a `target` interpreted from the `source`, this +/// will provide the corresponding location which describes the `source` +pub trait InvertLocation { + fn invert_location(l: &MultiLocation) -> MultiLocation; +} diff --git a/xcm/xcm-executor/src/traits/filter_asset_location.rs b/xcm/xcm-executor/src/traits/filter_asset_location.rs new file mode 100644 index 000000000000..084c5c1a0331 --- /dev/null +++ b/xcm/xcm-executor/src/traits/filter_asset_location.rs @@ -0,0 +1,32 @@ +// Copyright 2020 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 . + +use xcm::v0::{MultiAsset, MultiLocation}; + +pub trait FilterAssetLocation { + /// A filter to distinguish between asset/location pairs. + fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl FilterAssetLocation for Tuple { + fn filter_asset_location(what: &MultiAsset, origin: &MultiLocation) -> bool { + for_tuples!( #( + if Tuple::filter_asset_location(what, origin) { return true } + )* ); + false + } +} diff --git a/xcm/xcm-executor/src/traits/matches_fungible.rs b/xcm/xcm-executor/src/traits/matches_fungible.rs new file mode 100644 index 000000000000..64a35762c2db --- /dev/null +++ b/xcm/xcm-executor/src/traits/matches_fungible.rs @@ -0,0 +1,28 @@ +// Copyright 2020 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 . + +use xcm::v0::MultiAsset; + +pub trait MatchesFungible { + fn matches_fungible(a: &MultiAsset) -> Option; +} + +// TODO: impl for tuples +impl, X: MatchesFungible, Y: MatchesFungible> MatchesFungible for (X, Y) { + fn matches_fungible(a: &MultiAsset) -> Option { + X::matches_fungible(a).or_else(|| Y::matches_fungible(a)) + } +} diff --git a/xcm/xcm-executor/src/traits/mod.rs b/xcm/xcm-executor/src/traits/mod.rs new file mode 100644 index 000000000000..668255365a0c --- /dev/null +++ b/xcm/xcm-executor/src/traits/mod.rs @@ -0,0 +1,32 @@ +// Copyright 2020 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 . + +//! Various traits used in configuring the executor. + +mod conversion; +pub use conversion::{LocationConversion, InvertLocation, ConvertOrigin}; +mod filter_asset_location; +pub use filter_asset_location::{FilterAssetLocation}; +mod matches_fungible; +pub use matches_fungible::{MatchesFungible}; +mod on_response; +pub use on_response::OnResponse; +mod should_execute; +pub use should_execute::ShouldExecute; +mod transact_asset; +pub use transact_asset::TransactAsset; +mod weight; +pub use weight::{WeightBounds, WeightTrader}; diff --git a/xcm/xcm-executor/src/traits/on_response.rs b/xcm/xcm-executor/src/traits/on_response.rs new file mode 100644 index 000000000000..f74c8bdd8c75 --- /dev/null +++ b/xcm/xcm-executor/src/traits/on_response.rs @@ -0,0 +1,27 @@ +// Copyright 2020 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 . + +use xcm::v0::{Response, MultiLocation}; +use frame_support::weights::Weight; + +pub trait OnResponse { + fn expecting_response(origin: &MultiLocation, query_id: u64) -> bool; + fn on_response(origin: MultiLocation, query_id: u64, response: Response) -> Weight; +} +impl OnResponse for () { + fn expecting_response(_origin: &MultiLocation, _query_id: u64) -> bool { false } + fn on_response(_origin: MultiLocation, _query_id: u64, _response: Response) -> Weight { 0 } +} diff --git a/xcm/xcm-executor/src/traits/should_execute.rs b/xcm/xcm-executor/src/traits/should_execute.rs new file mode 100644 index 000000000000..e373616d5ee2 --- /dev/null +++ b/xcm/xcm-executor/src/traits/should_execute.rs @@ -0,0 +1,60 @@ +// Copyright 2020 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 . + +use sp_std::result::Result; +use xcm::v0::{Xcm, MultiLocation}; +use frame_support::weights::Weight; + +/// Trait to determine whether the execution engine should actually execute a given XCM. +pub trait ShouldExecute { + /// Returns `true` if the given `message` may be executed. + /// + /// - `origin`: The origin (sender) of the message. + /// - `top_level`: `true`` indicates the initial XCM coming from the `origin`, `false` indicates an embedded + /// XCM executed internally as part of another message or an `Order`. + /// - `message`: The message itself. + /// - `shallow_weight`: The weight of the non-negotiable execution of the message. This does not include any + /// embedded XCMs sat behind mechanisms like `BuyExecution` which would need to answer for their own weight. + /// - `weight_credit`: The pre-established amount of weight that the system has determined this message + /// may utilise in its execution. Typically non-zero only because of prior fee payment, but could + /// in principle be due to other factors. + fn should_execute( + origin: &MultiLocation, + top_level: bool, + message: &Xcm, + shallow_weight: Weight, + weight_credit: &mut Weight, + ) -> Result<(), ()>; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ShouldExecute for Tuple { + fn should_execute( + origin: &MultiLocation, + top_level: bool, + message: &Xcm, + shallow_weight: Weight, + weight_credit: &mut Weight, + ) -> Result<(), ()> { + for_tuples!( #( + match Tuple::should_execute(origin, top_level, message, shallow_weight, weight_credit) { + o @ Ok(()) => return o, + _ => (), + } + )* ); + Err(()) + } +} diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs new file mode 100644 index 000000000000..6a1e2bd497e4 --- /dev/null +++ b/xcm/xcm-executor/src/traits/transact_asset.rs @@ -0,0 +1,64 @@ +// Copyright 2020 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 . + +use sp_std::result::Result; +use xcm::v0::{Error as XcmError, Result as XcmResult, MultiAsset, MultiLocation}; +use crate::Assets; + +/// Facility for asset transacting. +/// +/// This should work with as many asset/location combinations as possible. Locations to support may include non- +/// account locations such as a `MultiLocation::X1(Junction::Parachain)`. Different chains may handle them in +/// different ways. +pub trait TransactAsset { + /// Deposit the `what` asset into the account of `who`. + /// + /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. + fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> XcmResult; + + /// Withdraw the given asset from the consensus system. Return the actual asset(s) withdrawn. In + /// the case of `what` being a wildcard, this may be something more specific. + /// + /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. + fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result; + + /// Move an `asset` `from` one location in `to` another location. + /// + /// Returns `XcmError::FailedToTransactAsset` if transfer failed. + fn transfer_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { + let withdrawn = Self::withdraw_asset(asset, from)?; + for asset in withdrawn.assets_iter() { + Self::deposit_asset(&asset, to)?; + } + Ok(withdrawn) + } +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl TransactAsset for Tuple { + fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> XcmResult { + for_tuples!( #( + match Tuple::deposit_asset(what, who) { o @ Ok(_) => return o, _ => () } + )* ); + Err(XcmError::Unimplemented) + } + fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { + for_tuples!( #( + match Tuple::withdraw_asset(what, who) { o @ Ok(_) => return o, _ => () } + )* ); + Err(XcmError::Unimplemented) + } +} diff --git a/xcm/xcm-executor/src/traits/weight.rs b/xcm/xcm-executor/src/traits/weight.rs new file mode 100644 index 000000000000..b28ef85a3047 --- /dev/null +++ b/xcm/xcm-executor/src/traits/weight.rs @@ -0,0 +1,63 @@ +// Copyright 2020 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 . + +use sp_std::result::Result; +use xcm::v0::{Xcm, MultiAsset}; +use frame_support::weights::Weight; +use crate::Assets; + +/// Determine the weight of an XCM message. +pub trait WeightBounds { + /// Return the minimum amount of weight that an attempted execution of this message would definitely + /// consume. + /// + /// This is useful to gauge how many fees should be paid up front to begin execution of the message. + /// It is not useful for determining whether execution should begin lest it result in surpassing weight + /// limits - in that case `deep` is the function to use. + fn shallow(message: &mut Xcm) -> Result; + + /// Return the deep amount of weight, over `shallow` that complete, successful and worst-case execution of + /// `message` would incur. + /// + /// This is perhaps overly pessimistic for determining how many fees should be paid for up-front since + /// fee payment (or any other way of offsetting the execution costs such as an voucher-style NFT) may + /// happen in stages throughout execution of the XCM. + /// + /// A reminder: if it is possible that `message` may have alternative means of successful completion + /// (perhaps a conditional path), then the *worst case* weight must be reported. + /// + /// This is guaranteed equal to the eventual sum of all `shallow` XCM messages that get executed through + /// any internal effects. Inner XCM messages may be executed by: + /// - Order::BuyExecution + fn deep(message: &mut Xcm) -> Result; +} + +/// Charge for weight in order to execute XCM. +pub trait WeightTrader { + /// Create a new trader instance. + fn new() -> Self; + + /// Purchase execution weight credit in return for up to a given `fee`. If less of the fee is required + /// then the surplus is returned. If the `fee` cannot be used to pay for the `weight`, then an error is + /// returned. + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result; + + /// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight was + /// purchased using `buy_weight`. + /// + /// Default implementation refunds nothing. + fn refund_weight(&mut self, _weight: Weight) -> MultiAsset { MultiAsset::None } +} From d1e3c3cb9b7c320ca2f4f82360f1bcb07cb33b39 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 14:01:39 +0200 Subject: [PATCH 24/40] Docs --- runtime/common/src/xcm_sender.rs | 2 +- runtime/parachains/src/ump.rs | 8 ++++---- xcm/src/v0/mod.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index 5b5d126d1647..84699d6b58b7 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -36,7 +36,7 @@ impl SendXcm for RelayChainXcmSender ).map_err(Into::::into)?; Ok(()) } else { - Err(Error::CannotReachDestination("TODO: `dest` to string")) + Err(Error::CannotReachDestination("UnsupportedDestination")) } } } diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 44475bce54c6..08174b72b837 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -66,7 +66,7 @@ impl UmpSink for XcmSink { use xcm::v0::{Junction, MultiLocation, ExecuteXcm, Outcome}; use xcm_executor::XcmExecutor; - // TODO: Get a proper weight limit here. Probably from Relay Chain Config + // TODO: #UMPQUEUE Get a proper weight limit here. Probably from Relay Chain Config let weight_limit = Weight::max_value(); let weight = if let Ok(versioned_xcm_message) = VersionedXcm::decode(&mut &msg[..]) { match versioned_xcm_message { @@ -89,9 +89,9 @@ impl UmpSink for XcmSink { Weight::zero() }; - // TODO: to be sound, this implementation must ensure that returned (and thus consumed) - // weight is limited to some small portion of the total block weight (as a ballpark, 1/4, 1/8 - // or lower). + // TODO: #UMPQUEUE to be sound, this implementation must ensure that returned (and thus consumed) + // weight is limited to some small portion of the total block weight (as a ballpark, 1/4, 1/8 + // or lower). weight } } diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 4440d3769e8f..759dfff50c93 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -33,7 +33,7 @@ pub use multi_location::MultiLocation; pub use order::Order; pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome}; -// TODO: Efficient encodings for Vec, Vec, using initial byte values 128+ to encode the number of +// TODO: #XCMENCODE Efficient encodings for Vec, Vec, using initial byte values 128+ to encode the number of // items in the vector. /// Basically just the XCM (more general) version of `ParachainDispatchOrigin`. From b95a84cff67b2bb5f8c29298939384b1640d082d Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 14:03:38 +0200 Subject: [PATCH 25/40] Docs --- xcm/xcm-builder/src/fungibles_adapter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs index a95cf92d62a1..5113e19614c3 100644 --- a/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/xcm/xcm-builder/src/fungibles_adapter.rs @@ -265,5 +265,5 @@ impl< Ok(what.clone().into()) } - // TODO: implement transfer_asset, but should move it into a different trait. + // TODO: #XCMXFERASSET implement transfer_asset, but should move it into a different trait. } From 3f4719b6ae6c7ab5c0458ea6e77bb27254643e86 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 14:26:10 +0200 Subject: [PATCH 26/40] Fixes --- xcm/xcm-builder/src/tests.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs index fb2a5afb884c..2a801eb25616 100644 --- a/xcm/xcm-builder/src/tests.rs +++ b/xcm/xcm-builder/src/tests.rs @@ -336,16 +336,3 @@ fn prepaid_result_of_query_should_get_free_execution() { let r = XcmExecutor::::execute_xcm(origin.clone(), message.clone(), weight_limit); assert_eq!(r, Outcome::Incomplete(10, XcmError::Barrier)); } - -// TODO: General ResponseMap of (QueryId, Origin) -> EitherOr> which -// allows free execution of the message and then either stores the result or calls a dispatch - in this case -// it could go overweight be up to the weight of whatever dispatch is in there. It should be added on and -// checked before executing any further XCMs. - -// TODO: Integrate into the XCM dispatch system in the runtimes - -// TODO: Ordering flag per message fragment in an aggregate message. - -// TODO: Test transact execution origins. - -// TODO: Don't just burn fees - send them somewhere, and test that we get them! From 1bc7fb3afddf30f54b58940a6f0a72c84441d443 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 7 Apr 2021 14:26:40 +0200 Subject: [PATCH 27/40] Update xcm/src/lib.rs Co-authored-by: Shawn Tabrizi --- xcm/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs index 25c8ed54f912..9768be8dacaa 100644 --- a/xcm/src/lib.rs +++ b/xcm/src/lib.rs @@ -52,7 +52,6 @@ pub mod opaque { pub type VersionedXcm = super::VersionedXcm<()>; } - /// A versioned multi-location, a relative location of a cross-consensus system identifier. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] pub enum VersionedMultiLocation { From 7277157c82cdc681c07bb1d47e80dcdd96d31280 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 14:27:46 +0200 Subject: [PATCH 28/40] Fixes --- xcm/xcm-executor/src/assets.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs index c676259a853d..69228112fbf7 100644 --- a/xcm/xcm-executor/src/assets.rs +++ b/xcm/xcm-executor/src/assets.rs @@ -93,13 +93,6 @@ impl Assets { /// New value, containing no assets. pub fn new() -> Self { Self::default() } - /// Substitute all abstract `MultiAsset` values for equivalent concrete values. - /// - /// If at least one of the values cannot be substituted, then return Err. - pub fn concretize(&mut self) -> Result<(), ()> { - todo!(); - } - /// An iterator over the fungible assets. pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator + 'a { self.fungible.iter() From acfedbb52f844494d998cacb6a3a9bcce5b2b6b5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 14:36:12 +0200 Subject: [PATCH 29/40] Docs --- xcm/xcm-executor/src/lib.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index ee738518d15e..a377a2afffd7 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -41,7 +41,7 @@ pub struct XcmExecutor(PhantomData); impl ExecuteXcm for XcmExecutor { fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Outcome { - // TODO: We should identify recursive bombs here and bail. + // TODO: #HARDENXCM We should identify recursive bombs here and bail. let mut message = Xcm::::from(message); let shallow_weight = match Config::Weigher::shallow(&mut message) { Ok(x) => x, @@ -61,7 +61,7 @@ impl ExecuteXcm for XcmExecutor { let mut trader = Config::Trader::new(); match Self::do_execute_xcm(origin, true, message, &mut 0, Some(shallow_weight), &mut trader) { Ok(surplus) => Outcome::Complete(maximum_weight.saturating_sub(surplus)), - // TODO: We can do better than returning `maximum_weight` here, and we should otherwise we'll + // TODO: #REALWEIGHT We can do better than returning `maximum_weight` here, and we should otherwise we'll // needlessly be disregarding block execution time. Err(e) => Outcome::Incomplete(maximum_weight, e), } @@ -151,8 +151,7 @@ impl XcmExecutor { (origin, Xcm::Transact { origin_type, require_weight_at_most, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. - // TODO: allow this to be configurable in the trait. - // TODO: allow the trait to issue filters for the relay-chain + // TODO: #TRANSACTFILTER allow the trait to issue filters for the relay-chain let message_call = call.take_decoded().map_err(|_| XcmError::FailedToDecode)?; let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_type) .map_err(|_| XcmError::BadOrigin)?; From 9f4f279355f79216b72cafeb716dc6016aa2c1ae Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 7 Apr 2021 14:39:00 +0200 Subject: [PATCH 30/40] Update runtime/parachains/src/ump.rs Co-authored-by: Shawn Tabrizi --- runtime/parachains/src/ump.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 08174b72b837..4559a38d04c9 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -74,11 +74,7 @@ impl UmpSink for XcmSink { let xcm_junction: Junction = Junction::Parachain { id: origin.into() }; let xcm_location: MultiLocation = xcm_junction.into(); let result = XcmExecutor::::execute_xcm(xcm_location, xcm_message, weight_limit); - match result { - Outcome::Complete(weight) => weight, - Outcome::Incomplete(weight, _e) => weight, - Outcome::Error(_e) => Weight::zero(), - } + result.weight_used() } } } else { From 29767d4a28416f2abce0952a9fae50f38027fc03 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 14:39:07 +0200 Subject: [PATCH 31/40] Docs --- xcm/xcm-executor/src/traits/conversion.rs | 6 +++--- xcm/xcm-executor/src/traits/matches_fungible.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs index 08afc2e0eb54..b7363a1eea48 100644 --- a/xcm/xcm-executor/src/traits/conversion.rs +++ b/xcm/xcm-executor/src/traits/conversion.rs @@ -17,14 +17,14 @@ use sp_std::result::Result; use xcm::v0::{MultiLocation, OriginKind}; -// TODO: change to use Convert trait. +// TODO: #LOCCONV change to use Convert trait. /// Attempt to convert a location into some value of type `T`, or vice-versa. pub trait LocationConversion { /// Convert `location` into `Some` value of `T`, or `None` if not possible. - // TODO: consider returning Result instead. + // TODO: #LOCCONV consider returning Result instead. fn from_location(location: &MultiLocation) -> Option; /// Convert some value `value` into a `location`, `Err`oring with the original `value` if not possible. - // TODO: consider renaming `into_location` + // TODO: #LOCCONV consider renaming `into_location` fn try_into_location(value: T) -> Result; } diff --git a/xcm/xcm-executor/src/traits/matches_fungible.rs b/xcm/xcm-executor/src/traits/matches_fungible.rs index 64a35762c2db..079b3f138a11 100644 --- a/xcm/xcm-executor/src/traits/matches_fungible.rs +++ b/xcm/xcm-executor/src/traits/matches_fungible.rs @@ -20,7 +20,7 @@ pub trait MatchesFungible { fn matches_fungible(a: &MultiAsset) -> Option; } -// TODO: impl for tuples +// TODO: #MATCHTUPLE impl for tuples impl, X: MatchesFungible, Y: MatchesFungible> MatchesFungible for (X, Y) { fn matches_fungible(a: &MultiAsset) -> Option { X::matches_fungible(a).or_else(|| Y::matches_fungible(a)) From 1016da9b3429d4b69eb8f40a490a6443da645d9d Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 14:49:55 +0200 Subject: [PATCH 32/40] Fixes --- xcm/src/v0/mod.rs | 32 +++++++++---------- .../src/traits/matches_fungible.rs | 11 ++++--- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 759dfff50c93..0f8b1c0a5e2b 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -164,6 +164,22 @@ pub enum Xcm { #[codec(index = 5)] TransferReserveAsset { assets: Vec, dest: MultiLocation, effects: Vec> }, + /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind + /// of origin `origin_type`. + /// + /// - `origin_type`: The means of expressing the message origin as a dispatch origin. + /// - `max_weight`: The weight of `call`; this should be at least the chain's calculated weight and will + /// be used in the weight determination arithmetic. + /// - `call`: The encoded transaction to be applied. + /// + /// Safety: No concerns. + /// + /// Kind: *Instruction*. + /// + /// Errors: + #[codec(index = 6)] + Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded }, + /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the /// relay-chain to a para. /// @@ -211,22 +227,6 @@ pub enum Xcm { #[codec(compact)] sender: u32, #[codec(compact)] recipient: u32, }, - - /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind - /// of origin `origin_type`. - /// - /// - `origin_type`: The means of expressing the message origin as a dispatch origin. - /// - `max_weight`: The weight of `call`; this should be at least the chain's calculated weight and will - /// be used in the weight determination arithmetic. - /// - `call`: The encoded transaction to be applied. - /// - /// Safety: No concerns. - /// - /// Kind: *Instruction*. - /// - /// Errors: - #[codec(index = 10)] - Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded }, } impl From> for VersionedXcm { diff --git a/xcm/xcm-executor/src/traits/matches_fungible.rs b/xcm/xcm-executor/src/traits/matches_fungible.rs index 079b3f138a11..70383e93966d 100644 --- a/xcm/xcm-executor/src/traits/matches_fungible.rs +++ b/xcm/xcm-executor/src/traits/matches_fungible.rs @@ -20,9 +20,12 @@ pub trait MatchesFungible { fn matches_fungible(a: &MultiAsset) -> Option; } -// TODO: #MATCHTUPLE impl for tuples -impl, X: MatchesFungible, Y: MatchesFungible> MatchesFungible for (X, Y) { - fn matches_fungible(a: &MultiAsset) -> Option { - X::matches_fungible(a).or_else(|| Y::matches_fungible(a)) +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl MatchesFungible for Tuple { + fn matches_fungible(a: &MultiAsset) -> Option { + for_tuples!( #( + match Tuple::matches_fungible(a) { o @ Some(_) => return o, _ => () } + )* ); + None } } From f5c02c3261c0b71e6ff6046b4426e11c088a5b24 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 15:43:20 +0200 Subject: [PATCH 33/40] Fixes --- xcm/xcm-builder/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs index 2a801eb25616..09bce676491b 100644 --- a/xcm/xcm-builder/src/tests.rs +++ b/xcm/xcm-builder/src/tests.rs @@ -133,7 +133,7 @@ fn allow_paid_should_work() { }; let r = AllowTopLevelPaidExecutionFrom::>::should_execute( - &X1(Parachain { id: 1 }), + &X1(Parent), true, &mut underpaying_message, 30, From 4eb6bb6fc410eb82dbd2148ff3c66c949045cc61 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 16:04:20 +0200 Subject: [PATCH 34/40] Fixes --- xcm/src/v0/traits.rs | 1 + xcm/xcm-executor/src/lib.rs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs index 0a8041d87036..0a5092f3cc57 100644 --- a/xcm/src/v0/traits.rs +++ b/xcm/src/v0/traits.rs @@ -24,6 +24,7 @@ use super::{MultiLocation, Xcm}; #[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, Debug)] pub enum Error { Undefined, + Overflow, Unimplemented, UnhandledXcmVersion, UnhandledXcmMessage, diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index a377a2afffd7..c6f74259c9cd 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -170,10 +170,10 @@ impl XcmExecutor { // didn't realise that we didn't have to do. // It works because we assume that the `Config::Weigher` will always count the `call`'s // `get_dispatch_info` weight into its `shallow` estimate. - *weight_credit += surplus; + *weight_credit = weight_credit.saturating_add(surplus); // Do the same for the total surplus, which is reported to the caller and eventually makes its way // back up the stack to be subtracted from the deep-weight. - total_surplus += surplus; + total_surplus = total_surplus.saturating_add(surplus); // Return the overestimated amount so we can adjust our expectations on how much this entire // execution has taken. None @@ -230,7 +230,7 @@ impl XcmExecutor { } Order::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { // pay for `weight` using up to `fees` of the holding account. - let purchasing_weight = Weight::from(weight + debt); + let purchasing_weight = Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?); let max_fee = holding.try_take(fees).map_err(|()| XcmError::NotHoldingFees)?; let unspent = trader.buy_weight(purchasing_weight, max_fee)?; holding.saturating_subsume_all(unspent); From 03d739b97b844e2e4baf2d137f288d4d99c01db6 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 16:15:46 +0200 Subject: [PATCH 35/40] Docs --- runtime/parachains/src/ump.rs | 4 ++-- xcm/src/v0/mod.rs | 4 ++-- xcm/xcm-builder/src/fungibles_adapter.rs | 2 +- xcm/xcm-executor/src/lib.rs | 8 ++++---- xcm/xcm-executor/src/traits/conversion.rs | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 4559a38d04c9..171bb0996dcb 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -66,7 +66,7 @@ impl UmpSink for XcmSink { use xcm::v0::{Junction, MultiLocation, ExecuteXcm, Outcome}; use xcm_executor::XcmExecutor; - // TODO: #UMPQUEUE Get a proper weight limit here. Probably from Relay Chain Config + // TODO: #2841 #UMPQUEUE Get a proper weight limit here. Probably from Relay Chain Config let weight_limit = Weight::max_value(); let weight = if let Ok(versioned_xcm_message) = VersionedXcm::decode(&mut &msg[..]) { match versioned_xcm_message { @@ -85,7 +85,7 @@ impl UmpSink for XcmSink { Weight::zero() }; - // TODO: #UMPQUEUE to be sound, this implementation must ensure that returned (and thus consumed) + // TODO: #2841 #UMPQUEUE to be sound, this implementation must ensure that returned (and thus consumed) // weight is limited to some small portion of the total block weight (as a ballpark, 1/4, 1/8 // or lower). weight diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs index 0f8b1c0a5e2b..e2add5364253 100644 --- a/xcm/src/v0/mod.rs +++ b/xcm/src/v0/mod.rs @@ -33,8 +33,8 @@ pub use multi_location::MultiLocation; pub use order::Order; pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome}; -// TODO: #XCMENCODE Efficient encodings for Vec, Vec, using initial byte values 128+ to encode the number of -// items in the vector. +// TODO: #2841 #XCMENCODE Efficient encodings for Vec, Vec, using initial byte values 128+ to encode +// the number of items in the vector. /// Basically just the XCM (more general) version of `ParachainDispatchOrigin`. #[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug)] diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs index 5113e19614c3..014d6d833472 100644 --- a/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/xcm/xcm-builder/src/fungibles_adapter.rs @@ -265,5 +265,5 @@ impl< Ok(what.clone().into()) } - // TODO: #XCMXFERASSET implement transfer_asset, but should move it into a different trait. + // TODO: #2841 #XCMXFERASSET implement transfer_asset, but should move it into a different trait. } diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index c6f74259c9cd..9b56631ddd14 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -41,7 +41,7 @@ pub struct XcmExecutor(PhantomData); impl ExecuteXcm for XcmExecutor { fn execute_xcm(origin: MultiLocation, message: Xcm, weight_limit: Weight) -> Outcome { - // TODO: #HARDENXCM We should identify recursive bombs here and bail. + // TODO: #2841 #HARDENXCM We should identify recursive bombs here and bail. let mut message = Xcm::::from(message); let shallow_weight = match Config::Weigher::shallow(&mut message) { Ok(x) => x, @@ -61,8 +61,8 @@ impl ExecuteXcm for XcmExecutor { let mut trader = Config::Trader::new(); match Self::do_execute_xcm(origin, true, message, &mut 0, Some(shallow_weight), &mut trader) { Ok(surplus) => Outcome::Complete(maximum_weight.saturating_sub(surplus)), - // TODO: #REALWEIGHT We can do better than returning `maximum_weight` here, and we should otherwise we'll - // needlessly be disregarding block execution time. + // TODO: #2841 #REALWEIGHT We can do better than returning `maximum_weight` here, and we should otherwise + // we'll needlessly be disregarding block execution time. Err(e) => Outcome::Incomplete(maximum_weight, e), } } @@ -151,7 +151,7 @@ impl XcmExecutor { (origin, Xcm::Transact { origin_type, require_weight_at_most, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. - // TODO: #TRANSACTFILTER allow the trait to issue filters for the relay-chain + // TODO: #2841 #TRANSACTFILTER allow the trait to issue filters for the relay-chain let message_call = call.take_decoded().map_err(|_| XcmError::FailedToDecode)?; let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_type) .map_err(|_| XcmError::BadOrigin)?; diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs index b7363a1eea48..103b8eea3b86 100644 --- a/xcm/xcm-executor/src/traits/conversion.rs +++ b/xcm/xcm-executor/src/traits/conversion.rs @@ -17,14 +17,14 @@ use sp_std::result::Result; use xcm::v0::{MultiLocation, OriginKind}; -// TODO: #LOCCONV change to use Convert trait. +// TODO: #2841 #LOCCONV change to use Convert trait. /// Attempt to convert a location into some value of type `T`, or vice-versa. pub trait LocationConversion { /// Convert `location` into `Some` value of `T`, or `None` if not possible. - // TODO: #LOCCONV consider returning Result instead. + // TODO: #2841 #LOCCONV consider returning Result instead. fn from_location(location: &MultiLocation) -> Option; /// Convert some value `value` into a `location`, `Err`oring with the original `value` if not possible. - // TODO: #LOCCONV consider renaming `into_location` + // TODO: #2841 #LOCCONV consider renaming `into_location` fn try_into_location(value: T) -> Result; } From 92b4eb1eb2e16b97901f684b64206a2bbd4a96c2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 16:43:02 +0200 Subject: [PATCH 36/40] Fixes --- xcm/xcm-builder/src/fungibles_adapter.rs | 102 +--------------------- xcm/xcm-executor/src/lib.rs | 2 +- xcm/xcm-executor/src/traits/conversion.rs | 100 ++++++++++++++++++++- xcm/xcm-executor/src/traits/mod.rs | 2 +- 4 files changed, 103 insertions(+), 103 deletions(-) diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs index 014d6d833472..bcbc66ba859f 100644 --- a/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/xcm/xcm-builder/src/fungibles_adapter.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::{prelude::*, result, convert::TryFrom, marker::PhantomData, borrow::Borrow}; +use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow}; use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction}; use frame_support::traits::{Get, tokens::fungibles::Mutate as Fungibles}; -use xcm_executor::traits::{LocationConversion, TransactAsset}; +use xcm_executor::traits::{LocationConversion, TransactAsset, Convert}; /// Asset transaction errors. pub enum Error { @@ -45,104 +45,6 @@ impl From for XcmError { } } -/// Generic third-party conversion trait. Use this when you don't want to force the user to use default -/// impls of `From` and `Into` for the types you wish to convert between. -/// -/// One of `convert`/`convert_ref` and `reverse`/`reverse_ref` MUST be implemented. If possible, implement -/// `convert_ref`, since this will never result in a clone. Use `convert` when you definitely need to consume -/// the source value. -pub trait Convert { - /// Convert from `value` (of type `A`) into an equivalent value of type `B`, `Err` if not possible. - fn convert(value: A) -> result::Result { Self::convert_ref(&value).map_err(|_| value) } - fn convert_ref(value: impl Borrow) -> result::Result { - Self::convert(value.borrow().clone()).map_err(|_| ()) - } - /// Convert from `value` (of type `B`) into an equivalent value of type `A`, `Err` if not possible. - fn reverse(value: B) -> result::Result { Self::reverse_ref(&value).map_err(|_| value) } - fn reverse_ref(value: impl Borrow) -> result::Result { - Self::reverse(value.borrow().clone()).map_err(|_| ()) - } -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl Convert for Tuple { - fn convert(value: A) -> result::Result { - for_tuples!( #( - let value = match Tuple::convert(value) { - Ok(result) => return Ok(result), - Err(v) => v, - }; - )* ); - Err(value) - } - fn reverse(value: B) -> result::Result { - for_tuples!( #( - let value = match Tuple::reverse(value) { - Ok(result) => return Ok(result), - Err(v) => v, - }; - )* ); - Err(value) - } - fn convert_ref(value: impl Borrow) -> result::Result { - let value = value.borrow(); - for_tuples!( #( - match Tuple::convert_ref(value) { - Ok(result) => return Ok(result), - Err(_) => (), - } - )* ); - Err(()) - } - fn reverse_ref(value: impl Borrow) -> result::Result { - let value = value.borrow(); - for_tuples!( #( - match Tuple::reverse_ref(value.clone()) { - Ok(result) => return Ok(result), - Err(_) => (), - } - )* ); - Err(()) - } -} - -/// Simple pass-through which implements `BytesConversion` while not doing any conversion. -pub struct Identity; -impl Convert for Identity { - fn convert(value: T) -> result::Result { Ok(value) } - fn reverse(value: T) -> result::Result { Ok(value) } -} - -/// Implementation of `Convert` trait using `TryFrom`. -pub struct JustTry; -impl + Clone, Dest: TryFrom + Clone> Convert for JustTry { - fn convert(value: Source) -> result::Result { - Dest::try_from(value.clone()).map_err(|_| value) - } - fn reverse(value: Dest) -> result::Result { - Source::try_from(value.clone()).map_err(|_| value) - } -} - -use parity_scale_codec::{Encode, Decode}; -/// Implementation of `Convert<_, Vec>` using the parity scale codec. -pub struct Encoded; -impl Convert> for Encoded { - fn convert_ref(value: impl Borrow) -> result::Result, ()> { Ok(value.borrow().encode()) } - fn reverse_ref(bytes: impl Borrow>) -> result::Result { - T::decode(&mut &bytes.borrow()[..]).map_err(|_| ()) - } -} - -/// Implementation of `Convert, _>` using the parity scale codec. -pub struct Decoded; -impl Convert, T> for Decoded { - fn convert_ref(bytes: impl Borrow>) -> result::Result { - T::decode(&mut &bytes.borrow()[..]).map_err(|_| ()) - } - fn reverse_ref(value: impl Borrow) -> result::Result, ()> { Ok(value.borrow().encode()) } -} - /// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be TryFrom/TryInto) /// into a `GeneralIndex` junction, prefixed by some `MultiLocation` value. The `MultiLocation` value will /// typically be a `PalletInstance` junction. diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 9b56631ddd14..334e49fbd9ee 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -96,7 +96,7 @@ impl XcmExecutor { // The surplus weight, defined as the amount by which `shallow_weight` plus all nested // `shallow_weight` values (ensuring no double-counting) is an overestimate of the actual weight // consumed. - let mut total_surplus = 0; + let mut total_surplus: Weight = 0; let maybe_holding_effects = match (origin.clone(), message) { (origin, Xcm::WithdrawAsset { assets, effects }) => { diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs index 103b8eea3b86..0e0ef22c1637 100644 --- a/xcm/xcm-executor/src/traits/conversion.rs +++ b/xcm/xcm-executor/src/traits/conversion.rs @@ -14,9 +14,107 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::result::Result; +use sp_std::{prelude::*, result::Result, borrow::Borrow, convert::TryFrom}; +use parity_scale_codec::{Encode, Decode}; use xcm::v0::{MultiLocation, OriginKind}; +/// Generic third-party conversion trait. Use this when you don't want to force the user to use default +/// impls of `From` and `Into` for the types you wish to convert between. +/// +/// One of `convert`/`convert_ref` and `reverse`/`reverse_ref` MUST be implemented. If possible, implement +/// `convert_ref`, since this will never result in a clone. Use `convert` when you definitely need to consume +/// the source value. +pub trait Convert { + /// Convert from `value` (of type `A`) into an equivalent value of type `B`, `Err` if not possible. + fn convert(value: A) -> Result { Self::convert_ref(&value).map_err(|_| value) } + fn convert_ref(value: impl Borrow) -> Result { + Self::convert(value.borrow().clone()).map_err(|_| ()) + } + /// Convert from `value` (of type `B`) into an equivalent value of type `A`, `Err` if not possible. + fn reverse(value: B) -> Result { Self::reverse_ref(&value).map_err(|_| value) } + fn reverse_ref(value: impl Borrow) -> Result { + Self::reverse(value.borrow().clone()).map_err(|_| ()) + } +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl Convert for Tuple { + fn convert(value: A) -> Result { + for_tuples!( #( + let value = match Tuple::convert(value) { + Ok(result) => return Ok(result), + Err(v) => v, + }; + )* ); + Err(value) + } + fn reverse(value: B) -> Result { + for_tuples!( #( + let value = match Tuple::reverse(value) { + Ok(result) => return Ok(result), + Err(v) => v, + }; + )* ); + Err(value) + } + fn convert_ref(value: impl Borrow) -> Result { + let value = value.borrow(); + for_tuples!( #( + match Tuple::convert_ref(value) { + Ok(result) => return Ok(result), + Err(_) => (), + } + )* ); + Err(()) + } + fn reverse_ref(value: impl Borrow) -> Result { + let value = value.borrow(); + for_tuples!( #( + match Tuple::reverse_ref(value.clone()) { + Ok(result) => return Ok(result), + Err(_) => (), + } + )* ); + Err(()) + } +} + +/// Simple pass-through which implements `BytesConversion` while not doing any conversion. +pub struct Identity; +impl Convert for Identity { + fn convert(value: T) -> Result { Ok(value) } + fn reverse(value: T) -> Result { Ok(value) } +} + +/// Implementation of `Convert` trait using `TryFrom`. +pub struct JustTry; +impl + Clone, Dest: TryFrom + Clone> Convert for JustTry { + fn convert(value: Source) -> Result { + Dest::try_from(value.clone()).map_err(|_| value) + } + fn reverse(value: Dest) -> Result { + Source::try_from(value.clone()).map_err(|_| value) + } +} + +/// Implementation of `Convert<_, Vec>` using the parity scale codec. +pub struct Encoded; +impl Convert> for Encoded { + fn convert_ref(value: impl Borrow) -> Result, ()> { Ok(value.borrow().encode()) } + fn reverse_ref(bytes: impl Borrow>) -> Result { + T::decode(&mut &bytes.borrow()[..]).map_err(|_| ()) + } +} + +/// Implementation of `Convert, _>` using the parity scale codec. +pub struct Decoded; +impl Convert, T> for Decoded { + fn convert_ref(bytes: impl Borrow>) -> Result { + T::decode(&mut &bytes.borrow()[..]).map_err(|_| ()) + } + fn reverse_ref(value: impl Borrow) -> Result, ()> { Ok(value.borrow().encode()) } +} + // TODO: #2841 #LOCCONV change to use Convert trait. /// Attempt to convert a location into some value of type `T`, or vice-versa. pub trait LocationConversion { diff --git a/xcm/xcm-executor/src/traits/mod.rs b/xcm/xcm-executor/src/traits/mod.rs index 668255365a0c..f292819615a5 100644 --- a/xcm/xcm-executor/src/traits/mod.rs +++ b/xcm/xcm-executor/src/traits/mod.rs @@ -17,7 +17,7 @@ //! Various traits used in configuring the executor. mod conversion; -pub use conversion::{LocationConversion, InvertLocation, ConvertOrigin}; +pub use conversion::{LocationConversion, InvertLocation, ConvertOrigin, Convert, JustTry, Identity, Encoded, Decoded}; mod filter_asset_location; pub use filter_asset_location::{FilterAssetLocation}; mod matches_fungible; From ad6e55e34d9d0973d9e34ba9f3bb891ea93ad1e1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 17:15:28 +0200 Subject: [PATCH 37/40] Fixes --- runtime/parachains/src/ump.rs | 2 +- runtime/rococo/src/lib.rs | 2 +- xcm/xcm-builder/src/currency_adapter.rs | 14 +-- xcm/xcm-builder/src/fungibles_adapter.rs | 14 +-- xcm/xcm-builder/src/location_conversion.rs | 120 ++++++++++----------- xcm/xcm-builder/src/origin_conversion.rs | 8 +- xcm/xcm-executor/src/traits/conversion.rs | 27 ----- xcm/xcm-executor/src/traits/mod.rs | 2 +- 8 files changed, 78 insertions(+), 111 deletions(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 171bb0996dcb..5c40844af790 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -63,7 +63,7 @@ impl UmpSink for XcmSink { fn process_upward_message(origin: ParaId, msg: Vec) -> Weight { use parity_scale_codec::Decode; use xcm::VersionedXcm; - use xcm::v0::{Junction, MultiLocation, ExecuteXcm, Outcome}; + use xcm::v0::{Junction, MultiLocation, ExecuteXcm}; use xcm_executor::XcmExecutor; // TODO: #2841 #UMPQUEUE Get a proper weight limit here. Probably from Relay Chain Config diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 5c61cb7084c3..d194fd60d96a 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -81,11 +81,11 @@ pub use pallet_balances::Call as BalancesCall; use polkadot_parachain::primitives::Id as ParaId; use xcm::v0::{MultiLocation, NetworkId}; -use xcm_executor::{traits::IsConcrete, FixedWeightBounds, FixedRateOfConcreteFungible}; use xcm_builder::{ AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter, + IsConcrete, FixedWeightBounds, FixedRateOfConcreteFungible, }; use constants::{time::*, currency::*, fee::*}; use frame_support::traits::InstanceFilter; diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs index 259ea6354f7d..4b08398a2dfb 100644 --- a/xcm/xcm-builder/src/currency_adapter.rs +++ b/xcm/xcm-builder/src/currency_adapter.rs @@ -18,7 +18,7 @@ use sp_std::{result, convert::TryInto, marker::PhantomData}; use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation}; use sp_runtime::traits::SaturatedConversion; use frame_support::traits::{ExistenceRequirement::AllowDeath, WithdrawReasons}; -use xcm_executor::traits::{MatchesFungible, LocationConversion, TransactAsset}; +use xcm_executor::traits::{MatchesFungible, Convert, TransactAsset}; use xcm_executor::Assets; /// Asset transaction errors. @@ -49,9 +49,9 @@ pub struct CurrencyAdapter( impl< Matcher: MatchesFungible, - AccountIdConverter: LocationConversion, + AccountIdConverter: Convert, Currency: frame_support::traits::Currency, - AccountId, // can't get away without it since Currency is generic over it. + AccountId: Clone, // can't get away without it since Currency is generic over it. > TransactAsset for CurrencyAdapter { fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result { @@ -59,8 +59,8 @@ impl< let amount: u128 = Matcher::matches_fungible(&what) .ok_or(Error::AssetNotFound)? .saturated_into(); - let who = AccountIdConverter::from_location(who) - .ok_or(Error::AccountIdConversionFailed)?; + let who = AccountIdConverter::convert_ref(who) + .map_err(|()| Error::AccountIdConversionFailed)?; let balance_amount = amount .try_into() .map_err(|_| Error::AmountToBalanceConversionFailed)?; @@ -76,8 +76,8 @@ impl< let amount: u128 = Matcher::matches_fungible(what) .ok_or(Error::AssetNotFound)? .saturated_into(); - let who = AccountIdConverter::from_location(who) - .ok_or(Error::AccountIdConversionFailed)?; + let who = AccountIdConverter::convert_ref(who) + .map_err(|()| Error::AccountIdConversionFailed)?; let balance_amount = amount .try_into() .map_err(|_| Error::AmountToBalanceConversionFailed)?; diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs index bcbc66ba859f..cd975a927a9f 100644 --- a/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/xcm/xcm-builder/src/fungibles_adapter.rs @@ -17,7 +17,7 @@ use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow}; use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction}; use frame_support::traits::{Get, tokens::fungibles::Mutate as Fungibles}; -use xcm_executor::traits::{LocationConversion, TransactAsset, Convert}; +use xcm_executor::traits::{TransactAsset, Convert}; /// Asset transaction errors. pub enum Error { @@ -141,15 +141,15 @@ pub struct FungiblesAdapter( impl< Assets: Fungibles, Matcher: MatchesFungibles, - AccountIdConverter: LocationConversion, - AccountId, // can't get away without it since Currency is generic over it. + AccountIdConverter: Convert, + AccountId: Clone, // can't get away without it since Currency is generic over it. > TransactAsset for FungiblesAdapter { fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result { // Check we handle this asset. let (asset_id, amount) = Matcher::matches_fungibles(what)?; - let who = AccountIdConverter::from_location(who) - .ok_or(Error::AccountIdConversionFailed)?; + let who = AccountIdConverter::convert_ref(who) + .map_err(|()| Error::AccountIdConversionFailed)?; Assets::mint_into(asset_id, &who, amount) .map_err(|e| XcmError::FailedToTransactAsset(e.into())) } @@ -160,8 +160,8 @@ impl< ) -> result::Result { // Check we handle this asset. let (asset_id, amount) = Matcher::matches_fungibles(what)?; - let who = AccountIdConverter::from_location(who) - .ok_or(Error::AccountIdConversionFailed)?; + let who = AccountIdConverter::convert_ref(who) + .map_err(|()| Error::AccountIdConversionFailed)?; Assets::burn_from(asset_id, &who, amount) .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; Ok(what.clone().into()) diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs index 5f4af1fcf31c..938ebc66730d 100644 --- a/xcm/xcm-builder/src/location_conversion.rs +++ b/xcm/xcm-builder/src/location_conversion.rs @@ -14,70 +14,68 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::marker::PhantomData; +use sp_std::{marker::PhantomData, borrow::Borrow}; use sp_io::hashing::blake2_256; use sp_runtime::traits::AccountIdConversion; use frame_support::traits::Get; use parity_scale_codec::Encode; use xcm::v0::{MultiLocation, NetworkId, Junction}; -use xcm_executor::traits::{InvertLocation, LocationConversion}; +use xcm_executor::traits::{InvertLocation, Convert}; pub struct Account32Hash(PhantomData<(Network, AccountId)>); impl< Network: Get, - AccountId: From<[u8; 32]> + Into<[u8; 32]>, -> LocationConversion for Account32Hash { - fn from_location(location: &MultiLocation) -> Option { - Some(("multiloc", location).using_encoded(blake2_256).into()) + AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone, +> Convert for Account32Hash { + fn convert_ref(location: impl Borrow) -> Result { + Ok(("multiloc", location.borrow()).using_encoded(blake2_256).into()) } - fn try_into_location(who: AccountId) -> Result { - Err(who) + fn reverse_ref(_: impl Borrow) -> Result { + Err(()) } } pub struct ParentIsDefault(PhantomData); - impl< - AccountId: Default + Eq, -> LocationConversion for ParentIsDefault { - fn from_location(location: &MultiLocation) -> Option { - if let MultiLocation::X1(Junction::Parent) = location { - Some(AccountId::default()) + AccountId: Default + Eq + Clone, +> Convert for ParentIsDefault { + fn convert_ref(location: impl Borrow) -> Result { + if let &MultiLocation::X1(Junction::Parent) = location.borrow() { + Ok(AccountId::default()) } else { - None + Err(()) } } - fn try_into_location(who: AccountId) -> Result { - if who == AccountId::default() { + fn reverse_ref(who: impl Borrow) -> Result { + if who.borrow() == &AccountId::default() { Ok(Junction::Parent.into()) } else { - Err(who) + Err(()) } } } pub struct ChildParachainConvertsVia(PhantomData<(ParaId, AccountId)>); - impl< ParaId: From + Into + AccountIdConversion, - AccountId, -> LocationConversion for ChildParachainConvertsVia { - fn from_location(location: &MultiLocation) -> Option { - if let MultiLocation::X1(Junction::Parachain { id }) = location { - Some(ParaId::from(*id).into_account()) + AccountId: Clone, +> Convert for ChildParachainConvertsVia { + fn convert_ref(location: impl Borrow) -> Result { + if let &MultiLocation::X1(Junction::Parachain { id }) = location.borrow() { + Ok(ParaId::from(id).into_account()) } else { - None + Err(()) } } - fn try_into_location(who: AccountId) -> Result { - if let Some(id) = ParaId::try_from_account(&who) { + fn reverse_ref(who: impl Borrow) -> Result { + if let Some(id) = ParaId::try_from_account(who.borrow()) { Ok(Junction::Parachain { id: id.into() }.into()) } else { - Err(who) + Err(()) } } } @@ -86,41 +84,40 @@ pub struct SiblingParachainConvertsVia(PhantomData<(ParaId, A impl< ParaId: From + Into + AccountIdConversion, - AccountId, -> LocationConversion for SiblingParachainConvertsVia { - fn from_location(location: &MultiLocation) -> Option { - if let MultiLocation::X2(Junction::Parent, Junction::Parachain { id }) = location { - Some(ParaId::from(*id).into_account()) + AccountId: Clone, +> Convert for SiblingParachainConvertsVia { + fn convert_ref(location: impl Borrow) -> Result { + if let &MultiLocation::X2(Junction::Parent, Junction::Parachain { id }) = location.borrow() { + Ok(ParaId::from(id).into_account()) } else { - None + Err(()) } } - fn try_into_location(who: AccountId) -> Result { - if let Some(id) = ParaId::try_from_account(&who) { + fn reverse_ref(who: impl Borrow) -> Result { + if let Some(id) = ParaId::try_from_account(who.borrow()) { Ok([Junction::Parent, Junction::Parachain { id: id.into() }].into()) } else { - Err(who) + Err(()) } } } pub struct AccountId32Aliases(PhantomData<(Network, AccountId)>); - impl< Network: Get, - AccountId: From<[u8; 32]> + Into<[u8; 32]>, -> LocationConversion for AccountId32Aliases { - fn from_location(location: &MultiLocation) -> Option { - if let MultiLocation::X1(Junction::AccountId32 { id, network }) = location { - if matches!(network, NetworkId::Any) || network == &Network::get() { - return Some((*id).into()) - } - } - None + AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone, +> Convert for AccountId32Aliases { + fn convert(location: MultiLocation) -> Result { + let id = match location { + MultiLocation::X1(Junction::AccountId32 { id, network: NetworkId::Any }) => id, + MultiLocation::X1(Junction::AccountId32 { id, network }) if &network == &Network::get() => id, + l => return Err(l), + }; + Ok(id.into()) } - fn try_into_location(who: AccountId) -> Result { + fn reverse(who: AccountId) -> Result { Ok(Junction::AccountId32 { id: who.into(), network: Network::get() }.into()) } } @@ -128,23 +125,20 @@ impl< pub struct AccountKey20Aliases(PhantomData<(Network, AccountId)>); impl< Network: Get, - AccountId: From<[u8; 20]> + Into<[u8; 20]> -> LocationConversion for AccountKey20Aliases { - fn from_location(location: &MultiLocation) -> Option { - if let MultiLocation::X1(Junction::AccountKey20 { key, network }) = location { - if matches!(network, NetworkId::Any) || network == &Network::get() { - return Some((*key).into()); - } - } - None + AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone, +> Convert for AccountKey20Aliases { + fn convert(location: MultiLocation) -> Result { + let key = match location { + MultiLocation::X1(Junction::AccountKey20 { key, network: NetworkId::Any }) => key, + MultiLocation::X1(Junction::AccountKey20 { key, network }) if &network == &Network::get() => key, + l => return Err(l), + }; + Ok(key.into()) } - fn try_into_location(who: AccountId) -> Result { - Ok(Junction::AccountKey20 { - key: who.into(), - network: Network::get(), - } - .into()) + fn reverse(who: AccountId) -> Result { + let j = Junction::AccountKey20 { key: who.into(), network: Network::get() }; + Ok(j.into()) } } diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs index 3c8d05d54bf3..f7871b6bca76 100644 --- a/xcm/xcm-builder/src/origin_conversion.rs +++ b/xcm/xcm-builder/src/origin_conversion.rs @@ -17,7 +17,7 @@ use sp_std::marker::PhantomData; use frame_support::traits::{Get, OriginTrait}; use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction}; -use xcm_executor::traits::{LocationConversion, ConvertOrigin}; +use xcm_executor::traits::{Convert, ConvertOrigin}; use polkadot_parachain::primitives::IsSystem; /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the @@ -26,12 +26,12 @@ pub struct SovereignSignedViaLocation( PhantomData<(LocationConverter, Origin)> ); impl< - LocationConverter: LocationConversion, + LocationConverter: Convert, Origin: OriginTrait, -> ConvertOrigin for SovereignSignedViaLocation { +> ConvertOrigin for SovereignSignedViaLocation where Origin::AccountId: Clone { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { if let OriginKind::SovereignAccount = kind { - let location = LocationConverter::from_location(&origin).ok_or(origin)?; + let location = LocationConverter::convert(origin)?; Ok(Origin::signed(location).into()) } else { Err(origin) diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs index 0e0ef22c1637..6237571335bc 100644 --- a/xcm/xcm-executor/src/traits/conversion.rs +++ b/xcm/xcm-executor/src/traits/conversion.rs @@ -115,33 +115,6 @@ impl Convert, T> for Decoded { fn reverse_ref(value: impl Borrow) -> Result, ()> { Ok(value.borrow().encode()) } } -// TODO: #2841 #LOCCONV change to use Convert trait. -/// Attempt to convert a location into some value of type `T`, or vice-versa. -pub trait LocationConversion { - /// Convert `location` into `Some` value of `T`, or `None` if not possible. - // TODO: #2841 #LOCCONV consider returning Result instead. - fn from_location(location: &MultiLocation) -> Option; - /// Convert some value `value` into a `location`, `Err`oring with the original `value` if not possible. - // TODO: #2841 #LOCCONV consider renaming `into_location` - fn try_into_location(value: T) -> Result; -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl LocationConversion for Tuple { - fn from_location(location: &MultiLocation) -> Option { - for_tuples!( #( - if let Some(result) = Tuple::from_location(location) { return Some(result) } - )* ); - None - } - fn try_into_location(who: AccountId) -> Result { - for_tuples!( #( - let who = match Tuple::try_into_location(who) { Err(w) => w, r => return r }; - )* ); - Err(who) - } -} - pub trait ConvertOrigin { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result; } diff --git a/xcm/xcm-executor/src/traits/mod.rs b/xcm/xcm-executor/src/traits/mod.rs index f292819615a5..163e4f0f79d1 100644 --- a/xcm/xcm-executor/src/traits/mod.rs +++ b/xcm/xcm-executor/src/traits/mod.rs @@ -17,7 +17,7 @@ //! Various traits used in configuring the executor. mod conversion; -pub use conversion::{LocationConversion, InvertLocation, ConvertOrigin, Convert, JustTry, Identity, Encoded, Decoded}; +pub use conversion::{InvertLocation, ConvertOrigin, Convert, JustTry, Identity, Encoded, Decoded}; mod filter_asset_location; pub use filter_asset_location::{FilterAssetLocation}; mod matches_fungible; From 05716c9c2e9c558109cbb4d4361348bc4e1f81bf Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 17:40:30 +0200 Subject: [PATCH 38/40] Introduce transfer_asset specialisation. --- xcm/xcm-builder/src/fungibles_adapter.rs | 63 +++++++++++++++++-- xcm/xcm-executor/src/traits/transact_asset.rs | 23 ++++--- 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs index cd975a927a9f..adb865ea7086 100644 --- a/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/xcm/xcm-builder/src/fungibles_adapter.rs @@ -16,7 +16,7 @@ use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow}; use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction}; -use frame_support::traits::{Get, tokens::fungibles::Mutate as Fungibles}; +use frame_support::traits::{Get, tokens::fungibles}; use xcm_executor::traits::{TransactAsset, Convert}; /// Asset transaction errors. @@ -134,16 +134,41 @@ impl< } } -pub struct FungiblesAdapter( +pub struct FungiblesTransferAdapter( PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)> ); +impl< + Assets: fungibles::Transfer, + Matcher: MatchesFungibles, + AccountIdConverter: Convert, + AccountId: Clone, // can't get away without it since Currency is generic over it. +> TransactAsset for FungiblesTransferAdapter { + fn transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + ) -> result::Result { + // Check we handle this asset. + let (asset_id, amount) = Matcher::matches_fungibles(what)?; + let source = AccountIdConverter::convert_ref(from) + .map_err(|()| Error::AccountIdConversionFailed)?; + let dest = AccountIdConverter::convert_ref(to) + .map_err(|()| Error::AccountIdConversionFailed)?; + Assets::transfer(asset_id, &source, &dest, amount, true) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(what.clone().into()) + } +} +pub struct FungiblesMutateAdapter( + PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)> +); impl< - Assets: Fungibles, + Assets: fungibles::Mutate, Matcher: MatchesFungibles, AccountIdConverter: Convert, AccountId: Clone, // can't get away without it since Currency is generic over it. -> TransactAsset for FungiblesAdapter { +> TransactAsset for FungiblesMutateAdapter { fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result { // Check we handle this asset. @@ -166,6 +191,34 @@ impl< .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; Ok(what.clone().into()) } +} + +pub struct FungiblesAdapter( + PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)> +); +impl< + Assets: fungibles::Mutate + fungibles::Transfer, + Matcher: MatchesFungibles, + AccountIdConverter: Convert, + AccountId: Clone, // can't get away without it since Currency is generic over it. +> TransactAsset for FungiblesAdapter { + + fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result { + FungiblesMutateAdapter::::deposit_asset(what, who) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation + ) -> result::Result { + FungiblesMutateAdapter::::withdraw_asset(what, who) + } - // TODO: #2841 #XCMXFERASSET implement transfer_asset, but should move it into a different trait. + fn transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + ) -> result::Result { + FungiblesTransferAdapter::::transfer_asset(what, from, to) + } } diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs index 6a1e2bd497e4..83895234dfce 100644 --- a/xcm/xcm-executor/src/traits/transact_asset.rs +++ b/xcm/xcm-executor/src/traits/transact_asset.rs @@ -27,23 +27,23 @@ pub trait TransactAsset { /// Deposit the `what` asset into the account of `who`. /// /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. - fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> XcmResult; + fn deposit_asset(_what: &MultiAsset, _who: &MultiLocation) -> XcmResult { + Err(XcmError::Unimplemented) + } /// Withdraw the given asset from the consensus system. Return the actual asset(s) withdrawn. In /// the case of `what` being a wildcard, this may be something more specific. /// /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. - fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result; + fn withdraw_asset(_what: &MultiAsset, _who: &MultiLocation) -> Result { + Err(XcmError::Unimplemented) + } /// Move an `asset` `from` one location in `to` another location. /// /// Returns `XcmError::FailedToTransactAsset` if transfer failed. - fn transfer_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { - let withdrawn = Self::withdraw_asset(asset, from)?; - for asset in withdrawn.assets_iter() { - Self::deposit_asset(&asset, to)?; - } - Ok(withdrawn) + fn transfer_asset(_asset: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result { + Err(XcmError::Unimplemented) } } @@ -61,4 +61,11 @@ impl TransactAsset for Tuple { )* ); Err(XcmError::Unimplemented) } + fn transfer_asset(what: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { + for_tuples!( #( + match Tuple::transfer_asset(what, from, to) { o @ Ok(_) => return o, _ => () } + )* ); + Err(XcmError::Unimplemented) + } } + From 995bcb171819905aba7187867fdcfd543f4eb00a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 21:19:43 +0200 Subject: [PATCH 39/40] Fixes --- xcm/xcm-executor/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 334e49fbd9ee..02fab7da3240 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -132,7 +132,14 @@ impl XcmExecutor { let inv_dest = Config::LocationInverter::invert_location(&dest); for asset in assets.iter_mut() { ensure!(!asset.is_wildcard(), XcmError::Wildcard); - Config::AssetTransactor::transfer_asset(&asset, &origin, &dest)?; + match Config::AssetTransactor::transfer_asset(&asset, &origin, &dest) { + Err(XcmError::Unimplemented) => { + // Fallback to using withdraw + deposit. + Config::AssetTransactor::withdraw_asset(&asset, &origin)?; + Config::AssetTransactor::deposit_asset(&asset, &origin)?; + } + x => { x?; }, + } asset.reanchor(&inv_dest)?; } Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; From b082bd8dbe257c23f28cff3a63c485e39d545a12 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 7 Apr 2021 21:49:18 +0200 Subject: [PATCH 40/40] Fixes --- xcm/xcm-builder/src/mock.rs | 1 + xcm/xcm-executor/src/lib.rs | 11 ++--------- xcm/xcm-executor/src/traits/transact_asset.rs | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs index 47e9e156dc9f..e062c81062bb 100644 --- a/xcm/xcm-builder/src/mock.rs +++ b/xcm/xcm-builder/src/mock.rs @@ -140,6 +140,7 @@ impl TransactAsset for TestAssetTransactor { } } + pub fn to_account(l: MultiLocation) -> Result { Ok(match l { // Siblings at 2000+id diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index 02fab7da3240..885b7a78c47f 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -123,7 +123,7 @@ impl XcmExecutor { // Take `assets` from the origin account (on-chain) and place into dest account. for asset in assets { ensure!(!asset.is_wildcard(), XcmError::Wildcard); - Config::AssetTransactor::transfer_asset(&asset, &origin, &dest)?; + Config::AssetTransactor::teleport_asset(&asset, &origin, &dest)?; } None } @@ -132,14 +132,7 @@ impl XcmExecutor { let inv_dest = Config::LocationInverter::invert_location(&dest); for asset in assets.iter_mut() { ensure!(!asset.is_wildcard(), XcmError::Wildcard); - match Config::AssetTransactor::transfer_asset(&asset, &origin, &dest) { - Err(XcmError::Unimplemented) => { - // Fallback to using withdraw + deposit. - Config::AssetTransactor::withdraw_asset(&asset, &origin)?; - Config::AssetTransactor::deposit_asset(&asset, &origin)?; - } - x => { x?; }, - } + Config::AssetTransactor::teleport_asset(&asset, &origin, &dest)?; asset.reanchor(&inv_dest)?; } Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs index 83895234dfce..7e699425e3ee 100644 --- a/xcm/xcm-executor/src/traits/transact_asset.rs +++ b/xcm/xcm-executor/src/traits/transact_asset.rs @@ -45,6 +45,21 @@ pub trait TransactAsset { fn transfer_asset(_asset: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result { Err(XcmError::Unimplemented) } + + /// Move an `asset` `from` one location in `to` another location. + /// + /// Attempts to use `transfer_asset` and if not available then falls back to using a two-part withdraw/deposit. + fn teleport_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { + match Self::transfer_asset(asset, from, to) { + Err(XcmError::Unimplemented) => { + let assets = Self::withdraw_asset(asset, from)?; + // Not a very forgiving attitude; once we implement roll-backs then it'll be nicer. + Self::deposit_asset(asset, to)?; + Ok(assets) + } + result => result + } + } } #[impl_trait_for_tuples::impl_for_tuples(30)]