Remove BoundedVec half-impls in xcm (#6636)

* Replace sp-core dependency with more primitive crates

* Remove BoundedVec half-impls in xcm

* Fixes

* Bump bounded-collections

* Address review comments

* Bump bounded-collections

* Fix benchmarks

* Fixes

* Fixes

* cargo fmt

* Fix tests

* Update url

* Bump url to 2.3.1

* Bump anyhow

* Use bounded-collections in pallet-xcm

* Update substrate
This commit is contained in:
Keith Yeung
2023-02-08 23:42:59 -03:00
committed by GitHub
parent 0ac0a24921
commit 7619fea80f
13 changed files with 233 additions and 264 deletions
+190 -189
View File
File diff suppressed because it is too large Load Diff
@@ -10,7 +10,7 @@ edition.workspace = true
[dependencies] [dependencies]
tokio = { version = "1.24.2", default-features = false, features = ["macros", "net", "rt-multi-thread", "sync"] } tokio = { version = "1.24.2", default-features = false, features = ["macros", "net", "rt-multi-thread", "sync"] }
url = "2.0.0" url = "2.3.1"
tokio-tungstenite = "0.17" tokio-tungstenite = "0.17"
futures-util = "0.3.23" futures-util = "0.3.23"
lazy_static = "1.4.0" lazy_static = "1.4.0"
+2 -2
View File
@@ -6,12 +6,12 @@ authors.workspace = true
edition.workspace = true edition.workspace = true
[dependencies] [dependencies]
bounded-collections = { version = "0.1.4", default-features = false }
derivative = { version = "2.2.0", default-features = false, features = [ "use_core" ] } derivative = { version = "2.2.0", default-features = false, features = [ "use_core" ] }
impl-trait-for-tuples = "0.2.2" impl-trait-for-tuples = "0.2.2"
log = { version = "0.4.17", default-features = false } log = { version = "0.4.17", default-features = false }
parity-scale-codec = { version = "3.3.0", default-features = false, features = [ "derive", "max-encoded-len" ] } parity-scale-codec = { version = "3.3.0", default-features = false, features = [ "derive", "max-encoded-len" ] }
scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } scale-info = { version = "2.1.2", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
serde = { version = "1.0.136", optional = true, features = ["derive"] } serde = { version = "1.0.136", optional = true, features = ["derive"] }
xcm-procedural = { path = "procedural" } xcm-procedural = { path = "procedural" }
@@ -23,9 +23,9 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
default = ["std"] default = ["std"]
wasm-api = [] wasm-api = []
std = [ std = [
"bounded-collections/std",
"parity-scale-codec/std", "parity-scale-codec/std",
"scale-info/std", "scale-info/std",
"serde", "serde",
"sp-core/std",
"sp-weights/std", "sp-weights/std",
] ]
@@ -21,7 +21,7 @@ use frame_benchmarking::{benchmarks, BenchmarkError};
use frame_support::dispatch::GetDispatchInfo; use frame_support::dispatch::GetDispatchInfo;
use sp_std::vec; use sp_std::vec;
use xcm::{ use xcm::{
latest::{prelude::*, MaybeErrorCode, Weight}, latest::{prelude::*, MaxDispatchErrorLen, MaybeErrorCode, Weight},
DoubleEncoded, DoubleEncoded,
}; };
use xcm_executor::{ExecutorError, FeesMode}; use xcm_executor::{ExecutorError, FeesMode};
@@ -360,9 +360,9 @@ benchmarks! {
expect_transact_status { expect_transact_status {
let mut executor = new_executor::<T>(Default::default()); let mut executor = new_executor::<T>(Default::default());
// 1024 is an overestimate but should be good enough until we have `max_encoded_len`. let worst_error = || -> MaybeErrorCode {
// Eventually it should be replaced by `DispatchError::max_encoded_len()`. vec![0; MaxDispatchErrorLen::get() as usize].into()
let worst_error = || MaybeErrorCode::Error(vec![0; 1024]); };
executor.set_transact_status(worst_error()); executor.set_transact_status(worst_error());
let instruction = Instruction::ExpectTransactStatus(worst_error()); let instruction = Instruction::ExpectTransactStatus(worst_error());
@@ -430,7 +430,7 @@ benchmarks! {
clear_transact_status { clear_transact_status {
let mut executor = new_executor::<T>(Default::default()); let mut executor = new_executor::<T>(Default::default());
executor.set_transact_status(MaybeErrorCode::Error(b"MyError".to_vec())); executor.set_transact_status(b"MyError".to_vec().into());
let instruction = Instruction::ClearTransactStatus; let instruction = Instruction::ClearTransactStatus;
let xcm = Xcm(vec![instruction]); let xcm = Xcm(vec![instruction]);
+2
View File
@@ -6,6 +6,7 @@ version.workspace = true
[dependencies] [dependencies]
bounded-collections = { version = "0.1.4", default-features = false }
codec = { package = "parity-scale-codec", version = "3.3.0", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.3.0", default-features = false, features = ["derive"] }
scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } scale-info = { version = "2.1.2", default-features = false, features = ["derive"] }
serde = { version = "1.0.137", optional = true, features = ["derive"] } serde = { version = "1.0.137", optional = true, features = ["derive"] }
@@ -31,6 +32,7 @@ xcm-builder = { path = "../xcm-builder" }
[features] [features]
default = ["std"] default = ["std"]
std = [ std = [
"bounded-collections/std",
"codec/std", "codec/std",
"scale-info/std", "scale-info/std",
"serde", "serde",
+1 -1
View File
@@ -15,10 +15,10 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use super::*; use super::*;
use bounded_collections::{ConstU32, WeakBoundedVec};
use frame_benchmarking::{benchmarks, BenchmarkError, BenchmarkResult}; use frame_benchmarking::{benchmarks, BenchmarkError, BenchmarkResult};
use frame_support::weights::Weight; use frame_support::weights::Weight;
use frame_system::RawOrigin; use frame_system::RawOrigin;
use sp_core::{bounded::WeakBoundedVec, ConstU32};
use sp_std::prelude::*; use sp_std::prelude::*;
use xcm::{latest::prelude::*, v2}; use xcm::{latest::prelude::*, v2};
+1 -1
View File
@@ -18,9 +18,9 @@
use super::{BodyId, BodyPart, Junctions, MultiLocation, NetworkId}; use super::{BodyId, BodyPart, Junctions, MultiLocation, NetworkId};
use crate::v3::Junction as NewJunction; use crate::v3::Junction as NewJunction;
use bounded_collections::{ConstU32, WeakBoundedVec};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo; use scale_info::TypeInfo;
use sp_core::{bounded::WeakBoundedVec, ConstU32};
/// A single item in a path to describe the relative location of a consensus system. /// A single item in a path to describe the relative location of a consensus system.
/// ///
+1 -1
View File
@@ -59,11 +59,11 @@ use super::{
DoubleEncoded, GetWeight, DoubleEncoded, GetWeight,
}; };
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec};
use bounded_collections::{ConstU32, WeakBoundedVec};
use core::{fmt::Debug, result}; use core::{fmt::Debug, result};
use derivative::Derivative; use derivative::Derivative;
use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo; use scale_info::TypeInfo;
use sp_core::{bounded::WeakBoundedVec, ConstU32};
mod junction; mod junction;
mod multiasset; mod multiasset;
+23 -58
View File
@@ -22,6 +22,7 @@ use super::v2::{
}; };
use crate::{DoubleEncoded, GetWeight}; use crate::{DoubleEncoded, GetWeight};
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec};
use bounded_collections::{parameter_types, BoundedVec};
use core::{ use core::{
convert::{TryFrom, TryInto}, convert::{TryFrom, TryInto},
fmt::Debug, fmt::Debug,
@@ -200,14 +201,20 @@ pub mod prelude {
} }
} }
#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] parameter_types! {
pub MaxPalletNameLen: u32 = 48;
/// Maximum size of the encoded error code coming from a `Dispatch` result, used for
/// `MaybeErrorCode`. This is not (yet) enforced, so it's just an indication of expectation.
pub MaxDispatchErrorLen: u32 = 128;
pub MaxPalletsInfo: u32 = 64;
}
#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
pub struct PalletInfo { pub struct PalletInfo {
#[codec(compact)] #[codec(compact)]
index: u32, index: u32,
// TODO: Change to `BoundedVec` so `MaxEncodedLen` derive will work. name: BoundedVec<u8, MaxPalletNameLen>,
name: Vec<u8>, module_name: BoundedVec<u8, MaxPalletNameLen>,
// TODO: Change to `BoundedVec` so `MaxEncodedLen` derive will work.
module_name: Vec<u8>,
#[codec(compact)] #[codec(compact)]
major: u32, major: u32,
#[codec(compact)] #[codec(compact)]
@@ -216,8 +223,6 @@ pub struct PalletInfo {
patch: u32, patch: u32,
} }
const MAX_NAME_LEN: usize = 48;
impl PalletInfo { impl PalletInfo {
pub fn new( pub fn new(
index: u32, index: u32,
@@ -227,44 +232,25 @@ impl PalletInfo {
minor: u32, minor: u32,
patch: u32, patch: u32,
) -> result::Result<Self, Error> { ) -> result::Result<Self, Error> {
if name.len() > MAX_NAME_LEN || module_name.len() > MAX_NAME_LEN { let name = BoundedVec::try_from(name).map_err(|_| Error::Overflow)?;
return Err(Error::Overflow) let module_name = BoundedVec::try_from(module_name).map_err(|_| Error::Overflow)?;
}
Ok(Self { index, name, module_name, major, minor, patch }) Ok(Self { index, name, module_name, major, minor, patch })
} }
} }
impl MaxEncodedLen for PalletInfo { #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
fn max_encoded_len() -> usize {
parity_scale_codec::Compact::<u32>::max_encoded_len() * 4 + (MAX_NAME_LEN + 1) * 2
}
}
#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)]
pub enum MaybeErrorCode { pub enum MaybeErrorCode {
Success, Success,
// TODO: Change to a `BoundedVec` so that deriving `MaxEncodedLen` works. Error(BoundedVec<u8, MaxDispatchErrorLen>),
Error(Vec<u8>), TruncatedError(BoundedVec<u8, MaxDispatchErrorLen>),
TruncatedError(Vec<u8>),
}
/// Maximum size of the encoded error code coming from a `Dispatch` result, used for
/// `MaybeErrorCode`. This is not (yet) enforced, so it's just an indication of expectation.
const MAX_DISPATCH_ERROR_LEN: usize = 128;
impl MaxEncodedLen for MaybeErrorCode {
fn max_encoded_len() -> usize {
MAX_DISPATCH_ERROR_LEN + 3
}
} }
impl From<Vec<u8>> for MaybeErrorCode { impl From<Vec<u8>> for MaybeErrorCode {
fn from(mut v: Vec<u8>) -> Self { fn from(v: Vec<u8>) -> Self {
if v.len() <= MAX_DISPATCH_ERROR_LEN { match BoundedVec::try_from(v) {
MaybeErrorCode::Error(v) Ok(error) => MaybeErrorCode::Error(error),
} else { Err(error) => MaybeErrorCode::TruncatedError(BoundedVec::truncate_from(error)),
v.truncate(MAX_DISPATCH_ERROR_LEN);
MaybeErrorCode::TruncatedError(v)
} }
} }
} }
@@ -275,26 +261,6 @@ impl Default for MaybeErrorCode {
} }
} }
/// Maximum number of pallets which we expect to be returned in `PalletsInfo`.
const MAX_PALLETS_INFO_LEN: usize = 64;
#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)]
pub struct VecPalletInfo(Vec<PalletInfo>);
impl TryFrom<Vec<PalletInfo>> for VecPalletInfo {
type Error = Error;
fn try_from(v: Vec<PalletInfo>) -> result::Result<Self, Error> {
if v.len() > MAX_PALLETS_INFO_LEN {
return Err(Error::Overflow)
}
Ok(VecPalletInfo(v))
}
}
impl MaxEncodedLen for VecPalletInfo {
fn max_encoded_len() -> usize {
PalletInfo::max_encoded_len() * MAX_PALLETS_INFO_LEN
}
}
/// Response data to a query. /// Response data to a query.
#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
pub enum Response { pub enum Response {
@@ -307,8 +273,7 @@ pub enum Response {
/// An XCM version. /// An XCM version.
Version(super::Version), Version(super::Version),
/// The index, instance name, pallet name and version of some pallets. /// The index, instance name, pallet name and version of some pallets.
// TODO: Change to a `BoundedVec` so that deriving `MaxEncodedLen` works. PalletsInfo(BoundedVec<PalletInfo, MaxPalletsInfo>),
PalletsInfo(VecPalletInfo),
/// The status of a dispatch attempt using `Transact`. /// The status of a dispatch attempt using `Transact`.
DispatchResult(MaybeErrorCode), DispatchResult(MaybeErrorCode),
} }
+1 -1
View File
@@ -24,7 +24,7 @@ log = { version = "0.4.17", default-features = false }
polkadot-parachain = { path = "../../parachain", default-features = false } polkadot-parachain = { path = "../../parachain", default-features = false }
[dev-dependencies] [dev-dependencies]
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } primitive-types = "0.12.1"
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-xcm = { path = "../pallet-xcm" } pallet-xcm = { path = "../pallet-xcm" }
polkadot-runtime-parachains = { path = "../../runtime/parachains" } polkadot-runtime-parachains = { path = "../../runtime/parachains" }
@@ -147,7 +147,7 @@ fn report_failed_transact_status_should_work() {
let r = XcmExecutor::<TestConfig>::execute_xcm(Parent, message, hash, weight_limit); let r = XcmExecutor::<TestConfig>::execute_xcm(Parent, message, hash, weight_limit);
assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70)));
let expected_msg = Xcm(vec![QueryResponse { let expected_msg = Xcm(vec![QueryResponse {
response: Response::DispatchResult(MaybeErrorCode::Error(vec![2])), response: Response::DispatchResult(vec![2].into()),
query_id: 42, query_id: 42,
max_weight: Weight::from_parts(5000, 5000), max_weight: Weight::from_parts(5000, 5000),
querier: Some(Here.into()), querier: Some(Here.into()),
@@ -197,7 +197,7 @@ fn expect_failed_transact_status_should_work() {
require_weight_at_most: Weight::from_parts(50, 50), require_weight_at_most: Weight::from_parts(50, 50),
call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(),
}, },
ExpectTransactStatus(MaybeErrorCode::Error(vec![2])), ExpectTransactStatus(vec![2].into()),
]); ]);
let hash = fake_message_hash(&message); let hash = fake_message_hash(&message);
let weight_limit = Weight::from_parts(70, 70); let weight_limit = Weight::from_parts(70, 70);
@@ -210,7 +210,7 @@ fn expect_failed_transact_status_should_work() {
require_weight_at_most: Weight::from_parts(50, 50), require_weight_at_most: Weight::from_parts(50, 50),
call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(),
}, },
ExpectTransactStatus(MaybeErrorCode::Error(vec![2])), ExpectTransactStatus(vec![2].into()),
]); ]);
let hash = fake_message_hash(&message); let hash = fake_message_hash(&message);
let weight_limit = Weight::from_parts(70, 70); let weight_limit = Weight::from_parts(70, 70);
+1 -1
View File
@@ -20,7 +20,7 @@ use frame_support::{
weights::Weight, weights::Weight,
}; };
use parity_scale_codec::Encode; use parity_scale_codec::Encode;
use sp_core::H256; use primitive_types::H256;
use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32}; use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
use sp_std::cell::RefCell; use sp_std::cell::RefCell;
+2 -1
View File
@@ -773,7 +773,8 @@ impl<Config: config::Config> XcmExecutor<Config> {
}) })
.collect::<Result<Vec<_>, XcmError>>()?; .collect::<Result<Vec<_>, XcmError>>()?;
let QueryResponseInfo { destination, query_id, max_weight } = response_info; let QueryResponseInfo { destination, query_id, max_weight } = response_info;
let response = Response::PalletsInfo(pallets.try_into()?); let response =
Response::PalletsInfo(pallets.try_into().map_err(|_| XcmError::Overflow)?);
let querier = Self::to_querier(self.cloned_origin(), &destination)?; let querier = Self::to_querier(self.cloned_origin(), &destination)?;
let instruction = QueryResponse { query_id, response, max_weight, querier }; let instruction = QueryResponse { query_id, response, max_weight, querier };
let message = Xcm(vec![instruction]); let message = Xcm(vec![instruction]);