diff --git a/Cargo.lock b/Cargo.lock index 9c9818e5ab764..9a8ae963203fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1113,6 +1113,7 @@ dependencies = [ "rococo-runtime-constants", "scale-info", "smallvec", + "snowbridge-rococo-common", "snowbridge-router-primitives", "sp-api", "sp-block-builder", @@ -2339,6 +2340,7 @@ dependencies = [ "snowbridge-core", "snowbridge-inbound-queue", "snowbridge-outbound-queue", + "snowbridge-rococo-common", "snowbridge-router-primitives", "snowbridge-system", "sp-core", @@ -2414,6 +2416,7 @@ dependencies = [ "snowbridge-inbound-queue", "snowbridge-outbound-queue", "snowbridge-outbound-queue-runtime-api", + "snowbridge-rococo-common", "snowbridge-router-primitives", "snowbridge-runtime-common", "snowbridge-system", @@ -12056,6 +12059,7 @@ dependencies = [ "polkadot-runtime-common", "scale-info", "smallvec", + "snowbridge-rococo-common", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -17724,6 +17728,15 @@ dependencies = [ "staging-xcm", ] +[[package]] +name = "snowbridge-rococo-common" +version = "0.0.1" +dependencies = [ + "frame-support", + "log", + "staging-xcm", +] + [[package]] name = "snowbridge-router-primitives" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index 260a247234266..d66c92b4753f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -559,3 +559,4 @@ snowbridge-outbound-queue = { path = "../parachain/pallets/outbound-queue" } snowbridge-outbound-queue-runtime-api = { path = "../parachain/pallets/outbound-queue/runtime-api" } snowbridge-router-primitives = { path = "../parachain/primitives/router" } snowbridge-runtime-common = { path = "../parachain/runtime/runtime-common" } +snowbridge-rococo-common = { path = "../parachain/runtime/rococo-common" } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml index c918bc6052250..289013a16e0bc 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml @@ -49,3 +49,4 @@ snowbridge-router-primitives = { git = "https://github.com/Snowfork/snowbridge.g snowbridge-system = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } snowbridge-inbound-queue = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } snowbridge-outbound-queue = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } +snowbridge-rococo-common = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index dd136b935f014..1cb8b5406bed1 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -19,6 +19,7 @@ use codec::{Decode, Encode}; use frame_support::pallet_prelude::TypeInfo; use hex_literal::hex; use snowbridge_core::outbound::OperatingMode; +use snowbridge_rococo_common::EthereumNetwork; use snowbridge_router_primitives::inbound::{Command, Destination, MessageV1, VersionedMessage}; use snowbridge_system; use sp_core::H256; @@ -243,8 +244,7 @@ fn send_token_to_penpal() { ]); let weth_asset_location: MultiLocation = - (Parent, Parent, Ethereum { chain_id: 15 }, AccountKey20 { network: None, key: WETH }) - .into(); + (Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into(); let weth_asset_id = weth_asset_location.into(); let origin_location = diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index c1cd29eed3908..f24d120b34ba7 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -82,7 +82,7 @@ parachain-info = { package = "staging-parachain-info", path = "../../../pallets/ parachains-common = { path = "../../../common", default-features = false } assets-common = { path = "../common", default-features = false } snowbridge-router-primitives = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } - +snowbridge-rococo-common = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } # Bridges pallet-xcm-bridge-hub-router = { path = "../../../../../bridges/modules/xcm-bridge-hub-router", default-features = false } bp-asset-hub-rococo = { path = "../../../../../bridges/primitives/chain-asset-hub-rococo", default-features = false } @@ -230,6 +230,7 @@ std = [ "rococo-runtime-constants/std", "scale-info/std", "snowbridge-router-primitives/std", + "snowbridge-rococo-common/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 3b54479db739b..cc67734a1eb30 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -892,7 +892,7 @@ impl pallet_xcm_bridge_hub_router::Config for Runti type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo; type UniversalLocation = xcm_config::UniversalLocation; - type BridgedNetworkId = xcm_config::bridging::to_ethereum::EthereumNetwork; + type BridgedNetworkId = snowbridge_rococo_common::EthereumNetwork; type Bridges = xcm_config::bridging::NetworkExportTable; #[cfg(not(feature = "runtime-benchmarks"))] diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 8be6b7517da3a..48606aa3e4f50 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -40,8 +40,10 @@ use parachains_common::{ use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::ExponentialPrice; use rococo_runtime_constants::system_parachain; +use snowbridge_rococo_common::EthereumNetwork; use snowbridge_router_primitives::inbound::GlobalConsensusEthereumConvertsFor; use sp_runtime::traits::{AccountIdConversion, ConvertInto}; +use sp_std::marker::PhantomData; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -59,6 +61,7 @@ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; #[cfg(feature = "runtime-benchmarks")] use cumulus_primitives_core::ParaId; +use frame_support::traits::{ContainsPair, Get}; parameter_types! { pub const TokenLocation: MultiLocation = MultiLocation::parent(); @@ -543,6 +546,7 @@ pub type WaivedLocations = /// - Sibling parachains' assets from where they originate (as `ForeignCreators`). pub type TrustedTeleporters = ( ConcreteAssetFromSystem, + ConcreteAssetFromSnowBridgeMessageQueue, IsForeignConcreteAsset>>, ); @@ -726,6 +730,18 @@ where } } +pub struct ConcreteAssetFromSnowBridgeMessageQueue(PhantomData); +impl> ContainsPair + for ConcreteAssetFromSnowBridgeMessageQueue +{ + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + log::trace!(target: "xcm::contains", "ConcreteAssetFromSystem asset: {:?}, origin: {:?}", asset, origin); + let from_snowbridge = origin + .eq(&bridging::to_ethereum::SiblingBridgeHubWithEthereumInboundQueueInstance::get()); + matches!(asset.id, Concrete(id) if id == AssetLocation::get()) && from_snowbridge + } +} + /// All configuration related to bridging pub mod bridging { use super::*; @@ -848,13 +864,20 @@ pub mod bridging { use super::*; parameter_types! { - pub EthereumNetwork: NetworkId = NetworkId::Ethereum { chain_id: 15 }; pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(EthereumNetwork::get()))); + /// User fee for ERC20 token transfer back to Ethereum. /// (initially was calculated by test `OutboundQueue::calculate_fees` - ETH/ROC 1/400 and fee_per_gas 20 GWEI = 2200698000000 + *25%) /// Needs to be more than fee calculated from DefaultFeeConfig FeeConfigRecord in snowbridge:parachain/pallets/outbound-queue/src/lib.rs /// Polkadot uses 12 decimals, Kusama and Rococo 10 decimals. pub const BridgeHubEthereumBaseFeeInROC: u128 = 2_750_872_500_000; + pub SiblingBridgeHubWithEthereumInboundQueueInstance: MultiLocation = MultiLocation::new( + 1, + X2( + Parachain(SiblingBridgeHubParaId::get()), + PalletInstance(snowbridge_rococo_common::INBOUND_QUEUE_MESSAGES_PALLET_INDEX) + ) + ); /// Set up exporters configuration. /// `Option` represents static "base fee" which is used for total delivery fee calculation. @@ -875,13 +898,13 @@ pub mod bridging { /// Universal aliases pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( sp_std::vec![ - (SiblingBridgeHub::get(), GlobalConsensus(EthereumNetwork::get())), + (SiblingBridgeHubWithEthereumInboundQueueInstance::get(), GlobalConsensus(EthereumNetwork::get())), ] ); } pub type IsTrustedBridgedReserveLocationForForeignAsset = - matching::IsForeignConcreteAsset>; + matching::IsForeignConcreteAsset>; impl Contains<(MultiLocation, Junction)> for UniversalAliases { fn contains(alias: &(MultiLocation, Junction)) -> bool { diff --git a/cumulus/parachains/runtimes/assets/common/src/matching.rs b/cumulus/parachains/runtimes/assets/common/src/matching.rs index 2f61a2824b09b..a8eb690995f89 100644 --- a/cumulus/parachains/runtimes/assets/common/src/matching.rs +++ b/cumulus/parachains/runtimes/assets/common/src/matching.rs @@ -59,9 +59,11 @@ impl> ContainsPair } } -pub struct FromNetwork(sp_std::marker::PhantomData); -impl> ContainsPair - for FromNetwork +pub struct FromNetwork( + sp_std::marker::PhantomData<(UniversalLocation, ExpectedNetworkId)>, +); +impl, ExpectedNetworkId: Get> + ContainsPair for FromNetwork { fn contains(&a: &MultiLocation, b: &MultiLocation) -> bool { // `a` needs to be from `b` at least @@ -69,11 +71,18 @@ impl> ContainsPair return false } - match a { - MultiLocation { parents: 2, interior } => { - matches!(interior.first(), Some(GlobalConsensus(network)) if *network == SelfNetworkId::get()) + let universal_source = UniversalLocation::get(); + + return match ensure_is_remote(universal_source, a) { + Ok((network_id, _)) => network_id == ExpectedNetworkId::get(), + Err(e) => { + log::trace!( + target: "xcm::contains", + "FromNetwork origin: {:?} is not remote to the universal_source: {:?} {:?}", + a, universal_source, e + ); + false }, - _ => false, } } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 40c472d3d8c1c..e6e5713aa9272 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -104,6 +104,7 @@ snowbridge-outbound-queue = { git = "https://github.com/Snowfork/snowbridge.git" snowbridge-outbound-queue-runtime-api = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } snowbridge-router-primitives = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } snowbridge-runtime-common = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } +snowbridge-rococo-common = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false } bridge-hub-common = { path = "../common", default-features = false } @@ -200,6 +201,7 @@ std = [ "snowbridge-outbound-queue/std", "snowbridge-router-primitives/std", "snowbridge-runtime-common/std", + "snowbridge-rococo-common/std", "substrate-wasm-builder", ] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs new file mode 100644 index 0000000000000..2ca09bc5278e9 --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs @@ -0,0 +1,13 @@ +use crate::{ + xcm_config::{AgentIdOf, UniversalLocation}, + Runtime, +}; +use snowbridge_rococo_common::EthereumNetwork; +use snowbridge_router_primitives::outbound::EthereumBlobExporter; + +pub type SnowbridgeExporter = EthereumBlobExporter< + UniversalLocation, + EthereumNetwork, + snowbridge_outbound_queue::Pallet, + AgentIdOf, +>; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index bfd1a8f365df5..f7254ad228738 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -18,9 +18,7 @@ use crate::{ bridge_common_config::{BridgeParachainWestendInstance, DeliveryRewardInBalance}, - weights, - xcm_config::{AgentIdOf, EthereumNetwork, UniversalLocation}, - AccountId, BridgeWestendMessages, ParachainInfo, Runtime, RuntimeEvent, RuntimeOrigin, + weights, AccountId, BridgeWestendMessages, ParachainInfo, Runtime, RuntimeEvent, RuntimeOrigin, XcmRouter, }; use bp_messages::LaneId; @@ -40,7 +38,6 @@ use bridge_runtime_common::{ RefundableMessagesLane, RefundableParachain, }, }; -use snowbridge_router_primitives::outbound::EthereumBlobExporter; use codec::Encode; use frame_support::{parameter_types, traits::PalletInfoAccess}; @@ -119,13 +116,6 @@ pub type ToBridgeHubWestendHaulBlobExporter = HaulBlobExporter< (), >; -pub type SnowbridgeExporter = EthereumBlobExporter< - UniversalLocation, - EthereumNetwork, - snowbridge_outbound_queue::Pallet, - AgentIdOf, ->; - pub struct ToBridgeHubWestendXcmBlobHauler; impl XcmBlobHauler for ToBridgeHubWestendXcmBlobHauler { type Runtime = Runtime; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index c3846879789f8..da41a733e535b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -28,6 +28,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod bridge_common_config; +pub mod bridge_to_ethereum_config; pub mod bridge_to_westend_config; mod weights; pub mod xcm_config; @@ -509,6 +510,7 @@ parameter_types! { pub const GatewayAddress: H160 = H160(hex_literal::hex!("EDa338E4dC46038493b885327842fD3E301CaB39")); pub const CreateAssetCall: [u8;2] = [53, 0]; pub const CreateAssetDeposit: u128 = (UNITS / 10) + EXISTENTIAL_DEPOSIT; + pub const InboundQueuePalletInstance: u8 = snowbridge_rococo_common::INBOUND_QUEUE_MESSAGES_PALLET_INDEX; pub Parameters: PricingParameters = PricingParameters { exchange_rate: FixedU128::from_rational(1, 400), fee_per_gas: gwei(20), @@ -535,7 +537,13 @@ impl snowbridge_inbound_queue::Config for Runtime { type GatewayAddress = GatewayAddress; #[cfg(feature = "runtime-benchmarks")] type Helper = Runtime; - type MessageConverter = MessageToXcm; + type MessageConverter = MessageToXcm< + CreateAssetCall, + CreateAssetDeposit, + InboundQueuePalletInstance, + AccountId, + Balance, + >; type WeightToFee = WeightToFee; type WeightInfo = weights::snowbridge_inbound_queue::WeightInfo; type PricingParameters = EthereumSystem; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs index ce20759a59149..4c85e882c8f7c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs @@ -40,6 +40,7 @@ use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::ExponentialPrice; use rococo_runtime_constants::system_parachain; use snowbridge_core::DescribeHere; +use snowbridge_rococo_common::EthereumNetwork; use snowbridge_runtime_common::XcmExportFeeToSibling; use sp_core::{Get, H256}; use sp_runtime::traits::AccountIdConversion; @@ -70,9 +71,6 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); - - // Network and location for the local Ethereum testnet. - pub const EthereumNetwork: NetworkId = NetworkId::Ethereum { chain_id: 15 }; } /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used @@ -306,7 +304,7 @@ impl xcm_executor::Config for XcmConfig { >; type MessageExporter = ( crate::bridge_to_westend_config::ToBridgeHubWestendHaulBlobExporter, - crate::bridge_to_westend_config::SnowbridgeExporter, + crate::bridge_to_ethereum_config::SnowbridgeExporter, ); type UniversalAliases = Nothing; type CallDispatcher = WithOriginFilter; @@ -470,8 +468,8 @@ impl, FeeHandler: HandleFee> FeeManager { fn is_waived(origin: Option<&MultiLocation>, fee_reason: FeeReason) -> bool { let Some(loc) = origin else { return false }; - if let Export { network: Ethereum { chain_id: 15 }, destination: Here } = fee_reason { - return false + if let Export { network, destination: Here } = fee_reason { + return !(network == EthereumNetwork::get()) } WaivedLocations::contains(loc) } diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index 4152c092aef90..e44120ec7589a 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -76,6 +76,7 @@ pallet-collator-selection = { path = "../../../../pallets/collator-selection", d parachain-info = { package = "staging-parachain-info", path = "../../../pallets/parachain-info", default-features = false } parachains-common = { path = "../../../common", default-features = false } assets-common = { path = "../../assets/common", default-features = false } +snowbridge-rococo-common = { git = "https://github.com/Snowfork/snowbridge.git", tag = "v0.9.0", default-features = false} [features] default = [ "std" ] @@ -116,6 +117,7 @@ std = [ "polkadot-parachain-primitives/std", "polkadot-primitives/std", "polkadot-runtime-common/std", + "snowbridge-rococo-common/std", "scale-info/std", "sp-api/std", "sp-block-builder/std", diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index ce9a75a897bc3..40f9a1eecd3a9 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -42,6 +42,7 @@ use pallet_assets::Instance1; use pallet_xcm::XcmPassthrough; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; +use snowbridge_rococo_common::EthereumNetwork; use sp_runtime::traits::Zero; use xcm::latest::prelude::*; use xcm_builder::{ @@ -271,7 +272,7 @@ parameter_types! { pub SystemAssetHubAssetsPalletLocation: MultiLocation = MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(Ethereum { chain_id: 15 }))); + pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(EthereumNetwork::get()))); } pub type Reserves = (