mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 23:21:02 +00:00
Adds Snowbridge to Rococo runtime (#2522)
# Description Adds Snowbridge to the Rococo bridge hub runtime. Includes config changes required in Rococo asset hub. --------- Co-authored-by: Alistair Singh <alistair.singh7@gmail.com> Co-authored-by: ron <yrong1997@gmail.com> Co-authored-by: Vincent Geddes <vincent.geddes@hey.com> Co-authored-by: claravanstaden <Cats 4 life!>
This commit is contained in:
@@ -90,6 +90,8 @@ bp-asset-hub-rococo = { path = "../../../../../bridges/primitives/chain-asset-hu
|
||||
bp-asset-hub-westend = { path = "../../../../../bridges/primitives/chain-asset-hub-westend", default-features = false }
|
||||
bp-bridge-hub-rococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-rococo", default-features = false }
|
||||
bp-bridge-hub-westend = { path = "../../../../../bridges/primitives/chain-bridge-hub-westend", default-features = false }
|
||||
snowbridge-router-primitives = { path = "../../../../../bridges/snowbridge/parachain/primitives/router", default-features = false }
|
||||
snowbridge-rococo-common = { path = "../../../../../bridges/snowbridge/parachain/runtime/rococo-common", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
asset-test-utils = { path = "../test-utils" }
|
||||
@@ -137,6 +139,8 @@ runtime-benchmarks = [
|
||||
"parachains-common/runtime-benchmarks",
|
||||
"polkadot-parachain-primitives/runtime-benchmarks",
|
||||
"polkadot-runtime-common/runtime-benchmarks",
|
||||
"snowbridge-rococo-common/runtime-benchmarks",
|
||||
"snowbridge-router-primitives/runtime-benchmarks",
|
||||
"sp-runtime/runtime-benchmarks",
|
||||
"xcm-builder/runtime-benchmarks",
|
||||
"xcm-executor/runtime-benchmarks",
|
||||
@@ -227,6 +231,8 @@ std = [
|
||||
"primitive-types/std",
|
||||
"rococo-runtime-constants/std",
|
||||
"scale-info/std",
|
||||
"snowbridge-rococo-common/std",
|
||||
"snowbridge-router-primitives/std",
|
||||
"sp-api/std",
|
||||
"sp-block-builder/std",
|
||||
"sp-consensus-aura/std",
|
||||
|
||||
@@ -30,11 +30,12 @@ pub mod xcm_config;
|
||||
use assets_common::{
|
||||
foreign_creators::ForeignCreators,
|
||||
local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
|
||||
matching::FromSiblingParachain,
|
||||
matching::{FromNetwork, FromSiblingParachain},
|
||||
AssetIdForTrustBackedAssetsConvert, MultiLocationForAssetId,
|
||||
};
|
||||
use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
|
||||
use cumulus_primitives_core::AggregateMessageOrigin;
|
||||
use snowbridge_rococo_common::EthereumNetwork;
|
||||
use sp_api::impl_runtime_apis;
|
||||
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
|
||||
use sp_runtime::{
|
||||
@@ -379,7 +380,10 @@ impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
|
||||
type AssetIdParameter = MultiLocationForAssetId;
|
||||
type Currency = Balances;
|
||||
type CreateOrigin = ForeignCreators<
|
||||
(FromSiblingParachain<parachain_info::Pallet<Runtime>>,),
|
||||
(
|
||||
FromSiblingParachain<parachain_info::Pallet<Runtime>>,
|
||||
FromNetwork<xcm_config::UniversalLocation, EthereumNetwork>,
|
||||
),
|
||||
ForeignCreatorsSovereignAccountOf,
|
||||
AccountId,
|
||||
>;
|
||||
@@ -913,7 +917,6 @@ construct_runtime!(
|
||||
|
||||
// Bridge utilities.
|
||||
ToWestendXcmRouter: pallet_xcm_bridge_hub_router::<Instance3>::{Pallet, Storage, Call} = 45,
|
||||
|
||||
// The main stage.
|
||||
Assets: pallet_assets::<Instance1>::{Pallet, Call, Storage, Event<T>} = 50,
|
||||
Uniques: pallet_uniques::{Pallet, Call, Storage, Event<T>} = 51,
|
||||
|
||||
@@ -21,7 +21,7 @@ use super::{
|
||||
};
|
||||
use assets_common::{
|
||||
local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation,
|
||||
matching::{FromSiblingParachain, IsForeignConcreteAsset},
|
||||
matching::{FromNetwork, FromSiblingParachain, IsForeignConcreteAsset},
|
||||
};
|
||||
use frame_support::{
|
||||
match_types, parameter_types,
|
||||
@@ -39,6 +39,8 @@ use parachains_common::{
|
||||
};
|
||||
use polkadot_parachain_primitives::primitives::Sibling;
|
||||
use polkadot_runtime_common::xcm_sender::ExponentialPrice;
|
||||
use snowbridge_rococo_common::EthereumNetwork;
|
||||
use snowbridge_router_primitives::inbound::GlobalConsensusEthereumConvertsFor;
|
||||
use sp_runtime::traits::{AccountIdConversion, ConvertInto};
|
||||
use xcm::latest::prelude::*;
|
||||
#[allow(deprecated)]
|
||||
@@ -50,9 +52,10 @@ use xcm_builder::{
|
||||
GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete, LocalMint,
|
||||
NetworkExportTableItem, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative,
|
||||
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
|
||||
SignedToAccountId32, SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus,
|
||||
TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin,
|
||||
WithUniqueTopic, XcmFeeManagerFromComponents, XcmFeeToAccount,
|
||||
SignedToAccountId32, SovereignPaidRemoteExporter, SovereignSignedViaLocation, StartsWith,
|
||||
StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
|
||||
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
|
||||
XcmFeeToAccount,
|
||||
};
|
||||
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};
|
||||
|
||||
@@ -90,6 +93,9 @@ pub type LocationToAccountId = (
|
||||
// Different global consensus parachain sovereign account.
|
||||
// (Used for over-bridge transfers and reserve processing)
|
||||
GlobalConsensusParachainConvertsFor<UniversalLocation, AccountId>,
|
||||
// Ethereum contract sovereign account.
|
||||
// (Used to get convert ethereum contract locations to sovereign account)
|
||||
GlobalConsensusEthereumConvertsFor<AccountId>,
|
||||
);
|
||||
|
||||
/// Means for transacting the native currency on this chain.
|
||||
@@ -259,10 +265,11 @@ impl Contains<RuntimeCall> for SafeCallFilter {
|
||||
// Allow to change dedicated storage items (called by governance-like)
|
||||
match call {
|
||||
RuntimeCall::System(frame_system::Call::set_storage { items })
|
||||
if items.iter().all(|(k, _)| k.eq(&bridging::XcmBridgeHubRouterByteFee::key())) ||
|
||||
items
|
||||
.iter()
|
||||
.all(|(k, _)| k.eq(&bridging::XcmBridgeHubRouterBaseFee::key())) =>
|
||||
if items.iter().all(|(k, _)| {
|
||||
k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) |
|
||||
k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) |
|
||||
k.eq(&bridging::to_ethereum::BridgeHubEthereumBaseFee::key())
|
||||
}) =>
|
||||
return true,
|
||||
_ => (),
|
||||
};
|
||||
@@ -534,7 +541,10 @@ impl xcm_executor::Config for XcmConfig {
|
||||
// as reserve locations (we trust the Bridge Hub to relay the message that a reserve is being
|
||||
// held). Asset Hub may _act_ as a reserve location for ROC and assets created
|
||||
// under `pallet-assets`. Users must use teleport where allowed (e.g. ROC with the Relay Chain).
|
||||
type IsReserve = (bridging::to_westend::IsTrustedBridgedReserveLocationForConcreteAsset,);
|
||||
type IsReserve = (
|
||||
bridging::to_westend::IsTrustedBridgedReserveLocationForConcreteAsset,
|
||||
bridging::to_ethereum::IsTrustedBridgedReserveLocationForForeignAsset,
|
||||
);
|
||||
type IsTeleporter = TrustedTeleporters;
|
||||
type UniversalLocation = UniversalLocation;
|
||||
type Barrier = Barrier;
|
||||
@@ -585,7 +595,8 @@ impl xcm_executor::Config for XcmConfig {
|
||||
XcmFeeToAccount<Self::AssetTransactor, AccountId, TreasuryAccount>,
|
||||
>;
|
||||
type MessageExporter = ();
|
||||
type UniversalAliases = (bridging::to_westend::UniversalAliases,);
|
||||
type UniversalAliases =
|
||||
(bridging::to_westend::UniversalAliases, bridging::to_ethereum::UniversalAliases);
|
||||
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
|
||||
type SafeCallFilter = SafeCallFilter;
|
||||
type Aliasers = Nothing;
|
||||
@@ -613,6 +624,9 @@ pub type XcmRouter = WithUniqueTopic<(
|
||||
// Router which wraps and sends xcm to BridgeHub to be delivered to the Westend
|
||||
// GlobalConsensus
|
||||
ToWestendXcmRouter,
|
||||
// Router which wraps and sends xcm to BridgeHub to be delivered to the Ethereum
|
||||
// GlobalConsensus
|
||||
SovereignPaidRemoteExporter<bridging::EthereumNetworkExportTable, XcmpQueue, UniversalLocation>,
|
||||
)>;
|
||||
|
||||
impl pallet_xcm::Config for Runtime {
|
||||
@@ -658,6 +672,7 @@ pub type ForeignCreatorsSovereignAccountOf = (
|
||||
SiblingParachainConvertsVia<Sibling, AccountId>,
|
||||
AccountId32Aliases<RelayNetwork, AccountId>,
|
||||
ParentIsPreset<AccountId>,
|
||||
GlobalConsensusEthereumConvertsFor<AccountId>,
|
||||
);
|
||||
|
||||
/// Simple conversion of `u32` into an `AssetId` for use in benchmarking.
|
||||
@@ -706,10 +721,17 @@ pub mod bridging {
|
||||
sp_std::vec::Vec::new().into_iter()
|
||||
.chain(to_westend::BridgeTable::get())
|
||||
.collect();
|
||||
|
||||
pub EthereumBridgeTable: sp_std::vec::Vec<NetworkExportTableItem> =
|
||||
sp_std::vec::Vec::new().into_iter()
|
||||
.chain(to_ethereum::BridgeTable::get())
|
||||
.collect();
|
||||
}
|
||||
|
||||
pub type NetworkExportTable = xcm_builder::NetworkExportTable<BridgeTable>;
|
||||
|
||||
pub type EthereumNetworkExportTable = xcm_builder::NetworkExportTable<EthereumBridgeTable>;
|
||||
|
||||
pub mod to_westend {
|
||||
use super::*;
|
||||
|
||||
@@ -786,6 +808,56 @@ pub mod bridging {
|
||||
}
|
||||
}
|
||||
|
||||
pub mod to_ethereum {
|
||||
use super::*;
|
||||
|
||||
parameter_types! {
|
||||
/// 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 10 decimals, Kusama and Rococo 12 decimals.
|
||||
pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000;
|
||||
pub storage BridgeHubEthereumBaseFee: Balance = DefaultBridgeHubEthereumBaseFee::get();
|
||||
pub SiblingBridgeHubWithEthereumInboundQueueInstance: MultiLocation = MultiLocation::new(
|
||||
1,
|
||||
X2(
|
||||
Parachain(SiblingBridgeHubParaId::get()),
|
||||
PalletInstance(snowbridge_rococo_common::INBOUND_QUEUE_MESSAGES_PALLET_INDEX)
|
||||
)
|
||||
);
|
||||
|
||||
/// Set up exporters configuration.
|
||||
/// `Option<MultiAsset>` represents static "base fee" which is used for total delivery fee calculation.
|
||||
pub BridgeTable: sp_std::vec::Vec<NetworkExportTableItem> = sp_std::vec![
|
||||
NetworkExportTableItem::new(
|
||||
EthereumNetwork::get(),
|
||||
Some(sp_std::vec![Junctions::Here]),
|
||||
SiblingBridgeHub::get(),
|
||||
Some((
|
||||
XcmBridgeHubRouterFeeAssetId::get(),
|
||||
BridgeHubEthereumBaseFee::get(),
|
||||
).into())
|
||||
),
|
||||
];
|
||||
|
||||
/// Universal aliases
|
||||
pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter(
|
||||
sp_std::vec![
|
||||
(SiblingBridgeHubWithEthereumInboundQueueInstance::get(), GlobalConsensus(EthereumNetwork::get())),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
pub type IsTrustedBridgedReserveLocationForForeignAsset =
|
||||
matching::IsForeignConcreteAsset<FromNetwork<UniversalLocation, EthereumNetwork>>;
|
||||
|
||||
impl Contains<(MultiLocation, Junction)> for UniversalAliases {
|
||||
fn contains(alias: &(MultiLocation, Junction)) -> bool {
|
||||
UniversalAliases::get().contains(alias)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Benchmarks helper for bridging configuration.
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub struct BridgingBenchmarksHelper;
|
||||
|
||||
@@ -865,3 +865,55 @@ fn change_xcm_bridge_hub_router_byte_fee_by_governance_works() {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_xcm_bridge_hub_router_base_fee_by_governance_works() {
|
||||
asset_test_utils::test_cases::change_storage_constant_by_governance_works::<
|
||||
Runtime,
|
||||
bridging::XcmBridgeHubRouterBaseFee,
|
||||
Balance,
|
||||
>(
|
||||
collator_session_keys(),
|
||||
1000,
|
||||
Box::new(|call| RuntimeCall::System(call).encode()),
|
||||
|| {
|
||||
(
|
||||
bridging::XcmBridgeHubRouterBaseFee::key().to_vec(),
|
||||
bridging::XcmBridgeHubRouterBaseFee::get(),
|
||||
)
|
||||
},
|
||||
|old_value| {
|
||||
if let Some(new_value) = old_value.checked_add(1) {
|
||||
new_value
|
||||
} else {
|
||||
old_value.checked_sub(1).unwrap()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_xcm_bridge_hub_ethereum_base_fee_by_governance_works() {
|
||||
asset_test_utils::test_cases::change_storage_constant_by_governance_works::<
|
||||
Runtime,
|
||||
bridging::to_ethereum::BridgeHubEthereumBaseFee,
|
||||
Balance,
|
||||
>(
|
||||
collator_session_keys(),
|
||||
1000,
|
||||
Box::new(|call| RuntimeCall::System(call).encode()),
|
||||
|| {
|
||||
(
|
||||
bridging::to_ethereum::BridgeHubEthereumBaseFee::key().to_vec(),
|
||||
bridging::to_ethereum::BridgeHubEthereumBaseFee::get(),
|
||||
)
|
||||
},
|
||||
|old_value| {
|
||||
if let Some(new_value) = old_value.checked_add(1) {
|
||||
new_value
|
||||
} else {
|
||||
old_value.checked_sub(1).unwrap()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user