1use crate::{ChainId, HeaderIdProvider};
18
19use codec::{Codec, Decode, Encode, MaxEncodedLen};
20use num_traits::{AsPrimitive, Bounded, CheckedSub, Saturating, SaturatingAdd, Zero};
21use pezframe_support::{weights::Weight, Parameter};
22use pezsp_runtime::{
23 traits::{
24 AtLeast32Bit, AtLeast32BitUnsigned, Hash as HashT, Header as HeaderT, MaybeDisplay,
25 MaybeSerialize, MaybeSerializeDeserialize, Member, SimpleBitOps, Verify,
26 },
27 FixedPointOperand, StateVersion,
28};
29use pezsp_std::{fmt::Debug, hash::Hash, str::FromStr, vec, vec::Vec};
30
31#[derive(Debug, Clone, PartialEq)]
33pub enum EncodedOrDecodedCall<ChainCall> {
34 Encoded(Vec<u8>),
39 Decoded(ChainCall),
41}
42
43impl<ChainCall: Clone + Codec> EncodedOrDecodedCall<ChainCall> {
44 pub fn to_decoded(&self) -> Result<ChainCall, codec::Error> {
46 match self {
47 Self::Encoded(ref encoded_call) => {
48 ChainCall::decode(&mut &encoded_call[..]).map_err(Into::into)
49 },
50 Self::Decoded(ref decoded_call) => Ok(decoded_call.clone()),
51 }
52 }
53
54 pub fn into_decoded(self) -> Result<ChainCall, codec::Error> {
56 match self {
57 Self::Encoded(encoded_call) => {
58 ChainCall::decode(&mut &encoded_call[..]).map_err(Into::into)
59 },
60 Self::Decoded(decoded_call) => Ok(decoded_call),
61 }
62 }
63
64 pub fn into_encoded(self) -> Vec<u8> {
66 match self {
67 Self::Encoded(encoded_call) => encoded_call,
68 Self::Decoded(decoded_call) => decoded_call.encode(),
69 }
70 }
71}
72
73impl<ChainCall> From<ChainCall> for EncodedOrDecodedCall<ChainCall> {
74 fn from(call: ChainCall) -> EncodedOrDecodedCall<ChainCall> {
75 EncodedOrDecodedCall::Decoded(call)
76 }
77}
78
79impl<ChainCall: Decode> Decode for EncodedOrDecodedCall<ChainCall> {
80 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
81 match input.remaining_len()? {
84 Some(remaining_len) => {
85 let mut encoded_call = vec![0u8; remaining_len];
86 input.read(&mut encoded_call)?;
87 Ok(EncodedOrDecodedCall::Encoded(encoded_call))
88 },
89 None => Ok(EncodedOrDecodedCall::Decoded(ChainCall::decode(input)?)),
90 }
91 }
92}
93
94impl<ChainCall: Encode> Encode for EncodedOrDecodedCall<ChainCall> {
95 fn encode(&self) -> Vec<u8> {
96 match *self {
97 Self::Encoded(ref encoded_call) => encoded_call.clone(),
98 Self::Decoded(ref decoded_call) => decoded_call.encode(),
99 }
100 }
101}
102
103pub trait Chain: Send + Sync + 'static {
105 const ID: ChainId;
107
108 type BlockNumber: Parameter
116 + Member
117 + MaybeSerializeDeserialize
118 + Hash
119 + Copy
120 + Default
121 + MaybeDisplay
122 + AtLeast32BitUnsigned
123 + FromStr
124 + AsPrimitive<usize>
125 + Default
126 + Saturating
127 + MaxEncodedLen;
128
129 type Hash: Parameter
134 + Member
135 + MaybeSerializeDeserialize
136 + Hash
137 + Ord
138 + Copy
139 + MaybeDisplay
140 + Default
141 + SimpleBitOps
142 + AsRef<[u8]>
143 + AsMut<[u8]>
144 + MaxEncodedLen;
145
146 type Hasher: HashT<Output = Self::Hash>;
152
153 type Header: Parameter
157 + HeaderT<Number = Self::BlockNumber, Hash = Self::Hash>
158 + HeaderIdProvider<Self::Header>
159 + MaybeSerializeDeserialize;
160
161 type AccountId: Parameter
163 + Member
164 + MaybeSerializeDeserialize
165 + Debug
166 + MaybeDisplay
167 + Ord
168 + MaxEncodedLen;
169 type Balance: AtLeast32BitUnsigned
174 + FixedPointOperand
175 + Parameter
176 + Member
177 + MaybeSerializeDeserialize
178 + Clone
179 + Copy
180 + Bounded
181 + CheckedSub
182 + PartialOrd
183 + SaturatingAdd
184 + Zero
185 + TryFrom<pezsp_core::U256>
186 + MaxEncodedLen;
187 type Nonce: Parameter
189 + Member
190 + MaybeSerialize
191 + Debug
192 + Default
193 + MaybeDisplay
194 + MaybeSerializeDeserialize
195 + AtLeast32Bit
196 + Copy
197 + MaxEncodedLen;
198 type Signature: Parameter + Verify;
200
201 const STATE_VERSION: StateVersion;
204
205 fn max_extrinsic_size() -> u32;
207 fn max_extrinsic_weight() -> Weight;
209}
210
211pub trait UnderlyingChainProvider: Send + Sync + 'static {
213 type Chain: Chain;
215}
216
217impl<T> Chain for T
218where
219 T: Send + Sync + 'static + UnderlyingChainProvider,
220{
221 const ID: ChainId = <T::Chain as Chain>::ID;
222
223 type BlockNumber = <T::Chain as Chain>::BlockNumber;
224 type Hash = <T::Chain as Chain>::Hash;
225 type Hasher = <T::Chain as Chain>::Hasher;
226 type Header = <T::Chain as Chain>::Header;
227 type AccountId = <T::Chain as Chain>::AccountId;
228 type Balance = <T::Chain as Chain>::Balance;
229 type Nonce = <T::Chain as Chain>::Nonce;
230 type Signature = <T::Chain as Chain>::Signature;
231
232 const STATE_VERSION: StateVersion = <T::Chain as Chain>::STATE_VERSION;
233
234 fn max_extrinsic_size() -> u32 {
235 <T::Chain as Chain>::max_extrinsic_size()
236 }
237
238 fn max_extrinsic_weight() -> Weight {
239 <T::Chain as Chain>::max_extrinsic_weight()
240 }
241}
242
243pub trait Teyrchain: Chain {
245 const TEYRCHAIN_ID: u32;
247 const MAX_HEADER_SIZE: u32;
253}
254
255impl<T> Teyrchain for T
256where
257 T: Chain + UnderlyingChainProvider,
258 <T as UnderlyingChainProvider>::Chain: Teyrchain,
259{
260 const TEYRCHAIN_ID: u32 = <<T as UnderlyingChainProvider>::Chain as Teyrchain>::TEYRCHAIN_ID;
261 const MAX_HEADER_SIZE: u32 =
262 <<T as UnderlyingChainProvider>::Chain as Teyrchain>::MAX_HEADER_SIZE;
263}
264
265pub struct TeyrchainIdOf<Para>(pezsp_std::marker::PhantomData<Para>);
267impl<Para: Teyrchain> pezframe_support::traits::Get<u32> for TeyrchainIdOf<Para> {
268 fn get() -> u32 {
269 Para::TEYRCHAIN_ID
270 }
271}
272
273pub type UnderlyingChainOf<C> = <C as UnderlyingChainProvider>::Chain;
275
276pub type BlockNumberOf<C> = <C as Chain>::BlockNumber;
278
279pub type HashOf<C> = <C as Chain>::Hash;
281
282pub type HasherOf<C> = <C as Chain>::Hasher;
284
285pub type HeaderOf<C> = <C as Chain>::Header;
287
288pub type AccountIdOf<C> = <C as Chain>::AccountId;
290
291pub type BalanceOf<C> = <C as Chain>::Balance;
293
294pub type NonceOf<C> = <C as Chain>::Nonce;
296
297pub type SignatureOf<C> = <C as Chain>::Signature;
299
300pub type AccountPublicOf<C> = <SignatureOf<C> as Verify>::Signer;
302
303pub type TransactionEraOf<C> = crate::TransactionEra<BlockNumberOf<C>, HashOf<C>>;
305
306#[macro_export]
315macro_rules! decl_bridge_finality_runtime_apis {
316 ($chain: ident $(, $consensus: ident => $justification_type: ty)?) => {
317 pezbp_runtime::paste::item! {
318 mod [<$chain _finality_api>] {
319 use super::*;
320
321 pub const [<BEST_FINALIZED_ $chain:upper _HEADER_METHOD>]: &str =
323 stringify!([<$chain:camel FinalityApi_best_finalized>]);
324
325 pub const [<FREE_HEADERS_INTERVAL_FOR_ $chain:upper _METHOD>]: &str =
327 stringify!([<$chain:camel FinalityApi_free_headers_interval>]);
328
329
330 $(
331 pub const [<$chain:upper _SYNCED_HEADERS_ $consensus:upper _INFO_METHOD>]: &str =
334 stringify!([<$chain:camel FinalityApi_synced_headers_ $consensus:lower _info>]);
335 )?
336
337 pezsp_api::decl_runtime_apis! {
338 pub trait [<$chain:camel FinalityApi>] {
343 fn best_finalized() -> Option<pezbp_runtime::HeaderId<Hash, BlockNumber>>;
345
346 fn free_headers_interval() -> Option<BlockNumber>;
352
353 $(
354 fn [<synced_headers_ $consensus:lower _info>](
356 ) -> $crate::private::Vec<$justification_type>;
357 )?
358 }
359 }
360 }
361
362 pub use [<$chain _finality_api>]::*;
363 }
364 };
365 ($chain: ident, grandpa) => {
366 decl_bridge_finality_runtime_apis!($chain, grandpa => bp_header_pez_chain::StoredHeaderGrandpaInfo<Header>);
367 };
368}
369
370#[doc(hidden)]
372pub mod __private {
373 pub use codec;
374}
375
376#[macro_export]
385macro_rules! decl_bridge_messages_runtime_apis {
386 ($chain: ident, $lane_id_type:ty) => {
387 pezbp_runtime::paste::item! {
388 mod [<$chain _messages_api>] {
389 use super::*;
390
391 pub const [<TO_ $chain:upper _MESSAGE_DETAILS_METHOD>]: &str =
393 stringify!([<To $chain:camel OutboundLaneApi_message_details>]);
394
395 pub const [<FROM_ $chain:upper _MESSAGE_DETAILS_METHOD>]: &str =
397 stringify!([<From $chain:camel InboundLaneApi_message_details>]);
398
399 pezsp_api::decl_runtime_apis! {
400 pub trait [<To $chain:camel OutboundLaneApi>] {
405 fn message_details(
411 lane: $lane_id_type,
412 begin: bp_messages::MessageNonce,
413 end: bp_messages::MessageNonce,
414 ) -> $crate::private::Vec<bp_messages::OutboundMessageDetails>;
415 }
416
417 pub trait [<From $chain:camel InboundLaneApi>] {
425 fn message_details(
427 lane: $lane_id_type,
428 messages: $crate::private::Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>,
429 ) -> $crate::private::Vec<bp_messages::InboundMessageDetails>;
430 }
431 }
432 }
433
434 pub use [<$chain _messages_api>]::*;
435 }
436 };
437}
438
439#[macro_export]
443macro_rules! decl_bridge_runtime_apis {
444 ($chain: ident $(, $consensus: ident, $lane_id_type:ident)?) => {
445 pezbp_runtime::decl_bridge_finality_runtime_apis!($chain $(, $consensus)?);
446 pezbp_runtime::decl_bridge_messages_runtime_apis!($chain, $lane_id_type);
447 };
448}