referrerpolicy=no-referrer-when-downgrade

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