From 98b2455326124e910da3196013a98a713b0cc4fe Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Tue, 3 Aug 2021 17:03:06 +0200 Subject: [PATCH] Refactor codec implementation for header (#9489) * add test * refactor --- .../primitives/runtime/src/generic/header.rs | 108 +++++++++++------- 1 file changed, 65 insertions(+), 43 deletions(-) diff --git a/substrate/primitives/runtime/src/generic/header.rs b/substrate/primitives/runtime/src/generic/header.rs index 07b7033707..d28f663db0 100644 --- a/substrate/primitives/runtime/src/generic/header.rs +++ b/substrate/primitives/runtime/src/generic/header.rs @@ -18,7 +18,7 @@ //! Generic implementation of a block header. use crate::{ - codec::{Codec, Decode, Encode, EncodeAsRef, Error, HasCompact, Input, Output}, + codec::{Codec, Decode, Encode}, generic::Digest, traits::{ self, AtLeast32BitUnsigned, Hash as HashT, MaybeDisplay, MaybeMallocSizeOf, MaybeSerialize, @@ -31,7 +31,7 @@ use sp_core::U256; use sp_std::{convert::TryFrom, fmt::Debug}; /// Abstraction over a block header for a substrate chain. -#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] +#[derive(Encode, Decode, PartialEq, Eq, Clone, sp_core::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] @@ -43,6 +43,7 @@ pub struct Header + TryFrom, Hash: HashT> { feature = "std", serde(serialize_with = "serialize_number", deserialize_with = "deserialize_number") )] + #[codec(compact)] pub number: Number, /// The state trie merkle root pub state_root: Hash::Output, @@ -89,47 +90,6 @@ where TryFrom::try_from(u256).map_err(|_| serde::de::Error::custom("Try from failed")) } -impl Decode for Header -where - Number: HasCompact + Copy + Into + TryFrom, - Hash: HashT, - Hash::Output: Decode, -{ - fn decode(input: &mut I) -> Result { - Ok(Self { - parent_hash: Decode::decode(input)?, - number: <::Type>::decode(input)?.into(), - state_root: Decode::decode(input)?, - extrinsics_root: Decode::decode(input)?, - digest: Decode::decode(input)?, - }) - } -} - -impl Encode for Header -where - Number: HasCompact + Copy + Into + TryFrom, - Hash: HashT, - Hash::Output: Encode, -{ - fn encode_to(&self, dest: &mut T) { - self.parent_hash.encode_to(dest); - <<::Type as EncodeAsRef<_>>::RefType>::from(&self.number) - .encode_to(dest); - self.state_root.encode_to(dest); - self.extrinsics_root.encode_to(dest); - self.digest.encode_to(dest); - } -} - -impl codec::EncodeLike for Header -where - Number: HasCompact + Copy + Into + TryFrom, - Hash: HashT, - Hash::Output: Encode, -{ -} - impl traits::Header for Header where Number: Member @@ -234,6 +194,7 @@ where #[cfg(all(test, feature = "std"))] mod tests { use super::*; + use crate::traits::BlakeTwo256; #[test] fn should_serialize_numbers() { @@ -264,4 +225,65 @@ mod tests { assert_eq!(deserialize("\"0xffffffffffffffff\""), u64::MAX as u128); assert_eq!(deserialize("\"0x10000000000000000\""), u64::MAX as u128 + 1); } + + #[test] + fn ensure_format_is_unchanged() { + let header = Header:: { + parent_hash: BlakeTwo256::hash(b"1"), + number: 2, + state_root: BlakeTwo256::hash(b"3"), + extrinsics_root: BlakeTwo256::hash(b"4"), + digest: crate::generic::Digest { + logs: vec![ + crate::generic::DigestItem::ChangesTrieRoot(BlakeTwo256::hash(b"5")), + crate::generic::DigestItem::Other(b"6".to_vec()), + ], + }, + }; + + let header_encoded = header.encode(); + assert_eq!( + header_encoded, + vec![ + 146, 205, 245, 120, 196, 112, 133, 165, 153, 34, 86, 240, 220, 249, 125, 11, 25, + 241, 241, 201, 222, 77, 95, 227, 12, 58, 206, 97, 145, 182, 229, 219, 8, 88, 19, + 72, 51, 123, 15, 62, 20, 134, 32, 23, 61, 170, 165, 249, 77, 0, 216, 129, 112, 93, + 203, 240, 170, 131, 239, 218, 186, 97, 210, 237, 225, 235, 134, 73, 33, 73, 151, + 87, 78, 32, 196, 100, 56, 138, 23, 36, 32, 210, 84, 3, 104, 43, 187, 184, 12, 73, + 104, 49, 200, 204, 31, 143, 13, 8, 2, 112, 178, 1, 53, 47, 36, 191, 28, 151, 112, + 185, 159, 143, 113, 32, 24, 33, 65, 28, 244, 20, 55, 124, 155, 140, 45, 188, 238, + 97, 219, 135, 214, 0, 4, 54 + ], + ); + assert_eq!(header, Header::::decode(&mut &header_encoded[..]).unwrap()); + + let header = Header:: { + parent_hash: BlakeTwo256::hash(b"1000"), + number: 2000, + state_root: BlakeTwo256::hash(b"3000"), + extrinsics_root: BlakeTwo256::hash(b"4000"), + digest: crate::generic::Digest { + logs: vec![ + crate::generic::DigestItem::Other(b"5000".to_vec()), + crate::generic::DigestItem::ChangesTrieRoot(BlakeTwo256::hash(b"6000")), + ], + }, + }; + + let header_encoded = header.encode(); + assert_eq!( + header_encoded, + vec![ + 197, 243, 254, 225, 31, 117, 21, 218, 179, 213, 92, 6, 247, 164, 230, 25, 47, 166, + 140, 117, 142, 159, 195, 202, 67, 196, 238, 26, 44, 18, 33, 92, 65, 31, 219, 225, + 47, 12, 107, 88, 153, 146, 55, 21, 226, 186, 110, 48, 167, 187, 67, 183, 228, 232, + 118, 136, 30, 254, 11, 87, 48, 112, 7, 97, 31, 82, 146, 110, 96, 87, 152, 68, 98, + 162, 227, 222, 78, 14, 244, 194, 120, 154, 112, 97, 222, 144, 174, 101, 220, 44, + 111, 126, 54, 34, 155, 220, 253, 124, 8, 0, 16, 53, 48, 48, 48, 2, 42, 105, 109, + 150, 206, 223, 24, 44, 164, 77, 27, 137, 177, 220, 25, 170, 140, 35, 156, 246, 233, + 112, 26, 23, 192, 61, 226, 14, 84, 219, 144, 252 + ], + ); + assert_eq!(header, Header::::decode(&mut &header_encoded[..]).unwrap()); + } }