Skip to content

Commit

Permalink
Add instruction limit when decoding XCMs (#1227)
Browse files Browse the repository at this point in the history
* Add instruction limit when decoding XCMs

* Make the instruction limit a constant

* Use vec for buffer

* ".git/.scripts/commands/fmt/fmt.sh"

* Go back on std

* Use BoundedVec's Decode implementation

* ".git/.scripts/commands/fmt/fmt.sh"

* Use an actual BoundedVec to decode XCMs

* Change comment location

* ".git/.scripts/commands/fmt/fmt.sh"

* Remove unused imports

* ".git/.scripts/commands/fmt/fmt.sh"

---------

Co-authored-by: command-bot <>
  • Loading branch information
franciscoaguirre authored and Daanvdplas committed Sep 11, 2023
1 parent d711697 commit 8fae92c
Showing 1 changed file with 29 additions and 4 deletions.
33 changes: 29 additions & 4 deletions polkadot/xcm/src/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ use super::v2::{
};
use crate::{DoubleEncoded, GetWeight};
use alloc::{vec, vec::Vec};
use bounded_collections::{parameter_types, BoundedVec};
use bounded_collections::{parameter_types, BoundedVec, ConstU32};
use core::{
convert::{TryFrom, TryInto},
fmt::Debug,
result,
};
use derivative::Derivative;
use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen};
use parity_scale_codec::{
self, Decode, Encode, Error as CodecError, Input as CodecInput, MaxEncodedLen,
};
use scale_info::TypeInfo;

mod junction;
Expand Down Expand Up @@ -60,13 +62,23 @@ pub const VERSION: super::Version = 3;
/// An identifier for a query.
pub type QueryId = u64;

#[derive(Derivative, Default, Encode, Decode, TypeInfo)]
// TODO (v4): Use `BoundedVec` instead of `Vec`
#[derive(Derivative, Default, Encode, TypeInfo)]
#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
#[codec(encode_bound())]
#[codec(decode_bound())]
#[scale_info(bounds(), skip_type_params(Call))]
pub struct Xcm<Call>(pub Vec<Instruction<Call>>);

const MAX_INSTRUCTIONS_TO_DECODE: u32 = 100;

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()))
}
}

impl<Call> Xcm<Call> {
/// Create an empty instance.
pub fn new() -> Self {
Expand Down Expand Up @@ -1426,4 +1438,17 @@ mod tests {
let new_xcm: Xcm<()> = old_xcm.try_into().unwrap();
assert_eq!(new_xcm, xcm);
}

#[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 { .. })));
}
}

0 comments on commit 8fae92c

Please sign in to comment.