// This file is part of Substrate. // Copyright (C) 2017-2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! Generic implementation of a block and associated items. #[cfg(feature = "std")] use std::fmt; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; use crate::{ codec::{Codec, Decode, Encode}, traits::{ self, Block as BlockT, Header as HeaderT, MaybeMallocSizeOf, MaybeSerialize, Member, NumberFor, }, Justifications, }; use sp_core::RuntimeDebug; use sp_std::prelude::*; /// Something to identify a block. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub enum BlockId { /// Identify by block header hash. Hash(Block::Hash), /// Identify by block number. Number(NumberFor), } impl BlockId { /// Create a block ID from a hash. pub fn hash(hash: Block::Hash) -> Self { BlockId::Hash(hash) } /// Create a block ID from a number. pub fn number(number: NumberFor) -> Self { BlockId::Number(number) } /// Check if this block ID refers to the pre-genesis state. pub fn is_pre_genesis(&self) -> bool { match self { BlockId::Hash(hash) => hash == &Default::default(), BlockId::Number(_) => false, } } /// Create a block ID for a pre-genesis state. pub fn pre_genesis() -> Self { BlockId::Hash(Default::default()) } } impl Copy for BlockId {} #[cfg(feature = "std")] impl fmt::Display for BlockId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) } } /// Abstraction over a substrate block. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct Block { /// The block header. pub header: Header, /// The accompanying extrinsics. pub extrinsics: Vec, } impl traits::Block for Block where Header: HeaderT, Extrinsic: Member + Codec + traits::Extrinsic + MaybeMallocSizeOf, { type Extrinsic = Extrinsic; type Header = Header; type Hash = ::Hash; fn header(&self) -> &Self::Header { &self.header } fn extrinsics(&self) -> &[Self::Extrinsic] { &self.extrinsics[..] } fn deconstruct(self) -> (Self::Header, Vec) { (self.header, self.extrinsics) } fn new(header: Self::Header, extrinsics: Vec) -> Self { Block { header, extrinsics } } fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec { (header, extrinsics).encode() } } /// Abstraction over a substrate block and justification. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct SignedBlock { /// Full block. pub block: Block, /// Block justification. pub justifications: Option, }