referrerpolicy=no-referrer-when-downgrade

substrate_relay_helper/parachains/
mod.rs

1// Copyright 2019-2021 Parity Technologies (UK) Ltd.
2// This file is part of Parity Bridges Common.
3
4// Parity Bridges Common is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Bridges Common is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Types and functions intended to ease adding of new Substrate -> Substrate
18//! parachain finality proofs synchronization pipelines.
19
20use async_trait::async_trait;
21use bp_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
22use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
23use pallet_bridge_parachains::{Call as BridgeParachainsCall, Config as BridgeParachainsConfig};
24use parachains_relay::ParachainsPipeline;
25use relay_substrate_client::{
26	CallOf, Chain, ChainWithTransactions, HeaderIdOf, Parachain, RelayChain,
27};
28use std::{fmt::Debug, marker::PhantomData};
29
30pub mod source;
31pub mod target;
32
33/// Substrate -> Substrate parachain finality proofs synchronization pipeline.
34///
35/// This is currently restricted to the single parachain, because it is how it
36/// will be used (at least) initially.
37#[async_trait]
38pub trait SubstrateParachainsPipeline: 'static + Clone + Debug + Send + Sync {
39	/// Headers of this parachain are submitted to the `Self::TargetChain`.
40	type SourceParachain: Parachain;
41	/// Relay chain that is storing headers of `Self::SourceParachain`.
42	type SourceRelayChain: RelayChain;
43	/// Target chain where `Self::SourceParachain` headers are submitted.
44	type TargetChain: ChainWithTransactions;
45
46	/// How submit parachains heads call is built?
47	type SubmitParachainHeadsCallBuilder: SubmitParachainHeadsCallBuilder<Self>;
48}
49
50/// Adapter that allows all `SubstrateParachainsPipeline` to act as `ParachainsPipeline`.
51#[derive(Clone, Debug)]
52pub struct ParachainsPipelineAdapter<P: SubstrateParachainsPipeline> {
53	_phantom: PhantomData<P>,
54}
55
56impl<P: SubstrateParachainsPipeline> ParachainsPipeline for ParachainsPipelineAdapter<P> {
57	type SourceParachain = P::SourceParachain;
58	type SourceRelayChain = P::SourceRelayChain;
59	type TargetChain = P::TargetChain;
60}
61
62/// Different ways of building `submit_parachain_heads` calls.
63pub trait SubmitParachainHeadsCallBuilder<P: SubstrateParachainsPipeline>:
64	'static + Send + Sync
65{
66	/// Given parachains and their heads proof, build call of `submit_parachain_heads`
67	/// function of bridge parachains module at the target chain.
68	fn build_submit_parachain_heads_call(
69		at_relay_block: HeaderIdOf<P::SourceRelayChain>,
70		parachains: Vec<(ParaId, ParaHash)>,
71		parachain_heads_proof: ParaHeadsProof,
72		is_free_execution_expected: bool,
73	) -> CallOf<P::TargetChain>;
74}
75
76/// Building `submit_parachain_heads` call when you have direct access to the target
77/// chain runtime.
78pub struct DirectSubmitParachainHeadsCallBuilder<P, R, I> {
79	_phantom: PhantomData<(P, R, I)>,
80}
81
82impl<P, R, I> SubmitParachainHeadsCallBuilder<P> for DirectSubmitParachainHeadsCallBuilder<P, R, I>
83where
84	P: SubstrateParachainsPipeline,
85	P::SourceRelayChain: Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber>,
86	R: BridgeParachainsConfig<I> + Send + Sync,
87	I: 'static + Send + Sync,
88	R::BridgedChain: bp_runtime::Chain<
89		BlockNumber = RelayBlockNumber,
90		Hash = RelayBlockHash,
91		Hasher = RelayBlockHasher,
92	>,
93	CallOf<P::TargetChain>: From<BridgeParachainsCall<R, I>>,
94{
95	fn build_submit_parachain_heads_call(
96		at_relay_block: HeaderIdOf<P::SourceRelayChain>,
97		parachains: Vec<(ParaId, ParaHash)>,
98		parachain_heads_proof: ParaHeadsProof,
99		_is_free_execution_expected: bool,
100	) -> CallOf<P::TargetChain> {
101		BridgeParachainsCall::<R, I>::submit_parachain_heads {
102			at_relay_block: (at_relay_block.0, at_relay_block.1),
103			parachains,
104			parachain_heads_proof,
105		}
106		.into()
107	}
108}