Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
polkadot-sdk
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
parity
Mirrored projects
polkadot-sdk
Commits
149b0ac2
Unverified
Commit
149b0ac2
authored
7 months ago
by
Branislav Kontur
Browse files
Options
Downloads
Patches
Plain Diff
Moved README.md to the lib.rs
parent
c01cc8d7
Branches
Branches containing commit
No related merge requests found
Pipeline
#487028
waiting for manual action with stages
in 35 minutes and 11 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bridges/modules/xcm-bridge-hub/README.md
+0
-86
0 additions, 86 deletions
bridges/modules/xcm-bridge-hub/README.md
bridges/modules/xcm-bridge-hub/src/lib.rs
+87
-0
87 additions, 0 deletions
bridges/modules/xcm-bridge-hub/src/lib.rs
with
87 additions
and
86 deletions
bridges/modules/xcm-bridge-hub/README.md
deleted
100644 → 0
+
0
−
86
View file @
c01cc8d7
# Bridge XCM Bridge Hub Pallet
The
`pallet_xcm_bridge_hub`
pallet is used to manage (open, close) bridges between chains from different consensuses.
The new extrinsics
`fn open_bridge`
and
`fn close_bridge`
are introduced. Other chains can manage channels
with different bridged global consensuses.
## Concept of `lane` and `LaneId`
There is another
`pallet_bridge_messages`
pallet that handles inbound/outbound lanes for messages.
Each lane is a unique connection between two chains from different consensuses and is identified by
`LaneId`
.
`LaneId`
is generated once when a new bridge is requested by
`fn open_bridge`
.
It is generated by
`BridgeLocations::calculate_lane_id`
based on the following parameters:
-
Source
`bridge_origin_universal_location`
(latest XCM)
-
Destination
`bridge_destination_universal_location`
(latest XCM)
-
XCM version (both sides of the bridge must use the same parameters to generate the same
`LaneId`
)
-
`bridge_origin_universal_location`
,
`bridge_destination_universal_location`
is converted to the
`Versioned*`
structs
`LaneId`
is expected to never change because:
-
We need the same
`LaneId`
on both sides of the bridge, as
`LaneId`
is part of the message key proofs.
-
Runtime upgrades are entirely asynchronous.
-
We already have a running production Polkadot/Kusama bridge that uses
`LaneId([0, 0, 0, 0])`
.
`LaneId`
is backward compatible, meaning it can be encoded/decoded from the older format
`[u8; 4]`
used for
static lanes, as well as the new format
`H256`
generated by
`BridgeLocations::calculate_lane_id`
.
## Concept of `bridge` and `BridgeId`
The
`pallet_xcm_bridge_hub`
pallet needs to store some metadata about opened bridges.
The bridge (or bridge metadata) is stored under the
`BridgeId`
key.
`BridgeId`
is generated from
`bridge_origin_relative_location`
and
`bridge_origin_universal_location`
using the
`latest`
XCM structs.
`BridgeId`
is not transferred over the bridge; it is only important for local consensus.
It essentially serves as an index/key to bridge metadata.
All the XCM infrastructure around
`XcmExecutor`
,
`SendXcm`
,
`ExportXcm`
use the
`latest`
XCM,
so
`BridgeId`
must remain compatible with the
`latest`
XCM. For example, we have an
`ExportXcm`
implementation
in
`exporter.rs`
that handles the
`ExportMessage`
instruction with
`universal_source`
and
`destination`
(latest XCM),
so we need to create
`BridgeId`
and the corresponding
`LaneId`
.
## Migrations and State
This pallet implements
`try_state`
, ensuring compatibility and checking everything so we know if any migration is needed.
`do_try_state`
checks for
`BridgeId`
compatibility, which is recalculated on runtime upgrade.
Upgrading to a new XCM version should not break anything, except removing older XCM versions.
In such cases, we need to add migration for
`BridgeId`
and stored
`Versioned*`
structs and
update
`LaneToBridge`
mapping, but this won't affect
`LaneId`
over the bridge.
## How to Open a Bridge?
The
`pallet_xcm_bridge_hub`
pallet has the extrinsic
`fn open_bridge`
and
an important configuration
`pallet_xcm_bridge_hub::Config::OpenBridgeOrigin`
,
which translates the call's origin to the XCM
`Location`
and converts it to the
`bridge_origin_universal_location`
.
With the current setup, this origin/location is expected to be either the relay chain or a sibling parachain
as one side of the bridge. Another parameter is
`bridge_destination_universal_location`
,
which is the other side of the bridge from a different global consensus.
Example of opening a bridge between some random parachains from Polkadot and Kusama:
1.
The local sibling parachain
`Location::new(1, Parachain(1234))`
must send some DOTs to its sovereign account
on BridgeHubPolkadot to cover
`BridgeDeposit`
, fees for
`Transact`
, and the existential deposit.
2.
Send a call to the BridgeHubPolkadot from the local sibling parachain:
`Location::new(1, Parachain(1234))`
```
xcm::Transact(
origin_kind: OriginKind::Xcm,
XcmOverBridgeHubKusama::open_bridge(
VersionedInteriorLocation::V4([GlobalConsensus(Kusama), Parachain(4567)].into()),
);
)
```
3.
Check the stored bridge metadata and generated
`LaneId`
.
4.
The local sibling parachain
`Location::new(1, Parachain(4567))`
must send some KSMs to its sovereign account
on BridgeHubKusama to cover
`BridgeDeposit`
, fees for
`Transact`
, and the existential deposit.
5.
Send a call to the BridgeHubKusama from the local sibling parachain:
`Location::new(1, Parachain(4567))`
```
xcm::Transact(
origin_kind: OriginKind::Xcm,
XcmOverBridgeHubKusama::open_bridge(
VersionedInteriorLocation::V4([GlobalConsensus(Polkadot), Parachain(1234)].into()),
);
)
```
6.
Check the stored bridge metadata and generated
`LaneId`
.
7.
Run the bridge messages relayer for
`LaneId`
.
8.
Send messages from both sides.
The opening bridge holds the configured
`BridgeDeposit`
from the origin's sovereign account,
but this deposit is returned when the bridge is closed with
`fn close_bridge`
.
\ No newline at end of file
This diff is collapsed.
Click to expand it.
bridges/modules/xcm-bridge-hub/src/lib.rs
+
87
−
0
View file @
149b0ac2
...
...
@@ -18,6 +18,67 @@
//! open and close bridges between local (to this pallet location) and remote XCM
//! destinations.
//!
//! The `pallet_xcm_bridge_hub` pallet is used to manage (open, close) bridges between chains from
//! different consensuses. The new extrinsics `fn open_bridge` and `fn close_bridge` are introduced.
//! Other chains can manage channels with different bridged global consensuses.
//!
//! # Concept of `lane` and `LaneId`
//!
//! There is another `pallet_bridge_messages` pallet that handles inbound/outbound lanes for
//! messages. Each lane is a unique connection between two chains from different consensuses and is
//! identified by `LaneId`. `LaneId` is generated once when a new bridge is requested by `fn
//! open_bridge`. It is generated by `BridgeLocations::calculate_lane_id` based on the following
//! parameters:
//! - Source `bridge_origin_universal_location` (latest XCM)
//! - Destination `bridge_destination_universal_location` (latest XCM)
//! - XCM version (both sides of the bridge must use the same parameters to generate the same
//! `LaneId`)
//! - `bridge_origin_universal_location`, `bridge_destination_universal_location` is converted to
//! the `Versioned*` structs
//!
//! `LaneId` is expected to never change because:
//! - We need the same `LaneId` on both sides of the bridge, as `LaneId` is part of the message key
//! proofs.
//! - Runtime upgrades are entirely asynchronous.
//! - We already have a running production Polkadot/Kusama bridge that uses `LaneId([0, 0, 0, 0])`.
//!
//! `LaneId` is backward compatible, meaning it can be encoded/decoded from the older format `[u8;
//! 4]` used for static lanes, as well as the new format `H256` generated by
//! `BridgeLocations::calculate_lane_id`.
//!
//! # Concept of `bridge` and `BridgeId`
//!
//! The `pallet_xcm_bridge_hub` pallet needs to store some metadata about opened bridges. The bridge
//! (or bridge metadata) is stored under the `BridgeId` key.
//!
//! `BridgeId` is generated from `bridge_origin_relative_location` and
//! `bridge_origin_universal_location` using the `latest` XCM structs. `BridgeId` is not transferred
//! over the bridge; it is only important for local consensus. It essentially serves as an index/key
//! to bridge metadata. All the XCM infrastructure around `XcmExecutor`, `SendXcm`, `ExportXcm` use
//! the `latest` XCM, so `BridgeId` must remain compatible with the `latest` XCM. For example, we
//! have an `ExportXcm` implementation in `exporter.rs` that handles the `ExportMessage` instruction
//! with `universal_source` and `destination` (latest XCM), so we need to create `BridgeId` and the
//! corresponding `LaneId`.
//!
//! # Migrations and State
//!
//! This pallet implements `try_state`, ensuring compatibility and checking everything so we know if
//! any migration is needed. `do_try_state` checks for `BridgeId` compatibility, which is
//! recalculated on runtime upgrade. Upgrading to a new XCM version should not break anything,
//! except removing older XCM versions. In such cases, we need to add migration for `BridgeId` and
//! stored `Versioned*` structs and update `LaneToBridge` mapping, but this won't affect `LaneId`
//! over the bridge.
//!
//! # How to Open a Bridge?
//!
//! The `pallet_xcm_bridge_hub` pallet has the extrinsic `fn open_bridge` and an important
//! configuration `pallet_xcm_bridge_hub::Config::OpenBridgeOrigin`, which translates the call's
//! origin to the XCM `Location` and converts it to the `bridge_origin_universal_location`. With the
//! current setup, this origin/location is expected to be either the relay chain or a sibling
//! parachain as one side of the bridge. Another parameter is
//! `bridge_destination_universal_location`, which is the other side of the bridge from a different
//! global consensus.
//!
//! Every bridge between two XCM locations has a dedicated lane in associated
//! messages pallet. Assuming that this pallet is deployed at the bridge hub
//! parachain and there's a similar pallet at the bridged network, the dynamic
...
...
@@ -47,6 +108,32 @@
//! are delivered to the destination, are processed in the way their sender expects. So if we
//! can't guarantee that, we shall not care about more complex procedures and leave it to the
//! participating parties.
//!
//! # Example
//!
//! Example of opening a bridge between some random parachains from Polkadot and Kusama:
//!
//! 1. The local sibling parachain `Location::new(1, Parachain(1234))` must send some DOTs to its
//! sovereign account on BridgeHubPolkadot to cover `BridgeDeposit`, fees for `Transact`, and the
//! existential deposit.
//! 2. Send a call to the BridgeHubPolkadot from the local sibling parachain: `Location::new(1,
//! Parachain(1234))` ``` xcm::Transact( origin_kind: OriginKind::Xcm,
//! XcmOverBridgeHubKusama::open_bridge( VersionedInteriorLocation::V4([GlobalConsensus(Kusama),
//! Parachain(4567)].into()), ); ) ```
//! 3. Check the stored bridge metadata and generated `LaneId`.
//! 4. The local sibling parachain `Location::new(1, Parachain(4567))` must send some KSMs to its
//! sovereign account
//! on BridgeHubKusama to cover `BridgeDeposit`, fees for `Transact`, and the existential deposit.
//! 5. Send a call to the BridgeHubKusama from the local sibling parachain: `Location::new(1,
//! Parachain(4567))` ``` xcm::Transact( origin_kind: OriginKind::Xcm,
//! XcmOverBridgeHubKusama::open_bridge(
//! VersionedInteriorLocation::V4([GlobalConsensus(Polkadot), Parachain(1234)].into()), ); ) ```
//! 6. Check the stored bridge metadata and generated `LaneId`.
//! 7. Run the bridge messages relayer for `LaneId`.
//! 8. Send messages from both sides.
//!
//! The opening bridge holds the configured `BridgeDeposit` from the origin's sovereign account, but
//! this deposit is returned when the bridge is closed with `fn close_bridge`.
#![warn(missing_docs)]
#![cfg_attr(not(feature
=
"std"
),
no_std)]
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment