sp_consensus_subspace/
inherents.rs

1//! Inherents for Subspace consensus
2
3#[cfg(not(feature = "std"))]
4extern crate alloc;
5
6#[cfg(not(feature = "std"))]
7use alloc::vec::Vec;
8use parity_scale_codec::{Decode, Encode};
9use sp_inherents::{Error, InherentData, InherentIdentifier, IsFatalError};
10use subspace_core_primitives::segments::SegmentHeader;
11
12/// The Subspace inherent identifier.
13pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"subspace";
14
15/// Errors that can occur while checking segment headers.
16#[derive(Debug, Encode)]
17#[cfg_attr(feature = "std", derive(Decode))]
18pub enum InherentError {
19    /// List of segment headers is not correct.
20    IncorrectSegmentHeadersList {
21        /// Expected list of segment headers according to node's inherents.
22        expected: Vec<SegmentHeader>,
23        /// List of segment headers contained within proposed block.
24        actual: Vec<SegmentHeader>,
25    },
26    /// List of segment headers is not present.
27    MissingSegmentHeadersList,
28}
29
30impl IsFatalError for InherentError {
31    fn is_fatal_error(&self) -> bool {
32        true
33    }
34}
35
36/// The type of the Subspace inherent data.
37#[derive(Debug, Encode, Decode)]
38pub struct InherentType {
39    /// Segment headers expected to be included in the block.
40    pub segment_headers: Vec<SegmentHeader>,
41}
42
43/// Auxiliary trait to extract Subspace inherent data.
44pub trait SubspaceInherentData {
45    /// Get Subspace inherent data.
46    fn subspace_inherent_data(&self) -> Result<Option<InherentType>, Error>;
47
48    /// Replace Subspace inherent data.
49    fn replace_subspace_inherent_data(&mut self, new: InherentType);
50}
51
52impl SubspaceInherentData for InherentData {
53    fn subspace_inherent_data(&self) -> Result<Option<InherentType>, Error> {
54        self.get_data(&INHERENT_IDENTIFIER)
55    }
56
57    fn replace_subspace_inherent_data(&mut self, new: InherentType) {
58        self.replace_data(INHERENT_IDENTIFIER, &new);
59    }
60}
61
62/// Provides the segment headers inherent data for Subspace.
63#[cfg(feature = "std")]
64pub struct InherentDataProvider {
65    data: InherentType,
66}
67
68#[cfg(feature = "std")]
69impl InherentDataProvider {
70    /// Create new inherent data provider from the given `segment_headers`.
71    pub fn new(segment_headers: Vec<SegmentHeader>) -> Self {
72        Self {
73            data: InherentType { segment_headers },
74        }
75    }
76
77    /// Returns the `data` of this inherent data provider.
78    pub fn data(&self) -> &InherentType {
79        &self.data
80    }
81}
82
83#[cfg(feature = "std")]
84#[async_trait::async_trait]
85impl sp_inherents::InherentDataProvider for InherentDataProvider {
86    async fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error> {
87        inherent_data.put_data(INHERENT_IDENTIFIER, &self.data)
88    }
89
90    async fn try_handle_error(
91        &self,
92        identifier: &InherentIdentifier,
93        error: &[u8],
94    ) -> Option<Result<(), Error>> {
95        if *identifier != INHERENT_IDENTIFIER {
96            return None;
97        }
98
99        let error = InherentError::decode(&mut &*error).ok()?;
100
101        Some(Err(Error::Application(Box::from(format!("{error:?}")))))
102    }
103}