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