try_runtime_core/common/empty_block/inherents/
providers.rs1use std::{sync::Arc, time::Duration};
21
22use parity_scale_codec::Encode;
23use sp_consensus_aura::{Slot, SlotDuration, AURA_ENGINE_ID};
24use sp_consensus_babe::{
25 digests::{PreDigest, SecondaryPlainPreDigest},
26 BABE_ENGINE_ID,
27};
28use sp_inherents::InherentData;
29use sp_runtime::{
30 traits::{Block as BlockT, HashingFor},
31 Digest, DigestItem,
32};
33use sp_state_machine::TestExternalities;
34use sp_std::prelude::*;
35use strum_macros::{Display, EnumIter};
36use tokio::sync::Mutex;
37
38use crate::common::empty_block::inherents::custom_idps;
39
40const RELAYCHAIN_BLOCKTIME_MS: u64 = 6000u64;
41
42pub trait InherentProvider<B: BlockT> {
44 type Err;
45
46 fn get_inherent_providers_and_pre_digest(
47 &self,
48 maybe_parent_info: Option<(InherentData, Digest)>,
49 parent_header: B::Header,
50 ext: Arc<Mutex<TestExternalities<HashingFor<B>>>>,
51 ) -> InherentProviderResult<Self::Err>;
52}
53
54type InherentProviderResult<Err> =
56 Result<(Box<dyn sp_inherents::InherentDataProvider>, Vec<DigestItem>), Err>;
57
58#[derive(Debug, Clone, EnumIter, Display, Copy)]
63pub enum ProviderVariant {
64 Smart(core::time::Duration),
69}
70
71impl<B: BlockT> InherentProvider<B> for ProviderVariant {
72 type Err = String;
73
74 fn get_inherent_providers_and_pre_digest(
75 &self,
76 maybe_parent_info: Option<(InherentData, Digest)>,
77 parent_header: B::Header,
78 ext: Arc<Mutex<TestExternalities<HashingFor<B>>>>,
79 ) -> InherentProviderResult<Self::Err> {
80 match *self {
81 ProviderVariant::Smart(blocktime) => {
82 <SmartInherentProvider as InherentProvider<B>>::get_inherent_providers_and_pre_digest(&SmartInherentProvider {
83 blocktime,
84 }, maybe_parent_info, parent_header, ext)
85 }
86 }
87 }
88}
89
90struct SmartInherentProvider {
99 blocktime: Duration,
100}
101
102impl<B: BlockT> InherentProvider<B> for SmartInherentProvider {
103 type Err = String;
104
105 fn get_inherent_providers_and_pre_digest(
106 &self,
107 maybe_parent_info: Option<(InherentData, Digest)>,
108 parent_header: B::Header,
109 ext: Arc<Mutex<TestExternalities<HashingFor<B>>>>,
110 ) -> InherentProviderResult<Self::Err> {
111 let timestamp_idp = custom_idps::timestamp::InherentDataProvider {
112 blocktime_millis: self.blocktime.as_millis() as u64,
113 maybe_parent_info,
114 };
115 let para_parachain_idp = custom_idps::para_parachain::InherentDataProvider::<B> {
116 blocktime_millis: RELAYCHAIN_BLOCKTIME_MS,
117 parent_header: parent_header.clone(),
118 timestamp: timestamp_idp.timestamp(),
119 ext_mutex: ext,
120 };
121 let relay_parachain_data_idp =
122 custom_idps::relay_parachains::InherentDataProvider::<B>::new(parent_header);
123
124 let slot = Slot::from_timestamp(
125 timestamp_idp.timestamp(),
126 SlotDuration::from_millis(self.blocktime.as_millis() as u64),
127 );
128 let digest = vec![
129 DigestItem::PreRuntime(
130 BABE_ENGINE_ID,
131 PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
132 slot,
133 authority_index: 0,
134 })
135 .encode(),
136 ),
137 DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode()),
138 ];
139
140 Ok((
141 Box::new((timestamp_idp, para_parachain_idp, relay_parachain_data_idp)),
142 digest,
143 ))
144 }
145}