From 72028edc2396e1ad0d1b768473b1cb48e6e44cd2 Mon Sep 17 00:00:00 2001
From: Branislav Kontur <bkontur@gmail.com>
Date: Wed, 31 Jul 2024 12:03:38 +0200
Subject: [PATCH] Add pallet's README.md

---
 bridges/modules/xcm-bridge-hub/README.md | 86 ++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 bridges/modules/xcm-bridge-hub/README.md

diff --git a/bridges/modules/xcm-bridge-hub/README.md b/bridges/modules/xcm-bridge-hub/README.md
new file mode 100644
index 00000000000..42bf3c18bed
--- /dev/null
+++ b/bridges/modules/xcm-bridge-hub/README.md
@@ -0,0 +1,86 @@
+# 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
-- 
GitLab