cumulus: add asset-hub-rococo runtime based on asset-hub-kusama and add asset-bridging support to it (#1215)

This commit adds Rococo Asset Hub dedicated runtime so we can test new
features here, before merging them in Kusama Asset Hub.
Also adds one such feature: asset transfer over bridge (Rococo AssetHub
<> Wococo AssetHub)

- clone `asset-hub-kusama-runtime` -> `asset-hub-rococo-runtime`
- make it use Rococo primitives, names, assets, constants, etc
- add asset-transfer-over-bridge support to Rococo AssetHub <> Wococo
AssetHub

Fixes #1128

---------

Co-authored-by: Branislav Kontur <bkontur@gmail.com>
Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
This commit is contained in:
Adrian Catangiu
2023-10-18 09:47:45 +03:00
committed by GitHub
parent e73729b15f
commit 8b3905d2a5
95 changed files with 14143 additions and 767 deletions
@@ -65,7 +65,7 @@ cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-fea
cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false, features = ["parameterized-consensus-hook",] }
cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false}
cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] }
cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false }
cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false }
pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false }
@@ -73,6 +73,8 @@ parachain-info = { path = "../../../pallets/parachain-info", default-features =
parachains-common = { path = "../../../common", default-features = false }
# Bridges
bp-asset-hub-rococo = { path = "../../../../../bridges/primitives/chain-asset-hub-rococo", default-features = false }
bp-asset-hub-wococo = { path = "../../../../../bridges/primitives/chain-asset-hub-wococo", default-features = false }
bp-bridge-hub-rococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-rococo", default-features = false }
bp-bridge-hub-wococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-wococo", default-features = false }
bp-header-chain = { path = "../../../../../bridges/primitives/header-chain", default-features = false }
@@ -98,6 +100,8 @@ sp-keyring = { path = "../../../../../substrate/primitives/keyring" }
[features]
default = [ "std" ]
std = [
"bp-asset-hub-rococo/std",
"bp-asset-hub-wococo/std",
"bp-bridge-hub-rococo/std",
"bp-bridge-hub-wococo/std",
"bp-header-chain/std",
@@ -33,6 +33,7 @@ use bridge_runtime_common::{
RefundableMessagesLane, RefundableParachain,
},
};
use codec::Encode;
use frame_support::{parameter_types, traits::PalletInfoAccess};
use sp_runtime::RuntimeDebug;
use xcm::{
@@ -51,12 +52,38 @@ parameter_types! {
pub BridgeHubRococoUniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Rococo), Parachain(ParachainInfo::parachain_id().into()));
pub WococoGlobalConsensusNetwork: NetworkId = NetworkId::Wococo;
pub ActiveOutboundLanesToBridgeHubWococo: &'static [bp_messages::LaneId] = &[DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO];
pub PriorityBoostPerMessage: u64 = 921_900_294;
// see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value
pub PriorityBoostPerMessage: u64 = 182_044_444_444_444;
pub AssetHubRococoParaId: cumulus_primitives_core::ParaId = bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID.into();
pub FromAssetHubRococoToAssetHubWococoRoute: SenderAndLane = SenderAndLane::new(
ParentThen(X1(Parachain(1000))).into(),
ParentThen(X1(Parachain(AssetHubRococoParaId::get().into()))).into(),
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
);
pub CongestedMessage: Xcm<()> = build_congestion_message(true).into();
pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into();
}
fn build_congestion_message<Call>(is_congested: bool) -> sp_std::vec::Vec<Instruction<Call>> {
sp_std::vec![
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
Transact {
origin_kind: OriginKind::Xcm,
require_weight_at_most:
bp_asset_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(),
call: bp_asset_hub_rococo::Call::ToWococoXcmRouter(
bp_asset_hub_rococo::XcmBridgeHubRouterCall::report_bridge_status {
bridge_id: Default::default(),
is_congested,
}
)
.encode()
.into(),
}
]
}
/// Proof of messages, coming from Wococo.
@@ -73,7 +100,7 @@ pub type OnBridgeHubRococoBlobDispatcher = BridgeBlobDispatcher<
BridgeWococoMessagesPalletInstance,
>;
/// Export XCM messages to be relayed to the otherside
/// Export XCM messages to be relayed to the other side
pub type ToBridgeHubWococoHaulBlobExporter = HaulBlobExporter<
XcmBlobHaulerAdapter<ToBridgeHubWococoXcmBlobHauler>,
WococoGlobalConsensusNetwork,
@@ -86,11 +113,14 @@ impl XcmBlobHauler for ToBridgeHubWococoXcmBlobHauler {
type SenderAndLane = FromAssetHubRococoToAssetHubWococoRoute;
type ToSourceChainSender = crate::XcmRouter;
type CongestedMessage = ();
type UncongestedMessage = ();
type CongestedMessage = CongestedMessage;
type UncongestedMessage = UncongestedMessage;
}
pub const DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO: LaneId = LaneId([0, 0, 0, 1]);
/// On messages delivered callback.
pub type OnMessagesDelivered = XcmBlobHaulerAdapter<ToBridgeHubWococoXcmBlobHauler>;
/// Messaging Bridge configuration for BridgeHubRococo -> BridgeHubWococo
pub struct WithBridgeHubWococoMessageBridge;
impl MessageBridge for WithBridgeHubWococoMessageBridge {
@@ -164,6 +194,18 @@ mod tests {
AssertCompleteBridgeConstants,
},
};
use parachains_common::{rococo, Balance};
/// Every additional message in the message delivery transaction boosts its priority.
/// So the priority of transaction with `N+1` messages is larger than priority of
/// transaction with `N` messages by the `PriorityBoostPerMessage`.
///
/// Economically, it is an equivalent of adding tip to the transaction with `N` messages.
/// The `FEE_BOOST_PER_MESSAGE` constant is the value of this tip.
///
/// We want this tip to be large enough (delivery transactions with more messages = less
/// operational costs and a faster bridge), so this value should be significant.
const FEE_BOOST_PER_MESSAGE: Balance = 2 * rococo::currency::UNITS;
#[test]
fn ensure_bridge_hub_rococo_message_lane_weights_are_correct() {
@@ -215,5 +257,16 @@ mod tests {
bp_bridge_hub_wococo::WITH_BRIDGE_HUB_WOCOCO_MESSAGES_PALLET_NAME,
},
});
bridge_runtime_common::priority_calculator::ensure_priority_boost_is_sane::<
Runtime,
WithBridgeHubWococoMessagesInstance,
PriorityBoostPerMessage,
>(FEE_BOOST_PER_MESSAGE);
assert_eq!(
BridgeWococoMessagesPalletInstance::get(),
X1(PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_WOCOCO_MESSAGES_PALLET_INDEX))
);
}
}
@@ -33,6 +33,7 @@ use bridge_runtime_common::{
RefundableMessagesLane, RefundableParachain,
},
};
use codec::Encode;
use frame_support::{parameter_types, traits::PalletInfoAccess};
use sp_runtime::RuntimeDebug;
use xcm::{
@@ -51,18 +52,44 @@ parameter_types! {
pub BridgeRococoMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(<BridgeRococoMessages as PalletInfoAccess>::index() as u8));
pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo;
pub ActiveOutboundLanesToBridgeHubRococo: &'static [bp_messages::LaneId] = &[DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO];
pub PriorityBoostPerMessage: u64 = 921_900_294;
// see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value
pub PriorityBoostPerMessage: u64 = 182_044_444_444_444;
pub AssetHubWococoParaId: cumulus_primitives_core::ParaId = bp_asset_hub_wococo::ASSET_HUB_WOCOCO_PARACHAIN_ID.into();
pub FromAssetHubWococoToAssetHubRococoRoute: SenderAndLane = SenderAndLane::new(
ParentThen(X1(Parachain(1000))).into(),
ParentThen(X1(Parachain(AssetHubWococoParaId::get().into()))).into(),
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
);
pub CongestedMessage: Xcm<()> = build_congestion_message(true).into();
pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into();
}
fn build_congestion_message<Call>(is_congested: bool) -> sp_std::vec::Vec<Instruction<Call>> {
sp_std::vec![
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
Transact {
origin_kind: OriginKind::Xcm,
require_weight_at_most:
bp_asset_hub_wococo::XcmBridgeHubRouterTransactCallMaxWeight::get(),
call: bp_asset_hub_wococo::Call::ToRococoXcmRouter(
bp_asset_hub_wococo::XcmBridgeHubRouterCall::report_bridge_status {
bridge_id: Default::default(),
is_congested,
}
)
.encode()
.into(),
}
]
}
/// Proof of messages, coming from Rococo.
pub type FromRococoBridgeHubMessagesProof =
FromBridgedChainMessagesProof<bp_bridge_hub_rococo::Hash>;
/// Messages delivery proof for Rococo Bridge Hub -> Wococo Bridge Hub messages.
/// Messages delivery proof for RococoBridge Hub -> Wococo BridgeHub messages.
pub type ToRococoBridgeHubMessagesDeliveryProof =
FromBridgedChainMessagesDeliveryProof<bp_bridge_hub_rococo::Hash>;
@@ -73,7 +100,7 @@ pub type OnBridgeHubWococoBlobDispatcher = BridgeBlobDispatcher<
BridgeRococoMessagesPalletInstance,
>;
/// Export XCM messages to be relayed to the otherside
/// Export XCM messages to be relayed to the other side
pub type ToBridgeHubRococoHaulBlobExporter = HaulBlobExporter<
XcmBlobHaulerAdapter<ToBridgeHubRococoXcmBlobHauler>,
RococoGlobalConsensusNetwork,
@@ -86,11 +113,14 @@ impl XcmBlobHauler for ToBridgeHubRococoXcmBlobHauler {
type SenderAndLane = FromAssetHubWococoToAssetHubRococoRoute;
type ToSourceChainSender = crate::XcmRouter;
type CongestedMessage = ();
type UncongestedMessage = ();
type CongestedMessage = CongestedMessage;
type UncongestedMessage = UncongestedMessage;
}
pub const DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO: LaneId = LaneId([0, 0, 0, 1]);
/// On messages delivered callback.
pub type OnMessagesDelivered = XcmBlobHaulerAdapter<ToBridgeHubRococoXcmBlobHauler>;
/// Messaging Bridge configuration for BridgeHubWococo -> BridgeHubRococo
pub struct WithBridgeHubRococoMessageBridge;
impl MessageBridge for WithBridgeHubRococoMessageBridge {
@@ -164,6 +194,18 @@ mod tests {
AssertCompleteBridgeConstants,
},
};
use parachains_common::{wococo, Balance};
/// Every additional message in the message delivery transaction boosts its priority.
/// So the priority of transaction with `N+1` messages is larger than priority of
/// transaction with `N` messages by the `PriorityBoostPerMessage`.
///
/// Economically, it is an equivalent of adding tip to the transaction with `N` messages.
/// The `FEE_BOOST_PER_MESSAGE` constant is the value of this tip.
///
/// We want this tip to be large enough (delivery transactions with more messages = less
/// operational costs and a faster bridge), so this value should be significant.
const FEE_BOOST_PER_MESSAGE: Balance = 2 * wococo::currency::UNITS;
#[test]
fn ensure_bridge_hub_wococo_message_lane_weights_are_correct() {
@@ -215,5 +257,16 @@ mod tests {
bp_bridge_hub_rococo::WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME,
},
});
bridge_runtime_common::priority_calculator::ensure_priority_boost_is_sane::<
Runtime,
WithBridgeHubRococoMessagesInstance,
PriorityBoostPerMessage,
>(FEE_BOOST_PER_MESSAGE);
assert_eq!(
BridgeRococoMessagesPalletInstance::get(),
X1(PalletInstance(bp_bridge_hub_wococo::WITH_BRIDGE_ROCOCO_MESSAGES_PALLET_INDEX))
);
}
}
@@ -14,6 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
//! # Bridge Hub Rococo Runtime
//!
//! This runtime is also used for Bridge Hub Wococo. But we dont want to create another exact copy
//! of Bridge Hub Rococo, so we injected some tweaks backed by `RuntimeFlavor` and `pub storage
//! Flavor: RuntimeFlavor`. (For example this is needed for successful asset transfer between Asset
//! Hub Rococo and Asset Hub Wococo, where we need to have correct `xcm_config::UniversalLocation`
//! with correct `GlobalConsensus`.
#![cfg_attr(not(feature = "std"), no_std)]
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]
@@ -27,6 +35,7 @@ pub mod bridge_hub_wococo_config;
mod weights;
pub mod xcm_config;
use codec::{Decode, Encode};
use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
use sp_api::impl_runtime_apis;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
@@ -92,6 +101,15 @@ use parachains_common::{
};
use xcm_executor::XcmExecutor;
/// Enum for handling differences in the runtime configuration for BridgeHubRococo vs
/// BridgeHubWococo.
#[derive(Default, Eq, PartialEq, Debug, Clone, Copy, Decode, Encode)]
pub enum RuntimeFlavor {
#[default]
Rococo,
Wococo,
}
/// The address format for describing accounts.
pub type Address = MultiAddress<AccountId, ()>;
@@ -473,7 +491,7 @@ parameter_types! {
pub const RelayerStakeReserveId: [u8; 8] = *b"brdgrlrs";
}
/// Add parachain bridge pallet to track Wococo bridge hub parachain
/// Add parachain bridge pallet to track Wococo BridgeHub parachain
pub type BridgeParachainWococoInstance = pallet_bridge_parachains::Instance1;
impl pallet_bridge_parachains::Config<BridgeParachainWococoInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
@@ -486,7 +504,7 @@ impl pallet_bridge_parachains::Config<BridgeParachainWococoInstance> for Runtime
type MaxParaHeadDataSize = MaxWococoParaHeadDataSize;
}
/// Add parachain bridge pallet to track Rococo bridge hub parachain
/// Add parachain bridge pallet to track Rococo BridgeHub parachain
pub type BridgeParachainRococoInstance = pallet_bridge_parachains::Instance2;
impl pallet_bridge_parachains::Config<BridgeParachainRococoInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
@@ -528,9 +546,15 @@ impl pallet_bridge_messages::Config<WithBridgeHubWococoMessagesInstance> for Run
>;
type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubWococoMessageBridge>;
type MessageDispatch =
XcmBlobMessageDispatch<OnBridgeHubRococoBlobDispatcher, Self::WeightInfo, ()>;
type OnMessagesDelivered = ();
type MessageDispatch = XcmBlobMessageDispatch<
OnBridgeHubRococoBlobDispatcher,
Self::WeightInfo,
cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider<
bridge_hub_rococo_config::AssetHubRococoParaId,
Runtime,
>,
>;
type OnMessagesDelivered = bridge_hub_rococo_config::OnMessagesDelivered;
}
/// Add XCM messages support for BridgeHubWococo to support Wococo->Rococo XCM messages
@@ -562,9 +586,15 @@ impl pallet_bridge_messages::Config<WithBridgeHubRococoMessagesInstance> for Run
>;
type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubRococoMessageBridge>;
type MessageDispatch =
XcmBlobMessageDispatch<OnBridgeHubWococoBlobDispatcher, Self::WeightInfo, ()>;
type OnMessagesDelivered = ();
type MessageDispatch = XcmBlobMessageDispatch<
OnBridgeHubWococoBlobDispatcher,
Self::WeightInfo,
cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider<
bridge_hub_wococo_config::AssetHubWococoParaId,
Runtime,
>,
>;
type OnMessagesDelivered = bridge_hub_wococo_config::OnMessagesDelivered;
}
/// Allows collect and claim rewards for relayers
@@ -617,16 +647,16 @@ construct_runtime!(
Utility: pallet_utility::{Pallet, Call, Event} = 40,
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 36,
// Rococo and Wococo Bridge Hubs are sharing the runtime, so this runtime has two sets of
// Rococo and Wococo BridgeHubs are sharing the runtime, so this runtime has two sets of
// bridge pallets. Both are deployed at both runtimes, but only one set is actually used
// at particular runtime.
// With-Wococo bridge modules that are active (used) at Rococo Bridge Hub runtime.
// With-Wococo bridge modules that are active (used) at Rococo BridgeHub runtime.
BridgeWococoGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 41,
BridgeWococoParachain: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage, Event<T>} = 42,
BridgeWococoMessages: pallet_bridge_messages::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 46,
// With-Rococo bridge modules that are active (used) at Wococo Bridge Hub runtime.
// With-Rococo bridge modules that are active (used) at Wococo BridgeHub runtime.
BridgeRococoGrandpa: pallet_bridge_grandpa::<Instance2>::{Pallet, Call, Storage, Event<T>, Config<T>} = 43,
BridgeRococoParachain: pallet_bridge_parachains::<Instance2>::{Pallet, Call, Storage, Event<T>} = 44,
BridgeRococoMessages: pallet_bridge_messages::<Instance2>::{Pallet, Call, Storage, Event<T>, Config<T>} = 45,
@@ -982,19 +1012,19 @@ impl_runtime_apis! {
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
use xcm::latest::prelude::*;
use xcm_config::RelayLocation;
use xcm_config::TokenLocation;
impl pallet_xcm_benchmarks::Config for Runtime {
type XcmConfig = xcm_config::XcmConfig;
type AccountIdConverter = xcm_config::LocationToAccountId;
fn valid_destination() -> Result<MultiLocation, BenchmarkError> {
Ok(RelayLocation::get())
Ok(TokenLocation::get())
}
fn worst_case_holding(_depositable_count: u32) -> MultiAssets {
// just concrete assets according to relay chain.
let assets: Vec<MultiAsset> = vec![
MultiAsset {
id: Concrete(RelayLocation::get()),
id: Concrete(TokenLocation::get()),
fun: Fungible(1_000_000 * UNITS),
}
];
@@ -1004,8 +1034,8 @@ impl_runtime_apis! {
parameter_types! {
pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some((
RelayLocation::get(),
MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) },
TokenLocation::get(),
MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) },
));
pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None;
@@ -1020,7 +1050,7 @@ impl_runtime_apis! {
fn get_multi_asset() -> MultiAsset {
MultiAsset {
id: Concrete(RelayLocation::get()),
id: Concrete(TokenLocation::get()),
fun: Fungible(UNITS),
}
}
@@ -1042,16 +1072,16 @@ impl_runtime_apis! {
}
fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> {
Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
}
fn subscribe_origin() -> Result<MultiLocation, BenchmarkError> {
Ok(RelayLocation::get())
Ok(TokenLocation::get())
}
fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> {
let origin = RelayLocation::get();
let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into();
let origin = TokenLocation::get();
let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into();
let ticket = MultiLocation { parents: 0, interior: Here };
Ok((origin, ticket, assets))
}
@@ -1062,7 +1092,7 @@ impl_runtime_apis! {
fn export_message_origin_and_destination(
) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> {
Ok((RelayLocation::get(), NetworkId::Wococo, X1(Parachain(100))))
Ok((TokenLocation::get(), NetworkId::Wococo, X1(Parachain(100))))
}
fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> {
@@ -17,8 +17,8 @@
use super::{
AccountId, AllPalletsWithSystem, Balances, BridgeGrandpaRococoInstance,
BridgeGrandpaWococoInstance, DeliveryRewardInBalance, ParachainInfo, ParachainSystem,
PolkadotXcm, RequiredStakeForStakeAndSlash, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
WeightToFee, XcmpQueue,
PolkadotXcm, RequiredStakeForStakeAndSlash, Runtime, RuntimeCall, RuntimeEvent, RuntimeFlavor,
RuntimeOrigin, WeightToFee, XcmpQueue,
};
use crate::{
bridge_hub_rococo_config::ToBridgeHubWococoHaulBlobExporter,
@@ -36,12 +36,11 @@ use sp_core::Get;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, IsConcrete,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter,
DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, IsConcrete, ParentAsSuperuser,
ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::{
traits::{ExportXcm, WithOriginFilter},
@@ -49,7 +48,8 @@ use xcm_executor::{
};
parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
pub storage Flavor: RuntimeFlavor = RuntimeFlavor::default();
pub const TokenLocation: MultiLocation = MultiLocation::parent();
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorMultiLocation =
X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into()));
@@ -57,6 +57,7 @@ parameter_types! {
pub const MaxAssetsIntoHolding: u32 = 64;
}
/// Adapter for resolving `NetworkId` based on `pub storage Flavor: RuntimeFlavor`.
pub struct RelayNetwork;
impl Get<Option<NetworkId>> for RelayNetwork {
fn get() -> Option<NetworkId> {
@@ -65,10 +66,9 @@ impl Get<Option<NetworkId>> for RelayNetwork {
}
impl Get<NetworkId> for RelayNetwork {
fn get() -> NetworkId {
match u32::from(ParachainInfo::parachain_id()) {
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID => NetworkId::Rococo,
bp_bridge_hub_wococo::BRIDGE_HUB_WOCOCO_PARACHAIN_ID => NetworkId::Wococo,
para_id => unreachable!("Not supported for para_id: {}", para_id),
match Flavor::get() {
RuntimeFlavor::Rococo => NetworkId::Rococo,
RuntimeFlavor::Wococo => NetworkId::Wococo,
}
}
}
@@ -90,7 +90,7 @@ pub type CurrencyTransactor = CurrencyAdapter<
// Use this currency:
Balances,
// Use this currency when it is a fungible asset matching the given location or name:
IsConcrete<RelayLocation>,
IsConcrete<TokenLocation>,
// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
LocationToAccountId,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
@@ -154,9 +154,10 @@ 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().any(|(k, _)| {
if items.iter().all(|(k, _)| {
k.eq(&DeliveryRewardInBalance::key()) |
k.eq(&RequiredStakeForStakeAndSlash::key())
k.eq(&RequiredStakeForStakeAndSlash::key()) |
k.eq(&Flavor::key())
}) =>
return true,
_ => (),
@@ -206,7 +207,7 @@ pub type Barrier = TrailingSetTopicAsId<
AllowKnownQueryResponses<PolkadotXcm>,
WithComputedOrigin<
(
// If the message is one that immediately attemps to pay for execution, then
// If the message is one that immediately attempts to pay for execution, then
// allow it.
AllowTopLevelPaidExecutionFrom<Everything>,
// Parent and its pluralities (i.e. governance bodies) get free execution.
@@ -217,16 +218,13 @@ pub type Barrier = TrailingSetTopicAsId<
UniversalLocation,
ConstU32<8>,
>,
// TODO:check-parameter - (https://github.com/paritytech/parity-bridges-common/issues/2084)
// remove this and extend `AllowExplicitUnpaidExecutionFrom` with "or SystemParachains" once merged https://github.com/paritytech/polkadot/pull/7005
AllowUnpaidExecutionFrom<Everything>,
),
>,
>;
/// Cases where a remote origin is accepted as trusted Teleporter for a given asset:
/// - NativeToken with the parent Relay Chain and sibling parachains.
pub type TrustedTeleporters = ConcreteAssetFromSystem<RelayLocation>;
pub type TrustedTeleporters = ConcreteAssetFromSystem<TokenLocation>;
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
@@ -246,7 +244,7 @@ impl xcm_executor::Config for XcmConfig {
MaxInstructions,
>;
type Trader =
UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ToStakingPot<Runtime>>;
UsingComponents<WeightToFee, TokenLocation, AccountId, Balances, ToStakingPot<Runtime>>;
type ResponseHandler = PolkadotXcm;
type AssetTrap = PolkadotXcm;
type AssetLocker = ();
@@ -19,7 +19,7 @@
use bp_polkadot_core::Signature;
use bridge_hub_rococo_runtime::{
bridge_hub_rococo_config, bridge_hub_wococo_config,
xcm_config::{RelayNetwork, XcmConfig},
xcm_config::{RelayNetwork, TokenLocation, XcmConfig},
AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, DeliveryRewardInBalance,
Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, RequiredStakeForStakeAndSlash,
Runtime, RuntimeCall, RuntimeEvent, SessionKeys, SignedExtra, UncheckedExtrinsic,
@@ -35,7 +35,7 @@ use sp_runtime::{
};
use xcm::latest::prelude::*;
// Para id of sibling chain (Rockmine/Wockmint) used in tests.
// Para id of sibling chain used in tests.
pub const SIBLING_PARACHAIN_ID: u32 = 1000;
parameter_types! {
@@ -55,7 +55,7 @@ fn construct_extrinsic(
frame_system::CheckNonce::<Runtime>::from(0),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
BridgeRejectObsoleteHeadersAndMessages {},
BridgeRejectObsoleteHeadersAndMessages::default(),
(
bridge_hub_wococo_config::BridgeRefundBridgeHubRococoMessages::default(),
bridge_hub_rococo_config::BridgeRefundBridgeHubWococoMessages::default(),
@@ -191,7 +191,11 @@ mod bridge_hub_rococo_tests {
}
}),
|| ExportMessage { network: Wococo, destination: X1(Parachain(1234)), xcm: Xcm(vec![]) },
bridge_hub_rococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO
bridge_hub_rococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
Some((TokenLocation::get(), ExistentialDeposit::get()).into()),
// value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer`
Some((TokenLocation::get(), bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs::get()).into()),
|| (),
)
}
@@ -222,6 +226,7 @@ mod bridge_hub_rococo_tests {
}
}),
bridge_hub_rococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
|| (),
)
}
@@ -243,6 +248,7 @@ mod bridge_hub_rococo_tests {
SIBLING_PARACHAIN_ID,
Rococo,
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
|| (),
)
}
@@ -268,6 +274,25 @@ mod bridge_hub_rococo_tests {
ExistentialDeposit::get(),
executive_init_block,
construct_and_apply_extrinsic,
|| (),
);
}
#[test]
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::<
Runtime,
XcmConfig,
WeightToFee,
>();
// check if estimated value is sane
let max_expected = bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs::get();
assert!(
estimated <= max_expected,
"calculated: {:?}, max_expected: {:?}, please adjust `bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs` value",
estimated,
max_expected
);
}
}
@@ -275,12 +300,38 @@ mod bridge_hub_rococo_tests {
mod bridge_hub_wococo_tests {
use super::*;
use bridge_hub_rococo_runtime::{
BridgeGrandpaRococoInstance, BridgeParachainRococoInstance,
WithBridgeHubRococoMessagesInstance,
xcm_config, AllPalletsWithoutSystem, BridgeGrandpaRococoInstance,
BridgeParachainRococoInstance, RuntimeFlavor, WithBridgeHubRococoMessagesInstance,
};
use bridge_hub_wococo_config::{
WithBridgeHubRococoMessageBridge, DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
};
use frame_support::assert_ok;
type RuntimeHelper = bridge_hub_test_utils::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;
pub(crate) fn set_wococo_flavor() {
let flavor_key = xcm_config::Flavor::key().to_vec();
let flavor = RuntimeFlavor::Wococo;
// encode `set_storage` call
let set_storage_call = RuntimeCall::System(frame_system::Call::<Runtime>::set_storage {
items: vec![(flavor_key, flavor.encode())],
})
.encode();
// estimate - storing just 1 value
use frame_system::WeightInfo;
let require_weight_at_most =
<Runtime as frame_system::Config>::SystemWeightInfo::set_storage(1);
// execute XCM with Transact to `set_storage` as governance does
assert_ok!(RuntimeHelper::execute_as_governance(set_storage_call, require_weight_at_most)
.ensure_complete());
// check if stored
assert_eq!(flavor, xcm_config::Flavor::get());
}
bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!(
Runtime,
@@ -370,7 +421,11 @@ mod bridge_hub_wococo_tests {
}
}),
|| ExportMessage { network: Rococo, destination: X1(Parachain(4321)), xcm: Xcm(vec![]) },
bridge_hub_wococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO
bridge_hub_wococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
Some((TokenLocation::get(), ExistentialDeposit::get()).into()),
// value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer`
Some((TokenLocation::get(), bp_asset_hub_wococo::BridgeHubWococoBaseFeeInWocs::get()).into()),
set_wococo_flavor,
)
}
@@ -401,6 +456,7 @@ mod bridge_hub_wococo_tests {
}
}),
bridge_hub_wococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
set_wococo_flavor,
)
}
@@ -422,6 +478,7 @@ mod bridge_hub_wococo_tests {
SIBLING_PARACHAIN_ID,
Wococo,
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
set_wococo_flavor,
)
}
@@ -447,6 +504,25 @@ mod bridge_hub_wococo_tests {
ExistentialDeposit::get(),
executive_init_block,
construct_and_apply_extrinsic,
set_wococo_flavor,
);
}
#[test]
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::<
Runtime,
XcmConfig,
WeightToFee,
>();
// check if estimated value is sane
let max_expected = bp_asset_hub_wococo::BridgeHubWococoBaseFeeInWocs::get();
assert!(
estimated <= max_expected,
"calculated: {:?}, max_expected: {:?}, please adjust `bp_asset_hub_wococo::BridgeHubWococoBaseFeeInWocs` value",
estimated,
max_expected
);
}
}