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

Make decoding of compact<perthing> saturating instead of invalid #7062

Merged
merged 4 commits into from
Sep 11, 2020
Merged
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
32 changes: 31 additions & 1 deletion primitives/arithmetic/src/per_things.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,28 @@ macro_rules! implement_per_thing {
///
#[doc = $title]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(Encode, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)]
#[derive(Encode, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)]
pub struct $name($type);

/// Implementation makes any compact encoding of `PerThing::Inner` valid,
/// when decoding it will saturate up to `PerThing::ACCURACY`.
impl CompactAs for $name {
type As = $type;
fn encode_as(&self) -> &Self::As {
&self.0
}
fn decode_from(x: Self::As) -> Self {
// Saturates if `x` is more than `$max` internally.
Self::from_parts(x)
gui1117 marked this conversation as resolved.
Show resolved Hide resolved
}
}

impl From<codec::Compact<$name>> for $name {
fn from(x: codec::Compact<$name>) -> $name {
x.0
}
}

impl PerThing for $name {
type Inner = $type;
type Upper = $upper_type;
Expand Down Expand Up @@ -1166,6 +1185,17 @@ macro_rules! implement_per_thing {
// deconstruct is also const, hence it can be called in const rhs.
const C5: bool = C1.deconstruct() == 0;
}

#[test]
fn compact_decoding_saturate_when_beyond_accuracy() {
use num_traits::Bounded;
use codec::Compact;

let p = Compact::<$name>::decode(&mut &Compact(<$type>::max_value()).encode()[..])
.unwrap();
assert_eq!((p.0).0, $max);
assert_eq!($name::from(p), $name::max_value());
}
}
};
}
Expand Down