sp_runtime/generic/
block.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 and associated items.
19
20#[cfg(feature = "std")]
21use std::fmt;
22
23#[cfg(feature = "serde")]
24use serde::{Deserialize, Serialize};
25
26use crate::{
27	codec::{Codec, Decode, DecodeWithMemTracking, Encode},
28	traits::{
29		self, Block as BlockT, Header as HeaderT, MaybeSerialize, MaybeSerializeDeserialize,
30		Member, NumberFor,
31	},
32	Justifications,
33};
34use alloc::vec::Vec;
35use sp_core::RuntimeDebug;
36
37/// Something to identify a block.
38#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
39pub enum BlockId<Block: BlockT> {
40	/// Identify by block header hash.
41	Hash(Block::Hash),
42	/// Identify by block number.
43	Number(NumberFor<Block>),
44}
45
46impl<Block: BlockT> BlockId<Block> {
47	/// Create a block ID from a hash.
48	pub const fn hash(hash: Block::Hash) -> Self {
49		BlockId::Hash(hash)
50	}
51
52	/// Create a block ID from a number.
53	pub const fn number(number: NumberFor<Block>) -> Self {
54		BlockId::Number(number)
55	}
56
57	/// Check if this block ID refers to the pre-genesis state.
58	pub fn is_pre_genesis(&self) -> bool {
59		match self {
60			BlockId::Hash(hash) => hash == &Default::default(),
61			BlockId::Number(_) => false,
62		}
63	}
64
65	/// Create a block ID for a pre-genesis state.
66	pub fn pre_genesis() -> Self {
67		BlockId::Hash(Default::default())
68	}
69}
70
71impl<Block: BlockT> Copy for BlockId<Block> {}
72
73#[cfg(feature = "std")]
74impl<Block: BlockT> fmt::Display for BlockId<Block> {
75	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76		write!(f, "{:?}", self)
77	}
78}
79
80/// Abstraction over a substrate block.
81#[derive(
82	PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, RuntimeDebug, scale_info::TypeInfo,
83)]
84#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
85#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
86#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
87pub struct Block<Header, Extrinsic> {
88	/// The block header.
89	pub header: Header,
90	/// The accompanying extrinsics.
91	pub extrinsics: Vec<Extrinsic>,
92}
93
94impl<Header, Extrinsic> traits::HeaderProvider for Block<Header, Extrinsic>
95where
96	Header: HeaderT,
97{
98	type HeaderT = Header;
99}
100
101impl<Header, Extrinsic: MaybeSerialize> traits::Block for Block<Header, Extrinsic>
102where
103	Header: HeaderT + MaybeSerializeDeserialize,
104	Extrinsic: Member + Codec + DecodeWithMemTracking + traits::ExtrinsicLike,
105{
106	type Extrinsic = Extrinsic;
107	type Header = Header;
108	type Hash = <Self::Header as traits::Header>::Hash;
109
110	fn header(&self) -> &Self::Header {
111		&self.header
112	}
113	fn extrinsics(&self) -> &[Self::Extrinsic] {
114		&self.extrinsics[..]
115	}
116	fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>) {
117		(self.header, self.extrinsics)
118	}
119	fn new(header: Self::Header, extrinsics: Vec<Self::Extrinsic>) -> Self {
120		Block { header, extrinsics }
121	}
122	fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec<u8> {
123		(header, extrinsics).encode()
124	}
125}
126
127/// Abstraction over a substrate block and justification.
128#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
129#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
130#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
131#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
132pub struct SignedBlock<Block> {
133	/// Full block.
134	pub block: Block,
135	/// Block justification.
136	pub justifications: Option<Justifications>,
137}