Try   HackMD

Bridges: Permissionless Lanes

TLDR:
We are introducing a new "permissionless lanes" feature, which allows for the dynamic management of opening and closing lanes instead of the current method of hard-coding them in the source code.

Current State of the Polkadot/Kusama Bridge

The existing Polkadot/Kusama (P/K) bridge deployment involves deploying several bridge-related pallets on both BridgeHubs.

  • pallet-bridge-grandpa (for syncing GRANDPA finality, e.g., BHP follows Kusama finality, and BHK follows Polkadot finality)
  • pallet-bridge-parachains (for syncing parachain finality on the opposite BridgeHub)
  • pallet-bridge-messages (for syncing messages with the bridged side)
  • pallet-xcm-bridge-hub (acts as an XCM exporter for bridged consensus and an XCM dispatcher/router for incoming bridged messages)
  • pallet-bridge-relayers (for registering relayers and collecting rewards)

The currently deployed pallet-bridge-messages::<Instance1> only supports the LaneId format [u8; 4], and it has a single hard-coded lane [0, 0, 0, 1] for bridging Polkadot and Kusama AssetHubs.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Permissionless Lanes Feature

This feature allows approved origins (relay chains, sibling parachains) to dynamically open and close bridges (via BridgeHubs) with another bridged (substrate-like) consensus, using only xcm::Transact and OriginKind::Xcm.

The pallet-xcm-bridge-hub will manage (open and close) bridges between chains with different consensuses. The new extrinsics, fn open_bridge and fn close_bridge, facilitate this. Internally, these create or remove inbound and outbound lanes in the pallet-bridge-messages instance.

Each lane represents a unique connection between two chains with different consensuses and is identified by a LaneId. A LaneId is generated when a new bridge is requested via fn open_bridge. It’s essential to ensure the same LaneId on both sides of the bridge, as the relayer can only relay messages when the LaneId matches on both ends. To achieve this, we introduced a new LaneId type, HashedLaneId, which is calculated based on the following parameters:

  • Source: bridge_origin_universal_location (from the latest XCM)
  • Destination: bridge_destination_universal_location (from the latest XCM)
  • XCM version (both sides of the bridge must use the same parameters to generate an identical LaneId)

The core concept involves ordering the source and destination universal locations and then calculating a hash (H256). The universal location is a xcm::InteriorLocation that must start with GlobalConsensus(NetworkId). The source universal location is derived from the origin that calls the open_bridge extrinsic. This algorithm ensures the same LaneId on both sides of the bridge.

We introduced the new 32-byte H256 HashedLaneId for several reasons. First, the 4-byte [u8; 4] format could not reliably hold the new calculated hash without conflicts. Second, upgrading the Polkadot/Kusama BridgeHubs is asynchronous, making it difficult to migrate existing pallet-bridge-messages to the new HashedLaneId. Since LaneId is part of the message proofs, upgrading only Kusama BridgeHub to the new HashedLaneId would prevent the un-upgraded Polkadot BridgeHub from understanding incoming messages.

The solution is to deploy a new pallet-bridge-messages::<Instance2> dedicated to permissionless lanes using LaneId(H256), while retaining pallet-bridge-messages::<Instance1> with LaneId([u8; 4]) for AssetHubs. This approach also allows for the potential removal of Instance1 in the future, leaving only Instance2.

Deployment Plan

We need to deploy additional instances of the following pallets:

  • pallet-bridge-messages::<Instance2> (for syncing permissionless lane messages with HashedLaneId)
  • pallet-xcm-bridge-hub::<Instance2> (as a dedicated XCM exporter/dispatcher for these bridged messages)
  • pallet-bridge-relayers::<Instance2> (for registering relayers and collecting rewards)

We are considering two possible variants for this deployment.

Deployment on the BridgeHubs

  • Deploy the specified pallets on the BridgeHub.
  • Parachains (either sibling chains or AssetHub) can open a channel via XCM on both sides using Transact(pallet-xcm-bridge-hub::<Instance2>::Call::open_bridge(..)) -> which generates a lane_id.
  • A relayer needs to be set up to relay messages for the new lane_id.
  • AssetHub still needs to send HRMP messages with ExportXcm to the BridgeHub.
  • Other parachains also need to send HRMP messages with ExportXcm to the BridgeHub.

Pros:

  • Easier setup, as we only need to add new instances on the BridgeHubs.

Cons:

  • Still requires one extra hop (through the BridgeHub) for the AssetHub scenario.
  • BridgeHubs only recognize the native tokens (DOT or KSM), which can be used exclusively for rewards and delivery fees.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Deployment on the AssetHubs

  • Deploy the specified pallets on the AssetHub.
  • Parachains (sibling chains or AssetHub) can open a channel via XCM on both sides using Transact(pallet-xcm-bridge-hub::<Instance2>::Call::open_bridge(..)), which generates a lane_id.
  • A relayer needs to be set up to relay messages for the new lane_id.
  • AssetHub does not need to send HRMP messages; instead, it can directly execute ExportXcm, eliminating the extra hop.
  • Other parachains need to send HRMP messages with ExportXcm to the AssetHub, but this provides more options for paying fees.

Pros:

  • No extra hop needed for AssetHubs, allowing direct message export.
    • Lower bridge fees for the sender, since the extra hop is avoided.
  • "Any" asset can be used for delivery fees or rewards on the AssetHubs.

Cons:

  • We need to sync finality proofs (bridged header_hash and state_root) from the BridgeHub to the AssetHub, so pallet-bridge-messages::<Instance2> can verify received bridged messages.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Subscribe/Query/Sync Service for Finality Proofs

The basic idea is that the pallet-bridge-messages must validate received proofs from the bridged chain, which requires a verified/proven bridged_header_hash and state_root from finality pallets. However, we don’t want to deploy finality pallets everywhere.

Currently, this information is verified and stored in the pallet-bridge-parachains's ImportedParaHeads deployed on the BridgeHubs.

Essentially, we need a solution that propagates (makes available) this information (bridged_header_hash and state_root) to the (para)chain where we want to deploy pallet-bridge-messages.

This parachain could trigger a call on the BridgeHub's pallet-bridge-parachains to subscribe for new verified bridged data (bridged_header_hash and state_root). This data would then be made available to the parachain (e.g., the BridgeHub would send it via XCM using Transact(update_proofs(bridged_header_hash, state_root)), and the parachain would deploy a simple pallet to store this data).

For more possible solutions, see: GitHub Issue #5827.

Removing the Old pallet-bridge-messages::<Instance1>

Regardless of where pallet-bridge-messages::<Instance2> is deployed for permissionless lanes, we plan to remove the old instance and migrate everything to the new one. The goal is to end up with a single pallet-bridge-messages instance. Here are the steps to proceed:

  1. Open a permissionless lane for AssetHubs in the new instance, pallet-bridge-messages::<Instance2>, generating a new calculated LaneId(H256).
  2. Once the lane is created on both sides:
    • We will launch new relayers (or modify existing ones).
    • We will start changing XCM routing on AssetHubs to use the new pallet-xcm-bridge-hub::<Instance2> as the XCM exporter.
    • This ensures no more messages will be generated for the old pallet-bridge-messages::<Instance1>.
  3. Once the XCM routing is changed on both AssetHubs and there are no in-flight messages, we can disable dispatch or remove the old pallet-bridge-messages::<Instance1> from the BridgeHub.
  4. Lastly, we will migrate or transfer any remaining rewards from the old pallet-bridge-relayers::<Instance1>.
    • If all rewards have been claimed, we can safely remove it.