From de0fad96031bdfc5ff7520590b4cc9dd69a0eb5e Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 29 Apr 2024 21:49:08 +0200 Subject: [PATCH] Integrate new xcm-emulator (#1324) * Integrate new xcm-emulator environment * Utilize new xcm-emulator interfaces * Spawn relay-para network using patched xcm-emulator * Use proper collator genesis config * Fix Rococo tests * Finalize Battery Station XCM tests * Finalize Zeitgeist XCM tests --- Cargo.lock | 112 ++++- Cargo.toml | 11 +- runtime/battery-station/Cargo.toml | 7 +- .../xcm/genesis/battery_station.rs | 79 +++ .../src/integration_tests/xcm/genesis/mod.rs | 19 + .../integration_tests/xcm/genesis/rococo.rs | 149 ++++++ .../src/integration_tests/xcm/mod.rs | 3 +- .../src/integration_tests/xcm/setup.rs | 123 ++--- .../src/integration_tests/xcm/test_net.rs | 157 +++--- .../xcm/tests/currency_id_convert.rs | 22 +- .../integration_tests/xcm/tests/transfers.rs | 380 +++++++-------- .../battery-station/src/parachain_params.rs | 2 +- .../battery-station/src/xcm_config/config.rs | 2 +- runtime/zeitgeist/Cargo.toml | 6 +- .../src/integration_tests/xcm/genesis/mod.rs | 19 + .../integration_tests/xcm/genesis/polkadot.rs | 134 +++++ .../xcm/genesis/zeitgeist.rs | 83 ++++ .../src/integration_tests/xcm/mod.rs | 3 +- .../src/integration_tests/xcm/setup.rs | 123 ++--- .../src/integration_tests/xcm/test_net.rs | 154 +++--- .../xcm/tests/currency_id_convert.rs | 6 +- .../integration_tests/xcm/tests/transfers.rs | 458 +++++++++--------- runtime/zeitgeist/src/parachain_params.rs | 2 +- runtime/zeitgeist/src/xcm_config/config.rs | 2 +- 24 files changed, 1239 insertions(+), 817 deletions(-) create mode 100644 runtime/battery-station/src/integration_tests/xcm/genesis/battery_station.rs create mode 100644 runtime/battery-station/src/integration_tests/xcm/genesis/mod.rs create mode 100644 runtime/battery-station/src/integration_tests/xcm/genesis/rococo.rs create mode 100644 runtime/zeitgeist/src/integration_tests/xcm/genesis/mod.rs create mode 100644 runtime/zeitgeist/src/integration_tests/xcm/genesis/polkadot.rs create mode 100644 runtime/zeitgeist/src/integration_tests/xcm/genesis/zeitgeist.rs diff --git a/Cargo.lock b/Cargo.lock index a0b7d23b3..13f5eccad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -832,6 +832,7 @@ dependencies = [ "pallet-democracy", "pallet-grandpa", "pallet-identity", + "pallet-im-online", "pallet-insecure-randomness-collective-flip", "pallet-membership", "pallet-message-queue", @@ -857,8 +858,11 @@ dependencies = [ "scale-info", "session-keys-primitives", "sp-api", + "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", + "sp-consensus-babe", + "sp-consensus-beefy", "sp-consensus-grandpa", "sp-core", "sp-debug-derive", @@ -876,7 +880,7 @@ dependencies = [ "substrate-fixed", "substrate-wasm-builder", "test-case", - "xcm-simulator", + "xcm-emulator", "zeitgeist-primitives", "zrml-asset-router", "zrml-authorized", @@ -6392,6 +6396,25 @@ dependencies = [ "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0)", ] +[[package]] +name = "pallet-collator-selection" +version = "3.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0#c8d2251cafadc108ba2f1f8a3208dc547ff38901" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "parity-scale-codec", + "rand 0.8.5", + "scale-info", + "sp-runtime", + "sp-staking", + "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0)", +] + [[package]] name = "pallet-collective" version = "4.0.0-dev" @@ -7299,6 +7322,42 @@ dependencies = [ "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0)", ] +[[package]] +name = "parachains-common" +version = "1.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0#c8d2251cafadc108ba2f1f8a3208dc547ff38901" +dependencies = [ + "cumulus-primitives-core", + "cumulus-primitives-utility", + "frame-support", + "frame-system", + "kusama-runtime-constants", + "log", + "num-traits", + "pallet-asset-tx-payment", + "pallet-assets", + "pallet-authorship", + "pallet-balances", + "pallet-collator-selection", + "parity-scale-codec", + "polkadot-core-primitives", + "polkadot-primitives", + "polkadot-runtime-constants", + "rococo-runtime-constants", + "scale-info", + "smallvec", + "sp-consensus-aura", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0)", + "staging-xcm", + "staging-xcm-builder", + "staging-xcm-executor", + "substrate-wasm-builder", + "westend-runtime-constants", +] + [[package]] name = "parity-db" version = "0.4.13" @@ -14684,34 +14743,48 @@ dependencies = [ ] [[package]] -name = "xcm-procedural" -version = "1.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0#c8d2251cafadc108ba2f1f8a3208dc547ff38901" -dependencies = [ - "Inflector", - "proc-macro2", - "quote", - "syn 2.0.60", -] - -[[package]] -name = "xcm-simulator" -version = "1.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0#c8d2251cafadc108ba2f1f8a3208dc547ff38901" +name = "xcm-emulator" +version = "0.1.0" +source = "git+https://github.com/zeitgeistpm/polkadot-sdk?branch=release-polkadot-v1.1.0-xcm-emulator-type-fix#84163279ce450f608de56b9d5151e65fe4bec51a" dependencies = [ + "cumulus-pallet-parachain-system", + "cumulus-primitives-core", + "cumulus-primitives-parachain-inherent", + "cumulus-test-relay-sproof-builder", "frame-support", + "frame-system", + "impl-trait-for-tuples", + "lazy_static", + "log", + "pallet-balances", + "pallet-message-queue", + "parachains-common", "parity-scale-codec", "paste", - "polkadot-core-primitives", "polkadot-parachain-primitives", + "polkadot-primitives", "polkadot-runtime-parachains", + "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0)", + "sp-core", "sp-io", + "sp-runtime", "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0)", + "sp-tracing", "staging-xcm", - "staging-xcm-builder", "staging-xcm-executor", ] +[[package]] +name = "xcm-procedural" +version = "1.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.1.0#c8d2251cafadc108ba2f1f8a3208dc547ff38901" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "yamux" version = "0.10.2" @@ -14901,6 +14974,7 @@ dependencies = [ "pallet-democracy", "pallet-grandpa", "pallet-identity", + "pallet-im-online", "pallet-insecure-randomness-collective-flip", "pallet-membership", "pallet-message-queue", @@ -14925,8 +14999,10 @@ dependencies = [ "scale-info", "session-keys-primitives", "sp-api", + "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", + "sp-consensus-babe", "sp-consensus-grandpa", "sp-core", "sp-debug-derive", @@ -14944,7 +15020,7 @@ dependencies = [ "substrate-fixed", "substrate-wasm-builder", "test-case", - "xcm-simulator", + "xcm-emulator", "zeitgeist-primitives", "zrml-asset-router", "zrml-authorized", diff --git a/Cargo.toml b/Cargo.toml index 3d05054d1..cd241b418 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -165,7 +165,6 @@ substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } try-runtime-cli = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } -xcm-simulator = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } # Substrate (wasm) frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } @@ -186,6 +185,7 @@ pallet-contracts-primitives = { git = "https://github.com/paritytech/polkadot-sd pallet-democracy = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } pallet-grandpa = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } pallet-identity = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } +pallet-im-online = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } pallet-membership = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } @@ -203,8 +203,11 @@ parity-scale-codec = { version = "3.6.9", default-features = false } scale-info = { version = "2.11.1", default-features = false } sp-api = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } sp-arithmetic = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } +sp-authority-discovery = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } +sp-consensus-babe = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } +sp-consensus-beefy = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } sp-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } sp-debug-derive = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } @@ -222,6 +225,7 @@ substrate-fixed = { git = "https://github.com/encointer/substrate-fixed", defaul polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } polkadot-service = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } polkadot-test-service = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } +xcm-emulator = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } # Polkadot / XCM (wasm) pallet-message-queue = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } @@ -231,6 +235,7 @@ polkadot-primitives = { git = "https://github.com/paritytech/polkadot-sdk", bran polkadot-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } rococo-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } +rococo-runtime-constants = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } xcm = { package = "staging-xcm", git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } @@ -352,6 +357,10 @@ panic = "unwind" # Commits: # - cb803be8cdc52d020890308a2076d752a8c4ce5c pallet-assets = { git = "https://github.com/zeitgeistpm/polkadot-sdk", branch = "zeitgeist-polkadot-v1.1.0" } +# xcm-emulator incompatible block number type fixed +# Commits: +# - +xcm-emulator = { git = "https://github.com/zeitgeistpm/polkadot-sdk", branch = "release-polkadot-v1.1.0-xcm-emulator-type-fix" } [patch."https://github.com/galacticcouncil/HydraDX-node"] # Ensure same Substrate dependencies are used everywhere diff --git a/runtime/battery-station/Cargo.toml b/runtime/battery-station/Cargo.toml index cf6c27557..417f6bd41 100644 --- a/runtime/battery-station/Cargo.toml +++ b/runtime/battery-station/Cargo.toml @@ -129,9 +129,13 @@ zrml-swaps-runtime-api = { workspace = true } [dev-dependencies] env_logger = { workspace = true } +pallet-im-online = { workspace = true, features = ["default"] } +sp-authority-discovery = { workspace = true, features = ["default"] } +sp-consensus-babe = { workspace = true, features = ["default"] } +sp-consensus-beefy = { workspace = true, features = ["default"] } sp-io = { workspace = true, features = ["default"] } test-case = { workspace = true } -xcm-simulator = { workspace = true } +xcm-emulator = { workspace = true } [features] default = ["std"] @@ -333,6 +337,7 @@ std = [ # Zeitgeist "zeitgeist-primitives/std", + "zrml-asset-router/std", "zrml-authorized/std", "zrml-court/std", "zrml-hybrid-router/std", diff --git a/runtime/battery-station/src/integration_tests/xcm/genesis/battery_station.rs b/runtime/battery-station/src/integration_tests/xcm/genesis/battery_station.rs new file mode 100644 index 000000000..79ede9c15 --- /dev/null +++ b/runtime/battery-station/src/integration_tests/xcm/genesis/battery_station.rs @@ -0,0 +1,79 @@ +// Copyright 2024 Forecasting Technologies LTD. +// +// This file is part of Zeitgeist. +// +// Zeitgeist 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. +// +// Zeitgeist 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 Zeitgeist. If not, see . + +use crate::{ + integration_tests::xcm::setup::{ + accounts, ztg, BTC_ID, FOREIGN_PARENT_ID, FOREIGN_SIBLING_ID, FOREIGN_ZTG_ID, + }, + parachain_params::MinCandidateStk, + parameters::ZeitgeistTreasuryAccount, + Asset, +}; +use nimbus_primitives::NimbusId; +use sp_core::storage::Storage; +use sp_runtime::BuildStorage; + +const ENDOWMENT: u128 = ztg(1_000_000); +const SAFE_XCM_VERSION: u32 = 2; + +pub(crate) fn genesis(parachain_id: u32) -> Storage { + let genesis_config = crate::RuntimeGenesisConfig { + author_mapping: crate::AuthorMappingConfig { + mappings: vec![( + accounts::get_from_seed::(accounts::ALICE), + accounts::alice(), + )], + }, + balances: crate::BalancesConfig { + balances: accounts::init_balances().iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + parachain_info: crate::ParachainInfoConfig { + parachain_id: parachain_id.into(), + ..Default::default() + }, + parachain_staking: crate::ParachainStakingConfig { + candidates: vec![(accounts::alice(), MinCandidateStk::get())], + ..Default::default() + }, + polkadot_xcm: crate::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + ..Default::default() + }, + system: crate::SystemConfig { + code: crate::WASM_BINARY.unwrap().to_vec(), + ..Default::default() + }, + tokens: crate::TokensConfig { + balances: accounts::init_balances() + .iter() + .chain(vec![(ZeitgeistTreasuryAccount::get())].iter()) + .map(|k| { + vec![ + (k.clone(), Asset::from(FOREIGN_PARENT_ID).try_into().unwrap(), ENDOWMENT), + (k.clone(), Asset::from(FOREIGN_SIBLING_ID).try_into().unwrap(), ENDOWMENT), + (k.clone(), Asset::from(FOREIGN_ZTG_ID).try_into().unwrap(), ENDOWMENT), + (k.clone(), Asset::from(BTC_ID).try_into().unwrap(), ENDOWMENT), + ] + }) + .flatten() + .collect::>(), + }, + ..Default::default() + }; + + genesis_config.build_storage().unwrap() +} diff --git a/runtime/battery-station/src/integration_tests/xcm/genesis/mod.rs b/runtime/battery-station/src/integration_tests/xcm/genesis/mod.rs new file mode 100644 index 000000000..1f5a5cdbe --- /dev/null +++ b/runtime/battery-station/src/integration_tests/xcm/genesis/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2024 Forecasting Technologies LTD. +// +// This file is part of Zeitgeist. +// +// Zeitgeist 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. +// +// Zeitgeist 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 Zeitgeist. If not, see . + +pub(super) mod battery_station; +pub(super) mod rococo; diff --git a/runtime/battery-station/src/integration_tests/xcm/genesis/rococo.rs b/runtime/battery-station/src/integration_tests/xcm/genesis/rococo.rs new file mode 100644 index 000000000..6d37c8450 --- /dev/null +++ b/runtime/battery-station/src/integration_tests/xcm/genesis/rococo.rs @@ -0,0 +1,149 @@ +// Copyright 2024 Forecasting Technologies LTD. +// +// Copyright (C) Parity Technologies (UK) Ltd. +// +// This file is part of Zeitgeist. +// +// Zeitgeist 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. +// +// Zeitgeist 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 Zeitgeist. If not, see . + +// TODO(#1325): Replace with crate "rococo-emulated-chain" from Cumulus starting from polkadot-v1.4.0 + +use crate::integration_tests::xcm::setup::{accounts, accounts::get_from_seed, roc}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use polkadot_primitives::{AccountId, AssignmentId, BlockNumber, ValidatorId}; +use polkadot_runtime_parachains::configuration::HostConfiguration; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_consensus_babe::AuthorityId as BabeId; +use sp_consensus_beefy::ecdsa_crypto::AuthorityId as BeefyId; +use sp_consensus_grandpa::AuthorityId as GrandpaId; +use sp_core::{sr25519, storage::Storage}; +use sp_runtime::BuildStorage; +use xcm_emulator::helpers::get_account_id_from_seed; + +const ENDOWMENT: u128 = roc(1_000_000); + +fn session_keys( + grandpa: GrandpaId, + babe: BabeId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + beefy: BeefyId, +) -> rococo_runtime::SessionKeys { + rococo_runtime::SessionKeys { + grandpa, + babe, + im_online, + para_validator, + para_assignment, + authority_discovery, + beefy, + } +} + +fn get_host_config() -> HostConfiguration { + HostConfiguration { + max_upward_queue_count: 10, + max_upward_queue_size: 51200, + max_upward_message_size: 51200, + max_upward_message_num_per_candidate: 10, + max_downward_message_size: 51200, + hrmp_sender_deposit: 0, + hrmp_recipient_deposit: 0, + hrmp_channel_max_capacity: 1000, + hrmp_channel_max_message_size: 102400, + hrmp_channel_max_total_size: 102400, + hrmp_max_parachain_outbound_channels: 30, + hrmp_max_parachain_inbound_channels: 30, + ..Default::default() + } +} + +mod validators { + use super::*; + + pub fn initial_authorities() -> Vec<( + AccountId, + AccountId, + GrandpaId, + BabeId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )> { + let seed = "Alice"; + vec![( + get_account_id_from_seed::(&format!("{}//stash", seed)), + get_account_id_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + )] + } +} + +pub(crate) fn genesis() -> Storage { + let genesis_config = rococo_runtime::RuntimeGenesisConfig { + system: rococo_runtime::SystemConfig { + code: rococo_runtime::WASM_BINARY.unwrap().to_vec(), + ..Default::default() + }, + balances: rococo_runtime::BalancesConfig { + balances: accounts::init_balances().iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + 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(), + x.8.clone(), + ), + ) + }) + .collect::>(), + }, + babe: rococo_runtime::BabeConfig { + authorities: Default::default(), + epoch_config: Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + sudo: rococo_runtime::SudoConfig { + key: Some(get_account_id_from_seed::("Alice")), + }, + configuration: rococo_runtime::ConfigurationConfig { config: get_host_config() }, + registrar: rococo_runtime::RegistrarConfig { + next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, + ..Default::default() + }, + ..Default::default() + }; + + genesis_config.build_storage().unwrap() +} diff --git a/runtime/battery-station/src/integration_tests/xcm/mod.rs b/runtime/battery-station/src/integration_tests/xcm/mod.rs index d37a62036..9ba9a1de3 100644 --- a/runtime/battery-station/src/integration_tests/xcm/mod.rs +++ b/runtime/battery-station/src/integration_tests/xcm/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2022 Forecasting Technologies LTD. +// Copyright 2022-2024 Forecasting Technologies LTD. // // This file is part of Zeitgeist. // @@ -17,6 +17,7 @@ #![cfg(all(feature = "parachain", test))] +mod genesis; mod setup; mod test_net; mod tests; diff --git a/runtime/battery-station/src/integration_tests/xcm/setup.rs b/runtime/battery-station/src/integration_tests/xcm/setup.rs index 7e033b5c3..7c54fc5e5 100644 --- a/runtime/battery-station/src/integration_tests/xcm/setup.rs +++ b/runtime/battery-station/src/integration_tests/xcm/setup.rs @@ -1,5 +1,4 @@ // Copyright 2022-2024 Forecasting Technologies LTD. -// Copyright 2021 Centrifuge Foundation (centrifuge.io). // // This file is part of Zeitgeist. // @@ -18,102 +17,70 @@ use crate::{ xcm_config::config::{battery_station, general_key}, - AccountId, AssetRegistry, AssetRegistryStringLimit, Assets, Balance, ExistentialDeposit, - Runtime, RuntimeOrigin, System, + AccountId, AssetRegistry, AssetRegistryStringLimit, Balance, ExistentialDeposit, RuntimeOrigin, }; use frame_support::assert_ok; use orml_traits::asset_registry::AssetMetadata; -use sp_runtime::{AccountId32, BuildStorage}; +use sp_core::{sr25519, Pair, Public}; use xcm::{ latest::{Junction::Parachain, Junctions::X2, MultiLocation}, VersionedMultiLocation, }; +use xcm_emulator::helpers::get_account_id_from_seed; use zeitgeist_primitives::types::{CustomMetadata, XcmAsset}; -pub(super) struct ExtBuilder { - balances: Vec<(AccountId, Assets, Balance)>, - parachain_id: u32, - safe_xcm_version: Option, -} - -impl Default for ExtBuilder { - fn default() -> Self { - Self { balances: vec![], parachain_id: battery_station::ID, safe_xcm_version: None } - } -} - -impl ExtBuilder { - pub fn set_balances(mut self, balances: Vec<(AccountId, Assets, Balance)>) -> Self { - self.balances = balances; - self +pub(super) mod accounts { + use super::*; + pub const ALICE: &str = "Alice"; + pub const BOB: &str = "Bob"; + pub const CHARLIE: &str = "Charlie"; + pub const DAVE: &str = "Dave"; + pub const EVE: &str = "Eve"; + pub const FERDIE: &str = "Ferdie"; + pub const ALICE_STASH: &str = "Alice//stash"; + pub const BOB_STASH: &str = "Bob//stash"; + pub const CHARLIE_STASH: &str = "Charlie//stash"; + pub const DAVE_STASH: &str = "Dave//stash"; + pub const EVE_STASH: &str = "Eve//stash"; + pub const FERDIE_STASH: &str = "Ferdie//stash"; + + pub fn init_balances() -> Vec { + vec![ + get_account_id_from_seed::(ALICE), + get_account_id_from_seed::(BOB), + get_account_id_from_seed::(CHARLIE), + get_account_id_from_seed::(DAVE), + get_account_id_from_seed::(EVE), + get_account_id_from_seed::(FERDIE), + get_account_id_from_seed::(ALICE_STASH), + get_account_id_from_seed::(BOB_STASH), + get_account_id_from_seed::(CHARLIE_STASH), + get_account_id_from_seed::(DAVE_STASH), + get_account_id_from_seed::(EVE_STASH), + get_account_id_from_seed::(FERDIE_STASH), + ] } - pub fn set_parachain_id(mut self, parachain_id: u32) -> Self { - self.parachain_id = parachain_id; - self + pub fn alice() -> AccountId { + get_account_id_from_seed::(ALICE) } - pub fn with_safe_xcm_version(mut self, safe_xcm_version: u32) -> Self { - self.safe_xcm_version = Some(safe_xcm_version); - self + pub fn bob() -> AccountId { + get_account_id_from_seed::(BOB) } - pub fn build(self) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let native_currency_id = Assets::Ztg; - - pallet_balances::GenesisConfig:: { - balances: self - .balances - .clone() - .into_iter() - .filter(|(_, currency_id, _)| *currency_id == native_currency_id) - .map(|(account_id, _, initial_balance)| (account_id, initial_balance)) - .collect::>(), - } - .assimilate_storage(&mut t) - .unwrap(); - - orml_tokens::GenesisConfig:: { - balances: self - .balances - .into_iter() - .filter(|(_, currency_id, _)| *currency_id != native_currency_id) - .map(|(account_id, currency_id, initial_balance)| { - (account_id, currency_id.try_into().unwrap(), initial_balance) - }) - .collect::>(), - } - .assimilate_storage(&mut t) - .unwrap(); - - parachain_info::GenesisConfig:: { - _config: Default::default(), - parachain_id: self.parachain_id.into(), - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_xcm::GenesisConfig:: { - _config: Default::default(), - safe_xcm_version: self.safe_xcm_version, - } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext + /// Helper function to generate a crypto pair from seed + pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() } } -/// Accounts -pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); -pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); - /// A PARA ID used for a sibling parachain. /// It must be one that doesn't collide with any other in use. pub const PARA_ID_SIBLING: u32 = 3000; +pub const PARA_ID_BATTERY_STATION: u32 = battery_station::ID; /// IDs that are used to represent tokens from other chains pub const FOREIGN_ZTG_ID: XcmAsset = XcmAsset::ForeignAsset(0); @@ -158,7 +125,7 @@ pub(super) const fn adjusted_balance(foreign_base: Balance, amount: Balance) -> // Multilocations that are used to represent tokens from other chains #[inline] pub(super) fn foreign_ztg_multilocation() -> MultiLocation { - MultiLocation::new(1, X2(Parachain(battery_station::ID), general_key(battery_station::KEY))) + MultiLocation::new(1, X2(Parachain(PARA_ID_BATTERY_STATION), general_key(battery_station::KEY))) } #[inline] @@ -237,7 +204,7 @@ pub(super) fn sibling_parachain_account() -> AccountId { #[inline] pub(super) fn zeitgeist_parachain_account() -> AccountId { - parachain_account(battery_station::ID) + parachain_account(PARA_ID_BATTERY_STATION) } #[inline] diff --git a/runtime/battery-station/src/integration_tests/xcm/test_net.rs b/runtime/battery-station/src/integration_tests/xcm/test_net.rs index 358110eb1..8b11bc5ef 100644 --- a/runtime/battery-station/src/integration_tests/xcm/test_net.rs +++ b/runtime/battery-station/src/integration_tests/xcm/test_net.rs @@ -1,5 +1,4 @@ // Copyright 2022-2024 Forecasting Technologies LTD. -// Copyright 2021-2022 Centrifuge GmbH (centrifuge.io). // // This file is part of Zeitgeist. // @@ -16,108 +15,80 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . +use super::{ + genesis::{battery_station, rococo}, + setup::{PARA_ID_BATTERY_STATION, PARA_ID_SIBLING}, +}; use crate::{ - parameters::ZeitgeistTreasuryAccount, xcm_config::config::battery_station, Assets, DmpQueue, - XcmpQueue, + xcm_config::config::LocationToAccountId, AssetManager, Balances, DmpQueue, ParachainInfo, + PolkadotXcm, XTokens, XcmpQueue, +}; +use xcm_emulator::{ + decl_test_networks, decl_test_parachains, decl_test_relay_chains, DefaultMessageProcessor, }; -use polkadot_runtime_parachains::configuration::HostConfiguration; -use sp_runtime::BuildStorage; -use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; - -use super::setup::{roc, ztg, ExtBuilder, ALICE, FOREIGN_PARENT_ID, PARA_ID_SIBLING}; - -decl_test_relay_chain! { - pub struct RococoNet { - Runtime = rococo_runtime::Runtime, - RuntimeCall = rococo_runtime::RuntimeCall, - RuntimeEvent = rococo_runtime::RuntimeEvent, - XcmConfig = rococo_runtime::XcmConfig, - MessageQueue = rococo_runtime::MessageQueue, - System = rococo_runtime::System, - new_ext = relay_ext(), - } -} -decl_test_parachain! { - pub struct Zeitgeist { - Runtime = Runtime, - XcmpMessageHandler = XcmpQueue, - DmpMessageHandler = DmpQueue, - new_ext = para_ext(battery_station::ID), - } +decl_test_relay_chains! { + #[api_version(5)] + pub struct Rococo { + genesis = rococo::genesis(), + on_init = (), + runtime = rococo_runtime, + core = { + MessageProcessor: DefaultMessageProcessor, + SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, + }, + pallets = { + XcmPallet: rococo_runtime::XcmPallet, + Sudo: rococo_runtime::Sudo, + Balances: rococo_runtime::Balances, + } + }, } -decl_test_parachain! { +decl_test_parachains! { + pub struct BatteryStation { + genesis = battery_station::genesis(PARA_ID_BATTERY_STATION), + on_init = (), + runtime = crate, + core = { + XcmpMessageHandler: XcmpQueue, + DmpMessageHandler: DmpQueue, + LocationToAccountId: LocationToAccountId, + ParachainInfo: ParachainInfo, + }, + pallets = { + PolkadotXcm: PolkadotXcm, + AssetManager: AssetManager, + Balances: Balances, + XTokens: XTokens, + } + }, pub struct Sibling { - Runtime = Runtime, - XcmpMessageHandler = XcmpQueue, - DmpMessageHandler = DmpQueue, - new_ext = para_ext(PARA_ID_SIBLING), - } + genesis = battery_station::genesis(PARA_ID_SIBLING), + on_init = (), + runtime = crate, + core = { + XcmpMessageHandler: XcmpQueue, + DmpMessageHandler: DmpQueue, + LocationToAccountId: LocationToAccountId, + ParachainInfo: ParachainInfo, + }, + pallets = { + PolkadotXcm: PolkadotXcm, + AssetManager: AssetManager, + Balances: Balances, + XTokens: XTokens, + } + }, } -decl_test_network! { +decl_test_networks! { pub struct TestNet { - relay_chain = RococoNet, + relay_chain = Rococo, parachains = vec![ - // N.B: Ideally, we could use the defined para id constants but doing so - // fails with: "error: arbitrary expressions aren't allowed in patterns" - - // Be sure to use `xcm_config::config::battery_station::ID` - (2101, Zeitgeist), - // Be sure to use `PARA_ID_SIBLING` - (3000, Sibling), + BatteryStation, + Sibling, ], - } -} - -pub(super) fn relay_ext() -> sp_io::TestExternalities { - use rococo_runtime::{Runtime, System}; - - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - - pallet_balances::GenesisConfig:: { balances: vec![(ALICE, roc(2002))] } - .assimilate_storage(&mut t) - .unwrap(); - - polkadot_runtime_parachains::configuration::GenesisConfig:: { - config: mock_relay_config(), - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_xcm::GenesisConfig:: { _config: Default::default(), safe_xcm_version: Some(2) } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext -} - -pub(super) fn para_ext(parachain_id: u32) -> sp_io::TestExternalities { - let _ = env_logger::builder().is_test(true).try_init(); - - ExtBuilder::default() - .set_balances(vec![ - (ALICE, Assets::Ztg, ztg(10)), - (ALICE, FOREIGN_PARENT_ID.into(), roc(10)), - (ZeitgeistTreasuryAccount::get(), FOREIGN_PARENT_ID.into(), roc(1)), - ]) - .set_parachain_id(parachain_id) - .with_safe_xcm_version(2) - .build() -} - -pub fn mock_relay_config() -> HostConfiguration { - HostConfiguration:: { - hrmp_channel_max_capacity: u32::MAX, - hrmp_channel_max_total_size: u32::MAX, - hrmp_max_parachain_inbound_channels: 10, - hrmp_max_parachain_outbound_channels: 10, - hrmp_channel_max_message_size: u32::MAX, - // Changed to avoid aritmetic errors within hrmp_close - max_downward_message_size: 100_000u32, - ..Default::default() + bridge = () } } diff --git a/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs b/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs index 50dfbcc41..c568b95a1 100644 --- a/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs +++ b/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs @@ -21,9 +21,9 @@ use crate::{ setup::{ foreign_parent_multilocation, foreign_sibling_multilocation, foreign_ztg_multilocation, register_foreign_parent, register_foreign_sibling, FOREIGN_PARENT_ID, - FOREIGN_SIBLING_ID, + FOREIGN_SIBLING_ID, PARA_ID_BATTERY_STATION, }, - test_net::Zeitgeist, + test_net::BatteryStation, }, xcm_config::config::{battery_station, general_key, AssetConvert}, Assets, CustomMetadata, ScalarPosition, XcmAsset, @@ -32,7 +32,7 @@ use core::fmt::Debug; use sp_runtime::traits::{Convert, MaybeEquivalence}; use test_case::test_case; use xcm::latest::{Junction::*, Junctions::*, MultiLocation}; -use xcm_simulator::TestExt; +use xcm_emulator::TestExt; fn convert_common_native(expected: T) where @@ -41,7 +41,7 @@ where { assert_eq!(battery_station::KEY.to_vec(), vec![0, 1]); - // The way Ztg is represented relative within the Zeitgeist runtime + // The way Ztg is represented relative within the Battery Station runtime let ztg_location_inner: MultiLocation = MultiLocation::new(0, X1(general_key(battery_station::KEY))); @@ -51,7 +51,7 @@ where ); // The canonical way Ztg is represented out in the wild - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { assert_eq!( >::convert(expected), Some(foreign_ztg_multilocation()) @@ -67,10 +67,10 @@ fn convert_common_non_native( T: Copy + Debug + PartialEq, AssetConvert: MaybeEquivalence + Convert>, { - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { assert_eq!(>::convert(&multilocation), None); assert_eq!(>::convert(expected), None); - // Register parent as foreign asset in the Zeitgeist parachain + // Register parent as foreign asset in the BatteryStation parachain register(None); assert_eq!( >::convert(&multilocation), @@ -129,9 +129,9 @@ fn convert_any_registered_sibling_multilocation_xcm_assets() { #[test] fn convert_unkown_multilocation() { let unknown_location: MultiLocation = - MultiLocation::new(1, X2(Parachain(battery_station::ID), general_key(&[42]))); + MultiLocation::new(1, X2(Parachain(PARA_ID_BATTERY_STATION), general_key(&[42]))); - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { assert!( >::convert(&unknown_location).is_none() ); @@ -175,5 +175,7 @@ where T: Copy + Debug + PartialEq, AssetConvert: Convert>, { - Zeitgeist::execute_with(|| assert_eq!(>::convert(asset), None)); + BatteryStation::execute_with(|| { + assert_eq!(>::convert(asset), None) + }); } diff --git a/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs b/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs index a2d62dc11..e22df751f 100644 --- a/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs +++ b/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs @@ -19,21 +19,21 @@ use crate::{ integration_tests::xcm::{ setup::{ + accounts::{alice, bob}, adjusted_balance, btc, register_btc, register_foreign_parent, register_foreign_ztg, - roc, sibling_parachain_account, zeitgeist_parachain_account, ztg, ALICE, BOB, BTC_ID, - FOREIGN_PARENT_ID, FOREIGN_ZTG_ID, PARA_ID_SIBLING, + roc, sibling_parachain_account, zeitgeist_parachain_account, ztg, BTC_ID, + FOREIGN_PARENT_ID, FOREIGN_ZTG_ID, PARA_ID_BATTERY_STATION, PARA_ID_SIBLING, }, - test_net::{RococoNet, Sibling, TestNet, Zeitgeist}, + test_net::{BatteryStation, Rococo, Sibling}, }, xcm_config::{config::battery_station, fees::default_per_second}, - AssetManager, AssetRegistry, Balance, Balances, RuntimeOrigin, XTokens, - ZeitgeistTreasuryAccount, + AssetManager, Balance, Balances, RuntimeOrigin, XTokens, ZeitgeistTreasuryAccount, }; use frame_support::{assert_ok, traits::tokens::fungible::Mutate}; use orml_traits::MultiCurrency; use xcm::latest::{Junction, Junction::*, Junctions::*, MultiLocation, WeightLimit}; -use xcm_simulator::TestExt; +use xcm_emulator::{RelayChain, TestExt}; use zeitgeist_primitives::{ constants::{BalanceFractionalDecimals, BASE}, types::{CustomMetadata, XcmAsset, XcmMetadata}, @@ -41,24 +41,23 @@ use zeitgeist_primitives::{ #[test] fn transfer_ztg_to_sibling() { - TestNet::reset(); - - let alice_initial_balance = ztg(10); + let mut alice_initial_balance = 0; + let mut bob_initial_balance = 0; let transfer_amount = ztg(5); let mut treasury_initial_balance = 0; Sibling::execute_with(|| { treasury_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); - assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); + bob_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); register_foreign_ztg(None); }); - Zeitgeist::execute_with(|| { - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance); + BatteryStation::execute_with(|| { + alice_initial_balance = Balances::free_balance(&alice()); assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), XcmAsset::Ztg, transfer_amount, Box::new( @@ -66,7 +65,7 @@ fn transfer_ztg_to_sibling() { 1, X2( Parachain(PARA_ID_SIBLING), - Junction::AccountId32 { network: None, id: BOB.into() } + Junction::AccountId32 { network: None, id: bob().into() } ) ) .into() @@ -75,92 +74,140 @@ fn transfer_ztg_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance - transfer_amount); - + assert_eq!(Balances::free_balance(&alice()), alice_initial_balance - transfer_amount); // Verify that the amount transferred is now part of the sibling account here assert_eq!(Balances::free_balance(sibling_parachain_account()), transfer_amount); }); Sibling::execute_with(|| { - let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); - - // Verify that BOB now has (amount transferred - fee) - assert_eq!(current_balance, transfer_amount - ztg_fee()); + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + let bob_expected = bob_initial_balance + transfer_amount - ztg_fee(); + let treasury_expected = treasury_initial_balance + ztg_fee(); + // Verify that bob() now has (amount transferred - fee) + assert_eq!(current_balance, bob_expected); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), - treasury_initial_balance + ztg_fee() + treasury_expected ) }); } #[test] -fn transfer_ztg_sibling_to_zeitgeist() { - TestNet::reset(); +fn transfer_ztg_to_sibling_with_custom_fee() { + // 10x fee factor, so ZTG has 10x the worth of sibling currency. + let fee_factor = 100_000_000_000; + let transfer_amount = ztg(5); + let mut treasury_initial_balance = 0; + let mut bob_initial_balance = 0; + + Sibling::execute_with(|| { + treasury_initial_balance = + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); + bob_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + let custom_metadata = CustomMetadata { + xcm: XcmMetadata { fee_factor: Some(fee_factor) }, + ..Default::default() + }; + register_foreign_ztg(Some(custom_metadata)); + }); + + BatteryStation::execute_with(|| { + let alice_initial_balance = Balances::free_balance(&alice()); + assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); + assert_ok!(XTokens::transfer( + RuntimeOrigin::signed(alice()), + XcmAsset::Ztg, + transfer_amount, + Box::new( + MultiLocation::new( + 1, + X2( + Parachain(PARA_ID_SIBLING), + Junction::AccountId32 { network: None, id: bob().into() } + ) + ) + .into() + ), + WeightLimit::Limited(4_000_000_000.into()), + )); + // Confirm that Alice's balance is initial_balance - amount_transferred + assert_eq!(Balances::free_balance(&alice()), alice_initial_balance - transfer_amount); + // Verify that the amount transferred is now part of the sibling account here + assert_eq!(Balances::free_balance(sibling_parachain_account()), transfer_amount); + }); - // In order to be able to transfer ZTG from Sibling to Zeitgeist, we need to first send - // ZTG from Zeitgeist to Sibling, or else it fails since it'd be like Sibling had minted - // ZTG on their side. - transfer_ztg_to_sibling(); + Sibling::execute_with(|| { + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + let custom_fee = ztg_fee() * fee_factor / BASE; + let bob_expected = bob_initial_balance + transfer_amount - custom_fee; + let treasury_expected = treasury_initial_balance + custom_fee; + + // Verify that bob() now has (amount transferred - fee) + assert_eq!(current_balance, bob_expected); + // Verify that fees (of foreign currency) have been put into treasury + assert_eq!( + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), + treasury_expected + ) + }); +} - let alice_initial_balance = ztg(5); - let bob_initial_balance = ztg(5) - ztg_fee(); +#[test] +fn transfer_ztg_sibling_to_zeitgeist() { + let mut alice_initial_balance = 0; let mut treasury_initial_balance = 0; - let sibling_sovereign_initial_balance = ztg(5); let transfer_amount = ztg(1); - // Note: This asset was registered in `transfer_ztg_to_sibling` + let sibling_initial_balance = transfer_amount; - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { treasury_initial_balance = Balances::free_balance(ZeitgeistTreasuryAccount::get()); - - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance); + alice_initial_balance = Balances::free_balance(&alice()); assert_eq!( - Balances::free_balance(sibling_parachain_account()), - sibling_sovereign_initial_balance + Balances::set_balance(&sibling_parachain_account(), sibling_initial_balance), + sibling_initial_balance ); }); Sibling::execute_with(|| { - assert_eq!(Balances::free_balance(zeitgeist_parachain_account()), 0); - assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), bob_initial_balance); + register_foreign_ztg(None); + let bob_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(BOB), + RuntimeOrigin::signed(bob()), FOREIGN_ZTG_ID, transfer_amount, Box::new( MultiLocation::new( 1, X2( - Parachain(battery_station::ID), - Junction::AccountId32 { network: None, id: ALICE.into() } + Parachain(PARA_ID_BATTERY_STATION), + Junction::AccountId32 { network: None, id: alice().into() } ) ) .into() ), WeightLimit::Limited(4_000_000_000.into()), )); - // Confirm that Bobs's balance is initial balance - amount transferred assert_eq!( - AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()), bob_initial_balance - transfer_amount ); }); - Zeitgeist::execute_with(|| { - // Verify that ALICE now has initial balance + amount transferred - fee + BatteryStation::execute_with(|| { + // Verify that alice() now has initial balance + amount transferred - fee assert_eq!( - Balances::free_balance(&ALICE), + Balances::free_balance(&alice()), alice_initial_balance + transfer_amount - ztg_fee(), ); - // Verify that the reserve has been adjusted properly assert_eq!( Balances::free_balance(sibling_parachain_account()), - sibling_sovereign_initial_balance - transfer_amount + sibling_initial_balance - transfer_amount ); - // Verify that fees (of native currency) have been put into treasury assert_eq!( Balances::free_balance(ZeitgeistTreasuryAccount::get()), @@ -171,33 +218,28 @@ fn transfer_ztg_sibling_to_zeitgeist() { #[test] fn transfer_btc_sibling_to_zeitgeist() { - TestNet::reset(); - - let sibling_alice_initial_balance = ztg(10); - let zeitgeist_alice_initial_balance = btc(0); - let initial_sovereign_balance = btc(100); + let mut zeitgeist_alice_initial_balance = 0; let transfer_amount = btc(100); let mut treasury_initial_balance = 0; - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { register_btc(None); treasury_initial_balance = AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()); - assert_eq!( - AssetManager::free_balance(BTC_ID.into(), &ALICE), - zeitgeist_alice_initial_balance, - ); + zeitgeist_alice_initial_balance = AssetManager::free_balance(BTC_ID.into(), &alice()); }); Sibling::execute_with(|| { - assert_eq!(Balances::free_balance(&ALICE), sibling_alice_initial_balance); + let alice_initial_balance = Balances::free_balance(&alice()); + let initial_sovereign_balance = transfer_amount; + // Set the sovereign balance such that it is not subject to dust collection assert_eq!( Balances::set_balance(&zeitgeist_parachain_account(), initial_sovereign_balance,), initial_sovereign_balance ); assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), // Target chain will interpret XcmAsset::Ztg as BTC in this context. XcmAsset::Ztg, transfer_amount, @@ -205,18 +247,16 @@ fn transfer_btc_sibling_to_zeitgeist() { MultiLocation::new( 1, X2( - Parachain(battery_station::ID), - Junction::AccountId32 { network: None, id: ALICE.into() } + Parachain(PARA_ID_BATTERY_STATION), + Junction::AccountId32 { network: None, id: alice().into() } ) ) .into() ), WeightLimit::Limited(4_000_000_000.into()), )); - // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Balances::free_balance(&ALICE), sibling_alice_initial_balance - transfer_amount); - + assert_eq!(Balances::free_balance(&alice()), alice_initial_balance - transfer_amount); // Verify that the amount transferred is now part of the zeitgeist account here assert_eq!( Balances::free_balance(zeitgeist_parachain_account()), @@ -224,42 +264,46 @@ fn transfer_btc_sibling_to_zeitgeist() { ); }); - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { let expected = transfer_amount - btc_fee(); let expected_adjusted = adjusted_balance(btc(1), expected); + let expected_treasury = treasury_initial_balance + adjusted_balance(btc(1), btc_fee()); // Verify that remote Alice now has initial balance + amount transferred - fee assert_eq!( - AssetManager::free_balance(BTC_ID.into(), &ALICE), + AssetManager::free_balance(BTC_ID.into(), &alice()), zeitgeist_alice_initial_balance + expected_adjusted, ); - // Verify that fees (of foreign currency) have been put into treasury assert_eq!( AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()), // Align decimal fractional places - treasury_initial_balance + adjusted_balance(btc(1), btc_fee()) + expected_treasury ) }); } #[test] fn transfer_btc_zeitgeist_to_sibling() { - TestNet::reset(); - - let transfer_amount = btc(100) - btc_fee(); - let initial_sovereign_balance = 2 * btc(100); - let sibling_bob_initial_balance = btc(0); - - transfer_btc_sibling_to_zeitgeist(); + let transfer_amount = btc(100); + let initial_sovereign_balance = transfer_amount; + let mut bob_initial_balance = 0; Sibling::execute_with(|| { - assert_eq!(AssetManager::free_balance(BTC_ID.into(), &BOB), sibling_bob_initial_balance,); + bob_initial_balance = Balances::free_balance(&bob()); + // Set the sovereign balance such that it is not subject to dust collection + assert_eq!( + Balances::set_balance(&zeitgeist_parachain_account(), initial_sovereign_balance,), + initial_sovereign_balance + ); }); - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { + register_btc(None); + let alice_initial_balance = AssetManager::free_balance(BTC_ID.into(), &alice()); + assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), BTC_ID, transfer_amount, Box::new( @@ -267,7 +311,7 @@ fn transfer_btc_zeitgeist_to_sibling() { 1, X2( Parachain(PARA_ID_SIBLING), - Junction::AccountId32 { network: None, id: BOB.into() } + Junction::AccountId32 { network: None, id: bob().into() } ) ) .into() @@ -276,201 +320,141 @@ fn transfer_btc_zeitgeist_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(AssetManager::free_balance(BTC_ID.into(), &ALICE), 0); + let alice_balance = AssetManager::free_balance(BTC_ID.into(), &alice()); + let alice_expected = alice_initial_balance - adjusted_balance(btc(1), transfer_amount); + assert_eq!(alice_balance, alice_expected); }); Sibling::execute_with(|| { - let fee_adjusted = adjusted_balance(btc(1), btc_fee()); - let expected = transfer_amount - fee_adjusted; + let expected = bob_initial_balance + transfer_amount - adjusted_balance(btc(1), btc_fee()); + let expected_sovereign = initial_sovereign_balance - transfer_amount; // Verify that Bob now has initial balance + amount transferred - fee - assert_eq!(Balances::free_balance(&BOB), sibling_bob_initial_balance + expected,); - + assert_eq!(Balances::free_balance(&bob()), expected); // Verify that the amount transferred is now subtracted from the zeitgeist account at sibling - assert_eq!( - Balances::free_balance(zeitgeist_parachain_account()), - initial_sovereign_balance - transfer_amount - ); + assert_eq!(Balances::free_balance(zeitgeist_parachain_account()), expected_sovereign); }); } #[test] fn transfer_roc_from_relay_chain() { - TestNet::reset(); - let transfer_amount: Balance = roc(1); let mut treasury_initial_balance = 0; + let mut bob_initial_balance = 0; - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { register_foreign_parent(None); treasury_initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ZeitgeistTreasuryAccount::get()); + bob_initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &bob()); }); - RococoNet::execute_with(|| { - let initial_balance = rococo_runtime::Balances::free_balance(&ALICE); + Rococo::execute_with(|| { + let initial_balance = rococo_runtime::Balances::free_balance(&alice()); assert!(initial_balance >= transfer_amount); assert_ok!(rococo_runtime::XcmPallet::reserve_transfer_assets( - rococo_runtime::RuntimeOrigin::signed(ALICE), - Box::new(Parachain(battery_station::ID).into()), - Box::new(Junction::AccountId32 { network: None, id: BOB.into() }.into()), + rococo_runtime::RuntimeOrigin::signed(alice()), + Box::new(Parachain(PARA_ID_BATTERY_STATION).into()), + Box::new(Junction::AccountId32 { network: None, id: bob().into() }.into()), Box::new((Here, transfer_amount).into()), 0 )); }); - Zeitgeist::execute_with(|| { + BatteryStation::execute_with(|| { let expected = transfer_amount - roc_fee(); - let expected_adjusted = adjusted_balance(roc(1), expected); - assert_eq!(AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &BOB), expected_adjusted); + let bob_expected = bob_initial_balance + adjusted_balance(roc(1), expected); + let treasury_expected = treasury_initial_balance + adjusted_balance(roc(1), roc_fee()); + + assert_eq!(AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &bob()), bob_expected); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ZeitgeistTreasuryAccount::get()), - // Align decimal fractional places - treasury_initial_balance + adjusted_balance(roc(1), roc_fee()) + treasury_expected ) }); } #[test] fn transfer_roc_to_relay_chain() { - TestNet::reset(); - let transfer_amount: Balance = roc(1); let transfer_amount_local: Balance = adjusted_balance(roc(1), transfer_amount); - transfer_roc_from_relay_chain(); - - Zeitgeist::execute_with(|| { - let initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE); - assert!(initial_balance >= transfer_amount); - - assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), - FOREIGN_PARENT_ID, - transfer_amount, - Box::new( - MultiLocation::new(1, X1(Junction::AccountId32 { id: BOB.into(), network: None })) - .into() - ), - WeightLimit::Limited(4_000_000_000.into()) - )); + let mut initial_balance_bob = 0; + Rococo::execute_with(|| { + initial_balance_bob = rococo_runtime::Balances::free_balance(&bob()); + let bs_acc = Rococo::sovereign_account_id_of_child_para(PARA_ID_BATTERY_STATION.into()); assert_eq!( - AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE), - initial_balance - transfer_amount_local - ) - }); - - RococoNet::execute_with(|| { - assert_eq!(rococo_runtime::Balances::free_balance(&BOB), 999_990_415_728); + rococo_runtime::Balances::set_balance(&bs_acc, transfer_amount), + transfer_amount + ); }); -} - -#[test] -fn transfer_ztg_to_sibling_with_custom_fee() { - TestNet::reset(); - - let alice_initial_balance = ztg(10); - // 10x fee factor, so ZTG has 10x the worth of sibling currency. - let fee_factor = 100_000_000_000; - let transfer_amount = ztg(5); - let mut treasury_initial_balance = 0; - Sibling::execute_with(|| { - treasury_initial_balance = - AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); - assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); - - register_foreign_ztg(None); - let custom_metadata = CustomMetadata { - xcm: XcmMetadata { fee_factor: Some(fee_factor) }, - ..Default::default() - }; - assert_ok!(AssetRegistry::do_update_asset( - FOREIGN_ZTG_ID, - None, - None, - None, - None, - None, - Some(custom_metadata) - )); - }); + BatteryStation::execute_with(|| { + register_foreign_parent(None); + let initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &alice()); + assert!(initial_balance >= transfer_amount_local); - Zeitgeist::execute_with(|| { - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance); - assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), - XcmAsset::Ztg, + RuntimeOrigin::signed(alice()), + FOREIGN_PARENT_ID, transfer_amount, Box::new( MultiLocation::new( 1, - X2( - Parachain(PARA_ID_SIBLING), - Junction::AccountId32 { network: None, id: BOB.into() } - ) + X1(Junction::AccountId32 { id: bob().into(), network: None }) ) .into() ), - WeightLimit::Limited(4_000_000_000.into()), + WeightLimit::Limited(4_000_000_000.into()) )); - // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance - transfer_amount); - - // Verify that the amount transferred is now part of the sibling account here - assert_eq!(Balances::free_balance(sibling_parachain_account()), transfer_amount); - }); - - Sibling::execute_with(|| { - let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); - let custom_fee = calc_fee(default_per_second(10) * 10); - - // Verify that BOB now has (amount transferred - fee) - assert_eq!(current_balance, transfer_amount - ztg_fee() * fee_factor / BASE); - - // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), - treasury_initial_balance + custom_fee + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &alice()), + initial_balance - transfer_amount_local ) }); + + #[cfg(not(feature = "runtime-benchmarks"))] + // rococo-runtime does not process messages when runtime-benchmarks is enabled: + // https://github.com/paritytech/polkadot-sdk/blob/release-polkadot-v1.1.0/polkadot/runtime/rococo/src/lib.rs#L1078-L1080 + Rococo::execute_with(|| { + let expected_fee = 10_454_619; + let expected_balance_bob = initial_balance_bob + transfer_amount - expected_fee; + assert_eq!(rococo_runtime::Balances::free_balance(&bob()), expected_balance_bob); + }); } #[test] fn test_total_fee() { + assert_eq!(btc_fee(), 642_960); + assert_eq!(roc_fee(), 8_037_000_000); assert_eq!(ztg_fee(), 64_296_000); - assert_eq!(roc_fee(), 6_429_600_000); } #[inline] fn ztg_fee() -> Balance { - fee(BalanceFractionalDecimals::get().into()) + fee(BalanceFractionalDecimals::get().into(), 8) } #[inline] -fn fee(decimals: u32) -> Balance { - calc_fee(default_per_second(decimals)) +fn fee(decimals: u32, multiplier: Balance) -> Balance { + calc_fee(default_per_second(decimals), multiplier) } -// The fee associated with transferring roc tokens #[inline] fn roc_fee() -> Balance { - fee(12) + fee(12, 10) } #[inline] fn btc_fee() -> Balance { - fee(8) + fee(8, 8) } #[inline] -const fn calc_fee(fee_per_second: Balance) -> Balance { - // We divide the fee to align its unit and multiply by 8 as that seems to be the unit of - // time the tests take. - // NOTE: it is possible that in different machines this value may differ. We shall see. - fee_per_second / 10_000 * 8 +const fn calc_fee(fee_per_second: Balance, multiplier: Balance) -> Balance { + // Adjust fee per second to actual test execution time + fee_per_second / 10_000 * multiplier } diff --git a/runtime/battery-station/src/parachain_params.rs b/runtime/battery-station/src/parachain_params.rs index d9affc3a2..7312994c4 100644 --- a/runtime/battery-station/src/parachain_params.rs +++ b/runtime/battery-station/src/parachain_params.rs @@ -1,4 +1,4 @@ -// Copyright 2022-2023 Forecasting Technologies LTD. +// Copyright 2022-2024 Forecasting Technologies LTD. // Copyright 2021-2022 Zeitgeist PM LLC. // // This file is part of Zeitgeist. diff --git a/runtime/battery-station/src/xcm_config/config.rs b/runtime/battery-station/src/xcm_config/config.rs index fc97e70e2..7dffe666f 100644 --- a/runtime/battery-station/src/xcm_config/config.rs +++ b/runtime/battery-station/src/xcm_config/config.rs @@ -54,7 +54,7 @@ use xcm_executor::{traits::TransactAsset, Assets as ExecutorAssets}; use zeitgeist_primitives::{constants::BalanceFractionalDecimals, types::XcmAsset}; pub mod battery_station { - #[cfg(test)] + #[cfg(any(test, feature = "runtime-benchmarks"))] pub const ID: u32 = 2101; pub const KEY: &[u8] = &[0, 1]; } diff --git a/runtime/zeitgeist/Cargo.toml b/runtime/zeitgeist/Cargo.toml index c53c48831..4a3b046f8 100644 --- a/runtime/zeitgeist/Cargo.toml +++ b/runtime/zeitgeist/Cargo.toml @@ -128,9 +128,12 @@ zrml-swaps-runtime-api = { workspace = true } [dev-dependencies] env_logger = { workspace = true } +pallet-im-online = { workspace = true, features = ["default"] } +sp-authority-discovery = { workspace = true, features = ["default"] } +sp-consensus-babe = { workspace = true, features = ["default"] } sp-io = { workspace = true, features = ["default"] } test-case = { workspace = true } -xcm-simulator = { workspace = true } +xcm-emulator = { workspace = true } [features] default = ["std"] @@ -323,6 +326,7 @@ std = [ # Zeitgeist "zeitgeist-primitives/std", + "zrml-asset-router/std", "zrml-authorized/std", "zrml-court/std", "zrml-hybrid-router/std", diff --git a/runtime/zeitgeist/src/integration_tests/xcm/genesis/mod.rs b/runtime/zeitgeist/src/integration_tests/xcm/genesis/mod.rs new file mode 100644 index 000000000..5b5ed972a --- /dev/null +++ b/runtime/zeitgeist/src/integration_tests/xcm/genesis/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2024 Forecasting Technologies LTD. +// +// This file is part of Zeitgeist. +// +// Zeitgeist 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. +// +// Zeitgeist 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 Zeitgeist. If not, see . + +pub(super) mod polkadot; +pub(super) mod zeitgeist; diff --git a/runtime/zeitgeist/src/integration_tests/xcm/genesis/polkadot.rs b/runtime/zeitgeist/src/integration_tests/xcm/genesis/polkadot.rs new file mode 100644 index 000000000..2ef8a7349 --- /dev/null +++ b/runtime/zeitgeist/src/integration_tests/xcm/genesis/polkadot.rs @@ -0,0 +1,134 @@ +// Copyright 2024 Forecasting Technologies LTD. +// +// Copyright (C) Parity Technologies (UK) Ltd. +// +// This file is part of Zeitgeist. +// +// Zeitgeist 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. +// +// Zeitgeist 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 Zeitgeist. If not, see . + +use crate::integration_tests::xcm::setup::{accounts, accounts::get_from_seed, dot}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use polkadot_primitives::{AccountId, AssignmentId, BlockNumber, ValidatorId}; +use polkadot_runtime_parachains::configuration::HostConfiguration; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_consensus_babe::AuthorityId as BabeId; +use sp_consensus_grandpa::AuthorityId as GrandpaId; +use sp_core::{sr25519, storage::Storage}; +use sp_runtime::BuildStorage; +use xcm_emulator::helpers::get_account_id_from_seed; + +const ENDOWMENT: u128 = dot(1_000_000); + +fn session_keys( + grandpa: GrandpaId, + babe: BabeId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, +) -> polkadot_runtime::SessionKeys { + polkadot_runtime::SessionKeys { + grandpa, + babe, + im_online, + para_validator, + para_assignment, + authority_discovery, + } +} + +fn get_host_config() -> HostConfiguration { + HostConfiguration { + max_upward_queue_count: 10, + max_upward_queue_size: 51200, + max_upward_message_size: 51200, + max_upward_message_num_per_candidate: 10, + max_downward_message_size: 51200, + hrmp_sender_deposit: 0, + hrmp_recipient_deposit: 0, + hrmp_channel_max_capacity: 1000, + hrmp_channel_max_message_size: 102400, + hrmp_channel_max_total_size: 102400, + hrmp_max_parachain_outbound_channels: 30, + hrmp_max_parachain_inbound_channels: 30, + ..Default::default() + } +} + +mod validators { + use super::*; + + pub fn initial_authorities() -> Vec<( + AccountId, + AccountId, + GrandpaId, + BabeId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + )> { + let seed = "Alice"; + vec![( + get_account_id_from_seed::(&format!("{}//stash", seed)), + get_account_id_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + )] + } +} + +pub(crate) fn genesis() -> Storage { + let genesis_config = polkadot_runtime::RuntimeGenesisConfig { + system: polkadot_runtime::SystemConfig { + code: polkadot_runtime::WASM_BINARY.unwrap().to_vec(), + ..Default::default() + }, + balances: polkadot_runtime::BalancesConfig { + balances: accounts::init_balances().iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + session: polkadot_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(), + ), + ) + }) + .collect::>(), + }, + babe: polkadot_runtime::BabeConfig { + authorities: Default::default(), + epoch_config: Some(polkadot_runtime::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + configuration: polkadot_runtime::ConfigurationConfig { config: get_host_config() }, + ..Default::default() + }; + + genesis_config.build_storage().unwrap() +} diff --git a/runtime/zeitgeist/src/integration_tests/xcm/genesis/zeitgeist.rs b/runtime/zeitgeist/src/integration_tests/xcm/genesis/zeitgeist.rs new file mode 100644 index 000000000..22e3fc162 --- /dev/null +++ b/runtime/zeitgeist/src/integration_tests/xcm/genesis/zeitgeist.rs @@ -0,0 +1,83 @@ +// Copyright 2024 Forecasting Technologies LTD. +// +// This file is part of Zeitgeist. +// +// Zeitgeist 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. +// +// Zeitgeist 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 Zeitgeist. If not, see . + +use crate::{ + integration_tests::xcm::setup::{ + accounts, ztg, BTC_ID, ETH_ID, FOREIGN_PARENT_ID, FOREIGN_SIBLING_ID, FOREIGN_ZTG_ID, + }, + parachain_params::MinCandidateStk, + parameters::ZeitgeistTreasuryAccount, + Asset, +}; +use nimbus_primitives::NimbusId; +use sp_core::storage::Storage; +use sp_runtime::BuildStorage; + +const ENDOWMENT: u128 = ztg(1_000_000_000_000_000); +const SAFE_XCM_VERSION: u32 = 2; + +pub(crate) fn genesis(parachain_id: u32) -> Storage { + let genesis_config = crate::RuntimeGenesisConfig { + author_mapping: crate::AuthorMappingConfig { + mappings: vec![( + accounts::get_from_seed::(accounts::ALICE), + accounts::alice(), + )], + }, + balances: crate::BalancesConfig { + balances: accounts::init_balances() + .iter() + .map(|k| (k.clone(), ztg(ENDOWMENT))) + .collect(), + }, + parachain_info: crate::ParachainInfoConfig { + parachain_id: parachain_id.into(), + ..Default::default() + }, + parachain_staking: crate::ParachainStakingConfig { + candidates: vec![(accounts::alice(), MinCandidateStk::get())], + ..Default::default() + }, + polkadot_xcm: crate::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + ..Default::default() + }, + system: crate::SystemConfig { + code: crate::WASM_BINARY.unwrap().to_vec(), + ..Default::default() + }, + tokens: crate::TokensConfig { + balances: accounts::init_balances() + .iter() + .chain(vec![(ZeitgeistTreasuryAccount::get())].iter()) + .map(|k| { + vec![ + (k.clone(), Asset::from(FOREIGN_PARENT_ID).try_into().unwrap(), ENDOWMENT), + (k.clone(), Asset::from(FOREIGN_SIBLING_ID).try_into().unwrap(), ENDOWMENT), + (k.clone(), Asset::from(FOREIGN_ZTG_ID).try_into().unwrap(), ENDOWMENT), + (k.clone(), Asset::from(BTC_ID).try_into().unwrap(), ENDOWMENT), + (k.clone(), Asset::from(ETH_ID).try_into().unwrap(), ENDOWMENT), + ] + }) + .flatten() + .collect::>(), + }, + ..Default::default() + }; + + genesis_config.build_storage().unwrap() +} diff --git a/runtime/zeitgeist/src/integration_tests/xcm/mod.rs b/runtime/zeitgeist/src/integration_tests/xcm/mod.rs index d37a62036..9ba9a1de3 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/mod.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2022 Forecasting Technologies LTD. +// Copyright 2022-2024 Forecasting Technologies LTD. // // This file is part of Zeitgeist. // @@ -17,6 +17,7 @@ #![cfg(all(feature = "parachain", test))] +mod genesis; mod setup; mod test_net; mod tests; diff --git a/runtime/zeitgeist/src/integration_tests/xcm/setup.rs b/runtime/zeitgeist/src/integration_tests/xcm/setup.rs index ba1433fef..3a35b1042 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/setup.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/setup.rs @@ -1,5 +1,4 @@ // Copyright 2022-2024 Forecasting Technologies LTD. -// Copyright 2021 Centrifuge Foundation (centrifuge.io). // // This file is part of Zeitgeist. // @@ -18,102 +17,70 @@ use crate::{ xcm_config::config::{general_key, zeitgeist}, - AccountId, AssetRegistry, AssetRegistryStringLimit, Assets, Balance, ExistentialDeposit, - Runtime, RuntimeOrigin, System, + AccountId, AssetRegistry, AssetRegistryStringLimit, Balance, ExistentialDeposit, RuntimeOrigin, }; use frame_support::assert_ok; use orml_traits::asset_registry::AssetMetadata; -use sp_runtime::{AccountId32, BuildStorage}; +use sp_core::{sr25519, Pair, Public}; use xcm::{ latest::{Junction::Parachain, Junctions::X2, MultiLocation}, VersionedMultiLocation, }; +use xcm_emulator::helpers::get_account_id_from_seed; use zeitgeist_primitives::types::{CustomMetadata, XcmAsset}; -pub(super) struct ExtBuilder { - balances: Vec<(AccountId, Assets, Balance)>, - parachain_id: u32, - safe_xcm_version: Option, -} - -impl Default for ExtBuilder { - fn default() -> Self { - Self { balances: vec![], parachain_id: zeitgeist::ID, safe_xcm_version: None } - } -} - -impl ExtBuilder { - pub fn set_balances(mut self, balances: Vec<(AccountId, Assets, Balance)>) -> Self { - self.balances = balances; - self +pub(super) mod accounts { + use super::*; + pub const ALICE: &str = "Alice"; + pub const BOB: &str = "Bob"; + pub const CHARLIE: &str = "Charlie"; + pub const DAVE: &str = "Dave"; + pub const EVE: &str = "Eve"; + pub const FERDIE: &str = "Ferdie"; + pub const ALICE_STASH: &str = "Alice//stash"; + pub const BOB_STASH: &str = "Bob//stash"; + pub const CHARLIE_STASH: &str = "Charlie//stash"; + pub const DAVE_STASH: &str = "Dave//stash"; + pub const EVE_STASH: &str = "Eve//stash"; + pub const FERDIE_STASH: &str = "Ferdie//stash"; + + pub fn init_balances() -> Vec { + vec![ + get_account_id_from_seed::(ALICE), + get_account_id_from_seed::(BOB), + get_account_id_from_seed::(CHARLIE), + get_account_id_from_seed::(DAVE), + get_account_id_from_seed::(EVE), + get_account_id_from_seed::(FERDIE), + get_account_id_from_seed::(ALICE_STASH), + get_account_id_from_seed::(BOB_STASH), + get_account_id_from_seed::(CHARLIE_STASH), + get_account_id_from_seed::(DAVE_STASH), + get_account_id_from_seed::(EVE_STASH), + get_account_id_from_seed::(FERDIE_STASH), + ] } - pub fn set_parachain_id(mut self, parachain_id: u32) -> Self { - self.parachain_id = parachain_id; - self + pub fn alice() -> AccountId { + get_account_id_from_seed::(ALICE) } - pub fn with_safe_xcm_version(mut self, safe_xcm_version: u32) -> Self { - self.safe_xcm_version = Some(safe_xcm_version); - self + pub fn bob() -> AccountId { + get_account_id_from_seed::(BOB) } - pub fn build(self) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let native_currency_id = Assets::Ztg; - - pallet_balances::GenesisConfig:: { - balances: self - .balances - .clone() - .into_iter() - .filter(|(_, currency_id, _)| *currency_id == native_currency_id) - .map(|(account_id, _, initial_balance)| (account_id, initial_balance)) - .collect::>(), - } - .assimilate_storage(&mut t) - .unwrap(); - - orml_tokens::GenesisConfig:: { - balances: self - .balances - .into_iter() - .filter(|(_, currency_id, _)| *currency_id != native_currency_id) - .map(|(account_id, currency_id, initial_balance)| { - (account_id, currency_id.try_into().unwrap(), initial_balance) - }) - .collect::>(), - } - .assimilate_storage(&mut t) - .unwrap(); - - parachain_info::GenesisConfig:: { - _config: Default::default(), - parachain_id: self.parachain_id.into(), - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_xcm::GenesisConfig:: { - _config: Default::default(), - safe_xcm_version: self.safe_xcm_version, - } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext + /// Helper function to generate a crypto pair from seed + pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() } } -/// Accounts -pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); -pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); - /// A PARA ID used for a sibling parachain. /// It must be one that doesn't collide with any other in use. pub const PARA_ID_SIBLING: u32 = 3000; +pub const PARA_ID_ZEITGEIST: u32 = zeitgeist::ID; /// IDs that are used to represent tokens from other chains pub const FOREIGN_ZTG_ID: XcmAsset = XcmAsset::ForeignAsset(0); @@ -164,7 +131,7 @@ pub(super) const fn adjusted_balance(foreign_base: Balance, amount: Balance) -> // Multilocations that are used to represent tokens from other chains #[inline] pub(super) fn foreign_ztg_multilocation() -> MultiLocation { - MultiLocation::new(1, X2(Parachain(zeitgeist::ID), general_key(zeitgeist::KEY))) + MultiLocation::new(1, X2(Parachain(PARA_ID_ZEITGEIST), general_key(zeitgeist::KEY))) } #[inline] @@ -256,7 +223,7 @@ pub(super) fn sibling_parachain_account() -> AccountId { #[inline] pub(super) fn zeitgeist_parachain_account() -> AccountId { - parachain_account(zeitgeist::ID) + parachain_account(PARA_ID_ZEITGEIST) } #[inline] diff --git a/runtime/zeitgeist/src/integration_tests/xcm/test_net.rs b/runtime/zeitgeist/src/integration_tests/xcm/test_net.rs index 6558aa0da..a70900558 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/test_net.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/test_net.rs @@ -1,5 +1,4 @@ // Copyright 2022-2024 Forecasting Technologies LTD. -// Copyright 2021-2022 Centrifuge GmbH (centrifuge.io). // // This file is part of Zeitgeist. // @@ -16,108 +15,79 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . +use super::{ + genesis::{polkadot, zeitgeist}, + setup::{PARA_ID_SIBLING, PARA_ID_ZEITGEIST}, +}; use crate::{ - parameters::ZeitgeistTreasuryAccount, xcm_config::config::zeitgeist, Assets, DmpQueue, - XcmpQueue, + xcm_config::config::LocationToAccountId, AssetManager, Balances, DmpQueue, ParachainInfo, + PolkadotXcm, XTokens, XcmpQueue, +}; +use xcm_emulator::{ + decl_test_networks, decl_test_parachains, decl_test_relay_chains, DefaultMessageProcessor, }; -use polkadot_runtime_parachains::configuration::HostConfiguration; -use sp_runtime::BuildStorage; -use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; - -use super::setup::{dot, ztg, ExtBuilder, ALICE, FOREIGN_PARENT_ID, PARA_ID_SIBLING}; -decl_test_relay_chain! { - pub struct PolkadotNet { - Runtime = polkadot_runtime::Runtime, - RuntimeCall = polkadot_runtime::RuntimeCall, - RuntimeEvent = polkadot_runtime::RuntimeEvent, - XcmConfig = polkadot_runtime::XcmConfig, - MessageQueue = polkadot_runtime::MessageQueue, - System = polkadot_runtime::System, - new_ext = relay_ext(), - } +decl_test_relay_chains! { + #[api_version(5)] + pub struct Polkadot { + genesis = polkadot::genesis(), + on_init = (), + runtime = polkadot_runtime, + core = { + MessageProcessor: DefaultMessageProcessor, + SovereignAccountOf: polkadot_runtime::xcm_config::SovereignAccountOf, + }, + pallets = { + XcmPallet: polkadot_runtime::XcmPallet, + Balances: polkadot_runtime::Balances, + } + }, } -decl_test_parachain! { +decl_test_parachains! { pub struct Zeitgeist { - Runtime = Runtime, - XcmpMessageHandler = XcmpQueue, - DmpMessageHandler = DmpQueue, - new_ext = para_ext(zeitgeist::ID), - } -} - -decl_test_parachain! { + genesis = zeitgeist::genesis(PARA_ID_ZEITGEIST), + on_init = (), + runtime = crate, + core = { + XcmpMessageHandler: XcmpQueue, + DmpMessageHandler: DmpQueue, + LocationToAccountId: LocationToAccountId, + ParachainInfo: ParachainInfo, + }, + pallets = { + PolkadotXcm: PolkadotXcm, + AssetManager: AssetManager, + Balances: Balances, + XTokens: XTokens, + } + }, pub struct Sibling { - Runtime = Runtime, - XcmpMessageHandler = XcmpQueue, - DmpMessageHandler = DmpQueue, - new_ext = para_ext(PARA_ID_SIBLING), - } + genesis = zeitgeist::genesis(PARA_ID_SIBLING), + on_init = (), + runtime = crate, + core = { + XcmpMessageHandler: XcmpQueue, + DmpMessageHandler: DmpQueue, + LocationToAccountId: LocationToAccountId, + ParachainInfo: ParachainInfo, + }, + pallets = { + PolkadotXcm: PolkadotXcm, + AssetManager: AssetManager, + Balances: Balances, + XTokens: XTokens, + } + }, } -decl_test_network! { +decl_test_networks! { pub struct TestNet { - relay_chain = PolkadotNet, + relay_chain = Polkadot, parachains = vec![ - // N.B: Ideally, we could use the defined para id constants but doing so - // fails with: "error: arbitrary expressions aren't allowed in patterns" - - // Be sure to use `xcm_config::config::zeitgeist::ID` - (2092, Zeitgeist), - // Be sure to use `PARA_ID_SIBLING` - (3000, Sibling), + Zeitgeist, + Sibling, ], - } -} - -pub(super) fn relay_ext() -> sp_io::TestExternalities { - use polkadot_runtime::{Runtime, System}; - - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - - pallet_balances::GenesisConfig:: { balances: vec![(ALICE, dot(2002))] } - .assimilate_storage(&mut t) - .unwrap(); - - polkadot_runtime_parachains::configuration::GenesisConfig:: { - config: mock_relay_config(), - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_xcm::GenesisConfig:: { _config: Default::default(), safe_xcm_version: Some(2) } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext -} - -pub(super) fn para_ext(parachain_id: u32) -> sp_io::TestExternalities { - let _ = env_logger::builder().is_test(true).try_init(); - - ExtBuilder::default() - .set_balances(vec![ - (ALICE, Assets::Ztg, ztg(10)), - (ALICE, FOREIGN_PARENT_ID.into(), dot(10)), - (ZeitgeistTreasuryAccount::get(), FOREIGN_PARENT_ID.into(), dot(10)), - ]) - .set_parachain_id(parachain_id) - .with_safe_xcm_version(2) - .build() -} - -pub fn mock_relay_config() -> HostConfiguration { - HostConfiguration:: { - hrmp_channel_max_capacity: u32::MAX, - hrmp_channel_max_total_size: u32::MAX, - hrmp_max_parachain_inbound_channels: 10, - hrmp_max_parachain_outbound_channels: 10, - hrmp_channel_max_message_size: u32::MAX, - // Changed to avoid aritmetic errors within hrmp_close - max_downward_message_size: 100_000u32, - ..Default::default() + bridge = () } } diff --git a/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs b/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs index 27f8c94fa..38d443dee 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs @@ -21,7 +21,7 @@ use crate::{ setup::{ foreign_parent_multilocation, foreign_sibling_multilocation, foreign_ztg_multilocation, register_foreign_parent, register_foreign_sibling, FOREIGN_PARENT_ID, - FOREIGN_SIBLING_ID, + FOREIGN_SIBLING_ID, PARA_ID_ZEITGEIST, }, test_net::Zeitgeist, }, @@ -32,7 +32,7 @@ use core::fmt::Debug; use sp_runtime::traits::{Convert, MaybeEquivalence}; use test_case::test_case; use xcm::latest::{Junction::*, Junctions::*, MultiLocation}; -use xcm_simulator::TestExt; +use xcm_emulator::TestExt; fn convert_common_native(expected: T) where @@ -128,7 +128,7 @@ fn convert_any_registered_sibling_multilocation_xcm_assets() { #[test] fn convert_unkown_multilocation() { let unknown_location: MultiLocation = - MultiLocation::new(1, X2(Parachain(zeitgeist::ID), general_key(&[42]))); + MultiLocation::new(1, X2(Parachain(PARA_ID_ZEITGEIST), general_key(&[42]))); Zeitgeist::execute_with(|| { assert!( diff --git a/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs b/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs index 13fca9797..72f5a6dac 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs @@ -19,21 +19,21 @@ use crate::{ integration_tests::xcm::{ setup::{ + accounts::{alice, bob}, adjusted_balance, btc, dot, eth, register_btc, register_eth, register_foreign_parent, register_foreign_ztg, sibling_parachain_account, zeitgeist_parachain_account, ztg, - ALICE, BOB, BTC_ID, ETH_ID, FOREIGN_PARENT_ID, FOREIGN_ZTG_ID, PARA_ID_SIBLING, + BTC_ID, ETH_ID, FOREIGN_PARENT_ID, FOREIGN_ZTG_ID, PARA_ID_SIBLING, PARA_ID_ZEITGEIST, }, - test_net::{PolkadotNet, Sibling, TestNet, Zeitgeist}, + test_net::{Polkadot, Sibling, Zeitgeist}, }, - xcm_config::{config::zeitgeist, fees::default_per_second}, - AssetManager, AssetRegistry, Balance, Balances, RuntimeOrigin, XTokens, - ZeitgeistTreasuryAccount, + xcm_config::fees::default_per_second, + AssetManager, Balance, Balances, RuntimeOrigin, XTokens, ZeitgeistTreasuryAccount, }; use frame_support::{assert_ok, traits::tokens::fungible::Mutate}; use orml_traits::MultiCurrency; use xcm::latest::{Junction, Junction::*, Junctions::*, MultiLocation, WeightLimit}; -use xcm_simulator::TestExt; +use xcm_emulator::{RelayChain, TestExt}; use zeitgeist_primitives::{ constants::{BalanceFractionalDecimals, BASE}, types::{CustomMetadata, XcmAsset, XcmMetadata}, @@ -41,24 +41,23 @@ use zeitgeist_primitives::{ #[test] fn transfer_ztg_to_sibling() { - TestNet::reset(); - - let alice_initial_balance = ztg(10); + let mut alice_initial_balance = 0; + let mut bob_initial_balance = 0; let transfer_amount = ztg(5); let mut treasury_initial_balance = 0; Sibling::execute_with(|| { treasury_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); - assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); + bob_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); register_foreign_ztg(None); }); Zeitgeist::execute_with(|| { - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance); + alice_initial_balance = Balances::free_balance(&alice()); assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), XcmAsset::Ztg, transfer_amount, Box::new( @@ -66,7 +65,7 @@ fn transfer_ztg_to_sibling() { 1, X2( Parachain(PARA_ID_SIBLING), - Junction::AccountId32 { network: None, id: BOB.into() } + Junction::AccountId32 { network: None, id: bob().into() } ) ) .into() @@ -75,92 +74,140 @@ fn transfer_ztg_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance - transfer_amount); - + assert_eq!(Balances::free_balance(&alice()), alice_initial_balance - transfer_amount); // Verify that the amount transferred is now part of the sibling account here assert_eq!(Balances::free_balance(sibling_parachain_account()), transfer_amount); }); Sibling::execute_with(|| { - let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); - - // Verify that BOB now has (amount transferred - fee) - assert_eq!(current_balance, transfer_amount - ztg_fee()); + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + let bob_expected = bob_initial_balance + transfer_amount - ztg_fee(); + let treasury_expected = treasury_initial_balance + ztg_fee(); + // Verify that bob() now has (amount transferred - fee) + assert_eq!(current_balance, bob_expected); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), - treasury_initial_balance + ztg_fee() + treasury_expected ) }); } #[test] -fn transfer_ztg_sibling_to_zeitgeist() { - TestNet::reset(); +fn transfer_ztg_to_sibling_with_custom_fee() { + // 10x fee factor, so ZTG has 10x the worth of sibling currency. + let fee_factor = 100_000_000_000; + let transfer_amount = ztg(5); + let mut treasury_initial_balance = 0; + let mut bob_initial_balance = 0; + + Sibling::execute_with(|| { + treasury_initial_balance = + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); + bob_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + let custom_metadata = CustomMetadata { + xcm: XcmMetadata { fee_factor: Some(fee_factor) }, + ..Default::default() + }; + register_foreign_ztg(Some(custom_metadata)); + }); + + Zeitgeist::execute_with(|| { + let alice_initial_balance = Balances::free_balance(&alice()); + assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); + assert_ok!(XTokens::transfer( + RuntimeOrigin::signed(alice()), + XcmAsset::Ztg, + transfer_amount, + Box::new( + MultiLocation::new( + 1, + X2( + Parachain(PARA_ID_SIBLING), + Junction::AccountId32 { network: None, id: bob().into() } + ) + ) + .into() + ), + WeightLimit::Limited(4_000_000_000.into()), + )); + // Confirm that Alice's balance is initial_balance - amount_transferred + assert_eq!(Balances::free_balance(&alice()), alice_initial_balance - transfer_amount); + // Verify that the amount transferred is now part of the sibling account here + assert_eq!(Balances::free_balance(sibling_parachain_account()), transfer_amount); + }); + + Sibling::execute_with(|| { + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + let custom_fee = ztg_fee() * fee_factor / BASE; + let bob_expected = bob_initial_balance + transfer_amount - custom_fee; + let treasury_expected = treasury_initial_balance + custom_fee; - // In order to be able to transfer ZTG from Sibling to Zeitgeist, we need to first send - // ZTG from Zeitgeist to Sibling, or else it fails since it'd be like Sibling had minted - // ZTG on their side. - transfer_ztg_to_sibling(); + // Verify that bob() now has (amount transferred - fee) + assert_eq!(current_balance, bob_expected); + // Verify that fees (of foreign currency) have been put into treasury + assert_eq!( + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), + treasury_expected + ) + }); +} - let alice_initial_balance = ztg(5); - let bob_initial_balance = ztg(5) - ztg_fee(); +#[test] +fn transfer_ztg_sibling_to_zeitgeist() { + let mut alice_initial_balance = 0; let mut treasury_initial_balance = 0; - let sibling_sovereign_initial_balance = ztg(5); let transfer_amount = ztg(1); - // Note: This asset was registered in `transfer_ztg_to_sibling` + let sibling_initial_balance = transfer_amount; Zeitgeist::execute_with(|| { treasury_initial_balance = Balances::free_balance(ZeitgeistTreasuryAccount::get()); - - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance); + alice_initial_balance = Balances::free_balance(&alice()); assert_eq!( - Balances::free_balance(sibling_parachain_account()), - sibling_sovereign_initial_balance + Balances::set_balance(&sibling_parachain_account(), sibling_initial_balance), + sibling_initial_balance ); }); Sibling::execute_with(|| { - assert_eq!(Balances::free_balance(zeitgeist_parachain_account()), 0); - assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), bob_initial_balance); + register_foreign_ztg(None); + let bob_initial_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()); + assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(BOB), + RuntimeOrigin::signed(bob()), FOREIGN_ZTG_ID, transfer_amount, Box::new( MultiLocation::new( 1, X2( - Parachain(zeitgeist::ID), - Junction::AccountId32 { network: None, id: ALICE.into() } + Parachain(PARA_ID_ZEITGEIST), + Junction::AccountId32 { network: None, id: alice().into() } ) ) .into() ), WeightLimit::Limited(4_000_000_000.into()), )); - // Confirm that Bobs's balance is initial balance - amount transferred assert_eq!( - AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &bob()), bob_initial_balance - transfer_amount ); }); Zeitgeist::execute_with(|| { - // Verify that ALICE now has initial balance + amount transferred - fee + // Verify that alice() now has initial balance + amount transferred - fee assert_eq!( - Balances::free_balance(&ALICE), + Balances::free_balance(&alice()), alice_initial_balance + transfer_amount - ztg_fee(), ); - // Verify that the reserve has been adjusted properly assert_eq!( Balances::free_balance(sibling_parachain_account()), - sibling_sovereign_initial_balance - transfer_amount + sibling_initial_balance - transfer_amount ); - // Verify that fees (of native currency) have been put into treasury assert_eq!( Balances::free_balance(ZeitgeistTreasuryAccount::get()), @@ -171,11 +218,7 @@ fn transfer_ztg_sibling_to_zeitgeist() { #[test] fn transfer_btc_sibling_to_zeitgeist() { - TestNet::reset(); - - let sibling_alice_initial_balance = ztg(10); - let zeitgeist_alice_initial_balance = btc(0); - let initial_sovereign_balance = btc(100); + let mut zeitgeist_alice_initial_balance = 0; let transfer_amount = btc(100); let mut treasury_initial_balance = 0; @@ -183,21 +226,20 @@ fn transfer_btc_sibling_to_zeitgeist() { register_btc(None); treasury_initial_balance = AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()); - assert_eq!( - AssetManager::free_balance(BTC_ID.into(), &ALICE), - zeitgeist_alice_initial_balance, - ); + zeitgeist_alice_initial_balance = AssetManager::free_balance(BTC_ID.into(), &alice()); }); Sibling::execute_with(|| { - assert_eq!(Balances::free_balance(&ALICE), sibling_alice_initial_balance); + let alice_initial_balance = Balances::free_balance(&alice()); + let initial_sovereign_balance = transfer_amount; + // Set the sovereign balance such that it is not subject to dust collection assert_eq!( Balances::set_balance(&zeitgeist_parachain_account(), initial_sovereign_balance,), initial_sovereign_balance ); assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), // Target chain will interpret XcmAsset::Ztg as BTC in this context. XcmAsset::Ztg, transfer_amount, @@ -205,18 +247,16 @@ fn transfer_btc_sibling_to_zeitgeist() { MultiLocation::new( 1, X2( - Parachain(zeitgeist::ID), - Junction::AccountId32 { network: None, id: ALICE.into() } + Parachain(PARA_ID_ZEITGEIST), + Junction::AccountId32 { network: None, id: alice().into() } ) ) .into() ), WeightLimit::Limited(4_000_000_000.into()), )); - // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Balances::free_balance(&ALICE), sibling_alice_initial_balance - transfer_amount); - + assert_eq!(Balances::free_balance(&alice()), alice_initial_balance - transfer_amount); // Verify that the amount transferred is now part of the zeitgeist account here assert_eq!( Balances::free_balance(zeitgeist_parachain_account()), @@ -227,39 +267,43 @@ fn transfer_btc_sibling_to_zeitgeist() { Zeitgeist::execute_with(|| { let expected = transfer_amount - btc_fee(); let expected_adjusted = adjusted_balance(btc(1), expected); + let expected_treasury = treasury_initial_balance + adjusted_balance(btc(1), btc_fee()); // Verify that remote Alice now has initial balance + amount transferred - fee assert_eq!( - AssetManager::free_balance(BTC_ID.into(), &ALICE), + AssetManager::free_balance(BTC_ID.into(), &alice()), zeitgeist_alice_initial_balance + expected_adjusted, ); - // Verify that fees (of foreign currency) have been put into treasury assert_eq!( AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()), // Align decimal fractional places - treasury_initial_balance + adjusted_balance(btc(1), btc_fee()) + expected_treasury ) }); } #[test] fn transfer_btc_zeitgeist_to_sibling() { - TestNet::reset(); - - let transfer_amount = btc(100) - btc_fee(); - let initial_sovereign_balance = 2 * btc(100); - let sibling_bob_initial_balance = btc(0); - - transfer_btc_sibling_to_zeitgeist(); + let transfer_amount = btc(100); + let initial_sovereign_balance = transfer_amount; + let mut bob_initial_balance = 0; Sibling::execute_with(|| { - assert_eq!(AssetManager::free_balance(BTC_ID.into(), &BOB), sibling_bob_initial_balance,); + bob_initial_balance = Balances::free_balance(&bob()); + // Set the sovereign balance such that it is not subject to dust collection + assert_eq!( + Balances::set_balance(&zeitgeist_parachain_account(), initial_sovereign_balance,), + initial_sovereign_balance + ); }); Zeitgeist::execute_with(|| { + register_btc(None); + let alice_initial_balance = AssetManager::free_balance(BTC_ID.into(), &alice()); + assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), BTC_ID, transfer_amount, Box::new( @@ -267,7 +311,7 @@ fn transfer_btc_zeitgeist_to_sibling() { 1, X2( Parachain(PARA_ID_SIBLING), - Junction::AccountId32 { network: None, id: BOB.into() } + Junction::AccountId32 { network: None, id: bob().into() } ) ) .into() @@ -276,57 +320,46 @@ fn transfer_btc_zeitgeist_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(AssetManager::free_balance(BTC_ID.into(), &ALICE), 0); + let alice_balance = AssetManager::free_balance(BTC_ID.into(), &alice()); + let alice_expected = alice_initial_balance - adjusted_balance(btc(1), transfer_amount); + assert_eq!(alice_balance, alice_expected); }); Sibling::execute_with(|| { - let fee_adjusted = adjusted_balance(btc(1), btc_fee()); - let expected = transfer_amount - fee_adjusted; + let expected = bob_initial_balance + transfer_amount - adjusted_balance(btc(1), btc_fee()); + let expected_sovereign = initial_sovereign_balance - transfer_amount; // Verify that Bob now has initial balance + amount transferred - fee - assert_eq!(Balances::free_balance(&BOB), sibling_bob_initial_balance + expected,); - + assert_eq!(Balances::free_balance(&bob()), expected); // Verify that the amount transferred is now subtracted from the zeitgeist account at sibling - assert_eq!( - Balances::free_balance(zeitgeist_parachain_account()), - initial_sovereign_balance - transfer_amount - ); + assert_eq!(Balances::free_balance(zeitgeist_parachain_account()), expected_sovereign); }); } #[test] fn transfer_eth_sibling_to_zeitgeist() { - TestNet::reset(); - - let sibling_alice_initial_balance = ztg(10) + eth(1); - let zeitgeist_alice_initial_balance = eth(0); - let initial_sovereign_balance = eth(1); - let transfer_amount = eth(1); + let mut zeitgeist_alice_initial_balance = 0; + let transfer_amount = eth(100); let mut treasury_initial_balance = 0; Zeitgeist::execute_with(|| { register_eth(None); treasury_initial_balance = AssetManager::free_balance(ETH_ID.into(), &ZeitgeistTreasuryAccount::get()); - assert_eq!( - AssetManager::free_balance(ETH_ID.into(), &ALICE), - zeitgeist_alice_initial_balance, - ); + zeitgeist_alice_initial_balance = AssetManager::free_balance(ETH_ID.into(), &alice()); }); Sibling::execute_with(|| { + let alice_initial_balance = Balances::free_balance(&alice()); + let initial_sovereign_balance = transfer_amount; + // Set the sovereign balance such that it is not subject to dust collection assert_eq!( Balances::set_balance(&zeitgeist_parachain_account(), initial_sovereign_balance,), initial_sovereign_balance ); - // Add 1 "fake" ETH to Alice's balance - assert_eq!( - Balances::set_balance(&ALICE, sibling_alice_initial_balance,), - sibling_alice_initial_balance - ); assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), // Target chain will interpret XcmAsset::Ztg as ETH in this context. XcmAsset::Ztg, transfer_amount, @@ -334,18 +367,16 @@ fn transfer_eth_sibling_to_zeitgeist() { MultiLocation::new( 1, X2( - Parachain(zeitgeist::ID), - Junction::AccountId32 { network: None, id: ALICE.into() } + Parachain(PARA_ID_ZEITGEIST), + Junction::AccountId32 { network: None, id: alice().into() } ) ) .into() ), WeightLimit::Limited(4_000_000_000.into()), )); - // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Balances::free_balance(&ALICE), sibling_alice_initial_balance - transfer_amount); - + assert_eq!(Balances::free_balance(&alice()), alice_initial_balance - transfer_amount); // Verify that the amount transferred is now part of the zeitgeist account here assert_eq!( Balances::free_balance(zeitgeist_parachain_account()), @@ -356,39 +387,43 @@ fn transfer_eth_sibling_to_zeitgeist() { Zeitgeist::execute_with(|| { let expected = transfer_amount - eth_fee(); let expected_adjusted = adjusted_balance(eth(1), expected); + let expected_treasury = treasury_initial_balance + adjusted_balance(eth(1), eth_fee()); // Verify that remote Alice now has initial balance + amount transferred - fee assert_eq!( - AssetManager::free_balance(ETH_ID.into(), &ALICE), + AssetManager::free_balance(ETH_ID.into(), &alice()), zeitgeist_alice_initial_balance + expected_adjusted, ); - // Verify that fees (of foreign currency) have been put into treasury assert_eq!( AssetManager::free_balance(ETH_ID.into(), &ZeitgeistTreasuryAccount::get()), // Align decimal fractional places - treasury_initial_balance + adjusted_balance(eth(1), eth_fee()) + expected_treasury ) }); } #[test] fn transfer_eth_zeitgeist_to_sibling() { - TestNet::reset(); - - let transfer_amount = eth(1) - eth_fee(); - let initial_sovereign_balance = 2 * eth(1); - let sibling_bob_initial_balance = eth(0); - - transfer_eth_sibling_to_zeitgeist(); + let transfer_amount = eth(100); + let initial_sovereign_balance = transfer_amount; + let mut bob_initial_balance = 0; Sibling::execute_with(|| { - assert_eq!(AssetManager::free_balance(ETH_ID.into(), &BOB), sibling_bob_initial_balance,); + bob_initial_balance = Balances::free_balance(&bob()); + // Set the sovereign balance such that it is not subject to dust collection + assert_eq!( + Balances::set_balance(&zeitgeist_parachain_account(), initial_sovereign_balance,), + initial_sovereign_balance + ); }); Zeitgeist::execute_with(|| { + register_eth(None); + let alice_initial_balance = AssetManager::free_balance(ETH_ID.into(), &alice()); + assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(alice()), ETH_ID, transfer_amount, Box::new( @@ -396,7 +431,7 @@ fn transfer_eth_zeitgeist_to_sibling() { 1, X2( Parachain(PARA_ID_SIBLING), - Junction::AccountId32 { network: None, id: BOB.into() } + Junction::AccountId32 { network: None, id: bob().into() } ) ) .into() @@ -405,200 +440,147 @@ fn transfer_eth_zeitgeist_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(AssetManager::free_balance(ETH_ID.into(), &ALICE), 0); + let alice_balance = AssetManager::free_balance(ETH_ID.into(), &alice()); + let alice_expected = alice_initial_balance - adjusted_balance(eth(1), transfer_amount); + assert_eq!(alice_balance, alice_expected); }); Sibling::execute_with(|| { - let fee_adjusted = adjusted_balance(eth(1), eth_fee()); - let expected = transfer_amount - fee_adjusted; + let expected = bob_initial_balance + transfer_amount - adjusted_balance(eth(1), eth_fee()); + let expected_sovereign = initial_sovereign_balance - transfer_amount; // Verify that Bob now has initial balance + amount transferred - fee - assert_eq!(Balances::free_balance(&BOB), sibling_bob_initial_balance + expected,); - + assert_eq!(Balances::free_balance(&bob()), expected); // Verify that the amount transferred is now subtracted from the zeitgeist account at sibling - assert_eq!( - Balances::free_balance(zeitgeist_parachain_account()), - initial_sovereign_balance - transfer_amount - ); + assert_eq!(Balances::free_balance(zeitgeist_parachain_account()), expected_sovereign); }); } #[test] fn transfer_dot_from_relay_chain() { - TestNet::reset(); - - let transfer_amount: Balance = dot(2); + let transfer_amount: Balance = dot(1); + let mut treasury_initial_balance = 0; + let mut bob_initial_balance = 0; Zeitgeist::execute_with(|| { register_foreign_parent(None); + treasury_initial_balance = + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ZeitgeistTreasuryAccount::get()); + bob_initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &bob()); }); - PolkadotNet::execute_with(|| { - let initial_balance = polkadot_runtime::Balances::free_balance(&ALICE); + Polkadot::execute_with(|| { + let initial_balance = polkadot_runtime::Balances::free_balance(&alice()); assert!(initial_balance >= transfer_amount); assert_ok!(polkadot_runtime::XcmPallet::reserve_transfer_assets( - polkadot_runtime::RuntimeOrigin::signed(ALICE), - Box::new(Parachain(zeitgeist::ID).into()), - Box::new(Junction::AccountId32 { network: None, id: BOB.into() }.into()), + polkadot_runtime::RuntimeOrigin::signed(alice()), + Box::new(Parachain(PARA_ID_ZEITGEIST).into()), + Box::new(Junction::AccountId32 { network: None, id: bob().into() }.into()), Box::new((Here, transfer_amount).into()), 0 )); }); Zeitgeist::execute_with(|| { - assert_eq!( - AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &BOB), - transfer_amount - dot_fee() - ); - }); -} - -#[test] -fn transfer_dot_to_relay_chain() { - TestNet::reset(); - - let transfer_amount: Balance = dot(2); - transfer_dot_from_relay_chain(); - - Zeitgeist::execute_with(|| { - let initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE); - assert!(initial_balance >= transfer_amount); - - assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), - FOREIGN_PARENT_ID, - transfer_amount, - Box::new( - MultiLocation::new(1, X1(Junction::AccountId32 { id: BOB.into(), network: None })) - .into() - ), - WeightLimit::Unlimited, - )); + let expected = transfer_amount - dot_fee(); + let bob_expected = bob_initial_balance + adjusted_balance(dot(1), expected); + let treasury_expected = treasury_initial_balance + adjusted_balance(dot(1), dot_fee()); + assert_eq!(AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &bob()), bob_expected); + // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE), - initial_balance - transfer_amount + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ZeitgeistTreasuryAccount::get()), + treasury_expected ) }); - - PolkadotNet::execute_with(|| { - assert_eq!(polkadot_runtime::Balances::free_balance(&BOB), 19_637_471_000); - }); } #[test] -fn transfer_ztg_to_sibling_with_custom_fee() { - TestNet::reset(); - - let alice_initial_balance = ztg(10); - // 10x fee factor, so ZTG has 10x the worth of sibling currency. - let fee_factor = 100_000_000_000; - let transfer_amount = ztg(5); - let mut treasury_initial_balance = 0; - - Sibling::execute_with(|| { - treasury_initial_balance = - AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); - assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); +fn transfer_dot_to_relay_chain() { + let transfer_amount: Balance = dot(1); + let transfer_amount_local: Balance = adjusted_balance(dot(1), transfer_amount); + let mut initial_balance_bob = 0; - register_foreign_ztg(None); - let custom_metadata = CustomMetadata { - xcm: XcmMetadata { fee_factor: Some(fee_factor) }, - ..Default::default() - }; - assert_ok!(AssetRegistry::do_update_asset( - FOREIGN_ZTG_ID, - None, - None, - None, - None, - None, - Some(custom_metadata) - )); + Polkadot::execute_with(|| { + initial_balance_bob = polkadot_runtime::Balances::free_balance(&bob()); + let bs_acc = Polkadot::sovereign_account_id_of_child_para(PARA_ID_ZEITGEIST.into()); + assert_eq!( + polkadot_runtime::Balances::set_balance(&bs_acc, transfer_amount), + transfer_amount + ); }); Zeitgeist::execute_with(|| { - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance); - assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); + register_foreign_parent(None); + let initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &alice()); + assert!(initial_balance >= transfer_amount_local); + assert_ok!(XTokens::transfer( - RuntimeOrigin::signed(ALICE), - XcmAsset::Ztg, + RuntimeOrigin::signed(alice()), + FOREIGN_PARENT_ID, transfer_amount, Box::new( MultiLocation::new( 1, - X2( - Parachain(PARA_ID_SIBLING), - Junction::AccountId32 { network: None, id: BOB.into() } - ) + X1(Junction::AccountId32 { id: bob().into(), network: None }) ) .into() ), - WeightLimit::Limited(4_000_000_000.into()), + WeightLimit::Limited(4_000_000_000.into()) )); - // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Balances::free_balance(&ALICE), alice_initial_balance - transfer_amount); - - // Verify that the amount transferred is now part of the sibling account here - assert_eq!(Balances::free_balance(sibling_parachain_account()), transfer_amount); - }); - - Sibling::execute_with(|| { - let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); - let custom_fee = calc_fee(default_per_second(10) * 10); - - // Verify that BOB now has (amount transferred - fee) - assert_eq!(current_balance, transfer_amount - custom_fee); - - // Sanity check for the actual amount BOB ends up with - assert_eq!(current_balance, transfer_amount - ztg_fee() * fee_factor / BASE); - - // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), - treasury_initial_balance + custom_fee + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &alice()), + initial_balance - transfer_amount_local ) }); + + #[cfg(not(feature = "runtime-benchmarks"))] + // polkadot-runtime does not process messages when runtime-benchmarks is enabled: + // https://github.com/paritytech/polkadot-sdk/blob/release-polkadot-v1.1.0/polkadot/runtime/polkadot/src/lib.rs#L1138-L1140 + Polkadot::execute_with(|| { + let expected_fee = 21_062_795; + let expected_balance_bob = initial_balance_bob + transfer_amount - expected_fee; + assert_eq!(polkadot_runtime::Balances::free_balance(&bob()), expected_balance_bob); + }); } #[test] fn test_total_fee() { + assert_eq!(btc_fee(), 642_960); + assert_eq!(dot_fee(), 80_370_000); assert_eq!(ztg_fee(), 64_296_000); - assert_eq!(dot_fee(), ztg_fee()); + assert_eq!(eth_fee(), 6_429_600_000_000_000); } #[inline] fn ztg_fee() -> Balance { - fee(BalanceFractionalDecimals::get().into()) + fee(BalanceFractionalDecimals::get().into(), 8) } #[inline] -fn fee(decimals: u32) -> Balance { - calc_fee(default_per_second(decimals)) +fn fee(decimals: u32, multiplier: Balance) -> Balance { + calc_fee(default_per_second(decimals), multiplier) } -// The fee associated with transferring dot tokens #[inline] fn dot_fee() -> Balance { - fee(10) + fee(10, 10) } #[inline] fn btc_fee() -> Balance { - fee(8) + fee(8, 8) } #[inline] fn eth_fee() -> Balance { - fee(18) + fee(18, 8) } #[inline] -const fn calc_fee(fee_per_second: Balance) -> Balance { - // We divide the fee to align its unit and multiply by 8 as that seems to be the unit of - // time the tests take. - // NOTE: it is possible that in different machines this value may differ. We shall see. - fee_per_second / 10_000 * 8 +const fn calc_fee(fee_per_second: Balance, multiplier: Balance) -> Balance { + // Adjust fee per second to actual test execution time + fee_per_second / 10_000 * multiplier } diff --git a/runtime/zeitgeist/src/parachain_params.rs b/runtime/zeitgeist/src/parachain_params.rs index 598488d90..55bf67d07 100644 --- a/runtime/zeitgeist/src/parachain_params.rs +++ b/runtime/zeitgeist/src/parachain_params.rs @@ -1,4 +1,4 @@ -// Copyright 2022-2023 Forecasting Technologies LTD. +// Copyright 2022-2024 Forecasting Technologies LTD. // Copyright 2021-2022 Zeitgeist PM LLC. // // This file is part of Zeitgeist. diff --git a/runtime/zeitgeist/src/xcm_config/config.rs b/runtime/zeitgeist/src/xcm_config/config.rs index 4dd3acfff..fe1b0b03f 100644 --- a/runtime/zeitgeist/src/xcm_config/config.rs +++ b/runtime/zeitgeist/src/xcm_config/config.rs @@ -56,7 +56,7 @@ use xcm_executor::{traits::TransactAsset, Assets as ExecutorAssets}; use zeitgeist_primitives::{constants::BalanceFractionalDecimals, types::XcmAsset}; pub mod zeitgeist { - #[cfg(test)] + #[cfg(any(test, feature = "runtime-benchmarks"))] pub const ID: u32 = 2092; pub const KEY: &[u8] = &[0, 1]; }