use crate::{
bridge_common_config::RelayersForPermissionlessLanesInstance, weights,
xcm_config::UniversalLocation, AccountId, Balance, Balances, BridgeRococoBulletinGrandpa,
BridgeRococoBulletinMessages, Runtime, RuntimeEvent, RuntimeHoldReason, XcmOverRococoBulletin,
XcmRouter,
};
use bp_messages::{
source_chain::FromBridgedChainMessagesDeliveryProof,
target_chain::FromBridgedChainMessagesProof, LegacyLaneId,
};
use frame_support::{
parameter_types,
traits::{Equals, PalletInfoAccess},
};
use frame_system::{EnsureNever, EnsureRoot};
use pallet_bridge_messages::LaneIdOf;
use pallet_bridge_relayers::extension::{
BridgeRelayersTransactionExtension, WithMessagesExtensionConfig,
};
use pallet_xcm_bridge_hub::XcmAsPlainPayload;
use polkadot_parachain_primitives::primitives::Sibling;
use testnet_parachains_constants::rococo::currency::UNITS as ROC;
use xcm::{
latest::prelude::*,
prelude::{InteriorLocation, NetworkId},
AlwaysV5,
};
use xcm_builder::{BridgeBlobDispatcher, ParentIsPreset, SiblingParachainConvertsVia};
parameter_types! {
pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [
PalletInstance(<BridgeRococoBulletinMessages as PalletInfoAccess>::index() as u8)
].into();
pub RococoBulletinGlobalConsensusNetwork: NetworkId = NetworkId::PolkadotBulletin;
pub RococoBulletinGlobalConsensusNetworkLocation: Location = Location::new(
2,
[GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())]
);
pub PriorityBoostPerRelayHeader: u64 = 58_014_163_614_163;
pub PriorityBoostPerMessage: u64 = 182_044_444_444_444;
pub PeopleRococoLocation: Location = Location::new(1, [Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)]);
pub storage BridgeDeposit: Balance = 5 * ROC;
}
pub type FromRococoBulletinMessagesProof<MI> =
FromBridgedChainMessagesProof<bp_polkadot_bulletin::Hash, LaneIdOf<Runtime, MI>>;
pub type ToRococoBulletinMessagesDeliveryProof<MI> =
FromBridgedChainMessagesDeliveryProof<bp_polkadot_bulletin::Hash, LaneIdOf<Runtime, MI>>;
type FromRococoBulletinMessageBlobDispatcher = BridgeBlobDispatcher<
XcmRouter,
UniversalLocation,
BridgeRococoToRococoBulletinMessagesPalletInstance,
>;
pub type OnBridgeHubRococoRefundRococoBulletinMessages = BridgeRelayersTransactionExtension<
Runtime,
WithMessagesExtensionConfig<
StrOnBridgeHubRococoRefundRococoBulletinMessages,
Runtime,
WithRococoBulletinMessagesInstance,
RelayersForPermissionlessLanesInstance,
PriorityBoostPerMessage,
>,
LaneIdOf<Runtime, WithRococoBulletinMessagesInstance>,
>;
bp_runtime::generate_static_str_provider!(OnBridgeHubRococoRefundRococoBulletinMessages);
pub type WithRococoBulletinMessagesInstance = pallet_bridge_messages::Instance4;
impl pallet_bridge_messages::Config<WithRococoBulletinMessagesInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo =
weights::pallet_bridge_messages_rococo_to_rococo_bulletin::WeightInfo<Runtime>;
type ThisChain = bp_bridge_hub_rococo::BridgeHubRococo;
type BridgedChain = bp_polkadot_bulletin::PolkadotBulletin;
type BridgedHeaderChain = BridgeRococoBulletinGrandpa;
type OutboundPayload = XcmAsPlainPayload;
type InboundPayload = XcmAsPlainPayload;
type LaneId = LegacyLaneId;
type DeliveryPayments = ();
type DeliveryConfirmationPayments = ();
type MessageDispatch = XcmOverRococoBulletin;
type OnMessagesDelivered = XcmOverRococoBulletin;
}
pub type XcmOverPolkadotBulletinInstance = pallet_xcm_bridge_hub::Instance2;
impl pallet_xcm_bridge_hub::Config<XcmOverPolkadotBulletinInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type UniversalLocation = UniversalLocation;
type BridgedNetwork = RococoBulletinGlobalConsensusNetworkLocation;
type BridgeMessagesPalletInstance = WithRococoBulletinMessagesInstance;
type MessageExportPrice = ();
type DestinationVersion = AlwaysV5;
type ForceOrigin = EnsureRoot<AccountId>;
type OpenBridgeOrigin = EnsureNever<Location>;
type BridgeOriginAccountIdConverter =
(ParentIsPreset<AccountId>, SiblingParachainConvertsVia<Sibling, AccountId>);
type BridgeDeposit = BridgeDeposit;
type Currency = Balances;
type RuntimeHoldReason = RuntimeHoldReason;
type AllowWithoutBridgeDeposit = Equals<PeopleRococoLocation>;
type LocalXcmChannelManager = ();
type BlobDispatcher = FromRococoBulletinMessageBlobDispatcher;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::bridge_common_config::BridgeGrandpaRococoBulletinInstance;
use bridge_runtime_common::{
assert_complete_bridge_types, integrity::check_message_lane_weights,
};
use parachains_common::Balance;
use testnet_parachains_constants::rococo;
const FEE_BOOST_PER_MESSAGE: Balance = 2 * rococo::currency::UNITS;
const FEE_BOOST_PER_RELAY_HEADER: Balance = 2 * rococo::currency::UNITS;
#[test]
fn ensure_bridge_hub_rococo_message_lane_weights_are_correct() {
check_message_lane_weights::<
bp_bridge_hub_rococo::BridgeHubRococo,
Runtime,
WithRococoBulletinMessagesInstance,
>(
bp_polkadot_bulletin::EXTRA_STORAGE_PROOF_SIZE,
bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
true,
);
}
#[test]
fn ensure_bridge_integrity() {
assert_complete_bridge_types!(
runtime: Runtime,
with_bridged_chain_messages_instance: WithRococoBulletinMessagesInstance,
this_chain: bp_bridge_hub_rococo::BridgeHubRococo,
bridged_chain: bp_polkadot_bulletin::PolkadotBulletin,
);
pallet_bridge_relayers::extension::per_relay_header::ensure_priority_boost_is_sane::<
Runtime,
BridgeGrandpaRococoBulletinInstance,
PriorityBoostPerRelayHeader,
>(FEE_BOOST_PER_RELAY_HEADER);
pallet_bridge_relayers::extension::per_message::ensure_priority_boost_is_sane::<
Runtime,
WithRococoBulletinMessagesInstance,
PriorityBoostPerMessage,
>(FEE_BOOST_PER_MESSAGE);
let expected: InteriorLocation = PalletInstance(
bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX,
)
.into();
assert_eq!(BridgeRococoToRococoBulletinMessagesPalletInstance::get(), expected,);
}
}
#[cfg(feature = "runtime-benchmarks")]
pub(crate) fn open_bridge_for_benchmarks<R, XBHI, C>(
with: pallet_xcm_bridge_hub::LaneIdOf<R, XBHI>,
sibling_para_id: u32,
) -> InteriorLocation
where
R: pallet_xcm_bridge_hub::Config<XBHI>,
XBHI: 'static,
C: xcm_executor::traits::ConvertLocation<
bp_runtime::AccountIdOf<pallet_xcm_bridge_hub::ThisChainOf<R, XBHI>>,
>,
{
use pallet_xcm_bridge_hub::{Bridge, BridgeId, BridgeState};
use sp_runtime::traits::Zero;
use xcm::{latest::ROCOCO_GENESIS_HASH, VersionedInteriorLocation};
let lane_id = with;
let sibling_parachain = Location::new(1, [Parachain(sibling_para_id)]);
let universal_source =
[GlobalConsensus(ByGenesis(ROCOCO_GENESIS_HASH)), Parachain(sibling_para_id)].into();
let universal_destination =
[GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())].into();
let bridge_id = BridgeId::new(&universal_source, &universal_destination);
pallet_xcm_bridge_hub::Bridges::<R, XBHI>::insert(
bridge_id,
Bridge {
bridge_origin_relative_location: alloc::boxed::Box::new(
sibling_parachain.clone().into(),
),
bridge_origin_universal_location: alloc::boxed::Box::new(
VersionedInteriorLocation::from(universal_source.clone()),
),
bridge_destination_universal_location: alloc::boxed::Box::new(
VersionedInteriorLocation::from(universal_destination),
),
state: BridgeState::Opened,
bridge_owner_account: C::convert_location(&sibling_parachain).expect("valid AccountId"),
deposit: Zero::zero(),
lane_id,
},
);
pallet_xcm_bridge_hub::LaneToBridge::<R, XBHI>::insert(lane_id, bridge_id);
universal_source
}