diff --git a/core/src/da_block.rs b/core/src/da_block.rs new file mode 100644 index 00000000..a3769f13 --- /dev/null +++ b/core/src/da_block.rs @@ -0,0 +1,151 @@ +// This file is part of Substrate. + +// Copyright (C) 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 DA block and associated items. + +#[cfg(feature = "std")] +use std::fmt; + +use codec::{Codec, Decode, Encode}; +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; +use sp_core::RuntimeDebug; +use sp_runtime::{ + traits::{ + self, Block as BlockT, Header as HeaderT, MaybeSerialize, MaybeSerializeDeserialize, + Member, NumberFor, + }, + Justifications, +}; +use sp_std::prelude::*; +use crate::traits::{ExtendedBlock, ExtendedHeader}; + +/// Something to identify a block. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +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 const fn hash(hash: Block::Hash) -> Self { + BlockId::Hash(hash) + } + + /// Create a block ID from a number. + pub const 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, scale_info::TypeInfo)] +#[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 DaBlock { + /// The block header. + pub header: Header, + /// The accompanying extrinsics. + pub extrinsics: Vec, +} + +impl traits::HeaderProvider for DaBlock +where + Header: HeaderT +{ + type HeaderT = Header; +} + +impl BlockT for DaBlock +where + Header: HeaderT + MaybeSerializeDeserialize, + Extrinsic: Member + Codec + traits::Extrinsic, +{ + 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 { + DaBlock { 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, +} + +impl ExtendedBlock for DaBlock +where + Header: HeaderT + + MaybeSerializeDeserialize + + ExtendedHeader< +
::Number, +
::Hash, + sp_runtime::Digest, + Extension, + >, + Extrinsic: Member + Codec + traits::Extrinsic + MaybeSerializeDeserialize, +{ + type Header = Header; +} + diff --git a/core/src/lib.rs b/core/src/lib.rs index 3b939ee2..c3f068c3 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -12,6 +12,9 @@ use sp_core::RuntimeDebug; pub mod opaque_extrinsic; pub use opaque_extrinsic::*; +pub mod da_block; +pub use da_block::*; + /// Customized headers. #[cfg(feature = "runtime")] pub mod header;