diff --git a/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index dcc8b15454c..4571909fafb 100644 --- a/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -172,27 +172,6 @@ mod bridge_hub_rococo_tests { Rococo, ); - #[test] - fn receive_single_message_proof() { - bridge_hub_test_utils::test_cases::receive_single_message_proof::< - Runtime, - XcmConfig, - ParachainSystem, - BridgeGrandpaWococoInstance, - BridgeParachainWococoInstance, - WithBridgeHubWococoMessagesInstance, - WithBridgeHubWococoMessageBridge, - >( - bridge_hub_test_utils::CollatorSessionKeys::new( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - ), - bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, - 1000, - ); - } - pub fn construct_extrinsic( sender: sp_core::sr25519::Pair, call: RuntimeCall, @@ -308,6 +287,8 @@ mod bridge_hub_rococo_tests { let some_currency = ExistentialDeposit::get() * 100000; Balances::mint_into(&relayer_id_on_target, some_currency).unwrap(); + let xcm = vec![xcm::v3::Instruction::<()>::ClearOrigin; 42]; + let expected_dispatch = xcm::VersionedXcm::<()>::V3(xcm.clone().into()); // generate bridged relay chain finality, parachain heads and message proofs, // to be submitted by relayer to this chain. let ( @@ -320,8 +301,10 @@ mod bridge_hub_rococo_tests { ) = test_data::make_complex_relayer_proofs::< BridgedHeader, WithBridgeHubWococoMessageBridge, + (), >( lane_id, + xcm.into(), message_nonce, message_destination, para_header_number, @@ -435,6 +418,12 @@ mod bridge_hub_rococo_tests { msg_proofs_rewards_account ) .is_some()); + // verify relayed bridged XCM message is dispatched to destination sibling para + let dispatched = test_data::take_outbound_message::< + cumulus_pallet_xcmp_queue::Pallet, + >(sibling_parachain_id.into()) + .unwrap(); + assert_eq!(dispatched, expected_dispatch); }) } } diff --git a/parachains/runtimes/bridge-hubs/test-utils/src/test_cases.rs b/parachains/runtimes/bridge-hubs/test-utils/src/test_cases.rs index 1744d13b4cd..3becfbc21d1 100644 --- a/parachains/runtimes/bridge-hubs/test-utils/src/test_cases.rs +++ b/parachains/runtimes/bridge-hubs/test-utils/src/test_cases.rs @@ -16,7 +16,7 @@ //! Module contains predefined test-case scenarios for `Runtime` with bridging capabilities. -use codec::Encode; +use codec::{DecodeLimit, Encode}; use frame_benchmarking::account; use frame_support::{ assert_ok, @@ -53,11 +53,10 @@ use bridge_runtime_common::{ target::FromBridgedChainMessagesProof, BridgedChain as MessageBridgedChain, MessageBridge, }, messages_generation::{encode_all_messages, encode_lane_data, prepare_messages_storage_proof}, - messages_utils::{prepare_inbound_message, prepare_message_proof_from_parachain}, messages_xcm_extension::{XcmAsPlainPayload, XcmBlobMessageDispatchResult}, }; +use cumulus_primitives_core::XcmpMessageSource; use pallet_bridge_grandpa::BridgedHeader; -use pallet_bridge_messages::{test_utils::MessageProofParams, EXPECTED_DEFAULT_MESSAGE_LENGTH}; /// Test-case makes sure that `Runtime` can process bridging initialize via governance-like call pub fn initialize_bridge_by_governance_works( @@ -498,6 +497,8 @@ pub fn relayed_incoming_message_works::ClearOrigin; 42]; + let expected_dispatch = xcm::VersionedXcm::<()>::V3(xcm.clone().into()); // generate bridged relay chain finality, parachain heads and message proofs, // to be submitted by relayer to this chain. let ( @@ -507,8 +508,9 @@ pub fn relayed_incoming_message_works, MB>( + ) = test_data::make_complex_relayer_proofs::, MB, ()>( lane_id, + xcm.into(), message_nonce, message_destination, para_header_number, @@ -553,7 +555,6 @@ pub fn relayed_incoming_message_works::take_outbound_messages( usize::MAX ) @@ -578,6 +579,12 @@ pub fn relayed_incoming_message_works, + >(sibling_parachain_id.into()) + .unwrap(); + assert_eq!(dispatched, expected_dispatch); }) } @@ -670,6 +677,8 @@ pub fn relayed_batch_works::AccountId>("relayer", 0, 0); + let xcm = vec![xcm::v3::Instruction::<()>::ClearOrigin; 42]; + let expected_dispatch = xcm::VersionedXcm::<()>::V3(xcm.clone().into()); // generate bridged relay chain finality, parachain heads and message proofs, // to be submitted by relayer to this chain. let ( @@ -679,8 +688,9 @@ pub fn relayed_batch_works, MB>( + ) = test_data::make_complex_relayer_proofs::, MB, ()>( lane_id, + xcm.into(), message_nonce, message_destination, para_header_number, @@ -689,7 +699,6 @@ pub fn relayed_batch_works::take_outbound_messages( usize::MAX ) @@ -748,6 +757,12 @@ pub fn relayed_batch_works, + >(sibling_parachain_id.into()) + .unwrap(); + assert_eq!(dispatched, expected_dispatch); }) } @@ -790,97 +805,6 @@ macro_rules! include_relayed_incoming_message_works( } ); -pub fn receive_single_message_proof( - collator_session_key: CollatorSessionKeys, - runtime_para_id: u32, - sibling_parachain_id: u32, -) where - Runtime: frame_system::Config - + pallet_balances::Config - + pallet_session::Config - + pallet_xcm::Config - + parachain_info::Config - + pallet_collator_selection::Config - + cumulus_pallet_dmp_queue::Config - + cumulus_pallet_parachain_system::Config - + cumulus_pallet_xcmp_queue::Config - + pallet_bridge_grandpa::Config - + pallet_bridge_parachains::Config - + pallet_bridge_parachains::Config - + pallet_bridge_messages::Config, - ValidatorIdOf: From>, - XcmConfig: xcm_executor::Config, - HrmpChannelOpener: frame_support::inherent::ProvideInherent< - Call = cumulus_pallet_parachain_system::Call, - >, - GPI: 'static, - PPI: 'static, - MPI: 'static, - MB: MessageBridge, - UnderlyingChainOf>: bp_runtime::Chain + Parachain, - <>::SourceHeaderChain as SourceHeaderChain>::MessagesProof: From>, -{ - assert_ne!(runtime_para_id, sibling_parachain_id); - - ExtBuilder::::default() - .with_collators(collator_session_key.collators()) - .with_session_keys(collator_session_key.session_keys()) - .with_safe_xcm_version(XCM_VERSION) - .with_para_id(runtime_para_id.into()) - .with_tracing() - .build() - .execute_with(|| { - // import message - let relayer_id_on_source = - pallet_bridge_messages::test_utils::default_bridged_relayer_id::(); - let relayer_id_on_target = - account::<::AccountId>("relayer", 0, 0); - - use cumulus_primitives_core::XcmpMessageSource; - assert!(cumulus_pallet_xcmp_queue::Pallet::::take_outbound_messages( - usize::MAX - ) - .is_empty()); - - mock_open_hrmp_channel::(runtime_para_id.into(), sibling_parachain_id.into()); - - let lane_id = LaneId([0, 0, 0, 0]); - - let params = MessageProofParams { - // TODO: customize this with test parameters - lane: lane_id.clone(), - message_nonces: 1..=1, - outbound_lane_data: None, - is_successful_dispatch_expected: true, - size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), - }; - - let ( - proof, - dispatch_weight, - _ - ) = prepare_message_proof_from_parachain::< - Runtime, - PPI, - MB, - >(params, X2(GlobalConsensus(Rococo), Parachain(sibling_parachain_id)), None); - - let proof: <>::SourceHeaderChain as SourceHeaderChain>::MessagesProof = proof.into(); - - assert_eq!( - pallet_bridge_messages::InboundLanes::::get(lane_id).last_delivered_nonce(), - 0, - ); - let result = pallet_bridge_messages::Pallet::::receive_messages_proof(RawOrigin::Signed(relayer_id_on_target).into(), relayer_id_on_source, proof, 1, dispatch_weight); - assert_ok!(result); - assert_eq!( - pallet_bridge_messages::InboundLanes::::get(lane_id).last_delivered_nonce(), - 1, - ); - // assert!(T::is_message_successfully_dispatched(21)); - }) -} - pub mod test_data { use super::*; use bp_header_chain::justification::GrandpaJustification; @@ -888,6 +812,8 @@ pub mod test_data { use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId}; use bp_runtime::BasicOperatingMode; use bp_test_utils::authority_list; + use cumulus_primitives_core::XcmpMessageFormat; + use xcm::MAX_XCM_DECODE_DEPTH; use xcm_builder::{HaulBlob, HaulBlobError, HaulBlobExporter}; use xcm_executor::traits::{validate_export, ExportXcm}; @@ -908,8 +834,22 @@ pub mod test_data { ) } - pub fn make_complex_relayer_proofs( + pub fn prepare_inbound_xcm( + xcm_message: Xcm, + destination: InteriorMultiLocation, + ) -> Vec { + let location = xcm::VersionedInteriorMultiLocation::V3(destination); + let xcm = xcm::VersionedXcm::::V3(xcm_message); + // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor + // or public fields, so just tuple + // (double encoding, because `.encode()` is called on original Xcm BLOB when it is pushed + // to the storage) + (location, xcm).encode().encode() + } + + pub fn make_complex_relayer_proofs( lane_id: LaneId, + xcm_message: Xcm, message_nonce: MessageNonce, message_destination: Junctions, para_header_number: u32, @@ -930,21 +870,15 @@ pub mod test_data { ::BridgedChain: Send + Sync + 'static, UnderlyingChainOf>: bp_runtime::Chain + Parachain, { - let params = MessageProofParams { - lane: lane_id, - message_nonces: message_nonce..=message_nonce, - outbound_lane_data: None, - is_successful_dispatch_expected: true, - size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), - }; - + let message_payload = prepare_inbound_xcm(xcm_message, message_destination); + let message_size = StorageProofSize::Minimal(message_payload.len() as u32); // prepare para storage proof containing message let (para_state_root, para_storage_proof) = prepare_messages_storage_proof::( - params.lane, - params.message_nonces.clone(), - params.outbound_lane_data.clone(), - params.size, - prepare_inbound_message(¶ms, message_destination), + lane_id, + message_nonce..=message_nonce, + None, + message_size, + message_payload, encode_all_messages, encode_lane_data, ); @@ -963,9 +897,9 @@ pub mod test_data { let message_proof = FromBridgedChainMessagesProof { bridged_header_hash: bridged_para_head.hash(), storage_proof: para_storage_proof, - lane: params.lane, - nonces_start: *params.message_nonces.start(), - nonces_end: *params.message_nonces.end(), + lane: lane_id, + nonces_start: message_nonce, + nonces_end: message_nonce, }; // import bridged relay chain block#1 with state root containing head#5 of bridged parachain @@ -984,6 +918,29 @@ pub mod test_data { ) } + pub fn take_outbound_message( + sent_to_para_id: cumulus_primitives_core::ParaId, + ) -> Option> { + match HrmpChannelSource::take_outbound_messages(10)[..] { + [(para_id, ref mut xcm_message_data)] if para_id.eq(&sent_to_para_id.into()) => { + let mut xcm_message_data = &xcm_message_data[..]; + // decode + let _ = XcmpMessageFormat::decode_with_depth_limit( + MAX_XCM_DECODE_DEPTH, + &mut xcm_message_data, + ) + .expect("valid format"); + xcm::VersionedXcm::<()>::decode_with_depth_limit( + MAX_XCM_DECODE_DEPTH, + &mut xcm_message_data, + ) + .map(|x| Some(x)) + .expect("result with xcm") + }, + _ => return None, + } + } + /// Helper that creates InitializationData mock data, that can be used to initialize bridge GRANDPA pallet pub fn initialization_data< Runtime: pallet_bridge_grandpa::Config,