Skip to content
Snippets Groups Projects
Unverified Commit 72028edc authored by Branislav Kontur's avatar Branislav Kontur
Browse files

Add pallet's README.md

parent 25aa13ad
No related merge requests found
Pipeline #487010 waiting for manual action with stages
in 5 minutes and 43 seconds
# 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
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment