mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 04:41:03 +00:00
cumulus: add asset-hub-rococo runtime based on asset-hub-kusama and add asset-bridging support to it (#1215)
This commit adds Rococo Asset Hub dedicated runtime so we can test new features here, before merging them in Kusama Asset Hub. Also adds one such feature: asset transfer over bridge (Rococo AssetHub <> Wococo AssetHub) - clone `asset-hub-kusama-runtime` -> `asset-hub-rococo-runtime` - make it use Rococo primitives, names, assets, constants, etc - add asset-transfer-over-bridge support to Rococo AssetHub <> Wococo AssetHub Fixes #1128 --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
- [Bridge-hub Parachains](#bridge-hub-parachains)
|
||||
- [Requirements for local run/testing](#requirements-for-local-runtesting)
|
||||
- [How to test local Rococo <-> Wococo bridge](#how-to-test-local-rococo---wococo-bridge)
|
||||
- [Run chains (Rococo + BridgeHub, Wococo + BridgeHub) with
|
||||
zombienet](#run-chains-rococo--bridgehub-wococo--bridgehub-with-zombienet)
|
||||
- [Run relayer (BridgeHubRococo, BridgeHubWococo)](#run-relayer-bridgehubrococo-bridgehubwococo)
|
||||
- [Run with script (alternative 1)](#run-with-script-alternative-1)
|
||||
- [Run with binary (alternative 2)](#run-with-binary-alternative-2)
|
||||
- [Send messages - transfer asset over bridge](#send-messages---transfer-asset-over-bridge)
|
||||
- [How to test live BridgeHubRococo/BridgeHubWococo](#how-to-test-live-bridgehubrococobridgehubwococo)
|
||||
- [Run Rococo/Wococo chains with zombienet](#run-rococowococo-chains-with-zombienet)
|
||||
- [Init bridge and run relayer between BridgeHubRococo and
|
||||
BridgeHubWococo](#init-bridge-and-run-relayer-between-bridgehubrococo-and-bridgehubwococo)
|
||||
- [Initialize configuration for transfer asset over bridge
|
||||
(ROCs/WOCs)](#initialize-configuration-for-transfer-asset-over-bridge-rocswocs)
|
||||
- [Send messages - transfer asset over bridge (ROCs/WOCs)](#send-messages---transfer-asset-over-bridge-rocswocs)
|
||||
- [Claim relayer's rewards on BridgeHubRococo and
|
||||
BridgeHubWococo](#claim-relayers-rewards-on-bridgehubrococo-and-bridgehubwococo)
|
||||
- [How to test local BridgeHubKusama/BridgeHubPolkadot](#how-to-test-local-bridgehubkusamabridgehubpolkadot)
|
||||
|
||||
# Bridge-hub Parachains
|
||||
@@ -42,17 +43,29 @@ Copy the apropriate binary (zombienet-linux) from the latest release to ~/local_
|
||||
|
||||
---
|
||||
# 2. Build polkadot binary
|
||||
git clone https://github.com/paritytech/polkadot.git
|
||||
cd polkadot
|
||||
|
||||
# if you want to test Kusama/Polkadot bridge, we need "sudo pallet + fast-runtime",
|
||||
# so please, find the latest polkadot's repository branch `it/release-vX.Y.Z-fast-sudo`
|
||||
# e.g:
|
||||
# git checkout -b it/release-v0.9.43-fast-sudo --track origin/it/release-v0.9.43-fast-sudo
|
||||
# If you want to test Kusama/Polkadot bridge, we need "sudo pallet + fast-runtime",
|
||||
# so we need to use sudofi in polkadot directory.
|
||||
#
|
||||
# Install sudofi: (skip if already installed)
|
||||
# cd <somewhere-outside-polkadot-sdk-git-repo-dir>
|
||||
# git clone https://github.com/paritytech/parachain-utils.git
|
||||
# cd parachain-utils # -> this is <parachain-utils-git-repo-dir>
|
||||
# cargo build --release --bin sudofi
|
||||
#
|
||||
# cd <polkadot-sdk-git-repo-dir>/polkadot
|
||||
# <parachain-utils-git-repo-dir>/target/release/sudofi
|
||||
|
||||
cargo build --release --features fast-runtime
|
||||
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
|
||||
@@ -71,124 +84,48 @@ cp target/release/substrate-relay ~/local_bridge_testing/bin/substrate-relay
|
||||
|
||||
---
|
||||
# 4. Build cumulus polkadot-parachain binary
|
||||
cd <cumulus-git-repo-dir>
|
||||
cd <polkadot-sdk-git-repo-dir>
|
||||
|
||||
# checkout desired branch or use master:
|
||||
# git checkout -b master --track origin/master
|
||||
|
||||
cargo build --release --locked --bin polkadot-parachain
|
||||
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
|
||||
|
||||
|
||||
|
||||
# !!! READ HERE (TODO remove once all mentioned branches bellow are merged)
|
||||
# The use case "moving assets over bridge" is not merged yet and is implemented in separate branches.
|
||||
# So, if you want to try it, you need to checkout different branch and continue with these instructions there.
|
||||
|
||||
# For Kusama/Polkadot local bridge testing:
|
||||
#
|
||||
# build BridgeHubs (polkadot-parachain) from branch:
|
||||
# git checkout -b bridge-hub-kusama-polkadot --track origin/bridge-hub-kusama-polkadot
|
||||
# cargo build --release --locked --bin polkadot-parachain
|
||||
# cp target/release/polkadot-parachain ~/local_bridge_testing/bin/polkadot-parachain
|
||||
#
|
||||
# build AssetHubs (polkadot-parachain-asset-hub) from branch:
|
||||
# git checkout -b bko-transfer-asset-via-bridge-pallet-xcm --track origin/bko-transfer-asset-via-bridge-pallet-xcm
|
||||
# cargo build --release --locked --bin polkadot-parachain
|
||||
# cp target/release/polkadot-parachain ~/local_bridge_testing/bin/polkadot-parachain-asset-hub
|
||||
|
||||
# For Rococo/Wococo local bridge testing:
|
||||
#
|
||||
# build AssetHubs (polkadot-parachain-asset-hub) from branch:
|
||||
# git checkout -b bko-transfer-asset-via-bridge-pallet-xcm-ro-wo --track origin/bko-transfer-asset-via-bridge-pallet-xcm-ro-wo
|
||||
# cargo build --release --locked --bin polkadot-parachain
|
||||
# cp target/release/polkadot-parachain ~/local_bridge_testing/bin/polkadot-parachain-asset-hub
|
||||
```
|
||||
|
||||
|
||||
## How to test local Rococo <-> Wococo bridge
|
||||
|
||||
### Run chains (Rococo + BridgeHub + AssetHub, Wococo + BridgeHub + AssetHub) with zombienet
|
||||
### Run Rococo/Wococo 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 ./zombienet/bridge-hubs/bridge_hub_rococo_local_network.toml
|
||||
~/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>
|
||||
|
||||
# Wococo + BridgeHubWococo + AssetHub for Wococo (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_WOCOCO=~/local_bridge_testing/bin/polkadot-parachain-asset-hub \
|
||||
~/local_bridge_testing/bin/zombienet-linux --provider native spawn ./zombienet/bridge-hubs/bridge_hub_wococo_local_network.toml
|
||||
~/local_bridge_testing/bin/zombienet-linux --provider native spawn ./cumulus/zombienet/bridge-hubs/bridge_hub_wococo_local_network.toml
|
||||
```
|
||||
|
||||
### Run relayer (BridgeHubRococo, BridgeHubWococo)
|
||||
### Init bridge and run relayer between BridgeHubRococo and BridgeHubWococo
|
||||
|
||||
**Accounts of BridgeHub parachains:**
|
||||
- `Bob` is pallet owner of all bridge pallets
|
||||
|
||||
#### Run with script (alternative 1)
|
||||
```
|
||||
cd <cumulus-git-repo-dir>
|
||||
./scripts/bridges_rococo_wococo.sh run-relay
|
||||
#### Run with script
|
||||
```
|
||||
cd <polkadot-sdk-git-repo-dir>
|
||||
|
||||
#### Run with binary (alternative 2)
|
||||
Need to wait for parachain activation (start producing blocks), then run:
|
||||
|
||||
```
|
||||
# 1. Init bridges:
|
||||
|
||||
# Rococo -> Wococo
|
||||
RUST_LOG=runtime=trace,rpc=trace,bridge=trace \
|
||||
~/local_bridge_testing/bin/substrate-relay init-bridge rococo-to-bridge-hub-wococo \
|
||||
--source-host localhost \
|
||||
--source-port 9942 \
|
||||
--source-version-mode Auto \
|
||||
--target-host localhost \
|
||||
--target-port 8945 \
|
||||
--target-version-mode Auto \
|
||||
--target-signer //Bob
|
||||
|
||||
# Wococo -> Rococo
|
||||
RUST_LOG=runtime=trace,rpc=trace,bridge=trace \
|
||||
~/local_bridge_testing/bin/substrate-relay init-bridge wococo-to-bridge-hub-rococo \
|
||||
--source-host localhost \
|
||||
--source-port 9945 \
|
||||
--source-version-mode Auto \
|
||||
--target-host localhost \
|
||||
--target-port 8943 \
|
||||
--target-version-mode Auto \
|
||||
--target-signer //Bob
|
||||
|
||||
# 2. Relay relay-chain headers, parachain headers and messages**
|
||||
RUST_LOG=runtime=trace,rpc=trace,bridge=trace \
|
||||
~/local_bridge_testing/bin/substrate-relay relay-headers-and-messages bridge-hub-rococo-bridge-hub-wococo \
|
||||
--rococo-host localhost \
|
||||
--rococo-port 9942 \
|
||||
--rococo-version-mode Auto \
|
||||
--bridge-hub-rococo-host localhost \
|
||||
--bridge-hub-rococo-port 8943 \
|
||||
--bridge-hub-rococo-version-mode Auto \
|
||||
--bridge-hub-rococo-signer //Charlie \
|
||||
--wococo-headers-to-bridge-hub-rococo-signer //Bob \
|
||||
--wococo-parachains-to-bridge-hub-rococo-signer //Bob \
|
||||
--bridge-hub-rococo-transactions-mortality 4 \
|
||||
--wococo-host localhost \
|
||||
--wococo-port 9945 \
|
||||
--wococo-version-mode Auto \
|
||||
--bridge-hub-wococo-host localhost \
|
||||
--bridge-hub-wococo-port 8945 \
|
||||
--bridge-hub-wococo-version-mode Auto \
|
||||
--bridge-hub-wococo-signer //Charlie \
|
||||
--rococo-headers-to-bridge-hub-wococo-signer //Bob \
|
||||
--rococo-parachains-to-bridge-hub-wococo-signer //Bob \
|
||||
--bridge-hub-wococo-transactions-mortality 4 \
|
||||
--lane 00000001
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh run-relay
|
||||
```
|
||||
|
||||
**Check relay-chain headers relaying:**
|
||||
@@ -199,34 +136,66 @@ RUST_LOG=runtime=trace,rpc=trace,bridge=trace \
|
||||
|
||||
**Check parachain headers relaying:**
|
||||
- Rococo parachain: - https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A8943#/chainstate - Pallet:
|
||||
**bridgeWococoParachain** - Keys: **bestParaHeads()**
|
||||
**bridgeWococoParachain** - Keys: **parasInfo(None)**
|
||||
- Wococo parachain: - https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A8945#/chainstate - Pallet:
|
||||
**bridgeRococoParachain** - Keys: **bestParaHeads()**
|
||||
**bridgeRococoParachain** - Keys: **parasInfo(None)**
|
||||
|
||||
### Send messages - transfer asset over bridge
|
||||
### Initialize configuration for transfer asset over bridge (ROCs/WOCs)
|
||||
|
||||
TODO: see `# !!! READ HERE` above
|
||||
This initialization does several things:
|
||||
- creates `ForeignAssets` for wrappedROCs/wrappedWOCs
|
||||
- drips SA for AssetHubRococo on AssetHubWococo (and vice versa) which holds reserved assets on source chains
|
||||
```
|
||||
cd <polkadot-sdk-git-repo-dir>
|
||||
|
||||
## How to test live BridgeHubRococo/BridgeHubWococo
|
||||
(here is still deployed older PoC from branch `origin/bko-transfer-asset-via-bridge`, which uses custom extrinsic, which
|
||||
is going to be replaced by `pallet_xcm` usage)
|
||||
- uses account seed on Live Rococo:Rockmine2
|
||||
```
|
||||
cd <cumulus-git-repo-dir>
|
||||
./scripts/bridges_rococo_wococo.sh transfer-asset-from-asset-hub-rococo
|
||||
```
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh init-asset-hub-rococo-local
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh init-bridge-hub-rococo-local
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh init-asset-hub-wococo-local
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh init-bridge-hub-wococo-local
|
||||
```
|
||||
|
||||
- open explorers: - Rockmine2 (see events `xcmpQueue.XcmpMessageSent`, `bridgeTransfer.ReserveAssetsDeposited`,
|
||||
`bridgeTransfer.TransferInitiated`)
|
||||
https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fws-rococo-rockmine2-collator-node-0.parity-testnet.parity.io#/explorer
|
||||
- BridgeHubRococo (see `bridgeWococoMessages.MessageAccepted`)
|
||||
https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-bridge-hub-rpc.polkadot.io#/explorer - BridgeHubWococo (see
|
||||
`bridgeRococoMessages.MessagesReceived`)
|
||||
https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fwococo-bridge-hub-rpc.polkadot.io#/explorer - Wockmint (see
|
||||
`xcmpQueue.Success` for `transfer-asset` and `xcmpQueue.Fail` for `ping-via-bridge`)
|
||||
https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fwococo-wockmint-rpc.polkadot.io#/explorer - BridgeHubRococo (see
|
||||
`bridgeWococoMessages.MessagesDelivered`)
|
||||
### Send messages - transfer asset over bridge (ROCs/WOCs)
|
||||
|
||||
Do (asset) transfers:
|
||||
```
|
||||
cd <polkadot-sdk-git-repo-dir>
|
||||
|
||||
# ROCs from Rococo's Asset Hub to Wococo's.
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh reserve-transfer-assets-from-asset-hub-rococo-local
|
||||
```
|
||||
```
|
||||
cd <polkadot-sdk-git-repo-dir>
|
||||
|
||||
# WOCs from Wococo's Asset Hub to Rococo's.
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh reserve-transfer-assets-from-asset-hub-wococo-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 `bridgeWococoMessages.MessageAccepted`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer
|
||||
- BridgeHubWococo (see `bridgeRococoMessages.MessagesReceived`, `xcmpQueue.XcmpMessageSent`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8945#/explorer
|
||||
- AssetHubWococo (see `foreignAssets.Issued`, `xcmpQueue.Success`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9010#/explorer
|
||||
- BridgeHubRocococ (see `bridgeWococoMessages.MessagesDelivered`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer
|
||||
|
||||
### Claim relayer's rewards on BridgeHubRococo and BridgeHubWococo
|
||||
|
||||
**Accounts of BridgeHub parachains:**
|
||||
- `//Charlie` is relayer account on BridgeHubRococo
|
||||
- `//Charlie` is relayer account on BridgeHubWococo
|
||||
|
||||
```
|
||||
cd <polkadot-sdk-git-repo-dir>
|
||||
|
||||
# Claim rewards on BridgeHubWococo:
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh claim-rewards-bridge-hub-rococo-local
|
||||
|
||||
# Claim rewards on BridgeHubWococo:
|
||||
./cumulus/scripts/bridges_rococo_wococo.sh claim-rewards-bridge-hub-wococo-local
|
||||
```
|
||||
|
||||
- open explorers: (see zombienets)
|
||||
- BridgeHubRococo (see 2x `bridgeRelayers.RewardPaid`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer
|
||||
- BridgeHubWococo (see 2x `bridgeRelayers.RewardPaid`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8945#/explorer
|
||||
|
||||
## How to test local BridgeHubKusama/BridgeHubPolkadot
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ pub type Barrier = TrailingSetTopicAsId<
|
||||
AllowKnownQueryResponses<PolkadotXcm>,
|
||||
WithComputedOrigin<
|
||||
(
|
||||
// If the message is one that immediately attemps to pay for execution, then
|
||||
// If the message is one that immediately attempts to pay for execution, then
|
||||
// allow it.
|
||||
AllowTopLevelPaidExecutionFrom<Everything>,
|
||||
// Parent and its pluralities (i.e. governance bodies) get free execution.
|
||||
|
||||
@@ -165,7 +165,7 @@ pub type Barrier = TrailingSetTopicAsId<
|
||||
AllowKnownQueryResponses<PolkadotXcm>,
|
||||
WithComputedOrigin<
|
||||
(
|
||||
// If the message is one that immediately attemps to pay for execution, then
|
||||
// If the message is one that immediately attempts to pay for execution, then
|
||||
// allow it.
|
||||
AllowTopLevelPaidExecutionFrom<Everything>,
|
||||
// Parent, its pluralities (i.e. governance bodies), and the Fellows plurality
|
||||
|
||||
@@ -65,7 +65,7 @@ cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-fea
|
||||
cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false, features = ["parameterized-consensus-hook",] }
|
||||
cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false}
|
||||
cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false }
|
||||
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false }
|
||||
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] }
|
||||
cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false }
|
||||
cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false }
|
||||
pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false }
|
||||
@@ -73,6 +73,8 @@ parachain-info = { path = "../../../pallets/parachain-info", default-features =
|
||||
parachains-common = { path = "../../../common", default-features = false }
|
||||
|
||||
# Bridges
|
||||
bp-asset-hub-rococo = { path = "../../../../../bridges/primitives/chain-asset-hub-rococo", default-features = false }
|
||||
bp-asset-hub-wococo = { path = "../../../../../bridges/primitives/chain-asset-hub-wococo", default-features = false }
|
||||
bp-bridge-hub-rococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-rococo", default-features = false }
|
||||
bp-bridge-hub-wococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-wococo", default-features = false }
|
||||
bp-header-chain = { path = "../../../../../bridges/primitives/header-chain", default-features = false }
|
||||
@@ -98,6 +100,8 @@ sp-keyring = { path = "../../../../../substrate/primitives/keyring" }
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
std = [
|
||||
"bp-asset-hub-rococo/std",
|
||||
"bp-asset-hub-wococo/std",
|
||||
"bp-bridge-hub-rococo/std",
|
||||
"bp-bridge-hub-wococo/std",
|
||||
"bp-header-chain/std",
|
||||
|
||||
+58
-5
@@ -33,6 +33,7 @@ use bridge_runtime_common::{
|
||||
RefundableMessagesLane, RefundableParachain,
|
||||
},
|
||||
};
|
||||
use codec::Encode;
|
||||
use frame_support::{parameter_types, traits::PalletInfoAccess};
|
||||
use sp_runtime::RuntimeDebug;
|
||||
use xcm::{
|
||||
@@ -51,12 +52,38 @@ parameter_types! {
|
||||
pub BridgeHubRococoUniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Rococo), Parachain(ParachainInfo::parachain_id().into()));
|
||||
pub WococoGlobalConsensusNetwork: NetworkId = NetworkId::Wococo;
|
||||
pub ActiveOutboundLanesToBridgeHubWococo: &'static [bp_messages::LaneId] = &[DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO];
|
||||
pub PriorityBoostPerMessage: u64 = 921_900_294;
|
||||
// see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value
|
||||
pub PriorityBoostPerMessage: u64 = 182_044_444_444_444;
|
||||
|
||||
pub AssetHubRococoParaId: cumulus_primitives_core::ParaId = bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID.into();
|
||||
|
||||
pub FromAssetHubRococoToAssetHubWococoRoute: SenderAndLane = SenderAndLane::new(
|
||||
ParentThen(X1(Parachain(1000))).into(),
|
||||
ParentThen(X1(Parachain(AssetHubRococoParaId::get().into()))).into(),
|
||||
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
|
||||
);
|
||||
|
||||
pub CongestedMessage: Xcm<()> = build_congestion_message(true).into();
|
||||
|
||||
pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into();
|
||||
}
|
||||
|
||||
fn build_congestion_message<Call>(is_congested: bool) -> sp_std::vec::Vec<Instruction<Call>> {
|
||||
sp_std::vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
Transact {
|
||||
origin_kind: OriginKind::Xcm,
|
||||
require_weight_at_most:
|
||||
bp_asset_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(),
|
||||
call: bp_asset_hub_rococo::Call::ToWococoXcmRouter(
|
||||
bp_asset_hub_rococo::XcmBridgeHubRouterCall::report_bridge_status {
|
||||
bridge_id: Default::default(),
|
||||
is_congested,
|
||||
}
|
||||
)
|
||||
.encode()
|
||||
.into(),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/// Proof of messages, coming from Wococo.
|
||||
@@ -73,7 +100,7 @@ pub type OnBridgeHubRococoBlobDispatcher = BridgeBlobDispatcher<
|
||||
BridgeWococoMessagesPalletInstance,
|
||||
>;
|
||||
|
||||
/// Export XCM messages to be relayed to the otherside
|
||||
/// Export XCM messages to be relayed to the other side
|
||||
pub type ToBridgeHubWococoHaulBlobExporter = HaulBlobExporter<
|
||||
XcmBlobHaulerAdapter<ToBridgeHubWococoXcmBlobHauler>,
|
||||
WococoGlobalConsensusNetwork,
|
||||
@@ -86,11 +113,14 @@ impl XcmBlobHauler for ToBridgeHubWococoXcmBlobHauler {
|
||||
type SenderAndLane = FromAssetHubRococoToAssetHubWococoRoute;
|
||||
|
||||
type ToSourceChainSender = crate::XcmRouter;
|
||||
type CongestedMessage = ();
|
||||
type UncongestedMessage = ();
|
||||
type CongestedMessage = CongestedMessage;
|
||||
type UncongestedMessage = UncongestedMessage;
|
||||
}
|
||||
pub const DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO: LaneId = LaneId([0, 0, 0, 1]);
|
||||
|
||||
/// On messages delivered callback.
|
||||
pub type OnMessagesDelivered = XcmBlobHaulerAdapter<ToBridgeHubWococoXcmBlobHauler>;
|
||||
|
||||
/// Messaging Bridge configuration for BridgeHubRococo -> BridgeHubWococo
|
||||
pub struct WithBridgeHubWococoMessageBridge;
|
||||
impl MessageBridge for WithBridgeHubWococoMessageBridge {
|
||||
@@ -164,6 +194,18 @@ mod tests {
|
||||
AssertCompleteBridgeConstants,
|
||||
},
|
||||
};
|
||||
use parachains_common::{rococo, Balance};
|
||||
|
||||
/// Every additional message in the message delivery transaction boosts its priority.
|
||||
/// So the priority of transaction with `N+1` messages is larger than priority of
|
||||
/// transaction with `N` messages by the `PriorityBoostPerMessage`.
|
||||
///
|
||||
/// Economically, it is an equivalent of adding tip to the transaction with `N` messages.
|
||||
/// The `FEE_BOOST_PER_MESSAGE` constant is the value of this tip.
|
||||
///
|
||||
/// We want this tip to be large enough (delivery transactions with more messages = less
|
||||
/// operational costs and a faster bridge), so this value should be significant.
|
||||
const FEE_BOOST_PER_MESSAGE: Balance = 2 * rococo::currency::UNITS;
|
||||
|
||||
#[test]
|
||||
fn ensure_bridge_hub_rococo_message_lane_weights_are_correct() {
|
||||
@@ -215,5 +257,16 @@ mod tests {
|
||||
bp_bridge_hub_wococo::WITH_BRIDGE_HUB_WOCOCO_MESSAGES_PALLET_NAME,
|
||||
},
|
||||
});
|
||||
|
||||
bridge_runtime_common::priority_calculator::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
WithBridgeHubWococoMessagesInstance,
|
||||
PriorityBoostPerMessage,
|
||||
>(FEE_BOOST_PER_MESSAGE);
|
||||
|
||||
assert_eq!(
|
||||
BridgeWococoMessagesPalletInstance::get(),
|
||||
X1(PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_WOCOCO_MESSAGES_PALLET_INDEX))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+59
-6
@@ -33,6 +33,7 @@ use bridge_runtime_common::{
|
||||
RefundableMessagesLane, RefundableParachain,
|
||||
},
|
||||
};
|
||||
use codec::Encode;
|
||||
use frame_support::{parameter_types, traits::PalletInfoAccess};
|
||||
use sp_runtime::RuntimeDebug;
|
||||
use xcm::{
|
||||
@@ -51,18 +52,44 @@ parameter_types! {
|
||||
pub BridgeRococoMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(<BridgeRococoMessages as PalletInfoAccess>::index() as u8));
|
||||
pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo;
|
||||
pub ActiveOutboundLanesToBridgeHubRococo: &'static [bp_messages::LaneId] = &[DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO];
|
||||
pub PriorityBoostPerMessage: u64 = 921_900_294;
|
||||
// see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value
|
||||
pub PriorityBoostPerMessage: u64 = 182_044_444_444_444;
|
||||
|
||||
pub AssetHubWococoParaId: cumulus_primitives_core::ParaId = bp_asset_hub_wococo::ASSET_HUB_WOCOCO_PARACHAIN_ID.into();
|
||||
|
||||
pub FromAssetHubWococoToAssetHubRococoRoute: SenderAndLane = SenderAndLane::new(
|
||||
ParentThen(X1(Parachain(1000))).into(),
|
||||
ParentThen(X1(Parachain(AssetHubWococoParaId::get().into()))).into(),
|
||||
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
|
||||
);
|
||||
|
||||
pub CongestedMessage: Xcm<()> = build_congestion_message(true).into();
|
||||
|
||||
pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into();
|
||||
}
|
||||
|
||||
fn build_congestion_message<Call>(is_congested: bool) -> sp_std::vec::Vec<Instruction<Call>> {
|
||||
sp_std::vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
Transact {
|
||||
origin_kind: OriginKind::Xcm,
|
||||
require_weight_at_most:
|
||||
bp_asset_hub_wococo::XcmBridgeHubRouterTransactCallMaxWeight::get(),
|
||||
call: bp_asset_hub_wococo::Call::ToRococoXcmRouter(
|
||||
bp_asset_hub_wococo::XcmBridgeHubRouterCall::report_bridge_status {
|
||||
bridge_id: Default::default(),
|
||||
is_congested,
|
||||
}
|
||||
)
|
||||
.encode()
|
||||
.into(),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/// Proof of messages, coming from Rococo.
|
||||
pub type FromRococoBridgeHubMessagesProof =
|
||||
FromBridgedChainMessagesProof<bp_bridge_hub_rococo::Hash>;
|
||||
/// Messages delivery proof for Rococo Bridge Hub -> Wococo Bridge Hub messages.
|
||||
/// Messages delivery proof for RococoBridge Hub -> Wococo BridgeHub messages.
|
||||
pub type ToRococoBridgeHubMessagesDeliveryProof =
|
||||
FromBridgedChainMessagesDeliveryProof<bp_bridge_hub_rococo::Hash>;
|
||||
|
||||
@@ -73,7 +100,7 @@ pub type OnBridgeHubWococoBlobDispatcher = BridgeBlobDispatcher<
|
||||
BridgeRococoMessagesPalletInstance,
|
||||
>;
|
||||
|
||||
/// Export XCM messages to be relayed to the otherside
|
||||
/// Export XCM messages to be relayed to the other side
|
||||
pub type ToBridgeHubRococoHaulBlobExporter = HaulBlobExporter<
|
||||
XcmBlobHaulerAdapter<ToBridgeHubRococoXcmBlobHauler>,
|
||||
RococoGlobalConsensusNetwork,
|
||||
@@ -86,11 +113,14 @@ impl XcmBlobHauler for ToBridgeHubRococoXcmBlobHauler {
|
||||
type SenderAndLane = FromAssetHubWococoToAssetHubRococoRoute;
|
||||
|
||||
type ToSourceChainSender = crate::XcmRouter;
|
||||
type CongestedMessage = ();
|
||||
type UncongestedMessage = ();
|
||||
type CongestedMessage = CongestedMessage;
|
||||
type UncongestedMessage = UncongestedMessage;
|
||||
}
|
||||
pub const DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO: LaneId = LaneId([0, 0, 0, 1]);
|
||||
|
||||
/// On messages delivered callback.
|
||||
pub type OnMessagesDelivered = XcmBlobHaulerAdapter<ToBridgeHubRococoXcmBlobHauler>;
|
||||
|
||||
/// Messaging Bridge configuration for BridgeHubWococo -> BridgeHubRococo
|
||||
pub struct WithBridgeHubRococoMessageBridge;
|
||||
impl MessageBridge for WithBridgeHubRococoMessageBridge {
|
||||
@@ -164,6 +194,18 @@ mod tests {
|
||||
AssertCompleteBridgeConstants,
|
||||
},
|
||||
};
|
||||
use parachains_common::{wococo, Balance};
|
||||
|
||||
/// Every additional message in the message delivery transaction boosts its priority.
|
||||
/// So the priority of transaction with `N+1` messages is larger than priority of
|
||||
/// transaction with `N` messages by the `PriorityBoostPerMessage`.
|
||||
///
|
||||
/// Economically, it is an equivalent of adding tip to the transaction with `N` messages.
|
||||
/// The `FEE_BOOST_PER_MESSAGE` constant is the value of this tip.
|
||||
///
|
||||
/// We want this tip to be large enough (delivery transactions with more messages = less
|
||||
/// operational costs and a faster bridge), so this value should be significant.
|
||||
const FEE_BOOST_PER_MESSAGE: Balance = 2 * wococo::currency::UNITS;
|
||||
|
||||
#[test]
|
||||
fn ensure_bridge_hub_wococo_message_lane_weights_are_correct() {
|
||||
@@ -215,5 +257,16 @@ mod tests {
|
||||
bp_bridge_hub_rococo::WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME,
|
||||
},
|
||||
});
|
||||
|
||||
bridge_runtime_common::priority_calculator::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
WithBridgeHubRococoMessagesInstance,
|
||||
PriorityBoostPerMessage,
|
||||
>(FEE_BOOST_PER_MESSAGE);
|
||||
|
||||
assert_eq!(
|
||||
BridgeRococoMessagesPalletInstance::get(),
|
||||
X1(PalletInstance(bp_bridge_hub_wococo::WITH_BRIDGE_ROCOCO_MESSAGES_PALLET_INDEX))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! # Bridge Hub Rococo Runtime
|
||||
//!
|
||||
//! This runtime is also used for Bridge Hub Wococo. But we dont want to create another exact copy
|
||||
//! of Bridge Hub Rococo, so we injected some tweaks backed by `RuntimeFlavor` and `pub storage
|
||||
//! Flavor: RuntimeFlavor`. (For example this is needed for successful asset transfer between Asset
|
||||
//! Hub Rococo and Asset Hub Wococo, where we need to have correct `xcm_config::UniversalLocation`
|
||||
//! with correct `GlobalConsensus`.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
|
||||
#![recursion_limit = "256"]
|
||||
@@ -27,6 +35,7 @@ pub mod bridge_hub_wococo_config;
|
||||
mod weights;
|
||||
pub mod xcm_config;
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
|
||||
use sp_api::impl_runtime_apis;
|
||||
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
|
||||
@@ -92,6 +101,15 @@ use parachains_common::{
|
||||
};
|
||||
use xcm_executor::XcmExecutor;
|
||||
|
||||
/// Enum for handling differences in the runtime configuration for BridgeHubRococo vs
|
||||
/// BridgeHubWococo.
|
||||
#[derive(Default, Eq, PartialEq, Debug, Clone, Copy, Decode, Encode)]
|
||||
pub enum RuntimeFlavor {
|
||||
#[default]
|
||||
Rococo,
|
||||
Wococo,
|
||||
}
|
||||
|
||||
/// The address format for describing accounts.
|
||||
pub type Address = MultiAddress<AccountId, ()>;
|
||||
|
||||
@@ -473,7 +491,7 @@ parameter_types! {
|
||||
pub const RelayerStakeReserveId: [u8; 8] = *b"brdgrlrs";
|
||||
}
|
||||
|
||||
/// Add parachain bridge pallet to track Wococo bridge hub parachain
|
||||
/// Add parachain bridge pallet to track Wococo BridgeHub parachain
|
||||
pub type BridgeParachainWococoInstance = pallet_bridge_parachains::Instance1;
|
||||
impl pallet_bridge_parachains::Config<BridgeParachainWococoInstance> for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
@@ -486,7 +504,7 @@ impl pallet_bridge_parachains::Config<BridgeParachainWococoInstance> for Runtime
|
||||
type MaxParaHeadDataSize = MaxWococoParaHeadDataSize;
|
||||
}
|
||||
|
||||
/// Add parachain bridge pallet to track Rococo bridge hub parachain
|
||||
/// Add parachain bridge pallet to track Rococo BridgeHub parachain
|
||||
pub type BridgeParachainRococoInstance = pallet_bridge_parachains::Instance2;
|
||||
impl pallet_bridge_parachains::Config<BridgeParachainRococoInstance> for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
@@ -528,9 +546,15 @@ impl pallet_bridge_messages::Config<WithBridgeHubWococoMessagesInstance> for Run
|
||||
>;
|
||||
|
||||
type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubWococoMessageBridge>;
|
||||
type MessageDispatch =
|
||||
XcmBlobMessageDispatch<OnBridgeHubRococoBlobDispatcher, Self::WeightInfo, ()>;
|
||||
type OnMessagesDelivered = ();
|
||||
type MessageDispatch = XcmBlobMessageDispatch<
|
||||
OnBridgeHubRococoBlobDispatcher,
|
||||
Self::WeightInfo,
|
||||
cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider<
|
||||
bridge_hub_rococo_config::AssetHubRococoParaId,
|
||||
Runtime,
|
||||
>,
|
||||
>;
|
||||
type OnMessagesDelivered = bridge_hub_rococo_config::OnMessagesDelivered;
|
||||
}
|
||||
|
||||
/// Add XCM messages support for BridgeHubWococo to support Wococo->Rococo XCM messages
|
||||
@@ -562,9 +586,15 @@ impl pallet_bridge_messages::Config<WithBridgeHubRococoMessagesInstance> for Run
|
||||
>;
|
||||
|
||||
type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubRococoMessageBridge>;
|
||||
type MessageDispatch =
|
||||
XcmBlobMessageDispatch<OnBridgeHubWococoBlobDispatcher, Self::WeightInfo, ()>;
|
||||
type OnMessagesDelivered = ();
|
||||
type MessageDispatch = XcmBlobMessageDispatch<
|
||||
OnBridgeHubWococoBlobDispatcher,
|
||||
Self::WeightInfo,
|
||||
cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider<
|
||||
bridge_hub_wococo_config::AssetHubWococoParaId,
|
||||
Runtime,
|
||||
>,
|
||||
>;
|
||||
type OnMessagesDelivered = bridge_hub_wococo_config::OnMessagesDelivered;
|
||||
}
|
||||
|
||||
/// Allows collect and claim rewards for relayers
|
||||
@@ -617,16 +647,16 @@ construct_runtime!(
|
||||
Utility: pallet_utility::{Pallet, Call, Event} = 40,
|
||||
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 36,
|
||||
|
||||
// Rococo and Wococo Bridge Hubs are sharing the runtime, so this runtime has two sets of
|
||||
// Rococo and Wococo BridgeHubs are sharing the runtime, so this runtime has two sets of
|
||||
// bridge pallets. Both are deployed at both runtimes, but only one set is actually used
|
||||
// at particular runtime.
|
||||
|
||||
// With-Wococo bridge modules that are active (used) at Rococo Bridge Hub runtime.
|
||||
// With-Wococo bridge modules that are active (used) at Rococo BridgeHub runtime.
|
||||
BridgeWococoGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 41,
|
||||
BridgeWococoParachain: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage, Event<T>} = 42,
|
||||
BridgeWococoMessages: pallet_bridge_messages::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 46,
|
||||
|
||||
// With-Rococo bridge modules that are active (used) at Wococo Bridge Hub runtime.
|
||||
// With-Rococo bridge modules that are active (used) at Wococo BridgeHub runtime.
|
||||
BridgeRococoGrandpa: pallet_bridge_grandpa::<Instance2>::{Pallet, Call, Storage, Event<T>, Config<T>} = 43,
|
||||
BridgeRococoParachain: pallet_bridge_parachains::<Instance2>::{Pallet, Call, Storage, Event<T>} = 44,
|
||||
BridgeRococoMessages: pallet_bridge_messages::<Instance2>::{Pallet, Call, Storage, Event<T>, Config<T>} = 45,
|
||||
@@ -982,19 +1012,19 @@ impl_runtime_apis! {
|
||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_config::RelayLocation;
|
||||
use xcm_config::TokenLocation;
|
||||
|
||||
impl pallet_xcm_benchmarks::Config for Runtime {
|
||||
type XcmConfig = xcm_config::XcmConfig;
|
||||
type AccountIdConverter = xcm_config::LocationToAccountId;
|
||||
fn valid_destination() -> Result<MultiLocation, BenchmarkError> {
|
||||
Ok(RelayLocation::get())
|
||||
Ok(TokenLocation::get())
|
||||
}
|
||||
fn worst_case_holding(_depositable_count: u32) -> MultiAssets {
|
||||
// just concrete assets according to relay chain.
|
||||
let assets: Vec<MultiAsset> = vec![
|
||||
MultiAsset {
|
||||
id: Concrete(RelayLocation::get()),
|
||||
id: Concrete(TokenLocation::get()),
|
||||
fun: Fungible(1_000_000 * UNITS),
|
||||
}
|
||||
];
|
||||
@@ -1004,8 +1034,8 @@ impl_runtime_apis! {
|
||||
|
||||
parameter_types! {
|
||||
pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some((
|
||||
RelayLocation::get(),
|
||||
MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) },
|
||||
TokenLocation::get(),
|
||||
MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) },
|
||||
));
|
||||
pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
|
||||
pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None;
|
||||
@@ -1020,7 +1050,7 @@ impl_runtime_apis! {
|
||||
|
||||
fn get_multi_asset() -> MultiAsset {
|
||||
MultiAsset {
|
||||
id: Concrete(RelayLocation::get()),
|
||||
id: Concrete(TokenLocation::get()),
|
||||
fun: Fungible(UNITS),
|
||||
}
|
||||
}
|
||||
@@ -1042,16 +1072,16 @@ impl_runtime_apis! {
|
||||
}
|
||||
|
||||
fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> {
|
||||
Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
|
||||
Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into()))
|
||||
}
|
||||
|
||||
fn subscribe_origin() -> Result<MultiLocation, BenchmarkError> {
|
||||
Ok(RelayLocation::get())
|
||||
Ok(TokenLocation::get())
|
||||
}
|
||||
|
||||
fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> {
|
||||
let origin = RelayLocation::get();
|
||||
let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into();
|
||||
let origin = TokenLocation::get();
|
||||
let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into();
|
||||
let ticket = MultiLocation { parents: 0, interior: Here };
|
||||
Ok((origin, ticket, assets))
|
||||
}
|
||||
@@ -1062,7 +1092,7 @@ impl_runtime_apis! {
|
||||
|
||||
fn export_message_origin_and_destination(
|
||||
) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> {
|
||||
Ok((RelayLocation::get(), NetworkId::Wococo, X1(Parachain(100))))
|
||||
Ok((TokenLocation::get(), NetworkId::Wococo, X1(Parachain(100))))
|
||||
}
|
||||
|
||||
fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> {
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
use super::{
|
||||
AccountId, AllPalletsWithSystem, Balances, BridgeGrandpaRococoInstance,
|
||||
BridgeGrandpaWococoInstance, DeliveryRewardInBalance, ParachainInfo, ParachainSystem,
|
||||
PolkadotXcm, RequiredStakeForStakeAndSlash, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
|
||||
WeightToFee, XcmpQueue,
|
||||
PolkadotXcm, RequiredStakeForStakeAndSlash, Runtime, RuntimeCall, RuntimeEvent, RuntimeFlavor,
|
||||
RuntimeOrigin, WeightToFee, XcmpQueue,
|
||||
};
|
||||
use crate::{
|
||||
bridge_hub_rococo_config::ToBridgeHubWococoHaulBlobExporter,
|
||||
@@ -36,12 +36,11 @@ use sp_core::Get;
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_builder::{
|
||||
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
|
||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
|
||||
CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, IsConcrete,
|
||||
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
|
||||
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
|
||||
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
|
||||
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
|
||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter,
|
||||
DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, IsConcrete, ParentAsSuperuser,
|
||||
ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
|
||||
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
|
||||
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
|
||||
};
|
||||
use xcm_executor::{
|
||||
traits::{ExportXcm, WithOriginFilter},
|
||||
@@ -49,7 +48,8 @@ use xcm_executor::{
|
||||
};
|
||||
|
||||
parameter_types! {
|
||||
pub const RelayLocation: MultiLocation = MultiLocation::parent();
|
||||
pub storage Flavor: RuntimeFlavor = RuntimeFlavor::default();
|
||||
pub const TokenLocation: MultiLocation = MultiLocation::parent();
|
||||
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||
pub UniversalLocation: InteriorMultiLocation =
|
||||
X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into()));
|
||||
@@ -57,6 +57,7 @@ parameter_types! {
|
||||
pub const MaxAssetsIntoHolding: u32 = 64;
|
||||
}
|
||||
|
||||
/// Adapter for resolving `NetworkId` based on `pub storage Flavor: RuntimeFlavor`.
|
||||
pub struct RelayNetwork;
|
||||
impl Get<Option<NetworkId>> for RelayNetwork {
|
||||
fn get() -> Option<NetworkId> {
|
||||
@@ -65,10 +66,9 @@ impl Get<Option<NetworkId>> for RelayNetwork {
|
||||
}
|
||||
impl Get<NetworkId> for RelayNetwork {
|
||||
fn get() -> NetworkId {
|
||||
match u32::from(ParachainInfo::parachain_id()) {
|
||||
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID => NetworkId::Rococo,
|
||||
bp_bridge_hub_wococo::BRIDGE_HUB_WOCOCO_PARACHAIN_ID => NetworkId::Wococo,
|
||||
para_id => unreachable!("Not supported for para_id: {}", para_id),
|
||||
match Flavor::get() {
|
||||
RuntimeFlavor::Rococo => NetworkId::Rococo,
|
||||
RuntimeFlavor::Wococo => NetworkId::Wococo,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ pub type CurrencyTransactor = CurrencyAdapter<
|
||||
// Use this currency:
|
||||
Balances,
|
||||
// Use this currency when it is a fungible asset matching the given location or name:
|
||||
IsConcrete<RelayLocation>,
|
||||
IsConcrete<TokenLocation>,
|
||||
// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
|
||||
LocationToAccountId,
|
||||
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||
@@ -154,9 +154,10 @@ impl Contains<RuntimeCall> for SafeCallFilter {
|
||||
// Allow to change dedicated storage items (called by governance-like)
|
||||
match call {
|
||||
RuntimeCall::System(frame_system::Call::set_storage { items })
|
||||
if items.iter().any(|(k, _)| {
|
||||
if items.iter().all(|(k, _)| {
|
||||
k.eq(&DeliveryRewardInBalance::key()) |
|
||||
k.eq(&RequiredStakeForStakeAndSlash::key())
|
||||
k.eq(&RequiredStakeForStakeAndSlash::key()) |
|
||||
k.eq(&Flavor::key())
|
||||
}) =>
|
||||
return true,
|
||||
_ => (),
|
||||
@@ -206,7 +207,7 @@ pub type Barrier = TrailingSetTopicAsId<
|
||||
AllowKnownQueryResponses<PolkadotXcm>,
|
||||
WithComputedOrigin<
|
||||
(
|
||||
// If the message is one that immediately attemps to pay for execution, then
|
||||
// If the message is one that immediately attempts to pay for execution, then
|
||||
// allow it.
|
||||
AllowTopLevelPaidExecutionFrom<Everything>,
|
||||
// Parent and its pluralities (i.e. governance bodies) get free execution.
|
||||
@@ -217,16 +218,13 @@ pub type Barrier = TrailingSetTopicAsId<
|
||||
UniversalLocation,
|
||||
ConstU32<8>,
|
||||
>,
|
||||
// TODO:check-parameter - (https://github.com/paritytech/parity-bridges-common/issues/2084)
|
||||
// remove this and extend `AllowExplicitUnpaidExecutionFrom` with "or SystemParachains" once merged https://github.com/paritytech/polkadot/pull/7005
|
||||
AllowUnpaidExecutionFrom<Everything>,
|
||||
),
|
||||
>,
|
||||
>;
|
||||
|
||||
/// Cases where a remote origin is accepted as trusted Teleporter for a given asset:
|
||||
/// - NativeToken with the parent Relay Chain and sibling parachains.
|
||||
pub type TrustedTeleporters = ConcreteAssetFromSystem<RelayLocation>;
|
||||
pub type TrustedTeleporters = ConcreteAssetFromSystem<TokenLocation>;
|
||||
|
||||
pub struct XcmConfig;
|
||||
impl xcm_executor::Config for XcmConfig {
|
||||
@@ -246,7 +244,7 @@ impl xcm_executor::Config for XcmConfig {
|
||||
MaxInstructions,
|
||||
>;
|
||||
type Trader =
|
||||
UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ToStakingPot<Runtime>>;
|
||||
UsingComponents<WeightToFee, TokenLocation, AccountId, Balances, ToStakingPot<Runtime>>;
|
||||
type ResponseHandler = PolkadotXcm;
|
||||
type AssetTrap = PolkadotXcm;
|
||||
type AssetLocker = ();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use bp_polkadot_core::Signature;
|
||||
use bridge_hub_rococo_runtime::{
|
||||
bridge_hub_rococo_config, bridge_hub_wococo_config,
|
||||
xcm_config::{RelayNetwork, XcmConfig},
|
||||
xcm_config::{RelayNetwork, TokenLocation, XcmConfig},
|
||||
AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, DeliveryRewardInBalance,
|
||||
Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, RequiredStakeForStakeAndSlash,
|
||||
Runtime, RuntimeCall, RuntimeEvent, SessionKeys, SignedExtra, UncheckedExtrinsic,
|
||||
@@ -35,7 +35,7 @@ use sp_runtime::{
|
||||
};
|
||||
use xcm::latest::prelude::*;
|
||||
|
||||
// Para id of sibling chain (Rockmine/Wockmint) used in tests.
|
||||
// Para id of sibling chain used in tests.
|
||||
pub const SIBLING_PARACHAIN_ID: u32 = 1000;
|
||||
|
||||
parameter_types! {
|
||||
@@ -55,7 +55,7 @@ fn construct_extrinsic(
|
||||
frame_system::CheckNonce::<Runtime>::from(0),
|
||||
frame_system::CheckWeight::<Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
|
||||
BridgeRejectObsoleteHeadersAndMessages {},
|
||||
BridgeRejectObsoleteHeadersAndMessages::default(),
|
||||
(
|
||||
bridge_hub_wococo_config::BridgeRefundBridgeHubRococoMessages::default(),
|
||||
bridge_hub_rococo_config::BridgeRefundBridgeHubWococoMessages::default(),
|
||||
@@ -191,7 +191,11 @@ mod bridge_hub_rococo_tests {
|
||||
}
|
||||
}),
|
||||
|| ExportMessage { network: Wococo, destination: X1(Parachain(1234)), xcm: Xcm(vec![]) },
|
||||
bridge_hub_rococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO
|
||||
bridge_hub_rococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
|
||||
Some((TokenLocation::get(), ExistentialDeposit::get()).into()),
|
||||
// value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer`
|
||||
Some((TokenLocation::get(), bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs::get()).into()),
|
||||
|| (),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -222,6 +226,7 @@ mod bridge_hub_rococo_tests {
|
||||
}
|
||||
}),
|
||||
bridge_hub_rococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
|
||||
|| (),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -243,6 +248,7 @@ mod bridge_hub_rococo_tests {
|
||||
SIBLING_PARACHAIN_ID,
|
||||
Rococo,
|
||||
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_WOCOCO,
|
||||
|| (),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -268,6 +274,25 @@ mod bridge_hub_rococo_tests {
|
||||
ExistentialDeposit::get(),
|
||||
executive_init_block,
|
||||
construct_and_apply_extrinsic,
|
||||
|| (),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
|
||||
let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::<
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
WeightToFee,
|
||||
>();
|
||||
|
||||
// check if estimated value is sane
|
||||
let max_expected = bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs::get();
|
||||
assert!(
|
||||
estimated <= max_expected,
|
||||
"calculated: {:?}, max_expected: {:?}, please adjust `bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs` value",
|
||||
estimated,
|
||||
max_expected
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -275,12 +300,38 @@ mod bridge_hub_rococo_tests {
|
||||
mod bridge_hub_wococo_tests {
|
||||
use super::*;
|
||||
use bridge_hub_rococo_runtime::{
|
||||
BridgeGrandpaRococoInstance, BridgeParachainRococoInstance,
|
||||
WithBridgeHubRococoMessagesInstance,
|
||||
xcm_config, AllPalletsWithoutSystem, BridgeGrandpaRococoInstance,
|
||||
BridgeParachainRococoInstance, RuntimeFlavor, WithBridgeHubRococoMessagesInstance,
|
||||
};
|
||||
use bridge_hub_wococo_config::{
|
||||
WithBridgeHubRococoMessageBridge, DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
|
||||
};
|
||||
use frame_support::assert_ok;
|
||||
|
||||
type RuntimeHelper = bridge_hub_test_utils::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;
|
||||
|
||||
pub(crate) fn set_wococo_flavor() {
|
||||
let flavor_key = xcm_config::Flavor::key().to_vec();
|
||||
let flavor = RuntimeFlavor::Wococo;
|
||||
|
||||
// encode `set_storage` call
|
||||
let set_storage_call = RuntimeCall::System(frame_system::Call::<Runtime>::set_storage {
|
||||
items: vec![(flavor_key, flavor.encode())],
|
||||
})
|
||||
.encode();
|
||||
|
||||
// estimate - storing just 1 value
|
||||
use frame_system::WeightInfo;
|
||||
let require_weight_at_most =
|
||||
<Runtime as frame_system::Config>::SystemWeightInfo::set_storage(1);
|
||||
|
||||
// execute XCM with Transact to `set_storage` as governance does
|
||||
assert_ok!(RuntimeHelper::execute_as_governance(set_storage_call, require_weight_at_most)
|
||||
.ensure_complete());
|
||||
|
||||
// check if stored
|
||||
assert_eq!(flavor, xcm_config::Flavor::get());
|
||||
}
|
||||
|
||||
bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!(
|
||||
Runtime,
|
||||
@@ -370,7 +421,11 @@ mod bridge_hub_wococo_tests {
|
||||
}
|
||||
}),
|
||||
|| ExportMessage { network: Rococo, destination: X1(Parachain(4321)), xcm: Xcm(vec![]) },
|
||||
bridge_hub_wococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO
|
||||
bridge_hub_wococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
|
||||
Some((TokenLocation::get(), ExistentialDeposit::get()).into()),
|
||||
// value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer`
|
||||
Some((TokenLocation::get(), bp_asset_hub_wococo::BridgeHubWococoBaseFeeInWocs::get()).into()),
|
||||
set_wococo_flavor,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -401,6 +456,7 @@ mod bridge_hub_wococo_tests {
|
||||
}
|
||||
}),
|
||||
bridge_hub_wococo_config::DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
|
||||
set_wococo_flavor,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -422,6 +478,7 @@ mod bridge_hub_wococo_tests {
|
||||
SIBLING_PARACHAIN_ID,
|
||||
Wococo,
|
||||
DEFAULT_XCM_LANE_TO_BRIDGE_HUB_ROCOCO,
|
||||
set_wococo_flavor,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -447,6 +504,25 @@ mod bridge_hub_wococo_tests {
|
||||
ExistentialDeposit::get(),
|
||||
executive_init_block,
|
||||
construct_and_apply_extrinsic,
|
||||
set_wococo_flavor,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
|
||||
let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::<
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
WeightToFee,
|
||||
>();
|
||||
|
||||
// check if estimated value is sane
|
||||
let max_expected = bp_asset_hub_wococo::BridgeHubWococoBaseFeeInWocs::get();
|
||||
assert!(
|
||||
estimated <= max_expected,
|
||||
"calculated: {:?}, max_expected: {:?}, please adjust `bp_asset_hub_wococo::BridgeHubWococoBaseFeeInWocs` value",
|
||||
estimated,
|
||||
max_expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ description = "Utils for BridgeHub testing"
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] }
|
||||
log = { version = "0.4.20", default-features = false }
|
||||
assert_matches = "1.4.0"
|
||||
|
||||
# Substrate
|
||||
frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking", default-features = false, optional = true }
|
||||
@@ -19,6 +18,7 @@ sp-core = { path = "../../../../../substrate/primitives/core", default-features
|
||||
sp-io = { path = "../../../../../substrate/primitives/io", default-features = false}
|
||||
sp-keyring = { path = "../../../../../substrate/primitives/keyring" }
|
||||
sp-runtime = { path = "../../../../../substrate/primitives/runtime", default-features = false}
|
||||
sp-tracing = { path = "../../../../../substrate/primitives/tracing" }
|
||||
pallet-balances = { path = "../../../../../substrate/frame/balances", default-features = false}
|
||||
pallet-utility = { path = "../../../../../substrate/frame/utility", default-features = false}
|
||||
pallet-session = { path = "../../../../../substrate/frame/session", default-features = false}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
//! Module contains predefined test-case scenarios for `Runtime` with bridging capabilities.
|
||||
|
||||
use assert_matches::assert_matches;
|
||||
use bp_messages::{
|
||||
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch, SourceHeaderChain},
|
||||
LaneId, MessageKey, OutboundLaneData, Weight,
|
||||
@@ -47,10 +46,16 @@ use parachains_runtimes_test_utils::{
|
||||
};
|
||||
use sp_core::H256;
|
||||
use sp_keyring::AccountKeyring::*;
|
||||
use sp_runtime::{traits::Header as HeaderT, AccountId32};
|
||||
use sp_runtime::{
|
||||
traits::{Header as HeaderT, Zero},
|
||||
AccountId32,
|
||||
};
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_builder::DispatchBlobError;
|
||||
use xcm_executor::XcmExecutor;
|
||||
use xcm_executor::{
|
||||
traits::{TransactAsset, WeightBounds},
|
||||
XcmExecutor,
|
||||
};
|
||||
|
||||
// Re-export test_case from assets
|
||||
pub use asset_test_utils::include_teleports_for_native_asset_works;
|
||||
@@ -137,6 +142,9 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works<
|
||||
>,
|
||||
export_message_instruction: fn() -> Instruction<XcmConfig::RuntimeCall>,
|
||||
expected_lane_id: LaneId,
|
||||
existential_deposit: Option<MultiAsset>,
|
||||
maybe_paid_export_message: Option<MultiAsset>,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -161,6 +169,8 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works<
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
// check queue before
|
||||
assert_eq!(
|
||||
pallet_bridge_messages::OutboundLanes::<Runtime, MessagesPalletInstance>::try_get(
|
||||
@@ -170,10 +180,35 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works<
|
||||
);
|
||||
|
||||
// prepare `ExportMessage`
|
||||
let xcm = Xcm(vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
export_message_instruction(),
|
||||
]);
|
||||
let xcm = if let Some(fee) = maybe_paid_export_message {
|
||||
// deposit ED to origin (if needed)
|
||||
if let Some(ed) = existential_deposit {
|
||||
XcmConfig::AssetTransactor::deposit_asset(
|
||||
&ed,
|
||||
&sibling_parachain_location,
|
||||
&XcmContext::with_message_id([0; 32]),
|
||||
)
|
||||
.expect("deposited ed");
|
||||
}
|
||||
// deposit fee to origin
|
||||
XcmConfig::AssetTransactor::deposit_asset(
|
||||
&fee,
|
||||
&sibling_parachain_location,
|
||||
&XcmContext::with_message_id([0; 32]),
|
||||
)
|
||||
.expect("deposited fee");
|
||||
|
||||
Xcm(vec![
|
||||
WithdrawAsset(MultiAssets::from(vec![fee.clone()])),
|
||||
BuyExecution { fees: fee, weight_limit: Unlimited },
|
||||
export_message_instruction(),
|
||||
])
|
||||
} else {
|
||||
Xcm(vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
export_message_instruction(),
|
||||
])
|
||||
};
|
||||
|
||||
// execute XCM
|
||||
let hash = xcm.using_encoded(sp_io::hashing::blake2_256);
|
||||
@@ -231,6 +266,7 @@ pub fn message_dispatch_routing_works<
|
||||
dyn Fn(Vec<u8>) -> Option<cumulus_pallet_xcmp_queue::Event<Runtime>>,
|
||||
>,
|
||||
expected_lane_id: LaneId,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -249,6 +285,7 @@ pub fn message_dispatch_routing_works<
|
||||
XcmConfig: xcm_executor::Config,
|
||||
MessagesPalletInstance: 'static,
|
||||
ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
|
||||
<Runtime as frame_system::Config>::AccountId: From<AccountId32>,
|
||||
HrmpChannelOpener: frame_support::inherent::ProvideInherent<
|
||||
Call = cumulus_pallet_parachain_system::Call<Runtime>,
|
||||
>,
|
||||
@@ -267,12 +304,14 @@ pub fn message_dispatch_routing_works<
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
let mut alice = [0u8; 32];
|
||||
alice[0] = 1;
|
||||
|
||||
let included_head = RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block(
|
||||
2,
|
||||
AccountId::from(alice),
|
||||
AccountId::from(alice).into(),
|
||||
);
|
||||
// 1. this message is sent from other global consensus with destination of this Runtime relay chain (UMP)
|
||||
let bridging_message =
|
||||
@@ -343,6 +382,7 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
sibling_parachain_id: u32,
|
||||
local_relay_chain_id: NetworkId,
|
||||
lane_id: LaneId,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -374,11 +414,11 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
ParaHash: From<<<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash>,
|
||||
<Runtime as frame_system::Config>::AccountId:
|
||||
Into<<<Runtime as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId>,
|
||||
<Runtime as frame_system::Config>::AccountId: From<AccountId32>,
|
||||
AccountIdOf<Runtime>: From<sp_core::sr25519::Public>,
|
||||
<Runtime as pallet_bridge_messages::Config<MPI>>::InboundRelayer: From<AccountId32>,
|
||||
{
|
||||
assert_ne!(runtime_para_id, sibling_parachain_id);
|
||||
assert_ne!(runtime_para_id, bridged_para_id);
|
||||
|
||||
ExtBuilder::<Runtime>::default()
|
||||
.with_collators(collator_session_key.collators())
|
||||
@@ -388,12 +428,14 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
let mut alice = [0u8; 32];
|
||||
alice[0] = 1;
|
||||
|
||||
let included_head = RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block(
|
||||
2,
|
||||
AccountId::from(alice),
|
||||
AccountId::from(alice).into(),
|
||||
);
|
||||
mock_open_hrmp_channel::<Runtime, HrmpChannelOpener>(
|
||||
runtime_para_id.into(),
|
||||
@@ -528,15 +570,24 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
.last_delivered_nonce(),
|
||||
1,
|
||||
);
|
||||
|
||||
// verify relayed bridged XCM message is dispatched to destination sibling para
|
||||
let dispatched = RuntimeHelper::<cumulus_pallet_xcmp_queue::Pallet<Runtime>>::take_xcm(
|
||||
sibling_parachain_id.into(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
// We use `WithUniqueTopic`, so expect a trailing `SetTopic`.
|
||||
assert_matches!(dispatched.0.pop(), Some(SetTopic(..)));
|
||||
assert_eq!(dispatched, expected_dispatch);
|
||||
// verify contains original message
|
||||
let dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
let mut dispatched_clone = dispatched.clone();
|
||||
for (idx, expected_instr) in expected_dispatch.0.iter().enumerate() {
|
||||
assert_eq!(expected_instr, &dispatched.0[idx]);
|
||||
assert_eq!(expected_instr, &dispatched_clone.0.remove(0));
|
||||
}
|
||||
match dispatched_clone.0.len() {
|
||||
0 => (),
|
||||
1 => assert!(matches!(dispatched_clone.0[0], SetTopic(_))),
|
||||
count => assert!(false, "Unexpected messages count: {:?}", count),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -557,6 +608,7 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
sp_keyring::AccountKeyring,
|
||||
pallet_utility::Call::<Runtime>
|
||||
) -> sp_runtime::DispatchOutcome,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -591,6 +643,7 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
<Runtime as frame_system::Config>::AccountId:
|
||||
Into<<<Runtime as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId>,
|
||||
AccountIdOf<Runtime>: From<sp_core::sr25519::Public>,
|
||||
<Runtime as frame_system::Config>::AccountId: From<AccountId32>,
|
||||
<Runtime as pallet_bridge_messages::Config<MPI>>::InboundRelayer: From<AccountId32>,
|
||||
<Runtime as pallet_utility::Config>::RuntimeCall:
|
||||
From<pallet_bridge_grandpa::Call<Runtime, GPI>>
|
||||
@@ -598,7 +651,6 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
+ From<pallet_bridge_messages::Call<Runtime, MPI>>
|
||||
{
|
||||
assert_ne!(runtime_para_id, sibling_parachain_id);
|
||||
assert_ne!(runtime_para_id, bridged_para_id);
|
||||
|
||||
// Relayer account at local/this BH.
|
||||
let relayer_at_target = Bob;
|
||||
@@ -617,12 +669,14 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
let mut alice = [0u8; 32];
|
||||
alice[0] = 1;
|
||||
|
||||
let included_head = RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block(
|
||||
2,
|
||||
AccountId::from(alice),
|
||||
AccountId::from(alice).into(),
|
||||
);
|
||||
let zero: BlockNumberFor<Runtime> = 0u32.into();
|
||||
let genesis_hash = frame_system::Pallet::<Runtime>::block_hash(zero);
|
||||
@@ -678,7 +732,7 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
message_proof,
|
||||
) = test_data::make_complex_relayer_proofs::<BridgedHeader<Runtime, GPI>, MB, ()>(
|
||||
lane_id,
|
||||
xcm.into(),
|
||||
xcm.clone().into(),
|
||||
message_nonce,
|
||||
message_destination,
|
||||
para_header_number,
|
||||
@@ -769,18 +823,133 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
msg_proofs_rewards_account
|
||||
)
|
||||
.is_some());
|
||||
|
||||
// verify relayed bridged XCM message is dispatched to destination sibling para
|
||||
let dispatched = RuntimeHelper::<cumulus_pallet_xcmp_queue::Pallet<Runtime>>::take_xcm(
|
||||
sibling_parachain_id.into(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
// We use `WithUniqueTopic`, so expect a trailing `SetTopic`.
|
||||
assert_matches!(dispatched.0.pop(), Some(SetTopic(..)));
|
||||
assert_eq!(dispatched, expected_dispatch);
|
||||
// verify contains original message
|
||||
let dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
let mut dispatched_clone = dispatched.clone();
|
||||
for (idx, expected_instr) in expected_dispatch.0.iter().enumerate() {
|
||||
assert_eq!(expected_instr, &dispatched.0[idx]);
|
||||
assert_eq!(expected_instr, &dispatched_clone.0.remove(0));
|
||||
}
|
||||
match dispatched_clone.0.len() {
|
||||
0 => (),
|
||||
1 => assert!(matches!(dispatched_clone.0[0], SetTopic(_))),
|
||||
count => assert!(false, "Unexpected messages count: {:?}", count),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Estimates fee for paid `ExportMessage` processing.
|
||||
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer<
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
WeightToFee,
|
||||
>() -> u128
|
||||
where
|
||||
Runtime: frame_system::Config + pallet_balances::Config,
|
||||
XcmConfig: xcm_executor::Config,
|
||||
WeightToFee: frame_support::weights::WeightToFee<Balance = BalanceOf<Runtime>>,
|
||||
<WeightToFee as frame_support::weights::WeightToFee>::Balance: From<u128> + Into<u128>,
|
||||
{
|
||||
// data here are not relevant for weighing
|
||||
let mut xcm = Xcm(vec![
|
||||
WithdrawAsset(MultiAssets::from(vec![MultiAsset {
|
||||
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||
fun: Fungible(34333299),
|
||||
}])),
|
||||
BuyExecution {
|
||||
fees: MultiAsset {
|
||||
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||
fun: Fungible(34333299),
|
||||
},
|
||||
weight_limit: Unlimited,
|
||||
},
|
||||
ExportMessage {
|
||||
network: Polkadot,
|
||||
destination: X1(Parachain(1000)),
|
||||
xcm: Xcm(vec![
|
||||
ReserveAssetDeposited(MultiAssets::from(vec![MultiAsset {
|
||||
id: Concrete(MultiLocation {
|
||||
parents: 2,
|
||||
interior: X1(GlobalConsensus(Kusama)),
|
||||
}),
|
||||
fun: Fungible(1000000000000),
|
||||
}])),
|
||||
ClearOrigin,
|
||||
BuyExecution {
|
||||
fees: MultiAsset {
|
||||
id: Concrete(MultiLocation {
|
||||
parents: 2,
|
||||
interior: X1(GlobalConsensus(Kusama)),
|
||||
}),
|
||||
fun: Fungible(1000000000000),
|
||||
},
|
||||
weight_limit: Unlimited,
|
||||
},
|
||||
DepositAsset {
|
||||
assets: Wild(AllCounted(1)),
|
||||
beneficiary: MultiLocation {
|
||||
parents: 0,
|
||||
interior: X1(xcm::latest::prelude::AccountId32 {
|
||||
network: None,
|
||||
id: [
|
||||
212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159,
|
||||
214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165,
|
||||
109, 162, 125,
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
SetTopic([
|
||||
116, 82, 194, 132, 171, 114, 217, 165, 23, 37, 161, 177, 165, 179, 247, 114,
|
||||
137, 101, 147, 70, 28, 157, 168, 32, 154, 63, 74, 228, 152, 180, 5, 63,
|
||||
]),
|
||||
]),
|
||||
},
|
||||
RefundSurplus,
|
||||
DepositAsset {
|
||||
assets: Wild(All),
|
||||
beneficiary: MultiLocation { parents: 1, interior: X1(Parachain(1000)) },
|
||||
},
|
||||
SetTopic([
|
||||
36, 224, 250, 165, 82, 195, 67, 110, 160, 170, 140, 87, 217, 62, 201, 164, 42, 98, 219,
|
||||
157, 124, 105, 248, 25, 131, 218, 199, 36, 109, 173, 100, 122,
|
||||
]),
|
||||
]);
|
||||
|
||||
// get weight
|
||||
let weight = XcmConfig::Weigher::weight(&mut xcm);
|
||||
assert_ok!(weight);
|
||||
let weight = weight.unwrap();
|
||||
// check if sane
|
||||
let max_expected = Runtime::BlockWeights::get().max_block / 10;
|
||||
assert!(
|
||||
weight.all_lte(max_expected),
|
||||
"calculated weight: {:?}, max_expected: {:?}",
|
||||
weight,
|
||||
max_expected
|
||||
);
|
||||
|
||||
// check fee, should not be 0
|
||||
let estimated_fee = WeightToFee::weight_to_fee(&weight);
|
||||
assert!(estimated_fee > BalanceOf::<Runtime>::zero());
|
||||
|
||||
sp_tracing::try_init_simple();
|
||||
log::error!(
|
||||
target: "bridges::estimate",
|
||||
"Estimate fee: {:?} for `ExportMessage` for runtime: {:?}",
|
||||
estimated_fee,
|
||||
Runtime::Version::get(),
|
||||
);
|
||||
|
||||
estimated_fee.into()
|
||||
}
|
||||
|
||||
pub mod test_data {
|
||||
use super::*;
|
||||
use bp_header_chain::justification::GrandpaJustification;
|
||||
@@ -928,7 +1097,7 @@ pub mod test_data {
|
||||
);
|
||||
|
||||
/// Simulates `HaulBlobExporter` and all its wrapping and captures generated plain bytes,
|
||||
/// which are transfered over bridge.
|
||||
/// which are transferred over bridge.
|
||||
pub(crate) fn simulate_message_exporter_on_bridged_chain<
|
||||
SourceNetwork: Get<NetworkId>,
|
||||
DestinationNetwork: Get<NetworkId>,
|
||||
|
||||
Reference in New Issue
Block a user