Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add environmental variable to track decoded instructions #1320

Merged
merged 7 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions polkadot/xcm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ scale-info = { version = "2.5.0", default-features = false, features = ["derive"
sp-weights = { path = "../../substrate/primitives/weights", default-features = false, features = ["serde"] }
serde = { version = "1.0.188", default-features = false, features = ["alloc", "derive"] }
xcm-procedural = { path = "procedural" }
environmental = { version = "1.1.4", default-features = false }

[dev-dependencies]
sp-io = { path = "../../substrate/primitives/io" }
Expand All @@ -27,6 +28,7 @@ default = [ "std" ]
wasm-api = []
std = [
"bounded-collections/std",
"environmental/std",
"parity-scale-codec/std",
"scale-info/std",
"serde/std",
Expand Down
3 changes: 2 additions & 1 deletion polkadot/xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
// necessarily related to FRAME or even Substrate.
//
// Hence, `no_std` rather than sp-runtime.
#![no_std]
#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

use derivative::Derivative;
Expand Down
12 changes: 6 additions & 6 deletions polkadot/xcm/src/v2/multilocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// # fn main() {
/// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild));
/// assert_eq!(
Expand All @@ -260,7 +260,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// let m = MultiLocation::new(1, X3(PalletInstance(3), OnlyChild, OnlyChild));
/// assert!(m.starts_with(&MultiLocation::new(1, X1(PalletInstance(3)))));
/// assert!(!m.starts_with(&MultiLocation::new(1, X1(GeneralIndex(99)))));
Expand All @@ -279,7 +279,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// # fn main() {
/// let mut m = MultiLocation::new(1, X1(Parachain(21)));
/// assert_eq!(m.append_with(X1(PalletInstance(3))), Ok(()));
Expand All @@ -302,7 +302,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation};
/// # fn main() {
/// let mut m = MultiLocation::new(2, X1(PalletInstance(3)));
/// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild))), Ok(()));
Expand Down Expand Up @@ -839,7 +839,7 @@ impl Junctions {
///
/// # Example
/// ```rust
/// # use xcm::v2::{Junctions::*, Junction::*};
/// # use staging_xcm::v2::{Junctions::*, Junction::*};
/// # fn main() {
/// let mut m = X3(Parachain(2), PalletInstance(3), OnlyChild);
/// assert_eq!(m.match_and_split(&X2(Parachain(2), PalletInstance(3))), Some(&OnlyChild));
Expand All @@ -857,7 +857,7 @@ impl Junctions {
///
/// # Example
/// ```rust
/// # use xcm::v2::{Junctions::*, Junction::*};
/// # use staging_xcm::v2::{Junctions::*, Junction::*};
/// let mut j = X3(Parachain(2), PalletInstance(3), OnlyChild);
/// assert!(j.starts_with(&X2(Parachain(2), PalletInstance(3))));
/// assert!(j.starts_with(&j));
Expand Down
2 changes: 1 addition & 1 deletion polkadot/xcm/src/v2/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ pub type SendResult = result::Result<(), SendError>;
///
/// # Example
/// ```rust
/// # use xcm::v2::prelude::*;
/// # use staging_xcm::v2::prelude::*;
/// # use parity_scale_codec::Encode;
///
/// /// A sender that only passes the message through and does nothing.
Expand Down
4 changes: 2 additions & 2 deletions polkadot/xcm/src/v3/junctions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ impl Junctions {
///
/// # Example
/// ```rust
/// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation};
/// # use staging_xcm::v3::{Junctions::*, Junction::*, MultiLocation};
/// # fn main() {
/// let mut m = X1(Parachain(21));
/// assert_eq!(m.append_with(X1(PalletInstance(3))), Ok(()));
Expand Down Expand Up @@ -568,7 +568,7 @@ impl Junctions {
///
/// # Example
/// ```rust
/// # use xcm::v3::{Junctions::*, Junction::*};
/// # use staging_xcm::v3::{Junctions::*, Junction::*};
/// # fn main() {
/// let mut m = X3(Parachain(2), PalletInstance(3), OnlyChild);
/// assert_eq!(m.match_and_split(&X2(Parachain(2), PalletInstance(3))), Some(&OnlyChild));
Expand Down
61 changes: 45 additions & 16 deletions polkadot/xcm/src/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ use super::v2::{
};
use crate::{DoubleEncoded, GetWeight};
use alloc::{vec, vec::Vec};
use bounded_collections::{parameter_types, BoundedVec, ConstU32};
use bounded_collections::{parameter_types, BoundedVec};
use core::{
convert::{TryFrom, TryInto},
fmt::Debug,
result,
};
use derivative::Derivative;
use parity_scale_codec::{
self, Decode, Encode, Error as CodecError, Input as CodecInput, MaxEncodedLen,
self, decode_vec_with_len, Compact, Decode, Encode, Error as CodecError, Input as CodecInput,
MaxEncodedLen,
};
use scale_info::TypeInfo;

Expand Down Expand Up @@ -69,13 +70,25 @@ pub type QueryId = u64;
#[scale_info(bounds(), skip_type_params(Call))]
pub struct Xcm<Call>(pub Vec<Instruction<Call>>);

const MAX_INSTRUCTIONS_TO_DECODE: u32 = 100;
const MAX_INSTRUCTIONS_TO_DECODE: u8 = 100;

environmental::environmental!(instructions_count: u8);

impl<Call> Decode for Xcm<Call> {
fn decode<I: CodecInput>(input: &mut I) -> core::result::Result<Self, CodecError> {
let bounded_instructions =
BoundedVec::<Instruction<Call>, ConstU32<MAX_INSTRUCTIONS_TO_DECODE>>::decode(input)?;
Ok(Self(bounded_instructions.into_inner()))
instructions_count::using_once(&mut 0, || {
let number_of_instructions: u32 = <Compact<u32>>::decode(input)?.into();
instructions_count::with(|count| {
*count = count.saturating_add(number_of_instructions as u8);
if *count > MAX_INSTRUCTIONS_TO_DECODE {
return Err(CodecError::from("Max instructions exceeded"))
}
Ok(())
})
.unwrap_or(Ok(()))?;
let decoded_instructions = decode_vec_with_len(input, number_of_instructions as usize)?;
Ok(Self(decoded_instructions))
})
}
}

Expand Down Expand Up @@ -1440,15 +1453,31 @@ mod tests {
}

#[test]
fn decoding_fails_when_too_many_instructions() {
let small_xcm = Xcm::<()>(vec![ClearOrigin; 20]);
let bytes = small_xcm.encode();
let decoded_xcm = Xcm::<()>::decode(&mut &bytes[..]);
assert!(matches!(decoded_xcm, Ok(_)));

let big_xcm = Xcm::<()>(vec![ClearOrigin; 64_000]);
let bytes = big_xcm.encode();
let decoded_xcm = Xcm::<()>::decode(&mut &bytes[..]);
assert!(matches!(decoded_xcm, Err(CodecError { .. })));
fn decoding_respects_limit() {
let max_xcm = Xcm::<()>(vec![ClearOrigin; MAX_INSTRUCTIONS_TO_DECODE as usize]);
let encoded = max_xcm.encode();
assert!(Xcm::<()>::decode(&mut &encoded[..]).is_ok());

let big_xcm = Xcm::<()>(vec![ClearOrigin; MAX_INSTRUCTIONS_TO_DECODE as usize + 1]);
let encoded = big_xcm.encode();
assert!(Xcm::<()>::decode(&mut &encoded[..]).is_err());

let nested_xcm = Xcm::<()>(vec![
DepositReserveAsset {
assets: All.into(),
dest: Here.into(),
xcm: max_xcm,
};
(MAX_INSTRUCTIONS_TO_DECODE / 2) as usize
]);
let encoded = nested_xcm.encode();
assert!(Xcm::<()>::decode(&mut &encoded[..]).is_err());

let even_more_nested_xcm = Xcm::<()>(vec![SetAppendix(nested_xcm); 64]);
let encoded = even_more_nested_xcm.encode();
assert_eq!(encoded.len(), 342530);
// This should not decode since the limit is 100
assert_eq!(MAX_INSTRUCTIONS_TO_DECODE, 100, "precondition");
assert!(Xcm::<()>::decode(&mut &encoded[..]).is_err());
}
franciscoaguirre marked this conversation as resolved.
Show resolved Hide resolved
}
10 changes: 5 additions & 5 deletions polkadot/xcm/src/v3/multilocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation};
/// # use staging_xcm::v3::{Junctions::*, Junction::*, MultiLocation};
/// # fn main() {
/// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild));
/// assert_eq!(
Expand All @@ -292,7 +292,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # use staging_xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # fn main() {
/// let mut m: MultiLocation = (Parent, Parachain(21), 69u64).into();
/// assert_eq!(m.append_with((Parent, PalletInstance(3))), Ok(()));
Expand All @@ -313,7 +313,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # use staging_xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # fn main() {
/// let mut m: MultiLocation = (Parent, Parachain(21), 69u64).into();
/// let r = m.appended_with((Parent, PalletInstance(3))).unwrap();
Expand All @@ -333,7 +333,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # use staging_xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # fn main() {
/// let mut m: MultiLocation = (Parent, Parent, PalletInstance(3)).into();
/// assert_eq!(m.prepend_with((Parent, Parachain(21), OnlyChild)), Ok(()));
Expand Down Expand Up @@ -382,7 +382,7 @@ impl MultiLocation {
///
/// # Example
/// ```rust
/// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # use staging_xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent};
/// # fn main() {
/// let m: MultiLocation = (Parent, Parent, PalletInstance(3)).into();
/// let r = m.prepended_with((Parent, Parachain(21), OnlyChild)).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions polkadot/xcm/src/v3/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,8 @@ pub type SendResult<T> = result::Result<(T, MultiAssets), SendError>;
/// # Example
/// ```rust
/// # use parity_scale_codec::Encode;
/// # use xcm::v3::{prelude::*, Weight};
/// # use xcm::VersionedXcm;
/// # use staging_xcm::v3::{prelude::*, Weight};
/// # use staging_xcm::VersionedXcm;
/// # use std::convert::Infallible;
///
/// /// A sender that only passes the message through and does nothing.
Expand Down
2 changes: 1 addition & 1 deletion polkadot/xcm/xcm-builder/src/currency_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl From<Error> for XcmError {
/// use frame_support::{parameter_types, PalletId};
/// use sp_runtime::traits::{AccountIdConversion, TrailingZeroInput};
/// use xcm::latest::prelude::*;
/// use xcm_builder::{ParentIsPreset, CurrencyAdapter, IsConcrete};
/// use staging_xcm_builder::{ParentIsPreset, CurrencyAdapter, IsConcrete};
///
/// /// Our chain's account id.
/// type AccountId = sp_runtime::AccountId32;
Expand Down
2 changes: 1 addition & 1 deletion polkadot/xcm/xcm-builder/src/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl<'a, Call> CreateMatcher for &'a mut [Instruction<Call>] {
/// ```rust
/// use frame_support::traits::ProcessMessageError;
/// use xcm::latest::Instruction;
/// use xcm_builder::{CreateMatcher, MatchXcm};
/// use staging_xcm_builder::{CreateMatcher, MatchXcm};
///
/// let mut msg = [Instruction::<()>::ClearOrigin];
/// let res = msg
Expand Down
4 changes: 2 additions & 2 deletions polkadot/xcm/xcm-builder/src/matches_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use xcm_executor::traits::{MatchesFungible, MatchesNonFungible};
///
/// ```
/// use xcm::latest::{MultiLocation, Parent};
/// use xcm_builder::IsConcrete;
/// use staging_xcm_builder::IsConcrete;
/// use xcm_executor::traits::MatchesFungible;
///
/// frame_support::parameter_types! {
Expand Down Expand Up @@ -71,7 +71,7 @@ impl<T: Get<MultiLocation>, I: TryFrom<AssetInstance>> MatchesNonFungible<I> for
///
/// ```
/// use xcm::latest::prelude::*;
/// use xcm_builder::IsAbstract;
/// use staging_xcm_builder::IsAbstract;
/// use xcm_executor::traits::{MatchesFungible, MatchesNonFungible};
///
/// frame_support::parameter_types! {
Expand Down
2 changes: 1 addition & 1 deletion polkadot/xcm/xcm-executor/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ impl Assets {
/// Example:
///
/// ```
/// use xcm_executor::Assets;
/// use staging_xcm_executor::Assets;
/// use xcm::latest::prelude::*;
/// let assets_i_have: Assets = vec![ (Here, 100).into(), ([0; 32], 100).into() ].into();
/// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), ([0; 32], 50).into() ].into();
Expand Down
2 changes: 1 addition & 1 deletion polkadot/xcm/xcm-executor/src/traits/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<AccountId> ConvertLocation<AccountId> for Tuple {
///
/// ```rust
/// # use xcm::latest::{MultiLocation, Junctions, Junction, OriginKind};
/// # use xcm_executor::traits::ConvertOrigin;
/// # use staging_xcm_executor::traits::ConvertOrigin;
/// // A convertor that will bump the para id and pass it to the next one.
/// struct BumpParaId;
/// impl ConvertOrigin<u32> for BumpParaId {
Expand Down