1use crate::{Config as RelayersConfig, Pallet as RelayersPallet, WeightInfoExt, LOG_TARGET};
26
27use bp_messages::{ChainWithMessages, MessageNonce};
28use bp_relayers::{
29 ExplicitOrAccountParams, ExtensionCallData, ExtensionCallInfo, ExtensionConfig,
30 RewardsAccountOwner, RewardsAccountParams,
31};
32use bp_runtime::{Chain, RangeInclusiveExt, StaticStrProvider};
33use codec::{Decode, DecodeWithMemTracking, Encode};
34use core::{fmt::Debug, marker::PhantomData};
35use frame_support::{
36 dispatch::{DispatchInfo, PostDispatchInfo},
37 pallet_prelude::TransactionSource,
38 weights::Weight,
39 CloneNoBound, DefaultNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
40};
41use frame_system::Config as SystemConfig;
42use pallet_bridge_messages::{
43 CallHelper as MessagesCallHelper, Config as BridgeMessagesConfig, LaneIdOf,
44};
45use pallet_transaction_payment::{
46 Config as TransactionPaymentConfig, OnChargeTransaction, Pallet as TransactionPaymentPallet,
47};
48use scale_info::TypeInfo;
49use sp_runtime::{
50 traits::{
51 AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf,
52 TransactionExtension, ValidateResult, Zero,
53 },
54 transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransactionBuilder},
55 DispatchResult, RuntimeDebug,
56};
57
58pub use grandpa_adapter::WithGrandpaChainExtensionConfig;
59pub use messages_adapter::WithMessagesExtensionConfig;
60pub use parachain_adapter::WithParachainExtensionConfig;
61pub use priority::*;
62
63mod grandpa_adapter;
64mod messages_adapter;
65mod parachain_adapter;
66mod priority;
67
68#[cfg_attr(test, derive(Debug, PartialEq))]
70pub struct PreDispatchData<
71 AccountId,
72 RemoteGrandpaChainBlockNumber: Debug,
73 LaneId: Clone + Copy + Debug,
74> {
75 relayer: AccountId,
77 call_info: ExtensionCallInfo<RemoteGrandpaChainBlockNumber, LaneId>,
79}
80
81impl<AccountId, RemoteGrandpaChainBlockNumber: Debug, LaneId: Clone + Copy + Debug>
82 PreDispatchData<AccountId, RemoteGrandpaChainBlockNumber, LaneId>
83{
84 #[cfg(test)]
87 pub fn submit_finality_proof_info_mut(
88 &mut self,
89 ) -> Option<&mut bp_header_chain::SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>> {
90 match self.call_info {
91 ExtensionCallInfo::AllFinalityAndMsgs(ref mut info, _, _) => Some(info),
92 ExtensionCallInfo::RelayFinalityAndMsgs(ref mut info, _) => Some(info),
93 _ => None,
94 }
95 }
96}
97
98#[derive(RuntimeDebug, PartialEq)]
100pub enum RelayerAccountAction<AccountId, RewardBalance, LaneId> {
101 None,
103 Reward(AccountId, RewardsAccountParams<LaneId>, RewardBalance),
105 Slash(AccountId, RewardsAccountParams<LaneId>),
107}
108
109#[derive(
117 DefaultNoBound,
118 CloneNoBound,
119 Decode,
120 DecodeWithMemTracking,
121 Encode,
122 EqNoBound,
123 PartialEqNoBound,
124 RuntimeDebugNoBound,
125 TypeInfo,
126)]
127#[scale_info(skip_type_params(Runtime, Config, LaneId))]
128pub struct BridgeRelayersTransactionExtension<Runtime, Config>(PhantomData<(Runtime, Config)>);
129
130impl<R, C> BridgeRelayersTransactionExtension<R, C>
131where
132 Self: 'static + Send + Sync,
133 R: RelayersConfig<C::BridgeRelayersPalletInstance>
134 + BridgeMessagesConfig<C::BridgeMessagesPalletInstance>
135 + TransactionPaymentConfig,
136 C: ExtensionConfig<Runtime = R>,
137 R::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
138 <R::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<R::AccountId> + Clone,
139 <R as TransactionPaymentConfig>::OnChargeTransaction: OnChargeTransaction<R>,
140 <R as RelayersConfig<C::BridgeRelayersPalletInstance>>::Reward:
141 From<RewardsAccountParams<C::LaneId>>,
142 <R as RelayersConfig<C::BridgeRelayersPalletInstance>>::RewardBalance: From<
143 <<R as TransactionPaymentConfig>::OnChargeTransaction as OnChargeTransaction<R>>::Balance,
144 >,
145 C::LaneId: From<LaneIdOf<R, C::BridgeMessagesPalletInstance>>,
146{
147 fn bundled_messages_for_priority_boost(
157 parsed_call: &ExtensionCallInfo<C::RemoteGrandpaChainBlockNumber, C::LaneId>,
158 ) -> Option<MessageNonce> {
159 if !parsed_call.is_receive_messages_proof_call() {
161 return None;
162 }
163
164 let bundled_messages = parsed_call.messages_call_info().bundled_messages().saturating_len();
166
167 let max_unconfirmed_messages_in_confirmation_tx = <R as BridgeMessagesConfig<C::BridgeMessagesPalletInstance>>::BridgedChain
169 ::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
170 if bundled_messages > max_unconfirmed_messages_in_confirmation_tx {
171 return None
172 }
173
174 Some(bundled_messages)
175 }
176
177 fn analyze_call_result(
180 pre: Option<PreDispatchData<R::AccountId, C::RemoteGrandpaChainBlockNumber, C::LaneId>>,
181 info: &DispatchInfo,
182 post_info: &PostDispatchInfo,
183 len: usize,
184 result: &DispatchResult,
185 ) -> RelayerAccountAction<R::AccountId, R::RewardBalance, C::LaneId> {
186 let (relayer, call_info) = match pre {
188 Some(pre) => (pre.relayer, pre.call_info),
189 _ => return RelayerAccountAction::None,
190 };
191
192 let lane_id = call_info.messages_call_info().lane_id();
195 let reward_account_params = RewardsAccountParams::new(
196 lane_id,
197 <R as BridgeMessagesConfig<C::BridgeMessagesPalletInstance>>::BridgedChain::ID,
198 if call_info.is_receive_messages_proof_call() {
199 RewardsAccountOwner::ThisChain
200 } else {
201 RewardsAccountOwner::BridgedChain
202 },
203 );
204
205 let may_slash_relayer = Self::bundled_messages_for_priority_boost(&call_info).is_some();
218 let slash_relayer_if_delivery_result = may_slash_relayer
219 .then(|| RelayerAccountAction::Slash(relayer.clone(), reward_account_params))
220 .unwrap_or(RelayerAccountAction::None);
221
222 if let Err(e) = result {
224 tracing::trace!(
225 target: LOG_TARGET,
226 error=?e,
227 id_provider=%Self::IDENTIFIER,
228 ?lane_id,
229 ?relayer,
230 "Relayer has submitted invalid messages transaction",
231 );
232 return slash_relayer_if_delivery_result
233 }
234
235 let mut call_data = ExtensionCallData::default();
237 if !C::check_call_result(&call_info, &mut call_data, &relayer) {
238 return slash_relayer_if_delivery_result
239 }
240
241 let tip = Zero::zero();
247
248 let post_info_len = len.saturating_sub(call_data.extra_size as usize);
250 let mut post_info_weight = post_info
251 .actual_weight
252 .unwrap_or(info.total_weight())
253 .saturating_sub(call_data.extra_weight);
254
255 if call_info.is_receive_messages_proof_call() {
257 post_info_weight = post_info_weight.saturating_sub(
258 <R as RelayersConfig<C::BridgeRelayersPalletInstance>>::WeightInfo::extra_weight_of_successful_receive_messages_proof_call(),
259 );
260 }
261
262 let mut post_info = *post_info;
264 post_info.actual_weight = Some(post_info_weight);
265 let refund = Self::compute_refund(info, &post_info, post_info_len, tip);
266
267 RelayerAccountAction::Reward(relayer, reward_account_params, refund.into())
269 }
270
271 fn compute_refund(
273 info: &DispatchInfo,
274 post_info: &PostDispatchInfo,
275 len: usize,
276 tip: <<R as TransactionPaymentConfig>::OnChargeTransaction as OnChargeTransaction<R>>::Balance,
277 ) -> <<R as TransactionPaymentConfig>::OnChargeTransaction as OnChargeTransaction<R>>::Balance
278 {
279 TransactionPaymentPallet::<R>::compute_actual_fee(len as _, info, post_info, tip)
280 }
281}
282
283impl<R, C> TransactionExtension<R::RuntimeCall> for BridgeRelayersTransactionExtension<R, C>
284where
285 Self: 'static + Send + Sync,
286 R: RelayersConfig<C::BridgeRelayersPalletInstance>
287 + BridgeMessagesConfig<C::BridgeMessagesPalletInstance>
288 + TransactionPaymentConfig,
289 C: ExtensionConfig<Runtime = R>,
290 R::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
291 <R::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<R::AccountId> + Clone,
292 <R as TransactionPaymentConfig>::OnChargeTransaction: OnChargeTransaction<R>,
293 <R as RelayersConfig<C::BridgeRelayersPalletInstance>>::Reward:
294 From<RewardsAccountParams<C::LaneId>>,
295 <R as RelayersConfig<C::BridgeRelayersPalletInstance>>::RewardBalance: From<
296 <<R as TransactionPaymentConfig>::OnChargeTransaction as OnChargeTransaction<R>>::Balance,
297 >,
298 C::LaneId: From<LaneIdOf<R, C::BridgeMessagesPalletInstance>>,
299{
300 const IDENTIFIER: &'static str = C::IdProvider::STR;
301 type Implicit = ();
302 type Pre = Option<PreDispatchData<R::AccountId, C::RemoteGrandpaChainBlockNumber, C::LaneId>>;
303 type Val = Self::Pre;
304
305 fn weight(&self, _call: &R::RuntimeCall) -> Weight {
306 Weight::zero()
307 }
308
309 fn validate(
310 &self,
311 origin: <R::RuntimeCall as Dispatchable>::RuntimeOrigin,
312 call: &R::RuntimeCall,
313 _info: &DispatchInfoOf<R::RuntimeCall>,
314 _len: usize,
315 _self_implicit: Self::Implicit,
316 _inherited_implication: &impl Encode,
317 _source: TransactionSource,
318 ) -> ValidateResult<Self::Val, R::RuntimeCall> {
319 let parsed_call = match C::parse_and_check_for_obsolete_call(call)? {
321 Some(parsed_call) => parsed_call,
322 None => return Ok((Default::default(), None, origin)),
323 };
324 let relayer = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?;
326
327 let data = PreDispatchData { relayer: relayer.clone(), call_info: parsed_call };
328
329 let bundled_messages = match Self::bundled_messages_for_priority_boost(&data.call_info) {
333 Some(bundled_messages) => bundled_messages,
334 None => return Ok((Default::default(), Some(data), origin)),
335 };
336
337 if !RelayersPallet::<R, C::BridgeRelayersPalletInstance>::is_registration_active(
339 &data.relayer,
340 ) {
341 return Ok((Default::default(), Some(data), origin))
342 }
343
344 let priority_boost =
346 priority::compute_priority_boost::<C::PriorityBoostPerMessage>(bundled_messages);
347 let valid_transaction = ValidTransactionBuilder::default().priority(priority_boost);
348
349 tracing::trace!(
350 target: LOG_TARGET,
351 id_provider=%Self::IDENTIFIER,
352 lane_id=?data.call_info.messages_call_info().lane_id(),
353 relayer=?data.relayer,
354 %bundled_messages,
355 %priority_boost,
356 "Has boosted priority of message delivery transaction of relayer"
357 );
358
359 let validity = valid_transaction.build()?;
360 Ok((validity, Some(data), origin))
361 }
362
363 fn prepare(
364 self,
365 val: Self::Val,
366 _origin: &<R::RuntimeCall as Dispatchable>::RuntimeOrigin,
367 _call: &R::RuntimeCall,
368 _info: &DispatchInfoOf<R::RuntimeCall>,
369 _len: usize,
370 ) -> Result<Self::Pre, TransactionValidityError> {
371 Ok(val.inspect(|data| {
372 tracing::trace!(
373 target: LOG_TARGET,
374 id_provider=%Self::IDENTIFIER,
375 lane_id=?data.call_info.messages_call_info().lane_id(),
376 call_info=?data.call_info,
377 "Parsed bridge transaction in prepare"
378 );
379 }))
380 }
381
382 fn post_dispatch_details(
383 pre: Self::Pre,
384 info: &DispatchInfoOf<R::RuntimeCall>,
385 post_info: &PostDispatchInfoOf<R::RuntimeCall>,
386 len: usize,
387 result: &DispatchResult,
388 ) -> Result<Weight, TransactionValidityError> {
389 let lane_id = pre.as_ref().map(|p| p.call_info.messages_call_info().lane_id());
390 let call_result = Self::analyze_call_result(pre, info, post_info, len, result);
391
392 match call_result {
393 RelayerAccountAction::None => (),
394 RelayerAccountAction::Reward(relayer, reward_account, reward) => {
395 RelayersPallet::<R, C::BridgeRelayersPalletInstance>::register_relayer_reward(
396 reward_account.into(),
397 &relayer,
398 reward,
399 );
400
401 tracing::trace!(
402 target: LOG_TARGET,
403 id_provider=%Self::IDENTIFIER,
404 ?lane_id,
405 ?relayer,
406 ?reward,
407 "Has registered reward"
408 );
409 },
410 RelayerAccountAction::Slash(relayer, slash_account) =>
411 RelayersPallet::<R, C::BridgeRelayersPalletInstance>::slash_and_deregister(
412 &relayer,
413 ExplicitOrAccountParams::Params(slash_account),
414 ),
415 }
416
417 Ok(Weight::zero())
418 }
419}
420
421pub(crate) fn verify_messages_call_succeeded<C>(
423 call_info: &ExtensionCallInfo<
424 C::RemoteGrandpaChainBlockNumber,
425 LaneIdOf<C::Runtime, C::BridgeMessagesPalletInstance>,
426 >,
427 _call_data: &mut ExtensionCallData,
428 relayer: &<C::Runtime as SystemConfig>::AccountId,
429) -> bool
430where
431 C: ExtensionConfig,
432 C::Runtime: BridgeMessagesConfig<C::BridgeMessagesPalletInstance>,
433{
434 let messages_call = call_info.messages_call_info();
435
436 if !MessagesCallHelper::<C::Runtime, C::BridgeMessagesPalletInstance>::was_successful(
437 messages_call,
438 ) {
439 tracing::trace!(
440 target: LOG_TARGET,
441 id_provider=%C::IdProvider::STR,
442 lane_id=?call_info.messages_call_info().lane_id(),
443 ?relayer,
444 "Relayer has submitted invalid messages call"
445 );
446 return false
447 }
448
449 true
450}
451
452#[cfg(test)]
453mod tests {
454 use super::*;
455 use crate::mock::*;
456
457 use bp_header_chain::{StoredHeaderDataBuilder, SubmitFinalityProofInfo};
458 use bp_messages::{
459 source_chain::FromBridgedChainMessagesDeliveryProof,
460 target_chain::FromBridgedChainMessagesProof, BaseMessagesProofInfo, DeliveredMessages,
461 InboundLaneData, MessageNonce, MessagesCallInfo, MessagesOperatingMode, OutboundLaneData,
462 ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, UnrewardedRelayer,
463 UnrewardedRelayerOccupation, UnrewardedRelayersState,
464 };
465 use bp_parachains::{BestParaHeadHash, ParaInfo, SubmitParachainHeadsInfo};
466 use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId};
467 use bp_relayers::RuntimeWithUtilityPallet;
468 use bp_runtime::{BasicOperatingMode, HeaderId, Parachain};
469 use bp_test_utils::{make_default_justification, test_keyring, TEST_GRANDPA_SET_ID};
470 use frame_support::{
471 __private::sp_tracing,
472 assert_storage_noop, parameter_types,
473 traits::{fungible::Mutate, ReservableCurrency},
474 weights::Weight,
475 };
476 use pallet_bridge_grandpa::{Call as GrandpaCall, Pallet as GrandpaPallet, StoredAuthoritySet};
477 use pallet_bridge_messages::{Call as MessagesCall, Pallet as MessagesPallet};
478 use pallet_bridge_parachains::{Call as ParachainsCall, Pallet as ParachainsPallet};
479 use pallet_utility::Call as UtilityCall;
480 use sp_runtime::{
481 traits::{ConstU64, DispatchTransaction, Header as HeaderT},
482 transaction_validity::{
483 InvalidTransaction, TransactionSource::External, TransactionValidity, ValidTransaction,
484 },
485 DispatchError,
486 };
487
488 parameter_types! {
489 TestParachain: u32 = BridgedUnderlyingParachain::PARACHAIN_ID;
490 pub MsgProofsRewardsAccount: RewardsAccountParams<TestLaneIdType> = RewardsAccountParams::new(
491 test_lane_id(),
492 TEST_BRIDGED_CHAIN_ID,
493 RewardsAccountOwner::ThisChain,
494 );
495 pub MsgDeliveryProofsRewardsAccount: RewardsAccountParams<TestLaneIdType> = RewardsAccountParams::new(
496 test_lane_id(),
497 TEST_BRIDGED_CHAIN_ID,
498 RewardsAccountOwner::BridgedChain,
499 );
500 }
501
502 bp_runtime::generate_static_str_provider!(TestGrandpaExtension);
503 bp_runtime::generate_static_str_provider!(TestExtension);
504 bp_runtime::generate_static_str_provider!(TestMessagesExtension);
505
506 type TestGrandpaExtensionConfig = grandpa_adapter::WithGrandpaChainExtensionConfig<
507 StrTestGrandpaExtension,
508 TestRuntime,
509 RuntimeWithUtilityPallet<TestRuntime>,
510 (),
511 (),
512 (),
513 ConstU64<1>,
514 >;
515 type TestGrandpaExtension =
516 BridgeRelayersTransactionExtension<TestRuntime, TestGrandpaExtensionConfig>;
517 type TestExtensionConfig = parachain_adapter::WithParachainExtensionConfig<
518 StrTestExtension,
519 TestRuntime,
520 RuntimeWithUtilityPallet<TestRuntime>,
521 (),
522 (),
523 (),
524 ConstU64<1>,
525 >;
526 type TestExtension = BridgeRelayersTransactionExtension<TestRuntime, TestExtensionConfig>;
527 type TestMessagesExtensionConfig = messages_adapter::WithMessagesExtensionConfig<
528 StrTestMessagesExtension,
529 TestRuntime,
530 (),
531 (),
532 ConstU64<1>,
533 >;
534 type TestMessagesExtension =
535 BridgeRelayersTransactionExtension<TestRuntime, TestMessagesExtensionConfig>;
536
537 fn initial_balance_of_relayer_account_at_this_chain() -> ThisChainBalance {
538 let test_stake: ThisChainBalance = Stake::get();
539 ExistentialDeposit::get().saturating_add(test_stake * 100)
540 }
541
542 fn delivery_rewards_account() -> ThisChainAccountId {
546 TestPaymentProcedure::rewards_account(MsgProofsRewardsAccount::get())
547 }
548
549 fn confirmation_rewards_account() -> ThisChainAccountId {
550 TestPaymentProcedure::rewards_account(MsgDeliveryProofsRewardsAccount::get())
551 }
552
553 fn relayer_account_at_this_chain() -> ThisChainAccountId {
554 0
555 }
556
557 fn relayer_account_at_bridged_chain() -> BridgedChainAccountId {
558 0
559 }
560
561 fn initialize_environment(
562 best_relay_header_number: BridgedChainBlockNumber,
563 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
564 best_message: MessageNonce,
565 ) {
566 let authorities = test_keyring().into_iter().map(|(a, w)| (a.into(), w)).collect();
567 let best_relay_header = HeaderId(best_relay_header_number, BridgedChainHash::default());
568 pallet_bridge_grandpa::CurrentAuthoritySet::<TestRuntime>::put(
569 StoredAuthoritySet::try_new(authorities, TEST_GRANDPA_SET_ID).unwrap(),
570 );
571 pallet_bridge_grandpa::BestFinalized::<TestRuntime>::put(best_relay_header);
572 pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::insert(
573 best_relay_header.hash(),
574 bp_test_utils::test_header::<BridgedChainHeader>(0).build(),
575 );
576
577 let para_id = ParaId(TestParachain::get());
578 let para_info = ParaInfo {
579 best_head_hash: BestParaHeadHash {
580 at_relay_block_number: parachain_head_at_relay_header_number,
581 head_hash: [parachain_head_at_relay_header_number as u8; 32].into(),
582 },
583 next_imported_hash_position: 0,
584 };
585 pallet_bridge_parachains::ParasInfo::<TestRuntime>::insert(para_id, para_info);
586
587 let lane_id = test_lane_id();
588 let in_lane_data =
589 InboundLaneData { last_confirmed_nonce: best_message, ..Default::default() };
590 pallet_bridge_messages::InboundLanes::<TestRuntime>::insert(lane_id, in_lane_data);
591
592 let out_lane_data =
593 OutboundLaneData { latest_received_nonce: best_message, ..Default::default() };
594 pallet_bridge_messages::OutboundLanes::<TestRuntime>::insert(lane_id, out_lane_data);
595
596 Balances::mint_into(&delivery_rewards_account(), ExistentialDeposit::get()).unwrap();
597 Balances::mint_into(&confirmation_rewards_account(), ExistentialDeposit::get()).unwrap();
598 Balances::mint_into(
599 &relayer_account_at_this_chain(),
600 initial_balance_of_relayer_account_at_this_chain(),
601 )
602 .unwrap();
603 }
604
605 fn submit_relay_header_call(relay_header_number: BridgedChainBlockNumber) -> RuntimeCall {
606 let relay_header = BridgedChainHeader::new(
607 relay_header_number,
608 Default::default(),
609 Default::default(),
610 Default::default(),
611 Default::default(),
612 );
613 let relay_justification = make_default_justification(&relay_header);
614
615 RuntimeCall::BridgeGrandpa(GrandpaCall::submit_finality_proof {
616 finality_target: Box::new(relay_header),
617 justification: relay_justification,
618 })
619 }
620
621 fn submit_relay_header_call_ex(relay_header_number: BridgedChainBlockNumber) -> RuntimeCall {
622 let relay_header = BridgedChainHeader::new(
623 relay_header_number,
624 Default::default(),
625 Default::default(),
626 Default::default(),
627 Default::default(),
628 );
629 let relay_justification = make_default_justification(&relay_header);
630
631 RuntimeCall::BridgeGrandpa(GrandpaCall::submit_finality_proof_ex {
632 finality_target: Box::new(relay_header),
633 justification: relay_justification,
634 current_set_id: TEST_GRANDPA_SET_ID,
635 is_free_execution_expected: false,
636 })
637 }
638
639 fn submit_parachain_head_call(
640 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
641 ) -> RuntimeCall {
642 RuntimeCall::BridgeParachains(ParachainsCall::submit_parachain_heads {
643 at_relay_block: (parachain_head_at_relay_header_number, BridgedChainHash::default()),
644 parachains: vec![(
645 ParaId(TestParachain::get()),
646 [parachain_head_at_relay_header_number as u8; 32].into(),
647 )],
648 parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() },
649 })
650 }
651
652 pub fn submit_parachain_head_call_ex(
653 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
654 ) -> RuntimeCall {
655 RuntimeCall::BridgeParachains(ParachainsCall::submit_parachain_heads_ex {
656 at_relay_block: (parachain_head_at_relay_header_number, BridgedChainHash::default()),
657 parachains: vec![(
658 ParaId(TestParachain::get()),
659 [parachain_head_at_relay_header_number as u8; 32].into(),
660 )],
661 parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() },
662 is_free_execution_expected: false,
663 })
664 }
665
666 fn message_delivery_call(best_message: MessageNonce) -> RuntimeCall {
667 RuntimeCall::BridgeMessages(MessagesCall::receive_messages_proof {
668 relayer_id_at_bridged_chain: relayer_account_at_bridged_chain(),
669 proof: Box::new(FromBridgedChainMessagesProof {
670 bridged_header_hash: Default::default(),
671 storage_proof: Default::default(),
672 lane: test_lane_id(),
673 nonces_start: pallet_bridge_messages::InboundLanes::<TestRuntime>::get(
674 test_lane_id(),
675 )
676 .unwrap()
677 .last_delivered_nonce() +
678 1,
679 nonces_end: best_message,
680 }),
681 messages_count: 1,
682 dispatch_weight: Weight::zero(),
683 })
684 }
685
686 fn message_confirmation_call(best_message: MessageNonce) -> RuntimeCall {
687 RuntimeCall::BridgeMessages(MessagesCall::receive_messages_delivery_proof {
688 proof: FromBridgedChainMessagesDeliveryProof {
689 bridged_header_hash: Default::default(),
690 storage_proof: Default::default(),
691 lane: test_lane_id(),
692 },
693 relayers_state: UnrewardedRelayersState {
694 last_delivered_nonce: best_message,
695 ..Default::default()
696 },
697 })
698 }
699
700 fn parachain_finality_and_delivery_batch_call(
701 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
702 best_message: MessageNonce,
703 ) -> RuntimeCall {
704 RuntimeCall::Utility(UtilityCall::batch_all {
705 calls: vec![
706 submit_parachain_head_call(parachain_head_at_relay_header_number),
707 message_delivery_call(best_message),
708 ],
709 })
710 }
711
712 fn parachain_finality_and_confirmation_batch_call(
713 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
714 best_message: MessageNonce,
715 ) -> RuntimeCall {
716 RuntimeCall::Utility(UtilityCall::batch_all {
717 calls: vec![
718 submit_parachain_head_call(parachain_head_at_relay_header_number),
719 message_confirmation_call(best_message),
720 ],
721 })
722 }
723
724 fn relay_finality_and_delivery_batch_call(
725 relay_header_number: BridgedChainBlockNumber,
726 best_message: MessageNonce,
727 ) -> RuntimeCall {
728 RuntimeCall::Utility(UtilityCall::batch_all {
729 calls: vec![
730 submit_relay_header_call(relay_header_number),
731 message_delivery_call(best_message),
732 ],
733 })
734 }
735
736 fn relay_finality_and_delivery_batch_call_ex(
737 relay_header_number: BridgedChainBlockNumber,
738 best_message: MessageNonce,
739 ) -> RuntimeCall {
740 RuntimeCall::Utility(UtilityCall::batch_all {
741 calls: vec![
742 submit_relay_header_call_ex(relay_header_number),
743 message_delivery_call(best_message),
744 ],
745 })
746 }
747
748 fn relay_finality_and_confirmation_batch_call(
749 relay_header_number: BridgedChainBlockNumber,
750 best_message: MessageNonce,
751 ) -> RuntimeCall {
752 RuntimeCall::Utility(UtilityCall::batch_all {
753 calls: vec![
754 submit_relay_header_call(relay_header_number),
755 message_confirmation_call(best_message),
756 ],
757 })
758 }
759
760 fn relay_finality_and_confirmation_batch_call_ex(
761 relay_header_number: BridgedChainBlockNumber,
762 best_message: MessageNonce,
763 ) -> RuntimeCall {
764 RuntimeCall::Utility(UtilityCall::batch_all {
765 calls: vec![
766 submit_relay_header_call_ex(relay_header_number),
767 message_confirmation_call(best_message),
768 ],
769 })
770 }
771
772 fn all_finality_and_delivery_batch_call(
773 relay_header_number: BridgedChainBlockNumber,
774 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
775 best_message: MessageNonce,
776 ) -> RuntimeCall {
777 RuntimeCall::Utility(UtilityCall::batch_all {
778 calls: vec![
779 submit_relay_header_call(relay_header_number),
780 submit_parachain_head_call(parachain_head_at_relay_header_number),
781 message_delivery_call(best_message),
782 ],
783 })
784 }
785
786 fn all_finality_and_delivery_batch_call_ex(
787 relay_header_number: BridgedChainBlockNumber,
788 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
789 best_message: MessageNonce,
790 ) -> RuntimeCall {
791 RuntimeCall::Utility(UtilityCall::batch_all {
792 calls: vec![
793 submit_relay_header_call_ex(relay_header_number),
794 submit_parachain_head_call_ex(parachain_head_at_relay_header_number),
795 message_delivery_call(best_message),
796 ],
797 })
798 }
799
800 fn all_finality_and_confirmation_batch_call(
801 relay_header_number: BridgedChainBlockNumber,
802 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
803 best_message: MessageNonce,
804 ) -> RuntimeCall {
805 RuntimeCall::Utility(UtilityCall::batch_all {
806 calls: vec![
807 submit_relay_header_call(relay_header_number),
808 submit_parachain_head_call(parachain_head_at_relay_header_number),
809 message_confirmation_call(best_message),
810 ],
811 })
812 }
813
814 fn all_finality_and_confirmation_batch_call_ex(
815 relay_header_number: BridgedChainBlockNumber,
816 parachain_head_at_relay_header_number: BridgedChainBlockNumber,
817 best_message: MessageNonce,
818 ) -> RuntimeCall {
819 RuntimeCall::Utility(UtilityCall::batch_all {
820 calls: vec![
821 submit_relay_header_call_ex(relay_header_number),
822 submit_parachain_head_call_ex(parachain_head_at_relay_header_number),
823 message_confirmation_call(best_message),
824 ],
825 })
826 }
827
828 fn all_finality_pre_dispatch_data(
829 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
830 PreDispatchData {
831 relayer: relayer_account_at_this_chain(),
832 call_info: ExtensionCallInfo::AllFinalityAndMsgs(
833 SubmitFinalityProofInfo {
834 block_number: 200,
835 current_set_id: None,
836 extra_weight: Weight::zero(),
837 extra_size: 0,
838 is_mandatory: false,
839 is_free_execution_expected: false,
840 },
841 SubmitParachainHeadsInfo {
842 at_relay_block: HeaderId(200, [0u8; 32].into()),
843 para_id: ParaId(TestParachain::get()),
844 para_head_hash: [200u8; 32].into(),
845 is_free_execution_expected: false,
846 },
847 MessagesCallInfo::ReceiveMessagesProof(ReceiveMessagesProofInfo {
848 base: BaseMessagesProofInfo {
849 lane_id: test_lane_id(),
850 bundled_range: 101..=200,
851 best_stored_nonce: 100,
852 },
853 unrewarded_relayers: UnrewardedRelayerOccupation {
854 free_relayer_slots:
855 BridgedUnderlyingParachain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
856 free_message_slots:
857 BridgedUnderlyingParachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
858 },
859 }),
860 ),
861 }
862 }
863
864 #[cfg(test)]
865 fn all_finality_pre_dispatch_data_ex(
866 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
867 let mut data = all_finality_pre_dispatch_data();
868 data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID);
869 data
870 }
871
872 fn all_finality_confirmation_pre_dispatch_data(
873 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
874 PreDispatchData {
875 relayer: relayer_account_at_this_chain(),
876 call_info: ExtensionCallInfo::AllFinalityAndMsgs(
877 SubmitFinalityProofInfo {
878 block_number: 200,
879 current_set_id: None,
880 extra_weight: Weight::zero(),
881 extra_size: 0,
882 is_mandatory: false,
883 is_free_execution_expected: false,
884 },
885 SubmitParachainHeadsInfo {
886 at_relay_block: HeaderId(200, [0u8; 32].into()),
887 para_id: ParaId(TestParachain::get()),
888 para_head_hash: [200u8; 32].into(),
889 is_free_execution_expected: false,
890 },
891 MessagesCallInfo::ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo(
892 BaseMessagesProofInfo {
893 lane_id: test_lane_id(),
894 bundled_range: 101..=200,
895 best_stored_nonce: 100,
896 },
897 )),
898 ),
899 }
900 }
901
902 fn all_finality_confirmation_pre_dispatch_data_ex(
903 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
904 let mut data = all_finality_confirmation_pre_dispatch_data();
905 data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID);
906 data
907 }
908
909 fn relay_finality_pre_dispatch_data(
910 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
911 PreDispatchData {
912 relayer: relayer_account_at_this_chain(),
913 call_info: ExtensionCallInfo::RelayFinalityAndMsgs(
914 SubmitFinalityProofInfo {
915 block_number: 200,
916 current_set_id: None,
917 extra_weight: Weight::zero(),
918 extra_size: 0,
919 is_mandatory: false,
920 is_free_execution_expected: false,
921 },
922 MessagesCallInfo::ReceiveMessagesProof(ReceiveMessagesProofInfo {
923 base: BaseMessagesProofInfo {
924 lane_id: test_lane_id(),
925 bundled_range: 101..=200,
926 best_stored_nonce: 100,
927 },
928 unrewarded_relayers: UnrewardedRelayerOccupation {
929 free_relayer_slots:
930 BridgedUnderlyingParachain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
931 free_message_slots:
932 BridgedUnderlyingParachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
933 },
934 }),
935 ),
936 }
937 }
938
939 fn relay_finality_pre_dispatch_data_ex(
940 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
941 let mut data = relay_finality_pre_dispatch_data();
942 data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID);
943 data
944 }
945
946 fn relay_finality_confirmation_pre_dispatch_data(
947 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
948 PreDispatchData {
949 relayer: relayer_account_at_this_chain(),
950 call_info: ExtensionCallInfo::RelayFinalityAndMsgs(
951 SubmitFinalityProofInfo {
952 block_number: 200,
953 current_set_id: None,
954 extra_weight: Weight::zero(),
955 extra_size: 0,
956 is_mandatory: false,
957 is_free_execution_expected: false,
958 },
959 MessagesCallInfo::ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo(
960 BaseMessagesProofInfo {
961 lane_id: test_lane_id(),
962 bundled_range: 101..=200,
963 best_stored_nonce: 100,
964 },
965 )),
966 ),
967 }
968 }
969
970 fn relay_finality_confirmation_pre_dispatch_data_ex(
971 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
972 let mut data = relay_finality_confirmation_pre_dispatch_data();
973 data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID);
974 data
975 }
976
977 fn parachain_finality_pre_dispatch_data(
978 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
979 PreDispatchData {
980 relayer: relayer_account_at_this_chain(),
981 call_info: ExtensionCallInfo::ParachainFinalityAndMsgs(
982 SubmitParachainHeadsInfo {
983 at_relay_block: HeaderId(200, [0u8; 32].into()),
984 para_id: ParaId(TestParachain::get()),
985 para_head_hash: [200u8; 32].into(),
986 is_free_execution_expected: false,
987 },
988 MessagesCallInfo::ReceiveMessagesProof(ReceiveMessagesProofInfo {
989 base: BaseMessagesProofInfo {
990 lane_id: test_lane_id(),
991 bundled_range: 101..=200,
992 best_stored_nonce: 100,
993 },
994 unrewarded_relayers: UnrewardedRelayerOccupation {
995 free_relayer_slots:
996 BridgedUnderlyingParachain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
997 free_message_slots:
998 BridgedUnderlyingParachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
999 },
1000 }),
1001 ),
1002 }
1003 }
1004
1005 fn parachain_finality_confirmation_pre_dispatch_data(
1006 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
1007 PreDispatchData {
1008 relayer: relayer_account_at_this_chain(),
1009 call_info: ExtensionCallInfo::ParachainFinalityAndMsgs(
1010 SubmitParachainHeadsInfo {
1011 at_relay_block: HeaderId(200, [0u8; 32].into()),
1012 para_id: ParaId(TestParachain::get()),
1013 para_head_hash: [200u8; 32].into(),
1014 is_free_execution_expected: false,
1015 },
1016 MessagesCallInfo::ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo(
1017 BaseMessagesProofInfo {
1018 lane_id: test_lane_id(),
1019 bundled_range: 101..=200,
1020 best_stored_nonce: 100,
1021 },
1022 )),
1023 ),
1024 }
1025 }
1026
1027 fn delivery_pre_dispatch_data<RemoteGrandpaChainBlockNumber: Debug>(
1028 ) -> PreDispatchData<ThisChainAccountId, RemoteGrandpaChainBlockNumber, TestLaneIdType> {
1029 PreDispatchData {
1030 relayer: relayer_account_at_this_chain(),
1031 call_info: ExtensionCallInfo::Msgs(MessagesCallInfo::ReceiveMessagesProof(
1032 ReceiveMessagesProofInfo {
1033 base: BaseMessagesProofInfo {
1034 lane_id: test_lane_id(),
1035 bundled_range: 101..=200,
1036 best_stored_nonce: 100,
1037 },
1038 unrewarded_relayers: UnrewardedRelayerOccupation {
1039 free_relayer_slots:
1040 BridgedUnderlyingParachain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
1041 free_message_slots:
1042 BridgedUnderlyingParachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
1043 },
1044 },
1045 )),
1046 }
1047 }
1048
1049 fn confirmation_pre_dispatch_data<RemoteGrandpaChainBlockNumber: Debug>(
1050 ) -> PreDispatchData<ThisChainAccountId, RemoteGrandpaChainBlockNumber, TestLaneIdType> {
1051 PreDispatchData {
1052 relayer: relayer_account_at_this_chain(),
1053 call_info: ExtensionCallInfo::Msgs(MessagesCallInfo::ReceiveMessagesDeliveryProof(
1054 ReceiveMessagesDeliveryProofInfo(BaseMessagesProofInfo {
1055 lane_id: test_lane_id(),
1056 bundled_range: 101..=200,
1057 best_stored_nonce: 100,
1058 }),
1059 )),
1060 }
1061 }
1062
1063 fn set_bundled_range_end(
1064 mut pre_dispatch_data: PreDispatchData<
1065 ThisChainAccountId,
1066 BridgedChainBlockNumber,
1067 TestLaneIdType,
1068 >,
1069 end: MessageNonce,
1070 ) -> PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType> {
1071 let msg_info = match pre_dispatch_data.call_info {
1072 ExtensionCallInfo::AllFinalityAndMsgs(_, _, ref mut info) => info,
1073 ExtensionCallInfo::RelayFinalityAndMsgs(_, ref mut info) => info,
1074 ExtensionCallInfo::ParachainFinalityAndMsgs(_, ref mut info) => info,
1075 ExtensionCallInfo::Msgs(ref mut info) => info,
1076 };
1077
1078 if let MessagesCallInfo::ReceiveMessagesProof(ref mut msg_info) = msg_info {
1079 msg_info.base.bundled_range = *msg_info.base.bundled_range.start()..=end
1080 }
1081
1082 pre_dispatch_data
1083 }
1084
1085 fn run_validate(call: RuntimeCall) -> TransactionValidity {
1086 let extension: TestExtension = BridgeRelayersTransactionExtension(PhantomData);
1087 extension
1088 .validate_only(
1089 Some(relayer_account_at_this_chain()).into(),
1090 &call,
1091 &DispatchInfo::default(),
1092 0,
1093 External,
1094 0,
1095 )
1096 .map(|t| t.0)
1097 }
1098
1099 fn run_grandpa_validate(call: RuntimeCall) -> TransactionValidity {
1100 let extension: TestGrandpaExtension = BridgeRelayersTransactionExtension(PhantomData);
1101 extension
1102 .validate_only(
1103 Some(relayer_account_at_this_chain()).into(),
1104 &call,
1105 &DispatchInfo::default(),
1106 0,
1107 External,
1108 0,
1109 )
1110 .map(|t| t.0)
1111 }
1112
1113 fn run_messages_validate(call: RuntimeCall) -> TransactionValidity {
1114 let extension: TestMessagesExtension = BridgeRelayersTransactionExtension(PhantomData);
1115 extension
1116 .validate_only(
1117 Some(relayer_account_at_this_chain()).into(),
1118 &call,
1119 &DispatchInfo::default(),
1120 0,
1121 External,
1122 0,
1123 )
1124 .map(|t| t.0)
1125 }
1126
1127 fn ignore_priority(tx: TransactionValidity) -> TransactionValidity {
1128 tx.map(|mut tx| {
1129 tx.priority = 0;
1130 tx
1131 })
1132 }
1133
1134 fn run_pre_dispatch(
1135 call: RuntimeCall,
1136 ) -> Result<
1137 Option<PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType>>,
1138 TransactionValidityError,
1139 > {
1140 sp_tracing::try_init_simple();
1141 let extension: TestExtension = BridgeRelayersTransactionExtension(PhantomData);
1142 extension
1143 .validate_and_prepare(
1144 Some(relayer_account_at_this_chain()).into(),
1145 &call,
1146 &DispatchInfo::default(),
1147 0,
1148 0,
1149 )
1150 .map(|(pre, _)| pre)
1151 }
1152
1153 fn run_grandpa_pre_dispatch(
1154 call: RuntimeCall,
1155 ) -> Result<
1156 Option<PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType>>,
1157 TransactionValidityError,
1158 > {
1159 let extension: TestGrandpaExtension = BridgeRelayersTransactionExtension(PhantomData);
1160 extension
1161 .validate_and_prepare(
1162 Some(relayer_account_at_this_chain()).into(),
1163 &call,
1164 &DispatchInfo::default(),
1165 0,
1166 0,
1167 )
1168 .map(|(pre, _)| pre)
1169 }
1170
1171 fn run_messages_pre_dispatch(
1172 call: RuntimeCall,
1173 ) -> Result<
1174 Option<PreDispatchData<ThisChainAccountId, (), TestLaneIdType>>,
1175 TransactionValidityError,
1176 > {
1177 let extension: TestMessagesExtension = BridgeRelayersTransactionExtension(PhantomData);
1178 extension
1179 .validate_and_prepare(
1180 Some(relayer_account_at_this_chain()).into(),
1181 &call,
1182 &DispatchInfo::default(),
1183 0,
1184 0,
1185 )
1186 .map(|(pre, _)| pre)
1187 }
1188
1189 fn dispatch_info() -> DispatchInfo {
1190 DispatchInfo {
1191 call_weight: Weight::from_parts(
1192 frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND,
1193 0,
1194 ),
1195 extension_weight: Weight::zero(),
1196 class: frame_support::dispatch::DispatchClass::Normal,
1197 pays_fee: frame_support::dispatch::Pays::Yes,
1198 }
1199 }
1200
1201 fn post_dispatch_info() -> PostDispatchInfo {
1202 PostDispatchInfo { actual_weight: None, pays_fee: frame_support::dispatch::Pays::Yes }
1203 }
1204
1205 fn run_post_dispatch(
1206 pre_dispatch_data: Option<
1207 PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType>,
1208 >,
1209 dispatch_result: DispatchResult,
1210 ) {
1211 let post_dispatch_result = TestExtension::post_dispatch_details(
1212 pre_dispatch_data,
1213 &dispatch_info(),
1214 &post_dispatch_info(),
1215 1024,
1216 &dispatch_result,
1217 );
1218 assert_eq!(post_dispatch_result, Ok(Weight::zero()));
1219 }
1220
1221 fn expected_delivery_reward() -> RewardBalance {
1222 let mut post_dispatch_info = post_dispatch_info();
1223 let extra_weight = <TestRuntime as RelayersConfig>::WeightInfo::extra_weight_of_successful_receive_messages_proof_call();
1224 post_dispatch_info.actual_weight =
1225 Some(dispatch_info().call_weight.saturating_sub(extra_weight));
1226 pallet_transaction_payment::Pallet::<TestRuntime>::compute_actual_fee(
1227 1024,
1228 &dispatch_info(),
1229 &post_dispatch_info,
1230 Zero::zero(),
1231 )
1232 }
1233
1234 fn expected_confirmation_reward() -> RewardBalance {
1235 pallet_transaction_payment::Pallet::<TestRuntime>::compute_actual_fee(
1236 1024,
1237 &dispatch_info(),
1238 &post_dispatch_info(),
1239 Zero::zero(),
1240 )
1241 }
1242
1243 #[test]
1244 fn validate_doesnt_boost_transaction_priority_if_relayer_is_not_registered() {
1245 run_test(|| {
1246 initialize_environment(100, 100, 100);
1247 Balances::set_balance(&relayer_account_at_this_chain(), ExistentialDeposit::get());
1248
1249 assert_eq!(run_validate(message_delivery_call(200)), Ok(Default::default()),);
1251 assert_eq!(
1252 run_validate(parachain_finality_and_delivery_batch_call(200, 200)),
1253 Ok(Default::default()),
1254 );
1255 assert_eq!(
1256 run_validate(all_finality_and_delivery_batch_call(200, 200, 200)),
1257 Ok(Default::default()),
1258 );
1259 assert_eq!(
1261 ignore_priority(run_validate(message_confirmation_call(200))),
1262 Ok(Default::default()),
1263 );
1264 assert_eq!(
1265 ignore_priority(run_validate(parachain_finality_and_confirmation_batch_call(
1266 200, 200
1267 ))),
1268 Ok(Default::default()),
1269 );
1270 assert_eq!(
1271 ignore_priority(run_validate(all_finality_and_confirmation_batch_call(
1272 200, 200, 200
1273 ))),
1274 Ok(Default::default()),
1275 );
1276 });
1277 }
1278
1279 #[test]
1280 fn validate_boosts_priority_of_message_delivery_transactions() {
1281 run_test(|| {
1282 initialize_environment(100, 100, 100);
1283
1284 BridgeRelayers::register(RuntimeOrigin::signed(relayer_account_at_this_chain()), 1000)
1285 .unwrap();
1286
1287 let priority_of_100_messages_delivery =
1288 run_validate(message_delivery_call(200)).unwrap().priority;
1289 let priority_of_200_messages_delivery =
1290 run_validate(message_delivery_call(300)).unwrap().priority;
1291 assert!(
1292 priority_of_200_messages_delivery > priority_of_100_messages_delivery,
1293 "Invalid priorities: {} for 200 messages vs {} for 100 messages",
1294 priority_of_200_messages_delivery,
1295 priority_of_100_messages_delivery,
1296 );
1297
1298 let priority_of_100_messages_confirmation =
1299 run_validate(message_confirmation_call(200)).unwrap().priority;
1300 let priority_of_200_messages_confirmation =
1301 run_validate(message_confirmation_call(300)).unwrap().priority;
1302 assert_eq!(
1303 priority_of_100_messages_confirmation,
1304 priority_of_200_messages_confirmation
1305 );
1306 });
1307 }
1308
1309 #[test]
1310 fn validate_does_not_boost_priority_of_message_delivery_transactions_with_too_many_messages() {
1311 run_test(|| {
1312 initialize_environment(100, 100, 100);
1313
1314 BridgeRelayers::register(RuntimeOrigin::signed(relayer_account_at_this_chain()), 1000)
1315 .unwrap();
1316
1317 let priority_of_max_messages_delivery = run_validate(message_delivery_call(
1318 100 + BridgedUnderlyingParachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
1319 ))
1320 .unwrap()
1321 .priority;
1322 let priority_of_more_than_max_messages_delivery = run_validate(message_delivery_call(
1323 100 + BridgedUnderlyingParachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX + 1,
1324 ))
1325 .unwrap()
1326 .priority;
1327
1328 assert!(
1329 priority_of_max_messages_delivery > priority_of_more_than_max_messages_delivery,
1330 "Invalid priorities: {} for MAX messages vs {} for MAX+1 messages",
1331 priority_of_max_messages_delivery,
1332 priority_of_more_than_max_messages_delivery,
1333 );
1334 });
1335 }
1336
1337 #[test]
1338 fn validate_allows_non_obsolete_transactions() {
1339 run_test(|| {
1340 initialize_environment(100, 100, 100);
1341
1342 assert_eq!(
1343 ignore_priority(run_validate(message_delivery_call(200))),
1344 Ok(ValidTransaction::default()),
1345 );
1346 assert_eq!(
1347 ignore_priority(run_validate(message_confirmation_call(200))),
1348 Ok(ValidTransaction::default()),
1349 );
1350 assert_eq!(
1351 ignore_priority(run_messages_validate(message_delivery_call(200))),
1352 Ok(ValidTransaction::default()),
1353 );
1354
1355 assert_eq!(
1356 ignore_priority(run_validate(parachain_finality_and_delivery_batch_call(200, 200))),
1357 Ok(ValidTransaction::default()),
1358 );
1359 assert_eq!(
1360 ignore_priority(run_validate(parachain_finality_and_confirmation_batch_call(
1361 200, 200
1362 ))),
1363 Ok(ValidTransaction::default()),
1364 );
1365
1366 assert_eq!(
1367 ignore_priority(run_validate(all_finality_and_delivery_batch_call(200, 200, 200))),
1368 Ok(ValidTransaction::default()),
1369 );
1370 assert_eq!(
1371 ignore_priority(run_validate(all_finality_and_confirmation_batch_call(
1372 200, 200, 200
1373 ))),
1374 Ok(ValidTransaction::default()),
1375 );
1376 });
1377 }
1378
1379 #[test]
1380 fn ext_rejects_batch_with_obsolete_relay_chain_header() {
1381 run_test(|| {
1382 initialize_environment(100, 100, 100);
1383
1384 assert_eq!(
1385 run_pre_dispatch(all_finality_and_delivery_batch_call(100, 200, 200)),
1386 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1387 );
1388 assert_eq!(
1389 run_pre_dispatch(all_finality_and_delivery_batch_call_ex(100, 200, 200)),
1390 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1391 );
1392
1393 assert_eq!(
1394 run_validate(all_finality_and_delivery_batch_call(100, 200, 200)),
1395 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1396 );
1397 assert_eq!(
1398 run_validate(all_finality_and_delivery_batch_call_ex(100, 200, 200)),
1399 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1400 );
1401 });
1402 }
1403
1404 #[test]
1405 fn ext_rejects_batch_with_obsolete_parachain_head() {
1406 run_test(|| {
1407 initialize_environment(100, 100, 100);
1408
1409 assert_eq!(
1410 run_pre_dispatch(all_finality_and_delivery_batch_call(101, 100, 200)),
1411 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1412 );
1413 assert_eq!(
1414 run_pre_dispatch(all_finality_and_delivery_batch_call_ex(101, 100, 200)),
1415 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1416 );
1417 assert_eq!(
1418 run_validate(all_finality_and_delivery_batch_call(101, 100, 200)),
1419 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1420 );
1421 assert_eq!(
1422 run_validate(all_finality_and_delivery_batch_call_ex(101, 100, 200)),
1423 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1424 );
1425
1426 assert_eq!(
1427 run_pre_dispatch(parachain_finality_and_delivery_batch_call(100, 200)),
1428 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1429 );
1430 assert_eq!(
1431 run_validate(parachain_finality_and_delivery_batch_call(100, 200)),
1432 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1433 );
1434 });
1435 }
1436
1437 #[test]
1438 fn ext_rejects_batch_with_obsolete_messages() {
1439 run_test(|| {
1440 initialize_environment(100, 100, 100);
1441
1442 assert_eq!(
1443 run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 100)),
1444 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1445 );
1446 assert_eq!(
1447 run_pre_dispatch(all_finality_and_delivery_batch_call_ex(200, 200, 100)),
1448 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1449 );
1450 assert_eq!(
1451 run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 100)),
1452 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1453 );
1454 assert_eq!(
1455 run_pre_dispatch(all_finality_and_confirmation_batch_call_ex(200, 200, 100)),
1456 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1457 );
1458
1459 assert_eq!(
1460 run_validate(all_finality_and_delivery_batch_call(200, 200, 100)),
1461 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1462 );
1463 assert_eq!(
1464 run_validate(all_finality_and_delivery_batch_call_ex(200, 200, 100)),
1465 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1466 );
1467 assert_eq!(
1468 run_validate(all_finality_and_confirmation_batch_call(200, 200, 100)),
1469 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1470 );
1471 assert_eq!(
1472 run_validate(all_finality_and_confirmation_batch_call_ex(200, 200, 100)),
1473 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1474 );
1475
1476 assert_eq!(
1477 run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 100)),
1478 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1479 );
1480 assert_eq!(
1481 run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 100)),
1482 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1483 );
1484
1485 assert_eq!(
1486 run_validate(parachain_finality_and_delivery_batch_call(200, 100)),
1487 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1488 );
1489 assert_eq!(
1490 run_validate(parachain_finality_and_confirmation_batch_call(200, 100)),
1491 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
1492 );
1493 });
1494 }
1495
1496 #[test]
1497 fn ext_rejects_batch_with_grandpa_finality_proof_when_grandpa_pallet_is_halted() {
1498 run_test(|| {
1499 initialize_environment(100, 100, 100);
1500
1501 GrandpaPallet::<TestRuntime, ()>::set_operating_mode(
1502 RuntimeOrigin::root(),
1503 BasicOperatingMode::Halted,
1504 )
1505 .unwrap();
1506
1507 assert_eq!(
1508 run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
1509 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1510 );
1511 assert_eq!(
1512 run_pre_dispatch(all_finality_and_delivery_batch_call_ex(200, 200, 200)),
1513 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1514 );
1515 assert_eq!(
1516 run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
1517 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1518 );
1519 assert_eq!(
1520 run_pre_dispatch(all_finality_and_confirmation_batch_call_ex(200, 200, 200)),
1521 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1522 );
1523 });
1524 }
1525
1526 #[test]
1527 fn ext_rejects_batch_with_parachain_finality_proof_when_parachains_pallet_is_halted() {
1528 run_test(|| {
1529 initialize_environment(100, 100, 100);
1530
1531 ParachainsPallet::<TestRuntime, ()>::set_operating_mode(
1532 RuntimeOrigin::root(),
1533 BasicOperatingMode::Halted,
1534 )
1535 .unwrap();
1536
1537 assert_eq!(
1538 run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
1539 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1540 );
1541 assert_eq!(
1542 run_pre_dispatch(all_finality_and_delivery_batch_call_ex(200, 200, 200)),
1543 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1544 );
1545 assert_eq!(
1546 run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
1547 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1548 );
1549 assert_eq!(
1550 run_pre_dispatch(all_finality_and_confirmation_batch_call_ex(200, 200, 200)),
1551 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1552 );
1553
1554 assert_eq!(
1555 run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 200)),
1556 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1557 );
1558 assert_eq!(
1559 run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 200)),
1560 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1561 );
1562 });
1563 }
1564
1565 #[test]
1566 fn ext_rejects_transaction_when_messages_pallet_is_halted() {
1567 run_test(|| {
1568 initialize_environment(100, 100, 100);
1569
1570 MessagesPallet::<TestRuntime, ()>::set_operating_mode(
1571 RuntimeOrigin::root(),
1572 MessagesOperatingMode::Basic(BasicOperatingMode::Halted),
1573 )
1574 .unwrap();
1575
1576 assert_eq!(
1577 run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
1578 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1579 );
1580 assert_eq!(
1581 run_pre_dispatch(all_finality_and_delivery_batch_call_ex(200, 200, 200)),
1582 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1583 );
1584 assert_eq!(
1585 run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
1586 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1587 );
1588 assert_eq!(
1589 run_pre_dispatch(all_finality_and_confirmation_batch_call_ex(200, 200, 200)),
1590 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1591 );
1592
1593 assert_eq!(
1594 run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 200)),
1595 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1596 );
1597 assert_eq!(
1598 run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 200)),
1599 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1600 );
1601
1602 assert_eq!(
1603 run_pre_dispatch(message_delivery_call(200)),
1604 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1605 );
1606 assert_eq!(
1607 run_pre_dispatch(message_confirmation_call(200)),
1608 Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1609 );
1610 });
1611 }
1612
1613 #[test]
1614 fn pre_dispatch_parses_batch_with_relay_chain_and_parachain_headers() {
1615 run_test(|| {
1616 initialize_environment(100, 100, 100);
1617
1618 assert_eq!(
1619 run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
1620 Ok(Some(all_finality_pre_dispatch_data())),
1621 );
1622 assert_eq!(
1623 run_pre_dispatch(all_finality_and_delivery_batch_call_ex(200, 200, 200)),
1624 Ok(Some(all_finality_pre_dispatch_data_ex())),
1625 );
1626 assert_eq!(
1627 run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
1628 Ok(Some(all_finality_confirmation_pre_dispatch_data())),
1629 );
1630 assert_eq!(
1631 run_pre_dispatch(all_finality_and_confirmation_batch_call_ex(200, 200, 200)),
1632 Ok(Some(all_finality_confirmation_pre_dispatch_data_ex())),
1633 );
1634 });
1635 }
1636
1637 #[test]
1638 fn pre_dispatch_parses_batch_with_parachain_header() {
1639 run_test(|| {
1640 initialize_environment(100, 100, 100);
1641
1642 assert_eq!(
1643 run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 200)),
1644 Ok(Some(parachain_finality_pre_dispatch_data())),
1645 );
1646 assert_eq!(
1647 run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 200)),
1648 Ok(Some(parachain_finality_confirmation_pre_dispatch_data())),
1649 );
1650 });
1651 }
1652
1653 #[test]
1654 fn pre_dispatch_fails_to_parse_batch_with_multiple_parachain_headers() {
1655 run_test(|| {
1656 initialize_environment(100, 100, 100);
1657
1658 let call = RuntimeCall::Utility(UtilityCall::batch_all {
1659 calls: vec![
1660 RuntimeCall::BridgeParachains(ParachainsCall::submit_parachain_heads {
1661 at_relay_block: (100, BridgedChainHash::default()),
1662 parachains: vec![
1663 (ParaId(TestParachain::get()), [1u8; 32].into()),
1664 (ParaId(TestParachain::get() + 1), [1u8; 32].into()),
1665 ],
1666 parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() },
1667 }),
1668 message_delivery_call(200),
1669 ],
1670 });
1671
1672 assert_eq!(run_pre_dispatch(call), Ok(None),);
1673 });
1674 }
1675
1676 #[test]
1677 fn pre_dispatch_parses_message_transaction() {
1678 run_test(|| {
1679 initialize_environment(100, 100, 100);
1680
1681 assert_eq!(
1682 run_pre_dispatch(message_delivery_call(200)),
1683 Ok(Some(delivery_pre_dispatch_data())),
1684 );
1685 assert_eq!(
1686 run_pre_dispatch(message_confirmation_call(200)),
1687 Ok(Some(confirmation_pre_dispatch_data())),
1688 );
1689 });
1690 }
1691
1692 #[test]
1693 fn post_dispatch_ignores_unknown_transaction() {
1694 run_test(|| {
1695 assert_storage_noop!(run_post_dispatch(None, Ok(())));
1696 });
1697 }
1698
1699 #[test]
1700 fn post_dispatch_ignores_failed_transaction() {
1701 run_test(|| {
1702 assert_storage_noop!(run_post_dispatch(
1703 Some(all_finality_pre_dispatch_data()),
1704 Err(DispatchError::BadOrigin)
1705 ));
1706 });
1707 }
1708
1709 #[test]
1710 fn post_dispatch_ignores_transaction_that_has_not_updated_relay_chain_state() {
1711 run_test(|| {
1712 initialize_environment(100, 200, 200);
1713
1714 assert_storage_noop!(run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(())));
1715 });
1716 }
1717
1718 #[test]
1719 fn post_dispatch_ignores_transaction_that_has_not_updated_parachain_state() {
1720 run_test(|| {
1721 initialize_environment(200, 100, 200);
1722
1723 assert_storage_noop!(run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(())));
1724 assert_storage_noop!(run_post_dispatch(
1725 Some(parachain_finality_pre_dispatch_data()),
1726 Ok(())
1727 ));
1728 });
1729 }
1730
1731 #[test]
1732 fn post_dispatch_ignores_transaction_that_has_not_delivered_any_messages() {
1733 run_test(|| {
1734 initialize_environment(200, 200, 100);
1735
1736 assert_storage_noop!(run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(())));
1737 assert_storage_noop!(run_post_dispatch(
1738 Some(parachain_finality_pre_dispatch_data()),
1739 Ok(())
1740 ));
1741 assert_storage_noop!(run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(())));
1742
1743 assert_storage_noop!(run_post_dispatch(
1744 Some(all_finality_confirmation_pre_dispatch_data()),
1745 Ok(())
1746 ));
1747 assert_storage_noop!(run_post_dispatch(
1748 Some(parachain_finality_confirmation_pre_dispatch_data()),
1749 Ok(())
1750 ));
1751 assert_storage_noop!(run_post_dispatch(Some(confirmation_pre_dispatch_data()), Ok(())));
1752 });
1753 }
1754
1755 #[test]
1756 fn post_dispatch_ignores_transaction_that_has_not_delivered_all_messages() {
1757 run_test(|| {
1758 initialize_environment(200, 200, 150);
1759
1760 assert_storage_noop!(run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(())));
1761 assert_storage_noop!(run_post_dispatch(
1762 Some(parachain_finality_pre_dispatch_data()),
1763 Ok(())
1764 ));
1765 assert_storage_noop!(run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(())));
1766
1767 assert_storage_noop!(run_post_dispatch(
1768 Some(all_finality_confirmation_pre_dispatch_data()),
1769 Ok(())
1770 ));
1771 assert_storage_noop!(run_post_dispatch(
1772 Some(parachain_finality_confirmation_pre_dispatch_data()),
1773 Ok(())
1774 ));
1775 assert_storage_noop!(run_post_dispatch(Some(confirmation_pre_dispatch_data()), Ok(())));
1776 });
1777 }
1778
1779 #[test]
1780 fn post_dispatch_refunds_relayer_in_all_finality_batch_with_extra_weight() {
1781 run_test(|| {
1782 initialize_environment(200, 200, 200);
1783
1784 let mut dispatch_info = dispatch_info();
1785 dispatch_info.call_weight = Weight::from_parts(
1786 frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND * 2,
1787 0,
1788 );
1789
1790 let pre_dispatch_data = all_finality_pre_dispatch_data();
1792 let regular_reward = expected_delivery_reward();
1793 run_post_dispatch(Some(pre_dispatch_data), Ok(()));
1794 assert_eq!(
1795 RelayersPallet::<TestRuntime>::relayer_reward(
1796 relayer_account_at_this_chain(),
1797 MsgProofsRewardsAccount::get()
1798 ),
1799 Some(regular_reward),
1800 );
1801
1802 let mut pre_dispatch_data = all_finality_pre_dispatch_data();
1804 match pre_dispatch_data.call_info {
1805 ExtensionCallInfo::AllFinalityAndMsgs(ref mut info, ..) => {
1806 info.extra_weight.set_ref_time(
1807 frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND,
1808 );
1809 info.extra_size = 32;
1810 },
1811 _ => unreachable!(),
1812 }
1813 run_post_dispatch(Some(pre_dispatch_data), Ok(()));
1814 let reward_after_two_calls = RelayersPallet::<TestRuntime>::relayer_reward(
1815 relayer_account_at_this_chain(),
1816 MsgProofsRewardsAccount::get(),
1817 )
1818 .unwrap();
1819 assert!(
1820 reward_after_two_calls < 2 * regular_reward,
1821 "{} must be < 2 * {}",
1822 reward_after_two_calls,
1823 2 * regular_reward,
1824 );
1825 });
1826 }
1827
1828 #[test]
1829 fn post_dispatch_refunds_relayer_in_all_finality_batch() {
1830 run_test(|| {
1831 initialize_environment(200, 200, 200);
1832
1833 run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(()));
1834 assert_eq!(
1835 RelayersPallet::<TestRuntime>::relayer_reward(
1836 relayer_account_at_this_chain(),
1837 MsgProofsRewardsAccount::get()
1838 ),
1839 Some(expected_delivery_reward()),
1840 );
1841
1842 run_post_dispatch(Some(all_finality_confirmation_pre_dispatch_data()), Ok(()));
1843 assert_eq!(
1844 RelayersPallet::<TestRuntime>::relayer_reward(
1845 relayer_account_at_this_chain(),
1846 MsgDeliveryProofsRewardsAccount::get()
1847 ),
1848 Some(expected_confirmation_reward()),
1849 );
1850 });
1851 }
1852
1853 #[test]
1854 fn post_dispatch_refunds_relayer_in_parachain_finality_batch() {
1855 run_test(|| {
1856 initialize_environment(200, 200, 200);
1857
1858 run_post_dispatch(Some(parachain_finality_pre_dispatch_data()), Ok(()));
1859 assert_eq!(
1860 RelayersPallet::<TestRuntime>::relayer_reward(
1861 relayer_account_at_this_chain(),
1862 MsgProofsRewardsAccount::get()
1863 ),
1864 Some(expected_delivery_reward()),
1865 );
1866
1867 run_post_dispatch(Some(parachain_finality_confirmation_pre_dispatch_data()), Ok(()));
1868 assert_eq!(
1869 RelayersPallet::<TestRuntime>::relayer_reward(
1870 relayer_account_at_this_chain(),
1871 MsgDeliveryProofsRewardsAccount::get()
1872 ),
1873 Some(expected_confirmation_reward()),
1874 );
1875 });
1876 }
1877
1878 #[test]
1879 fn post_dispatch_refunds_relayer_in_message_transaction() {
1880 run_test(|| {
1881 initialize_environment(200, 200, 200);
1882
1883 run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(()));
1884 assert_eq!(
1885 RelayersPallet::<TestRuntime>::relayer_reward(
1886 relayer_account_at_this_chain(),
1887 MsgProofsRewardsAccount::get()
1888 ),
1889 Some(expected_delivery_reward()),
1890 );
1891
1892 run_post_dispatch(Some(confirmation_pre_dispatch_data()), Ok(()));
1893 assert_eq!(
1894 RelayersPallet::<TestRuntime>::relayer_reward(
1895 relayer_account_at_this_chain(),
1896 MsgDeliveryProofsRewardsAccount::get()
1897 ),
1898 Some(expected_confirmation_reward()),
1899 );
1900 });
1901 }
1902
1903 #[test]
1904 fn post_dispatch_slashing_relayer_stake() {
1905 run_test(|| {
1906 initialize_environment(200, 200, 100);
1907
1908 let delivery_rewards_account_balance =
1909 Balances::free_balance(delivery_rewards_account());
1910
1911 let test_stake: ThisChainBalance = Stake::get();
1912 Balances::set_balance(
1913 &relayer_account_at_this_chain(),
1914 ExistentialDeposit::get() + test_stake * 10,
1915 );
1916
1917 BridgeRelayers::register(RuntimeOrigin::signed(relayer_account_at_this_chain()), 1000)
1919 .unwrap();
1920 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), test_stake);
1921 run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(()));
1922 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), 0);
1923 assert_eq!(
1924 delivery_rewards_account_balance + test_stake,
1925 Balances::free_balance(delivery_rewards_account())
1926 );
1927
1928 BridgeRelayers::register(RuntimeOrigin::signed(relayer_account_at_this_chain()), 1000)
1929 .unwrap();
1930 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), test_stake);
1931 run_post_dispatch(Some(parachain_finality_pre_dispatch_data()), Ok(()));
1932 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), 0);
1933 assert_eq!(
1934 delivery_rewards_account_balance + test_stake * 2,
1935 Balances::free_balance(delivery_rewards_account())
1936 );
1937
1938 BridgeRelayers::register(RuntimeOrigin::signed(relayer_account_at_this_chain()), 1000)
1939 .unwrap();
1940 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), test_stake);
1941 run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(()));
1942 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), 0);
1943 assert_eq!(
1944 delivery_rewards_account_balance + test_stake * 3,
1945 Balances::free_balance(delivery_rewards_account())
1946 );
1947
1948 let confirmation_rewards_account_balance =
1950 Balances::free_balance(confirmation_rewards_account());
1951
1952 Balances::reserve(&relayer_account_at_this_chain(), test_stake).unwrap();
1953 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), test_stake);
1954
1955 assert_eq!(
1956 confirmation_rewards_account_balance,
1957 Balances::free_balance(confirmation_rewards_account())
1958 );
1959 run_post_dispatch(Some(confirmation_pre_dispatch_data()), Ok(()));
1960 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), test_stake);
1961
1962 run_post_dispatch(Some(parachain_finality_confirmation_pre_dispatch_data()), Ok(()));
1963 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), test_stake);
1964
1965 run_post_dispatch(Some(all_finality_confirmation_pre_dispatch_data()), Ok(()));
1966 assert_eq!(Balances::reserved_balance(relayer_account_at_this_chain()), test_stake);
1967
1968 assert_eq!(
1970 delivery_rewards_account_balance + test_stake * 3,
1971 Balances::free_balance(delivery_rewards_account())
1972 );
1973 assert_eq!(
1974 confirmation_rewards_account_balance,
1975 Balances::free_balance(confirmation_rewards_account())
1976 );
1977 });
1978 }
1979
1980 fn run_analyze_call_result(
1981 pre_dispatch_data: PreDispatchData<
1982 ThisChainAccountId,
1983 BridgedChainBlockNumber,
1984 TestLaneIdType,
1985 >,
1986 dispatch_result: DispatchResult,
1987 ) -> RelayerAccountAction<ThisChainAccountId, RewardBalance, TestLaneIdType> {
1988 TestExtension::analyze_call_result(
1989 Some(pre_dispatch_data),
1990 &dispatch_info(),
1991 &post_dispatch_info(),
1992 1024,
1993 &dispatch_result,
1994 )
1995 }
1996
1997 #[test]
1998 fn analyze_call_result_shall_not_slash_for_transactions_with_too_many_messages() {
1999 run_test(|| {
2000 initialize_environment(100, 100, 100);
2001
2002 assert_eq!(
2005 run_analyze_call_result(all_finality_pre_dispatch_data(), Ok(())),
2006 RelayerAccountAction::Slash(
2007 relayer_account_at_this_chain(),
2008 MsgProofsRewardsAccount::get()
2009 ),
2010 );
2011 assert_eq!(
2012 run_analyze_call_result(parachain_finality_pre_dispatch_data(), Ok(())),
2013 RelayerAccountAction::Slash(
2014 relayer_account_at_this_chain(),
2015 MsgProofsRewardsAccount::get()
2016 ),
2017 );
2018 assert_eq!(
2019 run_analyze_call_result(delivery_pre_dispatch_data(), Ok(())),
2020 RelayerAccountAction::Slash(
2021 relayer_account_at_this_chain(),
2022 MsgProofsRewardsAccount::get()
2023 ),
2024 );
2025
2026 assert_eq!(
2029 run_analyze_call_result(
2030 set_bundled_range_end(all_finality_pre_dispatch_data(), 1_000_000),
2031 Ok(())
2032 ),
2033 RelayerAccountAction::None,
2034 );
2035 assert_eq!(
2036 run_analyze_call_result(
2037 set_bundled_range_end(parachain_finality_pre_dispatch_data(), 1_000_000),
2038 Ok(())
2039 ),
2040 RelayerAccountAction::None,
2041 );
2042 assert_eq!(
2043 run_analyze_call_result(
2044 set_bundled_range_end(delivery_pre_dispatch_data(), 1_000_000),
2045 Ok(())
2046 ),
2047 RelayerAccountAction::None,
2048 );
2049 });
2050 }
2051
2052 #[test]
2053 fn grandpa_ext_only_parses_valid_batches() {
2054 run_test(|| {
2055 initialize_environment(100, 100, 100);
2056
2057 assert_eq!(
2059 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2060 &all_finality_and_delivery_batch_call(200, 200, 200)
2061 ),
2062 Ok(None),
2063 );
2064
2065 assert_eq!(
2067 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2068 &all_finality_and_confirmation_batch_call(200, 200, 200)
2069 ),
2070 Ok(None),
2071 );
2072
2073 assert_eq!(
2075 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2076 ¶chain_finality_and_delivery_batch_call(200, 200)
2077 ),
2078 Ok(None),
2079 );
2080
2081 assert_eq!(
2083 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2084 ¶chain_finality_and_confirmation_batch_call(200, 200)
2085 ),
2086 Ok(None),
2087 );
2088
2089 assert_eq!(
2091 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2092 &relay_finality_and_delivery_batch_call(200, 200)
2093 ),
2094 Ok(Some(relay_finality_pre_dispatch_data().call_info)),
2095 );
2096
2097 assert_eq!(
2099 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2100 &relay_finality_and_confirmation_batch_call(200, 200)
2101 ),
2102 Ok(Some(relay_finality_confirmation_pre_dispatch_data().call_info)),
2103 );
2104
2105 assert_eq!(
2107 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2108 &message_delivery_call(200)
2109 ),
2110 Ok(Some(delivery_pre_dispatch_data().call_info)),
2111 );
2112
2113 assert_eq!(
2115 TestGrandpaExtensionConfig::parse_and_check_for_obsolete_call(
2116 &message_confirmation_call(200)
2117 ),
2118 Ok(Some(confirmation_pre_dispatch_data().call_info)),
2119 );
2120 });
2121 }
2122
2123 #[test]
2124 fn messages_ext_only_parses_standalone_transactions() {
2125 run_test(|| {
2126 initialize_environment(100, 100, 100);
2127
2128 assert_eq!(
2130 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2131 &all_finality_and_delivery_batch_call(200, 200, 200)
2132 ),
2133 Ok(None),
2134 );
2135 assert_eq!(
2136 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2137 &all_finality_and_delivery_batch_call_ex(200, 200, 200)
2138 ),
2139 Ok(None),
2140 );
2141
2142 assert_eq!(
2144 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2145 &all_finality_and_confirmation_batch_call(200, 200, 200)
2146 ),
2147 Ok(None),
2148 );
2149 assert_eq!(
2150 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2151 &all_finality_and_confirmation_batch_call_ex(200, 200, 200)
2152 ),
2153 Ok(None),
2154 );
2155
2156 assert_eq!(
2158 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2159 ¶chain_finality_and_delivery_batch_call(200, 200)
2160 ),
2161 Ok(None),
2162 );
2163
2164 assert_eq!(
2166 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2167 ¶chain_finality_and_confirmation_batch_call(200, 200)
2168 ),
2169 Ok(None),
2170 );
2171
2172 assert_eq!(
2174 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2175 &relay_finality_and_delivery_batch_call(200, 200)
2176 ),
2177 Ok(None),
2178 );
2179 assert_eq!(
2180 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2181 &relay_finality_and_delivery_batch_call_ex(200, 200)
2182 ),
2183 Ok(None),
2184 );
2185
2186 assert_eq!(
2188 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2189 &relay_finality_and_confirmation_batch_call(200, 200)
2190 ),
2191 Ok(None),
2192 );
2193 assert_eq!(
2194 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2195 &relay_finality_and_confirmation_batch_call_ex(200, 200)
2196 ),
2197 Ok(None),
2198 );
2199
2200 assert_eq!(
2202 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2203 &message_delivery_call(200)
2204 ),
2205 Ok(Some(delivery_pre_dispatch_data().call_info)),
2206 );
2207
2208 assert_eq!(
2210 TestMessagesExtensionConfig::parse_and_check_for_obsolete_call(
2211 &message_confirmation_call(200)
2212 ),
2213 Ok(Some(confirmation_pre_dispatch_data().call_info)),
2214 );
2215 });
2216 }
2217
2218 #[test]
2219 fn messages_ext_rejects_calls_with_obsolete_messages() {
2220 run_test(|| {
2221 initialize_environment(100, 100, 100);
2222
2223 assert_eq!(
2224 run_messages_pre_dispatch(message_delivery_call(100)),
2225 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2226 );
2227 assert_eq!(
2228 run_messages_pre_dispatch(message_confirmation_call(100)),
2229 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2230 );
2231
2232 assert_eq!(
2233 run_messages_validate(message_delivery_call(100)),
2234 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2235 );
2236 assert_eq!(
2237 run_messages_validate(message_confirmation_call(100)),
2238 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2239 );
2240 });
2241 }
2242
2243 #[test]
2244 fn messages_ext_accepts_calls_with_new_messages() {
2245 run_test(|| {
2246 initialize_environment(100, 100, 100);
2247
2248 assert_eq!(
2249 run_messages_pre_dispatch(message_delivery_call(200)),
2250 Ok(Some(delivery_pre_dispatch_data())),
2251 );
2252 assert_eq!(
2253 run_messages_pre_dispatch(message_confirmation_call(200)),
2254 Ok(Some(confirmation_pre_dispatch_data())),
2255 );
2256
2257 assert_eq!(run_messages_validate(message_delivery_call(200)), Ok(Default::default()),);
2258 assert_eq!(
2259 run_messages_validate(message_confirmation_call(200)),
2260 Ok(Default::default()),
2261 );
2262 });
2263 }
2264
2265 #[test]
2266 fn grandpa_ext_rejects_batch_with_obsolete_relay_chain_header() {
2267 run_test(|| {
2268 initialize_environment(100, 100, 100);
2269
2270 assert_eq!(
2271 run_grandpa_pre_dispatch(relay_finality_and_delivery_batch_call(100, 200)),
2272 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2273 );
2274 assert_eq!(
2275 run_grandpa_pre_dispatch(relay_finality_and_delivery_batch_call_ex(100, 200)),
2276 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2277 );
2278
2279 assert_eq!(
2280 run_grandpa_validate(relay_finality_and_delivery_batch_call(100, 200)),
2281 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2282 );
2283 assert_eq!(
2284 run_grandpa_validate(relay_finality_and_delivery_batch_call_ex(100, 200)),
2285 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2286 );
2287 });
2288 }
2289
2290 #[test]
2291 fn grandpa_ext_rejects_calls_with_obsolete_messages() {
2292 run_test(|| {
2293 initialize_environment(100, 100, 100);
2294
2295 assert_eq!(
2296 run_grandpa_pre_dispatch(relay_finality_and_delivery_batch_call(200, 100)),
2297 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2298 );
2299 assert_eq!(
2300 run_grandpa_pre_dispatch(relay_finality_and_delivery_batch_call_ex(200, 100)),
2301 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2302 );
2303 assert_eq!(
2304 run_grandpa_pre_dispatch(relay_finality_and_confirmation_batch_call(200, 100)),
2305 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2306 );
2307 assert_eq!(
2308 run_grandpa_pre_dispatch(relay_finality_and_confirmation_batch_call_ex(200, 100)),
2309 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2310 );
2311
2312 assert_eq!(
2313 run_grandpa_validate(relay_finality_and_delivery_batch_call(200, 100)),
2314 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2315 );
2316 assert_eq!(
2317 run_grandpa_validate(relay_finality_and_delivery_batch_call_ex(200, 100)),
2318 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2319 );
2320 assert_eq!(
2321 run_grandpa_validate(relay_finality_and_confirmation_batch_call(200, 100)),
2322 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2323 );
2324 assert_eq!(
2325 run_grandpa_validate(relay_finality_and_confirmation_batch_call_ex(200, 100)),
2326 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2327 );
2328
2329 assert_eq!(
2330 run_grandpa_pre_dispatch(message_delivery_call(100)),
2331 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2332 );
2333 assert_eq!(
2334 run_grandpa_pre_dispatch(message_confirmation_call(100)),
2335 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2336 );
2337
2338 assert_eq!(
2339 run_grandpa_validate(message_delivery_call(100)),
2340 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2341 );
2342 assert_eq!(
2343 run_grandpa_validate(message_confirmation_call(100)),
2344 Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
2345 );
2346 });
2347 }
2348
2349 #[test]
2350 fn grandpa_ext_accepts_calls_with_new_messages() {
2351 run_test(|| {
2352 initialize_environment(100, 100, 100);
2353
2354 assert_eq!(
2355 run_grandpa_pre_dispatch(relay_finality_and_delivery_batch_call(200, 200)),
2356 Ok(Some(relay_finality_pre_dispatch_data()),)
2357 );
2358 assert_eq!(
2359 run_grandpa_pre_dispatch(relay_finality_and_delivery_batch_call_ex(200, 200)),
2360 Ok(Some(relay_finality_pre_dispatch_data_ex()),)
2361 );
2362 assert_eq!(
2363 run_grandpa_pre_dispatch(relay_finality_and_confirmation_batch_call(200, 200)),
2364 Ok(Some(relay_finality_confirmation_pre_dispatch_data())),
2365 );
2366 assert_eq!(
2367 run_grandpa_pre_dispatch(relay_finality_and_confirmation_batch_call_ex(200, 200)),
2368 Ok(Some(relay_finality_confirmation_pre_dispatch_data_ex())),
2369 );
2370
2371 assert_eq!(
2372 run_grandpa_validate(relay_finality_and_delivery_batch_call(200, 200)),
2373 Ok(Default::default()),
2374 );
2375 assert_eq!(
2376 run_grandpa_validate(relay_finality_and_delivery_batch_call_ex(200, 200)),
2377 Ok(Default::default()),
2378 );
2379 assert_eq!(
2380 run_grandpa_validate(relay_finality_and_confirmation_batch_call(200, 200)),
2381 Ok(Default::default()),
2382 );
2383 assert_eq!(
2384 run_grandpa_validate(relay_finality_and_confirmation_batch_call_ex(200, 200)),
2385 Ok(Default::default()),
2386 );
2387
2388 assert_eq!(
2389 run_grandpa_pre_dispatch(message_delivery_call(200)),
2390 Ok(Some(delivery_pre_dispatch_data())),
2391 );
2392 assert_eq!(
2393 run_grandpa_pre_dispatch(message_confirmation_call(200)),
2394 Ok(Some(confirmation_pre_dispatch_data())),
2395 );
2396
2397 assert_eq!(run_grandpa_validate(message_delivery_call(200)), Ok(Default::default()),);
2398 assert_eq!(
2399 run_grandpa_validate(message_confirmation_call(200)),
2400 Ok(Default::default()),
2401 );
2402 });
2403 }
2404
2405 #[test]
2406 fn does_not_panic_on_boosting_priority_of_empty_message_delivery_transaction() {
2407 run_test(|| {
2408 let best_delivered_message =
2409 BridgedUnderlyingParachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
2410 initialize_environment(100, 100, best_delivered_message);
2411
2412 BridgeRelayers::register(RuntimeOrigin::signed(relayer_account_at_this_chain()), 1000)
2414 .unwrap();
2415
2416 let lane_id = test_lane_id();
2418 let in_lane_data = InboundLaneData {
2419 last_confirmed_nonce: 0,
2420 relayers: vec![UnrewardedRelayer {
2421 relayer: relayer_account_at_bridged_chain(),
2422 messages: DeliveredMessages { begin: 1, end: best_delivered_message },
2423 }]
2424 .into(),
2425 ..Default::default()
2426 };
2427 pallet_bridge_messages::InboundLanes::<TestRuntime>::insert(lane_id, in_lane_data);
2428
2429 let priority_of_zero_messages_delivery =
2431 run_validate(message_delivery_call(best_delivered_message)).unwrap().priority;
2432 let priority_of_one_messages_delivery =
2433 run_validate(message_delivery_call(best_delivered_message + 1))
2434 .unwrap()
2435 .priority;
2436
2437 assert_eq!(priority_of_zero_messages_delivery, priority_of_one_messages_delivery);
2438 });
2439 }
2440}