From ee0c8673b41f83811c5d06a53bf78c1b49755a47 Mon Sep 17 00:00:00 2001 From: yrong1997 Date: Tue, 3 Aug 2021 10:37:35 +0800 Subject: [PATCH] Add development runtime (#200) --- Cargo.lock | 131 ++ Cargo.toml | 2 + README.md | 8 +- node/cli/Cargo.toml | 3 + node/cli/src/command.rs | 50 +- node/service/Cargo.toml | 18 +- node/service/src/_manual.rs | 179 +++ node/service/src/chain_spec/dev.rs | 202 +++ node/service/src/chain_spec/mod.rs | 2 + node/service/src/client.rs | 50 + node/service/src/dev.rs | 331 +++++ node/service/src/lib.rs | 11 + runtime/dev/Cargo.toml | 190 +++ runtime/dev/build.rs | 29 + runtime/dev/src/constants.rs | 84 ++ runtime/dev/src/lib.rs | 1527 +++++++++++++++++++++ runtime/dev/src/weights/mod.rs | 24 + runtime/dev/src/weights/pallet_assets.rs | 53 + runtime/dev/src/weights/pallet_salp.rs | 69 + runtime/dev/src/weights/pallet_vesting.rs | 94 ++ 20 files changed, 3046 insertions(+), 11 deletions(-) create mode 100644 node/service/src/_manual.rs create mode 100644 node/service/src/chain_spec/dev.rs create mode 100644 node/service/src/dev.rs create mode 100644 runtime/dev/Cargo.toml create mode 100644 runtime/dev/build.rs create mode 100644 runtime/dev/src/constants.rs create mode 100644 runtime/dev/src/lib.rs create mode 100644 runtime/dev/src/weights/mod.rs create mode 100644 runtime/dev/src/weights/pallet_assets.rs create mode 100644 runtime/dev/src/weights/pallet_salp.rs create mode 100644 runtime/dev/src/weights/pallet_vesting.rs diff --git a/Cargo.lock b/Cargo.lock index 600e72915e..a4c0abd482 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2112,6 +2112,91 @@ dependencies = [ "syn", ] +[[package]] +name = "dev-runtime" +version = "0.8.0" +dependencies = [ + "bifrost-bancor", + "bifrost-bancor-runtime-api", + "bifrost-flexible-fee", + "bifrost-flexible-fee-rpc-runtime-api", + "bifrost-minter-reward", + "bifrost-runtime-common", + "bifrost-salp", + "bifrost-vsbond-auction", + "bifrost-vtoken-mint", + "cumulus-pallet-aura-ext", + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcm", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", + "cumulus-primitives-timestamp", + "cumulus-primitives-utility", + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-rpc-runtime-api", + "hex-literal 0.3.2", + "log", + "max-encoded-len", + "node-primitives", + "orml-currencies", + "orml-tokens", + "orml-traits", + "pallet-aura", + "pallet-authorship", + "pallet-balances", + "pallet-bounties", + "pallet-collator-selection", + "pallet-collective", + "pallet-democracy", + "pallet-elections-phragmen", + "pallet-grandpa", + "pallet-indices", + "pallet-membership", + "pallet-multisig", + "pallet-proxy", + "pallet-randomness-collective-flip", + "pallet-scheduler", + "pallet-session", + "pallet-sudo", + "pallet-timestamp", + "pallet-tips", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vesting", + "pallet-xcm", + "parachain-info", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-runtime-parachains", + "serde", + "sp-api", + "sp-arithmetic", + "sp-block-builder", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "static_assertions", + "substrate-wasm-builder", + "xcm", + "xcm-builder", + "xcm-executor", + "xcm-support", + "zenlink-protocol", + "zenlink-protocol-runtime-api", +] + [[package]] name = "digest" version = "0.8.1" @@ -4933,6 +5018,7 @@ dependencies = [ "cumulus-client-service", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", + "dev-runtime", "frame-benchmarking", "frame-system-rpc-runtime-api", "hex-literal 0.2.1", @@ -4944,9 +5030,16 @@ dependencies = [ "sc-basic-authorship", "sc-chain-spec", "sc-client-api", + "sc-consensus", + "sc-consensus-aura", + "sc-consensus-manual-seal", + "sc-consensus-slots", "sc-executor", + "sc-finality-grandpa", + "sc-keystore", "sc-network", "sc-rpc", + "sc-rpc-api", "sc-service", "sc-telemetry", "sc-tracing", @@ -4960,6 +5053,7 @@ dependencies = [ "sp-consensus-aura", "sp-core", "sp-finality-grandpa", + "sp-inherents", "sp-keystore", "sp-offchain", "sp-runtime", @@ -4967,6 +5061,8 @@ dependencies = [ "sp-storage", "sp-timestamp", "sp-transaction-pool", + "sp-trie", + "substrate-frame-rpc-system", "substrate-prometheus-endpoint", "zenlink-protocol-runtime-api", ] @@ -8245,6 +8341,41 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "sc-consensus-manual-seal" +version = "0.9.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#1b758b2a8d151d97d2242260c465b6df9cb8a7a4" +dependencies = [ + "assert_matches", + "async-trait", + "derive_more", + "futures 0.3.15", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "log", + "parity-scale-codec", + "parking_lot 0.11.1", + "sc-client-api", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-transaction-pool", + "serde", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-consensus-slots", + "sp-core", + "sp-inherents", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "sp-timestamp", + "sp-transaction-pool", + "substrate-prometheus-endpoint", +] + [[package]] name = "sc-consensus-slots" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index bfce3c6586..a138e36199 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -131,6 +131,8 @@ sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } +sc-consensus-manual-seal = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } +sc-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } sc-consensus-epochs = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } diff --git a/README.md b/README.md index ba585e31ad..21b72b63b1 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,13 @@ make run-benchmarking make build-all-release ``` -## Run local testnet polkadot-launch +## Run development chain + +```bash +RUST_LOG=debug cargo run -p node-cli --locked --features "with-dev-runtime" -- --tmp --dev +``` + +## Run local testnet with polkadot-launch Install `polkadot-launch`: diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index a8980f1986..ae6c2b7490 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -69,6 +69,9 @@ with-asgard-runtime = [ with-bifrost-runtime = [ "node-service/with-bifrost-runtime", ] +with-dev-runtime = [ + "node-service/with-dev-runtime" +] with-all-runtime = [ "with-asgard-runtime", "with-bifrost-runtime", diff --git a/node/cli/src/command.rs b/node/cli/src/command.rs index 6c27fb7aa5..031f1adc04 100644 --- a/node/cli/src/command.rs +++ b/node/cli/src/command.rs @@ -64,8 +64,6 @@ fn load_spec( #[cfg(feature = "with-asgard-runtime")] "asgard-genesis" => Box::new(service::chain_spec::asgard::chainspec_config(para_id)), #[cfg(feature = "with-asgard-runtime")] - "asgard-dev" => Box::new(service::chain_spec::asgard::development_config(para_id)?), - #[cfg(feature = "with-asgard-runtime")] "asgard-local" => Box::new(service::chain_spec::asgard::local_testnet_config(para_id)?), #[cfg(feature = "with-bifrost-runtime")] "bifrost" => Box::new(service::chain_spec::bifrost::ChainSpec::from_json_bytes( @@ -74,9 +72,9 @@ fn load_spec( #[cfg(feature = "with-bifrost-runtime")] "bifrost-genesis" => Box::new(service::chain_spec::bifrost::chainspec_config(para_id)), #[cfg(feature = "with-bifrost-runtime")] - "bifrost-dev" => Box::new(service::chain_spec::bifrost::development_config(para_id)?), - #[cfg(feature = "with-bifrost-runtime")] "bifrost-local" => Box::new(service::chain_spec::bifrost::local_testnet_config(para_id)?), + #[cfg(feature = "with-dev-runtime")] + "dev" => Box::new(service::chain_spec::dev::development_config(para_id)?), path => { let path = std::path::PathBuf::from(path); if path.to_str().map(|s| s.contains("asgard")) == Some(true) { @@ -86,13 +84,22 @@ fn load_spec( } #[cfg(not(feature = "with-asgard-runtime"))] return Err("Asgard runtime is not available. Please compile the node with `--features with-asgard-runtime` to enable it.".into()); - } else { + } else if path.to_str().map(|s| s.contains("bifrost")) == Some(true) { #[cfg(feature = "with-bifrost-runtime")] { Box::new(service::chain_spec::bifrost::ChainSpec::from_json_file(path)?) } #[cfg(not(feature = "with-bifrost-runtime"))] return Err("Bifrost runtime is not available. Please compile the node with `--features with-bifrost-runtime` to enable it.".into()); + } else if path.to_str().map(|s| s.contains("dev")) == Some(true) { + #[cfg(feature = "with-dev-runtime")] + { + Box::new(service::chain_spec::dev::ChainSpec::from_json_file(path)?) + } + #[cfg(not(feature = "with-dev-runtime"))] + return Err("Dev runtime is not available. Please compile the node with `--features with-dev-runtime` to enable it.".into()); + } else { + return Err("Unknown runtime is not available.".into()); } }, }) @@ -141,13 +148,20 @@ impl SubstrateCli for Cli { } #[cfg(not(feature = "with-asgard-runtime"))] panic!("Asgard runtime is not available. Please compile the node with `--features with-asgard-runtime` to enable it."); - } else { + } else if spec.is_bifrost() { #[cfg(feature = "with-bifrost-runtime")] { &service::collator::bifrost_runtime::VERSION } #[cfg(not(feature = "with-bifrost-runtime"))] panic!("Bifrost runtime is not available. Please compile the node with `--features with-bifrost-runtime` to enable it."); + } else { + #[cfg(feature = "with-dev-runtime")] + { + &service::dev::dev_runtime::VERSION + } + #[cfg(not(feature = "with-dev-runtime"))] + panic!("Asgard dev runtime is not available. Please compile the node with `--features with-dev-runtime` to enable it."); } } } @@ -227,6 +241,14 @@ macro_rules! construct_async_run { let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) }); + #[cfg(feature = "with-dev-runtime")] + return runner.async_run(|$config| { + let $components = crate::service::dev::new_partial( + &$config, + )?; + let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) + }); }} } @@ -239,6 +261,11 @@ pub fn run() -> Result<()> { None => { let runner = cli.create_runner(&cli.run.normalize())?; runner.run_node_until_exit(|config| async move { + if config.chain_spec.is_asgard_dev() { + #[cfg(feature = "with-dev-runtime")] + return service::dev::new_full(config).map_err(Into::into); + } + let para_id = node_service::chain_spec::RelayExtensions::try_get(&*config.chain_spec) .map(|e| e.para_id); @@ -283,11 +310,16 @@ pub fn run() -> Result<()> { .run::( config, ); - #[cfg(not(feature = "with-asgard-runtime"))] + #[cfg(feature = "with-bifrost-runtime")] return cmd .run::( config, ); + #[cfg(feature = "with-dev-runtime")] + return cmd + .run::( + config, + ); }); }, Some(Subcommand::Benchmark(cmd)) => @@ -298,9 +330,11 @@ pub fn run() -> Result<()> { #[cfg(feature = "with-asgard-runtime")] return cmd .run::(config); - #[cfg(not(feature = "with-asgard-runtime"))] + #[cfg(feature = "with-bifrost-runtime")] return cmd .run::(config); + #[cfg(feature = "with-dev-runtime")] + return cmd.run::(config); }); } else { Err("Benchmarking wasn't enabled when building the node. \ diff --git a/node/service/Cargo.toml b/node/service/Cargo.toml index 174d6038d5..f76670426b 100644 --- a/node/service/Cargo.toml +++ b/node/service/Cargo.toml @@ -15,22 +15,31 @@ sc-telemetry = { version = "3.0.0" } sc-transaction-pool = { version = "3.0.0" } sc-tracing = { version = "3.0.0" } sc-service = { version = "0.9.0", default-features = false } +sc-consensus = { version = "0.9.0" } +sc-consensus-manual-seal = { version = "0.9.0" } +sc-consensus-aura = { version = "0.9.0" } +sc-finality-grandpa = { version = "0.9.0" } +sc-consensus-slots = { version = "0.9.0"} +sc-rpc-api = { version = "0.9.0"} +sc-rpc = { version = "3.0.0" } +sc-keystore = { version = "3.0.0" } frame-benchmarking = { version = "3.0.0", default-features = false } # Substrate Primitives sp-consensus-aura = { version = "0.9.0" } sp-consensus = { version = "0.9.0" } -grandpa_primitives = { package = "sp-finality-grandpa", version = "3.0.0" } +sp-finality-grandpa = { version = "3.0.0" } +sp-inherents = { version = "3.0.0" } sp-api = { version = "3.0.0" } sp-block-builder = { version = "3.0.0" } sp-blockchain = { version = "3.0.0" } sp-core = { version = "3.0.0" } sp-keystore = { version = "0.9.0" } sp-offchain = { package = "sp-offchain", version = "3.0.0" } -sc-rpc = { version = "3.0.0" } sp-runtime = { version = "3.0.0" } sp-session = { version = "3.0.0" } sp-storage = { version = "3.0.0" } +sp-trie = { version = "3.0.0" } sp-timestamp = { version = "3.0.0" } sp-transaction-pool = { version = "3.0.0" } @@ -40,6 +49,7 @@ pallet-transaction-payment-rpc-runtime-api = { version = "3.0.0" } # Substrate Other frame-system-rpc-runtime-api = { version = "3.0.0" } substrate-prometheus-endpoint = { version = "0.9.0" } +substrate-frame-rpc-system = { version = "3.0.0" } # Cumulus dependencies cumulus-client-consensus-aura = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8" } @@ -61,6 +71,7 @@ serde_json = "1.0.60" # Runtimes asgard-runtime = { path = "../../runtime/asgard", optional = true } bifrost-runtime = { path = "../../runtime/bifrost", optional = true } +dev-runtime = { path = "../../runtime/dev", optional = true } node-primitives = { path = "../primitives" } node-rpc = { path = "../rpc" } @@ -86,6 +97,9 @@ with-asgard-runtime = [ with-bifrost-runtime = [ "bifrost-runtime", ] +with-dev-runtime = [ + "dev-runtime", +] with-all-runtime = [ "with-asgard-runtime", "with-bifrost-runtime", diff --git a/node/service/src/_manual.rs b/node/service/src/_manual.rs new file mode 100644 index 0000000000..d9abda4584 --- /dev/null +++ b/node/service/src/_manual.rs @@ -0,0 +1,179 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use std::sync::Arc; + +use asgard_runtime::Header; +use polkadot_service::{FullBackend, LongestChain}; +use sc_client_api::ExecutorProvider; +pub use sc_consensus_aura::{ImportQueueParams, StartAuraParams}; +use sc_consensus_manual_seal::InstantSealParams; +use sc_consensus_slots::SlotProportion; +use sc_service::{error::Error as ServiceError, Configuration, PartialComponents, TaskManager}; +use sc_telemetry::{Telemetry, TelemetryWorker, TelemetryWorkerHandle}; +use sp_api::TransactionFor; +use sp_consensus::{import_queue::BasicQueue, SlotData}; +use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; +use sp_inherents::{CreateInherentDataProviders, InherentDataProvider}; +use sp_runtime::generic; + +use crate::AsgardExecutor; + +type Block = generic::Block; +type FullSelectChain = LongestChain; +type FullClientDev = sc_service::TFullClient; + +#[allow(clippy::type_complexity)] +pub fn new_partial( + config: &Configuration, +) -> Result< + PartialComponents< + FullClientDev, + FullBackend, + FullSelectChain, + BasicQueue>, + sc_transaction_pool::FullPool, + (), + >, + ServiceError, +> { + let (client, backend, keystore_container, task_manager) = + sc_service::new_full_parts::( + &config, None, + )?; + let client = Arc::new(client); + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.role.is_authority().into(), + config.prometheus_registry(), + task_manager.spawn_essential_handle(), + client.clone(), + ); + + let import_queue = sc_consensus_manual_seal::import_queue( + Box::new(client.clone()), + &task_manager.spawn_handle(), + config.prometheus_registry(), + ); + + Ok(PartialComponents { + client, + backend, + import_queue, + keystore_container, + task_manager, + transaction_pool, + select_chain, + other: (), + }) +} + +pub fn new_full(config: Configuration) -> Result { + let sc_service::PartialComponents { + client, + backend, + mut task_manager, + import_queue, + keystore_container, + select_chain, + transaction_pool, + .. + } = new_partial(&config)?; + + let (network, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: None, + block_announce_validator_builder: None, + })?; + + let keystore = keystore_container.sync_keystore(); + if config.offchain_worker.enabled { + // Initialize seed for signing transaction using off-chain workers. This is a convenience + // so learners can see the transactions submitted simply running the node. + // Typically these keys should be inserted with RPC calls to `author_insertKey`. + #[cfg(feature = "ocw")] + { + sp_keystore::SyncCryptoStore::sr25519_generate_new( + &*keystore, + runtime::ocw_demo::KEY_TYPE, + Some("//Alice"), + ) + .expect("Creating key with account Alice should succeed."); + } + + sc_service::build_offchain_workers( + &config, + task_manager.spawn_handle(), + client.clone(), + network.clone(), + ); + } + + let is_authority = config.role.is_authority(); + let prometheus_registry = config.prometheus_registry().cloned(); + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + network, + client: client.clone(), + keystore, + task_manager: &mut task_manager, + transaction_pool: transaction_pool.clone(), + rpc_extensions_builder: Box::new(|_, _| ()), + on_demand: None, + remote_blockchain: None, + backend, + system_rpc_tx, + config, + telemetry: None, + })?; + + if is_authority { + let proposer = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool.clone(), + prometheus_registry.as_ref(), + None, + ); + + let authorship_future = sc_consensus_manual_seal::run_instant_seal(InstantSealParams { + block_import: client.clone(), + env: proposer, + client, + pool: transaction_pool.pool().clone(), + select_chain, + consensus_data_provider: None, + create_inherent_data_providers: None, + }); + + task_manager + .spawn_essential_handle() + .spawn_blocking("instant-seal", authorship_future); + }; + + network_starter.start_network(); + Ok(task_manager) +} diff --git a/node/service/src/chain_spec/dev.rs b/node/service/src/chain_spec/dev.rs new file mode 100644 index 0000000000..8a7049fa40 --- /dev/null +++ b/node/service/src/chain_spec/dev.rs @@ -0,0 +1,202 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use cumulus_primitives_core::ParaId; +use dev_runtime::{ + constants::{currency::DOLLARS, time::DAYS}, + AccountId, AuraConfig, AuraId, Balance, BalancesConfig, BancorConfig, BlockNumber, + CouncilConfig, DemocracyConfig, GenesisConfig, GrandpaConfig, IndicesConfig, + MinterRewardConfig, ParachainInfoConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, + TokensConfig, VestingConfig, VtokenMintConfig, WASM_BINARY, +}; +use hex_literal::hex; +use node_primitives::{CurrencyId, TokenSymbol}; +use sc_service::ChainType; +use sc_telemetry::TelemetryEndpoints; +use sp_core::sr25519; +use sp_finality_grandpa::AuthorityId as GrandpaId; + +use super::TELEMETRY_URL; +use crate::chain_spec::{get_account_id_from_seed, get_from_seed, RelayExtensions}; + +const DEFAULT_PROTOCOL_ID: &str = "asgard-dev"; + +/// Specialized `ChainSpec` for the asgard runtime. +pub type ChainSpec = sc_service::GenericChainSpec; + +const ENDOWMENT: u128 = 1_000_000 * DOLLARS; + +/// Helper function to create asgard GenesisConfig for testing +pub fn dev_genesis( + invulnerables: Vec<(AccountId, AuraId, GrandpaId)>, + root_key: AccountId, + id: ParaId, + balances: Vec<(AccountId, Balance)>, + vestings: Vec<(AccountId, BlockNumber, BlockNumber, Balance)>, + tokens: Vec<(AccountId, CurrencyId, Balance)>, +) -> GenesisConfig { + GenesisConfig { + system: SystemConfig { + code: WASM_BINARY.expect("WASM binary was not build, please build it!").to_vec(), + changes_trie_config: Default::default(), + }, + balances: BalancesConfig { balances }, + indices: IndicesConfig { indices: vec![] }, + democracy: DemocracyConfig::default(), + council: CouncilConfig { members: vec![], phantom: Default::default() }, + technical_committee: TechnicalCommitteeConfig { + members: vec![], + phantom: Default::default(), + }, + council_membership: Default::default(), + technical_membership: Default::default(), + treasury: Default::default(), + elections: Default::default(), + sudo: SudoConfig { key: root_key.clone() }, + parachain_info: ParachainInfoConfig { parachain_id: id }, + aura: AuraConfig { authorities: invulnerables.iter().map(|x| (x.1.clone())).collect() }, + grandpa: GrandpaConfig { + authorities: invulnerables.iter().map(|x| (x.2.clone(), 1)).collect(), + }, + parachain_system: Default::default(), + vesting: VestingConfig { vesting: vestings }, + tokens: TokensConfig { balances: tokens }, + bancor: BancorConfig { + bancor_pools: vec![ + (CurrencyId::Token(TokenSymbol::DOT), 10_000 * DOLLARS), + (CurrencyId::Token(TokenSymbol::KSM), 1_000_000 * DOLLARS), + ], + }, + minter_reward: MinterRewardConfig { + currency_weights: vec![ + (CurrencyId::Token(TokenSymbol::DOT), 1 * 1), + (CurrencyId::Token(TokenSymbol::ETH), 1 * 1), + (CurrencyId::Token(TokenSymbol::KSM), 1 * 3), + ], + reward_per_block: 5 * DOLLARS / 100, + cycle_index: 1, + }, + vtoken_mint: VtokenMintConfig { + pools: vec![ + (CurrencyId::Token(TokenSymbol::DOT), 1000 * DOLLARS), + (CurrencyId::VToken(TokenSymbol::DOT), 1000 * DOLLARS), + (CurrencyId::Token(TokenSymbol::ETH), 1000 * DOLLARS), + (CurrencyId::VToken(TokenSymbol::ETH), 1000 * DOLLARS), + (CurrencyId::Token(TokenSymbol::KSM), 1000 * DOLLARS), + (CurrencyId::VToken(TokenSymbol::KSM), 1000 * DOLLARS), + ], + staking_lock_period: vec![ + (CurrencyId::Token(TokenSymbol::DOT), 28 * DAYS), + (CurrencyId::Token(TokenSymbol::ETH), 14 * DAYS), + (CurrencyId::Token(TokenSymbol::KSM), 7 * DAYS), + ], + }, + } +} + +fn development_config_genesis(id: ParaId) -> GenesisConfig { + let endowed_accounts = vec![get_account_id_from_seed::("Alice")]; + let balances = endowed_accounts + .iter() + .chain(faucet_accounts().iter()) + .cloned() + .map(|x| (x, ENDOWMENT)) + .collect(); + let vestings = endowed_accounts + .iter() + .cloned() + .map(|x| (x.clone(), 0u32, 100u32, ENDOWMENT / 4)) + .collect(); + let tokens = endowed_accounts + .iter() + .chain(faucet_accounts().iter()) + .flat_map(|x| { + vec![ + (x.clone(), CurrencyId::Stable(TokenSymbol::AUSD), ENDOWMENT * 10_000), + (x.clone(), CurrencyId::Token(TokenSymbol::DOT), ENDOWMENT), + (x.clone(), CurrencyId::Token(TokenSymbol::ETH), ENDOWMENT), + (x.clone(), CurrencyId::Token(TokenSymbol::KSM), ENDOWMENT), + ] + }) + .collect(); + + dev_genesis( + vec![( + get_account_id_from_seed::("Alice"), + get_from_seed::("Alice"), + get_from_seed::("Alice"), + )], + get_account_id_from_seed::("Alice"), + id, + balances, + vestings, + tokens, + ) +} + +pub fn development_config(id: ParaId) -> Result { + Ok(ChainSpec::from_genesis( + "Development", + "dev", + ChainType::Development, + move || development_config_genesis(id), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + RelayExtensions { relay_chain: "westend-dev".into(), para_id: id.into() }, + )) +} + +pub fn chainspec_config(id: ParaId) -> ChainSpec { + let mut properties = sc_chain_spec::Properties::new(); + properties.insert("tokenSymbol".into(), "ASG".into()); + properties.insert("tokenDecimals".into(), 12.into()); + + ChainSpec::from_genesis( + "Bifrost Dev", + "dev_testnet", + ChainType::Custom("Dev Testnet".into()), + move || development_config_genesis(id), + vec![], + TelemetryEndpoints::new(vec![(TELEMETRY_URL.into(), 0)]).ok(), + Some(DEFAULT_PROTOCOL_ID), + Some(properties), + RelayExtensions { relay_chain: "westend".into(), para_id: id.into() }, + ) +} + +pub fn faucet_accounts() -> Vec { + vec![ + hex!["ce6072037670ca8e974fd571eae4f215a58d0bf823b998f619c3f87a911c3541"].into(), /* asgard sudo account */ + hex!["a2d57b8e781327bd2853b36e6f290bd8beeaa850971c9b0789ec4969f8beb01b"].into(), /* bifrost-faucet */ + hex!["a272fa6e2282767b61a299e81023d44ef583c640fef99b0bafe216399775cd17"].into(), + hex!["56f6e7bb0826cd128672ad3a03016533834123c319adc635c6db595c6f72272e"].into(), + hex!["7e9005c247601a0d0e967f68b03f6e39e402a735ec65c20e4965c6d94a22e42f"].into(), + hex!["f2449dfbb431a5f9e8dc7468e5f3521baff4c0125edcda746f38df5295d5fb28"].into(), + hex!["aaa565b52ea12bf3c8d7abb79411976bccd8054c5581922acc0165ad88640f09"].into(), + hex!["8afadc065940f22f73b745aab694b1b20cafea3d4e52adad844f581614fbdd00"].into(), + hex!["0831325e2b4953f247db9df3f6452becbf23d8f7f806c0396ad853cb3c284d06"].into(), + hex!["7ea84934a575487fb02c44e01f4488c2f242cdbf48052630780dcd8ac567950c"].into(), + hex!["ee05492a82cb982392aad78f7e6f6fff56eaee4988fd9961ebb84e177dd6526d"].into(), /* bifrost-faucet */ + hex!["7435653321694ee115e8cea8c8e117c0b6703b6fb91298b6df5adeef7679a46f"].into(), /* danny testing account */ + hex!["263c78393f33b23cd23f3211726b2316e950910749d20c1552ea6972091a645e"].into(), /* jianbo testing account */ + hex!["803feefeab8e5c81c3d268038b6c494d3018714fc8c5d08cf027111fd8114b06"].into(), /* tieqiao testing account */ + hex!["8898ffd2cb04fb751655ede7bc0081b6b6ebe13cd0bdee5bbb9273e6dcc9b91c"].into(), /* tyrone testing account */ + ] +} diff --git a/node/service/src/chain_spec/mod.rs b/node/service/src/chain_spec/mod.rs index 70252e7c87..04b9ba3844 100644 --- a/node/service/src/chain_spec/mod.rs +++ b/node/service/src/chain_spec/mod.rs @@ -20,6 +20,8 @@ pub mod asgard; #[cfg(feature = "with-bifrost-runtime")] pub mod bifrost; +#[cfg(feature = "with-dev-runtime")] +pub mod dev; pub use node_primitives::{AccountId, Block, Signature}; use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; diff --git a/node/service/src/client.rs b/node/service/src/client.rs index 1d291824e8..4726393746 100644 --- a/node/service/src/client.rs +++ b/node/service/src/client.rs @@ -151,6 +151,8 @@ pub enum Client { Asgard(Arc>), #[cfg(feature = "with-bifrost-runtime")] Bifrost(Arc>), + #[cfg(feature = "with-dev-runtime")] + AsgardDev(Arc>), } impl ClientHandle for Client { @@ -160,6 +162,8 @@ impl ClientHandle for Client { Self::Asgard(client) => T::execute_with_client::<_, _, FullBackend>(t, client.clone()), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => T::execute_with_client::<_, _, FullBackend>(t, client.clone()), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => T::execute_with_client::<_, _, FullBackend>(t, client.clone()), } } } @@ -171,6 +175,8 @@ impl sc_client_api::UsageProvider for Client { Self::Asgard(client) => client.usage_info(), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.usage_info(), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.usage_info(), } } } @@ -185,6 +191,8 @@ impl sc_client_api::BlockBackend for Client { Self::Asgard(client) => client.block_body(id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.block_body(id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.block_body(id), } } @@ -194,6 +202,8 @@ impl sc_client_api::BlockBackend for Client { Self::Asgard(client) => client.block(id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.block(id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.block(id), } } @@ -203,6 +213,8 @@ impl sc_client_api::BlockBackend for Client { Self::Asgard(client) => client.block_status(id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.block_status(id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.block_status(id), } } @@ -212,6 +224,8 @@ impl sc_client_api::BlockBackend for Client { Self::Asgard(client) => client.justifications(id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.justifications(id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.justifications(id), } } @@ -224,6 +238,8 @@ impl sc_client_api::BlockBackend for Client { Self::Asgard(client) => client.block_hash(number), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.block_hash(number), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.block_hash(number), } } @@ -236,6 +252,8 @@ impl sc_client_api::BlockBackend for Client { Self::Asgard(client) => client.indexed_transaction(id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.indexed_transaction(id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.indexed_transaction(id), } } @@ -248,6 +266,8 @@ impl sc_client_api::BlockBackend for Client { Self::Asgard(client) => client.block_indexed_body(id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.block_indexed_body(id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.block_indexed_body(id), } } } @@ -263,6 +283,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.storage(id, key), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.storage(id, key), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.storage(id, key), } } @@ -276,6 +298,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.storage_keys(id, key_prefix), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.storage_keys(id, key_prefix), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.storage_keys(id, key_prefix), } } @@ -289,6 +313,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.storage_hash(id, key), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.storage_hash(id, key), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.storage_hash(id, key), } } @@ -302,6 +328,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.storage_pairs(id, key_prefix), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.storage_pairs(id, key_prefix), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.storage_pairs(id, key_prefix), } } @@ -318,6 +346,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.storage_keys_iter(id, prefix, start_key), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.storage_keys_iter(id, prefix, start_key), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.storage_keys_iter(id, prefix, start_key), } } @@ -332,6 +362,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.child_storage(id, child_info, key), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.child_storage(id, child_info, key), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.child_storage(id, child_info, key), } } @@ -346,6 +378,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.child_storage_keys(id, child_info, key_prefix), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.child_storage_keys(id, child_info, key_prefix), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.child_storage_keys(id, child_info, key_prefix), } } @@ -360,6 +394,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.child_storage_hash(id, child_info, key), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.child_storage_hash(id, child_info, key), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.child_storage_hash(id, child_info, key), } } @@ -373,6 +409,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.max_key_changes_range(first, last), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.max_key_changes_range(first, last), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.max_key_changes_range(first, last), } } @@ -388,6 +426,8 @@ impl sc_client_api::StorageProvider for Client { Self::Asgard(client) => client.key_changes(first, last, storage_key, key), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.key_changes(first, last, storage_key, key), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.key_changes(first, last, storage_key, key), } } } @@ -399,6 +439,8 @@ impl sp_blockchain::HeaderBackend for Client { Self::Asgard(client) => client.header(&id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.header(&id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.header(&id), } } @@ -408,6 +450,8 @@ impl sp_blockchain::HeaderBackend for Client { Self::Asgard(client) => client.info(), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.info(), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.info(), } } @@ -417,6 +461,8 @@ impl sp_blockchain::HeaderBackend for Client { Self::Asgard(client) => client.status(id), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.status(id), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.status(id), } } @@ -426,6 +472,8 @@ impl sp_blockchain::HeaderBackend for Client { Self::Asgard(client) => client.number(hash), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.number(hash), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.number(hash), } } @@ -435,6 +483,8 @@ impl sp_blockchain::HeaderBackend for Client { Self::Asgard(client) => client.hash(number), #[cfg(feature = "with-bifrost-runtime")] Self::Bifrost(client) => client.hash(number), + #[cfg(feature = "with-dev-runtime")] + Self::AsgardDev(client) => client.hash(number), } } } diff --git a/node/service/src/dev.rs b/node/service/src/dev.rs new file mode 100644 index 0000000000..3eb581c89d --- /dev/null +++ b/node/service/src/dev.rs @@ -0,0 +1,331 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use std::{sync::Arc, time::Duration}; + +use cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider; +#[cfg(feature = "with-dev-runtime")] +pub use dev_runtime; +use sc_client_api::ExecutorProvider; +use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams}; +use sc_executor::native_executor_instance; +pub use sc_executor::NativeExecutor; +use sc_finality_grandpa::SharedVoterState; +use sc_keystore::LocalKeystore; +use sc_service::{error::Error as ServiceError, Configuration, TaskManager}; +use sc_telemetry::{Telemetry, TelemetryWorker}; +use sp_consensus::SlotData; +use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; + +#[cfg(feature = "with-dev-runtime")] +native_executor_instance!( + pub DevExecutor, + dev_runtime::api::dispatch, + dev_runtime::native_version, + frame_benchmarking::benchmarking::HostFunctions, +); + +type Block = dev_runtime::Block; +type Executor = crate::DevExecutor; +type RuntimeApi = dev_runtime::RuntimeApi; +type FullClient = sc_service::TFullClient; +type FullBackend = sc_service::TFullBackend; +type FullSelectChain = sc_consensus::LongestChain; + +fn default_mock_parachain_inherent_data_provider() -> MockValidationDataInherentDataProvider { + MockValidationDataInherentDataProvider { + current_para_block: 0, + relay_offset: 1000, + relay_blocks_per_para_block: 2, + } +} + +pub fn new_partial( + config: &Configuration, +) -> Result< + sc_service::PartialComponents< + FullClient, + FullBackend, + FullSelectChain, + sp_consensus::DefaultImportQueue, + sc_transaction_pool::FullPool, + ( + sc_finality_grandpa::GrandpaBlockImport< + FullBackend, + Block, + FullClient, + FullSelectChain, + >, + sc_finality_grandpa::LinkHalf, + Option, + ), + >, + ServiceError, +> { + if config.keystore_remote.is_some() { + return Err(ServiceError::Other(format!("Remote Keystores are not supported."))); + } + + let telemetry = config + .telemetry_endpoints + .clone() + .filter(|x| !x.is_empty()) + .map(|endpoints| -> Result<_, sc_telemetry::Error> { + let worker = TelemetryWorker::new(16)?; + let telemetry = worker.handle().new_telemetry(endpoints); + Ok((worker, telemetry)) + }) + .transpose()?; + + let (client, backend, keystore_container, task_manager) = + sc_service::new_full_parts::( + &config, + telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + )?; + let client = Arc::new(client); + + let telemetry = telemetry.map(|(worker, telemetry)| { + task_manager.spawn_handle().spawn("telemetry", worker.run()); + telemetry + }); + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.role.is_authority().into(), + config.prometheus_registry(), + task_manager.spawn_essential_handle(), + client.clone(), + ); + + let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( + client.clone(), + &(client.clone() as Arc<_>), + select_chain.clone(), + telemetry.as_ref().map(|x| x.handle()), + )?; + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration(); + + let import_queue = + sc_consensus_aura::import_queue::(ImportQueueParams { + block_import: grandpa_block_import.clone(), + justification_import: Some(Box::new(grandpa_block_import.clone())), + client: client.clone(), + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( + *timestamp, + slot_duration, + ); + + Ok((timestamp, slot, default_mock_parachain_inherent_data_provider())) + }, + spawner: &task_manager.spawn_essential_handle(), + can_author_with: sp_consensus::CanAuthorWithNativeVersion::new( + client.executor().clone(), + ), + registry: config.prometheus_registry(), + check_for_equivocation: Default::default(), + telemetry: telemetry.as_ref().map(|x| x.handle()), + })?; + + Ok(sc_service::PartialComponents { + client, + backend, + task_manager, + import_queue, + keystore_container, + select_chain, + transaction_pool, + other: (grandpa_block_import, grandpa_link, telemetry), + }) +} + +fn remote_keystore(_url: &String) -> Result, &'static str> { + // FIXME: here would the concrete keystore be built, + // must return a concrete type (NOT `LocalKeystore`) that + // implements `CryptoStore` and `SyncCryptoStore` + Err("Remote Keystore not supported.") +} + +/// Builds a new service for a full client. +pub fn new_full(mut config: Configuration) -> Result { + let sc_service::PartialComponents { + client, + backend, + mut task_manager, + import_queue, + mut keystore_container, + select_chain, + transaction_pool, + other: (block_import, grandpa_link, mut telemetry), + } = new_partial(&config)?; + + if let Some(url) = &config.keystore_remote { + match remote_keystore(url) { + Ok(k) => keystore_container.set_remote_keystore(k), + Err(e) => + return Err(ServiceError::Other(format!( + "Error hooking up remote keystore for {}: {}", + url, e + ))), + }; + } + + config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config()); + + let (network, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: None, + block_announce_validator_builder: None, + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, + task_manager.spawn_handle(), + client.clone(), + network.clone(), + ); + } + + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let backoff_authoring_blocks: Option<()> = None; + let name = config.network.node_name.clone(); + let enable_grandpa = !config.disable_grandpa; + let prometheus_registry = config.prometheus_registry().cloned(); + + let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { + network: network.clone(), + client: client.clone(), + keystore: keystore_container.sync_keystore(), + task_manager: &mut task_manager, + transaction_pool: transaction_pool.clone(), + rpc_extensions_builder: Box::new(|_, _| ()), + on_demand: None, + remote_blockchain: None, + backend, + system_rpc_tx, + config, + telemetry: telemetry.as_mut(), + })?; + + if role.is_authority() { + let proposer_factory = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry.as_ref(), + telemetry.as_ref().map(|x| x.handle()), + ); + + let can_author_with = + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + let raw_slot_duration = slot_duration.slot_duration(); + + let aura = sc_consensus_aura::start_aura::( + StartAuraParams { + slot_duration, + client: client.clone(), + select_chain, + block_import, + proposer_factory, + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( + *timestamp, + raw_slot_duration, + ); + + Ok((timestamp, slot, default_mock_parachain_inherent_data_provider())) + }, + force_authoring, + backoff_authoring_blocks, + keystore: keystore_container.sync_keystore(), + can_author_with, + sync_oracle: network.clone(), + justification_sync_link: network.clone(), + block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32), + max_block_proposal_slot_portion: None, + telemetry: telemetry.as_ref().map(|x| x.handle()), + }, + )?; + + // the AURA authoring task is considered essential, i.e. if it + // fails we take down the service with it. + task_manager.spawn_essential_handle().spawn_blocking("aura", aura); + } + + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = + if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None }; + + let grandpa_config = sc_finality_grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 512, + name: Some(name), + observer_enabled: false, + keystore, + local_role: role, + telemetry: telemetry.as_ref().map(|x| x.handle()), + }; + + if enable_grandpa { + // start the full GRANDPA voter + // NOTE: non-authorities could run the GRANDPA observer protocol, but at + // this point the full voter should provide better guarantees of block + // and vote data availability than the observer. The observer has not + // been tested extensively yet and having most nodes in a network run it + // could lead to finality stalls. + let grandpa_config = sc_finality_grandpa::GrandpaParams { + config: grandpa_config, + link: grandpa_link, + network, + voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), + prometheus_registry, + shared_voter_state: SharedVoterState::empty(), + telemetry: telemetry.as_ref().map(|x| x.handle()), + }; + + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + task_manager.spawn_essential_handle().spawn_blocking( + "grandpa-voter", + sc_finality_grandpa::run_grandpa_voter(grandpa_config)?, + ); + } + + network_starter.start_network(); + Ok(task_manager) +} diff --git a/node/service/src/lib.rs b/node/service/src/lib.rs index 42fc664a8e..296fda8f16 100644 --- a/node/service/src/lib.rs +++ b/node/service/src/lib.rs @@ -24,10 +24,14 @@ pub use client::*; pub use collator::*; +#[cfg(feature = "with-dev-runtime")] +pub use dev::*; pub mod chain_spec; mod client; pub mod collator; +#[cfg(feature = "with-dev-runtime")] +pub mod dev; /// Can be called for a `Configuration` to check if it is a configuration for the `Bifrost` network. pub trait IdentifyVariant { @@ -36,6 +40,9 @@ pub trait IdentifyVariant { /// Returns if this is a configuration for the `Bifrost` network. fn is_bifrost(&self) -> bool; + + /// Returns if this is a configuration for the `Dev` network. + fn is_asgard_dev(&self) -> bool; } impl IdentifyVariant for Box { @@ -46,4 +53,8 @@ impl IdentifyVariant for Box { fn is_bifrost(&self) -> bool { self.id().starts_with("bifrost") || self.id().starts_with("bnc") } + + fn is_asgard_dev(&self) -> bool { + self.id().starts_with("asgard-dev") || self.id().starts_with("dev") + } } diff --git a/runtime/dev/Cargo.toml b/runtime/dev/Cargo.toml new file mode 100644 index 0000000000..9814900128 --- /dev/null +++ b/runtime/dev/Cargo.toml @@ -0,0 +1,190 @@ +[package] +name = "dev-runtime" +version = "0.8.0" +authors = ["Ron Yang "] +edition = "2018" +build = "build.rs" + +[dependencies] +# third-party dependencies +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive", "max-encoded-len"] } +log = { version = "0.4.14", default-features = false } +serde = { version = "1.0.124", optional = true } +static_assertions = "1.1.0" +hex-literal = { version = "0.3.1"} + +# primitives +node-primitives = { default-features = false, path = "../../node/primitives" } +sp-block-builder = { version = "3.0.0", default-features = false} +sp-inherents = { version = "3.0.0", default-features = false } +sp-offchain = { version = "3.0.0", default-features = false } +sp-core = { version = "3.0.0", default-features = false } +sp-std = { version = "3.0.0", default-features = false } +sp-api = { version = "3.0.0", default-features = false } +sp-runtime = { version = "3.0.0", default-features = false } +sp-session = { version = "3.0.0", default-features = false } +sp-transaction-pool = { version = "3.0.0", default-features = false } +sp-version = { version = "3.0.0", default-features = false } +sp-consensus-aura = { version = "0.9.0", default-features = false } +sp-arithmetic = { version = "3.0.0", default-features = false } + +# frame dependencies +frame-benchmarking = { version = "3.0.0", default-features = false, optional = true } +frame-executive = { version = "3.0.0", default-features = false } +frame-support = { version = "3.0.0", default-features = false } +frame-system = { version = "3.0.0", default-features = false } +frame-system-rpc-runtime-api = { version = "3.0.0", default-features = false } +max-encoded-len = { version = "3.0.0", default-features = false } +pallet-authorship = { version = "3.0.0", default-features = false } +pallet-aura = { version = "3.0.0", default-features = false } +pallet-grandpa = { version = "3.0.0", default-features = false } +pallet-balances = { version = "3.0.0", default-features = false } +pallet-bounties = { version = "3.0.0", default-features = false } +pallet-collective = { version = "3.0.0", default-features = false } +pallet-democracy = { version = "3.0.0", default-features = false } +pallet-elections-phragmen = { version = "4.0.0", default-features = false } +pallet-indices = { version = "3.0.0", default-features = false } +pallet-membership = { version = "3.0.0", default-features = false } +pallet-multisig = { version = "3.0.0", default-features = false } +pallet-proxy = { version = "3.0.0", default-features = false } +pallet-randomness-collective-flip = { version = "3.0.0", default-features = false } +pallet-scheduler = { version = "3.0.0", default-features = false } +pallet-session = { version = "3.0.0", default-features = false } +pallet-sudo = { version = "3.0.0", default-features = false } +pallet-timestamp = { version = "3.0.0", default-features = false } +pallet-tips = { version = "3.0.0", default-features = false } +pallet-transaction-payment = { version = "3.0.0", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { version = "3.0.0", default-features = false } +pallet-treasury = { version = "3.0.0", default-features = false } +pallet-utility = { version = "3.0.0", default-features = false } +pallet-vesting = { version = "3.0.0", default-features = false } + +# Cumulus dependencies +cumulus-pallet-aura-ext = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +cumulus-primitives-timestamp = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +cumulus-primitives-utility = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +cumulus-pallet-xcm = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +parachain-info = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } +pallet-collator-selection = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.8" } + +# Polkadot dependencies +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } +xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } +xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } +xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } + +# bifrost pallets +bifrost-runtime-common = { package = "bifrost-runtime-common", path = "../common", default-features = false } +bifrost-vtoken-mint = { path = "../../pallets/vtoken-mint", default-features = false } +bifrost-minter-reward = { path = "../../pallets/minter-reward", default-features = false } +bifrost-flexible-fee = { path = "../../pallets/flexible-fee", default-features = false } +bifrost-flexible-fee-rpc-runtime-api = { path = "../../pallets/flexible-fee/rpc/runtime-api", default-features = false } +bifrost-salp= {path = "../../pallets/salp",default-features = false} +bifrost-bancor= {path = "../../pallets/bancor",default-features = false} +bifrost-vsbond-auction = { path = "../../pallets/vsbond-auction", default-features = false } +bifrost-bancor-runtime-api = { path = "../../pallets/bancor/rpc/runtime-api", default-features = false } + +# orml +orml-currencies = { version = "0.4.1-dev", default-features = false } +orml-tokens = { version = "0.4.1-dev", default-features = false } +orml-traits = { version = "0.4.1-dev", default-features = false } +xcm-support = { path = "../../xcm-support", default-features = false } + +zenlink-protocol = { version = "*", default-features = false } +zenlink-protocol-runtime-api = { version = "*", default-features = false } + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } + +[features] +default = ["std"] +with-tracing = [ "frame-executive/with-tracing" ] +std = [ + "codec/std", + "log/std", + "frame-benchmarking/std", + "frame-executive/std", + "frame-support/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "max-encoded-len/std", + "node-primitives/std", + "pallet-aura/std", + "pallet-grandpa/std", + "pallet-balances/std", + "pallet-bounties/std", + "pallet-collator-selection/std", + "pallet-collective/std", + "pallet-democracy/std", + "pallet-elections-phragmen/std", + "pallet-indices/std", + "pallet-membership/std", + "pallet-multisig/std", + "pallet-proxy/std", + "pallet-randomness-collective-flip/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-tips/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-treasury/std", + "pallet-session/std", + "pallet-vesting/std", + "pallet-utility/std", + "sp-arithmetic/std", + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-aura/std", + "sp-core/std", + "sp-inherents/std", + "sp-runtime/std", + "sp-offchain/std", + "sp-session/std", + "sp-std/std", + "sp-transaction-pool/std", + "parachain-info/std", + "cumulus-pallet-aura-ext/std", + "cumulus-pallet-dmp-queue/std", + "cumulus-pallet-parachain-system/std", + "cumulus-pallet-xcmp-queue/std", + "cumulus-pallet-xcm/std", + "cumulus-primitives-core/std", + "cumulus-primitives-timestamp/std", + "cumulus-primitives-utility/std", + "xcm/std", + "xcm-builder/std", + "xcm-executor/std", + "polkadot-runtime-parachains/std", + "bifrost-bancor/std", + "bifrost-bancor-runtime-api/std", + "bifrost-flexible-fee/std", + "bifrost-flexible-fee-rpc-runtime-api/std", + "bifrost-minter-reward/std", + "bifrost-runtime-common/std", + "bifrost-salp/std", + "bifrost-vsbond-auction/std", + "bifrost-vtoken-mint/std", + "orml-currencies/std", + "orml-traits/std", + "orml-tokens/std", + "xcm-support/std", + "zenlink-protocol/std", + "zenlink-protocol-runtime-api/std", +] + +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "bifrost-salp/runtime-benchmarks", +] diff --git a/runtime/dev/build.rs b/runtime/dev/build.rs new file mode 100644 index 0000000000..2a888dbc96 --- /dev/null +++ b/runtime/dev/build.rs @@ -0,0 +1,29 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .export_heap_base() + .import_memory() + .append_to_rust_flags("-C opt-level=z") // shrink the size of wasm binary + .append_to_rust_flags("-C linker-plugin-lto") + .build() +} diff --git a/runtime/dev/src/constants.rs b/runtime/dev/src/constants.rs new file mode 100644 index 0000000000..55c3881a59 --- /dev/null +++ b/runtime/dev/src/constants.rs @@ -0,0 +1,84 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! A set of constant values used in Bifrost dev runtime. + +/// Money matters. +pub mod currency { + use node_primitives::Balance; + + pub const BNCS: Balance = 1_000_000_000_000; + pub const DOLLARS: Balance = BNCS; + pub const CENTS: Balance = DOLLARS / 100; // assume this is worth about a cent. + pub const MILLICENTS: Balance = CENTS / 1_000; + pub const MILLIBNC: Balance = 1_000_000_000; + pub const MICROBNC: Balance = 1_000_000; + pub const XCM_WEIGHT: u64 = 1_000_000_000; + + pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 15 * CENTS + (bytes as Balance) * 6 * CENTS + } +} + +/// Time. +pub mod time { + use node_primitives::{BlockNumber, Moment}; + + /// Since BABE is probabilistic this is the average expected block time that + /// we are targetting. Blocks will be produced at a minimum duration defined + /// by `SLOT_DURATION`, but some slots will not be allocated to any + /// authority and hence no block will be produced. We expect to have this + /// block time on average following the defined slot duration and the value + /// of `c` configured for BABE (where `1 - c` represents the probability of + /// a slot being empty). + /// This value is only used indirectly to define the unit constants below + /// that are expressed in blocks. The rest of the code should use + /// `SLOT_DURATION` instead (like the Timestamp pallet for calculating the + /// minimum period). + /// + /// If using BABE with secondary slots (default) then all of the slots will + /// always be assigned, in which case `MILLISECS_PER_BLOCK` and + /// `SLOT_DURATION` should have the same value. + /// + /// + pub const MILLISECS_PER_BLOCK: Moment = 12000; + pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000; + + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + + // 1 in 4 blocks (on average, not counting collisions) will be primary BABE blocks. + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); + + pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES; + pub const EPOCH_DURATION_IN_SLOTS: u64 = { + const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64; + + (EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64 + }; + + // These time units are defined in number of blocks. + pub const MINUTES: BlockNumber = 60 / (SECS_PER_BLOCK as BlockNumber); + pub const HOURS: BlockNumber = MINUTES * 60; + pub const DAYS: BlockNumber = HOURS * 24; + pub const WEEKS: BlockNumber = DAYS * 7; + + // The `LeasePeriod` defination from `polkadot`. + pub const KUSAMA_LEASE_PERIOD: BlockNumber = 6 * WEEKS; + pub const ROCOCO_LEASE_PERIOD: BlockNumber = 1 * DAYS; + pub const WESTEND_LEASE_PERIOD: BlockNumber = 28 * DAYS; +} diff --git a/runtime/dev/src/lib.rs b/runtime/dev/src/lib.rs new file mode 100644 index 0000000000..c274ece108 --- /dev/null +++ b/runtime/dev/src/lib.rs @@ -0,0 +1,1527 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! The Bifrost Node runtime. This can be compiled with `#[no_std]`, ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use core::convert::TryInto; + +// A few exports that help ease life for downstream crates. +pub use frame_support::{ + construct_runtime, match_type, parameter_types, + traits::{All, InstanceFilter, IsInVec, LockIdentifier, MaxEncodedLen, Randomness}, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + DispatchClass, IdentityFee, Weight, + }, + PalletId, RuntimeDebug, StorageValue, +}; +use frame_system::{ + limits::{BlockLength, BlockWeights}, + EnsureOneOf, EnsureRoot, +}; +pub use pallet_balances::Call as BalancesCall; +use pallet_grandpa::{ + fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, +}; +pub use pallet_timestamp::Call as TimestampCall; +use sp_api::impl_runtime_apis; +use sp_arithmetic::Percent; +pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::{ + u32_trait::{_1, _2, _3, _4, _5}, + OpaqueMetadata, +}; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; +#[cfg(feature = "runtime-benchmarks")] +use sp_runtime::RuntimeString; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + traits::{BlakeTwo256, Block as BlockT, NumberFor, UniqueSaturatedInto, Zero}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, DispatchError, DispatchResult, SaturatedConversion, +}; +pub use sp_runtime::{Perbill, Permill}; +use sp_std::{marker::PhantomData, prelude::*}; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; + +/// Constant values used within the runtime. +pub mod constants; +use bifrost_flexible_fee::fee_dealer::FixedCurrencyFeeRate; +use bifrost_runtime_common::xcm_impl::{ + BifrostAssetMatcher, BifrostCurrencyIdConvert, BifrostFilteredAssets, BifrostXcmTransactFilter, +}; +use codec::{Decode, Encode}; +use constants::{currency::*, time::*}; +use cumulus_primitives_core::ParaId as CumulusParaId; +use frame_support::{sp_runtime::KeyTypeId, traits::KeyOwnerProofSystem}; +use node_primitives::{ + Amount, CurrencyId, Moment, Nonce, TokenSymbol, TransferOriginType, XcmBaseWeight, +}; +// orml imports +use orml_currencies::BasicCurrencyAdapter; +use orml_traits::MultiCurrency; +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +use sp_runtime::traits::ConvertInto; +use static_assertions::const_assert; +use xcm::v0::{BodyId, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, NetworkId, Xcm}; +use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, + EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, ParentAsSuperuser, + ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + UsingComponents, +}; +use xcm_executor::{Config, XcmExecutor}; +use xcm_support::{BifrostCurrencyAdapter, BifrostXcmAdaptor}; +// zenlink imports +use zenlink_protocol::{ + make_x2_location, AssetBalance, AssetId, LocalAssetHandler, MultiAssetsHandler, PairInfo, + ZenlinkMultiAssets, +}; + +mod weights; + +pub type SessionHandlers = (); + +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + pub grandpa: Grandpa, + } +} + +/// This runtime version. +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("asgard-dev"), + impl_name: create_runtime_str!("asgard-dev"), + authoring_version: 1, + spec_version: 1001, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, +}; + +/// The version information used to identify this runtime when compiled natively. +#[cfg(feature = "std")] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + +/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers. +/// This is used to limit the maximal weight of a single extrinsic. +const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); +/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used +/// by Operational extrinsics. +const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +/// We allow for 2 seconds of compute with a 6 second average block time. +const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND; + +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; + pub const Version: RuntimeVersion = VERSION; + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); + pub const SS58Prefix: u8 = 6; +} + +parameter_types! { + pub const NativeCurrencyId: CurrencyId = CurrencyId::Native(TokenSymbol::ASG); + pub const RelayCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); + pub const StableCurrencyId: CurrencyId = CurrencyId::Stable(TokenSymbol::AUSD); +} + +impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + type BaseCallFilter = (); + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + type BlockLength = RuntimeBlockLength; + /// The index type for blocks. + type BlockNumber = BlockNumber; + type BlockWeights = RuntimeBlockWeights; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + type DbWeight = RocksDbWeight; + /// The ubiquitous event type. + type Event = Event; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The header type. + type Header = generic::Header; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = Indices; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + /// The ubiquitous origin type. + type Origin = Origin; + /// Converts a module to an index of this module in the runtime. + type PalletInfo = PalletInfo; + type SS58Prefix = SS58Prefix; + type SystemWeightInfo = (); + /// Runtime version. + type Version = Version; +} + +parameter_types! { + pub const MinimumPeriod: Moment = SLOT_DURATION / 2; +} + +impl pallet_timestamp::Config for Runtime { + type MinimumPeriod = MinimumPeriod; + /// A timestamp: milliseconds since the unix epoch. + type Moment = Moment; + type OnTimestampSet = (); + type WeightInfo = pallet_timestamp::weights::SubstrateWeight; +} + +parameter_types! { + pub const ExistentialDeposit: u128 = 1 * MILLIBNC; + pub const TransferFee: u128 = 1 * MILLIBNC; + pub const CreationFee: u128 = 1 * MILLIBNC; + pub const TransactionByteFee: u128 = 1 * MICROBNC; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_utility::Config for Runtime { + type Call = Call; + type Event = Event; + type WeightInfo = pallet_utility::weights::SubstrateWeight; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u16 = 100; +} + +impl pallet_multisig::Config for Runtime { + type Call = Call; + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type Event = Event; + type MaxSignatories = MaxSignatories; + type WeightInfo = pallet_multisig::weights::SubstrateWeight; +} + +parameter_types! { + // One storage item; key size 32, value size 8; . + pub const ProxyDepositBase: Balance = deposit(1, 8); + // Additional storage item size of 33 bytes. + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u16 = 32; + pub const AnnouncementDepositBase: Balance = deposit(1, 8); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); + pub const MaxPending: u16 = 32; +} + +/// The type used to represent the kinds of proxying allowed. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen, +)] +pub enum ProxyType { + Any = 0, + NonTransfer = 1, + Governance = 2, + CancelProxy = 3, +} + +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} +impl InstanceFilter for ProxyType { + fn filter(&self, c: &Call) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => matches!( + c, + Call::System(..) | + Call::Scheduler(..) | + Call::Timestamp(..) | + Call::Indices(pallet_indices::Call::claim(..)) | + Call::Indices(pallet_indices::Call::free(..)) | + Call::Indices(pallet_indices::Call::freeze(..)) | + Call::Democracy(..) | + Call::Council(..) | + Call::TechnicalCommittee(..) | + Call::Elections(..) | + Call::TechnicalMembership(..) | + Call::Treasury(..) | + Call::Bounties(..) | + Call::Tips(..) | + Call::Vesting(pallet_vesting::Call::vest(..)) | + Call::Vesting(pallet_vesting::Call::vest_other(..)) | + // Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer` + Call::Utility(..) | + Call::Proxy(..) | + Call::Multisig(..) + ), + ProxyType::Governance => matches!( + c, + Call::Democracy(..) | + Call::Council(..) | Call::TechnicalCommittee(..) | + Call::Elections(..) | Call::Treasury(..) | + Call::Bounties(..) | Call::Tips(..) | + Call::Utility(..) + ), + ProxyType::CancelProxy => { + matches!(c, Call::Proxy(pallet_proxy::Call::reject_announcement(..))) + }, + } + } + + fn is_superset(&self, o: &Self) -> bool { + match (self, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::NonTransfer, _) => true, + _ => false, + } + } +} + +impl pallet_proxy::Config for Runtime { + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; + type Call = Call; + type CallHasher = BlakeTwo256; + type Currency = Balances; + type Event = Event; + type MaxPending = MaxPending; + type MaxProxies = MaxProxies; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type ProxyType = ProxyType; + type WeightInfo = pallet_proxy::weights::SubstrateWeight; +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + RuntimeBlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; +} + +impl pallet_scheduler::Config for Runtime { + type Call = Call; + type Event = Event; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type MaximumWeight = MaximumSchedulerWeight; + type Origin = Origin; + type PalletsOrigin = OriginCaller; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; +} + +parameter_types! { + pub const IndexDeposit: Balance = 1 * DOLLARS; +} + +impl pallet_indices::Config for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type Event = Event; + type WeightInfo = pallet_indices::weights::SubstrateWeight; +} + +impl pallet_balances::Config for Runtime { + type AccountStore = System; + /// The type for recording an account's balance. + type Balance = Balance; + type DustRemoval = (); + /// The ubiquitous event type. + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = pallet_balances::weights::SubstrateWeight; +} + +parameter_types! { + pub const CouncilMotionDuration: BlockNumber = 3 * DAYS; + pub const CouncilMaxProposals: u32 = 100; + pub const CouncilMaxMembers: u32 = 100; +} + +type CouncilCollective = pallet_collective::Instance1; +impl pallet_collective::Config for Runtime { + type DefaultVote = pallet_collective::PrimeDefaultVote; + type Event = Event; + type MaxMembers = CouncilMaxMembers; + type MaxProposals = CouncilMaxProposals; + type MotionDuration = CouncilMotionDuration; + type Origin = Origin; + type Proposal = Call; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} + +parameter_types! { + pub const CandidacyBond: Balance = 100 * CENTS; + // 1 storage item created, key size is 32 bytes, value size is 16+16. + pub const VotingBondBase: Balance = deposit(1, 64); + // additional data per vote is 32 bytes (account id). + pub const VotingBondFactor: Balance = deposit(0, 32); + /// Daily council elections + pub const TermDuration: BlockNumber = 24 * HOURS; + pub const DesiredMembers: u32 = 19; + pub const DesiredRunnersUp: u32 = 19; + pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect"; +} + +// Make sure that there are no more than MaxMembers members elected via phragmen. +const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get()); + +impl pallet_elections_phragmen::Config for Runtime { + type CandidacyBond = CandidacyBond; + type ChangeMembers = Council; + type Currency = Balances; + type CurrencyToVote = frame_support::traits::U128CurrencyToVote; + type DesiredMembers = DesiredMembers; + type DesiredRunnersUp = DesiredRunnersUp; + type Event = Event; + type InitializeMembers = Council; + type KickedMember = Treasury; + type LoserCandidate = Treasury; + type PalletId = PhragmenElectionPalletId; + type TermDuration = TermDuration; + type VotingBondBase = VotingBondBase; + type VotingBondFactor = VotingBondFactor; + type WeightInfo = pallet_elections_phragmen::weights::SubstrateWeight; +} + +parameter_types! { + pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS; + pub const TechnicalMaxProposals: u32 = 100; + pub const TechnicalMaxMembers: u32 = 100; +} + +type TechnicalCollective = pallet_collective::Instance2; +impl pallet_collective::Config for Runtime { + type DefaultVote = pallet_collective::PrimeDefaultVote; + type Event = Event; + type MaxMembers = TechnicalMaxMembers; + type MaxProposals = TechnicalMaxProposals; + type MotionDuration = TechnicalMotionDuration; + type Origin = Origin; + type Proposal = Call; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} + +type MoreThanHalfCouncil = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>, +>; + +impl pallet_membership::Config for Runtime { + type AddOrigin = MoreThanHalfCouncil; + type Event = Event; + type MaxMembers = CouncilMaxMembers; + type MembershipChanged = Council; + type MembershipInitialized = Council; + type PrimeOrigin = MoreThanHalfCouncil; + type RemoveOrigin = MoreThanHalfCouncil; + type ResetOrigin = MoreThanHalfCouncil; + type SwapOrigin = MoreThanHalfCouncil; + type WeightInfo = pallet_membership::weights::SubstrateWeight; +} + +impl pallet_membership::Config for Runtime { + type AddOrigin = MoreThanHalfCouncil; + type Event = Event; + type MaxMembers = TechnicalMaxMembers; + type MembershipChanged = TechnicalCommittee; + type MembershipInitialized = TechnicalCommittee; + type PrimeOrigin = MoreThanHalfCouncil; + type RemoveOrigin = MoreThanHalfCouncil; + type ResetOrigin = MoreThanHalfCouncil; + type SwapOrigin = MoreThanHalfCouncil; + type WeightInfo = pallet_membership::weights::SubstrateWeight; +} + +parameter_types! { + pub const LaunchPeriod: BlockNumber = 7 * DAYS; + pub const VotingPeriod: BlockNumber = 7 * DAYS; + pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS; + pub const MinimumDeposit: Balance = 50 * DOLLARS; + pub const EnactmentPeriod: BlockNumber = 8 * DAYS; + pub const CooloffPeriod: BlockNumber = 7 * DAYS; + // One cent: $10,000 / MB + pub const PreimageByteDeposit: Balance = 100 * MILLICENTS; + pub const InstantAllowed: bool = true; + pub const MaxVotes: u32 = 100; + pub const MaxProposals: u32 = 100; +} + +impl pallet_democracy::Config for Runtime { + type BlacklistOrigin = EnsureRoot; + // To cancel a proposal before it has been passed, the technical committee must be unanimous or + // Root must agree. + type CancelProposalOrigin = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>, + >; + // To cancel a proposal which has been passed, 2/3 of the council must agree to it. + type CancellationOrigin = + pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>; + type CooloffPeriod = CooloffPeriod; + type Currency = Balances; + type EnactmentPeriod = EnactmentPeriod; + type Event = Event; + /// A unanimous council can have the next scheduled referendum be a straight default-carries + /// (NTB) vote. + type ExternalDefaultOrigin = + pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>; + /// A super-majority can have the next scheduled referendum be a straight majority-carries vote. + type ExternalMajorityOrigin = + pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>; + /// A straight majority of the council can decide what their next motion is. + type ExternalOrigin = + pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>; + /// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote + /// be tabled immediately and with a shorter voting/enactment period. + type FastTrackOrigin = + pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>; + type FastTrackVotingPeriod = FastTrackVotingPeriod; + type InstantAllowed = InstantAllowed; + type InstantOrigin = + pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>; + type LaunchPeriod = LaunchPeriod; + type MaxProposals = MaxProposals; + type MaxVotes = MaxVotes; + type MinimumDeposit = MinimumDeposit; + type OperationalPreimageOrigin = pallet_collective::EnsureMember; + type PalletsOrigin = OriginCaller; + type PreimageByteDeposit = PreimageByteDeposit; + type Proposal = Call; + type Scheduler = Scheduler; + // NOTE: Treasury replaced by `()`. + type Slash = (); + // Any single technical committee member may veto a coming council proposal, however they can + // only do it once and it lasts only for the cool-off period. + type VetoOrigin = pallet_collective::EnsureMember; + type VotingPeriod = VotingPeriod; + type WeightInfo = pallet_democracy::weights::SubstrateWeight; +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 50 * DOLLARS; + pub const SpendPeriod: BlockNumber = 6 * DAYS; + pub const Burn: Permill = Permill::from_perthousand(2); + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + + pub const TipCountdown: BlockNumber = 1 * DAYS; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: Balance = 1 * DOLLARS; + pub const DataDepositPerByte: Balance = 10 * CENTS; + pub const BountyDepositBase: Balance = 1 * DOLLARS; + pub const BountyDepositPayoutDelay: BlockNumber = 4 * DAYS; + pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS; + pub const MaximumReasonLength: u32 = 16384; + pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); + pub const BountyValueMinimum: Balance = 10 * DOLLARS; + pub const MaxApprovals: u32 = 100; +} + +type ApproveOrigin = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>, +>; + +impl pallet_treasury::Config for Runtime { + type ApproveOrigin = ApproveOrigin; + type Burn = Burn; + type BurnDestination = (); + type Currency = Balances; + type Event = Event; + type MaxApprovals = MaxApprovals; + type OnSlash = Treasury; + type PalletId = TreasuryPalletId; + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type RejectOrigin = MoreThanHalfCouncil; + type SpendFunds = Bounties; + type SpendPeriod = SpendPeriod; + type WeightInfo = pallet_treasury::weights::SubstrateWeight; +} + +impl pallet_bounties::Config for Runtime { + type BountyCuratorDeposit = BountyCuratorDeposit; + type BountyDepositBase = BountyDepositBase; + type BountyDepositPayoutDelay = BountyDepositPayoutDelay; + type BountyUpdatePeriod = BountyUpdatePeriod; + type BountyValueMinimum = BountyValueMinimum; + type DataDepositPerByte = DataDepositPerByte; + type Event = Event; + type MaximumReasonLength = MaximumReasonLength; + type WeightInfo = pallet_bounties::weights::SubstrateWeight; +} + +impl pallet_tips::Config for Runtime { + type DataDepositPerByte = DataDepositPerByte; + type Event = Event; + type MaximumReasonLength = MaximumReasonLength; + type TipCountdown = TipCountdown; + type TipFindersFee = TipFindersFee; + type TipReportDepositBase = TipReportDepositBase; + type Tippers = Elections; + type WeightInfo = pallet_tips::weights::SubstrateWeight; +} + +impl pallet_transaction_payment::Config for Runtime { + type FeeMultiplierUpdate = (); + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = IdentityFee; +} + +impl pallet_sudo::Config for Runtime { + type Call = Call; + type Event = Event; +} + +// culumus runtime start +parameter_types! { + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + type DmpMessageHandler = DmpQueue; + type Event = Event; + type OnValidationData = (); + type OutboundXcmpMessageSource = XcmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type SelfParaId = parachain_info::Pallet; + type XcmpMessageHandler = XcmpQueue; +} + +impl parachain_info::Config for Runtime {} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +impl pallet_randomness_collective_flip::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = X1(Parent); + pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub SelfParaChainId: CumulusParaId = ParachainInfo::parachain_id(); + pub Ancestry: MultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); +} + +/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// when determining ownership of accounts for asset transacting and when attempting to use XCM +/// `Transact` in order to determine the dispatch Origin. +pub type LocationToAccountId = ( + // The parent (Relay-chain) origin converts to the default `AccountId`. + ParentIsDefault, + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +/// Means for transacting assets on this chain. +pub type LocalAssetTransactor = CurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We don't track any teleports. + (), +>; + +/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, +/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can +/// biases the kind of local `Origin` it will become. +pub type XcmOriginToTransactDispatchOrigin = ( + // Sovereign account converter; this attempts to derive an `AccountId` from the origin location + // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for + // foreign chains who want to have a local sovereign account on this chain which they control. + SovereignSignedViaLocation, + // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when + // recognised. + RelayChainAsNative, + // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when + // recognised. + SiblingParachainAsNative, + // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a + // transaction from the Root origin. + ParentAsSuperuser, + // Native signed account converter; this just converts an `AccountId32` origin into a normal + // `Origin::Signed` origin of the same 32-byte value. + SignedAccountId32AsNative, + // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. + XcmPassthrough, +); + +parameter_types! { + // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate. + pub UnitWeightCost: Weight = 1_000_000; + // One ROC buys 1 second of weight. + pub const WeightPrice: (MultiLocation, u128) = (X1(Parent), BNCS); +} + +match_type! { + pub type ParentOrParentsUnitPlurality: impl Contains = { + X1(Parent) | X2(Parent, Plurality { id: BodyId::Unit, .. }) + }; +} + +pub type Barrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom>, + // ^^^ Parent & its unit plurality gets free execution + AllowUnpaidExecutionFrom, + BifrostXcmTransactFilter>, +); + +pub type BifrostAssetTransactor = BifrostCurrencyAdapter< + Tokens, + BifrostAssetMatcher>, + AccountId, + LocationToAccountId, + CurrencyId, + BifrostCurrencyIdConvert, +>; + +pub struct XcmConfig; +impl Config for XcmConfig { + type AssetTransactor = BifrostAssetTransactor; + type Barrier = Barrier; + type Call = Call; + type IsReserve = BifrostFilteredAssets; + type IsTeleporter = BifrostFilteredAssets; + type LocationInverter = LocationInverter; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type ResponseHandler = (); + type Trader = UsingComponents, RelayLocation, AccountId, Balances, ()>; + type Weigher = FixedWeightBounds; + type XcmSender = XcmRouter; // Don't handle responses for now. +} + +/// No local origins on this chain are allowed to dispatch XCM sends/executions. +pub type LocalOriginToLocation = SignedToAccountId32; + +/// The means for routing XCM messages which are not for local execution into the right message +/// queues. +pub type XcmRouter = ( + // Two routers - use UMP to communicate with the relay chain: + cumulus_primitives_utility::ParentAsUmp, + // ..and XCMP to communicate with the sibling chains. + XcmpQueue, +); + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type SendXcmOrigin = EnsureXcmOrigin; + type Weigher = FixedWeightBounds; + type XcmExecuteFilter = All<(MultiLocation, Xcm)>; + type XcmExecutor = XcmExecutor; + type XcmReserveTransferFilter = All<(MultiLocation, Vec)>; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = All<(MultiLocation, Vec)>; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type ChannelInfo = ParachainSystem; + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type Event = Event; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; + type XcmExecutor = XcmExecutor; +} + +impl pallet_aura::Config for Runtime { + type AuthorityId = AuraId; +} + +impl pallet_grandpa::Config for Runtime { + type Event = Event; + type Call = Call; + + type KeyOwnerProofSystem = (); + + type KeyOwnerProof = + >::Proof; + + type KeyOwnerIdentification = >::IdentificationTuple; + + type HandleEquivocation = (); + + type WeightInfo = (); +} + +parameter_types! { + pub const PotId: PalletId = PalletId(*b"PotStake"); + pub const MaxCandidates: u32 = 1000; + pub const MinCandidates: u32 = 5; + pub const SessionLength: BlockNumber = 6 * HOURS; + pub const MaxInvulnerables: u32 = 100; +} + +// culumus runtime end + +// bifrost runtime start + +parameter_types! { + // 3 hours(1800 blocks) as an era + pub const VtokenMintDuration: BlockNumber = 3 * 60 * MINUTES; + pub const StakingPalletId: PalletId = PalletId(*b"staking "); +} +impl bifrost_vtoken_mint::Config for Runtime { + type Event = Event; + type MinterReward = MinterReward; + type MultiCurrency = Currencies; + type WeightInfo = bifrost_vtoken_mint::weights::BifrostWeight; +} + +orml_traits::parameter_type_with_key! { + pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance { + match currency_id { + &CurrencyId::Native(TokenSymbol::ASG) => 1 * CENTS, + _ => Zero::zero(), + } + }; +} + +impl orml_tokens::Config for Runtime { + type Amount = Amount; + type Balance = Balance; + type CurrencyId = CurrencyId; + type Event = Event; + type ExistentialDeposits = ExistentialDeposits; + type MaxLocks = MaxLocks; + type OnDust = (); + type WeightInfo = (); +} + +parameter_types! { + pub const AlternativeFeeCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); + pub const AltFeeCurrencyExchangeRate: (u32, u32) = (1, 100); +} + +impl bifrost_flexible_fee::Config for Runtime { + type Balance = Balance; + type Currency = Balances; + type DexOperator = ZenlinkProtocol; + // type FeeDealer = FlexibleFee; + type FeeDealer = FixedCurrencyFeeRate; + type Event = Event; + type MultiCurrency = Currencies; + type NativeCurrencyId = NativeCurrencyId; + type AlternativeFeeCurrencyId = AlternativeFeeCurrencyId; + type AltFeeCurrencyExchangeRate = AltFeeCurrencyExchangeRate; + type OnUnbalanced = (); + type WeightInfo = (); +} + +parameter_types! { + pub const HalvingCycle: u32 = 60; + pub const RewardWindow: u32 = 10; + pub const MaximumExtendedPeriod: u32 = 20; +} + +impl bifrost_minter_reward::Config for Runtime { + type DexOperator = ZenlinkProtocol; + type Event = Event; + type HalvingCycle = HalvingCycle; + type MaximumExtendedPeriod = MaximumExtendedPeriod; + type MultiCurrency = Currencies; + type RewardWindow = RewardWindow; + type ShareWeight = Balance; + type StableCurrencyId = StableCurrencyId; +} + +parameter_types! { + pub const SubmissionDeposit: Balance = 100 * DOLLARS; + pub const MinContribution: Balance = 1 * DOLLARS; + pub const BifrostCrowdloanId: PalletId = PalletId(*b"bf/salp#"); + pub const RemoveKeysLimit: u32 = 500; + pub const VSBondValidPeriod: BlockNumber = 30 * DAYS; + pub const ReleaseCycle: BlockNumber = 1 * DAYS; + pub const LeasePeriod: BlockNumber = KUSAMA_LEASE_PERIOD; + pub const ReleaseRatio: Percent = Percent::from_percent(50); + pub const SlotLength: BlockNumber = 8u32 as BlockNumber; + pub const XcmTransferOrigin: TransferOriginType = TransferOriginType::FromRelayChain; + pub XcmWeight: XcmBaseWeight = XCM_WEIGHT.into(); +} + +impl bifrost_salp::Config for Runtime { + type BancorPool = Bancor; + type BifrostXcmExecutor = BifrostXcmAdaptor; + type DepositToken = NativeCurrencyId; + type Event = Event; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type LeasePeriod = LeasePeriod; + type MinContribution = MinContribution; + type MultiCurrency = Currencies; + type PalletId = BifrostCrowdloanId; + type RelayChainToken = RelayCurrencyId; + type ReleaseCycle = ReleaseCycle; + type ReleaseRatio = ReleaseRatio; + type RemoveKeysLimit = RemoveKeysLimit; + type SlotLength = SlotLength; + type SubmissionDeposit = SubmissionDeposit; + type VSBondValidPeriod = VSBondValidPeriod; + type XcmTransferOrigin = XcmTransferOrigin; + type WeightInfo = weights::pallet_salp::WeightInfo; // bifrost_salp::TestWeightInfo; +} + +parameter_types! { + pub const InterventionPercentage: Percent = Percent::from_percent(75); + pub const DailyReleasePercentage: Percent = Percent::from_percent(5); +} + +impl bifrost_bancor::Config for Runtime { + type Event = Event; + type InterventionPercentage = InterventionPercentage; + type DailyReleasePercentage = DailyReleasePercentage; + type MultiCurrency = Currencies; + type WeightInfo = bifrost_bancor::weights::BifrostWeight; +} + +parameter_types! { + pub const MaximumOrderInTrade: u32 = 5; + pub const MinimumSupply: Balance = 0; +} + +impl bifrost_vsbond_auction::Config for Runtime { + type Event = Event; + type InvoicingCurrency = RelayCurrencyId; + type MaximumOrderInTrade = MaximumOrderInTrade; + type MinimumSupply = MinimumSupply; + type MultiCurrency = Currencies; +} + +// bifrost runtime end + +// zenlink runtime start +parameter_types! { + pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink"); + pub SelfParaId: u32 = ParachainInfo::parachain_id().into(); + pub const GetExchangeFee: (u32, u32) = (3, 1000); // 0.3% + + // xcm + pub const AnyNetwork: NetworkId = NetworkId::Any; + pub ZenlinkRegistedParaChains: Vec<(MultiLocation, u128)> = vec![ + // Bifrost local and live, 0.01 BNC + (make_x2_location(2001), 10_000_000_000), + // Phala local and live, 1 PHA + (make_x2_location(2004), 1_000_000_000_000), + // Plasm local and live, 0.0000000000001 SDN + (make_x2_location(2007), 1_000_000), + // Sherpax live, 0 KSX + (make_x2_location(2013), 0), + + // Zenlink local 1 for test + (make_x2_location(200), 1_000_000), + // Zenlink local 2 for test + (make_x2_location(300), 1_000_000), + ]; +} + +impl zenlink_protocol::Config for Runtime { + type Conversion = ZenlinkLocationToAccountId; + type Event = Event; + type GetExchangeFee = GetExchangeFee; + type MultiAssetsHandler = MultiAssets; + type PalletId = ZenlinkPalletId; + type SelfParaId = SelfParaId; + type TargetChains = ZenlinkRegistedParaChains; + type XcmExecutor = XcmExecutor; +} + +type MultiAssets = ZenlinkMultiAssets>; + +pub type ZenlinkLocationToAccountId = ( + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +// Below is the implementation of tokens manipulation functions other than native token. +pub struct LocalAssetAdaptor(PhantomData); + +impl LocalAssetHandler for LocalAssetAdaptor +where + Local: MultiCurrency, +{ + fn local_balance_of(asset_id: AssetId, who: &AccountId) -> AssetBalance { + let currency_id: CurrencyId = asset_id.try_into().unwrap_or_default(); + Local::free_balance(currency_id, &who).saturated_into() + } + + fn local_total_supply(asset_id: AssetId) -> AssetBalance { + let currency_id: CurrencyId = asset_id.try_into().unwrap_or_default(); + Local::total_issuance(currency_id).saturated_into() + } + + fn local_is_exists(asset_id: AssetId) -> bool { + let currency_id: Result = asset_id.try_into(); + match currency_id { + Ok(_) => true, + Err(_) => false, + } + } + + fn local_transfer( + asset_id: AssetId, + origin: &AccountId, + target: &AccountId, + amount: AssetBalance, + ) -> DispatchResult { + let currency_id: CurrencyId = asset_id.try_into().unwrap_or_default(); + Local::transfer(currency_id, &origin, &target, amount.unique_saturated_into())?; + + Ok(()) + } + + fn local_deposit( + asset_id: AssetId, + origin: &AccountId, + amount: AssetBalance, + ) -> Result { + let currency_id: CurrencyId = asset_id.try_into().unwrap_or_default(); + Local::deposit(currency_id, &origin, amount.unique_saturated_into())?; + return Ok(amount); + } + + fn local_withdraw( + asset_id: AssetId, + origin: &AccountId, + amount: AssetBalance, + ) -> Result { + let currency_id: CurrencyId = asset_id.try_into().unwrap_or_default(); + Local::withdraw(currency_id, &origin, amount.unique_saturated_into())?; + + Ok(amount) + } +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 100 * CENTS; +} + +impl pallet_vesting::Config for Runtime { + type BlockNumberToBalance = ConvertInto; + type Currency = Balances; + type Event = Event; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = weights::pallet_vesting::WeightInfo; +} + +// zenlink runtime end + +// orml runtime start + +pub type BifrostToken = BasicCurrencyAdapter; + +impl orml_currencies::Config for Runtime { + type Event = Event; + type GetNativeCurrencyId = NativeCurrencyId; + type MultiCurrency = Tokens; + type NativeCurrency = BifrostToken; + type WeightInfo = (); +} + +// orml runtime end + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = generic::Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + // Basic stuff + System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 1, + Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 2, + Sudo: pallet_sudo::{Pallet, Call, Config, Storage, Event} = 3, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 4, + ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event} = 5, + ParachainInfo: parachain_info::{Pallet, Storage, Config} = 6, + + // Monetary stuff + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 11, + + Aura: pallet_aura::{Pallet, Storage, Config} = 23, + Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event} = 25, + + // Governance stuff + Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event} = 30, + Council: pallet_collective::::{Pallet, Call, Storage, Origin, Event, Config} = 31, + TechnicalCommittee: pallet_collective::::{Pallet, Call, Storage, Origin, Event, Config} = 32, + Elections: pallet_elections_phragmen::{Pallet, Call, Storage, Event, Config} = 33, + CouncilMembership: pallet_membership::::{Pallet, Call, Storage, Event, Config} = 34, + TechnicalMembership: pallet_membership::::{Pallet, Call, Storage, Event, Config} = 35, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 36, + Bounties: pallet_bounties::{Pallet, Call, Storage, Event} = 37, + Tips: pallet_tips::{Pallet, Call, Storage, Event} = 38, + + // XCM helpers. + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 40, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin} = 41, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 42, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 43, + + // utilities + Utility: pallet_utility::{Pallet, Call, Event} = 50, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 51, + Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 52, + Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 53, + + // Vesting. Usable initially, but removed once all vesting is finished. + Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 60, + + // Third party modules + ZenlinkProtocol: zenlink_protocol::{Pallet, Call, Storage, Event} = 61, + // XTokens: orml_xtokens::{Pallet, Storage, Call, Event} = 70, + Tokens: orml_tokens::{Pallet, Call, Storage, Event, Config} = 71, + Currencies: orml_currencies::{Pallet, Call, Event} = 72, + + // Bifrost modules + VtokenMint: bifrost_vtoken_mint::{Pallet, Call, Storage, Event, Config} = 101, + MinterReward: bifrost_minter_reward::{Pallet, Storage, Event, Config} = 102, + FlexibleFee: bifrost_flexible_fee::{Pallet, Call, Storage, Event} = 104, + Salp: bifrost_salp::{Pallet, Call, Storage, Event} = 105, + Bancor: bifrost_bancor::{Pallet, Call, Storage, Event, Config} = 106, + VSBondAuction: bifrost_vsbond_auction::{Pallet, Call, Storage, Event} = 107, + } +} + +/// The type for looking up accounts. We don't expect more than 4 billion of them. +pub type AccountIndex = u32; +/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. +pub type Signature = sp_runtime::MultiSignature; +/// Some way of identifying an account on the chain. We intentionally make it equivalent +/// to the public key of our transaction signing scheme. +pub type AccountId = <::Signer as sp_runtime::traits::IdentifyAccount>::AccountId; +/// Balance of an account. +pub type Balance = u128; +/// Index of a transaction in the chain. +pub type Index = u32; +/// A hash of some data used by the chain. +pub type Hash = sp_core::H256; +/// An index to a block. +pub type BlockNumber = u32; +/// The address format for describing accounts. +pub type Address = sp_runtime::MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// BlockId type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckSpecVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = generic::CheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPallets, +>; + +impl_runtime_apis! { + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic( + extrinsic: ::Extrinsic, + ) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents(block: Block, data: sp_inherents::InherentData) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info(uxt: ::Extrinsic, len: u32) -> pallet_transaction_payment::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + + fn query_fee_details(uxt: ::Extrinsic, len: u32) -> pallet_transaction_payment_rpc_runtime_api::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_session::SessionKeys for Runtime { + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> GrandpaAuthorityList { + Grandpa::grandpa_authorities() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + NumberFor, + >, + _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + _authority_id: GrandpaId, + ) -> Option { + // NOTE: this is the only implementation possible since we've + // defined our key owner proof type as a bottom type (i.e. a type + // with no values). + None + } + } + + impl cumulus_primitives_core::CollectCollationInfo for Runtime { + fn collect_collation_info() -> cumulus_primitives_core::CollationInfo { + ParachainSystem::collect_collation_info() + } + } + + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + } + + fn authorities() -> Vec { + Aura::authorities() + } + } + + impl bifrost_flexible_fee_rpc_runtime_api::FlexibleFeeRuntimeApi for Runtime { + fn get_fee_token_and_amount(who: AccountId, fee: Balance) -> (CurrencyId, Balance) { + let rs = FlexibleFee::cal_fee_token_and_amount(&who, fee); + match rs { + Ok(val) => val, + _ => (CurrencyId::Native(TokenSymbol::ASG), Zero::zero()), + } + } + } + + impl bifrost_bancor_runtime_api::BancorRuntimeApi for Runtime { + fn get_bancor_token_amount_out(token_id: CurrencyId, vstoken_amount: Balance) -> Balance { + let rs = Bancor::calculate_price_for_token(token_id, vstoken_amount); + match rs { + Ok(val) => val, + _ => Zero::zero(), + } + } + + fn get_bancor_vstoken_amount_out(token_id: CurrencyId, token_amount: Balance) -> Balance { + let rs = Bancor::calculate_price_for_vstoken(token_id, token_amount); + match rs { + Ok(val) => val, + _ => Zero::zero(), + } + } + + fn get_instant_vstoken_price(currency_id: CurrencyId) -> (Balance, Balance) { + let rs = Bancor::get_instant_vstoken_price(currency_id); + match rs { + Ok((nominator, denominator)) => (nominator, denominator), + _ => (Zero::zero(), Zero::zero()), + } + } + + fn get_instant_token_price(currency_id: CurrencyId) -> (Balance, Balance) { + let rs = Bancor::get_instant_token_price(currency_id); + match rs { + Ok((nominator, denominator)) => (nominator, denominator), + _ => (Zero::zero(), Zero::zero()), + } + } + } + + // zenlink runtime outer apis + impl zenlink_protocol_runtime_api::ZenlinkProtocolApi for Runtime { + fn get_assets() -> Vec { + ZenlinkProtocol::get_assets() + } + + fn get_balance( + asset_id: AssetId, + owner: AccountId + ) -> AssetBalance { + ::MultiAssetsHandler::balance_of(asset_id, &owner) + } + + fn get_sovereigns_info( + asset_id: AssetId + ) -> Vec<(u32, AccountId, AssetBalance)> { + ZenlinkProtocol::get_sovereigns_info(&asset_id) + } + + fn get_all_pairs() -> Vec> { + ZenlinkProtocol::get_all_pairs() + } + + fn get_owner_pairs( + owner: AccountId + ) -> Vec> { + ZenlinkProtocol::get_owner_pairs(&owner) + } + + fn get_pair_by_asset_id( + asset_0: AssetId, + asset_1: AssetId + ) -> Option> { + ZenlinkProtocol::get_pair_by_asset_id(asset_0, asset_1) + } + + fn get_amount_in_price( + supply: AssetBalance, + path: Vec + ) -> AssetBalance { + ZenlinkProtocol::desired_in_amount(supply, path) + } + + fn get_amount_out_price( + supply: AssetBalance, + path: Vec + ) -> AssetBalance { + ZenlinkProtocol::supply_out_amount(supply, path) + } + + fn get_estimate_lptoken( + token_0: AssetId, + token_1: AssetId, + amount_0_desired: AssetBalance, + amount_1_desired: AssetBalance, + amount_0_min: AssetBalance, + amount_1_min: AssetBalance, + ) -> AssetBalance{ + ZenlinkProtocol::get_estimate_lptoken( + token_0, + token_1, + amount_0_desired, + amount_1_desired, + amount_0_min, + amount_1_min + ) + } + } + + // benchmarks for asgard modules + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, RuntimeString> { + use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; + + let whitelist: Vec = vec![ + // Block Number + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), + // Total Issuance + hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), + // Execution Phase + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), + // Event Count + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), + // System Events + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), + // Caller 0 Account + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da946c154ffd9992e395af90b5b13cc6f295c77033fce8a9045824a6690bbf99c6db269502f0a8d1d2a008542d5690a0749").to_vec().into(), + // Treasury Account + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000").to_vec().into(), + ]; + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + add_benchmark!(params, batches, bifrost_salp, Salp); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } +} + +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + block: &Block, + relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + let relay_chain_slot = relay_state_proof + .read_slot() + .expect("Could not read the relay chain slot from the proof"); + + let inherent_data = + cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration( + relay_chain_slot, + sp_std::time::Duration::from_secs(6), + ) + .create_inherent_data() + .expect("Could not create the timestamp inherent data"); + + inherent_data.check_extrinsics(&block) + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, + CheckInherents = CheckInherents, +} diff --git a/runtime/dev/src/weights/mod.rs b/runtime/dev/src/weights/mod.rs new file mode 100644 index 0000000000..3cdec6fda5 --- /dev/null +++ b/runtime/dev/src/weights/mod.rs @@ -0,0 +1,24 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 + +//! A list of the different weight modules for our runtime. + +pub mod pallet_salp; +pub mod pallet_vesting; diff --git a/runtime/dev/src/weights/pallet_assets.rs b/runtime/dev/src/weights/pallet_assets.rs new file mode 100644 index 0000000000..82ec7cfe61 --- /dev/null +++ b/runtime/dev/src/weights/pallet_assets.rs @@ -0,0 +1,53 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +pub struct WeightInfo(PhantomData); +impl bifrost_assets::WeightInfo for WeightInfo { + fn create() -> Weight { + (65949000 as Weight) + //.saturating_add(T::DbWeight::get().reads(0 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn create_pair() -> Weight { + (65949000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn issue() -> Weight { + (46665000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn transfer() -> Weight { + (27086000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn destroy() -> Weight { + (39_603_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn redeem() -> Weight { + (110_679_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } +} diff --git a/runtime/dev/src/weights/pallet_salp.rs b/runtime/dev/src/weights/pallet_salp.rs new file mode 100644 index 0000000000..5b82ba2d59 --- /dev/null +++ b/runtime/dev/src/weights/pallet_salp.rs @@ -0,0 +1,69 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! Autogenerated weights for bifrost_salp +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-07-11, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("asgard-dev"), DB CACHE: 128 + +// Executed Command: +// target/debug/bifrost +// benchmark +// --chain +// asgard-dev +// --steps=50 +// --repeat=20 +// --pallet=bifrost-salp +// --extrinsic +// * +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./HEADER-GPL3 +// --output=./runtime/asgard/src/weights/salp.rs + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for bifrost_salp. +pub struct WeightInfo(PhantomData); +impl bifrost_salp::WeightInfo for WeightInfo { + fn create() -> Weight { + (2_345_291_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + + fn contribute() -> Weight { + (1_251_633_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + + fn on_finalize(n: u32) -> Weight { + (290_825_000 as Weight) + // Standard Error: 5_000 + .saturating_add((399_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } +} diff --git a/runtime/dev/src/weights/pallet_vesting.rs b/runtime/dev/src/weights/pallet_vesting.rs new file mode 100644 index 0000000000..86dac90d23 --- /dev/null +++ b/runtime/dev/src/weights/pallet_vesting.rs @@ -0,0 +1,94 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . +//! Autogenerated weights for pallet_vesting +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-04-27, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_vesting +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for pallet_vesting. +pub struct WeightInfo(PhantomData); +impl pallet_vesting::WeightInfo for WeightInfo { + fn vest_locked(l: u32) -> Weight { + (40_504_000 as Weight) + // Standard Error: 20_000 + .saturating_add((261_000 as Weight).saturating_mul(l as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + + fn vest_unlocked(l: u32) -> Weight { + (44_880_000 as Weight) + // Standard Error: 2_000 + .saturating_add((138_000 as Weight).saturating_mul(l as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + + fn vest_other_locked(l: u32) -> Weight { + (39_872_000 as Weight) + // Standard Error: 20_000 + .saturating_add((265_000 as Weight).saturating_mul(l as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + + fn vest_other_unlocked(l: u32) -> Weight { + (44_683_000 as Weight) + // Standard Error: 1_000 + .saturating_add((137_000 as Weight).saturating_mul(l as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + + fn vested_transfer(l: u32) -> Weight { + (95_999_000 as Weight) + // Standard Error: 17_000 + .saturating_add((242_000 as Weight).saturating_mul(l as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + + fn force_vested_transfer(l: u32) -> Weight { + (95_418_000 as Weight) + // Standard Error: 17_000 + .saturating_add((242_000 as Weight).saturating_mul(l as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } +}