1#![cfg_attr(not(feature = "std"), no_std)]
21
22use tetcore_std::{result::Result, prelude::*};
23
24use codec::{Encode, Decode};
25use tp_inherents::{Error, InherentIdentifier, InherentData, IsFatalError};
26use tp_runtime::RuntimeString;
27
28pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"uncles00";
30
31#[derive(Encode, tp_runtime::RuntimeDebug)]
33#[cfg_attr(feature = "std", derive(Decode))]
34pub enum InherentError {
35 Uncles(RuntimeString),
36}
37
38impl IsFatalError for InherentError {
39 fn is_fatal_error(&self) -> bool {
40 match self {
41 InherentError::Uncles(_) => true,
42 }
43 }
44}
45
46pub trait UnclesInherentData<H: Decode> {
48 fn uncles(&self) -> Result<Vec<H>, Error>;
50}
51
52impl<H: Decode> UnclesInherentData<H> for InherentData {
53 fn uncles(&self) -> Result<Vec<H>, Error> {
54 Ok(self.get_data(&INHERENT_IDENTIFIER)?.unwrap_or_default())
55 }
56}
57
58#[cfg(feature = "std")]
60pub struct InherentDataProvider<F, H> {
61 inner: F,
62 _marker: std::marker::PhantomData<H>,
63}
64
65#[cfg(feature = "std")]
66impl<F, H> InherentDataProvider<F, H> {
67 pub fn new(uncles_oracle: F) -> Self {
68 InherentDataProvider { inner: uncles_oracle, _marker: Default::default() }
69 }
70}
71
72#[cfg(feature = "std")]
73impl<F, H: Encode + std::fmt::Debug> tp_inherents::ProvideInherentData for InherentDataProvider<F, H>
74where F: Fn() -> Vec<H>
75{
76 fn inherent_identifier(&self) -> &'static InherentIdentifier {
77 &INHERENT_IDENTIFIER
78 }
79
80 fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error> {
81 let uncles = (self.inner)();
82 if !uncles.is_empty() {
83 inherent_data.put_data(INHERENT_IDENTIFIER, &uncles)
84 } else {
85 Ok(())
86 }
87 }
88
89 fn error_to_string(&self, _error: &[u8]) -> Option<String> {
90 Some(format!("no further information"))
91 }
92}