From e0187b8ad80803a34406bae7e4ae4a13c82858a2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 13 Jul 2023 17:36:17 +0300 Subject: [PATCH] introduce partial bp-xcm-bridge-hub - just LocalXcmChannelManager --- Cargo.lock | 7 +++ Cargo.toml | 1 + primitives/xcm-bridge-hub/Cargo.toml | 18 +++++++ primitives/xcm-bridge-hub/src/lib.rs | 75 ++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 primitives/xcm-bridge-hub/Cargo.toml create mode 100644 primitives/xcm-bridge-hub/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 9a03f85896..58109de8fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1139,6 +1139,13 @@ dependencies = [ "sp-api", ] +[[package]] +name = "bp-xcm-bridge-hub" +version = "0.1.0" +dependencies = [ + "xcm", +] + [[package]] name = "bridge-runtime-common" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 8048b9fcdc..4bb4697656 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ members = [ "primitives/relayers", "primitives/runtime", "primitives/test-utils", + "primitives/xcm-bridge-hub", "relays/bin-substrate", "relays/client-bridge-hub-kusama", "relays/client-bridge-hub-polkadot", diff --git a/primitives/xcm-bridge-hub/Cargo.toml b/primitives/xcm-bridge-hub/Cargo.toml new file mode 100644 index 0000000000..dcd65545fa --- /dev/null +++ b/primitives/xcm-bridge-hub/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "bp-xcm-bridge-hub" +description = "Primitives of the xcm-bridge-hub pallet." +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[dependencies] +# Polkadot Dependencies + +xcm = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } + +[features] +default = ["std"] +std = [ + "xcm/std", +] \ No newline at end of file diff --git a/primitives/xcm-bridge-hub/src/lib.rs b/primitives/xcm-bridge-hub/src/lib.rs new file mode 100644 index 0000000000..fa37e2aa6c --- /dev/null +++ b/primitives/xcm-bridge-hub/src/lib.rs @@ -0,0 +1,75 @@ +// Copyright 2019-2021 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 . + +//! Primitives of the xcm-bridge-hub pallet. + +#![cfg_attr(not(feature = "std"), no_std)] + +use xcm::latest::prelude::*; + +/// A manager of XCM communication channels between the bridge hub and parent/sibling chains +/// that have opened bridges at this bridge hub. +/// +/// We use this interface to suspend and resume channels programmatically to implement backpressure +/// mechanism for bridge queues. +#[allow(clippy::result_unit_err)] // XCM uses `Result<(), ()>` everywhere +pub trait LocalXcmChannelManager { + // TODO: https://github.com/paritytech/parity-bridges-common/issues/2255 + // check following assumptions. They are important at least for following cases: + // 1) we now close the associated outbound lane when misbehavior is reported. If we'll keep + // handling inbound XCM messages after the `suspend_inbound_channel`, they will be dropped + // 2) the sender will be able to enqueue message to othe lanes if we won't stop handling inbound + // XCM immediately. He even may open additional bridges + + /// Stop handling new incoming XCM messages from given bridge `owner` (parent/sibling chain). + /// + /// We assume that the channel will be suspended immediately, but we don't mind if inbound + /// messages will keep piling up here for some time. Once this is communicated to the + /// `owner` chain (in any form), we expect it to stop sending messages to us and queue + /// messages at that `owner` chain instead. + /// + /// This method will be called if we detect a misbehavior in one of bridges, owned by + /// the `owner`. We expect that: + /// + /// - no more incoming XCM messages from the `owner` will be processed until further + /// `resume_inbound_channel` call; + /// + /// - soon after the call, the channel will switch to the state when incoming messages are + /// piling up at the sending chain, not at the bridge hub. + /// + /// This method shall not fail if the channel is already suspended. + fn suspend_inbound_channel(owner: MultiLocation) -> Result<(), ()>; + + /// Start handling incoming messages from from given bridge `owner` (parent/sibling chain) + /// again. + /// + /// This method is called when the `owner` tries to resume bridge operations after + /// resolving "misbehavior" issues. The channel is assumed to be suspended by the previous + /// `suspend_inbound_channel` call, however we don't check it anywhere. + /// + /// This method shall not fail if the channel is already resumed. + fn resume_inbound_channel(owner: MultiLocation) -> Result<(), ()>; +} + +impl LocalXcmChannelManager for () { + fn suspend_inbound_channel(_owner: MultiLocation) -> Result<(), ()> { + Ok(()) + } + + fn resume_inbound_channel(_owner: MultiLocation) -> Result<(), ()> { + Err(()) + } +}