referrerpolicy=no-referrer-when-downgrade

bridge_hub_test_utils/test_cases/
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//! Module contains predefined test-case scenarios for `Runtime` with bridging capabilities
18//! with remote parachain.
19
20use crate::{
21	test_cases::{bridges_prelude::*, helpers, run_test},
22	test_data,
23	test_data::XcmAsPlainPayload,
24};
25
26use alloc::{boxed::Box, vec};
27use bp_header_chain::ChainWithGrandpa;
28use bp_messages::UnrewardedRelayersState;
29use bp_polkadot_core::parachains::ParaHash;
30use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
31use bp_runtime::{Chain, Parachain};
32use frame_support::traits::{OnFinalize, OnInitialize};
33use frame_system::pallet_prelude::BlockNumberFor;
34use pallet_bridge_messages::{BridgedChainOf, LaneIdOf, ThisChainOf};
35use parachains_runtimes_test_utils::{
36	AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations,
37};
38use sp_core::Get;
39use sp_keyring::Sr25519Keyring::*;
40use sp_runtime::{traits::Header as HeaderT, AccountId32};
41use xcm::latest::prelude::*;
42
43/// Helper trait to test bridges with remote parachain.
44///
45/// This is only used to decrease amount of lines, dedicated to bounds.
46pub trait WithRemoteParachainHelper {
47	/// This chain runtime.
48	type Runtime: BasicParachainRuntime
49		+ cumulus_pallet_xcmp_queue::Config
50		+ BridgeGrandpaConfig<Self::GPI>
51		+ BridgeParachainsConfig<Self::PPI>
52		+ BridgeMessagesConfig<
53			Self::MPI,
54			InboundPayload = XcmAsPlainPayload,
55			OutboundPayload = XcmAsPlainPayload,
56		> + pallet_bridge_relayers::Config<Self::RPI, Reward = Self::RelayerReward>;
57	/// All pallets of this chain, excluding system pallet.
58	type AllPalletsWithoutSystem: OnInitialize<BlockNumberFor<Self::Runtime>>
59		+ OnFinalize<BlockNumberFor<Self::Runtime>>;
60	/// Instance of the `pallet-bridge-grandpa`, used to bridge with remote relay chain.
61	type GPI: 'static;
62	/// Instance of the `pallet-bridge-parachains`, used to bridge with remote parachain.
63	type PPI: 'static;
64	/// Instance of the `pallet-bridge-messages`, used to bridge with remote parachain.
65	type MPI: 'static;
66	/// Instance of the `pallet-bridge-relayers`, used to collect rewards from messages `MPI`
67	/// instance.
68	type RPI: 'static;
69	/// Relayer reward type.
70	type RelayerReward: From<RewardsAccountParams<LaneIdOf<Self::Runtime, Self::MPI>>>;
71}
72
73/// Adapter struct that implements `WithRemoteParachainHelper`.
74pub struct WithRemoteParachainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, RPI>(
75	core::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, RPI)>,
76);
77
78impl<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, RPI> WithRemoteParachainHelper
79	for WithRemoteParachainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, RPI>
80where
81	Runtime: BasicParachainRuntime
82		+ cumulus_pallet_xcmp_queue::Config
83		+ BridgeGrandpaConfig<GPI>
84		+ BridgeParachainsConfig<PPI>
85		+ BridgeMessagesConfig<
86			MPI,
87			InboundPayload = XcmAsPlainPayload,
88			OutboundPayload = XcmAsPlainPayload,
89		> + pallet_bridge_relayers::Config<RPI>,
90	AllPalletsWithoutSystem:
91		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
92	<Runtime as pallet_bridge_relayers::Config<RPI>>::Reward:
93		From<RewardsAccountParams<LaneIdOf<Runtime, MPI>>>,
94	GPI: 'static,
95	PPI: 'static,
96	MPI: 'static,
97	RPI: 'static,
98{
99	type Runtime = Runtime;
100	type AllPalletsWithoutSystem = AllPalletsWithoutSystem;
101	type GPI = GPI;
102	type PPI = PPI;
103	type MPI = MPI;
104	type RPI = RPI;
105	type RelayerReward = Runtime::Reward;
106}
107
108/// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer,
109/// with proofs (finality, para heads, message) independently submitted.
110/// Also verifies relayer transaction signed extensions work as intended.
111pub fn relayed_incoming_message_works<RuntimeHelper>(
112	collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
113	slot_durations: SlotDurations,
114	runtime_para_id: u32,
115	bridged_para_id: u32,
116	sibling_parachain_id: u32,
117	local_relay_chain_id: NetworkId,
118	prepare_configuration: impl Fn() -> LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
119	construct_and_apply_extrinsic: fn(
120		sp_keyring::Sr25519Keyring,
121		<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
122	) -> sp_runtime::DispatchOutcome,
123	expect_rewards: bool,
124) where
125	RuntimeHelper: WithRemoteParachainHelper,
126	AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
127	RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>>
128		+ From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>>
129		+ From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
130	BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain,
131	<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
132		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
133{
134	helpers::relayed_incoming_message_works::<
135		RuntimeHelper::Runtime,
136		RuntimeHelper::AllPalletsWithoutSystem,
137		RuntimeHelper::MPI,
138	>(
139		collator_session_key,
140		slot_durations,
141		runtime_para_id,
142		sibling_parachain_id,
143		local_relay_chain_id,
144		construct_and_apply_extrinsic,
145		|relayer_id_at_this_chain,
146		 relayer_id_at_bridged_chain,
147		 message_destination,
148		 message_nonce,
149		 xcm,
150		 bridged_chain_id| {
151			let para_header_number = 5;
152			let relay_header_number = 1;
153
154			let lane_id = prepare_configuration();
155
156			// start with bridged relay chain block#0
157			helpers::initialize_bridge_grandpa_pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
158				test_data::initialization_data::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(0),
159			);
160
161			// generate bridged relay chain finality, parachain heads and message proofs,
162			// to be submitted by relayer to this chain.
163			let (
164				relay_chain_header,
165				grandpa_justification,
166				parachain_head,
167				parachain_heads,
168				para_heads_proof,
169				message_proof,
170			) = test_data::from_parachain::make_complex_relayer_delivery_proofs::<
171				<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain,
172				BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
173				ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
174				LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
175			>(
176				lane_id,
177				xcm.into(),
178				message_nonce,
179				message_destination,
180				para_header_number,
181				relay_header_number,
182				bridged_para_id,
183				false,
184			);
185
186			let parachain_head_hash = parachain_head.hash();
187			let relay_chain_header_hash = relay_chain_header.hash();
188			let relay_chain_header_number = *relay_chain_header.number();
189			vec![
190				(
191					BridgeGrandpaCall::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::submit_finality_proof {
192						finality_target: Box::new(relay_chain_header),
193						justification: grandpa_justification,
194					}.into(),
195					helpers::VerifySubmitGrandpaFinalityProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::expect_best_header_hash(
196						relay_chain_header_hash,
197					),
198				),
199				(
200					BridgeParachainsCall::<RuntimeHelper::Runtime, RuntimeHelper::PPI>::submit_parachain_heads {
201						at_relay_block: (relay_chain_header_number, relay_chain_header_hash),
202						parachains: parachain_heads,
203						parachain_heads_proof: para_heads_proof,
204					}.into(),
205					helpers::VerifySubmitParachainHeaderProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::PPI>::expect_best_header_hash(
206						bridged_para_id,
207						parachain_head_hash,
208					),
209				),
210				(
211					BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof {
212						relayer_id_at_bridged_chain,
213						proof: Box::new(message_proof),
214						messages_count: 1,
215						dispatch_weight: Weight::from_parts(1000000000, 0),
216					}.into(),
217					Box::new((
218						helpers::VerifySubmitMessagesProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::expect_last_delivered_nonce(
219							lane_id,
220							1,
221						),
222						if expect_rewards {
223                            helpers::VerifyRelayerRewarded::<RuntimeHelper::Runtime, RuntimeHelper::RPI>::expect_relayer_reward(
224                                relayer_id_at_this_chain,
225                                RewardsAccountParams::new(
226                                    lane_id,
227                                    bridged_chain_id,
228                                    RewardsAccountOwner::ThisChain,
229                                ),
230                            )
231						} else {
232							Box::new(())
233						}
234					)),
235				),
236			]
237		},
238	);
239}
240
241/// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer,
242/// with proofs (finality, para heads, message) independently submitted.
243/// Finality and para heads are submitted for free in this test.
244/// Also verifies relayer transaction signed extensions work as intended.
245pub fn free_relay_extrinsic_works<RuntimeHelper>(
246	collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
247	slot_durations: SlotDurations,
248	runtime_para_id: u32,
249	bridged_para_id: u32,
250	sibling_parachain_id: u32,
251	local_relay_chain_id: NetworkId,
252	prepare_configuration: impl Fn() -> LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
253	construct_and_apply_extrinsic: fn(
254		sp_keyring::Sr25519Keyring,
255		<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
256	) -> sp_runtime::DispatchOutcome,
257	expect_rewards: bool,
258) where
259	RuntimeHelper: WithRemoteParachainHelper,
260	RuntimeHelper::Runtime: pallet_balances::Config,
261	AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
262	RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>>
263		+ From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>>
264		+ From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
265	BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain,
266	<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
267		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
268{
269	// ensure that the runtime allows free header submissions
270	let free_headers_interval = <RuntimeHelper::Runtime as BridgeGrandpaConfig<
271		RuntimeHelper::GPI,
272	>>::FreeHeadersInterval::get()
273	.expect("this test requires runtime, configured to accept headers for free; qed");
274
275	helpers::relayed_incoming_message_works::<
276		RuntimeHelper::Runtime,
277		RuntimeHelper::AllPalletsWithoutSystem,
278		RuntimeHelper::MPI,
279	>(
280		collator_session_key,
281		slot_durations,
282		runtime_para_id,
283		sibling_parachain_id,
284		local_relay_chain_id,
285		construct_and_apply_extrinsic,
286		|relayer_id_at_this_chain,
287		 relayer_id_at_bridged_chain,
288		 message_destination,
289		 message_nonce,
290		 xcm,
291		 bridged_chain_id| {
292			let lane_id = prepare_configuration();
293
294			// start with bridged relay chain block#0
295			let initial_block_number = 0;
296			helpers::initialize_bridge_grandpa_pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
297				test_data::initialization_data::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
298					initial_block_number,
299				),
300			);
301
302			// free relay chain header is `0 + free_headers_interval`
303			let relay_header_number = initial_block_number + free_headers_interval;
304			// first parachain header is always submitted for free
305			let para_header_number = 1;
306
307			// relayer balance shall not change after relay and para header submissions
308			let initial_relayer_balance =
309				pallet_balances::Pallet::<RuntimeHelper::Runtime>::free_balance(
310					relayer_id_at_this_chain.clone(),
311				);
312
313			// initialize the `FreeHeadersRemaining` storage value
314			pallet_bridge_grandpa::Pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::on_initialize(
315				0u32.into(),
316			);
317
318			// generate bridged relay chain finality, parachain heads and message proofs,
319			// to be submitted by relayer to this chain.
320			let (
321				relay_chain_header,
322				grandpa_justification,
323				parachain_head,
324				parachain_heads,
325				para_heads_proof,
326				message_proof,
327			) = test_data::from_parachain::make_complex_relayer_delivery_proofs::<
328				<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain,
329				BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
330				ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
331				LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
332			>(
333				lane_id,
334				xcm.into(),
335				message_nonce,
336				message_destination,
337				para_header_number,
338				relay_header_number,
339				bridged_para_id,
340				true,
341			);
342
343			let parachain_head_hash = parachain_head.hash();
344			let relay_chain_header_hash = relay_chain_header.hash();
345			let relay_chain_header_number = *relay_chain_header.number();
346			vec![
347				(
348					BridgeGrandpaCall::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::submit_finality_proof {
349						finality_target: Box::new(relay_chain_header),
350						justification: grandpa_justification,
351					}.into(),
352					Box::new((
353						helpers::VerifySubmitGrandpaFinalityProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::expect_best_header_hash(
354							relay_chain_header_hash,
355						),
356						helpers::VerifyRelayerBalance::<RuntimeHelper::Runtime>::expect_relayer_balance(
357							relayer_id_at_this_chain.clone(),
358							initial_relayer_balance,
359						),
360					)),
361				),
362				(
363					BridgeParachainsCall::<RuntimeHelper::Runtime, RuntimeHelper::PPI>::submit_parachain_heads {
364						at_relay_block: (relay_chain_header_number, relay_chain_header_hash),
365						parachains: parachain_heads,
366						parachain_heads_proof: para_heads_proof,
367					}.into(),
368					Box::new((
369						helpers::VerifySubmitParachainHeaderProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::PPI>::expect_best_header_hash(
370							bridged_para_id,
371							parachain_head_hash,
372						),
373						helpers::VerifyRelayerBalance::<RuntimeHelper::Runtime>::expect_relayer_balance(
374							relayer_id_at_this_chain.clone(),
375							initial_relayer_balance,
376						),
377					)),
378				),
379				(
380					BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof {
381						relayer_id_at_bridged_chain,
382						proof: Box::new(message_proof),
383						messages_count: 1,
384						dispatch_weight: Weight::from_parts(1000000000, 0),
385					}.into(),
386					Box::new((
387						helpers::VerifySubmitMessagesProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::expect_last_delivered_nonce(
388							lane_id,
389							1,
390						),
391						if expect_rewards {
392                            helpers::VerifyRelayerRewarded::<RuntimeHelper::Runtime, RuntimeHelper::RPI>::expect_relayer_reward(
393                                relayer_id_at_this_chain,
394                                RewardsAccountParams::new(
395                                    lane_id,
396                                    bridged_chain_id,
397                                    RewardsAccountOwner::ThisChain,
398                                ),
399                            )
400						} else {
401							Box::new(())
402						}
403					)),
404				),
405			]
406		},
407	);
408}
409
410/// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer,
411/// with proofs (finality, para heads, message) batched together in signed extrinsic.
412/// Also verifies relayer transaction signed extensions work as intended.
413pub fn complex_relay_extrinsic_works<RuntimeHelper>(
414	collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
415	slot_durations: SlotDurations,
416	runtime_para_id: u32,
417	bridged_para_id: u32,
418	sibling_parachain_id: u32,
419	local_relay_chain_id: NetworkId,
420	prepare_configuration: impl Fn() -> LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
421	construct_and_apply_extrinsic: fn(
422		sp_keyring::Sr25519Keyring,
423		<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
424	) -> sp_runtime::DispatchOutcome,
425) where
426	RuntimeHelper: WithRemoteParachainHelper,
427	RuntimeHelper::Runtime:
428		pallet_utility::Config<RuntimeCall = RuntimeCallOf<RuntimeHelper::Runtime>>,
429	AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
430	RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>>
431		+ From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>>
432		+ From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>
433		+ From<pallet_utility::Call<RuntimeHelper::Runtime>>,
434	BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain,
435	<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
436		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
437{
438	helpers::relayed_incoming_message_works::<
439		RuntimeHelper::Runtime,
440		RuntimeHelper::AllPalletsWithoutSystem,
441		RuntimeHelper::MPI,
442	>(
443		collator_session_key,
444		slot_durations,
445		runtime_para_id,
446		sibling_parachain_id,
447		local_relay_chain_id,
448		construct_and_apply_extrinsic,
449		|relayer_id_at_this_chain,
450		 relayer_id_at_bridged_chain,
451		 message_destination,
452		 message_nonce,
453		 xcm,
454		 bridged_chain_id| {
455			let para_header_number = 5;
456			let relay_header_number = 1;
457
458			let lane_id = prepare_configuration();
459
460			// start with bridged relay chain block#0
461			helpers::initialize_bridge_grandpa_pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
462				test_data::initialization_data::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(0),
463			);
464
465			// generate bridged relay chain finality, parachain heads and message proofs,
466			// to be submitted by relayer to this chain.
467			let (
468				relay_chain_header,
469				grandpa_justification,
470				parachain_head,
471				parachain_heads,
472				para_heads_proof,
473				message_proof,
474			) = test_data::from_parachain::make_complex_relayer_delivery_proofs::<
475				<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain,
476				BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
477				ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
478				LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
479			>(
480				lane_id,
481				xcm.into(),
482				message_nonce,
483				message_destination,
484				para_header_number,
485				relay_header_number,
486				bridged_para_id,
487				false,
488			);
489
490			let parachain_head_hash = parachain_head.hash();
491			let relay_chain_header_hash = relay_chain_header.hash();
492			let relay_chain_header_number = *relay_chain_header.number();
493			vec![
494				(
495					pallet_utility::Call::<RuntimeHelper::Runtime>::batch_all {
496						calls: vec![
497						BridgeGrandpaCall::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::submit_finality_proof {
498							finality_target: Box::new(relay_chain_header),
499							justification: grandpa_justification,
500						}.into(),
501						BridgeParachainsCall::<RuntimeHelper::Runtime, RuntimeHelper::PPI>::submit_parachain_heads {
502							at_relay_block: (relay_chain_header_number, relay_chain_header_hash),
503							parachains: parachain_heads,
504							parachain_heads_proof: para_heads_proof,
505						}.into(),
506						BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof {
507							relayer_id_at_bridged_chain,
508							proof: Box::new(message_proof),
509							messages_count: 1,
510							dispatch_weight: Weight::from_parts(1000000000, 0),
511						}.into(),
512					],
513					}
514					.into(),
515					Box::new(
516						(
517							helpers::VerifySubmitGrandpaFinalityProofOutcome::<
518								RuntimeHelper::Runtime,
519								RuntimeHelper::GPI,
520							>::expect_best_header_hash(relay_chain_header_hash),
521							helpers::VerifySubmitParachainHeaderProofOutcome::<
522								RuntimeHelper::Runtime,
523								RuntimeHelper::PPI,
524							>::expect_best_header_hash(bridged_para_id, parachain_head_hash),
525							helpers::VerifySubmitMessagesProofOutcome::<
526								RuntimeHelper::Runtime,
527								RuntimeHelper::MPI,
528							>::expect_last_delivered_nonce(lane_id, 1),
529							helpers::VerifyRelayerRewarded::<
530								RuntimeHelper::Runtime,
531								RuntimeHelper::RPI,
532							>::expect_relayer_reward(
533								relayer_id_at_this_chain,
534								RewardsAccountParams::new(
535									lane_id,
536									bridged_chain_id,
537									RewardsAccountOwner::ThisChain,
538								),
539							),
540						),
541					),
542				),
543			]
544		},
545	);
546}
547
548/// Estimates transaction fee for default message delivery transaction (batched with required
549/// proofs) from bridged parachain.
550pub fn can_calculate_fee_for_complex_message_delivery_transaction<RuntimeHelper>(
551	collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
552	compute_extrinsic_fee: fn(pallet_utility::Call<RuntimeHelper::Runtime>) -> u128,
553) -> u128
554where
555	RuntimeHelper: WithRemoteParachainHelper,
556	RuntimeHelper::Runtime:
557		pallet_utility::Config<RuntimeCall = RuntimeCallOf<RuntimeHelper::Runtime>>,
558	RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>>
559		+ From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>>
560		+ From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
561	BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain,
562	<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
563		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
564{
565	run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
566		// generate bridged relay chain finality, parachain heads and message proofs,
567		// to be submitted by relayer to this chain.
568		//
569		// we don't care about parameter values here, apart from the XCM message size. But we
570		// do not need to have a large message here, because we're charging for every byte of
571		// the message additionally
572		let (
573			relay_chain_header,
574			grandpa_justification,
575			_,
576			parachain_heads,
577			para_heads_proof,
578			message_proof,
579		) = test_data::from_parachain::make_complex_relayer_delivery_proofs::<
580			<RuntimeHelper::Runtime as pallet_bridge_grandpa::Config<RuntimeHelper::GPI>>::BridgedChain,
581			BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
582			ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
583			LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>
584		>(
585			LaneIdOf::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::default(),
586			vec![Instruction::<()>::ClearOrigin; 1_024].into(),
587			1,
588			[GlobalConsensus(Polkadot), Parachain(1_000)].into(),
589			1,
590			5,
591			1_000,
592			false,
593		);
594
595		// generate batch call that provides finality for bridged relay and parachains + message
596		// proof
597		let batch = test_data::from_parachain::make_complex_relayer_delivery_batch::<
598			RuntimeHelper::Runtime,
599			RuntimeHelper::GPI,
600			RuntimeHelper::PPI,
601			RuntimeHelper::MPI,
602		>(
603			relay_chain_header,
604			grandpa_justification,
605			parachain_heads,
606			para_heads_proof,
607			message_proof,
608			helpers::relayer_id_at_bridged_chain::<RuntimeHelper::Runtime, RuntimeHelper::MPI>(),
609		);
610
611		compute_extrinsic_fee(batch)
612	})
613}
614
615/// Estimates transaction fee for default message confirmation transaction (batched with required
616/// proofs) from bridged parachain.
617pub fn can_calculate_fee_for_complex_message_confirmation_transaction<RuntimeHelper>(
618	collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
619	compute_extrinsic_fee: fn(pallet_utility::Call<RuntimeHelper::Runtime>) -> u128,
620) -> u128
621where
622	RuntimeHelper: WithRemoteParachainHelper,
623	AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
624	RuntimeHelper::Runtime:
625		pallet_utility::Config<RuntimeCall = RuntimeCallOf<RuntimeHelper::Runtime>>,
626	ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>:
627		Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>,
628	RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>>
629		+ From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>>
630		+ From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
631	BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain,
632	<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
633		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
634{
635	run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
636		// generate bridged relay chain finality, parachain heads and message proofs,
637		// to be submitted by relayer to this chain.
638		let unrewarded_relayers = UnrewardedRelayersState {
639			unrewarded_relayer_entries: 1,
640			total_messages: 1,
641			..Default::default()
642		};
643		let (
644			relay_chain_header,
645			grandpa_justification,
646			_,
647			parachain_heads,
648			para_heads_proof,
649			message_delivery_proof,
650		) = test_data::from_parachain::make_complex_relayer_confirmation_proofs::<
651			<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain,
652			BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
653			ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
654			LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
655		>(
656			LaneIdOf::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::default(),
657			1,
658			5,
659			1_000,
660			AccountId32::from(Alice.public()).into(),
661			unrewarded_relayers.clone(),
662		);
663
664		// generate batch call that provides finality for bridged relay and parachains + message
665		// proof
666		let batch = test_data::from_parachain::make_complex_relayer_confirmation_batch::<
667			RuntimeHelper::Runtime,
668			RuntimeHelper::GPI,
669			RuntimeHelper::PPI,
670			RuntimeHelper::MPI,
671		>(
672			relay_chain_header,
673			grandpa_justification,
674			parachain_heads,
675			para_heads_proof,
676			message_delivery_proof,
677			unrewarded_relayers,
678		);
679
680		compute_extrinsic_fee(batch)
681	})
682}
683
684/// Estimates transaction fee for default message delivery transaction from bridged parachain.
685pub fn can_calculate_fee_for_standalone_message_delivery_transaction<RuntimeHelper>(
686	collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
687	compute_extrinsic_fee: fn(
688		<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
689	) -> u128,
690) -> u128
691where
692	RuntimeHelper: WithRemoteParachainHelper,
693	RuntimeCallOf<RuntimeHelper::Runtime>:
694		From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
695	BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain,
696	<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
697		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
698{
699	run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
700		// generate bridged relay chain finality, parachain heads and message proofs,
701		// to be submitted by relayer to this chain.
702		//
703		// we don't care about parameter values here, apart from the XCM message size. But we
704		// do not need to have a large message here, because we're charging for every byte of
705		// the message additionally
706		let (
707			_,
708			_,
709			_,
710			_,
711			_,
712			message_proof,
713		) = test_data::from_parachain::make_complex_relayer_delivery_proofs::<
714			<RuntimeHelper::Runtime as pallet_bridge_grandpa::Config<RuntimeHelper::GPI>>::BridgedChain,
715			BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
716			ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
717			LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
718		>(
719			LaneIdOf::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::default(),
720			vec![Instruction::<()>::ClearOrigin; 1_024].into(),
721			1,
722			[GlobalConsensus(Polkadot), Parachain(1_000)].into(),
723			1,
724			5,
725			1_000,
726			false,
727		);
728
729		let call = test_data::from_parachain::make_standalone_relayer_delivery_call::<
730			RuntimeHelper::Runtime,
731			RuntimeHelper::MPI,
732		>(
733			message_proof,
734			helpers::relayer_id_at_bridged_chain::<RuntimeHelper::Runtime, RuntimeHelper::MPI>(),
735		);
736
737		compute_extrinsic_fee(call)
738	})
739}
740
741/// Estimates transaction fee for default message confirmation transaction (batched with required
742/// proofs) from bridged parachain.
743pub fn can_calculate_fee_for_standalone_message_confirmation_transaction<RuntimeHelper>(
744	collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
745	compute_extrinsic_fee: fn(
746		<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
747	) -> u128,
748) -> u128
749where
750	RuntimeHelper: WithRemoteParachainHelper,
751	AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
752	ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>:
753		Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>,
754	RuntimeCallOf<RuntimeHelper::Runtime>:
755		From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
756	BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain,
757	<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
758		bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
759{
760	run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
761		// generate bridged relay chain finality, parachain heads and message proofs,
762		// to be submitted by relayer to this chain.
763		let unrewarded_relayers = UnrewardedRelayersState {
764			unrewarded_relayer_entries: 1,
765			total_messages: 1,
766			..Default::default()
767		};
768		let (_, _, _, _, _, message_delivery_proof) =
769			test_data::from_parachain::make_complex_relayer_confirmation_proofs::<
770				<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain,
771				BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
772				ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
773				LaneIdOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>,
774			>(
775				LaneIdOf::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::default(),
776				1,
777				5,
778				1_000,
779				AccountId32::from(Alice.public()).into(),
780				unrewarded_relayers.clone(),
781			);
782
783		let call = test_data::from_parachain::make_standalone_relayer_confirmation_call::<
784			RuntimeHelper::Runtime,
785			RuntimeHelper::MPI,
786		>(message_delivery_proof, unrewarded_relayers);
787
788		compute_extrinsic_fee(call)
789	})
790}