Add Bridges to xcm-emulator (#2812)

* rename bridge hub + BridgeMessages type

* bridge base

* bridge string approach

* add decl_test_bridges macro

* outbound lanes on the way

* get & dispatch mock bridge done

* fix bridge errors + log::debug for messages

* clean up

* update source OutboundLaneData

* rococo & wococo added

* sender_receiver_accounts_parameter_types macro

* sender_receiver_accounts_parameter_types macro 2

* fixed multi parachain + example on the way

* working but router error

* bridge working

* refactor NetworkComponent

* make it generic

* working as generic

* clean up

* last bit

* ".git/.scripts/commands/fmt/fmt.sh"

* fix bridge hub handler name

* ".git/.scripts/commands/fmt/fmt.sh"

* add AssetConversion back for AssetHubWestend

* Update xcm/xcm-emulator/src/lib.rs

Co-authored-by: Squirrel <gilescope@gmail.com>

* add LaneId wrapper

* update substrate

* fix wrapper conversion

* remove duplicate in workspace

* Revert "update substrate"

This reverts commit 92e8f201ae433aed3f70b998ebd4c23d9168d0ee.

* ".git/.scripts/commands/fmt/fmt.sh"

---------

Co-authored-by: command-bot <>
Co-authored-by: Squirrel <gilescope@gmail.com>
This commit is contained in:
Ignacio Palacios
2023-07-05 11:39:08 +02:00
committed by GitHub
parent fdd2e5221e
commit f6b33fe927
15 changed files with 1121 additions and 283 deletions
+37 -2
View File
@@ -1357,6 +1357,34 @@ dependencies = [
"xcm-executor",
]
[[package]]
name = "bridge-hub-rococo-integration-tests"
version = "1.0.0"
dependencies = [
"bp-messages",
"bridge-hub-rococo-runtime",
"cumulus-pallet-xcmp-queue",
"frame-support",
"frame-system",
"integration-tests-common",
"pallet-assets",
"pallet-balances",
"pallet-bridge-messages",
"pallet-xcm",
"parachains-common",
"parity-scale-codec",
"polkadot-core-primitives",
"polkadot-parachain",
"polkadot-runtime",
"polkadot-runtime-parachains",
"sp-core",
"sp-runtime",
"sp-weights",
"xcm",
"xcm-emulator",
"xcm-executor",
]
[[package]]
name = "bridge-hub-rococo-runtime"
version = "0.1.0"
@@ -1883,7 +1911,7 @@ dependencies = [
]
[[package]]
name = "collectives-polkadot-it"
name = "collectives-polkadot-integration-tests"
version = "0.1.0"
dependencies = [
"asset-hub-polkadot-runtime",
@@ -5261,8 +5289,12 @@ dependencies = [
"asset-hub-kusama-runtime",
"asset-hub-polkadot-runtime",
"asset-hub-westend-runtime",
"bp-messages",
"bp-runtime",
"bridge-hub-kusama-runtime",
"bridge-hub-polkadot-runtime",
"bridge-hub-rococo-runtime",
"bridge-runtime-common",
"collectives-polkadot-runtime",
"cumulus-primitives-core",
"frame-support",
@@ -5271,6 +5303,7 @@ dependencies = [
"kusama-runtime-constants",
"pallet-assets",
"pallet-balances",
"pallet-bridge-messages",
"pallet-im-online",
"pallet-staking",
"pallet-xcm",
@@ -5285,9 +5318,12 @@ dependencies = [
"polkadot-runtime-constants",
"polkadot-runtime-parachains",
"polkadot-service",
"rococo-runtime",
"rococo-runtime-constants",
"sc-consensus-grandpa",
"sp-authority-discovery",
"sp-consensus-babe",
"sp-consensus-beefy",
"sp-core",
"sp-runtime",
"sp-weights",
@@ -16378,7 +16414,6 @@ dependencies = [
"sp-std",
"sp-trie",
"xcm",
"xcm-executor",
]
[[package]]
+1
View File
@@ -57,6 +57,7 @@ members = [
"parachains/integration-tests/emulated/assets/asset-hub-polkadot",
"parachains/integration-tests/emulated/assets/asset-hub-westend",
"parachains/integration-tests/emulated/collectives/collectives-polkadot",
"parachains/integration-tests/emulated/bridges/bridge-hub-rococo",
"test/client",
"test/relay-sproof-builder",
"test/relay-validation-worker-provider",
@@ -25,12 +25,12 @@ pub use integration_tests_common::{
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
},
AccountId, AssetHubKusama, AssetHubKusamaPallet, AssetHubKusamaReceiver, AssetHubKusamaSender,
BHKusama, BHKusamaPallet, BHKusamaReceiver, BHKusamaSender, BHPolkadot, BHPolkadotPallet,
BHPolkadotReceiver, BHPolkadotSender, Collectives, CollectivesPallet, CollectivesReceiver,
CollectivesSender, Kusama, KusamaMockNet, KusamaPallet, KusamaReceiver, KusamaSender,
PenpalKusama, PenpalKusamaReceiver, PenpalKusamaSender, PenpalPolkadot, PenpalPolkadotReceiver,
PenpalPolkadotSender, Polkadot, PolkadotMockNet, PolkadotPallet, PolkadotReceiver,
PolkadotSender,
BridgeHubKusama, BridgeHubKusamaPallet, BridgeHubKusamaReceiver, BridgeHubKusamaSender,
BridgeHubPolkadot, BridgeHubPolkadotPallet, BridgeHubPolkadotReceiver, BridgeHubPolkadotSender,
Collectives, CollectivesPallet, CollectivesReceiver, CollectivesSender, Kusama, KusamaMockNet,
KusamaPallet, KusamaReceiver, KusamaSender, PenpalKusama, PenpalKusamaReceiver,
PenpalKusamaSender, PenpalPolkadot, PenpalPolkadotReceiver, PenpalPolkadotSender, Polkadot,
PolkadotMockNet, PolkadotPallet, PolkadotReceiver, PolkadotSender,
};
pub use polkadot_core_primitives::InboundDownwardMessage;
pub use xcm::{
@@ -26,12 +26,12 @@ pub use integration_tests_common::{
},
AccountId, AssetHubKusama, AssetHubKusamaPallet, AssetHubKusamaReceiver, AssetHubKusamaSender,
AssetHubPolkadot, AssetHubPolkadotPallet, AssetHubPolkadotReceiver, AssetHubPolkadotSender,
BHKusama, BHKusamaPallet, BHKusamaReceiver, BHKusamaSender, BHPolkadot, BHPolkadotPallet,
BHPolkadotReceiver, BHPolkadotSender, Collectives, CollectivesPallet, CollectivesReceiver,
CollectivesSender, Kusama, KusamaMockNet, KusamaPallet, KusamaReceiver, KusamaSender,
PenpalKusama, PenpalKusamaReceiver, PenpalKusamaSender, PenpalPolkadot, PenpalPolkadotReceiver,
PenpalPolkadotSender, Polkadot, PolkadotMockNet, PolkadotPallet, PolkadotReceiver,
PolkadotSender,
BridgeHubKusama, BridgeHubKusamaPallet, BridgeHubKusamaReceiver, BridgeHubKusamaSender,
BridgeHubPolkadot, BridgeHubPolkadotPallet, BridgeHubPolkadotReceiver, BridgeHubPolkadotSender,
Collectives, CollectivesPallet, CollectivesReceiver, CollectivesSender, Kusama, KusamaMockNet,
KusamaPallet, KusamaReceiver, KusamaSender, PenpalKusama, PenpalKusamaReceiver,
PenpalKusamaSender, PenpalPolkadot, PenpalPolkadotReceiver, PenpalPolkadotSender, Polkadot,
PolkadotMockNet, PolkadotPallet, PolkadotReceiver, PolkadotSender,
};
pub use polkadot_core_primitives::InboundDownwardMessage;
pub use xcm::{
@@ -0,0 +1,38 @@
[package]
name = "bridge-hub-rococo-integration-tests"
version = "1.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
description = "Bridge Hub Rococo runtime integration tests with xcm-emulator"
[dependencies]
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
# Substrate
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
sp-weights = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-assets = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
# Polkadot
polkadot-core-primitives = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-parachain = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" }
xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
# Cumulus
parachains-common = { path = "../../../../common" }
cumulus-pallet-xcmp-queue = { default-features = false, path = "../../../../../pallets/xcmp-queue" }
bridge-hub-rococo-runtime = { path = "../../../../runtimes/bridge-hubs/bridge-hub-rococo" }
pallet-bridge-messages = { default-features = false, path = "../../../../../bridges/modules/messages" }
bp-messages = { default-features = false, path = "../../../../../bridges/primitives/messages" }
# Local
xcm-emulator = { default-features = false, path = "../../../../../xcm/xcm-emulator" }
integration-tests-common = { default-features = false, path = "../../common" }
@@ -0,0 +1,48 @@
// Copyright Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
pub use bp_messages::LaneId;
pub use codec::Encode;
pub use frame_support::{assert_ok, pallet_prelude::Weight};
pub use integration_tests_common::{
constants::{
accounts::{ALICE, BOB},
rococo::{ED as ROCOCO_ED, ED as WOCOCO_ED},
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
},
AccountId, AssetHubWococo, BridgeHubPolkadot, BridgeHubPolkadotPallet,
BridgeHubPolkadotReceiver, BridgeHubPolkadotSender, BridgeHubRococo, BridgeHubRococoPallet,
BridgeHubRococoReceiver, BridgeHubRococoSender, BridgeHubWococo, Collectives,
CollectivesPallet, CollectivesReceiver, CollectivesSender, Kusama, KusamaPallet,
PenpalPolkadot, PenpalPolkadotReceiver, PenpalPolkadotSender, Polkadot, PolkadotMockNet,
PolkadotPallet, PolkadotReceiver, PolkadotSender, Rococo, RococoMockNet, RococoPallet,
RococoReceiver, RococoSender,
};
// pub use polkadot_core_primitives::InboundDownwardMessage;
pub use xcm::{
prelude::*,
v3::{
Error,
NetworkId::{Rococo as RococoId, Wococo as WococoId},
},
};
pub use xcm_emulator::{
assert_expected_events, bx, cumulus_pallet_dmp_queue, helpers::weight_within_threshold,
Parachain as Para, RelayChain as Relay, TestExt,
};
#[cfg(test)]
mod tests;
@@ -0,0 +1,99 @@
// Copyright Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
use crate::*;
#[test]
fn example() {
// Init tests variables
// XcmPallet send arguments
let sudo_origin = <Rococo as Relay>::RuntimeOrigin::root();
let destination = Rococo::child_location_of(BridgeHubRococo::para_id()).into();
let weight_limit = WeightLimit::Unlimited;
let check_origin = None;
let remote_xcm = Xcm(vec![ClearOrigin]);
let xcm = VersionedXcm::from(Xcm(vec![
UnpaidExecution { weight_limit, check_origin },
ExportMessage {
network: WococoId,
destination: X1(Parachain(AssetHubWococo::para_id().into())),
xcm: remote_xcm,
},
]));
//Rococo Global Consensus
// Send XCM message from Relay Chain to Bridge Hub source Parachain
Rococo::execute_with(|| {
assert_ok!(<Rococo as RococoPallet>::XcmPallet::send(
sudo_origin,
bx!(destination),
bx!(xcm),
));
type RuntimeEvent = <Rococo as Relay>::RuntimeEvent;
assert_expected_events!(
Rococo,
vec![
RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {},
]
);
});
// Receive XCM message in Bridge Hub source Parachain
BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Para>::RuntimeEvent;
assert_expected_events!(
BridgeHubRococo,
vec![
RuntimeEvent::DmpQueue(cumulus_pallet_dmp_queue::Event::ExecutedDownward {
outcome: Outcome::Complete(_),
..
}) => {},
RuntimeEvent::BridgeWococoMessages(pallet_bridge_messages::Event::MessageAccepted {
lane_id: LaneId([0, 0, 0, 1]),
nonce: 1,
}) => {},
]
);
});
// Wococo GLobal Consensus
// Receive XCM message in Bridge Hub target Parachain
BridgeHubWococo::execute_with(|| {
type RuntimeEvent = <BridgeHubWococo as Para>::RuntimeEvent;
assert_expected_events!(
BridgeHubWococo,
vec![
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {},
]
);
});
// Receive embeded XCM message within `ExportMessage` in Parachain destination
AssetHubWococo::execute_with(|| {
type RuntimeEvent = <AssetHubWococo as Para>::RuntimeEvent;
assert_expected_events!(
AssetHubWococo,
vec![
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Fail { .. }) => {},
]
);
});
}
@@ -0,0 +1,17 @@
// Copyright Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
mod example;
@@ -1,5 +1,5 @@
[package]
name = "collectives-polkadot-it"
name = "collectives-polkadot-integration-tests"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
@@ -21,6 +21,7 @@ pallet-balances = { default-features = false, git = "https://github.com/parityte
pallet-assets = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-staking = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-im-online = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
beefy-primitives = { package = "sp-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master" }
# Polkadot
polkadot-core-primitives = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
@@ -32,6 +33,8 @@ polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "m
polkadot-runtime-constants = { git = "https://github.com/paritytech/polkadot", branch = "master" }
kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" }
kusama-runtime-constants = { git = "https://github.com/paritytech/polkadot", branch = "master" }
rococo-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" }
rococo-runtime-constants = { git = "https://github.com/paritytech/polkadot", branch = "master" }
westend-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" }
westend-runtime-constants = { git = "https://github.com/paritytech/polkadot", branch = "master" }
xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
@@ -49,7 +52,12 @@ asset-hub-westend-runtime = { path = "../../../runtimes/assets/asset-hub-westend
collectives-polkadot-runtime = { path = "../../../runtimes/collectives/collectives-polkadot" }
bridge-hub-kusama-runtime = { path = "../../../runtimes/bridge-hubs/bridge-hub-kusama" }
bridge-hub-polkadot-runtime = { path = "../../../runtimes/bridge-hubs/bridge-hub-polkadot" }
bridge-hub-rococo-runtime = { path = "../../../runtimes/bridge-hubs/bridge-hub-rococo" }
xcm-emulator = { default-features = false, path = "../../../../xcm/xcm-emulator" }
bp-messages = { path = "../../../../bridges/primitives/messages"}
bp-runtime = { path = "../../../../bridges/primitives/runtime"}
pallet-bridge-messages = { path = "../../../../bridges/modules/messages" }
bridge-runtime-common = { path = "../../../../bridges/bin/runtime-common"}
[features]
runtime-benchmarks = [
@@ -1,8 +1,9 @@
use beefy_primitives::crypto::AuthorityId as BeefyId;
use grandpa::AuthorityId as GrandpaId;
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
pub use parachains_common::{AccountId, AssetHubPolkadotAuraId, AuraId, Balance, BlockNumber};
use parachains_common::{AccountId, AssetHubPolkadotAuraId, AuraId, Balance, BlockNumber};
use polkadot_primitives::{AssignmentId, ValidatorId};
pub use polkadot_runtime_parachains::configuration::HostConfiguration;
use polkadot_runtime_parachains::configuration::HostConfiguration;
use polkadot_service::chain_spec::get_authority_keys_from_seed_no_beefy;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_consensus_babe::AuthorityId as BabeId;
@@ -11,7 +12,7 @@ use sp_runtime::{
traits::{IdentifyAccount, Verify},
BuildStorage, MultiSignature, Perbill,
};
pub use xcm;
use xcm;
pub const XCM_V2: u32 = 3;
pub const XCM_V3: u32 = 2;
@@ -49,6 +50,7 @@ pub mod accounts {
pub const DAVE_STASH: &str = "Dave//stash";
pub const EVE_STASH: &str = "Eve//stash";
pub const FERDIE_STASH: &str = "Ferdie//stash";
pub const FERDIE_BEEFY: &str = "Ferdie//stash";
pub fn init_balances() -> Vec<AccountId> {
vec![
@@ -209,6 +211,7 @@ pub mod polkadot {
}
}
// Westend
pub mod westend {
use super::*;
use westend_runtime_constants::currency::UNITS as WND;
@@ -401,6 +404,93 @@ pub mod kusama {
}
}
// Rococo
pub mod rococo {
use super::*;
pub const ED: Balance = rococo_runtime_constants::currency::EXISTENTIAL_DEPOSIT;
use rococo_runtime_constants::currency::UNITS as ROC;
const ENDOWMENT: u128 = 1_000_000 * ROC;
pub fn get_host_config() -> HostConfiguration<BlockNumber> {
HostConfiguration {
max_upward_queue_size: 51200,
max_upward_message_size: 51200,
max_upward_message_num_per_candidate: 10,
max_downward_message_size: 51200,
..Default::default()
}
}
fn session_keys(
babe: BabeId,
grandpa: GrandpaId,
im_online: ImOnlineId,
para_validator: ValidatorId,
para_assignment: AssignmentId,
authority_discovery: AuthorityDiscoveryId,
beefy: BeefyId,
) -> rococo_runtime::SessionKeys {
rococo_runtime::SessionKeys {
babe,
grandpa,
im_online,
para_validator,
para_assignment,
authority_discovery,
beefy,
}
}
pub fn genesis() -> Storage {
let genesis_config = rococo_runtime::RuntimeGenesisConfig {
system: rococo_runtime::SystemConfig {
code: rococo_runtime::WASM_BINARY.unwrap().to_vec(),
},
balances: rococo_runtime::BalancesConfig {
balances: accounts::init_balances()
.iter()
.map(|k| (k.clone(), ENDOWMENT))
.collect(),
},
// indices: rococo_runtime::IndicesConfig { indices: vec![] },
session: rococo_runtime::SessionConfig {
keys: validators::initial_authorities()
.iter()
.map(|x| {
(
x.0.clone(),
x.0.clone(),
session_keys(
x.2.clone(),
x.3.clone(),
x.4.clone(),
x.5.clone(),
x.6.clone(),
x.7.clone(),
get_from_seed::<BeefyId>("Alice"),
),
)
})
.collect::<Vec<_>>(),
},
babe: rococo_runtime::BabeConfig {
authorities: Default::default(),
epoch_config: Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG),
},
sudo: rococo_runtime::SudoConfig {
key: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
},
configuration: rococo_runtime::ConfigurationConfig { config: get_host_config() },
registrar: rococo_runtime::RegistrarConfig {
next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID,
},
..Default::default()
};
genesis_config.build_storage().unwrap()
}
}
// Asset Hub Polkadot
pub mod asset_hub_polkadot {
use super::*;
@@ -445,12 +535,10 @@ pub mod asset_hub_polkadot {
})
.collect(),
},
aura: Default::default(),
aura_ext: Default::default(),
parachain_system: Default::default(),
polkadot_xcm: asset_hub_polkadot_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
..Default::default()
};
genesis_config.build_storage().unwrap()
@@ -501,12 +589,10 @@ pub mod asset_hub_westend {
})
.collect(),
},
aura: Default::default(),
aura_ext: Default::default(),
parachain_system: Default::default(),
polkadot_xcm: asset_hub_westend_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
..Default::default()
};
genesis_config.build_storage().unwrap()
@@ -557,12 +643,10 @@ pub mod asset_hub_kusama {
})
.collect(),
},
aura: Default::default(),
aura_ext: Default::default(),
parachain_system: Default::default(),
polkadot_xcm: asset_hub_kusama_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
..Default::default()
};
genesis_config.build_storage().unwrap()
@@ -611,15 +695,13 @@ pub mod penpal {
})
.collect(),
},
aura: Default::default(),
aura_ext: Default::default(),
parachain_system: Default::default(),
polkadot_xcm: penpal_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
sudo: penpal_runtime::SudoConfig {
key: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
},
..Default::default()
};
genesis_config.build_storage().unwrap()
@@ -670,22 +752,17 @@ pub mod collectives {
})
.collect(),
},
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
// of this.
aura: Default::default(),
aura_ext: Default::default(),
parachain_system: Default::default(),
polkadot_xcm: collectives_polkadot_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
alliance: Default::default(),
alliance_motion: Default::default(),
..Default::default()
};
genesis_config.build_storage().unwrap()
}
}
// Bridge Hub Kusama
pub mod bridge_hub_kusama {
use super::*;
pub const PARA_ID: u32 = 1002;
@@ -729,18 +806,17 @@ pub mod bridge_hub_kusama {
})
.collect(),
},
aura: Default::default(),
aura_ext: Default::default(),
parachain_system: Default::default(),
polkadot_xcm: bridge_hub_kusama_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
..Default::default()
};
genesis_config.build_storage().unwrap()
}
}
// Bridge Hub Polkadot
pub mod bridge_hub_polkadot {
use super::*;
pub const PARA_ID: u32 = 1002;
@@ -784,12 +860,80 @@ pub mod bridge_hub_polkadot {
})
.collect(),
},
aura: Default::default(),
aura_ext: Default::default(),
parachain_system: Default::default(),
polkadot_xcm: bridge_hub_polkadot_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
..Default::default()
};
genesis_config.build_storage().unwrap()
}
}
// Bridge Hub Rococo & Bridge Hub Wococo
pub mod bridge_hub_rococo {
use super::*;
pub const PARA_ID: u32 = 1013;
pub const ED: Balance = bridge_hub_rococo_runtime::constants::currency::EXISTENTIAL_DEPOSIT;
pub fn genesis() -> Storage {
let genesis_config = bridge_hub_rococo_runtime::RuntimeGenesisConfig {
system: bridge_hub_rococo_runtime::SystemConfig {
code: bridge_hub_rococo_runtime::WASM_BINARY
.expect("WASM binary was not build, please build it!")
.to_vec(),
},
balances: bridge_hub_rococo_runtime::BalancesConfig {
balances: accounts::init_balances()
.iter()
.cloned()
.map(|k| (k, ED * 4096))
.collect(),
},
parachain_info: bridge_hub_rococo_runtime::ParachainInfoConfig {
parachain_id: PARA_ID.into(),
},
collator_selection: bridge_hub_rococo_runtime::CollatorSelectionConfig {
invulnerables: collators::invulnerables()
.iter()
.cloned()
.map(|(acc, _)| acc)
.collect(),
candidacy_bond: ED * 16,
..Default::default()
},
session: bridge_hub_rococo_runtime::SessionConfig {
keys: collators::invulnerables()
.into_iter()
.map(|(acc, aura)| {
(
acc.clone(), // account id
acc, // validator id
bridge_hub_rococo_runtime::SessionKeys { aura }, // session keys
)
})
.collect(),
},
polkadot_xcm: bridge_hub_rococo_runtime::PolkadotXcmConfig {
safe_xcm_version: Some(SAFE_XCM_VERSION),
},
bridge_wococo_grandpa: bridge_hub_rococo_runtime::BridgeWococoGrandpaConfig {
owner: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
..Default::default()
},
bridge_rococo_grandpa: bridge_hub_rococo_runtime::BridgeRococoGrandpaConfig {
owner: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
..Default::default()
},
bridge_rococo_messages: bridge_hub_rococo_runtime::BridgeRococoMessagesConfig {
owner: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
..Default::default()
},
bridge_wococo_messages: bridge_hub_rococo_runtime::BridgeWococoMessagesConfig {
owner: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
..Default::default()
},
..Default::default()
};
genesis_config.build_storage().unwrap()
@@ -0,0 +1,126 @@
use super::{BridgeHubRococo, BridgeHubWococo};
use bp_messages::{
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
LaneId, MessageKey, OutboundLaneData,
};
use bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatchResult;
use codec::Decode;
pub use cumulus_primitives_core::{DmpMessageHandler, XcmpMessageHandler};
use pallet_bridge_messages::{Config, Instance1, Instance2, OutboundLanes, Pallet};
use sp_core::Get;
use xcm_emulator::{BridgeMessage, BridgeMessageDispatchError, BridgeMessageHandler, Parachain};
pub struct BridgeHubMessageHandler<S, T, I> {
_marker: std::marker::PhantomData<(S, T, I)>,
}
struct LaneIdWrapper(LaneId);
impl From<LaneIdWrapper> for u32 {
fn from(lane_id: LaneIdWrapper) -> u32 {
u32::from_be_bytes(lane_id.0 .0)
}
}
impl From<u32> for LaneIdWrapper {
fn from(id: u32) -> LaneIdWrapper {
LaneIdWrapper(LaneId(id.to_be_bytes()))
}
}
type BridgeHubRococoRuntime = <BridgeHubRococo as Parachain>::Runtime;
type BridgeHubWococoRuntime = <BridgeHubWococo as Parachain>::Runtime;
// TODO: uncomment when https://github.com/paritytech/cumulus/pull/2528 is merged
// type BridgeHubPolkadotRuntime = <BridgeHubPolkadot as Parachain>::Runtime;
// type BridgeHubKusamaRuntime = <BridgeHubKusama as Parachain>::Runtime;
pub type RococoWococoMessageHandler =
BridgeHubMessageHandler<BridgeHubRococoRuntime, BridgeHubWococoRuntime, Instance2>;
pub type WococoRococoMessageHandler =
BridgeHubMessageHandler<BridgeHubWococoRuntime, BridgeHubRococoRuntime, Instance2>;
// TODO: uncomment when https://github.com/paritytech/cumulus/pull/2528 is merged
// pub type PolkadotKusamaMessageHandler
// = BridgeHubMessageHandler<BridgeHubPolkadotRuntime, BridgeHubKusamaRuntime, Instance1>;
// pub type KusamaPolkadotMessageHandler
// = BridgeHubMessageHandler<BridgeHubKusamaRuntime, BridgeHubPolkadoRuntime, Instance1>;
impl<S, T, I> BridgeMessageHandler for BridgeHubMessageHandler<S, T, I>
where
S: Config<Instance1>,
T: Config<I>,
I: 'static,
<T as Config<I>>::InboundPayload: From<Vec<u8>>,
<T as Config<I>>::MessageDispatch:
MessageDispatch<DispatchLevelResult = XcmBlobMessageDispatchResult>,
{
fn get_source_outbound_messages() -> Vec<BridgeMessage> {
// get the source active outbound lanes
let active_lanes = S::ActiveOutboundLanes::get();
let mut messages: Vec<BridgeMessage> = Default::default();
// collect messages from `OutboundMessages` for each active outbound lane in the source
for lane in active_lanes {
let latest_generated_nonce =
OutboundLanes::<S, Instance1>::get(lane).latest_generated_nonce;
let latest_received_nonce =
OutboundLanes::<S, Instance1>::get(lane).latest_received_nonce;
(latest_received_nonce + 1..=latest_generated_nonce).for_each(|nonce| {
let encoded_payload: Vec<u8> =
Pallet::<S, Instance1>::outbound_message_data(*lane, nonce)
.expect("Bridge message does not exist")
.into();
let payload = Vec::<u8>::decode(&mut &encoded_payload[..])
.expect("Decodign XCM message failed");
let id: u32 = LaneIdWrapper(*lane).into();
let message = BridgeMessage { id, nonce, payload };
messages.push(message);
});
}
messages
}
fn dispatch_target_inbound_message(
message: BridgeMessage,
) -> Result<(), BridgeMessageDispatchError> {
type TargetMessageDispatch<T, I> = <T as Config<I>>::MessageDispatch;
type InboundPayload<T, I> = <T as Config<I>>::InboundPayload;
let lane_id = LaneIdWrapper::from(message.id).0;
let nonce = message.nonce;
let payload = Ok(From::from(message.payload));
// Directly dispatch outbound messages assuming everything is correct
// and bypassing the `Relayers` and `InboundLane` logic
let dispatch_result = TargetMessageDispatch::<T, I>::dispatch(DispatchMessage {
key: MessageKey { lane_id, nonce },
data: DispatchMessageData::<InboundPayload<T, I>> { payload },
});
let result = match dispatch_result.dispatch_level_result {
XcmBlobMessageDispatchResult::Dispatched => Ok(()),
XcmBlobMessageDispatchResult::InvalidPayload => Err(BridgeMessageDispatchError(
Box::new(XcmBlobMessageDispatchResult::InvalidPayload),
)),
XcmBlobMessageDispatchResult::NotDispatched(e) => Err(BridgeMessageDispatchError(
Box::new(XcmBlobMessageDispatchResult::NotDispatched(e)),
)),
};
result
}
fn notify_source_message_delivery(lane_id: u32) {
let data = OutboundLanes::<S, Instance1>::get(LaneIdWrapper::from(lane_id).0);
let new_data = OutboundLaneData {
oldest_unpruned_nonce: data.oldest_unpruned_nonce + 1,
latest_received_nonce: data.latest_received_nonce + 1,
..data
};
OutboundLanes::<S, Instance1>::insert(LaneIdWrapper::from(lane_id).0, new_data);
}
}
@@ -1,41 +1,25 @@
pub mod constants;
pub mod impls;
pub use constants::{
accounts::{ALICE, BOB},
asset_hub_kusama, asset_hub_polkadot, asset_hub_westend, bridge_hub_kusama,
bridge_hub_polkadot, collectives, kusama, penpal, polkadot, westend,
bridge_hub_polkadot, bridge_hub_rococo, collectives, kusama, penpal, polkadot, rococo, westend,
};
pub use impls::{RococoWococoMessageHandler, WococoRococoMessageHandler};
use frame_support::{parameter_types, sp_io, sp_tracing};
pub use parachains_common::{AccountId, AssetHubPolkadotAuraId, AuraId, Balance, BlockNumber};
pub use sp_core::{sr25519, storage::Storage, Get};
use xcm::prelude::*;
use xcm_emulator::{
decl_test_networks, decl_test_parachains, decl_test_relay_chains, Parachain, RelayChain,
TestExt,
decl_test_bridges, decl_test_networks, decl_test_parachains, decl_test_relay_chains,
decl_test_sender_receiver_accounts_parameter_types, BridgeMessageHandler, Parachain,
RelayChain, TestExt,
};
use xcm_executor::traits::ConvertLocation;
decl_test_relay_chains! {
#[api_version(5)]
pub struct Westend {
genesis = westend::genesis(),
on_init = (),
runtime = {
Runtime: westend_runtime::Runtime,
RuntimeOrigin: westend_runtime::RuntimeOrigin,
RuntimeCall: westend_runtime::RuntimeCall,
RuntimeEvent: westend_runtime::RuntimeEvent,
MessageQueue: westend_runtime::MessageQueue,
XcmConfig: westend_runtime::xcm_config::XcmConfig,
SovereignAccountOf: westend_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
System: westend_runtime::System,
Balances: westend_runtime::Balances,
},
pallets_extra = {
XcmPallet: westend_runtime::XcmPallet,
Sudo: westend_runtime::Sudo,
}
},
#[api_version(5)]
pub struct Polkadot {
genesis = polkadot::genesis(),
@@ -73,35 +57,71 @@ decl_test_relay_chains! {
pallets_extra = {
XcmPallet: kusama_runtime::XcmPallet,
}
},
#[api_version(5)]
pub struct Westend {
genesis = westend::genesis(),
on_init = (),
runtime = {
Runtime: westend_runtime::Runtime,
RuntimeOrigin: westend_runtime::RuntimeOrigin,
RuntimeCall: westend_runtime::RuntimeCall,
RuntimeEvent: westend_runtime::RuntimeEvent,
MessageQueue: westend_runtime::MessageQueue,
XcmConfig: westend_runtime::xcm_config::XcmConfig,
SovereignAccountOf: westend_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
System: westend_runtime::System,
Balances: westend_runtime::Balances,
},
pallets_extra = {
XcmPallet: westend_runtime::XcmPallet,
Sudo: westend_runtime::Sudo,
}
},
#[api_version(5)]
pub struct Rococo {
genesis = rococo::genesis(),
on_init = (),
runtime = {
Runtime: rococo_runtime::Runtime,
RuntimeOrigin: rococo_runtime::RuntimeOrigin,
RuntimeCall: rococo_runtime::RuntimeCall,
RuntimeEvent: rococo_runtime::RuntimeEvent,
MessageQueue: rococo_runtime::MessageQueue,
XcmConfig: rococo_runtime::xcm_config::XcmConfig,
SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
System: rococo_runtime::System,
Balances: rococo_runtime::Balances,
},
pallets_extra = {
XcmPallet: rococo_runtime::XcmPallet,
Sudo: rococo_runtime::Sudo,
}
},
#[api_version(5)]
pub struct Wococo {
genesis = rococo::genesis(),
on_init = (),
runtime = {
Runtime: rococo_runtime::Runtime,
RuntimeOrigin: rococo_runtime::RuntimeOrigin,
RuntimeCall: rococo_runtime::RuntimeCall,
RuntimeEvent: rococo_runtime::RuntimeEvent,
MessageQueue: rococo_runtime::MessageQueue,
XcmConfig: rococo_runtime::xcm_config::XcmConfig,
SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
System: rococo_runtime::System,
Balances: rococo_runtime::Balances,
},
pallets_extra = {
XcmPallet: rococo_runtime::XcmPallet,
Sudo: rococo_runtime::Sudo,
}
}
}
decl_test_parachains! {
// Westend
pub struct AssetHubWestend {
genesis = asset_hub_westend::genesis(),
on_init = (),
runtime = {
Runtime: asset_hub_westend_runtime::Runtime,
RuntimeOrigin: asset_hub_westend_runtime::RuntimeOrigin,
RuntimeCall: asset_hub_westend_runtime::RuntimeCall,
RuntimeEvent: asset_hub_westend_runtime::RuntimeEvent,
XcmpMessageHandler: asset_hub_westend_runtime::XcmpQueue,
DmpMessageHandler: asset_hub_westend_runtime::DmpQueue,
LocationToAccountId: asset_hub_westend_runtime::xcm_config::LocationToAccountId,
System: asset_hub_westend_runtime::System,
Balances: asset_hub_westend_runtime::Balances,
ParachainSystem: asset_hub_westend_runtime::ParachainSystem,
ParachainInfo: asset_hub_westend_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: asset_hub_westend_runtime::PolkadotXcm,
Assets: asset_hub_westend_runtime::Assets,
ForeignAssets: asset_hub_westend_runtime::ForeignAssets,
AssetConversion: asset_hub_westend_runtime::AssetConversion,
}
},
// Polkadot
// Polkadot Parachains
pub struct AssetHubPolkadot {
genesis = asset_hub_polkadot::genesis(),
on_init = (),
@@ -123,6 +143,46 @@ decl_test_parachains! {
Assets: asset_hub_polkadot_runtime::Assets,
}
},
pub struct Collectives {
genesis = collectives::genesis(),
on_init = (),
runtime = {
Runtime: collectives_polkadot_runtime::Runtime,
RuntimeOrigin: collectives_polkadot_runtime::RuntimeOrigin,
RuntimeCall: collectives_polkadot_runtime::RuntimeCall,
RuntimeEvent: collectives_polkadot_runtime::RuntimeEvent,
XcmpMessageHandler: collectives_polkadot_runtime::XcmpQueue,
DmpMessageHandler: collectives_polkadot_runtime::DmpQueue,
LocationToAccountId: collectives_polkadot_runtime::xcm_config::LocationToAccountId,
System: collectives_polkadot_runtime::System,
Balances: collectives_polkadot_runtime::Balances,
ParachainSystem: collectives_polkadot_runtime::ParachainSystem,
ParachainInfo: collectives_polkadot_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: collectives_polkadot_runtime::PolkadotXcm,
}
},
pub struct BridgeHubPolkadot {
genesis = bridge_hub_polkadot::genesis(),
on_init = (),
runtime = {
Runtime: bridge_hub_polkadot_runtime::Runtime,
RuntimeOrigin: bridge_hub_polkadot_runtime::RuntimeOrigin,
RuntimeCall: bridge_hub_polkadot_runtime::RuntimeCall,
RuntimeEvent: bridge_hub_polkadot_runtime::RuntimeEvent,
XcmpMessageHandler: bridge_hub_polkadot_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_polkadot_runtime::DmpQueue,
LocationToAccountId: bridge_hub_polkadot_runtime::xcm_config::LocationToAccountId,
System: bridge_hub_polkadot_runtime::System,
Balances: bridge_hub_polkadot_runtime::Balances,
ParachainSystem: bridge_hub_polkadot_runtime::ParachainSystem,
ParachainInfo: bridge_hub_polkadot_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: bridge_hub_polkadot_runtime::PolkadotXcm,
}
},
pub struct PenpalPolkadot {
genesis = penpal::genesis(penpal::PARA_ID),
on_init = (),
@@ -144,29 +204,7 @@ decl_test_parachains! {
Assets: penpal_runtime::Assets,
}
},
pub struct PenpalWestend {
genesis = penpal::genesis(penpal::PARA_ID),
on_init = (),
runtime = {
Runtime: penpal_runtime::Runtime,
RuntimeOrigin: penpal_runtime::RuntimeOrigin,
RuntimeCall: penpal_runtime::RuntimeCall,
RuntimeEvent: penpal_runtime::RuntimeEvent,
XcmpMessageHandler: penpal_runtime::XcmpQueue,
DmpMessageHandler: penpal_runtime::DmpQueue,
LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId,
System: penpal_runtime::System,
Balances: penpal_runtime::Balances,
ParachainSystem: penpal_runtime::ParachainSystem,
ParachainInfo: penpal_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: penpal_runtime::PolkadotXcm,
Assets: penpal_runtime::Assets,
}
},
// Kusama
// Kusama Parachains
pub struct AssetHubKusama {
genesis = asset_hub_kusama::genesis(),
on_init = (),
@@ -189,6 +227,26 @@ decl_test_parachains! {
ForeignAssets: asset_hub_kusama_runtime::Assets,
}
},
pub struct BridgeHubKusama {
genesis = bridge_hub_kusama::genesis(),
on_init = (),
runtime = {
Runtime: bridge_hub_kusama_runtime::Runtime,
RuntimeOrigin: bridge_hub_kusama_runtime::RuntimeOrigin,
RuntimeCall: bridge_hub_kusama_runtime::RuntimeCall,
RuntimeEvent: bridge_hub_kusama_runtime::RuntimeEvent,
XcmpMessageHandler: bridge_hub_kusama_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_kusama_runtime::DmpQueue,
LocationToAccountId: bridge_hub_kusama_runtime::xcm_config::LocationToAccountId,
System: bridge_hub_kusama_runtime::System,
Balances: bridge_hub_kusama_runtime::Balances,
ParachainSystem: bridge_hub_kusama_runtime::ParachainSystem,
ParachainInfo: bridge_hub_kusama_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: bridge_hub_kusama_runtime::PolkadotXcm,
}
},
pub struct PenpalKusama {
genesis = penpal::genesis(penpal::PARA_ID),
on_init = (),
@@ -210,64 +268,133 @@ decl_test_parachains! {
Assets: penpal_runtime::Assets,
}
},
pub struct Collectives {
genesis = collectives::genesis(),
// Westend Parachains
pub struct AssetHubWestend {
genesis = asset_hub_westend::genesis(),
on_init = (),
runtime = {
Runtime: collectives_polkadot_runtime::Runtime,
RuntimeOrigin: collectives_polkadot_runtime::RuntimeOrigin,
RuntimeCall: collectives_polkadot_runtime::RuntimeCall,
RuntimeEvent: collectives_polkadot_runtime::RuntimeEvent,
XcmpMessageHandler: collectives_polkadot_runtime::XcmpQueue,
DmpMessageHandler: collectives_polkadot_runtime::DmpQueue,
LocationToAccountId: collectives_polkadot_runtime::xcm_config::LocationToAccountId,
System: collectives_polkadot_runtime::System,
Balances: collectives_polkadot_runtime::Balances,
ParachainSystem: collectives_polkadot_runtime::ParachainSystem,
ParachainInfo: collectives_polkadot_runtime::ParachainInfo,
Runtime: asset_hub_westend_runtime::Runtime,
RuntimeOrigin: asset_hub_westend_runtime::RuntimeOrigin,
RuntimeCall: asset_hub_westend_runtime::RuntimeCall,
RuntimeEvent: asset_hub_westend_runtime::RuntimeEvent,
XcmpMessageHandler: asset_hub_westend_runtime::XcmpQueue,
DmpMessageHandler: asset_hub_westend_runtime::DmpQueue,
LocationToAccountId: asset_hub_westend_runtime::xcm_config::LocationToAccountId,
System: asset_hub_westend_runtime::System,
Balances: asset_hub_westend_runtime::Balances,
ParachainSystem: asset_hub_westend_runtime::ParachainSystem,
ParachainInfo: asset_hub_westend_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: collectives_polkadot_runtime::PolkadotXcm,
PolkadotXcm: asset_hub_westend_runtime::PolkadotXcm,
Assets: asset_hub_westend_runtime::Assets,
ForeignAssets: asset_hub_westend_runtime::ForeignAssets,
AssetConversion: asset_hub_westend_runtime::AssetConversion,
}
},
pub struct BHKusama {
genesis = bridge_hub_kusama::genesis(),
pub struct PenpalWestend {
genesis = penpal::genesis(penpal::PARA_ID),
on_init = (),
runtime = {
Runtime: bridge_hub_kusama_runtime::Runtime,
RuntimeOrigin: bridge_hub_kusama_runtime::RuntimeOrigin,
RuntimeCall: bridge_hub_kusama_runtime::RuntimeCall,
RuntimeEvent: bridge_hub_kusama_runtime::RuntimeEvent,
XcmpMessageHandler: bridge_hub_kusama_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_kusama_runtime::DmpQueue,
LocationToAccountId: bridge_hub_kusama_runtime::xcm_config::LocationToAccountId,
System: bridge_hub_kusama_runtime::System,
Balances: bridge_hub_kusama_runtime::Balances,
ParachainSystem: bridge_hub_kusama_runtime::ParachainSystem,
ParachainInfo:bridge_hub_kusama_runtime::ParachainInfo,
Runtime: penpal_runtime::Runtime,
RuntimeOrigin: penpal_runtime::RuntimeOrigin,
RuntimeCall: penpal_runtime::RuntimeCall,
RuntimeEvent: penpal_runtime::RuntimeEvent,
XcmpMessageHandler: penpal_runtime::XcmpQueue,
DmpMessageHandler: penpal_runtime::DmpQueue,
LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId,
System: penpal_runtime::System,
Balances: penpal_runtime::Balances,
ParachainSystem: penpal_runtime::ParachainSystem,
ParachainInfo: penpal_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: bridge_hub_kusama_runtime::PolkadotXcm,
PolkadotXcm: penpal_runtime::PolkadotXcm,
Assets: penpal_runtime::Assets,
}
},
pub struct BHPolkadot {
genesis = bridge_hub_polkadot::genesis(),
// Rococo Parachains
pub struct BridgeHubRococo {
genesis = bridge_hub_rococo::genesis(),
on_init = (),
runtime = {
Runtime: bridge_hub_polkadot_runtime::Runtime,
RuntimeOrigin: bridge_hub_polkadot_runtime::RuntimeOrigin,
RuntimeCall: bridge_hub_polkadot_runtime::RuntimeCall,
RuntimeEvent: bridge_hub_polkadot_runtime::RuntimeEvent,
XcmpMessageHandler: bridge_hub_polkadot_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_polkadot_runtime::DmpQueue,
LocationToAccountId: bridge_hub_polkadot_runtime::xcm_config::LocationToAccountId,
System: bridge_hub_polkadot_runtime::System,
Balances: bridge_hub_polkadot_runtime::Balances,
ParachainSystem: bridge_hub_polkadot_runtime::ParachainSystem,
ParachainInfo:bridge_hub_polkadot_runtime::ParachainInfo,
Runtime: bridge_hub_rococo_runtime::Runtime,
RuntimeOrigin: bridge_hub_rococo_runtime::RuntimeOrigin,
RuntimeCall: bridge_hub_rococo_runtime::RuntimeCall,
RuntimeEvent: bridge_hub_rococo_runtime::RuntimeEvent,
XcmpMessageHandler: bridge_hub_rococo_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_rococo_runtime::DmpQueue,
LocationToAccountId: bridge_hub_rococo_runtime::xcm_config::LocationToAccountId,
System: bridge_hub_rococo_runtime::System,
Balances: bridge_hub_rococo_runtime::Balances,
ParachainSystem: bridge_hub_rococo_runtime::ParachainSystem,
ParachainInfo: bridge_hub_rococo_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: bridge_hub_polkadot_runtime::PolkadotXcm,
PolkadotXcm: bridge_hub_rococo_runtime::PolkadotXcm,
}
},
pub struct AssetHubRococo {
genesis = asset_hub_polkadot::genesis(),
on_init = (),
runtime = {
Runtime: asset_hub_polkadot_runtime::Runtime,
RuntimeOrigin: asset_hub_polkadot_runtime::RuntimeOrigin,
RuntimeCall: asset_hub_polkadot_runtime::RuntimeCall,
RuntimeEvent: asset_hub_polkadot_runtime::RuntimeEvent,
XcmpMessageHandler: asset_hub_polkadot_runtime::XcmpQueue,
DmpMessageHandler: asset_hub_polkadot_runtime::DmpQueue,
LocationToAccountId: asset_hub_polkadot_runtime::xcm_config::LocationToAccountId,
System: asset_hub_polkadot_runtime::System,
Balances: asset_hub_polkadot_runtime::Balances,
ParachainSystem: asset_hub_polkadot_runtime::ParachainSystem,
ParachainInfo: asset_hub_polkadot_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: asset_hub_polkadot_runtime::PolkadotXcm,
Assets: asset_hub_polkadot_runtime::Assets,
}
},
// Wococo Parachains
pub struct BridgeHubWococo {
genesis = bridge_hub_rococo::genesis(),
on_init = (),
runtime = {
Runtime: bridge_hub_rococo_runtime::Runtime,
RuntimeOrigin: bridge_hub_rococo_runtime::RuntimeOrigin,
RuntimeCall: bridge_hub_rococo_runtime::RuntimeCall,
RuntimeEvent: bridge_hub_rococo_runtime::RuntimeEvent,
XcmpMessageHandler: bridge_hub_rococo_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_rococo_runtime::DmpQueue,
LocationToAccountId: bridge_hub_rococo_runtime::xcm_config::LocationToAccountId,
System: bridge_hub_rococo_runtime::System,
Balances: bridge_hub_rococo_runtime::Balances,
ParachainSystem: bridge_hub_rococo_runtime::ParachainSystem,
ParachainInfo: bridge_hub_rococo_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: bridge_hub_rococo_runtime::PolkadotXcm,
}
},
pub struct AssetHubWococo {
genesis = asset_hub_polkadot::genesis(),
on_init = (),
runtime = {
Runtime: asset_hub_polkadot_runtime::Runtime,
RuntimeOrigin: asset_hub_polkadot_runtime::RuntimeOrigin,
RuntimeCall: asset_hub_polkadot_runtime::RuntimeCall,
RuntimeEvent: asset_hub_polkadot_runtime::RuntimeEvent,
XcmpMessageHandler: asset_hub_polkadot_runtime::XcmpQueue,
DmpMessageHandler: asset_hub_polkadot_runtime::DmpQueue,
LocationToAccountId: asset_hub_polkadot_runtime::xcm_config::LocationToAccountId,
System: asset_hub_polkadot_runtime::System,
Balances: asset_hub_polkadot_runtime::Balances,
ParachainSystem: asset_hub_polkadot_runtime::ParachainSystem,
ParachainInfo: asset_hub_polkadot_runtime::ParachainInfo,
},
pallets_extra = {
PolkadotXcm: asset_hub_polkadot_runtime::PolkadotXcm,
Assets: asset_hub_polkadot_runtime::Assets,
}
}
}
@@ -279,16 +406,22 @@ decl_test_networks! {
AssetHubPolkadot,
PenpalPolkadot,
Collectives,
BHPolkadot,
BridgeHubPolkadot,
],
// TODO: uncomment when https://github.com/paritytech/cumulus/pull/2528 is merged
// bridge = PolkadotKusamaMockBridge
bridge = ()
},
pub struct KusamaMockNet {
relay_chain = Kusama,
parachains = vec![
AssetHubKusama,
PenpalKusama,
BHKusama,
BridgeHubKusama,
],
// TODO: uncomment when https://github.com/paritytech/cumulus/pull/2528 is merged
// bridge = KusamaPolkadotMockBridge
bridge = ()
},
pub struct WestendMockNet {
relay_chain = Westend,
@@ -296,44 +429,72 @@ decl_test_networks! {
AssetHubWestend,
PenpalWestend,
],
bridge = ()
},
pub struct RococoMockNet {
relay_chain = Rococo,
parachains = vec![
AssetHubRococo,
BridgeHubRococo,
],
bridge = RococoWococoMockBridge
},
pub struct WococoMockNet {
relay_chain = Wococo,
parachains = vec![
AssetHubWococo,
BridgeHubWococo,
],
bridge = WococoRococoMockBridge
}
}
parameter_types! {
// Polkadot
pub PolkadotSender: AccountId = Polkadot::account_id_of(ALICE);
pub PolkadotReceiver: AccountId = Polkadot::account_id_of(BOB);
// Kusama
pub KusamaSender: AccountId = Kusama::account_id_of(ALICE);
pub KusamaReceiver: AccountId = Kusama::account_id_of(BOB);
// Westend
pub WestendSender: AccountId = Westend::account_id_of(ALICE);
pub WestendReceiver: AccountId = Westend::account_id_of(BOB);
// Asset Hub Westend
pub AssetHubWestendSender: AccountId = AssetHubWestend::account_id_of(ALICE);
pub AssetHubWestendReceiver: AccountId = AssetHubWestend::account_id_of(BOB);
// Asset Hub Polkadot
pub AssetHubPolkadotSender: AccountId = AssetHubPolkadot::account_id_of(ALICE);
pub AssetHubPolkadotReceiver: AccountId = AssetHubPolkadot::account_id_of(BOB);
// Asset Hub Kusama
pub AssetHubKusamaSender: AccountId = AssetHubKusama::account_id_of(ALICE);
pub AssetHubKusamaReceiver: AccountId = AssetHubKusama::account_id_of(BOB);
// Penpal Polkadot
pub PenpalPolkadotSender: AccountId = PenpalPolkadot::account_id_of(ALICE);
pub PenpalPolkadotReceiver: AccountId = PenpalPolkadot::account_id_of(BOB);
// Penpal Kusama
pub PenpalKusamaSender: AccountId = PenpalKusama::account_id_of(ALICE);
pub PenpalKusamaReceiver: AccountId = PenpalKusama::account_id_of(BOB);
// Penpal Westend
pub PenpalWestendSender: AccountId = PenpalWestend::account_id_of(ALICE);
pub PenpalWestendReceiver: AccountId = PenpalWestend::account_id_of(BOB);
// Collectives
pub CollectivesSender: AccountId = Collectives::account_id_of(ALICE);
pub CollectivesReceiver: AccountId = Collectives::account_id_of(BOB);
// Bridge Hub Polkadot
pub BHPolkadotSender: AccountId = BHPolkadot::account_id_of(ALICE);
pub BHPolkadotReceiver: AccountId = BHPolkadot::account_id_of(BOB);
// Bridge Hub Kusama
pub BHKusamaSender: AccountId = BHKusama::account_id_of(ALICE);
pub BHKusamaReceiver: AccountId = BHKusama::account_id_of(BOB);
decl_test_bridges! {
pub struct RococoWococoMockBridge {
source = BridgeHubRococo,
target = BridgeHubWococo,
handler = RococoWococoMessageHandler
},
pub struct WococoRococoMockBridge {
source = BridgeHubWococo,
target = BridgeHubRococo,
handler = WococoRococoMessageHandler
}
// TODO: uncomment when https://github.com/paritytech/cumulus/pull/2528 is merged
// pub struct PolkadotKusamaMockBridge {
// source = BridgeHubPolkadot,
// target = BridgeHubKusama,
// handler = PolkadotKusamaMessageHandler
// },
// pub struct KusamaPolkadotMockBridge {
// source = BridgeHubKusama,
// target = BridgeHubPolkadot,
// handler = KusamaPolkadotMessageHandler
// }
}
decl_test_sender_receiver_accounts_parameter_types! {
// Relays
Polkadot { sender: ALICE, receiver: BOB },
Kusama { sender: ALICE, receiver: BOB },
Westend { sender: ALICE, receiver: BOB },
Rococo { sender: ALICE, receiver: BOB },
Wococo { sender: ALICE, receiver: BOB },
// Asset Hubs
AssetHubPolkadot { sender: ALICE, receiver: BOB },
AssetHubKusama { sender: ALICE, receiver: BOB },
AssetHubWestend { sender: ALICE, receiver: BOB },
AssetHubRococo { sender: ALICE, receiver: BOB },
AssetHubWococo { sender: ALICE, receiver: BOB },
// Collectives
Collectives { sender: ALICE, receiver: BOB },
// Bridged Hubs
BridgeHubPolkadot { sender: ALICE, receiver: BOB },
BridgeHubKusama { sender: ALICE, receiver: BOB },
BridgeHubRococo { sender: ALICE, receiver: BOB },
BridgeHubWococo { sender: ALICE, receiver: BOB },
// Penpals
PenpalPolkadot { sender: ALICE, receiver: BOB },
PenpalKusama { sender: ALICE, receiver: BOB },
PenpalWestend { sender: ALICE, receiver: BOB }
}
+3 -1
View File
@@ -12,6 +12,7 @@ quote = "1.0.29"
casey = "0.4.0"
log = { version = "0.4.19", default-features = false }
# Substrate
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
@@ -22,6 +23,7 @@ sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master" }
# Cumulus
cumulus-primitives-core = { path = "../../primitives/core"}
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue" }
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue" }
@@ -32,7 +34,7 @@ cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inh
cumulus-test-relay-sproof-builder = { path = "../../test/relay-sproof-builder" }
parachains-common = { path = "../../parachains/common" }
# Polkadot
xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" }
xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+245 -86
View File
@@ -14,23 +14,26 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
pub use casey::pascal;
pub use codec::Encode;
pub use codec::{Decode, Encode};
pub use log;
pub use paste;
pub use std::{collections::HashMap, error::Error, fmt, thread::LocalKey};
// Substrate
pub use frame_support::{
sp_runtime::BuildStorage,
assert_ok,
traits::{EnqueueMessage, Get, Hooks, ProcessMessage, ProcessMessageError, ServiceQueues},
weights::{Weight, WeightMeter},
};
pub use frame_system::AccountInfo;
pub use log;
pub use pallet_balances::AccountData;
pub use paste;
pub use sp_arithmetic::traits::Bounded;
pub use sp_core::storage::Storage;
pub use sp_core::{storage::Storage, H256};
pub use sp_io;
pub use sp_std::{cell::RefCell, collections::vec_deque::VecDeque, marker::PhantomData};
pub use sp_std::{cell::RefCell, collections::vec_deque::VecDeque, fmt::Debug};
pub use sp_trie::StorageProof;
//Cumulus
pub use cumulus_pallet_dmp_queue;
pub use cumulus_pallet_parachain_system;
pub use cumulus_pallet_xcmp_queue;
@@ -44,15 +47,14 @@ pub use cumulus_test_service::get_account_id_from_seed;
pub use pallet_message_queue;
pub use parachain_info;
pub use parachains_common::{AccountId, BlockNumber};
pub use polkadot_primitives;
pub use polkadot_runtime_parachains::{
dmp,
inclusion::{AggregateMessageOrigin, UmpQueueId},
};
pub use std::{collections::HashMap, thread::LocalKey};
pub use xcm::{v3::prelude::*, VersionedXcm};
pub use xcm_executor::XcmExecutor;
// Polkadot
pub use xcm::v3::prelude::*;
thread_local! {
/// Downward messages, each message is: `(to_para_id, [(relay_block_number, msg)])`
@@ -67,8 +69,10 @@ thread_local! {
#[allow(clippy::type_complexity)]
pub static HORIZONTAL_MESSAGES: RefCell<HashMap<String, VecDeque<(u32, Vec<(ParaId, RelayBlockNumber, Vec<u8>)>)>>>
= RefCell::new(HashMap::new());
/// Upward messages, each message is: `(from_para_id, msg)
/// Upward messages, each message is: `(from_para_id, msg)`
pub static UPWARD_MESSAGES: RefCell<HashMap<String, VecDeque<(u32, Vec<u8>)>>> = RefCell::new(HashMap::new());
/// Bridged messages, each message is: `BridgeMessage`
pub static BRIDGED_MESSAGES: RefCell<HashMap<String, VecDeque<BridgeMessage>>> = RefCell::new(HashMap::new());
/// Global incremental relay chain block number
pub static RELAY_BLOCK_NUMBER: RefCell<HashMap<String, u32>> = RefCell::new(HashMap::new());
/// Parachains Ids a the Network
@@ -85,41 +89,46 @@ pub trait TestExt {
fn ext_wrapper<R>(func: impl FnOnce() -> R) -> R;
}
impl TestExt for () {
fn build_new_ext(_storage: Storage) -> sp_io::TestExternalities {
sp_io::TestExternalities::default()
}
fn new_ext() -> sp_io::TestExternalities {
sp_io::TestExternalities::default()
}
fn reset_ext() {}
fn execute_with<R>(execute: impl FnOnce() -> R) -> R {
execute()
}
fn ext_wrapper<R>(func: impl FnOnce() -> R) -> R {
func()
}
}
pub trait Network {
fn _init();
fn _para_ids() -> Vec<u32>;
fn _relay_block_number() -> u32;
fn _set_relay_block_number(block_number: u32);
fn _process_messages();
fn _has_unprocessed_messages() -> bool;
fn _process_downward_messages();
fn _process_horizontal_messages();
fn _process_upward_messages();
fn _hrmp_channel_parachain_inherent_data(
type Bridge: Bridge;
fn init();
fn para_ids() -> Vec<u32>;
fn relay_block_number() -> u32;
fn set_relay_block_number(block_number: u32);
fn process_messages();
fn has_unprocessed_messages() -> bool;
fn process_downward_messages();
fn process_horizontal_messages();
fn process_upward_messages();
fn process_bridged_messages();
fn hrmp_channel_parachain_inherent_data(
para_id: u32,
relay_parent_number: u32,
) -> ParachainInherentData;
}
pub trait NetworkComponent<N: Network> {
pub trait NetworkComponent {
type Network: Network;
fn network_name() -> &'static str;
fn init() {
N::_init();
}
fn relay_block_number() -> u32 {
N::_relay_block_number()
}
fn set_relay_block_number(block_number: u32) {
N::_set_relay_block_number(block_number);
}
fn para_ids() -> Vec<u32> {
N::_para_ids()
}
fn send_horizontal_messages<I: Iterator<Item = (ParaId, RelayBlockNumber, Vec<u8>)>>(
to_para_id: u32,
iter: I,
@@ -153,15 +162,9 @@ pub trait NetworkComponent<N: Network> {
});
}
fn hrmp_channel_parachain_inherent_data(
para_id: u32,
relay_parent_number: u32,
) -> ParachainInherentData {
N::_hrmp_channel_parachain_inherent_data(para_id, relay_parent_number)
}
fn process_messages() {
N::_process_messages();
fn send_bridged_messages(msg: BridgeMessage) {
BRIDGED_MESSAGES
.with(|b| b.borrow_mut().get_mut(Self::network_name()).unwrap().push_back(msg));
}
}
@@ -190,6 +193,64 @@ pub trait Parachain: XcmpMessageHandler + DmpMessageHandler {
type ParachainInfo;
}
pub trait Bridge {
type Source: TestExt;
type Target: TestExt;
type Handler: BridgeMessageHandler;
fn init();
}
impl Bridge for () {
type Source = ();
type Target = ();
type Handler = ();
fn init() {}
}
#[derive(Clone, Default, Debug)]
pub struct BridgeMessage {
pub id: u32,
pub nonce: u64,
pub payload: Vec<u8>,
}
pub trait BridgeMessageHandler {
fn get_source_outbound_messages() -> Vec<BridgeMessage>;
fn dispatch_target_inbound_message(
message: BridgeMessage,
) -> Result<(), BridgeMessageDispatchError>;
fn notify_source_message_delivery(lane_id: u32);
}
impl BridgeMessageHandler for () {
fn get_source_outbound_messages() -> Vec<BridgeMessage> {
Default::default()
}
fn dispatch_target_inbound_message(
_message: BridgeMessage,
) -> Result<(), BridgeMessageDispatchError> {
Err(BridgeMessageDispatchError(Box::new("Not a bridge")))
}
fn notify_source_message_delivery(_lane_id: u32) {}
}
#[derive(Debug)]
pub struct BridgeMessageDispatchError(pub Box<dyn Debug>);
impl Error for BridgeMessageDispatchError {}
impl fmt::Display for BridgeMessageDispatchError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}
// Relay Chain Implementation
#[macro_export]
macro_rules! decl_test_relay_chains {
@@ -322,9 +383,9 @@ macro_rules! __impl_test_ext_for_relay_chain {
}
fn execute_with<R>(execute: impl FnOnce() -> R) -> R {
use $crate::{NetworkComponent};
use $crate::{NetworkComponent, Network};
// Make sure the Network is initialized
<$name>::init();
<$name as NetworkComponent>::Network::init();
let r = $ext_name.with(|v| v.borrow_mut().execute_with(execute));
@@ -334,7 +395,7 @@ macro_rules! __impl_test_ext_for_relay_chain {
use $crate::polkadot_primitives::runtime_api::runtime_decl_for_parachain_host::$api_version;
//TODO: mark sent count & filter out sent msg
for para_id in <$name>::para_ids() {
for para_id in<$name as NetworkComponent>::Network::para_ids() {
// downward messages
let downward_messages = <Self as RelayChain>::Runtime::dmq_contents(para_id.into())
.into_iter()
@@ -350,7 +411,7 @@ macro_rules! __impl_test_ext_for_relay_chain {
})
});
<$name>::process_messages();
<$name as NetworkComponent>::Network::process_messages();
r
}
@@ -368,10 +429,12 @@ macro_rules! __impl_test_ext_for_relay_chain {
#[macro_export]
macro_rules! __impl_relay {
($network_name:ident, $relay_chain:ty) => {
impl $crate::NetworkComponent<$network_name> for $relay_chain {
($network:ident, $relay_chain:ty) => {
impl $crate::NetworkComponent for $relay_chain {
type Network = $network;
fn network_name() -> &'static str {
stringify!($network_name)
stringify!($network)
}
}
@@ -549,24 +612,24 @@ macro_rules! __impl_test_ext_for_parachain {
}
fn execute_with<R>(execute: impl FnOnce() -> R) -> R {
use $crate::{Get, Hooks, NetworkComponent};
use $crate::{Get, Hooks, NetworkComponent, Network, Bridge};
// Make sure the Network is initialized
<$name>::init();
<$name as NetworkComponent>::Network::init();
let mut relay_block_number = <$name>::relay_block_number();
let mut relay_block_number = <$name as NetworkComponent>::Network::relay_block_number();
relay_block_number += 1;
<$name>::set_relay_block_number(relay_block_number);
<$name as NetworkComponent>::Network::set_relay_block_number(relay_block_number);
let para_id = <$name>::para_id().into();
$ext_name.with(|v| {
v.borrow_mut().execute_with(|| {
// Make sure it has been recorded properly
let relay_block_number = <$name>::relay_block_number();
let relay_block_number = <$name as NetworkComponent>::Network::relay_block_number();
let _ = <Self as Parachain>::ParachainSystem::set_validation_data(
<Self as Parachain>::RuntimeOrigin::none(),
<$name>::hrmp_channel_parachain_inherent_data(para_id, relay_block_number),
<$name as NetworkComponent>::Network::hrmp_channel_parachain_inherent_data(para_id, relay_block_number),
);
})
});
@@ -588,12 +651,12 @@ macro_rules! __impl_test_ext_for_parachain {
Default::default(),
);
// get messages
// get xcmp messages
<Self as Parachain>::ParachainSystem::on_finalize(block_number);
let collation_info = <Self as Parachain>::ParachainSystem::collect_collation_info(&mock_header);
// send upward messages
let relay_block_number = <$name>::relay_block_number();
let relay_block_number = <$name as NetworkComponent>::Network::relay_block_number();
for msg in collation_info.upward_messages.clone() {
<$name>::send_upward_message(para_id, msg);
}
@@ -606,12 +669,22 @@ macro_rules! __impl_test_ext_for_parachain {
);
}
// get bridge messages
type NetworkBridge = <<$name as NetworkComponent>::Network as Network>::Bridge;
let bridge_messages = <NetworkBridge as Bridge>::Handler::get_source_outbound_messages();
// send bridged messages
for msg in bridge_messages {
<$name>::send_bridged_messages(msg);
}
// clean messages
<Self as Parachain>::ParachainSystem::on_initialize(block_number);
})
});
<$name>::process_messages();
<$name as NetworkComponent>::Network::process_messages();
r
}
@@ -629,10 +702,12 @@ macro_rules! __impl_test_ext_for_parachain {
#[macro_export]
macro_rules! __impl_parachain {
($network_name:ident, $parachain:ty) => {
impl $crate::NetworkComponent<$network_name> for $parachain {
($network:ident, $parachain:ty) => {
impl $crate::NetworkComponent for $parachain {
type Network = $network;
fn network_name() -> &'static str {
stringify!($network_name)
stringify!($network)
}
}
@@ -645,6 +720,10 @@ macro_rules! __impl_parachain {
(Parent).into()
}
pub fn sibling_location_of(para_id: $crate::ParaId) -> $crate::MultiLocation {
(Parent, X1(Parachain(para_id.into()))).into()
}
pub fn account_id_of(seed: &str) -> $crate::AccountId {
$crate::get_account_id_from_seed::<sr25519::Public>(seed)
}
@@ -677,7 +756,7 @@ macro_rules! __impl_parachain {
}
fn prepare_for_xcmp() {
use $crate::NetworkComponent;
use $crate::{Network, NetworkComponent};
let para_id = Self::para_id();
<Self as TestExt>::ext_wrapper(|| {
@@ -687,7 +766,10 @@ macro_rules! __impl_parachain {
let _ = <Self as Parachain>::ParachainSystem::set_validation_data(
<Self as Parachain>::RuntimeOrigin::none(),
Self::hrmp_channel_parachain_inherent_data(para_id.into(), 1),
<Self as NetworkComponent>::Network::hrmp_channel_parachain_inherent_data(
para_id.into(),
1,
),
);
// set `AnnouncedHrmpMessagesPerCandidate`
<Self as Parachain>::ParachainSystem::on_initialize(block_number);
@@ -705,6 +787,7 @@ macro_rules! decl_test_networks {
pub struct $name:ident {
relay_chain = $relay_chain:ty,
parachains = vec![ $( $parachain:ty, )* ],
bridge = $bridge:ty
}
),
+
@@ -721,16 +804,18 @@ macro_rules! decl_test_networks {
$crate::DMP_DONE.with(|b| b.borrow_mut().remove(stringify!($name)));
$crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().remove(stringify!($name)));
$crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().remove(stringify!($name)));
$crate::BRIDGED_MESSAGES.with(|b| b.borrow_mut().remove(stringify!($name)));
$crate::RELAY_BLOCK_NUMBER.with(|b| b.borrow_mut().remove(stringify!($name)));
<$relay_chain>::reset_ext();
$( <$parachain>::reset_ext(); )*
$( <$parachain>::prepare_for_xcmp(); )*
}
}
impl $crate::Network for $name {
fn _init() {
type Bridge = $bridge;
fn init() {
// If Network has not been itialized yet, it gets initialized
if $crate::INITIALIZED.with(|b| b.borrow_mut().get(stringify!($name)).is_none()) {
$crate::INITIALIZED.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), true));
@@ -738,42 +823,45 @@ macro_rules! decl_test_networks {
$crate::DMP_DONE.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new()));
$crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new()));
$crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new()));
$crate::BRIDGED_MESSAGES.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new()));
$crate::RELAY_BLOCK_NUMBER.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), 1));
$crate::PARA_IDS.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), Self::_para_ids()));
$crate::PARA_IDS.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), Self::para_ids()));
$( <$parachain>::prepare_for_xcmp(); )*
}
}
fn _para_ids() -> Vec<u32> {
fn para_ids() -> Vec<u32> {
vec![$(
<$parachain>::para_id().into(),
)*]
}
fn _relay_block_number() -> u32 {
fn relay_block_number() -> u32 {
$crate::RELAY_BLOCK_NUMBER.with(|v| *v.clone().borrow().get(stringify!($name)).unwrap())
}
fn _set_relay_block_number(block_number: u32) {
fn set_relay_block_number(block_number: u32) {
$crate::RELAY_BLOCK_NUMBER.with(|v| v.borrow_mut().insert(stringify!($name).to_string(), block_number));
}
fn _process_messages() {
while Self::_has_unprocessed_messages() {
Self::_process_upward_messages();
Self::_process_horizontal_messages();
Self::_process_downward_messages();
fn process_messages() {
while Self::has_unprocessed_messages() {
Self::process_upward_messages();
Self::process_horizontal_messages();
Self::process_downward_messages();
Self::process_bridged_messages();
}
}
fn _has_unprocessed_messages() -> bool {
fn has_unprocessed_messages() -> bool {
$crate::DOWNWARD_MESSAGES.with(|b| !b.borrow_mut().get_mut(stringify!($name)).unwrap().is_empty())
|| $crate::HORIZONTAL_MESSAGES.with(|b| !b.borrow_mut().get_mut(stringify!($name)).unwrap().is_empty())
|| $crate::UPWARD_MESSAGES.with(|b| !b.borrow_mut().get_mut(stringify!($name)).unwrap().is_empty())
|| $crate::BRIDGED_MESSAGES.with(|b| !b.borrow_mut().get_mut(stringify!($name)).unwrap().is_empty())
}
fn _process_downward_messages() {
fn process_downward_messages() {
use $crate::{DmpMessageHandler, Bounded};
use polkadot_parachain::primitives::RelayChainBlockNumber;
@@ -794,6 +882,7 @@ macro_rules! decl_test_networks {
}).collect::<Vec<(RelayChainBlockNumber, Vec<u8>)>>();
if msgs.len() != 0 {
<$parachain>::handle_dmp_messages(msgs.clone().into_iter(), $crate::Weight::max_value());
$crate::log::debug!(target: concat!("dmp::", stringify!($name)) , "DMP messages processed {:?} to para_id {:?}", msgs.clone(), &to_para_id);
for m in msgs {
$crate::DMP_DONE.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().push_back((to_para_id, m.0, m.1)));
}
@@ -803,7 +892,7 @@ macro_rules! decl_test_networks {
}
}
fn _process_horizontal_messages() {
fn process_horizontal_messages() {
use $crate::{XcmpMessageHandler, Bounded};
while let Some((to_para_id, messages))
@@ -814,12 +903,13 @@ macro_rules! decl_test_networks {
if $crate::PARA_IDS.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().contains(&to_para_id)) && para_id == to_para_id {
<$parachain>::handle_xcmp_messages(iter.clone(), $crate::Weight::max_value());
$crate::log::debug!(target: concat!("hrmp::", stringify!($name)) , "HRMP messages processed {:?} to para_id {:?}", &messages, &to_para_id);
}
)*
}
}
fn _process_upward_messages() {
fn process_upward_messages() {
use $crate::{Bounded, ProcessMessage, WeightMeter};
use sp_core::Encode;
while let Some((from_para_id, msg)) = $crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().pop_front()) {
@@ -830,10 +920,33 @@ macro_rules! decl_test_networks {
&mut weight_meter,
&mut msg.using_encoded(sp_core::blake2_256),
);
$crate::log::debug!(target: concat!("ump::", stringify!($name)) , "Upward message processed {:?} from para_id {:?}", &msg, &from_para_id);
}
}
fn _hrmp_channel_parachain_inherent_data(
fn process_bridged_messages() {
use $crate::Bridge;
// Make sure both, including the target `Network` are initialized
<Self::Bridge as Bridge>::init();
while let Some(msg) = $crate::BRIDGED_MESSAGES.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().pop_front()) {
let dispatch_result = <<Self::Bridge as $crate::Bridge>::Target as TestExt>::ext_wrapper(|| {
<<Self::Bridge as Bridge>::Handler as BridgeMessageHandler>::dispatch_target_inbound_message(msg.clone())
});
match dispatch_result {
Err(e) => panic!("Error {:?} processing bridged message: {:?}", e, msg.clone()),
Ok(()) => {
<<Self::Bridge as $crate::Bridge>::Source as TestExt>::ext_wrapper(|| {
<<Self::Bridge as Bridge>::Handler as BridgeMessageHandler>::notify_source_message_delivery(msg.id);
});
$crate::log::debug!(target: concat!("bridge::", stringify!($name)) , "Bridged message processed {:?}", msg.clone());
}
}
}
}
fn hrmp_channel_parachain_inherent_data(
para_id: u32,
relay_parent_number: u32,
) -> $crate::ParachainInherentData {
@@ -891,6 +1004,38 @@ macro_rules! decl_test_networks {
};
}
#[macro_export]
macro_rules! decl_test_bridges {
(
$(
pub struct $name:ident {
source = $source:ty,
target = $target:ty,
handler = $handler:ty
}
),
+
) => {
$(
#[derive(Debug)]
pub struct $name;
impl $crate::Bridge for $name {
type Source = $source;
type Target = $target;
type Handler = $handler;
fn init() {
use $crate::{NetworkComponent, Network};
// Make sure source and target `Network` has been initialized
<$source as NetworkComponent>::Network::init();
<$target as NetworkComponent>::Network::init();
}
}
)+
};
}
#[macro_export]
macro_rules! assert_expected_events {
( $chain:ident, vec![$( $event_pat:pat => { $($attr:ident : $condition:expr, )* }, )*] ) => {
@@ -900,7 +1045,7 @@ macro_rules! assert_expected_events {
let mut event_message: Vec<String> = Vec::new();
let event_received = <$chain>::events().iter().any(|event| {
$crate::log::debug!(target: format!("events::{}", stringify!($chain)).to_lowercase().as_str(), "{:?}", event);
$crate::log::debug!(target: concat!("events::", stringify!($chain)), "{:?}", event);
match event {
$event_pat => {
@@ -936,6 +1081,20 @@ macro_rules! bx {
};
}
#[macro_export]
macro_rules! decl_test_sender_receiver_accounts_parameter_types {
( $( $chain:ident { sender: $sender:expr, receiver: $receiver:expr }),+ ) => {
$crate::paste::paste! {
parameter_types! {
$(
pub [<$chain Sender>]: $crate::AccountId = <$chain>::account_id_of($sender);
pub [<$chain Receiver>]: $crate::AccountId = <$chain>::account_id_of($receiver);
)+
}
}
};
}
pub mod helpers {
use super::Weight;