diff --git a/Cargo.lock b/Cargo.lock
index 18a49df670..e8e725f11b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1255,14 +1255,11 @@ dependencies = [
"frame-support",
"parity-scale-codec",
"scale-info",
+ "serde",
"sp-std 8.0.0 (git+https://github.com/paritytech/substrate?branch=master)",
"xcm",
]
-[[package]]
-name = "bp-xcm-bridge-hub-router"
-version = "0.1.0"
-
[[package]]
name = "bridge-runtime-common"
version = "0.1.0"
@@ -1274,6 +1271,7 @@ dependencies = [
"bp-relayers",
"bp-runtime",
"bp-test-utils",
+ "bp-xcm-bridge-hub",
"frame-support",
"frame-system",
"hash-db",
@@ -6174,6 +6172,7 @@ dependencies = [
"sp-timestamp",
"substrate-build-script-utils",
"substrate-frame-rpc-system",
+ "xcm",
]
[[package]]
@@ -6190,7 +6189,7 @@ dependencies = [
"bp-rialto-parachain",
"bp-runtime",
"bp-westend",
- "bp-xcm-bridge-hub-router",
+ "bp-xcm-bridge-hub",
"bridge-runtime-common",
"env_logger",
"frame-benchmarking",
@@ -6217,6 +6216,7 @@ dependencies = [
"pallet-transaction-payment-rpc-runtime-api",
"pallet-utility",
"pallet-xcm",
+ "pallet-xcm-bridge-hub",
"pallet-xcm-bridge-hub-router",
"parity-scale-codec",
"scale-info",
@@ -7972,7 +7972,7 @@ dependencies = [
name = "pallet-xcm-bridge-hub-router"
version = "0.1.0"
dependencies = [
- "bp-xcm-bridge-hub-router",
+ "bp-xcm-bridge-hub",
"frame-benchmarking",
"frame-support",
"frame-system",
@@ -10502,6 +10502,7 @@ dependencies = [
"sp-core",
"sp-runtime",
"substrate-build-script-utils",
+ "xcm",
]
[[package]]
@@ -10557,6 +10558,7 @@ dependencies = [
"substrate-build-script-utils",
"substrate-frame-rpc-system",
"substrate-prometheus-endpoint",
+ "xcm",
]
[[package]]
@@ -10569,6 +10571,7 @@ dependencies = [
"bp-relayers",
"bp-rialto-parachain",
"bp-runtime",
+ "bp-xcm-bridge-hub",
"bridge-runtime-common",
"cumulus-pallet-aura-ext",
"cumulus-pallet-dmp-queue",
@@ -10594,6 +10597,7 @@ dependencies = [
"pallet-transaction-payment",
"pallet-transaction-payment-rpc-runtime-api",
"pallet-xcm",
+ "pallet-xcm-bridge-hub",
"parachain-info",
"parity-scale-codec",
"polkadot-parachain",
@@ -10627,6 +10631,7 @@ dependencies = [
"bp-relayers",
"bp-rialto",
"bp-runtime",
+ "bp-xcm-bridge-hub",
"bridge-runtime-common",
"env_logger",
"frame-benchmarking",
@@ -10654,6 +10659,7 @@ dependencies = [
"pallet-transaction-payment",
"pallet-transaction-payment-rpc-runtime-api",
"pallet-xcm",
+ "pallet-xcm-bridge-hub",
"parity-scale-codec",
"polkadot-primitives",
"polkadot-runtime-common",
@@ -13934,6 +13940,7 @@ dependencies = [
"num-traits",
"pallet-bridge-messages",
"pallet-bridge-parachains",
+ "pallet-xcm-bridge-hub",
"parachains-relay",
"parity-scale-codec",
"polkadot-parachain",
diff --git a/Cargo.toml b/Cargo.toml
index 20cf2e8d6d..5d948cdebf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -40,7 +40,6 @@ members = [
"primitives/runtime",
"primitives/test-utils",
"primitives/xcm-bridge-hub",
- "primitives/xcm-bridge-hub-router",
"relays/bin-substrate",
"relays/client-bridge-hub-kusama",
"relays/client-bridge-hub-polkadot",
diff --git a/README.md b/README.md
index e72d4b2cd4..383e57609d 100644
--- a/README.md
+++ b/README.md
@@ -189,7 +189,7 @@ You will also see the message lane relayers listening for new messages.
```
# Message Relayer Logs
-[Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7] [date] DEBUG bridge Asking Millau::ReceivingConfirmationsDelivery about best message nonces
+[Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7] [date] DEBUG bridge Asking Millau::ReceivingConfirmationsDelivery about best message nonces
[...] [date] INFO bridge Synced Some(2) of Some(3) nonces in Millau::MessagesDelivery -> Rialto::MessagesDelivery race
[...] [date] DEBUG bridge Asking Millau::MessagesDelivery about message nonces
[...] [date] DEBUG bridge Received best nonces from Millau::ReceivingConfirmationsDelivery: TargetClientNonces { latest_nonce: 0, nonces_data: () }
diff --git a/bin/millau/node/Cargo.toml b/bin/millau/node/Cargo.toml
index 5b8ddced15..47b00fe1fc 100644
--- a/bin/millau/node/Cargo.toml
+++ b/bin/millau/node/Cargo.toml
@@ -54,6 +54,10 @@ sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "mast
substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-network-common = { git = "https://github.com/paritytech/substrate", branch = "master" }
+# Polkadot Dependencies
+
+xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+
[build-dependencies]
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
diff --git a/bin/millau/node/src/chain_spec.rs b/bin/millau/node/src/chain_spec.rs
index ced3f4939c..8f63d35368 100644
--- a/bin/millau/node/src/chain_spec.rs
+++ b/bin/millau/node/src/chain_spec.rs
@@ -14,12 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
-use bridge_runtime_common::messages_xcm_extension::XcmBlobHauler;
use millau_runtime::{
AccountId, AuraConfig, BalancesConfig, BeefyConfig, BridgeRialtoMessagesConfig,
BridgeRialtoParachainMessagesConfig, BridgeWestendGrandpaConfig, GrandpaConfig,
RuntimeGenesisConfig, SessionConfig, SessionKeys, Signature, SudoConfig, SystemConfig,
- WASM_BINARY,
+ XcmRialtoBridgeHubConfig, XcmRialtoParachainBridgeHubConfig, WASM_BINARY,
};
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_consensus_beefy::crypto::AuthorityId as BeefyId;
@@ -225,19 +224,34 @@ fn testnet_genesis(
},
bridge_rialto_messages: BridgeRialtoMessagesConfig {
owner: Some(get_account_id_from_seed::(RIALTO_MESSAGES_PALLET_OWNER)),
- opened_lanes: vec![millau_runtime::rialto_messages::ToRialtoXcmBlobHauler::xcm_lane()],
+ opened_lanes: vec![millau_runtime::rialto_messages::Bridge::get().lane_id()],
..Default::default()
},
bridge_rialto_parachain_messages: BridgeRialtoParachainMessagesConfig {
owner: Some(get_account_id_from_seed::(
RIALTO_PARACHAIN_MESSAGES_PALLET_OWNER,
)),
- opened_lanes: vec![
- millau_runtime::rialto_parachain_messages::ToRialtoParachainXcmBlobHauler::xcm_lane(
- ),
- ],
+ opened_lanes: vec![millau_runtime::rialto_parachain_messages::Bridge::get().lane_id()],
..Default::default()
},
xcm_pallet: Default::default(),
+ xcm_rialto_bridge_hub: XcmRialtoBridgeHubConfig {
+ opened_bridges: vec![(
+ xcm::latest::Junctions::Here.into(),
+ xcm::latest::InteriorMultiLocation::from(
+ millau_runtime::xcm_config::RialtoNetwork::get(),
+ ),
+ )],
+ ..Default::default()
+ },
+ xcm_rialto_parachain_bridge_hub: XcmRialtoParachainBridgeHubConfig {
+ opened_bridges: vec![(
+ xcm::latest::Junctions::Here.into(),
+ xcm::latest::InteriorMultiLocation::from(
+ millau_runtime::xcm_config::RialtoParachainNetwork::get(),
+ ),
+ )],
+ ..Default::default()
+ },
}
}
diff --git a/bin/millau/runtime/Cargo.toml b/bin/millau/runtime/Cargo.toml
index ccff85b99e..4bb32f724f 100644
--- a/bin/millau/runtime/Cargo.toml
+++ b/bin/millau/runtime/Cargo.toml
@@ -23,13 +23,14 @@ bp-rialto = { path = "../../../primitives/chain-rialto", default-features = fals
bp-rialto-parachain = { path = "../../../primitives/chain-rialto-parachain", default-features = false }
bp-runtime = { path = "../../../primitives/runtime", default-features = false }
bp-westend = { path = "../../../primitives/chain-westend", default-features = false }
-bp-xcm-bridge-hub-router = { path = "../../../primitives/xcm-bridge-hub-router", default-features = false }
+bp-xcm-bridge-hub = { path = "../../../primitives/xcm-bridge-hub", default-features = false }
bridge-runtime-common = { path = "../../runtime-common", default-features = false }
pallet-bridge-grandpa = { path = "../../../modules/grandpa", default-features = false }
pallet-bridge-messages = { path = "../../../modules/messages", default-features = false }
pallet-bridge-parachains = { path = "../../../modules/parachains", default-features = false }
pallet-bridge-relayers = { path = "../../../modules/relayers", default-features = false }
pallet-shift-session-manager = { path = "../../../modules/shift-session-manager", default-features = false }
+pallet-xcm-bridge-hub = { path = "../../../modules/xcm-bridge-hub", default-features = false }
pallet-xcm-bridge-hub-router = { path = "../../../modules/xcm-bridge-hub-router", default-features = false }
# Substrate Dependencies
@@ -92,7 +93,7 @@ std = [
"bp-rialto-parachain/std",
"bp-runtime/std",
"bp-westend/std",
- "bp-xcm-bridge-hub-router/std",
+ "bp-xcm-bridge-hub/std",
"bridge-runtime-common/std",
"codec/std",
"frame-executive/std",
@@ -117,6 +118,7 @@ std = [
"pallet-transaction-payment/std",
"pallet-utility/std",
"pallet-xcm/std",
+ "pallet-xcm-bridge-hub/std",
"pallet-xcm-bridge-hub-router/std",
"scale-info/std",
"sp-api/std",
@@ -144,6 +146,7 @@ runtime-benchmarks = [
"pallet-bridge-parachains/runtime-benchmarks",
"pallet-bridge-relayers/runtime-benchmarks",
"pallet-xcm/runtime-benchmarks",
+ "pallet-xcm-bridge-hub/runtime-benchmarks",
"pallet-xcm-bridge-hub-router/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
diff --git a/bin/millau/runtime/src/lib.rs b/bin/millau/runtime/src/lib.rs
index 22e4e1b722..b4292e21b1 100644
--- a/bin/millau/runtime/src/lib.rs
+++ b/bin/millau/runtime/src/lib.rs
@@ -55,6 +55,7 @@ use sp_std::prelude::*;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
+use xcm_builder::NetworkExportTable;
// to be able to use Millau runtime in `bridge-runtime-common` tests
pub use bridge_runtime_common;
@@ -442,8 +443,8 @@ impl pallet_bridge_messages::Config for Runtime {
type BridgedChain = bp_rialto::Rialto;
type BridgedHeaderChain = BridgeRialtoGrandpa;
- type OutboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
- type InboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
+ type OutboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
+ type InboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
type DeliveryPayments = ();
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
@@ -451,8 +452,9 @@ impl pallet_bridge_messages::Config for Runtime {
WithRialtoMessagesInstance,
frame_support::traits::ConstU64<100_000>,
>;
+ type OnMessagesDelivered = XcmRialtoBridgeHub;
- type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch;
+ type MessageDispatch = XcmRialtoBridgeHub;
}
/// Instance of the messages pallet used to relay messages to/from RialtoParachain chain.
@@ -470,8 +472,8 @@ impl pallet_bridge_messages::Config for Run
bp_rialto_parachain::RialtoParachain,
>;
- type OutboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
- type InboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
+ type OutboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
+ type InboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
type DeliveryPayments = ();
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
@@ -479,8 +481,9 @@ impl pallet_bridge_messages::Config for Run
WithRialtoParachainMessagesInstance,
frame_support::traits::ConstU64<100_000>,
>;
+ type OnMessagesDelivered = XcmRialtoParachainBridgeHub;
- type MessageDispatch = crate::rialto_parachain_messages::FromRialtoParachainMessageDispatch;
+ type MessageDispatch = XcmRialtoParachainBridgeHub;
}
parameter_types! {
@@ -527,21 +530,75 @@ impl pallet_utility::Config for Runtime {
// this config is totally incorrect - the pallet is not actually used at this runtime. We need
// it only to be able to run benchmarks and make required traits (and default weights for tests).
+
+parameter_types! {
+ pub BridgeTable: Vec<(xcm::prelude::NetworkId, xcm::prelude::MultiLocation, Option)>
+ = vec![(
+ xcm_config::RialtoNetwork::get(),
+ xcm_config::TokenLocation::get(),
+ Some((xcm_config::TokenAssetId::get(), 1_000_000_000_u128).into()),
+ )];
+}
+
impl pallet_xcm_bridge_hub_router::Config for Runtime {
type WeightInfo = ();
type UniversalLocation = xcm_config::UniversalLocation;
type SiblingBridgeHubLocation = xcm_config::TokenLocation;
type BridgedNetworkId = xcm_config::RialtoNetwork;
+ type Bridges = NetworkExportTable;
type ToBridgeHubSender = xcm_config::XcmRouter;
- type WithBridgeHubChannel = xcm_config::EmulatedSiblingXcmpChannel;
+ type LocalXcmChannelManager = xcm_config::EmulatedSiblingXcmpChannel;
- type BaseFee = ConstU128<1_000_000_000>;
type ByteFee = ConstU128<1_000>;
type FeeAsset = xcm_config::TokenAssetId;
}
+/// Instance of the XCM bridge hub pallet used to relay messages to/from Rialto chain.
+pub type WithRialtoXcmBridgeHubInstance = ();
+
+impl pallet_xcm_bridge_hub::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+
+ type UniversalLocation = xcm_config::UniversalLocation;
+ type BridgedNetworkId = xcm_config::RialtoNetwork;
+ type BridgeMessagesPalletInstance = WithRialtoMessagesInstance;
+
+ type MaxSuspendedBridges = ConstU32<1>;
+ type OpenBridgeOrigin = frame_support::traits::NeverEnsureOrigin;
+ type BridgeOriginAccountIdConverter = xcm_config::SovereignAccountOf;
+
+ type BridgeReserve = ConstU64<1_000_000_000>;
+ type NativeCurrency = Balances;
+
+ type LocalXcmChannelManager = ();
+ type BlobDispatcher = xcm_config::OnMillauBlobDispatcher;
+ type MessageExportPrice = ();
+}
+
+/// Instance of the XCM bridge hub pallet used to relay messages to/from RialtoParachain chain.
+pub type WithRialtoParachainXcmBridgeHubInstance = pallet_xcm_bridge_hub::Instance1;
+
+impl pallet_xcm_bridge_hub::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+
+ type UniversalLocation = xcm_config::UniversalLocation;
+ type BridgedNetworkId = xcm_config::RialtoParachainNetwork;
+ type BridgeMessagesPalletInstance = WithRialtoParachainMessagesInstance;
+
+ type MaxSuspendedBridges = ConstU32<1>;
+ type OpenBridgeOrigin = frame_support::traits::NeverEnsureOrigin;
+ type BridgeOriginAccountIdConverter = xcm_config::SovereignAccountOf;
+
+ type BridgeReserve = ConstU64<1_000_000_000>;
+ type NativeCurrency = Balances;
+
+ type LocalXcmChannelManager = ();
+ type BlobDispatcher = xcm_config::OnMillauBlobDispatcher;
+ type MessageExportPrice = ();
+}
+
construct_runtime!(
pub enum Runtime {
System: frame_system::{Pallet, Call, Config, Storage, Event},
@@ -569,6 +626,7 @@ construct_runtime!(
BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event},
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event},
BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config},
+ XcmRialtoBridgeHub: pallet_xcm_bridge_hub::{Pallet, Call, Storage, Event, Config},
// Westend bridge modules.
BridgeWestendGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Config, Storage, Event},
@@ -577,6 +635,7 @@ construct_runtime!(
// RialtoParachain bridge modules.
BridgeRialtoParachains: pallet_bridge_parachains::{Pallet, Call, Storage, Event},
BridgeRialtoParachainMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config},
+ XcmRialtoParachainBridgeHub: pallet_xcm_bridge_hub::::{Pallet, Call, Storage, Event, Config},
// Pallet for sending XCM.
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99,
@@ -602,7 +661,11 @@ pub type PriorityBoostPerMessage = ConstU64<351_343_108>;
pub type BridgeRefundRialtoParachainMessages = RefundBridgedParachainMessages<
Runtime,
RefundableParachain,
- RefundableMessagesLane,
+ RefundableMessagesLane<
+ Runtime,
+ WithRialtoParachainMessagesInstance,
+ rialto_parachain_messages::Lane,
+ >,
ActualFeeRefund,
PriorityBoostPerMessage,
StrBridgeRefundRialtoPara2000Lane0Msgs,
diff --git a/bin/millau/runtime/src/rialto_messages.rs b/bin/millau/runtime/src/rialto_messages.rs
index 7e785703ae..8f18658822 100644
--- a/bin/millau/runtime/src/rialto_messages.rs
+++ b/bin/millau/runtime/src/rialto_messages.rs
@@ -16,53 +16,19 @@
//! Everything required to serve Millau <-> Rialto messages.
-use crate::{Runtime, WithRialtoMessagesInstance};
+use crate::Runtime;
-use bp_messages::LaneId;
-use bridge_runtime_common::messages_xcm_extension::{
- LaneIdFromChainId, XcmBlobHauler, XcmBlobHaulerAdapter,
-};
+use bp_xcm_bridge_hub::BridgeId;
use frame_support::{parameter_types, weights::Weight};
use pallet_bridge_relayers::WeightInfoExt as _;
-use sp_core::Get;
-use xcm_builder::HaulBlobExporter;
-
-/// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
-/// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual
-/// tests, confirming that we don't break encoding somewhere between.
-pub const BASE_XCM_WEIGHT_TWICE: Weight = crate::xcm_config::BaseXcmWeight::get().saturating_mul(2);
+use xcm::prelude::*;
parameter_types! {
- /// Weight credit for our test messages.
- ///
- /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
- /// (it is prepended with `UniversalOrigin` instruction).
- pub const WeightCredit: Weight = BASE_XCM_WEIGHT_TWICE;
-}
-
-/// Call-dispatch based message dispatch for Rialto -> Millau messages.
-pub type FromRialtoMessageDispatch =
- bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
- crate::xcm_config::OnMillauBlobDispatcher,
- (),
- >;
-
-/// Export XCM messages to be relayed to Rialto.
-pub type ToRialtoBlobExporter = HaulBlobExporter<
- XcmBlobHaulerAdapter,
- crate::xcm_config::RialtoNetwork,
- (),
->;
-
-/// To-Rialto XCM hauler.
-pub struct ToRialtoXcmBlobHauler;
-
-impl XcmBlobHauler for ToRialtoXcmBlobHauler {
- type MessageSender = pallet_bridge_messages::Pallet;
-
- fn xcm_lane() -> LaneId {
- LaneIdFromChainId::::get()
- }
+ /// Bridge identifier that is used to bridge with Rialto.
+ pub Bridge: BridgeId = BridgeId::new(
+ &InteriorMultiLocation::from(crate::xcm_config::ThisNetwork::get()).into(),
+ &InteriorMultiLocation::from(crate::xcm_config::RialtoNetwork::get()).into(),
+ );
}
impl pallet_bridge_messages::WeightInfoExt for crate::weights::RialtoMessagesWeightInfo {
@@ -129,8 +95,8 @@ mod tests {
// there's nothing criminal if it is changed, but then thou need to fix it across
// all deployments scripts, alerts and so on
assert_eq!(
- *ToRialtoXcmBlobHauler::xcm_lane().as_ref(),
- hex_literal::hex!("52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7")
+ *Bridge::get().lane_id().as_ref(),
+ hex_literal::hex!("efed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7")
.into(),
);
}
diff --git a/bin/millau/runtime/src/rialto_parachain_messages.rs b/bin/millau/runtime/src/rialto_parachain_messages.rs
index e13c4c203c..0b09067b3c 100644
--- a/bin/millau/runtime/src/rialto_parachain_messages.rs
+++ b/bin/millau/runtime/src/rialto_parachain_messages.rs
@@ -16,54 +16,22 @@
//! Everything required to serve Millau <-> RialtoParachain messages.
-use crate::{Runtime, WithRialtoParachainMessagesInstance};
+use crate::Runtime;
use bp_messages::LaneId;
-use bridge_runtime_common::messages_xcm_extension::{
- LaneIdFromChainId, XcmBlobHauler, XcmBlobHaulerAdapter,
-};
+use bp_xcm_bridge_hub::BridgeId;
use frame_support::{parameter_types, weights::Weight};
use pallet_bridge_relayers::WeightInfoExt as _;
-use sp_core::Get;
-use xcm_builder::HaulBlobExporter;
-
-/// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
-/// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual
-/// tests, confirming that we don't break encoding somewhere between.
-pub const BASE_XCM_WEIGHT_TWICE: Weight = crate::xcm_config::BaseXcmWeight::get().saturating_mul(2);
+use xcm::prelude::*;
parameter_types! {
- /// Weight credit for our test messages.
- ///
- /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
- /// (it is prepended with `UniversalOrigin` instruction).
- pub const WeightCredit: Weight = BASE_XCM_WEIGHT_TWICE;
-}
-
-/// Call-dispatch based message dispatch for RialtoParachain -> Millau messages.
-pub type FromRialtoParachainMessageDispatch =
- bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
- crate::xcm_config::OnMillauBlobDispatcher,
- (),
- >;
-
-/// Export XCM messages to be relayed to Rialto.
-pub type ToRialtoParachainBlobExporter = HaulBlobExporter<
- XcmBlobHaulerAdapter,
- crate::xcm_config::RialtoParachainNetwork,
- (),
->;
-
-/// To-RialtoParachain XCM hauler.
-pub struct ToRialtoParachainXcmBlobHauler;
-
-impl XcmBlobHauler for ToRialtoParachainXcmBlobHauler {
- type MessageSender =
- pallet_bridge_messages::Pallet;
-
- fn xcm_lane() -> LaneId {
- LaneIdFromChainId::::get()
- }
+ /// Bridge identifier that is used to bridge with RialtoParachain.
+ pub Bridge: BridgeId = BridgeId::new(
+ &InteriorMultiLocation::from(crate::xcm_config::ThisNetwork::get()).into(),
+ &InteriorMultiLocation::from(crate::xcm_config::RialtoParachainNetwork::get()).into(),
+ );
+ /// Lane identifier, used by with-RialtoParachain bridge.
+ pub Lane: LaneId = Bridge::get().lane_id();
}
impl pallet_bridge_messages::WeightInfoExt
@@ -142,8 +110,8 @@ mod tests {
// there's nothing criminal if it is changed, but then thou need to fix it across
// all deployments scripts, alerts and so on
assert_eq!(
- *ToRialtoParachainXcmBlobHauler::xcm_lane().as_ref(),
- hex_literal::hex!("6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de")
+ *Bridge::get().lane_id().as_ref(),
+ hex_literal::hex!("ee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c")
.into(),
);
}
diff --git a/bin/millau/runtime/src/xcm_config.rs b/bin/millau/runtime/src/xcm_config.rs
index 33307ab9c8..d1c20d1c48 100644
--- a/bin/millau/runtime/src/xcm_config.rs
+++ b/bin/millau/runtime/src/xcm_config.rs
@@ -17,11 +17,11 @@
//! XCM configurations for the Millau runtime.
use super::{
- rialto_messages::ToRialtoBlobExporter,
- rialto_parachain_messages::ToRialtoParachainBlobExporter, AccountId, AllPalletsWithSystem,
- Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, XcmPallet,
+ AccountId, AllPalletsWithSystem, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
+ XcmPallet,
};
use bp_millau::WeightToFee;
+use bp_xcm_bridge_hub::{BridgeId, BridgeLocations};
use bridge_runtime_common::CustomNetworkId;
use frame_support::{
parameter_types,
@@ -29,11 +29,12 @@ use frame_support::{
weights::Weight,
};
use frame_system::EnsureRoot;
+use sp_std::prelude::*;
use xcm::latest::prelude::*;
use xcm_builder::{
- AccountId32Aliases, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation,
- SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
- UsingComponents,
+ Account32Hash, AccountId32Aliases, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete,
+ MintLocation, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
+ TakeWeightCredit, UsingComponents,
};
use xcm_executor::traits::ExportXcm;
@@ -64,6 +65,8 @@ parameter_types! {
pub type SovereignAccountOf = (
// We can directly alias an `AccountId32` into a local account.
AccountId32Aliases,
+ // Dummy stuff for our tests.
+ Account32Hash,
);
/// Our asset transactor. This is what allows us to interest with the runtime facilities from the
@@ -199,7 +202,7 @@ impl pallet_xcm::Config for Runtime {
pub struct ToRialtoOrRialtoParachainSwitchExporter;
impl ExportXcm for ToRialtoOrRialtoParachainSwitchExporter {
- type Ticket = (NetworkId, (sp_std::prelude::Vec, XcmHash));
+ type Ticket = (NetworkId, (Box, sp_std::prelude::Vec, XcmHash));
fn validate(
network: NetworkId,
@@ -209,10 +212,16 @@ impl ExportXcm for ToRialtoOrRialtoParachainSwitchExporter {
message: &mut Option>,
) -> SendResult {
if network == RialtoNetwork::get() {
- ToRialtoBlobExporter::validate(network, channel, universal_source, destination, message)
- .map(|result| ((RialtoNetwork::get(), result.0), result.1))
+ crate::XcmRialtoBridgeHub::validate(
+ network,
+ channel,
+ universal_source,
+ destination,
+ message,
+ )
+ .map(|result| ((RialtoNetwork::get(), result.0), result.1))
} else if network == RialtoParachainNetwork::get() {
- ToRialtoParachainBlobExporter::validate(
+ crate::XcmRialtoParachainBridgeHub::validate(
network,
channel,
universal_source,
@@ -228,9 +237,9 @@ impl ExportXcm for ToRialtoOrRialtoParachainSwitchExporter {
fn deliver(ticket: Self::Ticket) -> Result {
let (network, ticket) = ticket;
if network == RialtoNetwork::get() {
- ToRialtoBlobExporter::deliver(ticket)
+ crate::XcmRialtoBridgeHub::deliver(ticket)
} else if network == RialtoParachainNetwork::get() {
- ToRialtoParachainBlobExporter::deliver(ticket)
+ crate::XcmRialtoParachainBridgeHub::deliver(ticket)
} else {
Err(SendError::Unroutable)
}
@@ -248,26 +257,33 @@ impl EmulatedSiblingXcmpChannel {
}
}
-impl bp_xcm_bridge_hub_router::LocalXcmChannel for EmulatedSiblingXcmpChannel {
- fn is_congested() -> bool {
+impl bp_xcm_bridge_hub::LocalXcmChannelManager for EmulatedSiblingXcmpChannel {
+ type Error = ();
+
+ fn is_congested(_with: &MultiLocation) -> bool {
frame_support::storage::unhashed::get_or_default(b"EmulatedSiblingXcmpChannel.Congested")
}
+
+ fn suspend_bridge(_with: &MultiLocation, _bridge_id: BridgeId) -> Result<(), Self::Error> {
+ Ok(())
+ }
+
+ fn resume_bridge(_with: &MultiLocation, _bridge_id: BridgeId) -> Result<(), Self::Error> {
+ Ok(())
+ }
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
- rialto_messages::FromRialtoMessageDispatch, WithRialtoMessagesInstance,
- WithRialtoParachainMessagesInstance,
+ WithRialtoMessagesInstance, WithRialtoParachainMessagesInstance, XcmRialtoBridgeHub,
+ XcmRialtoParachainBridgeHub,
};
use bp_messages::{
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
LaneId, MessageKey, OutboundLaneData,
};
- use bridge_runtime_common::messages_xcm_extension::{
- XcmBlobHauler, XcmBlobMessageDispatchResult,
- };
use codec::Encode;
use pallet_bridge_messages::OutboundLanes;
use sp_runtime::BuildStorage;
@@ -292,7 +308,7 @@ mod tests {
fn xcm_messages_to_rialto_are_sent_using_bridge_exporter() {
new_test_ext().execute_with(|| {
// ensure that the there are no messages queued
- let lane_id = crate::rialto_messages::ToRialtoXcmBlobHauler::xcm_lane();
+ let lane_id = crate::rialto_messages::Bridge::get().lane_id();
OutboundLanes::::insert(
lane_id,
OutboundLaneData::opened(),
@@ -329,8 +345,7 @@ mod tests {
fn xcm_messages_to_rialto_parachain_are_sent_using_bridge_exporter() {
new_test_ext().execute_with(|| {
// ensure that the there are no messages queued
- let lane_id =
- crate::rialto_parachain_messages::ToRialtoParachainXcmBlobHauler::xcm_lane();
+ let lane_id = crate::rialto_parachain_messages::Lane::get();
OutboundLanes::::insert(
lane_id,
OutboundLaneData::opened(),
@@ -378,31 +393,29 @@ mod tests {
#[test]
fn xcm_messages_from_rialto_are_dispatched() {
- let incoming_message = prepare_inbound_bridge_message(
- crate::rialto_messages::ToRialtoXcmBlobHauler::xcm_lane(),
- );
+ let incoming_message =
+ prepare_inbound_bridge_message(crate::rialto_messages::Bridge::get().lane_id());
// we care only about handing message to the XCM dispatcher, so we don't care about its
// actual dispatch
- let dispatch_result = FromRialtoMessageDispatch::dispatch(incoming_message);
+ let dispatch_result = XcmRialtoBridgeHub::dispatch(incoming_message);
assert!(matches!(
dispatch_result.dispatch_level_result,
- XcmBlobMessageDispatchResult::NotDispatched(_),
+ pallet_xcm_bridge_hub::XcmBlobMessageDispatchResult::NotDispatched(_),
));
}
#[test]
fn xcm_messages_from_rialto_parachain_are_dispatched() {
- let incoming_message = prepare_inbound_bridge_message(
- crate::rialto_parachain_messages::ToRialtoParachainXcmBlobHauler::xcm_lane(),
- );
+ let incoming_message =
+ prepare_inbound_bridge_message(crate::rialto_parachain_messages::Lane::get());
// we care only about handing message to the XCM dispatcher, so we don't care about its
// actual dispatch
- let dispatch_result = FromRialtoMessageDispatch::dispatch(incoming_message);
+ let dispatch_result = XcmRialtoParachainBridgeHub::dispatch(incoming_message);
assert!(matches!(
dispatch_result.dispatch_level_result,
- XcmBlobMessageDispatchResult::NotDispatched(_),
+ pallet_xcm_bridge_hub::XcmBlobMessageDispatchResult::NotDispatched(_),
));
}
}
diff --git a/bin/rialto-parachain/node/Cargo.toml b/bin/rialto-parachain/node/Cargo.toml
index 4be9ced3d6..5f217b1666 100644
--- a/bin/rialto-parachain/node/Cargo.toml
+++ b/bin/rialto-parachain/node/Cargo.toml
@@ -82,3 +82,4 @@ cumulus-relay-chain-interface = { git = "https://github.com/paritytech/cumulus",
polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" }
diff --git a/bin/rialto-parachain/node/src/chain_spec.rs b/bin/rialto-parachain/node/src/chain_spec.rs
index 2aa7a1c0be..2b0c76ad81 100644
--- a/bin/rialto-parachain/node/src/chain_spec.rs
+++ b/bin/rialto-parachain/node/src/chain_spec.rs
@@ -14,9 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
-use bridge_runtime_common::messages_xcm_extension::XcmBlobHauler;
use cumulus_primitives_core::ParaId;
-use rialto_parachain_runtime::{AccountId, AuraId, BridgeMillauMessagesConfig, Signature};
+use rialto_parachain_runtime::{
+ AccountId, AuraId, BridgeMillauMessagesConfig, Signature, XcmMillauBridgeHubConfig,
+};
use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
use sc_service::ChainType;
use serde::{Deserialize, Serialize};
@@ -197,9 +198,16 @@ fn testnet_genesis(
aura_ext: Default::default(),
bridge_millau_messages: BridgeMillauMessagesConfig {
owner: Some(get_account_id_from_seed::(MILLAU_MESSAGES_PALLET_OWNER)),
- opened_lanes: vec![
- rialto_parachain_runtime::millau_messages::ToMillauXcmBlobHauler::xcm_lane(),
- ],
+ opened_lanes: vec![rialto_parachain_runtime::millau_messages::Bridge::get().lane_id()],
+ ..Default::default()
+ },
+ xcm_millau_bridge_hub: XcmMillauBridgeHubConfig {
+ opened_bridges: vec![(
+ xcm::latest::Junctions::Here.into(),
+ xcm::latest::InteriorMultiLocation::from(
+ rialto_parachain_runtime::MillauNetwork::get(),
+ ),
+ )],
..Default::default()
},
}
diff --git a/bin/rialto-parachain/runtime/Cargo.toml b/bin/rialto-parachain/runtime/Cargo.toml
index 1b87205e9e..0e1fd61b2d 100644
--- a/bin/rialto-parachain/runtime/Cargo.toml
+++ b/bin/rialto-parachain/runtime/Cargo.toml
@@ -22,10 +22,12 @@ bp-millau = { path = "../../../primitives/chain-millau", default-features = fals
bp-relayers = { path = "../../../primitives/relayers", default-features = false }
bp-runtime = { path = "../../../primitives/runtime", default-features = false }
bp-rialto-parachain = { path = "../../../primitives/chain-rialto-parachain", default-features = false }
+bp-xcm-bridge-hub = { path = "../../../primitives/xcm-bridge-hub", default-features = false }
bridge-runtime-common = { path = "../../runtime-common", default-features = false }
pallet-bridge-grandpa = { path = "../../../modules/grandpa", default-features = false }
pallet-bridge-messages = { path = "../../../modules/messages", default-features = false }
pallet-bridge-relayers = { path = "../../../modules/relayers", default-features = false }
+pallet-xcm-bridge-hub = { path = "../../../modules/xcm-bridge-hub", default-features = false }
# Substrate Dependencies
## Substrate Primitive Dependencies
@@ -98,6 +100,7 @@ std = [
"bp-relayers/std",
"bp-runtime/std",
"bp-rialto-parachain/std",
+ "bp-xcm-bridge-hub/std",
"bridge-runtime-common/std",
"codec/std",
"scale-info/std",
@@ -125,6 +128,7 @@ std = [
"pallet-transaction-payment/std",
"pallet-transaction-payment-rpc-runtime-api/std",
"pallet-xcm/std",
+ "pallet-xcm-bridge-hub/std",
"parachain-info/std",
"polkadot-parachain/std",
"cumulus-pallet-aura-ext/std",
diff --git a/bin/rialto-parachain/runtime/src/lib.rs b/bin/rialto-parachain/runtime/src/lib.rs
index 5166ca7ca8..d69dfa7c65 100644
--- a/bin/rialto-parachain/runtime/src/lib.rs
+++ b/bin/rialto-parachain/runtime/src/lib.rs
@@ -34,7 +34,7 @@ use sp_api::impl_runtime_apis;
use sp_core::{crypto::KeyTypeId, ConstBool, OpaqueMetadata};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
- traits::{AccountIdLookup, Block as BlockT, DispatchInfoOf, SignedExtension},
+ traits::{AccountIdLookup, Block as BlockT, ConstU128, DispatchInfoOf, SignedExtension},
transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
ApplyExtrinsicResult,
};
@@ -83,10 +83,10 @@ use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use xcm::latest::prelude::*;
use xcm_builder::{
- AccountId32Aliases, CurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, IsConcrete,
- NativeAsset, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
- SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
- SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
+ Account32Hash, AccountId32Aliases, CurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds,
+ IsConcrete, NativeAsset, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative,
+ SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
+ SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
};
use xcm_executor::{Config, XcmExecutor};
@@ -365,6 +365,8 @@ pub type LocationToAccountId = (
SiblingParachainConvertsVia,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases,
+ // Dummy stuff for our tests.
+ Account32Hash,
);
/// Means for transacting assets on this chain.
@@ -455,7 +457,7 @@ impl Config for XcmConfig {
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
- type MessageExporter = millau_messages::ToMillauBlobExporter;
+ type MessageExporter = XcmMillauBridgeHub;
type UniversalAliases = Nothing;
type CallDispatcher = RuntimeCall;
type SafeCallFilter = Everything;
@@ -565,8 +567,8 @@ impl pallet_bridge_messages::Config for Runtime {
type BridgedChain = bp_millau::Millau;
type BridgedHeaderChain = BridgeMillauGrandpa;
- type OutboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
- type InboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
+ type OutboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
+ type InboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
type DeliveryPayments = ();
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
@@ -574,8 +576,31 @@ impl pallet_bridge_messages::Config for Runtime {
WithMillauMessagesInstance,
frame_support::traits::ConstU128<100_000>,
>;
+ type OnMessagesDelivered = XcmMillauBridgeHub;
- type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch;
+ type MessageDispatch = XcmMillauBridgeHub;
+}
+
+/// Instance of the XCM bridge hub pallet used to relay messages to/from Millau chain.
+pub type WithMillauXcmBridgeHubInstance = ();
+
+impl pallet_xcm_bridge_hub::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+
+ type UniversalLocation = UniversalLocation;
+ type BridgedNetworkId = MillauNetwork;
+ type BridgeMessagesPalletInstance = WithMillauMessagesInstance;
+
+ type MaxSuspendedBridges = ConstU32<1>;
+ type OpenBridgeOrigin = frame_support::traits::NeverEnsureOrigin;
+ type BridgeOriginAccountIdConverter = LocationToAccountId;
+
+ type BridgeReserve = ConstU128<1_000_000_000>;
+ type NativeCurrency = Balances;
+
+ type LocalXcmChannelManager = ();
+ type BlobDispatcher = OnRialtoParachainBlobDispatcher;
+ type MessageExportPrice = ();
}
// Create the runtime by composing the FRAME pallets that were previously configured.
@@ -604,6 +629,7 @@ construct_runtime!(
BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event},
BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event},
BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config},
+ XcmMillauBridgeHub: pallet_xcm_bridge_hub::{Pallet, Call, Storage, Event, Config},
}
);
@@ -840,16 +866,12 @@ cumulus_pallet_parachain_system::register_validate_block!(
#[cfg(test)]
mod tests {
use super::*;
- use crate::millau_messages::FromMillauMessageDispatch;
use bp_messages::{
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
MessageKey, OutboundLaneData,
};
use bp_runtime::Chain;
- use bridge_runtime_common::{
- integrity::check_additional_signed,
- messages_xcm_extension::{XcmBlobHauler, XcmBlobMessageDispatchResult},
- };
+ use bridge_runtime_common::integrity::check_additional_signed;
use codec::Encode;
use pallet_bridge_messages::OutboundLanes;
use sp_runtime::generic::Era;
@@ -882,7 +904,7 @@ mod tests {
fn xcm_messages_to_millau_are_sent_using_bridge_exporter() {
new_test_ext().execute_with(|| {
// ensure that the there are no messages queued
- let lane_id = crate::millau_messages::ToMillauXcmBlobHauler::xcm_lane();
+ let lane_id = crate::millau_messages::Bridge::get().lane_id();
OutboundLanes::::insert(
lane_id,
OutboundLaneData::opened(),
@@ -921,7 +943,7 @@ mod tests {
xcm::VersionedInteriorMultiLocation::V3(X1(GlobalConsensus(ThisNetwork::get())));
// this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor
// or public fields, so just tuple
- let xcm_lane = crate::millau_messages::ToMillauXcmBlobHauler::xcm_lane();
+ let xcm_lane = crate::millau_messages::Bridge::get().lane_id();
let bridge_message = (location, xcm).encode();
DispatchMessage {
key: MessageKey { lane_id: xcm_lane, nonce: 1 },
@@ -936,10 +958,10 @@ mod tests {
// we care only about handing message to the XCM dispatcher, so we don't care about its
// actual dispatch
- let dispatch_result = FromMillauMessageDispatch::dispatch(incoming_message);
+ let dispatch_result = XcmMillauBridgeHub::dispatch(incoming_message);
assert!(matches!(
dispatch_result.dispatch_level_result,
- XcmBlobMessageDispatchResult::NotDispatched(_),
+ pallet_xcm_bridge_hub::XcmBlobMessageDispatchResult::NotDispatched(_),
));
});
}
diff --git a/bin/rialto-parachain/runtime/src/millau_messages.rs b/bin/rialto-parachain/runtime/src/millau_messages.rs
index 2eb7c1b852..cd9bdab5cc 100644
--- a/bin/rialto-parachain/runtime/src/millau_messages.rs
+++ b/bin/rialto-parachain/runtime/src/millau_messages.rs
@@ -16,52 +16,16 @@
//! Everything required to serve Millau <-> RialtoParachain messages.
-// TODO: this is almost exact copy of `millau_messages.rs` from Rialto runtime.
-// Should be extracted to a separate crate and reused here.
-
-use crate::{Runtime, WithMillauMessagesInstance};
-
-use bp_messages::LaneId;
-use bridge_runtime_common::messages_xcm_extension::{
- LaneIdFromChainId, XcmBlobHauler, XcmBlobHaulerAdapter,
-};
-use frame_support::{parameter_types, weights::Weight};
-use sp_core::Get;
-use xcm_builder::HaulBlobExporter;
-
-/// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
-/// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual
-/// tests, confirming that we don't break encoding somewhere between.
-pub const BASE_XCM_WEIGHT_TWICE: Weight = crate::UnitWeightCost::get().saturating_mul(2);
+use bp_xcm_bridge_hub::BridgeId;
+use frame_support::parameter_types;
+use xcm::prelude::*;
parameter_types! {
- /// Weight credit for our test messages.
- ///
- /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
- /// (it is prepended with `UniversalOrigin` instruction).
- pub const WeightCredit: Weight = BASE_XCM_WEIGHT_TWICE;
-}
-
-/// Call-dispatch based message dispatch for Millau -> RialtoParachain messages.
-pub type FromMillauMessageDispatch =
- bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
- crate::OnRialtoParachainBlobDispatcher,
- (),
- >;
-
-/// Export XCM messages to be relayed to Millau.
-pub type ToMillauBlobExporter =
- HaulBlobExporter, crate::MillauNetwork, ()>;
-
-/// To-Millau XCM hauler.
-pub struct ToMillauXcmBlobHauler;
-
-impl XcmBlobHauler for ToMillauXcmBlobHauler {
- type MessageSender = pallet_bridge_messages::Pallet;
-
- fn xcm_lane() -> LaneId {
- LaneIdFromChainId::::get()
- }
+ /// Bridge identifier that is used to bridge with Millau.
+ pub Bridge: BridgeId = BridgeId::new(
+ &InteriorMultiLocation::from(crate::ThisNetwork::get()).into(),
+ &InteriorMultiLocation::from(crate::MillauNetwork::get()).into(),
+ );
}
#[cfg(test)]
@@ -117,8 +81,8 @@ mod tests {
// there's nothing criminal if it is changed, but then thou need to fix it across
// all deployments scripts, alerts and so on
assert_eq!(
- *ToMillauXcmBlobHauler::xcm_lane().as_ref(),
- hex_literal::hex!("6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de")
+ *Bridge::get().lane_id().as_ref(),
+ hex_literal::hex!("ee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c")
.into(),
);
}
diff --git a/bin/rialto/node/Cargo.toml b/bin/rialto/node/Cargo.toml
index 5e158a7f6b..5d3d707666 100644
--- a/bin/rialto/node/Cargo.toml
+++ b/bin/rialto/node/Cargo.toml
@@ -35,10 +35,12 @@ sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
# Polkadot Dependencies
+
polkadot-node-core-pvf = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false, features = [ "full-node", "polkadot-native" ] }
+xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" }
[build-dependencies]
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
diff --git a/bin/rialto/node/src/chain_spec.rs b/bin/rialto/node/src/chain_spec.rs
index 83a9fa2ce2..c2ea60f7ef 100644
--- a/bin/rialto/node/src/chain_spec.rs
+++ b/bin/rialto/node/src/chain_spec.rs
@@ -14,12 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
-use bridge_runtime_common::messages_xcm_extension::XcmBlobHauler;
use polkadot_primitives::v5::{AssignmentId, ValidatorId};
use rialto_runtime::{
AccountId, BabeConfig, BalancesConfig, BeefyConfig, BridgeMillauMessagesConfig,
ConfigurationConfig, GrandpaConfig, RuntimeGenesisConfig, SessionConfig, SessionKeys,
- Signature, SudoConfig, SystemConfig, WASM_BINARY,
+ Signature, SudoConfig, SystemConfig, XcmMillauBridgeHubConfig, WASM_BINARY,
};
use serde_json::json;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
@@ -280,9 +279,18 @@ fn testnet_genesis(
paras: Default::default(),
bridge_millau_messages: BridgeMillauMessagesConfig {
owner: Some(get_account_id_from_seed::(MILLAU_MESSAGES_PALLET_OWNER)),
- opened_lanes: vec![rialto_runtime::millau_messages::ToMillauXcmBlobHauler::xcm_lane()],
+ opened_lanes: vec![rialto_runtime::millau_messages::Bridge::get().lane_id()],
..Default::default()
},
xcm_pallet: Default::default(),
+ xcm_millau_bridge_hub: XcmMillauBridgeHubConfig {
+ opened_bridges: vec![(
+ xcm::latest::Junctions::Here.into(),
+ xcm::latest::InteriorMultiLocation::from(
+ rialto_runtime::xcm_config::MillauNetwork::get(),
+ ),
+ )],
+ ..Default::default()
+ },
}
}
diff --git a/bin/rialto/runtime/Cargo.toml b/bin/rialto/runtime/Cargo.toml
index 0f7c4c0f78..89479740e5 100644
--- a/bin/rialto/runtime/Cargo.toml
+++ b/bin/rialto/runtime/Cargo.toml
@@ -18,12 +18,14 @@ bp-millau = { path = "../../../primitives/chain-millau", default-features = fals
bp-relayers = { path = "../../../primitives/relayers", default-features = false }
bp-rialto = { path = "../../../primitives/chain-rialto", default-features = false }
bp-runtime = { path = "../../../primitives/runtime", default-features = false }
+bp-xcm-bridge-hub = { path = "../../../primitives/xcm-bridge-hub", default-features = false }
bridge-runtime-common = { path = "../../runtime-common", default-features = false }
pallet-bridge-beefy = { path = "../../../modules/beefy", default-features = false }
pallet-bridge-grandpa = { path = "../../../modules/grandpa", default-features = false }
pallet-bridge-messages = { path = "../../../modules/messages", default-features = false }
pallet-bridge-relayers = { path = "../../../modules/relayers", default-features = false }
pallet-shift-session-manager = { path = "../../../modules/shift-session-manager", default-features = false }
+pallet-xcm-bridge-hub = { path = "../../../modules/xcm-bridge-hub", default-features = false }
# Substrate Dependencies
@@ -87,6 +89,7 @@ std = [
"bp-relayers/std",
"bp-rialto/std",
"bp-runtime/std",
+ "bp-xcm-bridge-hub/std",
"bridge-runtime-common/std",
"codec/std",
"frame-benchmarking/std",
@@ -113,6 +116,7 @@ std = [
"pallet-timestamp/std",
"pallet-transaction-payment-rpc-runtime-api/std",
"pallet-transaction-payment/std",
+ "pallet-xcm-bridge-hub/std",
"polkadot-primitives/std",
"polkadot-runtime-common/std",
"polkadot-runtime-parachains/std",
diff --git a/bin/rialto/runtime/src/lib.rs b/bin/rialto/runtime/src/lib.rs
index 90887e37d0..caf46fef46 100644
--- a/bin/rialto/runtime/src/lib.rs
+++ b/bin/rialto/runtime/src/lib.rs
@@ -43,7 +43,7 @@ use sp_consensus_beefy::{crypto::AuthorityId as BeefyId, mmr::MmrLeafVersion, Va
use sp_core::OpaqueMetadata;
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
- traits::{AccountIdLookup, Block as BlockT, Keccak256, NumberFor, OpaqueKeys},
+ traits::{AccountIdLookup, Block as BlockT, ConstU128, Keccak256, NumberFor, OpaqueKeys},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult, FixedPointNumber, Perquintill,
};
@@ -423,8 +423,8 @@ impl pallet_bridge_messages::Config for Runtime {
type BridgedChain = bp_millau::Millau;
type BridgedHeaderChain = BridgeMillauGrandpa;
- type OutboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
- type InboundPayload = bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload;
+ type OutboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
+ type InboundPayload = bp_xcm_bridge_hub::XcmAsPlainPayload;
type DeliveryPayments = ();
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
@@ -432,8 +432,9 @@ impl pallet_bridge_messages::Config for Runtime {
WithMillauMessagesInstance,
frame_support::traits::ConstU128<100_000>,
>;
+ type OnMessagesDelivered = XcmMillauBridgeHub;
- type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch;
+ type MessageDispatch = XcmMillauBridgeHub;
}
pub type MillauBeefyInstance = ();
@@ -443,6 +444,28 @@ impl pallet_bridge_beefy::Config for Runtime {
type BridgedChain = bp_millau::Millau;
}
+/// Instance of the XCM bridge hub pallet used to relay messages to/from Millau chain.
+pub type WithMillauXcmBridgeHubInstance = ();
+
+impl pallet_xcm_bridge_hub::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+
+ type UniversalLocation = xcm_config::UniversalLocation;
+ type BridgedNetworkId = xcm_config::MillauNetwork;
+ type BridgeMessagesPalletInstance = WithMillauMessagesInstance;
+
+ type MaxSuspendedBridges = ConstU32<1>;
+ type OpenBridgeOrigin = frame_support::traits::NeverEnsureOrigin;
+ type BridgeOriginAccountIdConverter = xcm_config::SovereignAccountOf;
+
+ type BridgeReserve = ConstU128<1_000_000_000>;
+ type NativeCurrency = Balances;
+
+ type LocalXcmChannelManager = ();
+ type BlobDispatcher = xcm_config::OnRialtoBlobDispatcher;
+ type MessageExportPrice = ();
+}
+
construct_runtime!(
pub enum Runtime {
System: frame_system::{Pallet, Call, Config, Storage, Event},
@@ -470,6 +493,7 @@ construct_runtime!(
BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event},
BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event},
BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config},
+ XcmMillauBridgeHub: pallet_xcm_bridge_hub::{Pallet, Call, Storage, Event, Config},
// Millau bridge modules (BEEFY based).
BridgeMillauBeefy: pallet_bridge_beefy::{Pallet, Call, Storage},
diff --git a/bin/rialto/runtime/src/millau_messages.rs b/bin/rialto/runtime/src/millau_messages.rs
index b8f6fadcad..a1c3164d68 100644
--- a/bin/rialto/runtime/src/millau_messages.rs
+++ b/bin/rialto/runtime/src/millau_messages.rs
@@ -16,52 +16,16 @@
//! Everything required to serve Millau <-> Rialto messages.
-use crate::{Runtime, WithMillauMessagesInstance};
-
-use bp_messages::LaneId;
-use bridge_runtime_common::messages_xcm_extension::{
- LaneIdFromChainId, XcmBlobHauler, XcmBlobHaulerAdapter,
-};
-use frame_support::{parameter_types, weights::Weight};
-use sp_core::Get;
-use xcm_builder::HaulBlobExporter;
-
-/// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
-/// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual
-/// tests, confirming that we don't break encoding somewhere between.
-pub const BASE_XCM_WEIGHT_TWICE: Weight = crate::xcm_config::BaseXcmWeight::get().saturating_mul(2);
+use bp_xcm_bridge_hub::BridgeId;
+use frame_support::parameter_types;
+use xcm::prelude::*;
parameter_types! {
- /// Weight credit for our test messages.
- ///
- /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
- /// (it is prepended with `UniversalOrigin` instruction).
- pub const WeightCredit: Weight = BASE_XCM_WEIGHT_TWICE;
-}
-
-/// Call-dispatch based message dispatch for Millau -> Rialto messages.
-pub type FromMillauMessageDispatch =
- bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
- crate::xcm_config::OnRialtoBlobDispatcher,
- (),
- >;
-
-/// Export XCM messages to be relayed to Millau.
-pub type ToMillauBlobExporter = HaulBlobExporter<
- XcmBlobHaulerAdapter,
- crate::xcm_config::MillauNetwork,
- (),
->;
-
-/// To-Millau XCM hauler.
-pub struct ToMillauXcmBlobHauler;
-
-impl XcmBlobHauler for ToMillauXcmBlobHauler {
- type MessageSender = pallet_bridge_messages::Pallet;
-
- fn xcm_lane() -> LaneId {
- LaneIdFromChainId::::get()
- }
+ /// Bridge identifier that is used to bridge with Millau.
+ pub Bridge: BridgeId = BridgeId::new(
+ &InteriorMultiLocation::from(crate::xcm_config::ThisNetwork::get()).into(),
+ &InteriorMultiLocation::from(crate::xcm_config::MillauNetwork::get()).into(),
+ );
}
#[cfg(test)]
@@ -113,8 +77,8 @@ mod tests {
// there's nothing criminal if it is changed, but then thou need to fix it across
// all deployments scripts, alerts and so on
assert_eq!(
- *ToMillauXcmBlobHauler::xcm_lane().as_ref(),
- hex_literal::hex!("52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7")
+ *Bridge::get().lane_id().as_ref(),
+ hex_literal::hex!("efed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7")
.into(),
);
}
diff --git a/bin/rialto/runtime/src/xcm_config.rs b/bin/rialto/runtime/src/xcm_config.rs
index 12d8c11a3e..f846a2fddb 100644
--- a/bin/rialto/runtime/src/xcm_config.rs
+++ b/bin/rialto/runtime/src/xcm_config.rs
@@ -17,8 +17,8 @@
//! XCM configurations for the Rialto runtime.
use super::{
- millau_messages::ToMillauBlobExporter, AccountId, AllPalletsWithSystem, Balances, Runtime,
- RuntimeCall, RuntimeEvent, RuntimeOrigin, XcmPallet,
+ AccountId, AllPalletsWithSystem, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
+ XcmPallet,
};
use bp_rialto::WeightToFee;
use bridge_runtime_common::CustomNetworkId;
@@ -30,9 +30,9 @@ use frame_support::{
use frame_system::EnsureRoot;
use xcm::latest::prelude::*;
use xcm_builder::{
- AccountId32Aliases, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation,
- SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
- UsingComponents,
+ Account32Hash, AccountId32Aliases, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete,
+ MintLocation, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
+ TakeWeightCredit, UsingComponents,
};
parameter_types! {
@@ -58,6 +58,8 @@ parameter_types! {
pub type SovereignAccountOf = (
// We can directly alias an `AccountId32` into a local account.
AccountId32Aliases,
+ // Dummy stuff for our tests.
+ Account32Hash,
);
/// Our asset transactor. This is what allows us to interest with the runtime facilities from the
@@ -134,7 +136,7 @@ impl xcm_executor::Config for XcmConfig {
type PalletInstancesInfo = AllPalletsWithSystem;
type MaxAssetsIntoHolding = ConstU32<64>;
type FeeManager = ();
- type MessageExporter = ToMillauBlobExporter;
+ type MessageExporter = crate::XcmMillauBridgeHub;
type UniversalAliases = Nothing;
type CallDispatcher = RuntimeCall;
type SafeCallFilter = Everything;
@@ -193,14 +195,11 @@ impl pallet_xcm::Config for Runtime {
#[cfg(test)]
mod tests {
use super::*;
- use crate::{millau_messages::FromMillauMessageDispatch, WithMillauMessagesInstance};
+ use crate::{WithMillauMessagesInstance, XcmMillauBridgeHub};
use bp_messages::{
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
MessageKey, OutboundLaneData,
};
- use bridge_runtime_common::messages_xcm_extension::{
- XcmBlobHauler, XcmBlobMessageDispatchResult,
- };
use codec::Encode;
use pallet_bridge_messages::OutboundLanes;
use sp_runtime::BuildStorage;
@@ -225,7 +224,7 @@ mod tests {
fn xcm_messages_to_millau_are_sent_using_bridge_exporter() {
new_test_ext().execute_with(|| {
// ensure that the there are no messages queued
- let lane_id = crate::millau_messages::ToMillauXcmBlobHauler::xcm_lane();
+ let lane_id = crate::millau_messages::Bridge::get().lane_id();
OutboundLanes::::insert(
lane_id,
OutboundLaneData::opened(),
@@ -265,7 +264,7 @@ mod tests {
// this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor
// or public fields, so just tuple
let bridge_message = (location, xcm).encode();
- let lane_id = crate::millau_messages::ToMillauXcmBlobHauler::xcm_lane();
+ let lane_id = crate::millau_messages::Bridge::get().lane_id();
DispatchMessage {
key: MessageKey { lane_id, nonce: 1 },
data: DispatchMessageData { payload: Ok(bridge_message) },
@@ -278,10 +277,10 @@ mod tests {
// we care only about handing message to the XCM dispatcher, so we don't care about its
// actual dispatch
- let dispatch_result = FromMillauMessageDispatch::dispatch(incoming_message);
+ let dispatch_result = XcmMillauBridgeHub::dispatch(incoming_message);
assert!(matches!(
dispatch_result.dispatch_level_result,
- XcmBlobMessageDispatchResult::NotDispatched(_),
+ pallet_xcm_bridge_hub::XcmBlobMessageDispatchResult::NotDispatched(_),
));
}
}
diff --git a/bin/runtime-common/Cargo.toml b/bin/runtime-common/Cargo.toml
index e1bb263e81..50df84f0db 100644
--- a/bin/runtime-common/Cargo.toml
+++ b/bin/runtime-common/Cargo.toml
@@ -21,6 +21,7 @@ bp-parachains = { path = "../../primitives/parachains", default-features = false
bp-polkadot-core = { path = "../../primitives/polkadot-core", default-features = false }
bp-relayers = { path = "../../primitives/relayers", default-features = false }
bp-runtime = { path = "../../primitives/runtime", default-features = false }
+bp-xcm-bridge-hub = { path = "../../primitives/xcm-bridge-hub", default-features = false }
pallet-bridge-grandpa = { path = "../../modules/grandpa", default-features = false }
pallet-bridge-messages = { path = "../../modules/messages", default-features = false }
pallet-bridge-parachains = { path = "../../modules/parachains", default-features = false }
@@ -56,6 +57,7 @@ std = [
"bp-parachains/std",
"bp-polkadot-core/std",
"bp-runtime/std",
+ "bp-xcm-bridge-hub/std",
"codec/std",
"frame-support/std",
"frame-system/std",
diff --git a/bin/runtime-common/src/integrity.rs b/bin/runtime-common/src/integrity.rs
index 739bc9153f..aaf0810ca4 100644
--- a/bin/runtime-common/src/integrity.rs
+++ b/bin/runtime-common/src/integrity.rs
@@ -64,9 +64,9 @@ macro_rules! assert_bridge_messages_pallet_types(
// if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard
// configuration is used), or something has broke existing configuration (meaning that all bridged chains
// and relays will stop functioning)
- use $crate::messages_xcm_extension::XcmAsPlainPayload;
use bp_messages::ChainWithMessages;
use bp_runtime::Chain;
+ use bp_xcm_bridge_hub::XcmAsPlainPayload;
use pallet_bridge_messages::Config as MessagesConfig;
use static_assertions::assert_type_eq_all;
diff --git a/bin/runtime-common/src/lib.rs b/bin/runtime-common/src/lib.rs
index 459466264e..9a1df7fd31 100644
--- a/bin/runtime-common/src/lib.rs
+++ b/bin/runtime-common/src/lib.rs
@@ -28,7 +28,6 @@ use xcm::v3::NetworkId;
pub mod messages_api;
pub mod messages_benchmarking;
pub mod messages_call_ext;
-pub mod messages_xcm_extension;
pub mod parachains_benchmarking;
pub mod priority_calculator;
pub mod refund_relayer_extension;
@@ -38,8 +37,6 @@ mod mock;
#[cfg(feature = "integrity-test")]
pub mod integrity;
-const LOG_TARGET_BRIDGE_DISPATCH: &str = "runtime::bridge-dispatch";
-
/// A duplication of the `FilterCall` trait.
///
/// We need this trait in order to be able to implement it for the messages pallet,
diff --git a/bin/runtime-common/src/messages_call_ext.rs b/bin/runtime-common/src/messages_call_ext.rs
index daf51e0a33..926aa9fb52 100644
--- a/bin/runtime-common/src/messages_call_ext.rs
+++ b/bin/runtime-common/src/messages_call_ext.rs
@@ -17,7 +17,9 @@
//! Signed extension for the `pallet-bridge-messages` that is able to reject obsolete
//! (and some other invalid) transactions.
-use bp_messages::{ChainWithMessages, InboundLaneData, LaneId, MessageNonce};
+use bp_messages::{
+ target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneId, MessageNonce,
+};
use bp_runtime::AccountIdOf;
use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug};
use pallet_bridge_messages::{BridgedChainOf, Config, Pallet};
@@ -74,7 +76,12 @@ impl ReceiveMessagesProofInfo {
///
/// - or there are no bundled messages, but the inbound lane is blocked by too many unconfirmed
/// messages and/or unrewarded relayers.
- fn is_obsolete(&self) -> bool {
+ fn is_obsolete(&self, is_dispatcher_active: bool) -> bool {
+ // if dispatcher is inactive, we don't accept any delivery transactions
+ if !is_dispatcher_active {
+ return true
+ }
+
// transactions with zero bundled nonces are not allowed, unless they're message
// delivery transactions, which brings reward confirmations required to unblock
// the lane
@@ -271,7 +278,10 @@ impl<
fn check_obsolete_call(&self) -> TransactionValidity {
match self.call_info() {
- Some(CallInfo::ReceiveMessagesProof(proof_info)) if proof_info.is_obsolete() => {
+ Some(CallInfo::ReceiveMessagesProof(proof_info))
+ if proof_info
+ .is_obsolete(T::MessageDispatch::is_active(proof_info.base.lane_id)) =>
+ {
log::trace!(
target: pallet_bridge_messages::LOG_TARGET,
"Rejecting obsolete messages delivery transaction: {:?}",
@@ -320,7 +330,7 @@ mod tests {
use super::*;
use crate::{
messages_call_ext::MessagesCallSubType,
- mock::{BridgedUnderlyingChain, TestRuntime, ThisChainRuntimeCall},
+ mock::{BridgedUnderlyingChain, DummyMessageDispatch, TestRuntime, ThisChainRuntimeCall},
};
use bp_messages::{
source_chain::FromBridgedChainMessagesDeliveryProof,
@@ -452,6 +462,18 @@ mod tests {
});
}
+ #[test]
+ fn extension_reject_call_when_dispatcher_is_inactive() {
+ run_test(|| {
+ // when current best delivered is message#10 and we're trying to deliver message 11..=15
+ // => tx is accepted
+ deliver_message_10();
+
+ DummyMessageDispatch::deactivate(test_lane_id());
+ assert!(!validate_message_delivery(11, 15));
+ });
+ }
+
#[test]
fn extension_rejects_empty_delivery_with_rewards_confirmations_if_there_are_free_relayer_and_message_slots(
) {
diff --git a/bin/runtime-common/src/messages_xcm_extension.rs b/bin/runtime-common/src/messages_xcm_extension.rs
deleted file mode 100644
index 6b412747f6..0000000000
--- a/bin/runtime-common/src/messages_xcm_extension.rs
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2023 Parity Technologies (UK) Ltd.
-// This file is part of Parity Bridges Common.
-
-// Parity Bridges Common is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Parity Bridges Common is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Parity Bridges Common. If not, see .
-
-//! Module provides utilities for easier XCM handling, e.g:
-//! `XcmExecutor` -> `MessageSender` -> `OutboundMessageQueue`
-//! |
-//! `Relayer`
-//! |
-//! `XcmRouter` <- `MessageDispatch` <- `InboundMessageQueue`
-
-use bp_messages::{
- source_chain::MessagesBridge,
- target_chain::{DispatchMessage, MessageDispatch},
- LaneId,
-};
-use bp_runtime::{messages::MessageDispatchResult, Chain};
-use codec::{Decode, Encode};
-use frame_support::{dispatch::Weight, CloneNoBound, EqNoBound, PartialEqNoBound};
-use pallet_bridge_messages::WeightInfoExt as MessagesPalletWeights;
-use scale_info::TypeInfo;
-use sp_core::Get;
-use sp_runtime::SaturatedConversion;
-use sp_std::marker::PhantomData;
-use xcm_builder::{DispatchBlob, DispatchBlobError, HaulBlob, HaulBlobError};
-
-/// Plain "XCM" payload, which we transfer through bridge
-pub type XcmAsPlainPayload = sp_std::prelude::Vec;
-
-/// Make LaneId from chain identifiers of two bridge endpoints.
-// TODO: https://github.com/paritytech/parity-bridges-common/issues/1666: this function
-// is a temporary solution, because `ChainId` and will be removed soon.
-pub struct LaneIdFromChainId(PhantomData<(R, I)>);
-
-impl Get for LaneIdFromChainId
-where
- R: pallet_bridge_messages::Config,
- I: 'static,
-{
- fn get() -> LaneId {
- LaneId::new(
- pallet_bridge_messages::ThisChainOf::::ID,
- pallet_bridge_messages::BridgedChainOf::::ID,
- )
- }
-}
-
-/// Message dispatch result type for single message.
-#[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)]
-pub enum XcmBlobMessageDispatchResult {
- /// We've been unable to decode message payload.
- InvalidPayload,
- /// Message has been dispatched.
- Dispatched,
- /// Message has **NOT** been dispatched because of given error.
- NotDispatched(#[codec(skip)] Option),
-}
-
-/// [`XcmBlobMessageDispatch`] is responsible for dispatching received messages
-pub struct XcmBlobMessageDispatch {
- _marker: sp_std::marker::PhantomData<(DispatchBlob, Weights)>,
-}
-
-impl MessageDispatch
- for XcmBlobMessageDispatch
-{
- type DispatchPayload = XcmAsPlainPayload;
- type DispatchLevelResult = XcmBlobMessageDispatchResult;
-
- fn dispatch_weight(message: &mut DispatchMessage) -> Weight {
- match message.data.payload {
- Ok(ref payload) => {
- let payload_size = payload.encoded_size().saturated_into();
- Weights::message_dispatch_weight(payload_size)
- },
- Err(_) => Weight::zero(),
- }
- }
-
- fn dispatch(
- message: DispatchMessage,
- ) -> MessageDispatchResult {
- let payload = match message.data.payload {
- Ok(payload) => payload,
- Err(e) => {
- log::error!(
- target: crate::LOG_TARGET_BRIDGE_DISPATCH,
- "[XcmBlobMessageDispatch] payload error: {:?} - message_nonce: {:?}",
- e,
- message.key.nonce
- );
- return MessageDispatchResult {
- unspent_weight: Weight::zero(),
- dispatch_level_result: XcmBlobMessageDispatchResult::InvalidPayload,
- }
- },
- };
- let dispatch_level_result = match BlobDispatcher::dispatch_blob(payload) {
- Ok(_) => {
- log::debug!(
- target: crate::LOG_TARGET_BRIDGE_DISPATCH,
- "[XcmBlobMessageDispatch] DispatchBlob::dispatch_blob was ok - message_nonce: {:?}",
- message.key.nonce
- );
- XcmBlobMessageDispatchResult::Dispatched
- },
- Err(e) => {
- log::error!(
- target: crate::LOG_TARGET_BRIDGE_DISPATCH,
- "[XcmBlobMessageDispatch] DispatchBlob::dispatch_blob failed, error: {:?} - message_nonce: {:?}",
- e, message.key.nonce
- );
- XcmBlobMessageDispatchResult::NotDispatched(Some(e))
- },
- };
- MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result }
- }
-}
-
-/// [`XcmBlobHauler`] is responsible for sending messages to the bridge "point-to-point link" from
-/// one side, where on the other it can be dispatched by [`XcmBlobMessageDispatch`].
-pub trait XcmBlobHauler {
- /// Runtime message sender adapter.
- type MessageSender: MessagesBridge;
-
- /// Return message lane (as "point-to-point link") used to deliver XCM messages.
- fn xcm_lane() -> LaneId;
-}
-
-/// XCM bridge adapter which connects [`XcmBlobHauler`] with [`XcmBlobHauler::MessageSender`] and
-/// makes sure that XCM blob is sent to the [`pallet_bridge_messages`] queue to be relayed.
-pub struct XcmBlobHaulerAdapter(sp_std::marker::PhantomData);
-impl HaulBlob for XcmBlobHaulerAdapter {
- fn haul_blob(blob: sp_std::prelude::Vec) -> Result<(), HaulBlobError> {
- let lane = H::xcm_lane();
- H::MessageSender::send_message(lane, blob)
- .map(|artifacts| (lane, artifacts.nonce).using_encoded(sp_io::hashing::blake2_256))
- .map(|result| {
- log::info!(
- target: crate::LOG_TARGET_BRIDGE_DISPATCH,
- "haul_blob result - ok: {:?} on lane: {:?}",
- result,
- lane
- )
- })
- .map_err(|error| {
- log::error!(
- target: crate::LOG_TARGET_BRIDGE_DISPATCH,
- "haul_blob result - error: {:?} on lane: {:?}",
- error,
- lane
- );
- HaulBlobError::Transport("MessageSenderError")
- })
- }
-}
diff --git a/bin/runtime-common/src/mock.rs b/bin/runtime-common/src/mock.rs
index ad59483196..194f469b56 100644
--- a/bin/runtime-common/src/mock.rs
+++ b/bin/runtime-common/src/mock.rs
@@ -23,20 +23,21 @@
#![cfg(test)]
-use crate::messages_xcm_extension::XcmAsPlainPayload;
-
use bp_header_chain::ChainWithGrandpa;
-use bp_messages::{target_chain::ForbidInboundMessages, ChainWithMessages, LaneId, MessageNonce};
+use bp_messages::{
+ target_chain::{DispatchMessage, MessageDispatch},
+ ChainWithMessages, LaneId, MessageNonce,
+};
use bp_parachains::SingleParaStoredHeaderDataBuilder;
use bp_relayers::PayRewardFromAccount;
-use bp_runtime::{Chain, ChainId, Parachain};
+use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Parachain};
+use codec::Encode;
use frame_support::{
parameter_types,
weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight},
StateVersion,
};
use pallet_transaction_payment::Multiplier;
-use sp_core::Get;
use sp_runtime::{
testing::H256,
traits::{BlakeTwo256, ConstU32, ConstU64, ConstU8, IdentityLookup},
@@ -90,7 +91,7 @@ pub type TestStakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed<
/// Message lane used in tests.
pub fn test_lane_id() -> LaneId {
- crate::messages_xcm_extension::LaneIdFromChainId::::get()
+ LaneId::new(1, 2)
}
/// Bridged chain id used in tests.
@@ -217,7 +218,7 @@ impl pallet_bridge_messages::Config for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = pallet_bridge_messages::weights::BridgeWeight;
- type OutboundPayload = XcmAsPlainPayload;
+ type OutboundPayload = Vec;
type InboundPayload = Vec;
type DeliveryPayments = ();
@@ -227,8 +228,9 @@ impl pallet_bridge_messages::Config for TestRuntime {
(),
ConstU64<100_000>,
>;
+ type OnMessagesDelivered = ();
- type MessageDispatch = ForbidInboundMessages>;
+ type MessageDispatch = DummyMessageDispatch;
type ThisChain = ThisUnderlyingChain;
type BridgedChain = BridgedUnderlyingChain;
type BridgedHeaderChain = BridgeGrandpa;
@@ -242,6 +244,35 @@ impl pallet_bridge_relayers::Config for TestRuntime {
type WeightInfo = ();
}
+/// Dummy message dispatcher.
+pub struct DummyMessageDispatch;
+
+impl DummyMessageDispatch {
+ pub fn deactivate(lane: LaneId) {
+ frame_support::storage::unhashed::put(&(b"inactive", lane).encode()[..], &false);
+ }
+}
+
+impl MessageDispatch for DummyMessageDispatch {
+ type DispatchPayload = Vec;
+ type DispatchLevelResult = ();
+
+ fn is_active(lane: LaneId) -> bool {
+ frame_support::storage::unhashed::take::(&(b"inactive", lane).encode()[..]) !=
+ Some(false)
+ }
+
+ fn dispatch_weight(_message: &mut DispatchMessage) -> Weight {
+ Weight::zero()
+ }
+
+ fn dispatch(
+ _: DispatchMessage,
+ ) -> MessageDispatchResult {
+ MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result: () }
+ }
+}
+
/// Underlying chain of `ThisChain`.
pub struct ThisUnderlyingChain;
diff --git a/bin/runtime-common/src/refund_relayer_extension.rs b/bin/runtime-common/src/refund_relayer_extension.rs
index 0e932ffb5f..0fca846a84 100644
--- a/bin/runtime-common/src/refund_relayer_extension.rs
+++ b/bin/runtime-common/src/refund_relayer_extension.rs
@@ -19,11 +19,8 @@
//! with calls that are: delivering new messsage and all necessary underlying headers
//! (parachain or relay chain).
-use crate::{
- messages_call_ext::{
- CallHelper as MessagesCallHelper, CallInfo as MessagesCallInfo, MessagesCallSubType,
- },
- messages_xcm_extension::LaneIdFromChainId,
+use crate::messages_call_ext::{
+ CallHelper as MessagesCallHelper, CallInfo as MessagesCallInfo, MessagesCallSubType,
};
use bp_messages::{ChainWithMessages, LaneId, MessageNonce};
use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
@@ -105,15 +102,17 @@ pub trait RefundableMessagesLaneId {
}
/// Default implementation of `RefundableMessagesLaneId`.
-pub struct RefundableMessagesLane(PhantomData<(Runtime, Instance)>);
+pub struct RefundableMessagesLane(PhantomData<(Runtime, Instance, Lane)>);
-impl RefundableMessagesLaneId for RefundableMessagesLane
+impl RefundableMessagesLaneId
+ for RefundableMessagesLane
where
Runtime: MessagesConfig,
Instance: 'static,
+ Lane: Get,
{
type Instance = Instance;
- type Id = LaneIdFromChainId;
+ type Id = Lane;
}
/// Refund calculator.
@@ -693,13 +692,14 @@ mod tests {
TEST_BRIDGED_CHAIN_ID,
RewardsAccountOwner::BridgedChain,
);
+ pub TestLaneId: LaneId = test_lane_id();
}
bp_runtime::generate_static_str_provider!(TestExtension);
type TestExtension = RefundBridgedParachainMessages<
TestRuntime,
DefaultRefundableParachainId<(), TestParachain>,
- RefundableMessagesLane,
+ RefundableMessagesLane,
ActualFeeRefund,
ConstU64<1>,
StrTestExtension,
diff --git a/deployments/bridges/rialto-millau/dashboard/grafana/relay-millau-to-rialto-messages-dashboard.json b/deployments/bridges/rialto-millau/dashboard/grafana/relay-millau-to-rialto-messages-dashboard.json
index d3c59e9886..44ec8454b3 100644
--- a/deployments/bridges/rialto-millau/dashboard/grafana/relay-millau-to-rialto-messages-dashboard.json
+++ b/deployments/bridges/rialto-millau/dashboard/grafana/relay-millau-to-rialto-messages-dashboard.json
@@ -63,14 +63,14 @@
"steppedLine": false,
"targets": [
{
- "expr": "Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_target_block_number",
+ "expr": "Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_target_block_number",
"instant": false,
"interval": "",
"legendFormat": "At Rialto",
"refId": "A"
},
{
- "expr": "Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_target_at_source_block_number",
+ "expr": "Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_target_at_source_block_number",
"instant": false,
"interval": "",
"legendFormat": "At Millau",
@@ -164,13 +164,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_source_block_number",
+ "expr": "Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_source_block_number",
"interval": "",
"legendFormat": "At Millau",
"refId": "A"
},
{
- "expr": "Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_source_at_target_block_number",
+ "expr": "Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_source_at_target_block_number",
"interval": "",
"legendFormat": "At Rialto",
"refId": "B"
@@ -298,13 +298,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from Rialto\", \"type\", \"source_latest_generated\"), \"type\", \"Latest Rialto message received by Millau\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from Rialto\", \"type\", \"source_latest_generated\"), \"type\", \"Latest Rialto message received by Millau\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
},
{
- "expr": "increase(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
+ "expr": "increase(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
"hide": true,
"interval": "",
"legendFormat": "Messages generated in last 5 minutes (Millau -> Rialto)",
@@ -407,7 +407,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by Rialto to Millau\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest Rialto message received by Millau\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by Rialto to Millau\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest Rialto message received by Millau\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
@@ -535,7 +535,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
+ "expr": "scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
"format": "time_series",
"instant": false,
"interval": "",
@@ -543,7 +543,7 @@
"refId": "A"
},
{
- "expr": "increase(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[5m]) OR on() vector(0)",
+ "expr": "increase(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[5m]) OR on() vector(0)",
"interval": "",
"legendFormat": "Millau Messages delivered to Rialto in last 5m",
"refId": "B"
@@ -680,7 +680,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
+ "expr": "scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
"interval": "",
"legendFormat": "Unconfirmed messages at Millau",
"refId": "A"
@@ -817,13 +817,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]))",
+ "expr": "scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at Rialto",
"refId": "A"
},
{
- "expr": "(scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]) > bool min_over_time(Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
+ "expr": "(scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]) > bool min_over_time(Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at Millau->Rialto (zero if messages are not being delivered to Rialto)",
"refId": "B"
diff --git a/deployments/bridges/rialto-millau/dashboard/grafana/relay-rialto-to-millau-messages-dashboard.json b/deployments/bridges/rialto-millau/dashboard/grafana/relay-rialto-to-millau-messages-dashboard.json
index 68932a0589..1dec1b688c 100644
--- a/deployments/bridges/rialto-millau/dashboard/grafana/relay-rialto-to-millau-messages-dashboard.json
+++ b/deployments/bridges/rialto-millau/dashboard/grafana/relay-rialto-to-millau-messages-dashboard.json
@@ -64,14 +64,14 @@
"steppedLine": false,
"targets": [
{
- "expr": "Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_target_block_number",
+ "expr": "Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_target_block_number",
"instant": false,
"interval": "",
"legendFormat": "At Millau",
"refId": "A"
},
{
- "expr": "Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_target_at_source_block_number",
+ "expr": "Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_target_at_source_block_number",
"instant": false,
"interval": "",
"legendFormat": "At Rialto",
@@ -165,13 +165,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_source_block_number",
+ "expr": "Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_source_block_number",
"interval": "",
"legendFormat": "At Rialto",
"refId": "A"
},
{
- "expr": "Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_best_source_at_target_block_number",
+ "expr": "Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_best_source_at_target_block_number",
"interval": "",
"legendFormat": "At Millau",
"refId": "B"
@@ -299,13 +299,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from Millau\", \"type\", \"source_latest_generated\"), \"type\", \"Latest message received by Rialto\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from Millau\", \"type\", \"source_latest_generated\"), \"type\", \"Latest message received by Rialto\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
},
{
- "expr": "increase(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
+ "expr": "increase(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
"hide": true,
"interval": "",
"legendFormat": "Messages generated in last 5 minutes (Rialto -> Millau)",
@@ -399,7 +399,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by Millau to Rialto\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest message received by Rialto\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by Millau to Rialto\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest message received by Rialto\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
@@ -527,7 +527,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
+ "expr": "scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
"format": "time_series",
"instant": false,
"interval": "",
@@ -535,7 +535,7 @@
"refId": "A"
},
{
- "expr": "increase(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[5m]) OR on() vector(0)",
+ "expr": "increase(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[5m]) OR on() vector(0)",
"interval": "",
"legendFormat": "Rialto Messages delivered to Millau in last 5m",
"refId": "B"
@@ -672,7 +672,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
+ "expr": "scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
"interval": "",
"legendFormat": "Unconfirmed messages at Rialto",
"refId": "A"
@@ -809,13 +809,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]))",
+ "expr": "scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at Millau",
"refId": "A"
},
{
- "expr": "(scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]) > bool min_over_time(Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
+ "expr": "(scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]) > bool min_over_time(Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_lane_state_nonces{type=\"target_latest_received\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at Millau (zero if messages are not being delivered to Millau)",
"refId": "B"
diff --git a/deployments/bridges/rialto-millau/dashboard/grafana/rialto-millau-maintenance-dashboard.json b/deployments/bridges/rialto-millau/dashboard/grafana/rialto-millau-maintenance-dashboard.json
index 23a180b17c..3ce23db469 100644
--- a/deployments/bridges/rialto-millau/dashboard/grafana/rialto-millau-maintenance-dashboard.json
+++ b/deployments/bridges/rialto-millau/dashboard/grafana/rialto-millau-maintenance-dashboard.json
@@ -426,7 +426,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "Rialto_to_Millau_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_is_source_and_source_at_target_using_different_forks OR on() vector(0)",
+ "expr": "Rialto_to_Millau_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_is_source_and_source_at_target_using_different_forks OR on() vector(0)",
"interval": "",
"legendFormat": "On different forks?",
"refId": "A"
@@ -559,7 +559,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "Millau_to_Rialto_MessageLane_0x52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7_is_source_and_source_at_target_using_different_forks OR on() vector(0)",
+ "expr": "Millau_to_Rialto_MessageLane_0xefed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7_is_source_and_source_at_target_using_different_forks OR on() vector(0)",
"interval": "",
"legendFormat": "On different forks?",
"refId": "A"
diff --git a/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh b/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh
index 1227c4a445..5816884c12 100755
--- a/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh
+++ b/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh
@@ -5,7 +5,7 @@ sleep 15
# see `rialto_millau_bridge_identifier_did_not_changed` test in `millau-runtime` crate for
# details on how this lane is computed
-MESSAGE_LANE="52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7"
+MESSAGE_LANE="efed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7"
/home/user/substrate-relay init-bridge millau-to-rialto \
--source-host millau-node-alice \
diff --git a/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-millau-to-rialto-parachain-messages-dashboard.json b/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-millau-to-rialto-parachain-messages-dashboard.json
index d4feb6a4c7..80bb7917c0 100644
--- a/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-millau-to-rialto-parachain-messages-dashboard.json
+++ b/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-millau-to-rialto-parachain-messages-dashboard.json
@@ -63,14 +63,14 @@
"steppedLine": false,
"targets": [
{
- "expr": "Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"instant": false,
"interval": "",
"legendFormat": "At RialtoParachain",
"refId": "A"
},
{
- "expr": "Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_target_at_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_target_at_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"instant": false,
"interval": "",
"legendFormat": "At Millau",
@@ -164,13 +164,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"interval": "",
"legendFormat": "At Millau",
"refId": "A"
},
{
- "expr": "Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_source_at_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_source_at_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"interval": "",
"legendFormat": "At RialtoParachain",
"refId": "B"
@@ -298,13 +298,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from RialtoParachain\", \"type\", \"source_latest_generated\"), \"type\", \"Latest RialtoParachain message received by Millau\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from RialtoParachain\", \"type\", \"source_latest_generated\"), \"type\", \"Latest RialtoParachain message received by Millau\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
},
{
- "expr": "increase(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
+ "expr": "increase(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
"hide": true,
"interval": "",
"legendFormat": "Messages generated in last 5 minutes (Millau -> RialtoParachain)",
@@ -407,7 +407,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by RialtoParachain to Millau\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest RialtoParachain message received by Millau\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by RialtoParachain to Millau\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest RialtoParachain message received by Millau\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
@@ -535,7 +535,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
+ "expr": "scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
"format": "time_series",
"instant": false,
"interval": "",
@@ -543,7 +543,7 @@
"refId": "A"
},
{
- "expr": "increase(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[5m]) OR on() vector(0)",
+ "expr": "increase(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[5m]) OR on() vector(0)",
"interval": "",
"legendFormat": "Millau Messages delivered to RialtoParachain in last 5m",
"refId": "B"
@@ -679,7 +679,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
+ "expr": "scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
"interval": "",
"legendFormat": "Unconfirmed messages at Millau",
"refId": "A"
@@ -815,13 +815,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]))",
+ "expr": "scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at RialtoParachain",
"refId": "A"
},
{
- "expr": "(scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) > bool min_over_time(Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
+ "expr": "(scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) > bool min_over_time(Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at Millau->RaltoParachain (zero if messages are not being delivered to RialtoParachain)",
"refId": "B"
diff --git a/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-rialto-parachain-to-millau-messages-dashboard.json b/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-rialto-parachain-to-millau-messages-dashboard.json
index 10c8fcd392..9d252b17f5 100644
--- a/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-rialto-parachain-to-millau-messages-dashboard.json
+++ b/deployments/bridges/rialto-parachain-millau/dashboard/grafana/relay-rialto-parachain-to-millau-messages-dashboard.json
@@ -63,14 +63,14 @@
"steppedLine": false,
"targets": [
{
- "expr": "RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"instant": false,
"interval": "",
"legendFormat": "At Millau",
"refId": "A"
},
{
- "expr": "RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_target_at_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_target_at_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"instant": false,
"interval": "",
"legendFormat": "At RialtoParachain",
@@ -164,13 +164,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_source_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"interval": "",
"legendFormat": "At RialtoParachain",
"refId": "A"
},
{
- "expr": "RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_best_source_at_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_best_source_at_target_block_number{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"interval": "",
"legendFormat": "At Millau",
"refId": "B"
@@ -298,13 +298,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from Millau\", \"type\", \"source_latest_generated\"), \"type\", \"Latest Millau message received by RialtoParachain\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_generated|target_latest_received\"}, \"type\", \"Latest message sent from Millau\", \"type\", \"source_latest_generated\"), \"type\", \"Latest Millau message received by RialtoParachain\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
},
{
- "expr": "increase(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
+ "expr": "increase(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[10m]) OR on() vector(0)",
"hide": true,
"interval": "",
"legendFormat": "Messages generated in last 5 minutes (RialtoParachain -> Millau)",
@@ -406,7 +406,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "label_replace(label_replace(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by Millau to RialtoParachain\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest Millau message received by RialtoParachain\", \"type\", \"target_latest_received\")",
+ "expr": "label_replace(label_replace(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=~\"source_latest_confirmed|target_latest_received\"}, \"type\", \"Latest message confirmed by Millau to RialtoParachain\", \"type\", \"source_latest_confirmed\"), \"type\", \"Latest Millau message received by RialtoParachain\", \"type\", \"target_latest_received\")",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
@@ -534,7 +534,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
+ "expr": "scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_generated\"}[2m])) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
"format": "time_series",
"instant": false,
"interval": "",
@@ -542,7 +542,7 @@
"refId": "A"
},
{
- "expr": "increase(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[5m]) OR on() vector(0)",
+ "expr": "increase(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[5m]) OR on() vector(0)",
"interval": "",
"legendFormat": "RialtoParachain Messages delivered to Millau in last 5m",
"refId": "B"
@@ -678,7 +678,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
+ "expr": "scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) OR on() vector(0)) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0))",
"interval": "",
"legendFormat": "Unconfirmed messages at RialtoParachain",
"refId": "A"
@@ -814,13 +814,13 @@
"steppedLine": false,
"targets": [
{
- "expr": "scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]))",
+ "expr": "scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m])) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at Millau",
"refId": "A"
},
{
- "expr": "(scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) > bool min_over_time(RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
+ "expr": "(scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"source_latest_confirmed\"}[2m]) OR on() vector(0)) - scalar(max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_confirmed\"}[2m]) OR on() vector(0))) * (max_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]) > bool min_over_time(RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_lane_state_nonces{instance=\"relay-millau-rialto-parachain-1:9616\",type=\"target_latest_received\"}[2m]))",
"interval": "",
"legendFormat": "Unconfirmed rewards at Millau (zero if messages are not being delivered to Millau)",
"refId": "B"
diff --git a/deployments/bridges/rialto-parachain-millau/dashboard/grafana/rialto-parachain-millau-maintenance-dashboard.json b/deployments/bridges/rialto-parachain-millau/dashboard/grafana/rialto-parachain-millau-maintenance-dashboard.json
index d3cd10f5a8..cfdeacfa7b 100644
--- a/deployments/bridges/rialto-parachain-millau/dashboard/grafana/rialto-parachain-millau-maintenance-dashboard.json
+++ b/deployments/bridges/rialto-parachain-millau/dashboard/grafana/rialto-parachain-millau-maintenance-dashboard.json
@@ -111,7 +111,7 @@
},
{
"exemplar": true,
- "expr": "at_RialtoParachain_relay_MillauMessages_reward_for_msgs_from_Millau_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_RialtoParachain_relay_MillauMessages_reward_for_msgs_to_Millau_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "at_RialtoParachain_relay_MillauMessages_reward_for_msgs_from_Millau_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_RialtoParachain_relay_MillauMessages_reward_for_msgs_to_Millau_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"hide": false,
"instant": false,
"interval": "",
@@ -120,7 +120,7 @@
},
{
"exemplar": true,
- "expr": "at_RialtoParachain_relay_MillauMessages_balance{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_RialtoParachain_relay_MillauMessages_reward_for_msgs_from_Millau_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_RialtoParachain_relay_MillauMessages_reward_for_msgs_to_Millau_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "at_RialtoParachain_relay_MillauMessages_balance{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_RialtoParachain_relay_MillauMessages_reward_for_msgs_from_Millau_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_RialtoParachain_relay_MillauMessages_reward_for_msgs_to_Millau_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"hide": false,
"interval": "",
"legendFormat": "With-Millau relay account total balance (balance + reward)",
@@ -262,7 +262,7 @@
},
{
"exemplar": true,
- "expr": "at_Millau_relay_RialtoParachainMessages_reward_for_msgs_from_RialtoParachain_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_Millau_relay_RialtoParachainMessages_reward_for_msgs_to_RialtoParachain_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "at_Millau_relay_RialtoParachainMessages_reward_for_msgs_from_RialtoParachain_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_Millau_relay_RialtoParachainMessages_reward_for_msgs_to_RialtoParachain_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"hide": false,
"interval": "",
"legendFormat": "With-Rialto relay account reward",
@@ -270,7 +270,7 @@
},
{
"exemplar": true,
- "expr": "at_Millau_relay_RialtoParachainMessages_balance{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_Millau_relay_RialtoParachainMessages_reward_for_msgs_from_RialtoParachain_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_Millau_relay_RialtoParachainMessages_reward_for_msgs_to_RialtoParachain_on_lane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de{instance=\"relay-millau-rialto-parachain-1:9616\"}",
+ "expr": "at_Millau_relay_RialtoParachainMessages_balance{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_Millau_relay_RialtoParachainMessages_reward_for_msgs_from_RialtoParachain_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"} + at_Millau_relay_RialtoParachainMessages_reward_for_msgs_to_RialtoParachain_on_lane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c{instance=\"relay-millau-rialto-parachain-1:9616\"}",
"hide": false,
"interval": "",
"legendFormat": "With-Rialto relay account total balance (balance + reward)",
@@ -404,7 +404,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "RialtoParachain_to_Millau_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_is_source_and_source_at_target_using_different_forks{instance=\"relay-millau-rialto-parachain-1:9616\"} OR on() vector(0)",
+ "expr": "RialtoParachain_to_Millau_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_is_source_and_source_at_target_using_different_forks{instance=\"relay-millau-rialto-parachain-1:9616\"} OR on() vector(0)",
"instant": false,
"interval": "",
"legendFormat": "On different forks?",
@@ -538,7 +538,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "Millau_to_RialtoParachain_MessageLane_0x6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de_is_source_and_source_at_target_using_different_forks{instance=\"relay-millau-rialto-parachain-1:9616\"} OR on() vector(0)",
+ "expr": "Millau_to_RialtoParachain_MessageLane_0xee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c_is_source_and_source_at_target_using_different_forks{instance=\"relay-millau-rialto-parachain-1:9616\"} OR on() vector(0)",
"interval": "",
"legendFormat": "On different forks?",
"refId": "A"
diff --git a/deployments/bridges/rialto-parachain-millau/entrypoints/relay-millau-rialto-parachain-entrypoint.sh b/deployments/bridges/rialto-parachain-millau/entrypoints/relay-millau-rialto-parachain-entrypoint.sh
index caa3ebb7ce..613e99d1b3 100755
--- a/deployments/bridges/rialto-parachain-millau/entrypoints/relay-millau-rialto-parachain-entrypoint.sh
+++ b/deployments/bridges/rialto-parachain-millau/entrypoints/relay-millau-rialto-parachain-entrypoint.sh
@@ -9,7 +9,7 @@ RIALTO_PARACHAIN_RELAY_ACCOUNT=${EXT_RIALTO_PARACHAIN_RELAY_ACCOUNT:-//Millau.He
# see `rialto_parachain_millau_bridge_identifier_did_not_changed` test in `millau-runtime` crate for
# details on how this lane is computed
-MESSAGE_LANE="6aa61bff567db6b5d5f0cb815ee6d8f5ac630e222a95700cb3d594134e3805de"
+MESSAGE_LANE="ee7158d2a51c3c43853ced550cc25bd00eb2662b231b1ddbb92e495ec882969c"
/home/user/substrate-relay init-bridge millau-to-rialto-parachain \
--source-host millau-node-alice \
diff --git a/deployments/local-scripts/relay-messages-millau-to-rialto.sh b/deployments/local-scripts/relay-messages-millau-to-rialto.sh
index 90f9c8c9dd..eca1052a7f 100755
--- a/deployments/local-scripts/relay-messages-millau-to-rialto.sh
+++ b/deployments/local-scripts/relay-messages-millau-to-rialto.sh
@@ -10,7 +10,7 @@ RIALTO_PORT="${RIALTO_PORT:-9944}"
RUST_LOG=bridge=debug \
./target/debug/substrate-relay relay-messages millau-to-rialto \
- --lane "52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7" \
+ --lane "efed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7" \
--source-host localhost \
--source-port $MILLAU_PORT \
--source-signer //Bob \
diff --git a/deployments/local-scripts/relay-messages-rialto-to-millau.sh b/deployments/local-scripts/relay-messages-rialto-to-millau.sh
index 03791d4135..455fffa242 100755
--- a/deployments/local-scripts/relay-messages-rialto-to-millau.sh
+++ b/deployments/local-scripts/relay-messages-rialto-to-millau.sh
@@ -10,7 +10,7 @@ RIALTO_PORT="${RIALTO_PORT:-9944}"
RUST_LOG=bridge=debug \
./target/debug/substrate-relay relay-messages rialto-to-millau \
- --lane "52011894c856c0c613a2ad2395dfbb509090f6b7a6aef9359adb75aa26a586c7" \
+ --lane "efed785b626e94da3969257012f506524bcec78867420e26ff8c55ddcdb0f7b7" \
--source-host localhost \
--source-port $RIALTO_PORT \
--source-signer //Bob \
diff --git a/modules/messages/src/lanes_manager.rs b/modules/messages/src/lanes_manager.rs
index 11b03ed843..da6967368e 100644
--- a/modules/messages/src/lanes_manager.rs
+++ b/modules/messages/src/lanes_manager.rs
@@ -21,8 +21,8 @@ use crate::{
};
use bp_messages::{
- ChainWithMessages, InboundLaneData, LaneId, LaneState, MessageKey, MessageNonce,
- MessagePayload, OutboundLaneData, VerificationError,
+ target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneId, LaneState,
+ MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError,
};
use bp_runtime::AccountIdOf;
use codec::{Decode, Encode, MaxEncodedLen};
@@ -45,6 +45,9 @@ pub enum LanesManagerError {
ClosedInboundLane,
/// Outbound lane with given id is closed.
ClosedOutboundLane,
+ /// Message dispatcher is inactive at given inbound lane. This is logical equivalent
+ /// of the [`Self::ClosedInboundLane`] variant.
+ LaneDispatcherInactive,
}
/// Message lanes manager.
@@ -145,10 +148,32 @@ impl, I: 'static> RuntimeInboundLaneStorage {
) -> Result, LanesManagerError> {
let cached_data =
InboundLanes::::get(lane_id).ok_or(LanesManagerError::UnknownInboundLane)?;
- ensure!(
- !check_active || cached_data.state.is_active(),
- LanesManagerError::ClosedInboundLane
- );
+
+ if check_active {
+ // check that the lane is not explicitly closed
+ ensure!(cached_data.state.is_active(), LanesManagerError::ClosedInboundLane);
+ // apart from the explicit closure, the lane may be unable to receive any messages.
+ // Right now we do an additional check here, but it may be done later (e.g. by
+ // explicitly closing the lane and reopening it from
+ // `pallet-xcm-bridge-hub::on-initialize`)
+ //
+ // The fact that we only check it here, means that the `MessageDispatch` may switch
+ // to inactive state during some message dispatch in the middle of message delivery
+ // transaction. But we treat result of `MessageDispatch::is_active()` as a hint, so
+ // we know that it won't drop messages - just it experiences problems with processing.
+ // This would allow us to check that in our signed extensions, and invalidate
+ // transaction early, thus avoiding losing honest relayers funds. This problem should
+ // gone with relayers coordination protocol.
+ //
+ // There's a limit on number of messages in the message delivery transaction, so even
+ // if we dispatch (enqueue) some additional messages, we'll know the maximal queue
+ // length;
+ ensure!(
+ T::MessageDispatch::is_active(lane_id),
+ LanesManagerError::LaneDispatcherInactive
+ );
+ }
+
Ok(RuntimeInboundLaneStorage {
lane_id,
cached_data: cached_data.into(),
diff --git a/modules/messages/src/lib.rs b/modules/messages/src/lib.rs
index 410e54908f..b6b99ab854 100644
--- a/modules/messages/src/lib.rs
+++ b/modules/messages/src/lib.rs
@@ -53,7 +53,8 @@ pub use weights_ext::{
use bp_header_chain::HeaderChain;
use bp_messages::{
source_chain::{
- DeliveryConfirmationPayments, FromBridgedChainMessagesDeliveryProof, SendMessageArtifacts,
+ DeliveryConfirmationPayments, FromBridgedChainMessagesDeliveryProof, OnMessagesDelivered,
+ SendMessageArtifacts,
},
target_chain::{
DeliveryPayments, DispatchMessage, FromBridgedChainMessagesProof, MessageDispatch,
@@ -64,7 +65,8 @@ use bp_messages::{
OutboundMessageDetails, UnrewardedRelayersState, VerificationError,
};
use bp_runtime::{
- AccountIdOf, BasicOperatingMode, HashOf, OwnedBridgeModule, PreComputedSize, Size,
+ AccountIdOf, BasicOperatingMode, HashOf, OwnedBridgeModule, PreComputedSize, RangeInclusiveExt,
+ Size,
};
use codec::{Decode, Encode};
use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound};
@@ -124,6 +126,8 @@ pub mod pallet {
/// Handler for relayer payments that happen during message delivery confirmation
/// transaction.
type DeliveryConfirmationPayments: DeliveryConfirmationPayments;
+ /// Delivery confirmation callback.
+ type OnMessagesDelivered: OnMessagesDelivered;
/// Message dispatch handler.
type MessageDispatch: MessageDispatch;
@@ -409,6 +413,12 @@ pub mod pallet {
lane_id,
);
+ // notify others about messages delivery
+ T::OnMessagesDelivered::on_messages_delivered(
+ lane_id,
+ lane.queued_messages().saturating_len(),
+ );
+
// because of lags, the inbound lane state (`lane_data`) may have entries for
// already rewarded relayers and messages (if all entries are duplicated, then
// this transaction must be filtered out by our signed extension)
@@ -616,6 +626,9 @@ fn send_message, I: 'static>(
.send_message(encoded_payload)
.map_err(Error::::MessageRejectedByPallet)?;
+ // return number of messages in the queue to let sender know about its state
+ let enqueued_messages = lane.queued_messages().saturating_len();
+
log::trace!(
target: LOG_TARGET,
"Accepted message {} to lane {:?}. Message size: {:?}",
@@ -626,7 +639,7 @@ fn send_message, I: 'static>(
Pallet::::deposit_event(Event::MessageAccepted { lane_id, nonce });
- Ok(SendMessageArtifacts { nonce })
+ Ok(SendMessageArtifacts { nonce, enqueued_messages })
}
/// Ensure that the pallet is in normal operational mode.
diff --git a/modules/messages/src/tests/mock.rs b/modules/messages/src/tests/mock.rs
index 6e78be6369..8472521933 100644
--- a/modules/messages/src/tests/mock.rs
+++ b/modules/messages/src/tests/mock.rs
@@ -220,11 +220,6 @@ impl pallet_bridge_grandpa::Config for TestRuntime {
type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight;
}
-parameter_types! {
- pub const MaxMessagesToPruneAtOnce: u64 = 10;
- pub const TestBridgedChainId: bp_runtime::ChainId = *b"test";
-}
-
/// weights of messages pallet calls we use in tests.
pub type TestWeightInfo = ();
@@ -242,6 +237,7 @@ impl Config for TestRuntime {
type DeliveryPayments = TestDeliveryPayments;
type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments;
+ type OnMessagesDelivered = ();
type MessageDispatch = TestMessageDispatch;
}
@@ -381,10 +377,24 @@ impl DeliveryConfirmationPayments for TestDeliveryConfirmationPayment
#[derive(Debug)]
pub struct TestMessageDispatch;
+impl TestMessageDispatch {
+ pub fn emulate_enqueued_message(lane: LaneId) {
+ let key = (b"dispatched", lane).encode();
+ let dispatched = frame_support::storage::unhashed::get_or_default::(&key[..]);
+ frame_support::storage::unhashed::put(&key[..], &(dispatched + 1));
+ }
+}
+
impl MessageDispatch for TestMessageDispatch {
type DispatchPayload = TestPayload;
type DispatchLevelResult = TestDispatchLevelResult;
+ fn is_active(lane: LaneId) -> bool {
+ frame_support::storage::unhashed::get_or_default::(
+ &(b"dispatched", lane).encode()[..],
+ ) <= BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX
+ }
+
fn dispatch_weight(message: &mut DispatchMessage) -> Weight {
match message.data.payload.as_ref() {
Ok(payload) => payload.declared_weight,
@@ -396,7 +406,10 @@ impl MessageDispatch for TestMessageDispatch {
message: DispatchMessage,
) -> MessageDispatchResult {
match message.data.payload.as_ref() {
- Ok(payload) => payload.dispatch_result.clone(),
+ Ok(payload) => {
+ Self::emulate_enqueued_message(message.key.lane_id);
+ payload.dispatch_result.clone()
+ },
Err(_) => dispatch_result(0),
}
}
diff --git a/modules/messages/src/tests/pallet_tests.rs b/modules/messages/src/tests/pallet_tests.rs
index b2686b8b0c..22b2cdf1ff 100644
--- a/modules/messages/src/tests/pallet_tests.rs
+++ b/modules/messages/src/tests/pallet_tests.rs
@@ -26,10 +26,11 @@ use crate::{
use bp_messages::{
source_chain::FromBridgedChainMessagesDeliveryProof,
- target_chain::FromBridgedChainMessagesProof, BridgeMessagesCall, ChainWithMessages,
- DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, LaneState, MessageKey,
- MessageNonce, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails,
- UnrewardedRelayer, UnrewardedRelayersState, VerificationError,
+ target_chain::{FromBridgedChainMessagesProof, MessageDispatch},
+ BridgeMessagesCall, ChainWithMessages, DeliveredMessages, InboundLaneData,
+ InboundMessageDetails, LaneId, LaneState, MessageKey, MessageNonce, MessagesOperatingMode,
+ OutboundLaneData, OutboundMessageDetails, UnrewardedRelayer, UnrewardedRelayersState,
+ VerificationError,
};
use bp_runtime::{BasicOperatingMode, PreComputedSize, Size};
use bp_test_utils::generate_owned_bridge_module_tests;
@@ -322,6 +323,86 @@ fn receive_messages_proof_updates_confirmed_message_nonce() {
});
}
+#[test]
+fn receive_messages_proof_fails_when_dispatcher_is_inactive() {
+ run_test(|| {
+ // "enqueue" enough (to deactivate dispatcher) messages at dispatcher
+ let latest_received_nonce = BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX + 1;
+ for _ in 1..=latest_received_nonce {
+ TestMessageDispatch::emulate_enqueued_message(test_lane_id());
+ }
+ assert!(!TestMessageDispatch::is_active(test_lane_id()));
+ InboundLanes::::insert(
+ test_lane_id(),
+ InboundLaneData {
+ state: LaneState::Opened,
+ last_confirmed_nonce: latest_received_nonce,
+ relayers: vec![].into(),
+ },
+ );
+
+ // try to delvier next message - it should fail because dispatcher is in "suspended" state
+ // at the beginning of the call
+ let messages_proof =
+ prepare_messages_proof(vec![message(latest_received_nonce + 1, REGULAR_PAYLOAD)], None);
+ assert_noop!(
+ Pallet::::receive_messages_proof(
+ RuntimeOrigin::signed(1),
+ TEST_RELAYER_A,
+ messages_proof,
+ 1,
+ REGULAR_PAYLOAD.declared_weight,
+ ),
+ Error::::LanesManager(LanesManagerError::LaneDispatcherInactive)
+ );
+ assert!(!TestMessageDispatch::is_active(test_lane_id()));
+ });
+}
+
+#[test]
+fn receive_messages_succeeds_when_dispatcher_becomes_inactive_in_the_middle_of_transaction() {
+ run_test(|| {
+ // "enqueue" enough (to deactivate dispatcher) messages at dispatcher
+ let latest_received_nonce = BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX / 2;
+ for _ in 1..=latest_received_nonce {
+ TestMessageDispatch::emulate_enqueued_message(test_lane_id());
+ }
+ assert!(TestMessageDispatch::is_active(test_lane_id()));
+ InboundLanes::::insert(
+ test_lane_id(),
+ InboundLaneData {
+ state: LaneState::Opened,
+ last_confirmed_nonce: latest_received_nonce,
+ relayers: vec![].into(),
+ },
+ );
+
+ // try to delvier next `BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX` messages
+ // - it will lead to dispatcher deactivation, but the transaction shall not fail and all
+ // messages must be delivered
+ let messages_begin = latest_received_nonce + 1;
+ let messages_end =
+ messages_begin + BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
+ let messages_range = messages_begin..messages_end;
+ let messages_count = BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
+ assert_ok!(Pallet::::receive_messages_proof(
+ RuntimeOrigin::signed(1),
+ TEST_RELAYER_A,
+ prepare_messages_proof(
+ messages_range.map(|nonce| message(nonce, REGULAR_PAYLOAD)).collect(),
+ None,
+ ),
+ messages_count as _,
+ REGULAR_PAYLOAD.declared_weight * messages_count,
+ ),);
+ assert_eq!(
+ inbound_unrewarded_relayers_state(test_lane_id()).last_delivered_nonce,
+ messages_end - 1,
+ );
+ assert!(!TestMessageDispatch::is_active(test_lane_id()));
+ });
+}
+
#[test]
fn receive_messages_proof_does_not_accept_message_if_dispatch_weight_is_not_enough() {
run_test(|| {
diff --git a/modules/xcm-bridge-hub-router/Cargo.toml b/modules/xcm-bridge-hub-router/Cargo.toml
index 72699580d1..965e3ef23d 100644
--- a/modules/xcm-bridge-hub-router/Cargo.toml
+++ b/modules/xcm-bridge-hub-router/Cargo.toml
@@ -13,7 +13,7 @@ scale-info = { version = "2.8.0", default-features = false, features = ["bit-vec
# Bridge dependencies
-bp-xcm-bridge-hub-router = { path = "../../primitives/xcm-bridge-hub-router", default-features = false }
+bp-xcm-bridge-hub = { path = "../../primitives/xcm-bridge-hub", default-features = false }
# Substrate Dependencies
@@ -36,7 +36,7 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" }
[features]
default = ["std"]
std = [
- "bp-xcm-bridge-hub-router/std",
+ "bp-xcm-bridge-hub/std",
"codec/std",
"frame-benchmarking/std",
"frame-support/std",
diff --git a/modules/xcm-bridge-hub-router/src/benchmarking.rs b/modules/xcm-bridge-hub-router/src/benchmarking.rs
index 1a4338a6fc..84be404b47 100644
--- a/modules/xcm-bridge-hub-router/src/benchmarking.rs
+++ b/modules/xcm-bridge-hub-router/src/benchmarking.rs
@@ -18,7 +18,7 @@
#![cfg(feature = "runtime-benchmarks")]
-use crate::{DeliveryFeeFactor, InitialFactor};
+use crate::{DeliveryFeeFactor, InitialFactor, MINIMAL_DELIVERY_FEE_FACTOR};
use frame_benchmarking::benchmarks_instance_pallet;
use frame_support::traits::{Get, Hooks};
@@ -35,13 +35,13 @@ pub trait Config: crate::Config {
benchmarks_instance_pallet! {
on_initialize_when_non_congested {
- DeliveryFeeFactor::::put(InitialFactor::get() + InitialFactor::get());
+ DeliveryFeeFactor::::put(MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR);
}: {
crate::Pallet::::on_initialize(Zero::zero())
}
on_initialize_when_congested {
- DeliveryFeeFactor::::put(InitialFactor::get() + InitialFactor::get());
+ DeliveryFeeFactor::::put(MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR);
T::make_congested();
}: {
crate::Pallet::::on_initialize(Zero::zero())
diff --git a/modules/xcm-bridge-hub-router/src/lib.rs b/modules/xcm-bridge-hub-router/src/lib.rs
index 2461547485..8081338a80 100644
--- a/modules/xcm-bridge-hub-router/src/lib.rs
+++ b/modules/xcm-bridge-hub-router/src/lib.rs
@@ -22,13 +22,18 @@
//! All other bridge hub queues offer some backpressure mechanisms. So if at least one
//! of all queues is congested, it will eventually lead to the growth of the queue at
//! this chain.
+//!
+//! **A note on terminology**: when we mention the bridge hub here, we mean the chain that
+//! has the messages pallet deployed (`pallet-bridge-grandpa`, `pallet-bridge-messages`,
+//! `pallet-xcm-bridge-hub`, ...). It may be the system bridge hub parachain or any other
+//! chain.
#![cfg_attr(not(feature = "std"), no_std)]
-use bp_xcm_bridge_hub_router::LocalXcmChannel;
+use bp_xcm_bridge_hub::LocalXcmChannelManager;
use codec::Encode;
use frame_support::traits::Get;
-use sp_runtime::{traits::One, FixedPointNumber, FixedU128, Saturating};
+use sp_runtime::{FixedPointNumber, FixedU128, Saturating};
use xcm::prelude::*;
use xcm_builder::{ExporterFor, SovereignPaidRemoteExporter};
@@ -40,6 +45,9 @@ pub mod weights;
mod mock;
+/// Minimal delivery fee factor.
+pub const MINIMAL_DELIVERY_FEE_FACTOR: FixedU128 = FixedU128::from_u32(1);
+
/// The factor that is used to increase current message fee factor when bridge experiencing
/// some lags.
const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(105, 100); // 1.05
@@ -75,17 +83,20 @@ pub mod pallet {
type UniversalLocation: Get;
/// Relative location of the sibling bridge hub.
type SiblingBridgeHubLocation: Get;
- /// The bridged network that this config is for.
+ /// The bridged network that this config is for if specified.
+ /// Also used for filtering `Bridges` by `BridgedNetworkId`.
+ /// If not specified, allows all networks pass through.
type BridgedNetworkId: Get;
+ /// Configuration for supported **bridged networks/locations** with **bridge location** and
+ /// **possible fee**. Allows to externalize better control over allowed **bridged
+ /// networks/locations**.
+ type Bridges: ExporterFor;
/// Actual message sender (`HRMP` or `DMP`) to the sibling bridge hub location.
type ToBridgeHubSender: SendXcm;
- /// Underlying channel with the sibling bridge hub. It must match the channel, used
- /// by the `Self::ToBridgeHubSender`.
- type WithBridgeHubChannel: LocalXcmChannel;
+ /// Local XCM channel manager.
+ type LocalXcmChannelManager: LocalXcmChannelManager;
- /// Base bridge fee that is paid for every outbound message.
- type BaseFee: Get;
/// Additional fee that is paid for every byte of the outbound message.
type ByteFee: Get;
/// Asset that is used to paid bridge fee.
@@ -98,37 +109,36 @@ pub mod pallet {
#[pallet::hooks]
impl, I: 'static> Hooks> for Pallet {
fn on_initialize(_n: BlockNumberFor) -> Weight {
- // if XCM queue is still congested, we don't change anything
- if T::WithBridgeHubChannel::is_congested() {
+ // if XCM channel is still congested, we don't change anything
+ if T::LocalXcmChannelManager::is_congested(&T::SiblingBridgeHubLocation::get()) {
return T::WeightInfo::on_initialize_when_congested()
}
- DeliveryFeeFactor::::mutate(|f| {
- let previous_factor = *f;
- *f = InitialFactor::get().max(*f / EXPONENTIAL_FEE_BASE);
- if previous_factor != *f {
- log::info!(
- target: LOG_TARGET,
- "Bridge queue is uncongested. Decreased fee factor from {} to {}",
- previous_factor,
- f,
- );
+ // if we can't decrease the delivery fee factor anymore, we don't change anything
+ let mut delivery_fee_factor = Self::delivery_fee_factor();
+ if delivery_fee_factor == MINIMAL_DELIVERY_FEE_FACTOR {
+ return T::WeightInfo::on_initialize_when_congested()
+ }
- T::WeightInfo::on_initialize_when_non_congested()
- } else {
- // we have not actually updated the `DeliveryFeeFactor`, so we may deduct
- // single db write from maximal weight
- T::WeightInfo::on_initialize_when_non_congested()
- .saturating_sub(T::DbWeight::get().writes(1))
- }
- })
+ let previous_factor = delivery_fee_factor;
+ delivery_fee_factor =
+ MINIMAL_DELIVERY_FEE_FACTOR.max(delivery_fee_factor / EXPONENTIAL_FEE_BASE);
+ log::info!(
+ target: LOG_TARGET,
+ "Bridge channel is uncongested. Decreased fee factor from {} to {}",
+ previous_factor,
+ delivery_fee_factor,
+ );
+
+ DeliveryFeeFactor::::put(delivery_fee_factor);
+ T::WeightInfo::on_initialize_when_non_congested()
}
}
/// Initialization value for the delivery fee factor.
#[pallet::type_value]
pub fn InitialFactor() -> FixedU128 {
- FixedU128::one()
+ MINIMAL_DELIVERY_FEE_FACTOR
}
/// The number to multiply the base delivery fee by.
@@ -169,8 +179,8 @@ pub mod pallet {
impl, I: 'static> Pallet {
/// Called when new message is sent (queued to local outbound XCM queue) over the bridge.
pub(crate) fn on_message_sent_to_bridge(message_size: u32) {
- // if outbound queue is not congested, do nothing
- if !T::WithBridgeHubChannel::is_congested() {
+ // if outbound channel is not congested, do nothing
+ if !T::LocalXcmChannelManager::is_congested(&T::SiblingBridgeHubLocation::get()) {
return
}
@@ -183,7 +193,7 @@ pub mod pallet {
*f = f.saturating_mul(total_factor);
log::info!(
target: LOG_TARGET,
- "Bridge queue is congested. Increased fee factor from {} to {}",
+ "Bridge channel is congested. Increased fee factor from {} to {}",
previous_factor,
f,
);
@@ -206,32 +216,89 @@ type ViaBridgeHubExporter = SovereignPaidRemoteExporter<
impl, I: 'static> ExporterFor for Pallet {
fn exporter_for(
network: &NetworkId,
- _remote_location: &InteriorMultiLocation,
+ remote_location: &InteriorMultiLocation,
message: &Xcm<()>,
) -> Option<(MultiLocation, Option)> {
- // ensure that the message is sent to the expected bridged network
+ // ensure that the message is sent to the expected bridged network (if specified).
if *network != T::BridgedNetworkId::get() {
+ log::trace!(
+ target: LOG_TARGET,
+ "Router with bridged_network_id {:?} does not support bridging to network {:?}!",
+ T::BridgedNetworkId::get(),
+ network,
+ );
return None
}
+ // ensure that the message is sent to the expected bridged network and location.
+ let Some((bridge_hub_location, maybe_payment)) =
+ T::Bridges::exporter_for(network, remote_location, message)
+ else {
+ log::trace!(
+ target: LOG_TARGET,
+ "Router with bridged_network_id {:?} does not support bridging to network {:?} \
+ and remote_location {:?}!",
+ T::BridgedNetworkId::get(),
+ network,
+ remote_location,
+ );
+ return None
+ };
+
+ // ensure that the bridge hub location is the expected one
+ if bridge_hub_location != T::SiblingBridgeHubLocation::get() {
+ log::trace!(
+ target: LOG_TARGET,
+ "Router with bridged_network_id {:?} is configured to use different bridge hub \
+ router {:?}. Expected: {:?}",
+ T::BridgedNetworkId::get(),
+ bridge_hub_location,
+ T::SiblingBridgeHubLocation::get(),
+ );
+ return None
+ }
+
+ // take `base_fee` from `T::Brides`, but it has to be the same `T::FeeAsset`
+ let base_fee = match maybe_payment {
+ Some(payment) => match payment {
+ MultiAsset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount,
+ invalid_asset => {
+ log::error!(
+ target: LOG_TARGET,
+ "Router with bridged_network_id {:?} is configured for `T::FeeAsset` {:?} \
+ which is not compatible with {:?} for bridge_hub_location: {:?} for bridging to {:?}/{:?}!",
+ T::BridgedNetworkId::get(),
+ T::FeeAsset::get(),
+ invalid_asset,
+ bridge_hub_location,
+ network,
+ remote_location,
+ );
+ return None
+ },
+ },
+ None => 0,
+ };
+
// compute fee amount. Keep in mind that this is only the bridge fee. The fee for sending
// message from this chain to child/sibling bridge hub is determined by the
// `Config::ToBridgeHubSender`
let message_size = message.encoded_size();
let message_fee = (message_size as u128).saturating_mul(T::ByteFee::get());
- let fee_sum = T::BaseFee::get().saturating_add(message_fee);
+ let fee_sum = base_fee.saturating_add(message_fee);
let fee_factor = Self::delivery_fee_factor();
let fee = fee_factor.saturating_mul_int(fee_sum);
+ let fee = if fee > 0 { Some((T::FeeAsset::get(), fee).into()) } else { None };
log::info!(
target: LOG_TARGET,
- "Going to send message ({} bytes) over bridge. Computed bridge fee {} using fee factor {}",
+ "Going to send message ({} bytes) over bridge. Computed bridge fee {:?} using fee factor {}",
+ message_size,
fee,
fee_factor,
- message_size,
);
- Some((T::SiblingBridgeHubLocation::get(), Some((T::FeeAsset::get(), fee).into())))
+ Some((bridge_hub_location, fee))
}
}
@@ -272,7 +339,7 @@ impl, I: 'static> SendXcm for Pallet {
// use router to enqueue message to the sibling/child bridge hub. This also should handle
// payment for passing through this queue.
let (message_size, ticket) = ticket;
- let xcm_hash = T::ToBridgeHubSender::deliver(ticket)?;
+ let xcm_hash = ViaBridgeHubExporter::::deliver(ticket)?;
// increase delivery fee factor if required
Self::on_message_sent_to_bridge(message_size);
@@ -287,11 +354,12 @@ mod tests {
use mock::*;
use frame_support::traits::Hooks;
+ use sp_runtime::traits::One;
#[test]
fn initial_fee_factor_is_one() {
run_test(|| {
- assert_eq!(DeliveryFeeFactor::::get(), FixedU128::one());
+ assert_eq!(DeliveryFeeFactor::::get(), MINIMAL_DELIVERY_FEE_FACTOR);
})
}
@@ -299,7 +367,7 @@ mod tests {
fn fee_factor_is_not_decreased_from_on_initialize_when_queue_is_congested() {
run_test(|| {
DeliveryFeeFactor::::put(FixedU128::from_rational(125, 100));
- TestWithBridgeHubChannel::make_congested();
+ TestLocalXcmChannelManager::make_congested();
// it should not decrease, because queue is congested
let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor();
@@ -314,13 +382,13 @@ mod tests {
DeliveryFeeFactor::::put(FixedU128::from_rational(125, 100));
// it shold eventually decreased to one
- while XcmBridgeHubRouter::delivery_fee_factor() > FixedU128::one() {
+ while XcmBridgeHubRouter::delivery_fee_factor() > MINIMAL_DELIVERY_FEE_FACTOR {
XcmBridgeHubRouter::on_initialize(One::one());
}
// verify that it doesn't decreases anymore
XcmBridgeHubRouter::on_initialize(One::one());
- assert_eq!(XcmBridgeHubRouter::delivery_fee_factor(), FixedU128::one());
+ assert_eq!(XcmBridgeHubRouter::delivery_fee_factor(), MINIMAL_DELIVERY_FEE_FACTOR);
})
}
@@ -407,7 +475,7 @@ mod tests {
#[test]
fn sent_message_increases_factor_if_queue_is_congested() {
run_test(|| {
- TestWithBridgeHubChannel::make_congested();
+ TestLocalXcmChannelManager::make_congested();
let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor();
assert_eq!(
diff --git a/modules/xcm-bridge-hub-router/src/mock.rs b/modules/xcm-bridge-hub-router/src/mock.rs
index 04540158e6..2756553278 100644
--- a/modules/xcm-bridge-hub-router/src/mock.rs
+++ b/modules/xcm-bridge-hub-router/src/mock.rs
@@ -18,7 +18,7 @@
use crate as pallet_xcm_bridge_hub_router;
-use bp_xcm_bridge_hub_router::LocalXcmChannel;
+use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager};
use frame_support::{construct_runtime, parameter_types};
use sp_core::H256;
use sp_runtime::{
@@ -26,6 +26,7 @@ use sp_runtime::{
BuildStorage,
};
use xcm::prelude::*;
+use xcm_builder::NetworkExportTable;
pub type AccountId = u64;
type Block = frame_system::mocking::MockBlock;
@@ -51,6 +52,11 @@ parameter_types! {
pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ThisNetworkId::get()), Parachain(1000));
pub SiblingBridgeHubLocation: MultiLocation = ParentThen(X1(Parachain(1002))).into();
pub BridgeFeeAsset: AssetId = MultiLocation::parent().into();
+ pub BridgeTable: Vec<(NetworkId, MultiLocation, Option)> = vec![(
+ BridgedNetworkId::get(),
+ SiblingBridgeHubLocation::get(),
+ Some((BridgeFeeAsset::get(), BASE_FEE).into()),
+ )];
}
impl frame_system::Config for TestRuntime {
@@ -85,11 +91,11 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime {
type UniversalLocation = UniversalLocation;
type SiblingBridgeHubLocation = SiblingBridgeHubLocation;
type BridgedNetworkId = BridgedNetworkId;
+ type Bridges = NetworkExportTable;
type ToBridgeHubSender = TestToBridgeHubSender;
- type WithBridgeHubChannel = TestWithBridgeHubChannel;
+ type LocalXcmChannelManager = TestLocalXcmChannelManager;
- type BaseFee = ConstU128;
type ByteFee = ConstU128;
type FeeAsset = BridgeFeeAsset;
}
@@ -118,17 +124,27 @@ impl SendXcm for TestToBridgeHubSender {
}
}
-pub struct TestWithBridgeHubChannel;
+pub struct TestLocalXcmChannelManager;
-impl TestWithBridgeHubChannel {
+impl TestLocalXcmChannelManager {
pub fn make_congested() {
- frame_support::storage::unhashed::put(b"TestWithBridgeHubChannel.Congested", &true);
+ frame_support::storage::unhashed::put(b"TestLocalXcmChannelManager.Congested", &true);
}
}
-impl LocalXcmChannel for TestWithBridgeHubChannel {
- fn is_congested() -> bool {
- frame_support::storage::unhashed::get_or_default(b"TestWithBridgeHubChannel.Congested")
+impl LocalXcmChannelManager for TestLocalXcmChannelManager {
+ type Error = ();
+
+ fn is_congested(_with: &MultiLocation) -> bool {
+ frame_support::storage::unhashed::get_or_default(b"TestLocalXcmChannelManager.Congested")
+ }
+
+ fn suspend_bridge(_with: &MultiLocation, _bridge: BridgeId) -> Result<(), Self::Error> {
+ Ok(())
+ }
+
+ fn resume_bridge(_with: &MultiLocation, _bridge: BridgeId) -> Result<(), Self::Error> {
+ Ok(())
}
}
diff --git a/modules/xcm-bridge-hub/Cargo.toml b/modules/xcm-bridge-hub/Cargo.toml
index 815054fd73..4cf457da7f 100644
--- a/modules/xcm-bridge-hub/Cargo.toml
+++ b/modules/xcm-bridge-hub/Cargo.toml
@@ -29,7 +29,7 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", d
# Polkadot Dependencies
xcm = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false }
-xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false }
xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false }
[dev-dependencies]
diff --git a/modules/xcm-bridge-hub/src/dispatcher.rs b/modules/xcm-bridge-hub/src/dispatcher.rs
index 0d0662fdc1..5898e1b67d 100644
--- a/modules/xcm-bridge-hub/src/dispatcher.rs
+++ b/modules/xcm-bridge-hub/src/dispatcher.rs
@@ -18,16 +18,23 @@
//! bridge messages dispatcher. Internally, it just forwards inbound blob to the
//! XCM-level blob dispatcher, which pushes message to some other queue (e.g.
//! to HRMP queue with the sibling target chain).
+//!
+//! This code is executed at the target bridge hub.
-use crate::{Config, Pallet, XcmAsPlainPayload, LOG_TARGET};
+use crate::{Config, Pallet, LOG_TARGET};
-use bp_messages::target_chain::{DispatchMessage, MessageDispatch};
+use bp_messages::{
+ target_chain::{DispatchMessage, MessageDispatch},
+ LaneId,
+};
use bp_runtime::messages::MessageDispatchResult;
+use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager, XcmAsPlainPayload};
use codec::{Decode, Encode};
use frame_support::{dispatch::Weight, CloneNoBound, EqNoBound, PartialEqNoBound};
use pallet_bridge_messages::{Config as BridgeMessagesConfig, WeightInfoExt};
use scale_info::TypeInfo;
use sp_runtime::SaturatedConversion;
+use xcm::prelude::*;
use xcm_builder::{DispatchBlob, DispatchBlobError};
/// Message dispatch result type for single message.
@@ -52,6 +59,14 @@ where
type DispatchPayload = XcmAsPlainPayload;
type DispatchLevelResult = XcmBlobMessageDispatchResult;
+ fn is_active(lane: LaneId) -> bool {
+ let bridge_id = BridgeId::from_lane_id(lane);
+ Pallet::::bridge(bridge_id)
+ .and_then(|bridge| bridge.bridge_origin_relative_location.try_as().cloned().ok())
+ .map(|recipient: MultiLocation| !T::LocalXcmChannelManager::is_congested(&recipient))
+ .unwrap_or(false)
+ }
+
fn dispatch_weight(message: &mut DispatchMessage) -> Weight {
match message.data.payload {
Ok(ref payload) => {
diff --git a/modules/xcm-bridge-hub/src/exporter.rs b/modules/xcm-bridge-hub/src/exporter.rs
index 5eab79b38a..d42ba7523b 100644
--- a/modules/xcm-bridge-hub/src/exporter.rs
+++ b/modules/xcm-bridge-hub/src/exporter.rs
@@ -17,16 +17,31 @@
//! The code that allows to use the pallet (`pallet-xcm-bridge-hub`) as XCM message
//! exporter at the sending bridge hub. Internally, it just enqueues outbound blob
//! in the messages pallet queue.
+//!
+//! This code is executed at the source bridge hub.
-use crate::{Config, Pallet, XcmAsPlainPayload, LOG_TARGET};
+use crate::{Config, Pallet, SuspendedBridges, LOG_TARGET};
-use bp_messages::{source_chain::MessagesBridge, LaneId};
+use bp_messages::{
+ source_chain::{MessagesBridge, OnMessagesDelivered},
+ LaneId, MessageNonce,
+};
+use bp_xcm_bridge_hub::{BridgeId, BridgeLocations, LocalXcmChannelManager, XcmAsPlainPayload};
use frame_support::traits::Get;
use pallet_bridge_messages::{Config as BridgeMessagesConfig, Pallet as BridgeMessagesPallet};
+use sp_std::boxed::Box;
use xcm::prelude::*;
use xcm_builder::{HaulBlob, HaulBlobError, HaulBlobExporter};
use xcm_executor::traits::ExportXcm;
+/// Maximal number of messages in the outbound bridge queue. Once we reach this limit, we
+/// suspend a bridge.
+const OUTBOUND_LANE_CONGESTED_THRESHOLD: MessageNonce = 8_192;
+
+/// After we have suspended the bridge, we wait until number of messages in the outbound bridge
+/// queue drops to this count, before sending resuming the bridge.
+const OUTBOUND_LANE_UNCONGESTED_THRESHOLD: MessageNonce = 1_024;
+
// An easy way to access `HaulBlobExporter`.
type PalletAsHaulBlobExporter = HaulBlobExporter<
DummyHaulBlob,
@@ -43,7 +58,7 @@ where
OutboundPayload = XcmAsPlainPayload,
>,
{
- type Ticket = (LaneId, XcmAsPlainPayload, XcmHash);
+ type Ticket = (Box, XcmAsPlainPayload, XcmHash);
fn validate(
network: NetworkId,
@@ -83,37 +98,40 @@ where
bridge_origin_universal_location.relative_to(&T::UniversalLocation::get());
// then we are able to compute the lane id used to send messages
- let bridge_locations = Self::bridge_locations(
+ let locations = Self::bridge_locations(
Box::new(bridge_origin_relative_location),
Box::new(bridge_destination_universal_location.into()),
)
.map_err(|_| SendError::Unroutable)?;
- Ok(((bridge_locations.lane_id, blob, id), price))
+ Ok(((locations, blob, id), price))
}
fn deliver(
- (lane_id, blob, id): (LaneId, XcmAsPlainPayload, XcmHash),
+ (locations, blob, id): (Box, XcmAsPlainPayload, XcmHash),
) -> Result {
- let send_result = MessagesPallet::::send_message(lane_id, blob);
+ let send_result = MessagesPallet::::send_message(locations.bridge_id.lane_id(), blob);
match send_result {
Ok(artifacts) => {
log::info!(
target: LOG_TARGET,
- "XCM message {:?} has been enqueued at lane {:?} with nonce {}",
+ "XCM message {:?} has been enqueued at bridge {:?} with nonce {}",
id,
- lane_id,
+ locations.bridge_id,
artifacts.nonce,
);
+
+ // maybe we need switch to congested state
+ Self::on_bridge_message_enqueued(locations, artifacts.enqueued_messages);
},
Err(error) => {
log::debug!(
target: LOG_TARGET,
- "XCM message {:?} has been dropped because of bridge error {:?} on lane {:?}",
+ "XCM message {:?} has been dropped because of bridge error {:?} on bridge {:?}",
id,
error,
- lane_id,
+ locations.bridge_id,
);
return Err(SendError::Transport("BridgeSendError"))
},
@@ -123,6 +141,149 @@ where
}
}
+impl, I: 'static> OnMessagesDelivered for Pallet {
+ fn on_messages_delivered(lane_id: LaneId, enqueued_messages: MessageNonce) {
+ Self::on_bridge_messages_delivered(lane_id, enqueued_messages);
+ }
+}
+
+impl, I: 'static> Pallet {
+ /// Called when new message is pushed onto outbound bridge queue.
+ fn on_bridge_message_enqueued(
+ locations: Box,
+ enqueued_messages: MessageNonce,
+ ) {
+ // if the bridge queue is not congested, we don't want to do anything
+ let is_congested = enqueued_messages > OUTBOUND_LANE_CONGESTED_THRESHOLD;
+ if !is_congested {
+ return
+ }
+
+ // TODO: https://github.com/paritytech/parity-bridges-common/issues/2006 we either need fishermens
+ // to watch thsi rule violation (suspended, but keep sending new messages), or we need a
+ // hard limit for that like other XCM queues have
+
+ // check if the lane is already suspended. If it is, do nothing. We still accept new
+ // messages to the suspended bridge, hoping that it'll be actually suspended soon
+ let is_already_congested = SuspendedBridges::::get().contains(&locations.bridge_id);
+ if is_already_congested {
+ return
+ }
+
+ // else - suspend the bridge
+ let suspend_result = T::LocalXcmChannelManager::suspend_bridge(
+ &locations.bridge_origin_relative_location,
+ locations.bridge_id,
+ );
+ match suspend_result {
+ Ok(_) => {
+ log::debug!(
+ target: LOG_TARGET,
+ "Suspended the bridge {:?}, originated by the {:?}",
+ locations.bridge_id,
+ locations.bridge_origin_relative_location,
+ );
+ },
+ Err(e) => {
+ log::debug!(
+ target: LOG_TARGET,
+ "Failed to suspended the bridge {:?}, originated by the {:?}: {:?}",
+ locations.bridge_id,
+ locations.bridge_origin_relative_location,
+ e,
+ );
+
+ return
+ },
+ }
+
+ // and remember that we have suspended the bridge
+ SuspendedBridges::::mutate(|suspended_bridges| {
+ let maybe_error = suspended_bridges.try_push(locations.bridge_id);
+ if let Err(e) = maybe_error {
+ // TODO: https://github.com/paritytech/parity-bridges-common/issues/2006
+ // we've sent the suspend signal, but failed to remember that => we'll keep
+ // up sending the signal on every further message, effectively blocking the XCM
+ // lane. We need some limit on total number of bridges so that this call won't ever
+ // fail.
+
+ log::debug!(
+ target: LOG_TARGET,
+ "Failed to remember the suspended bridge {:?}, originated by the {:?}: {:?}",
+ locations.bridge_id,
+ locations.bridge_origin_relative_location,
+ e,
+ );
+ }
+ });
+ }
+
+ /// Must be called whenever we receive a message delivery confirmation.
+ fn on_bridge_messages_delivered(lane_id: LaneId, enqueued_messages: MessageNonce) {
+ // if the bridge queue is still congested, we don't want to do anything
+ let is_congested = enqueued_messages > OUTBOUND_LANE_UNCONGESTED_THRESHOLD;
+ if is_congested {
+ return
+ }
+
+ // if we have not suspended the bridge before, we don't want to do anything
+ let bridge_id = BridgeId::from_lane_id(lane_id);
+ if !SuspendedBridges::::get().contains(&bridge_id) {
+ return
+ }
+
+ // else - resume the bridge
+ if let Some(bridge) = Self::bridge(bridge_id) {
+ let bridge_origin_relative_location =
+ (*bridge.bridge_origin_relative_location).try_into();
+ let bridge_origin_relative_location = match bridge_origin_relative_location {
+ Ok(bridge_origin_relative_location) => bridge_origin_relative_location,
+ Err(e) => {
+ log::debug!(
+ target: LOG_TARGET,
+ "Failed to convert the bridge {:?} location: {:?}",
+ lane_id,
+ e,
+ );
+
+ return
+ },
+ };
+
+ let resume_result = T::LocalXcmChannelManager::resume_bridge(
+ &bridge_origin_relative_location,
+ bridge_id,
+ );
+ match resume_result {
+ Ok(_) => {
+ log::debug!(
+ target: LOG_TARGET,
+ "Resumed the bridge {:?}, originated by the {:?}",
+ lane_id,
+ bridge_origin_relative_location,
+ );
+ },
+ Err(e) => {
+ log::debug!(
+ target: LOG_TARGET,
+ "Failed to resume the bridge {:?}, originated by the {:?}: {:?}",
+ lane_id,
+ bridge_origin_relative_location,
+ e,
+ );
+
+ return
+ },
+ }
+ }
+
+ // and forget that we have previously suspended the bridge
+ SuspendedBridges::::mutate(|suspended_bridges| {
+ suspended_bridges.retain(|b| *b != bridge_id);
+ });
+ }
+}
+
/// Dummy implementation of the `HaulBlob` trait that is never called.
///
/// We are using `HaulBlobExporter`, which requires `HaulBlob` implementation. It assumes that
@@ -155,9 +316,9 @@ mod tests {
XcmOverBridge::bridge_locations_from_origin(origin, Box::new(with.into())).unwrap();
let lanes_manager = LanesManagerOf::::new();
- lanes_manager.create_outbound_lane(locations.lane_id).unwrap();
+ lanes_manager.create_outbound_lane(locations.bridge_id.lane_id()).unwrap();
assert!(lanes_manager
- .active_outbound_lane(locations.lane_id)
+ .active_outbound_lane(locations.bridge_id.lane_id())
.unwrap()
.queued_messages()
.is_empty());
@@ -175,7 +336,7 @@ mod tests {
// double check that the message has been pushed to the expected lane
// (it should already been checked during `send_message` call)
assert!(!lanes_manager
- .active_outbound_lane(locations.lane_id)
+ .active_outbound_lane(locations.bridge_id.lane_id())
.unwrap()
.queued_messages()
.is_empty());
diff --git a/modules/xcm-bridge-hub/src/lib.rs b/modules/xcm-bridge-hub/src/lib.rs
index 8fe956e75b..c2ade2bcb5 100644
--- a/modules/xcm-bridge-hub/src/lib.rs
+++ b/modules/xcm-bridge-hub/src/lib.rs
@@ -51,15 +51,20 @@
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
-use bp_messages::{LaneId, LaneState, MessageNonce};
+use bp_messages::{LaneState, MessageNonce};
use bp_runtime::{AccountIdOf, BalanceOf, BlockNumberOf, RangeInclusiveExt};
use bp_xcm_bridge_hub::{
- bridge_locations, Bridge, BridgeLocations, BridgeLocationsError, BridgeState,
+ bridge_locations, Bridge, BridgeId, BridgeLocations, BridgeLocationsError, BridgeState,
+ LocalXcmChannelManager,
+};
+use frame_support::{
+ traits::{Currency, ReservableCurrency},
+ DefaultNoBound,
};
-use frame_support::traits::{Currency, ReservableCurrency};
use frame_system::Config as SystemConfig;
use pallet_bridge_messages::{Config as BridgeMessagesConfig, LanesManagerError};
use sp_runtime::traits::{Header as HeaderT, HeaderProvider, Zero};
+use sp_std::{boxed::Box, vec::Vec};
use xcm::prelude::*;
use xcm_builder::DispatchBlob;
use xcm_executor::traits::ConvertLocation;
@@ -71,10 +76,6 @@ mod dispatcher;
mod exporter;
mod mock;
-/// Encoded XCM blob. We expect the bridge messages pallet to use this blobtype for both inbound
-/// and outbound payloads.
-pub type XcmAsPlainPayload = Vec;
-
/// The target that will be used when publishing logs related to this pallet.
pub const LOG_TARGET: &str = "runtime::bridge-xcm";
@@ -105,6 +106,10 @@ pub mod pallet {
/// `BridgedNetworkId` consensus.
type BridgeMessagesPalletInstance: 'static;
+ /// Maximal number of suspended bridges.
+ #[pallet::constant]
+ type MaxSuspendedBridges: Get;
+
/// A set of XCM locations within local consensus system that are allowed to open
/// bridges with remote destinations.
// TODO: there's only one impl of `EnsureOrigin` -
@@ -124,9 +129,11 @@ pub mod pallet {
/// Currency used to pay for bridge registration.
type NativeCurrency: ReservableCurrency;
+ /// Local XCM channel manager.
+ type LocalXcmChannelManager: LocalXcmChannelManager;
/// XCM-level dispatcher for inbound bridge messages.
type BlobDispatcher: DispatchBlob;
- /// Price of single message export.
+ /// Price of single message export to the bridged consensus (`Self::BridgedNetworkId`).
type MessageExportPrice: Get;
}
@@ -181,7 +188,7 @@ pub mod pallet {
.map_err(|_| Error::::FailedToReserveBridgeReserve)?;
// save bridge metadata
- Bridges::::try_mutate(locations.lane_id, |bridge| match bridge {
+ Bridges::::try_mutate(locations.bridge_id, |bridge| match bridge {
Some(_) => Err(Error::::BridgeAlreadyExists),
None => {
*bridge = Some(BridgeOf:: {
@@ -199,24 +206,24 @@ pub mod pallet {
// create new lanes. Under normal circumstances, following calls shall never fail
let lanes_manager = LanesManagerOf::::new();
lanes_manager
- .create_inbound_lane(locations.lane_id)
+ .create_inbound_lane(locations.bridge_id.lane_id())
.map_err(Error::::LanesManager)?;
lanes_manager
- .create_outbound_lane(locations.lane_id)
+ .create_outbound_lane(locations.bridge_id.lane_id())
.map_err(Error::::LanesManager)?;
// write something to log
log::trace!(
target: LOG_TARGET,
"Bridge {:?} between {:?} and {:?} has been opened",
- locations.lane_id,
+ locations.bridge_id,
locations.bridge_origin_universal_location,
locations.bridge_destination_universal_location,
);
// deposit `BridgeOpened` event
Self::deposit_event(Event::::BridgeOpened {
- lane_id: locations.lane_id,
+ bridge_id: locations.bridge_id,
local_endpoint: Box::new(locations.bridge_origin_universal_location),
remote_endpoint: Box::new(locations.bridge_destination_universal_location),
});
@@ -257,7 +264,7 @@ pub mod pallet {
// update bridge metadata - this also guarantees that the bridge is in the proper state
let bridge =
- Bridges::::try_mutate_exists(locations.lane_id, |bridge| match bridge {
+ Bridges::::try_mutate_exists(locations.bridge_id, |bridge| match bridge {
Some(bridge) => {
bridge.state = BridgeState::Closed;
Ok(bridge.clone())
@@ -268,10 +275,10 @@ pub mod pallet {
// close inbound and outbound lanes
let lanes_manager = LanesManagerOf::::new();
let mut inbound_lane = lanes_manager
- .any_state_inbound_lane(locations.lane_id)
+ .any_state_inbound_lane(locations.bridge_id.lane_id())
.map_err(Error::::LanesManager)?;
let mut outbound_lane = lanes_manager
- .any_state_outbound_lane(locations.lane_id)
+ .any_state_outbound_lane(locations.bridge_id.lane_id())
.map_err(Error::::LanesManager)?;
// now prune queued messages
@@ -296,7 +303,7 @@ pub mod pallet {
log::trace!(
target: LOG_TARGET,
"Bridge {:?} between {:?} and {:?} is closing. {} messages remaining",
- locations.lane_id,
+ locations.bridge_id,
locations.bridge_origin_universal_location,
locations.bridge_destination_universal_location,
enqueued_messages,
@@ -304,7 +311,7 @@ pub mod pallet {
// deposit the `ClosingBridge` event
Self::deposit_event(Event::::ClosingBridge {
- lane_id: locations.lane_id,
+ bridge_id: locations.bridge_id,
pruned_messages,
enqueued_messages,
});
@@ -315,7 +322,11 @@ pub mod pallet {
// else we have pruned all messages, so lanes and the bridge itself may gone
inbound_lane.purge();
outbound_lane.purge();
- Bridges::::remove(locations.lane_id);
+ Bridges::::remove(locations.bridge_id);
+ SuspendedBridges::::mutate(|suspended_bridges| {
+ suspended_bridges.retain(|b| *b != locations.bridge_id);
+ // TODO: https://github.com/paritytech/parity-bridges-common/issues/2006 send resume signal or not???
+ });
// unreserve remaining amount
let failed_to_unreserve =
@@ -327,7 +338,7 @@ pub mod pallet {
target: LOG_TARGET,
"Failed to unreserve {:?} during ridge {:?} closure",
failed_to_unreserve,
- locations.lane_id,
+ locations.bridge_id,
);
}
@@ -335,14 +346,14 @@ pub mod pallet {
log::trace!(
target: LOG_TARGET,
"Bridge {:?} between {:?} and {:?} has been closed",
- locations.lane_id,
+ locations.bridge_id,
locations.bridge_origin_universal_location,
locations.bridge_destination_universal_location,
);
// deposit the `BridgePruned` event
Self::deposit_event(Event::::BridgePruned {
- lane_id: locations.lane_id,
+ bridge_id: locations.bridge_id,
pruned_messages,
});
@@ -385,8 +396,62 @@ pub mod pallet {
/// All registered bridges.
#[pallet::storage]
+ #[pallet::getter(fn bridge)]
pub type Bridges, I: 'static = ()> =
- StorageMap<_, Identity, LaneId, BridgeOf>;
+ StorageMap<_, Identity, BridgeId, BridgeOf>;
+
+ /// All currently suspended bridges.
+ #[pallet::storage]
+ #[pallet::getter(fn bridges_by_local_origin)]
+ pub type SuspendedBridges, I: 'static = ()> =
+ StorageValue<_, BoundedVec, ValueQuery>;
+
+ #[pallet::genesis_config]
+ #[derive(DefaultNoBound)]
+ pub struct GenesisConfig, I: 'static = ()> {
+ /// Opened bridges.
+ ///
+ /// Keep in mind that we are **NOT** reserving any amount for the bridges, opened at
+ /// genesis. We are **NOT** opening lanes, used by this bridge. It all must be done using
+ /// other pallets genesis configuration or some other means.
+ pub opened_bridges: Vec<(MultiLocation, InteriorMultiLocation)>,
+ /// Dummy marker.
+ pub phantom: sp_std::marker::PhantomData<(T, I)>,
+ }
+
+ #[pallet::genesis_build]
+ impl, I: 'static> BuildGenesisConfig for GenesisConfig
+ where
+ T: frame_system::Config>>,
+ {
+ fn build(&self) {
+ for (bridge_origin_relative_location, bridge_destination_universal_location) in
+ &self.opened_bridges
+ {
+ let locations = Pallet::::bridge_locations(
+ Box::new(*bridge_origin_relative_location),
+ Box::new((*bridge_destination_universal_location).into()),
+ )
+ .expect("Invalid genesis configuration");
+ let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location(
+ &locations.bridge_origin_relative_location,
+ )
+ .expect("Invalid genesis configuration");
+
+ Bridges::::insert(
+ locations.bridge_id,
+ Bridge {
+ bridge_origin_relative_location: Box::new(
+ locations.bridge_origin_relative_location.into(),
+ ),
+ state: BridgeState::Opened,
+ bridge_owner_account,
+ reserve: Zero::zero(),
+ },
+ );
+ }
+ }
+ }
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
@@ -397,13 +462,13 @@ pub mod pallet {
local_endpoint: Box,
/// Universal location of remote bridge endpoint.
remote_endpoint: Box,
- /// Bridge and its lane identifier.
- lane_id: LaneId,
+ /// Bridge identifier.
+ bridge_id: BridgeId,
},
/// Bridge is going to be closed, but not yet fully pruned from the runtime storage.
ClosingBridge {
- /// Bridge and its lane identifier.
- lane_id: LaneId,
+ /// Bridge identifier.
+ bridge_id: BridgeId,
/// Number of pruned messages during the close call.
pruned_messages: MessageNonce,
/// Number of enqueued messages that need to be pruned in follow up calls.
@@ -412,8 +477,8 @@ pub mod pallet {
/// Bridge has been closed and pruned from the runtime storage. It now may be reopened
/// again by any participant.
BridgePruned {
- /// Bridge and its lane identifier.
- lane_id: LaneId,
+ /// Bridge identifier.
+ bridge_id: BridgeId,
/// Number of pruned messages during the close call.
pruned_messages: MessageNonce,
},
@@ -427,6 +492,8 @@ pub mod pallet {
InvalidBridgeOriginAccount,
/// The bridge is already registered in this pallet.
BridgeAlreadyExists,
+ /// The local origin already owns a maximal number of bridges.
+ TooManyBridgesForLocalOrigin,
/// Trying to close already closed bridge.
BridgeAlreadyClosed,
/// Lanes manager error.
@@ -445,6 +512,7 @@ mod tests {
use super::*;
use mock::*;
+ use bp_messages::LaneId;
use frame_support::{assert_noop, assert_ok, traits::fungible::Mutate};
use frame_system::{EventRecord, Phase};
@@ -475,11 +543,11 @@ mod tests {
bridge_owner_account,
reserve,
};
- Bridges::::insert(locations.lane_id, bridge.clone());
+ Bridges::::insert(locations.bridge_id, bridge.clone());
let lanes_manager = LanesManagerOf::::new();
- lanes_manager.create_inbound_lane(locations.lane_id).unwrap();
- lanes_manager.create_outbound_lane(locations.lane_id).unwrap();
+ lanes_manager.create_inbound_lane(locations.bridge_id.lane_id()).unwrap();
+ lanes_manager.create_outbound_lane(locations.bridge_id.lane_id()).unwrap();
(bridge, *locations)
}
@@ -615,7 +683,7 @@ mod tests {
);
Bridges::::insert(
- locations.lane_id,
+ locations.bridge_id,
Bridge {
bridge_origin_relative_location: Box::new(
locations.bridge_origin_relative_location.into(),
@@ -649,7 +717,7 @@ mod tests {
let lanes_manager = LanesManagerOf::::new();
- lanes_manager.create_inbound_lane(locations.lane_id).unwrap();
+ lanes_manager.create_inbound_lane(locations.bridge_id.lane_id()).unwrap();
assert_noop!(
XcmOverBridge::open_bridge(
origin.clone(),
@@ -658,8 +726,11 @@ mod tests {
Error::::LanesManager(LanesManagerError::InboundLaneAlreadyExists),
);
- lanes_manager.active_inbound_lane(locations.lane_id).unwrap().purge();
- lanes_manager.create_outbound_lane(locations.lane_id).unwrap();
+ lanes_manager
+ .active_inbound_lane(locations.bridge_id.lane_id())
+ .unwrap()
+ .purge();
+ lanes_manager.create_outbound_lane(locations.bridge_id.lane_id()).unwrap();
assert_noop!(
XcmOverBridge::open_bridge(origin, Box::new(bridged_asset_hub_location().into()),),
Error::::LanesManager(
@@ -696,13 +767,13 @@ mod tests {
.unwrap();
// ensure that there's no bridge and lanes in the storage
- assert_eq!(Bridges::