diff --git a/Cargo.lock b/Cargo.lock index dab998969e86b..78d466dad704e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2202,6 +2202,7 @@ dependencies = [ "snowbridge-outbound-queue", "snowbridge-outbound-queue-runtime-api", "snowbridge-router-primitives", + "snowbridge-runtime-common", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -16997,6 +16998,19 @@ dependencies = [ "staging-xcm-executor", ] +[[package]] +name = "snowbridge-runtime-common" +version = "0.1.1" +dependencies = [ + "bp-rococo", + "frame-support", + "log", + "snowbridge-core", + "staging-xcm", + "staging-xcm-builder", + "staging-xcm-executor", +] + [[package]] name = "socket2" version = "0.4.9" 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 2eb4e54bc9d62..b9ed51fa41309 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -94,15 +94,16 @@ pallet-bridge-relayers = { path = "../../../../../bridges/modules/relayers", def bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", default-features = false } # Ethereum Bridge (Snowbridge) -snowbridge-core = { path = "../../../../../../parachain/primitives/core", default-features = false } snowbridge-beacon-primitives = { path = "../../../../../../parachain/primitives/beacon", default-features = false } -snowbridge-router-primitives = { path = "../../../../../../parachain/primitives/router", default-features = false } +snowbridge-control = { path = "../../../../../../parachain/pallets/control", default-features = false } +snowbridge-control-runtime-api = { path = "../../../../../../parachain/pallets/control/runtime-api", default-features = false } +snowbridge-core = { path = "../../../../../../parachain/primitives/core", default-features = false } snowbridge-ethereum-beacon-client = { path = "../../../../../../parachain/pallets/ethereum-beacon-client", default-features = false } snowbridge-inbound-queue = { path = "../../../../../../parachain/pallets/inbound-queue", default-features = false } snowbridge-outbound-queue = { path = "../../../../../../parachain/pallets/outbound-queue", default-features = false } snowbridge-outbound-queue-runtime-api = { path = "../../../../../../parachain/pallets/outbound-queue/runtime-api", default-features = false } -snowbridge-control = { path = "../../../../../../parachain/pallets/control", default-features = false } -snowbridge-control-runtime-api = { path = "../../../../../../parachain/pallets/control/runtime-api", default-features = false } +snowbridge-router-primitives = { path = "../../../../../../parachain/primitives/router", default-features = false } +snowbridge-runtime-common = { path = "../../../../../../parachain/primitives/runtime-common", default-features = false } [dev-dependencies] static_assertions = "1.1" @@ -186,15 +187,16 @@ std = [ "xcm-builder/std", "xcm-executor/std", "xcm/std", - "snowbridge-core/std", - "snowbridge-router-primitives/std", "snowbridge-beacon-primitives/std", + "snowbridge-control-runtime-api/std", + "snowbridge-control/std", + "snowbridge-core/std", "snowbridge-ethereum-beacon-client/std", "snowbridge-inbound-queue/std", - "snowbridge-outbound-queue/std", "snowbridge-outbound-queue-runtime-api/std", - "snowbridge-control/std", - "snowbridge-control-runtime-api/std", + "snowbridge-outbound-queue/std", + "snowbridge-router-primitives/std", + "snowbridge-runtime-common/std", "substrate-wasm-builder", ] @@ -225,11 +227,12 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", - "snowbridge-core/runtime-benchmarks", "snowbridge-control/runtime-benchmarks", + "snowbridge-core/runtime-benchmarks", + "snowbridge-ethereum-beacon-client/runtime-benchmarks", "snowbridge-inbound-queue/runtime-benchmarks", "snowbridge-outbound-queue/runtime-benchmarks", - "snowbridge-ethereum-beacon-client/runtime-benchmarks" + "snowbridge-runtime-common/runtime-benchmarks", ] try-runtime = [ 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 a201c5da019d5..162610b0bd14c 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 @@ -50,11 +50,8 @@ use parachains_common::{ use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::ExponentialPrice; use rococo_runtime_constants::system_parachain::SystemParachains; -use snowbridge_core::{ - outbound::SendMessageFeeProvider, - sibling_sovereign_account_raw -}; use snowbridge_router_primitives:: outbound::EthereumBlobExporter; +use snowbridge_runtime_common::XcmExportFeeToSnowbridge; use sp_core::{Get, H256}; use sp_runtime::traits::AccountIdConversion; use sp_std::marker::PhantomData; @@ -583,112 +580,4 @@ impl< fee } -} - -/// A `HandleFee` implementation that takes fees from `ExportMessage` XCM instructions -/// to Snowbridge and holds it in a receiver account. Burns the fees in case of a failure. -pub struct XcmExportFeeToSnowbridge< - TokenLocation, - EthereumNetwork, - ReceiverAccount, - AssetTransactor, - OutboundQueue, ->( - PhantomData<( - TokenLocation, - EthereumNetwork, - ReceiverAccount, - AssetTransactor, - OutboundQueue, - )>, -); - -impl< - TokenLocation: Get, - EthereumNetwork: Get, - ReceiverAccount: Get, - AssetTransactor: TransactAsset, - OutboundQueue: SendMessageFeeProvider, - > HandleFee - for XcmExportFeeToSnowbridge< - TokenLocation, - EthereumNetwork, - ReceiverAccount, - AssetTransactor, - OutboundQueue, - > -{ - fn handle_fee( - fees: MultiAssets, - context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { - let token_location = TokenLocation::get(); - let mut fees = fees.into_inner(); - - if matches!(reason, FeeReason::Export { network: bridged_network, destination } - if bridged_network == EthereumNetwork::get() && destination == Here) - { - log::info!( - target: "xcm::fees", - "XcmExportFeeToSnowbridge fees: {fees:?}, context: {context:?}, reason: {reason:?}", - ); - - let fee_item_index = fees.iter().position(|asset| { - matches!( - asset, - MultiAsset { id: Concrete(location), fun: Fungible(..)} - if *location == token_location, - ) - }); - // Find the fee asset. - let fee_item = if let Some(element) = fee_item_index { - fees.remove(element) - } else { - return fees.into() - }; - - let receiver = ReceiverAccount::get(); - // There is an origin so split fee into parts. - if let Some(XcmContext { origin: Some(MultiLocation { parents: 1, interior }), .. }) = context { - if let Some(Parachain(sibling_para_id)) = interior.first() { - let account: AccountId = sibling_sovereign_account_raw((*sibling_para_id).into()).into(); - let local_fee = OutboundQueue::local_fee(); - if let Fungible(amount) = fee_item.fun { - let remote_fee = amount.checked_sub(local_fee).unwrap_or(0); - - // Send local fee to receiver - deposit_or_burn_fee::( - MultiAsset { - id: Concrete(token_location), - fun: Fungible(amount - remote_fee), - } - .into(), - context, - receiver, - ); - // Send remote fee to origin - deposit_or_burn_fee::( - MultiAsset { id: Concrete(token_location), fun: Fungible(remote_fee) } - .into(), - context, - account, - ); - } else { - // Push the fee item back and bail out to let other handlers run. - fees.push(fee_item); - return fees.into() - } - } else { - // Origin conversion failed so send the full fee to the receiver. - deposit_or_burn_fee::(fee_item.into(), context, receiver); - } - } else { - // There is no context so send the full fee to the receiver. - deposit_or_burn_fee::(fee_item.into(), context, receiver); - } - } - - fees.into() - } -} +} \ No newline at end of file