1#![warn(missing_docs)]
20#![cfg_attr(not(feature = "std"), no_std)]
21
22pub use pezbp_header_pez_chain::StoredHeaderData;
23pub use call_info::{BridgeTeyrchainCall, SubmitTeyrchainHeadsInfo};
24
25use pezbp_pezkuwi_core::teyrchains::{ParaHash, ParaHead, ParaId};
26use codec::{Decode, Encode, MaxEncodedLen};
27use pezbp_runtime::{
28 BlockNumberOf, Chain, HashOf, HeaderOf, StorageDoubleMapKeyProvider, StorageMapKeyProvider,
29 Teyrchain,
30};
31use pezframe_support::{weights::Weight, Blake2_128Concat, Twox64Concat};
32use pezsp_core::storage::StorageKey;
33use pezsp_runtime::{traits::Header as HeaderT, RuntimeDebug};
34use pezsp_std::{marker::PhantomData, prelude::*};
35use scale_info::TypeInfo;
36
37pub type RelayBlockHash = pezbp_pezkuwi_core::Hash;
39pub type RelayBlockNumber = pezbp_pezkuwi_core::BlockNumber;
41pub type RelayBlockHasher = pezbp_pezkuwi_core::Hasher;
43
44mod call_info;
45
46#[derive(Clone, Decode, Encode, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)]
48pub struct BestParaHeadHash {
49 pub at_relay_block_number: RelayBlockNumber,
58 pub head_hash: ParaHash,
60}
61
62#[derive(Decode, Encode, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)]
64pub struct ParaInfo {
65 pub best_head_hash: BestParaHeadHash,
67 pub next_imported_hash_position: u32,
69}
70
71pub fn teyrchain_head_storage_key_at_source(
75 paras_pallet_name: &str,
76 para_id: ParaId,
77) -> StorageKey {
78 pezbp_runtime::storage_map_final_key::<Twox64Concat>(
79 paras_pallet_name,
80 "Heads",
81 ¶_id.encode(),
82 )
83}
84
85pub struct ParasInfoKeyProvider;
89impl StorageMapKeyProvider for ParasInfoKeyProvider {
90 const MAP_NAME: &'static str = "ParasInfo";
91
92 type Hasher = Blake2_128Concat;
93 type Key = ParaId;
94 type Value = ParaInfo;
95}
96
97pub struct ImportedParaHeadsKeyProvider;
102impl StorageDoubleMapKeyProvider for ImportedParaHeadsKeyProvider {
103 const MAP_NAME: &'static str = "ImportedParaHeads";
104
105 type Hasher1 = Blake2_128Concat;
106 type Key1 = ParaId;
107 type Hasher2 = Blake2_128Concat;
108 type Key2 = ParaHash;
109 type Value = ParaStoredHeaderData;
110}
111
112#[derive(Clone, Decode, Encode, PartialEq, RuntimeDebug, TypeInfo)]
119pub struct ParaStoredHeaderData(pub Vec<u8>);
120
121impl ParaStoredHeaderData {
122 pub fn decode_teyrchain_head_data<C: Chain>(
124 &self,
125 ) -> Result<StoredHeaderData<BlockNumberOf<C>, HashOf<C>>, codec::Error> {
126 StoredHeaderData::<BlockNumberOf<C>, HashOf<C>>::decode(&mut &self.0[..])
127 }
128}
129
130pub trait ParaStoredHeaderDataBuilder {
132 fn max_free_head_size() -> u32;
135
136 fn supported_teyrchains() -> u32;
138
139 fn try_build(para_id: ParaId, para_head: &ParaHead) -> Option<ParaStoredHeaderData>;
141}
142
143pub struct SingleParaStoredHeaderDataBuilder<C: Teyrchain>(PhantomData<C>);
145
146impl<C: Teyrchain> ParaStoredHeaderDataBuilder for SingleParaStoredHeaderDataBuilder<C> {
147 fn max_free_head_size() -> u32 {
148 C::MAX_HEADER_SIZE
149 }
150
151 fn supported_teyrchains() -> u32 {
152 1
153 }
154
155 fn try_build(para_id: ParaId, para_head: &ParaHead) -> Option<ParaStoredHeaderData> {
156 if para_id == ParaId(C::TEYRCHAIN_ID) {
157 let header = HeaderOf::<C>::decode(&mut ¶_head.0[..]).ok()?;
158 return Some(ParaStoredHeaderData(
159 StoredHeaderData { number: *header.number(), state_root: *header.state_root() }
160 .encode(),
161 ));
162 }
163 None
164 }
165}
166
167#[impl_trait_for_tuples::impl_for_tuples(1, 30)]
169#[tuple_types_custom_trait_bound(Teyrchain)]
170impl ParaStoredHeaderDataBuilder for C {
171 fn max_free_head_size() -> u32 {
172 let mut result = 0_u32;
173 for_tuples!( #(
174 result = pezsp_std::cmp::max(
175 result,
176 SingleParaStoredHeaderDataBuilder::<C>::max_free_head_size(),
177 );
178 )* );
179 result
180 }
181
182 fn supported_teyrchains() -> u32 {
183 let mut result = 0;
184 for_tuples!( #(
185 result += SingleParaStoredHeaderDataBuilder::<C>::supported_teyrchains();
186 )* );
187 result
188 }
189
190 fn try_build(para_id: ParaId, para_head: &ParaHead) -> Option<ParaStoredHeaderData> {
191 for_tuples!( #(
192 let maybe_para_head = SingleParaStoredHeaderDataBuilder::<C>::try_build(para_id, para_head);
193 if let Some(maybe_para_head) = maybe_para_head {
194 return Some(maybe_para_head);
195 }
196 )* );
197
198 None
199 }
200}
201
202pub trait OnNewHead {
204 fn on_new_head(id: ParaId, head: &ParaHead) -> Weight;
207}
208
209#[impl_trait_for_tuples::impl_for_tuples(8)]
210impl OnNewHead for Tuple {
211 fn on_new_head(id: ParaId, head: &ParaHead) -> Weight {
212 let mut weight: Weight = Default::default();
213 for_tuples!( #( weight.saturating_accrue(Tuple::on_new_head(id, head)); )* );
214 weight
215 }
216}