sp_runtime/generic/
header.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Generic implementation of a block header.
19
20use crate::{
21	codec::{Codec, Decode, Encode},
22	generic::Digest,
23	scale_info::TypeInfo,
24	traits::{self, AtLeast32BitUnsigned, BlockNumber, Hash as HashT, MaybeDisplay, Member},
25};
26#[cfg(feature = "serde")]
27use serde::{Deserialize, Serialize};
28use sp_core::U256;
29
30/// Abstraction over a block header for a substrate chain.
31#[derive(Encode, Decode, PartialEq, Eq, Clone, sp_core::RuntimeDebug, TypeInfo)]
32#[scale_info(skip_type_params(Hash))]
33#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
34#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
35#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
36pub struct Header<Number: Copy + Into<U256> + TryFrom<U256>, Hash: HashT> {
37	/// The parent hash.
38	pub parent_hash: Hash::Output,
39	/// The block number.
40	#[cfg_attr(
41		feature = "serde",
42		serde(serialize_with = "serialize_number", deserialize_with = "deserialize_number")
43	)]
44	#[codec(compact)]
45	pub number: Number,
46	/// The state trie merkle root
47	pub state_root: Hash::Output,
48	/// The merkle root of the extrinsics.
49	pub extrinsics_root: Hash::Output,
50	/// A chain-specific digest of data useful for light clients or referencing auxiliary data.
51	pub digest: Digest,
52}
53
54#[cfg(feature = "serde")]
55pub fn serialize_number<S, T: Copy + Into<U256> + TryFrom<U256>>(
56	val: &T,
57	s: S,
58) -> Result<S::Ok, S::Error>
59where
60	S: serde::Serializer,
61{
62	let u256: U256 = (*val).into();
63	serde::Serialize::serialize(&u256, s)
64}
65
66#[cfg(feature = "serde")]
67pub fn deserialize_number<'a, D, T: Copy + Into<U256> + TryFrom<U256>>(d: D) -> Result<T, D::Error>
68where
69	D: serde::Deserializer<'a>,
70{
71	let u256: U256 = serde::Deserialize::deserialize(d)?;
72	TryFrom::try_from(u256).map_err(|_| serde::de::Error::custom("Try from failed"))
73}
74
75impl<Number, Hash> traits::Header for Header<Number, Hash>
76where
77	Number: BlockNumber,
78	Hash: HashT,
79{
80	type Number = Number;
81	type Hash = <Hash as HashT>::Output;
82	type Hashing = Hash;
83
84	fn new(
85		number: Self::Number,
86		extrinsics_root: Self::Hash,
87		state_root: Self::Hash,
88		parent_hash: Self::Hash,
89		digest: Digest,
90	) -> Self {
91		Self { number, extrinsics_root, state_root, parent_hash, digest }
92	}
93	fn number(&self) -> &Self::Number {
94		&self.number
95	}
96
97	fn set_number(&mut self, num: Self::Number) {
98		self.number = num
99	}
100	fn extrinsics_root(&self) -> &Self::Hash {
101		&self.extrinsics_root
102	}
103
104	fn set_extrinsics_root(&mut self, root: Self::Hash) {
105		self.extrinsics_root = root
106	}
107	fn state_root(&self) -> &Self::Hash {
108		&self.state_root
109	}
110
111	fn set_state_root(&mut self, root: Self::Hash) {
112		self.state_root = root
113	}
114	fn parent_hash(&self) -> &Self::Hash {
115		&self.parent_hash
116	}
117
118	fn set_parent_hash(&mut self, hash: Self::Hash) {
119		self.parent_hash = hash
120	}
121
122	fn digest(&self) -> &Digest {
123		&self.digest
124	}
125
126	fn digest_mut(&mut self) -> &mut Digest {
127		#[cfg(feature = "std")]
128		log::debug!(target: "header", "Retrieving mutable reference to digest");
129		&mut self.digest
130	}
131}
132
133impl<Number, Hash> Header<Number, Hash>
134where
135	Number: Member
136		+ core::hash::Hash
137		+ Copy
138		+ MaybeDisplay
139		+ AtLeast32BitUnsigned
140		+ Codec
141		+ Into<U256>
142		+ TryFrom<U256>,
143	Hash: HashT,
144{
145	/// Convenience helper for computing the hash of the header without having
146	/// to import the trait.
147	pub fn hash(&self) -> Hash::Output {
148		Hash::hash_of(self)
149	}
150}
151
152#[cfg(all(test, feature = "std"))]
153mod tests {
154	use super::*;
155	use crate::traits::BlakeTwo256;
156
157	#[test]
158	fn should_serialize_numbers() {
159		fn serialize(num: u128) -> String {
160			let mut v = vec![];
161			{
162				let mut ser = serde_json::Serializer::new(std::io::Cursor::new(&mut v));
163				serialize_number(&num, &mut ser).unwrap();
164			}
165			String::from_utf8(v).unwrap()
166		}
167
168		assert_eq!(serialize(0), "\"0x0\"".to_owned());
169		assert_eq!(serialize(1), "\"0x1\"".to_owned());
170		assert_eq!(serialize(u64::MAX as u128), "\"0xffffffffffffffff\"".to_owned());
171		assert_eq!(serialize(u64::MAX as u128 + 1), "\"0x10000000000000000\"".to_owned());
172	}
173
174	#[test]
175	fn should_deserialize_number() {
176		fn deserialize(num: &str) -> u128 {
177			let mut der = serde_json::Deserializer::new(serde_json::de::StrRead::new(num));
178			deserialize_number(&mut der).unwrap()
179		}
180
181		assert_eq!(deserialize("\"0x0\""), 0);
182		assert_eq!(deserialize("\"0x1\""), 1);
183		assert_eq!(deserialize("\"0xffffffffffffffff\""), u64::MAX as u128);
184		assert_eq!(deserialize("\"0x10000000000000000\""), u64::MAX as u128 + 1);
185	}
186
187	#[test]
188	fn ensure_format_is_unchanged() {
189		let header = Header::<u32, BlakeTwo256> {
190			parent_hash: BlakeTwo256::hash(b"1"),
191			number: 2,
192			state_root: BlakeTwo256::hash(b"3"),
193			extrinsics_root: BlakeTwo256::hash(b"4"),
194			digest: crate::generic::Digest {
195				logs: vec![crate::generic::DigestItem::Other(b"6".to_vec())],
196			},
197		};
198
199		let header_encoded = header.encode();
200		assert_eq!(
201			header_encoded,
202			vec![
203				146, 205, 245, 120, 196, 112, 133, 165, 153, 34, 86, 240, 220, 249, 125, 11, 25,
204				241, 241, 201, 222, 77, 95, 227, 12, 58, 206, 97, 145, 182, 229, 219, 8, 88, 19,
205				72, 51, 123, 15, 62, 20, 134, 32, 23, 61, 170, 165, 249, 77, 0, 216, 129, 112, 93,
206				203, 240, 170, 131, 239, 218, 186, 97, 210, 237, 225, 235, 134, 73, 33, 73, 151,
207				87, 78, 32, 196, 100, 56, 138, 23, 36, 32, 210, 84, 3, 104, 43, 187, 184, 12, 73,
208				104, 49, 200, 204, 31, 143, 13, 4, 0, 4, 54
209			],
210		);
211		assert_eq!(header, Header::<u32, BlakeTwo256>::decode(&mut &header_encoded[..]).unwrap());
212
213		let header = Header::<u32, BlakeTwo256> {
214			parent_hash: BlakeTwo256::hash(b"1000"),
215			number: 2000,
216			state_root: BlakeTwo256::hash(b"3000"),
217			extrinsics_root: BlakeTwo256::hash(b"4000"),
218			digest: crate::generic::Digest {
219				logs: vec![crate::generic::DigestItem::Other(b"5000".to_vec())],
220			},
221		};
222
223		let header_encoded = header.encode();
224		assert_eq!(
225			header_encoded,
226			vec![
227				197, 243, 254, 225, 31, 117, 21, 218, 179, 213, 92, 6, 247, 164, 230, 25, 47, 166,
228				140, 117, 142, 159, 195, 202, 67, 196, 238, 26, 44, 18, 33, 92, 65, 31, 219, 225,
229				47, 12, 107, 88, 153, 146, 55, 21, 226, 186, 110, 48, 167, 187, 67, 183, 228, 232,
230				118, 136, 30, 254, 11, 87, 48, 112, 7, 97, 31, 82, 146, 110, 96, 87, 152, 68, 98,
231				162, 227, 222, 78, 14, 244, 194, 120, 154, 112, 97, 222, 144, 174, 101, 220, 44,
232				111, 126, 54, 34, 155, 220, 253, 124, 4, 0, 16, 53, 48, 48, 48
233			],
234		);
235		assert_eq!(header, Header::<u32, BlakeTwo256>::decode(&mut &header_encoded[..]).unwrap());
236	}
237}