From fad37b0c80bb015b8da91dbb66e294956679023d Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 9 Sep 2020 17:10:55 +0200 Subject: [PATCH 1/4] make decoding of cmopact saturating --- primitives/arithmetic/src/per_things.rs | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index cf53988b33d31..d7d45a1d77d86 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -323,9 +323,27 @@ 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 { + Self::from_parts(x) + } + } + + impl From> for $name { + fn from(x: codec::Compact<$name>) -> $name { + x.0 + } + } + impl PerThing for $name { type Inner = $type; type Upper = $upper_type; @@ -1166,6 +1184,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()); + } } }; } From fd0fc19bdb0103d1a1015fc8577f1b9a69773e7d Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 9 Sep 2020 18:06:02 +0200 Subject: [PATCH 2/4] fix stable build --- primitives/arithmetic/src/per_things.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index d7d45a1d77d86..66aa7a7b40278 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -1192,7 +1192,7 @@ macro_rules! implement_per_thing { let p = Compact::<$name>::decode(&mut &Compact(<$type>::max_value()).encode()[..]) .unwrap(); - assert_eq!(p.0.0, $max); + assert_eq!((p.0).0, $max); assert_eq!($name::from(p), $name::max_value()); } } From 6f45e2fc3d48f254305dacee3a6a25a045b41899 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 10 Sep 2020 14:02:11 +0200 Subject: [PATCH 3/4] Update primitives/arithmetic/src/per_things.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- primitives/arithmetic/src/per_things.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 66aa7a7b40278..e3e5b2751c8d2 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -327,7 +327,7 @@ macro_rules! implement_per_thing { pub struct $name($type); /// Implementation makes any compact encoding of `PerThing::Inner` valid, - /// when decoding it will saturate up to `PerThing::ACCURACY` + /// when decoding it will saturate up to `PerThing::ACCURACY`. impl CompactAs for $name { type As = $type; fn encode_as(&self) -> &Self::As { From c86c020819aa4a96c101d8d5917521e754f24c79 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 10 Sep 2020 14:02:21 +0200 Subject: [PATCH 4/4] Update primitives/arithmetic/src/per_things.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- primitives/arithmetic/src/per_things.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index e3e5b2751c8d2..035a704ba3009 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -334,6 +334,7 @@ macro_rules! implement_per_thing { &self.0 } fn decode_from(x: Self::As) -> Self { + // Saturates if `x` is more than `$max` internally. Self::from_parts(x) } }