diff --git a/parachain/primitives/router/src/outbound/mod.rs b/parachain/primitives/router/src/outbound/mod.rs index 8260cbe89f..ab7da13dda 100644 --- a/parachain/primitives/router/src/outbound/mod.rs +++ b/parachain/primitives/router/src/outbound/mod.rs @@ -9,7 +9,10 @@ use core::slice::Iter; use codec::{Decode, Encode}; -use frame_support::{ensure, traits::Get}; +use frame_support::{ + ensure, + traits::{ContainsPair, Get}, +}; use snowbridge_core::{ outbound::{AgentExecuteCommand, Command, Message, SendMessage}, ChannelId, ParaId, @@ -24,15 +27,31 @@ pub struct EthereumBlobExporter< EthereumNetwork, OutboundQueue, AgentHashedDescription, ->(PhantomData<(UniversalLocation, EthereumNetwork, OutboundQueue, AgentHashedDescription)>); - -impl ExportXcm - for EthereumBlobExporter -where + ExportFilter, +>( + PhantomData<( + UniversalLocation, + EthereumNetwork, + OutboundQueue, + AgentHashedDescription, + ExportFilter, + )>, +); + +impl + ExportXcm + for EthereumBlobExporter< + UniversalLocation, + EthereumNetwork, + OutboundQueue, + AgentHashedDescription, + ExportFilter, + > where UniversalLocation: Get, EthereumNetwork: Get, OutboundQueue: SendMessage, AgentHashedDescription: ConvertLocation, + ExportFilter: ContainsPair, { type Ticket = (Vec, XcmHash); @@ -57,7 +76,7 @@ where return Err(SendError::NotApplicable) } - let (local_net, local_sub) = universal_source + let (local_net, local_origin) = universal_source .take() .ok_or_else(|| { log::error!(target: "xcm::ethereum_blob_exporter", "universal source not provided."); @@ -74,10 +93,10 @@ where return Err(SendError::NotApplicable) } - let para_id = match local_sub { + let para_id = match local_origin { X1(Parachain(para_id)) => para_id, _ => { - log::error!(target: "xcm::ethereum_blob_exporter", "could not get parachain id from universal source '{local_sub:?}'."); + log::error!(target: "xcm::ethereum_blob_exporter", "could not get parachain id from universal source '{local_origin:?}'."); return Err(SendError::MissingArgument) }, }; @@ -93,12 +112,12 @@ where SendError::Unroutable })?; - // local_sub is relative to the relaychain. No conversion needed. - let local_sub_location: MultiLocation = local_sub.into(); - let agent_id = match AgentHashedDescription::convert_location(&local_sub_location) { + // local_origin is relative to the relaychain. No conversion needed. + let local_origin_location: MultiLocation = local_origin.into(); + let agent_id = match AgentHashedDescription::convert_location(&local_origin_location) { Some(id) => id, None => { - log::error!(target: "xcm::ethereum_blob_exporter", "unroutable due to not being able to create agent id. '{local_sub_location:?}'"); + log::error!(target: "xcm::ethereum_blob_exporter", "unroutable due to not being able to create agent id. '{local_origin_location:?}'"); return Err(SendError::Unroutable) }, }; @@ -111,6 +130,12 @@ where command: Command::AgentExecute { agent_id, command: agent_execute_command }, }; + // filter out message + if !ExportFilter::contains(&local_origin, &outbound_message) { + log::error!(target: "xcm::ethereum_blob_exporter", "unroutable due to being filtered. '{local_origin:?}'"); + return Err(SendError::Unroutable) + } + // validate the message let (ticket, fee) = OutboundQueue::validate(&outbound_message).map_err(|err| { log::error!(target: "xcm::ethereum_blob_exporter", "OutboundQueue validation of message failed. {err:?}"); diff --git a/parachain/primitives/router/src/outbound/tests.rs b/parachain/primitives/router/src/outbound/tests.rs index f64ad8698c..bdeb5ad018 100644 --- a/parachain/primitives/router/src/outbound/tests.rs +++ b/parachain/primitives/router/src/outbound/tests.rs @@ -1,4 +1,7 @@ -use frame_support::parameter_types; +use frame_support::{ + assert_err, assert_ok, parameter_types, + traits::{Everything, Nothing}, +}; use hex_literal::hex; use snowbridge_core::outbound::{Fee, SendError, SendMessageFeeProvider}; @@ -66,15 +69,15 @@ fn exporter_validate_with_unknown_network_yields_not_applicable() { let mut destination: Option = None; let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::NotApplicable)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::NotApplicable); } #[test] @@ -85,15 +88,15 @@ fn exporter_validate_with_invalid_destination_yields_missing_argument() { let mut destination: Option = None; let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::MissingArgument)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::MissingArgument); } #[test] @@ -106,15 +109,15 @@ fn exporter_validate_with_x8_destination_yields_not_applicable() { )); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::NotApplicable)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::NotApplicable); } #[test] @@ -125,15 +128,15 @@ fn exporter_validate_without_universal_source_yields_missing_argument() { let mut destination: Option = Here.into(); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::MissingArgument)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::MissingArgument); } #[test] @@ -144,15 +147,15 @@ fn exporter_validate_without_global_universal_location_yields_unroutable() { let mut destination: Option = Here.into(); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::Unroutable)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::Unroutable); } #[test] @@ -163,15 +166,15 @@ fn exporter_validate_without_global_bridge_location_yields_not_applicable() { let mut destination: Option = Here.into(); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::NotApplicable)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::NotApplicable); } #[test] @@ -183,15 +186,15 @@ fn exporter_validate_with_remote_universal_source_yields_not_applicable() { let mut destination: Option = Here.into(); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::NotApplicable)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::NotApplicable); } #[test] @@ -202,15 +205,15 @@ fn exporter_validate_without_para_id_in_source_yields_missing_argument() { let mut destination: Option = Here.into(); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::MissingArgument)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::MissingArgument); } #[test] @@ -222,15 +225,15 @@ fn exporter_validate_complex_para_id_in_source_yields_missing_argument() { let mut destination: Option = Here.into(); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::MissingArgument)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::MissingArgument); } #[test] @@ -242,15 +245,15 @@ fn exporter_validate_without_xcm_message_yields_missing_argument() { let mut destination: Option = Here.into(); let mut message: Option> = None; - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); - assert_eq!(result, Err(XcmSendError::MissingArgument)); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + assert_err!(result, XcmSendError::MissingArgument); } #[test] @@ -289,16 +292,16 @@ fn exporter_validate_with_max_target_fee_yields_unroutable() { .into(), ); - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); - assert_eq!(result, Err(XcmSendError::Unroutable)); + assert_err!(result, XcmSendError::Unroutable); } #[test] @@ -316,16 +319,16 @@ fn exporter_validate_with_unparsable_xcm_yields_unroutable() { let mut message: Option> = Some(vec![WithdrawAsset(fees), BuyExecution { fees: fee, weight_limit: Unlimited }].into()); - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message - ); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); - assert_eq!(result, Err(XcmSendError::Unroutable)); + assert_err!(result, XcmSendError::Unroutable); } #[test] @@ -362,16 +365,62 @@ fn exporter_validate_xcm_success_case_1() { .into(), ); - let result = EthereumBlobExporter::< - UniversalLocation, - BridgedNetwork, - MockOkOutboundQueue, - AgentIdOf, - >::validate( - network, channel, &mut universal_source, &mut destination, &mut message + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Everything, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + + assert_ok!(result); +} + +#[test] +fn exporter_validate_with_filter_yields_unroutable() { + let network = BridgedNetwork::get(); + let mut destination: Option = Here.into(); + + let mut universal_source: Option = + Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + + let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); + let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); + + let channel: u32 = 0; + let assets: MultiAssets = vec![MultiAsset { + id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + fun: Fungible(1000), + }] + .into(); + let fee = assets.clone().get(0).unwrap().clone(); + let filter: MultiAssetFilter = assets.clone().into(); + + let mut message: Option> = Some( + vec![ + WithdrawAsset(assets.clone()), + ClearOrigin, + BuyExecution { fees: fee, weight_limit: Unlimited }, + DepositAsset { + assets: filter, + beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + }, + SetTopic([0; 32]), + ] + .into(), ); - assert!(result.is_ok()); + let result = + EthereumBlobExporter::< + UniversalLocation, + BridgedNetwork, + MockOkOutboundQueue, + AgentIdOf, + Nothing, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); + + assert_err!(result, XcmSendError::Unroutable); } #[test] @@ -381,8 +430,9 @@ fn exporter_deliver_with_submit_failure_yields_unroutable() { BridgedNetwork, MockErrOutboundQueue, AgentIdOf, + Everything, >::deliver((hex!("deadbeef").to_vec(), XcmHash::default())); - assert_eq!(result, Err(XcmSendError::Transport("other transport error"))) + assert_err!(result, XcmSendError::Transport("other transport error")) } #[test] @@ -417,7 +467,7 @@ fn xcm_converter_convert_success() { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok((expected_payload, [0; 32]))); + assert_ok!(result, (expected_payload, [0; 32])); } #[test] @@ -450,7 +500,7 @@ fn xcm_converter_convert_without_buy_execution_yields_success() { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok((expected_payload, [0; 32]))); + assert_ok!(result, (expected_payload, [0; 32])); } #[test] @@ -485,7 +535,7 @@ fn xcm_converter_convert_with_wildcard_all_asset_filter_succeeds() { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok((expected_payload, [0; 32]))); + assert_ok!(result, (expected_payload, [0; 32])); } #[test] @@ -521,7 +571,7 @@ fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok((expected_payload, [0; 32]))); + assert_ok!(result, (expected_payload, [0; 32])); } #[test] @@ -550,7 +600,7 @@ fn xcm_converter_convert_without_set_topic_yields_set_topic_expected() { .into(); let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::SetTopicExpected)); + assert_err!(result, XcmConverterError::SetTopicExpected); } #[test] @@ -567,7 +617,7 @@ fn xcm_converter_convert_with_partial_message_yields_unexpected_end_of_xcm() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::UnexpectedEndOfXcm)); + assert_err!(result, XcmConverterError::UnexpectedEndOfXcm); } #[test] @@ -601,7 +651,7 @@ fn xcm_converter_with_different_fee_asset_fails() { .into(); let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::InvalidFeeAsset)); + assert_err!(result, XcmConverterError::InvalidFeeAsset); } #[test] @@ -632,7 +682,7 @@ fn xcm_converter_with_fees_greater_than_reserve_fails() { .into(); let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::InvalidFeeAsset)); + assert_err!(result, XcmConverterError::InvalidFeeAsset); } #[test] @@ -644,7 +694,7 @@ fn xcm_converter_convert_with_empty_xcm_yields_unexpected_end_of_xcm() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::UnexpectedEndOfXcm)); + assert_err!(result, XcmConverterError::UnexpectedEndOfXcm); } #[test] @@ -676,7 +726,7 @@ fn xcm_converter_convert_with_extra_instructions_yields_end_of_xcm_message_expec let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::EndOfXcmMessageExpected)); + assert_err!(result, XcmConverterError::EndOfXcmMessageExpected); } #[test] @@ -706,7 +756,7 @@ fn xcm_converter_convert_without_withdraw_asset_yields_withdraw_expected() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::WithdrawAssetExpected)); + assert_err!(result, XcmConverterError::WithdrawAssetExpected); } #[test] @@ -731,7 +781,7 @@ fn xcm_converter_convert_without_withdraw_asset_yields_deposit_expected() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::DepositAssetExpected)); + assert_err!(result, XcmConverterError::DepositAssetExpected); } #[test] @@ -764,7 +814,7 @@ fn xcm_converter_convert_without_assets_yields_no_reserve_assets() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::NoReserveAssets)); + assert_err!(result, XcmConverterError::NoReserveAssets); } #[test] @@ -802,7 +852,7 @@ fn xcm_converter_convert_with_two_assets_yields_too_many_assets() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::TooManyAssets)); + assert_err!(result, XcmConverterError::TooManyAssets); } #[test] @@ -833,7 +883,7 @@ fn xcm_converter_convert_without_consuming_filter_yields_filter_does_not_consume let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::FilterDoesNotConsumeAllAssets)); + assert_err!(result, XcmConverterError::FilterDoesNotConsumeAllAssets); } #[test] @@ -864,7 +914,7 @@ fn xcm_converter_convert_with_zero_amount_asset_yields_zero_asset_transfer() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::ZeroAssetTransfer)); + assert_err!(result, XcmConverterError::ZeroAssetTransfer); } #[test] @@ -894,7 +944,7 @@ fn xcm_converter_convert_non_ethereum_asset_yields_asset_resolution_failed() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::AssetResolutionFailed)); + assert_err!(result, XcmConverterError::AssetResolutionFailed); } #[test] @@ -927,7 +977,7 @@ fn xcm_converter_convert_non_ethereum_chain_asset_yields_asset_resolution_failed let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::AssetResolutionFailed)); + assert_err!(result, XcmConverterError::AssetResolutionFailed); } #[test] @@ -960,7 +1010,7 @@ fn xcm_converter_convert_non_ethereum_chain_yields_asset_resolution_failed() { let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::AssetResolutionFailed)); + assert_err!(result, XcmConverterError::AssetResolutionFailed); } #[test] @@ -997,7 +1047,7 @@ fn xcm_converter_convert_with_non_ethereum_beneficiary_yields_beneficiary_resolu let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::BeneficiaryResolutionFailed)); + assert_err!(result, XcmConverterError::BeneficiaryResolutionFailed); } #[test] @@ -1033,5 +1083,5 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ let mut converter = XcmConverter::new(&message, &network); let result = converter.convert(); - assert_eq!(result.err(), Some(XcmConverterError::BeneficiaryResolutionFailed)); + assert_err!(result, XcmConverterError::BeneficiaryResolutionFailed); } diff --git a/parachain/runtime/tests/src/lib.rs b/parachain/runtime/tests/src/lib.rs index 7375f84c80..c2811f7ab8 100644 --- a/parachain/runtime/tests/src/lib.rs +++ b/parachain/runtime/tests/src/lib.rs @@ -8,6 +8,7 @@ mod test_cases; use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee; use bridge_hub_rococo_runtime::{xcm_config::XcmConfig, Runtime, RuntimeEvent, SessionKeys}; use codec::Decode; +use cumulus_primitives_core::XcmError::{FailedToTransactAsset, NotHoldingFees, Unroutable}; use parachains_common::{AccountId, AuraId}; use sp_core::H160; use sp_keyring::AccountKeyring::Alice; @@ -38,6 +39,21 @@ pub fn transfer_token_to_ethereum_works() { ) } +#[test] +pub fn transfer_token_from_non_assethub_to_ethereum_unroutable() { + test_cases::send_transfer_token_message_failure::( + collator_session_keys(), + 1013, + 1001, + DefaultBridgeHubEthereumBaseFee::get() + 1_000_000_000, + H160::random(), + H160::random(), + // fee not enough + 1_000_000_000, + Unroutable, + ) +} + #[test] pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { test_cases::send_unpaid_transfer_token_message::( @@ -51,25 +67,29 @@ pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { #[test] pub fn transfer_token_to_ethereum_fee_not_enough() { - test_cases::send_transfer_token_message_fee_not_enough::( + test_cases::send_transfer_token_message_failure::( collator_session_keys(), 1013, 1000, + DefaultBridgeHubEthereumBaseFee::get() + 1_000_000_000, H160::random(), H160::random(), // fee not enough 1_000_000_000, + NotHoldingFees, ) } #[test] pub fn transfer_token_to_ethereum_insufficient_fund() { - test_cases::send_transfer_token_message_insufficient_fund::( + test_cases::send_transfer_token_message_failure::( collator_session_keys(), 1013, 1000, + 1_000_000_000, H160::random(), H160::random(), DefaultBridgeHubEthereumBaseFee::get(), + FailedToTransactAsset("InsufficientBalance"), ) } diff --git a/parachain/runtime/tests/src/test_cases.rs b/parachain/runtime/tests/src/test_cases.rs index c2c2274517..0c921787aa 100644 --- a/parachain/runtime/tests/src/test_cases.rs +++ b/parachain/runtime/tests/src/test_cases.rs @@ -15,7 +15,7 @@ use xcm::latest::prelude::*; use xcm_executor::XcmExecutor; // Re-export test_case from `parachains-runtimes-test-utils` pub use parachains_runtimes_test_utils::test_cases::change_storage_constant_by_governance_works; -use xcm::v3::Error::{Barrier, FailedToTransactAsset, NotHoldingFees}; +use xcm::v3::Error::{self, Barrier}; type RuntimeHelper = parachains_runtimes_test_utils::RuntimeHelper; @@ -240,13 +240,15 @@ pub fn send_unpaid_transfer_token_message( }); } -pub fn send_transfer_token_message_fee_not_enough( +pub fn send_transfer_token_message_failure( collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, + initial_amount: u128, weth_contract_address: H160, destination_address: H160, fee_amount: u128, + expected_error: Error, ) where Runtime: frame_system::Config + pallet_balances::Config @@ -267,10 +269,7 @@ pub fn send_transfer_token_message_fee_not_enough( .build() .execute_with(|| { // fund asset hub sovereign account enough so it can pay fees - initial_fund::( - assethub_parachain_id, - DefaultBridgeHubEthereumBaseFee::get() + 1_000_000_000, - ); + initial_fund::(assethub_parachain_id, initial_amount); let outcome = send_transfer_token_message::( assethub_parachain_id, @@ -279,46 +278,6 @@ pub fn send_transfer_token_message_fee_not_enough( fee_amount, ); // check err is NotHoldingFees - assert_err!(outcome.ensure_complete(), NotHoldingFees); - }); -} - -pub fn send_transfer_token_message_insufficient_fund( - collator_session_key: CollatorSessionKeys, - runtime_para_id: u32, - assethub_parachain_id: u32, - weth_contract_address: H160, - destination_address: H160, - fee_amount: u128, -) where - Runtime: frame_system::Config - + pallet_balances::Config - + pallet_session::Config - + pallet_xcm::Config - + parachain_info::Config - + pallet_collator_selection::Config - + cumulus_pallet_parachain_system::Config - + snowbridge_outbound_queue::Config, - XcmConfig: xcm_executor::Config, - ValidatorIdOf: From>, -{ - ExtBuilder::::default() - .with_collators(collator_session_key.collators()) - .with_session_keys(collator_session_key.session_keys()) - .with_para_id(runtime_para_id.into()) - .with_tracing() - .build() - .execute_with(|| { - // initial fund not enough - initial_fund::(assethub_parachain_id, 1_000_000_000); - - let outcome = send_transfer_token_message::( - assethub_parachain_id, - weth_contract_address, - destination_address, - fee_amount, - ); - // check err is FailedToTransactAsset("InsufficientBalance") - assert_err!(outcome.ensure_complete(), FailedToTransactAsset("InsufficientBalance")); + assert_err!(outcome.ensure_complete(), expected_error); }); } diff --git a/polkadot-sdk b/polkadot-sdk index 00e8eb2e04..6252d96cb9 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit 00e8eb2e04375260d728f143352e21cbf7a4436c +Subproject commit 6252d96cb9555e8b407df8dd27b0b8ef359b74ef