Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
add snowbridge-runtime-common
Browse files Browse the repository at this point in the history
  • Loading branch information
alistair-singh committed Nov 9, 2023
1 parent b971a09 commit 8bfa0c1
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 124 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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",
]

Expand Down Expand Up @@ -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 = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<MultiLocation>,
EthereumNetwork: Get<NetworkId>,
ReceiverAccount: Get<AccountId>,
AssetTransactor: TransactAsset,
OutboundQueue: SendMessageFeeProvider<Balance = bp_rococo::Balance>,
> 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::<AssetTransactor, _>(
MultiAsset {
id: Concrete(token_location),
fun: Fungible(amount - remote_fee),
}
.into(),
context,
receiver,
);
// Send remote fee to origin
deposit_or_burn_fee::<AssetTransactor, _>(
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::<AssetTransactor, _>(fee_item.into(), context, receiver);
}
} else {
// There is no context so send the full fee to the receiver.
deposit_or_burn_fee::<AssetTransactor, _>(fee_item.into(), context, receiver);
}
}

fees.into()
}
}
}

0 comments on commit 8bfa0c1

Please sign in to comment.