mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 01:41:03 +00:00
575b8f8d15
## Summary This pull request proposes a solution for improved control of the versioned XCM flow over the bridge (across different consensus chains) and resolves the situation where the sending chain/consensus has already migrated to a higher XCM version than the receiving chain/consensus. ## Problem/Motivation The current flow over the bridge involves a transfer from AssetHubRococo (AHR) to BridgeHubRococo (BHR) to BridgeHubWestend (BHW) and finally to AssetHubWestend (AHW), beginning with a reserve-backed transfer on AHR. In this process: 1. AHR sends XCM `ExportMessage` through `XcmpQueue`, incorporating XCM version checks using the `WrapVersion` feature, influenced by `pallet_xcm::SupportedVersion` (managed by `pallet_xcm::force_xcm_version` or version discovery). 2. BHR handles the `ExportMessage` instruction, utilizing the latest XCM version. The `HaulBlobExporter` converts the inner XCM to [`VersionedXcm::from`](https://github.com/paritytech/polkadot-sdk/blob/63ac2471aa0210f0ac9903bdd7d8f9351f9a635f/polkadot/xcm/xcm-builder/src/universal_exports.rs#L465-L467), also using the latest XCM version. However, challenges arise: - Incompatibility when BHW uses a different version than BHR. For instance, if BHR migrates to **XCMv4** while BHW remains on **XCMv3**, BHR's `VersionedXcm::from` uses `VersionedXcm::V4` variant, causing encoding issues for BHW. ``` /// Just a simulation of possible error, which could happen on BHW /// (this code is based on actual master without XCMv4) let encoded = hex_literal::hex!("0400"); println!("{:?}", VersionedXcm::<()>::decode(&mut &encoded[..])); Err(Error { cause: None, desc: "Could not decode `VersionedXcm`, variant doesn't exist" }) ``` - Similar compatibility issues exist between AHR and AHW. ## Solution This pull request introduces the following solutions: 1. **New trait `CheckVersion`** - added to the `xcm` module and exposing `pallet_xcm::SupportedVersion`. This enhancement allows checking the actual XCM version for desired destinations outside of the `pallet_xcm` module. 2. **Version Check in `HaulBlobExporter`** uses `CheckVersion` to check known/configured destination versions, ensuring compatibility. For example, in the scenario mentioned, BHR can store the version `3` for BHW. If BHR is on XCMv4, it will attempt to downgrade the message to version `3` instead of using the latest version `4`. 3. **Version Check in `pallet-xcm-bridge-hub-router`** - this check ensures compatibility with the real destination's XCM version, preventing the unnecessary sending of messages to the local bridge hub if versions are incompatible. These additions aim to improve the control and compatibility of XCM flows over the bridge and addressing issues related to version mismatches. ## Possible alternative solution _(More investigation is needed, and at the very least, it should extend to XCMv4/5. If this proves to be a viable option, I can open an RFC for XCM.)._ Add the `XcmVersion` attribute to the `ExportMessage` so that the sending chain can determine, based on what is stored in `pallet_xcm::SupportedVersion`, the version the destination is using. This way, we may not need to handle the version in `HaulBlobExporter`. ``` ExportMessage { network: NetworkId, destination: InteriorMultiLocation, xcm: Xcm<()> destination_xcm_version: Version, // <- new attritbute }, ``` ``` pub trait ExportXcm { fn validate( network: NetworkId, channel: u32, universal_source: &mut Option<InteriorMultiLocation>, destination: &mut Option<InteriorMultiLocation>, message: &mut Option<Xcm<()>>, destination_xcm_version: Version, , // <- new attritbute ) -> SendResult<Self::Ticket>; ``` ## Future Directions This PR does not fix version discovery over bridge, further investigation will be conducted here: https://github.com/paritytech/polkadot-sdk/issues/2417. ## TODO - [x] `pallet_xcm` mock for tests uses hard-coded XCM version `2` - change to 3 or lastest? - [x] fix `pallet-xcm-bridge-hub-router` - [x] fix HaulBlobExporter with version determination [here](https://github.com/paritytech/polkadot-sdk/blob/2183669d05f9b510f979a0cc3c7847707bacba2e/polkadot/xcm/xcm-builder/src/universal_exports.rs#L465) - [x] add unit-tests to the runtimes - [x] run benchmarks for `ExportMessage` - [x] extend local run scripts about `force_xcm_version(dest, version)` - [ ] when merged, prepare governance calls for Rococo/Westend - [ ] add PRDoc Part of: https://github.com/paritytech/parity-bridges-common/issues/2719 --------- Co-authored-by: command-bot <>
- Bridge-hub Parachains
- Requirements for local run/testing
- How to test local Rococo <-> Westend bridge
- Run Rococo/Westend chains with zombienet
- Init bridge and run relayer between BridgeHubRococo and BridgeHubWestend
- Initialize configuration for transfer asset over bridge (ROCs/WNDs)
- Send messages - transfer asset over bridge (ROCs/WNDs)
- Claim relayer's rewards on BridgeHubRococo and BridgeHubWestend
- How to test local BridgeHubKusama/BridgeHubPolkadot
Bridge-hub Parachains
BridgeHub(s) are system parachains that will house trustless bridges from the local ecosystem to others. The current trustless bridges planned for the BridgeHub(s) are:
BridgeHubPolkadotsystem parachain:- Polkadot <-> Kusama bridge
- Polkadot <-> Ethereum bridge (Snowbridge)
BridgeHubKusamasystem parachain:- Kusama <-> Polkadot bridge
- Kusama <-> Ethereum bridge The high-level responsibilities of each bridge living on BridgeHub:
- sync finality proofs between relay chains (or equivalent)
- sync finality proofs between BridgeHub parachains
- pass (XCM) messages between different BridgeHub parachains
Requirements for local run/testing
# Prepare empty directory for testing
mkdir -p ~/local_bridge_testing/bin
mkdir -p ~/local_bridge_testing/logs
---
# 1. Install zombienet
Go to: https://github.com/paritytech/zombienet/releases
Copy the apropriate binary (zombienet-linux) from the latest release to ~/local_bridge_testing/bin
---
# 2. Build polkadot binary
We need polkadot binary with "fast-runtime" feature:
cd <polkadot-sdk-git-repo-dir>
cargo build --release --features fast-runtime --bin polkadot
cp target/release/polkadot ~/local_bridge_testing/bin/polkadot
cargo build --release --features fast-runtime --bin polkadot-prepare-worker
cp target/release/polkadot-prepare-worker ~/local_bridge_testing/bin/polkadot-prepare-worker
cargo build --release --features fast-runtime --bin polkadot-execute-worker
cp target/release/polkadot-execute-worker ~/local_bridge_testing/bin/polkadot-execute-worker
---
# 3. Build substrate-relay binary
git clone https://github.com/paritytech/parity-bridges-common.git
cd parity-bridges-common
# checkout desired branch or use master:
# git checkout -b master --track origin/master
# `polkadot-staging` (recommended) is stabilized and compatible for Cumulus releases
# `master` is latest development
git checkout -b polkadot-staging --track origin/polkadot-staging
cargo build --release -p substrate-relay
cp target/release/substrate-relay ~/local_bridge_testing/bin/substrate-relay
---
# 4. Build cumulus polkadot-parachain binary
cd <polkadot-sdk-git-repo-dir>
cargo build --release -p polkadot-parachain-bin
cp target/release/polkadot-parachain ~/local_bridge_testing/bin/polkadot-parachain
cp target/release/polkadot-parachain ~/local_bridge_testing/bin/polkadot-parachain-asset-hub
How to test local Rococo <-> Westend bridge
Run Rococo/Westend chains with zombienet
cd <polkadot-sdk-git-repo-dir>
# Rococo + BridgeHubRococo + AssetHub for Rococo (mirroring Kusama)
POLKADOT_BINARY_PATH=~/local_bridge_testing/bin/polkadot \
POLKADOT_PARACHAIN_BINARY_PATH=~/local_bridge_testing/bin/polkadot-parachain \
POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_ROCOCO=~/local_bridge_testing/bin/polkadot-parachain-asset-hub \
~/local_bridge_testing/bin/zombienet-linux --provider native spawn ./cumulus/zombienet/bridge-hubs/bridge_hub_rococo_local_network.toml
cd <polkadot-sdk-git-repo-dir>
# Westend + BridgeHubWestend + AssetHub for Westend (mirroring Polkadot)
POLKADOT_BINARY_PATH=~/local_bridge_testing/bin/polkadot \
POLKADOT_PARACHAIN_BINARY_PATH=~/local_bridge_testing/bin/polkadot-parachain \
POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_WESTEND=~/local_bridge_testing/bin/polkadot-parachain-asset-hub \
~/local_bridge_testing/bin/zombienet-linux --provider native spawn ./cumulus/zombienet/bridge-hubs/bridge_hub_westend_local_network.toml
Init bridge and run relayer between BridgeHubRococo and BridgeHubWestend
Accounts of BridgeHub parachains:
Bobis pallet owner of all bridge pallets
Run with script
cd <polkadot-sdk-git-repo-dir>
./cumulus/scripts/bridges_rococo_westend.sh run-relay
Check relay-chain headers relaying:
- Rococo parachain: - https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A8943#/chainstate - Pallet: bridgeWestendGrandpa - Keys: bestFinalized()
- Westend parachain: - https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A8945#/chainstate - Pallet: bridgeRococoGrandpa - Keys: bestFinalized()
Check parachain headers relaying:
- Rococo parachain: - https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A8943#/chainstate - Pallet: bridgeWestendParachains - Keys: parasInfo(None)
- Westend parachain: - https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A8945#/chainstate - Pallet: bridgeRococoParachains - Keys: parasInfo(None)
Initialize configuration for transfer asset over bridge (ROCs/WNDs)
This initialization does several things:
- creates
ForeignAssetsfor wrappedROCs/wrappedWNDs - drips SA for AssetHubRococo on AssetHubWestend (and vice versa) which holds reserved assets on source chains
cd <polkadot-sdk-git-repo-dir>
./cumulus/scripts/bridges_rococo_westend.sh init-asset-hub-rococo-local
./cumulus/scripts/bridges_rococo_westend.sh init-bridge-hub-rococo-local
./cumulus/scripts/bridges_rococo_westend.sh init-asset-hub-westend-local
./cumulus/scripts/bridges_rococo_westend.sh init-bridge-hub-westend-local
Send messages - transfer asset over bridge (ROCs/WNDs)
Do reserve-backed transfers:
cd <polkadot-sdk-git-repo-dir>
# ROCs from Rococo's Asset Hub to Westend's.
./cumulus/scripts/bridges_rococo_westend.sh reserve-transfer-assets-from-asset-hub-rococo-local
cd <polkadot-sdk-git-repo-dir>
# WNDs from Westend's Asset Hub to Rococo's.
./cumulus/scripts/bridges_rococo_westend.sh reserve-transfer-assets-from-asset-hub-westend-local
- open explorers: (see zombienets)
- AssetHubRococo (see events
xcmpQueue.XcmpMessageSent,polkadotXcm.Attempted) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9910#/explorer - BridgeHubRococo (see
bridgeWestendMessages.MessageAccepted) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer - BridgeHubWestend (see
bridgeRococoMessages.MessagesReceived,xcmpQueue.XcmpMessageSent) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8945#/explorer - AssetHubWestend (see
foreignAssets.Issued,xcmpQueue.Success) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9010#/explorer - BridgeHubRocococ (see
bridgeWestendMessages.MessagesDelivered) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer
- AssetHubRococo (see events
Do reserve withdraw transfers: (when previous is finished)
cd <polkadot-sdk-git-repo-dir>
# wrappedWNDs from Rococo's Asset Hub to Westend's.
./cumulus/scripts/bridges_rococo_westend.sh withdraw-reserve-assets-from-asset-hub-rococo-local
cd <polkadot-sdk-git-repo-dir>
# wrappedROCs from Westend's Asset Hub to Rococo's.
./cumulus/scripts/bridges_rococo_westend.sh withdraw-reserve-assets-from-asset-hub-westend-local
Claim relayer's rewards on BridgeHubRococo and BridgeHubWestend
Accounts of BridgeHub parachains:
//Charlieis relayer account on BridgeHubRococo//Charlieis relayer account on BridgeHubWestend
cd <polkadot-sdk-git-repo-dir>
# Claim rewards on BridgeHubWestend:
./cumulus/scripts/bridges_rococo_westend.sh claim-rewards-bridge-hub-rococo-local
# Claim rewards on BridgeHubWestend:
./cumulus/scripts/bridges_rococo_westend.sh claim-rewards-bridge-hub-westend-local
- open explorers: (see zombienets)
- BridgeHubRococo (see 2x
bridgeRelayers.RewardPaid) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer - BridgeHubWestend (see 2x
bridgeRelayers.RewardPaid) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8945#/explorer
- BridgeHubRococo (see 2x
How to test local BridgeHubKusama/BridgeHubPolkadot
TODO: see # !!! READ HERE above
