referrerpolicy=no-referrer-when-downgrade

bridge_hub_test_utils/test_data/
from_parachain.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3// SPDX-License-Identifier: Apache-2.0
4
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// 	http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17//! Generating test data for bridges with remote parachains.
18
19use super::{
20	from_grandpa_chain::make_complex_bridged_grandpa_header_proof, prepare_inbound_xcm,
21	XcmAsPlainPayload,
22};
23
24use bp_messages::{
25	source_chain::FromBridgedChainMessagesDeliveryProof,
26	target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneState,
27	UnrewardedRelayersState, Weight,
28};
29use bp_parachains::{RelayBlockHash, RelayBlockNumber};
30use bp_runtime::{
31	AccountIdOf, BlockNumberOf, Chain, HeaderOf, Parachain, UnverifiedStorageProofParams,
32};
33use bp_test_utils::prepare_parachain_heads_proof;
34use codec::Encode;
35use pallet_bridge_grandpa::BridgedHeader;
36use sp_runtime::traits::Header as HeaderT;
37use xcm::latest::prelude::*;
38
39use crate::test_cases::helpers::InboundRelayerId;
40use bp_header_chain::{justification::GrandpaJustification, ChainWithGrandpa};
41use bp_messages::{DeliveredMessages, InboundLaneData, MessageNonce, UnrewardedRelayer};
42use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId};
43use pallet_bridge_messages::{
44	messages_generation::{
45		encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof,
46		prepare_messages_storage_proof,
47	},
48	BridgedChainOf, LaneIdOf,
49};
50use sp_runtime::SaturatedConversion;
51
52/// Prepare a batch call with relay finality proof, parachain head proof and message proof.
53pub fn make_complex_relayer_delivery_batch<Runtime, GPI, PPI, MPI>(
54	relay_chain_header: BridgedHeader<Runtime, GPI>,
55	grandpa_justification: GrandpaJustification<BridgedHeader<Runtime, GPI>>,
56	parachain_heads: Vec<(ParaId, ParaHash)>,
57	para_heads_proof: ParaHeadsProof,
58	message_proof: FromBridgedChainMessagesProof<ParaHash, LaneIdOf<Runtime, MPI>>,
59	relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>,
60) -> pallet_utility::Call<Runtime>
61where
62	Runtime: pallet_bridge_grandpa::Config<GPI>
63		+ pallet_bridge_parachains::Config<PPI>
64		+ pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload>
65		+ pallet_utility::Config,
66	GPI: 'static,
67	PPI: 'static,
68	MPI: 'static,
69	ParaHash: From<
70		<<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash,
71	>,
72	<<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash:
73		From<ParaHash>,
74	BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain,
75	<Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>>
76		+ From<pallet_bridge_parachains::Call<Runtime, PPI>>
77		+ From<pallet_bridge_messages::Call<Runtime, MPI>>,
78{
79	let relay_chain_header_hash = relay_chain_header.hash();
80	let relay_chain_header_number = *relay_chain_header.number();
81	let submit_grandpa = pallet_bridge_grandpa::Call::<Runtime, GPI>::submit_finality_proof {
82		finality_target: Box::new(relay_chain_header),
83		justification: grandpa_justification,
84	};
85	let submit_para_head = pallet_bridge_parachains::Call::<Runtime, PPI>::submit_parachain_heads {
86		at_relay_block: (
87			relay_chain_header_number.saturated_into(),
88			relay_chain_header_hash.into(),
89		),
90		parachains: parachain_heads,
91		parachain_heads_proof: para_heads_proof,
92	};
93	let submit_message = pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof {
94		relayer_id_at_bridged_chain: relayer_id_at_bridged_chain.into(),
95		proof: Box::new(message_proof),
96		messages_count: 1,
97		dispatch_weight: Weight::from_parts(1000000000, 0),
98	};
99	pallet_utility::Call::<Runtime>::batch_all {
100		calls: vec![submit_grandpa.into(), submit_para_head.into(), submit_message.into()],
101	}
102}
103
104/// Prepare a batch call with relay finality proof, parachain head proof and message delivery
105/// proof.
106pub fn make_complex_relayer_confirmation_batch<Runtime, GPI, PPI, MPI>(
107	relay_chain_header: BridgedHeader<Runtime, GPI>,
108	grandpa_justification: GrandpaJustification<BridgedHeader<Runtime, GPI>>,
109	parachain_heads: Vec<(ParaId, ParaHash)>,
110	para_heads_proof: ParaHeadsProof,
111	message_delivery_proof: FromBridgedChainMessagesDeliveryProof<ParaHash, LaneIdOf<Runtime, MPI>>,
112	relayers_state: UnrewardedRelayersState,
113) -> pallet_utility::Call<Runtime>
114where
115	Runtime: pallet_bridge_grandpa::Config<GPI>
116		+ pallet_bridge_parachains::Config<PPI>
117		+ pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>
118		+ pallet_utility::Config,
119	GPI: 'static,
120	PPI: 'static,
121	MPI: 'static,
122	<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain:
123		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
124	BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain,
125	<Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>>
126		+ From<pallet_bridge_parachains::Call<Runtime, PPI>>
127		+ From<pallet_bridge_messages::Call<Runtime, MPI>>,
128{
129	let relay_chain_header_hash = relay_chain_header.hash();
130	let relay_chain_header_number = *relay_chain_header.number();
131	let submit_grandpa = pallet_bridge_grandpa::Call::<Runtime, GPI>::submit_finality_proof {
132		finality_target: Box::new(relay_chain_header),
133		justification: grandpa_justification,
134	};
135	let submit_para_head = pallet_bridge_parachains::Call::<Runtime, PPI>::submit_parachain_heads {
136		at_relay_block: (
137			relay_chain_header_number.saturated_into(),
138			relay_chain_header_hash.into(),
139		),
140		parachains: parachain_heads,
141		parachain_heads_proof: para_heads_proof,
142	};
143	let submit_message_delivery_proof =
144		pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof {
145			proof: message_delivery_proof,
146			relayers_state,
147		};
148	pallet_utility::Call::<Runtime>::batch_all {
149		calls: vec![
150			submit_grandpa.into(),
151			submit_para_head.into(),
152			submit_message_delivery_proof.into(),
153		],
154	}
155}
156
157/// Prepare a call with message proof.
158pub fn make_standalone_relayer_delivery_call<Runtime, MPI>(
159	message_proof: FromBridgedChainMessagesProof<ParaHash, LaneIdOf<Runtime, MPI>>,
160	relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>,
161) -> Runtime::RuntimeCall
162where
163	Runtime: pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload>,
164	MPI: 'static,
165	Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>,
166	BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain,
167{
168	pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof {
169		relayer_id_at_bridged_chain: relayer_id_at_bridged_chain.into(),
170		proof: Box::new(message_proof),
171		messages_count: 1,
172		dispatch_weight: Weight::from_parts(1000000000, 0),
173	}
174	.into()
175}
176
177/// Prepare a call with message delivery proof.
178pub fn make_standalone_relayer_confirmation_call<Runtime, MPI>(
179	message_delivery_proof: FromBridgedChainMessagesDeliveryProof<ParaHash, LaneIdOf<Runtime, MPI>>,
180	relayers_state: UnrewardedRelayersState,
181) -> Runtime::RuntimeCall
182where
183	Runtime: pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>,
184	MPI: 'static,
185	Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>,
186	BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain,
187{
188	pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof {
189		proof: message_delivery_proof,
190		relayers_state,
191	}
192	.into()
193}
194
195/// Prepare storage proofs of messages, stored at the source chain.
196pub fn make_complex_relayer_delivery_proofs<
197	BridgedRelayChain,
198	BridgedParachain,
199	ThisChainWithMessages,
200	LaneId,
201>(
202	lane_id: LaneId,
203	xcm_message: Xcm<()>,
204	message_nonce: MessageNonce,
205	message_destination: Junctions,
206	para_header_number: u32,
207	relay_header_number: u32,
208	bridged_para_id: u32,
209	is_minimal_call: bool,
210) -> (
211	HeaderOf<BridgedRelayChain>,
212	GrandpaJustification<HeaderOf<BridgedRelayChain>>,
213	ParaHead,
214	Vec<(ParaId, ParaHash)>,
215	ParaHeadsProof,
216	FromBridgedChainMessagesProof<ParaHash, LaneId>,
217)
218where
219	BridgedRelayChain:
220		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
221	BridgedParachain: bp_runtime::Chain<Hash = ParaHash> + Parachain,
222	ThisChainWithMessages: ChainWithMessages,
223	LaneId: Copy + Encode,
224{
225	// prepare message
226	let message_payload = prepare_inbound_xcm(xcm_message, message_destination);
227	// prepare para storage proof containing message
228	let (para_state_root, para_storage_proof) =
229		prepare_messages_storage_proof::<BridgedParachain, ThisChainWithMessages, LaneId>(
230			lane_id,
231			message_nonce..=message_nonce,
232			None,
233			UnverifiedStorageProofParams::from_db_size(message_payload.len() as u32),
234			|_| message_payload.clone(),
235			encode_all_messages,
236			encode_lane_data,
237			false,
238			false,
239		);
240
241	let (relay_chain_header, justification, bridged_para_head, parachain_heads, para_heads_proof) =
242		make_complex_bridged_parachain_heads_proof::<BridgedRelayChain, BridgedParachain>(
243			para_state_root,
244			para_header_number,
245			relay_header_number,
246			bridged_para_id,
247			is_minimal_call,
248		);
249
250	let message_proof = FromBridgedChainMessagesProof {
251		bridged_header_hash: bridged_para_head.hash(),
252		storage_proof: para_storage_proof,
253		lane: lane_id,
254		nonces_start: message_nonce,
255		nonces_end: message_nonce,
256	};
257
258	(
259		relay_chain_header,
260		justification,
261		bridged_para_head,
262		parachain_heads,
263		para_heads_proof,
264		message_proof,
265	)
266}
267
268/// Prepare storage proofs of message confirmations, stored at the target parachain.
269pub fn make_complex_relayer_confirmation_proofs<
270	BridgedRelayChain,
271	BridgedParachain,
272	ThisChainWithMessages,
273	LaneId,
274>(
275	lane_id: LaneId,
276	para_header_number: u32,
277	relay_header_number: u32,
278	bridged_para_id: u32,
279	relayer_id_at_this_chain: AccountIdOf<ThisChainWithMessages>,
280	relayers_state: UnrewardedRelayersState,
281) -> (
282	HeaderOf<BridgedRelayChain>,
283	GrandpaJustification<HeaderOf<BridgedRelayChain>>,
284	ParaHead,
285	Vec<(ParaId, ParaHash)>,
286	ParaHeadsProof,
287	FromBridgedChainMessagesDeliveryProof<ParaHash, LaneId>,
288)
289where
290	BridgedRelayChain:
291		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
292	BridgedParachain: bp_runtime::Chain<Hash = ParaHash> + Parachain,
293	ThisChainWithMessages: ChainWithMessages,
294	LaneId: Copy + Encode,
295{
296	// prepare para storage proof containing message delivery proof
297	let (para_state_root, para_storage_proof) =
298		prepare_message_delivery_storage_proof::<BridgedParachain, ThisChainWithMessages, LaneId>(
299			lane_id,
300			InboundLaneData {
301				state: LaneState::Opened,
302				relayers: vec![
303					UnrewardedRelayer {
304						relayer: relayer_id_at_this_chain.into(),
305						messages: DeliveredMessages::new(1)
306					};
307					relayers_state.unrewarded_relayer_entries as usize
308				]
309				.into(),
310				last_confirmed_nonce: 1,
311			},
312			UnverifiedStorageProofParams::default(),
313		);
314
315	let (relay_chain_header, justification, bridged_para_head, parachain_heads, para_heads_proof) =
316		make_complex_bridged_parachain_heads_proof::<BridgedRelayChain, BridgedParachain>(
317			para_state_root,
318			para_header_number,
319			relay_header_number,
320			bridged_para_id,
321			false,
322		);
323
324	let message_delivery_proof = FromBridgedChainMessagesDeliveryProof {
325		bridged_header_hash: bridged_para_head.hash(),
326		storage_proof: para_storage_proof,
327		lane: lane_id,
328	};
329
330	(
331		relay_chain_header,
332		justification,
333		bridged_para_head,
334		parachain_heads,
335		para_heads_proof,
336		message_delivery_proof,
337	)
338}
339
340/// Make bridged parachain header with given state root and relay header that is finalizing it.
341pub fn make_complex_bridged_parachain_heads_proof<BridgedRelayChain, BridgedParachain>(
342	para_state_root: ParaHash,
343	para_header_number: u32,
344	relay_header_number: BlockNumberOf<BridgedRelayChain>,
345	bridged_para_id: u32,
346	is_minimal_call: bool,
347) -> (
348	HeaderOf<BridgedRelayChain>,
349	GrandpaJustification<HeaderOf<BridgedRelayChain>>,
350	ParaHead,
351	Vec<(ParaId, ParaHash)>,
352	ParaHeadsProof,
353)
354where
355	BridgedRelayChain:
356		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
357	BridgedParachain: bp_runtime::Chain<Hash = ParaHash> + Parachain,
358{
359	let bridged_para_head = ParaHead(
360		bp_test_utils::test_header_with_root::<HeaderOf<BridgedParachain>>(
361			para_header_number.into(),
362			para_state_root,
363		)
364		.encode(),
365	);
366	let (relay_state_root, para_heads_proof, parachain_heads) =
367		prepare_parachain_heads_proof::<HeaderOf<BridgedParachain>>(vec![(
368			bridged_para_id,
369			bridged_para_head.clone(),
370		)]);
371	assert_eq!(bridged_para_head.hash(), parachain_heads[0].1);
372
373	let (relay_chain_header, justification) =
374		make_complex_bridged_grandpa_header_proof::<BridgedRelayChain>(
375			relay_state_root,
376			relay_header_number,
377			is_minimal_call,
378		);
379
380	(relay_chain_header, justification, bridged_para_head, parachain_heads, para_heads_proof)
381}