--- a/Cargo.lock +++ b/Cargo.lock @@ -5194,6 +5194,82 @@ checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] +name = "opal-runtime" +version = "0.1.0" +dependencies = [ + "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", + "derivative", + "fp-rpc", + "fp-self-contained", + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "hex-literal", + "orml-vesting", + "pallet-aura", + "pallet-balances", + "pallet-base-fee", + "pallet-common", + "pallet-ethereum", + "pallet-evm", + "pallet-evm-coder-substrate", + "pallet-evm-contract-helpers", + "pallet-evm-migration", + "pallet-evm-transaction-payment", + "pallet-fungible", + "pallet-inflation", + "pallet-nonfungible", + "pallet-randomness-collective-flip", + "pallet-refungible", + "pallet-sudo", + "pallet-template-transaction-payment", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-unique", + "pallet-unq-scheduler", + "pallet-xcm", + "parachain-info", + "parity-scale-codec", + "polkadot-parachain", + "scale-info", + "serde", + "smallvec", + "sp-api", + "sp-arithmetic", + "sp-block-builder", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-io", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder", + "unique-runtime-common", + "up-data-structs", + "up-evm-mapping", + "up-rpc", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] name = "opaque-debug" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -8260,6 +8336,82 @@ ] [[package]] +name = "quartz-runtime" +version = "0.1.0" +dependencies = [ + "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", + "derivative", + "fp-rpc", + "fp-self-contained", + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "hex-literal", + "orml-vesting", + "pallet-aura", + "pallet-balances", + "pallet-base-fee", + "pallet-common", + "pallet-ethereum", + "pallet-evm", + "pallet-evm-coder-substrate", + "pallet-evm-contract-helpers", + "pallet-evm-migration", + "pallet-evm-transaction-payment", + "pallet-fungible", + "pallet-inflation", + "pallet-nonfungible", + "pallet-randomness-collective-flip", + "pallet-refungible", + "pallet-sudo", + "pallet-template-transaction-payment", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-unique", + "pallet-unq-scheduler", + "pallet-xcm", + "parachain-info", + "parity-scale-codec", + "polkadot-parachain", + "scale-info", + "serde", + "smallvec", + "sp-api", + "sp-arithmetic", + "sp-block-builder", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-io", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder", + "unique-runtime-common", + "up-data-structs", + "up-evm-mapping", + "up-rpc", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -11787,8 +11939,10 @@ "jsonrpc-core", "jsonrpc-pubsub", "log", + "opal-runtime", "pallet-ethereum", "pallet-transaction-payment-rpc", + "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "parking_lot 0.11.2", "polkadot-cli", @@ -11796,6 +11950,7 @@ "polkadot-primitives", "polkadot-service", "polkadot-test-service", + "quartz-runtime", "sc-basic-authorship", "sc-chain-spec", "sc-cli", @@ -11834,7 +11989,9 @@ "substrate-prometheus-endpoint", "unique-rpc", "unique-runtime", + "unique-runtime-common", "up-data-structs", + "up-rpc", ] [[package]] @@ -11849,6 +12006,7 @@ "futures 0.3.21", "jsonrpc-core", "jsonrpc-pubsub", + "pallet-common", "pallet-ethereum", "pallet-transaction-payment-rpc", "pallet-transaction-payment-rpc-runtime-api", @@ -11864,6 +12022,7 @@ "sc-rpc-api", "sc-service", "sc-transaction-pool", + "serde", "sp-api", "sp-block-builder", "sp-blockchain", @@ -11878,7 +12037,7 @@ "substrate-frame-rpc-system", "tokio 0.2.25", "uc-rpc", - "unique-runtime", + "unique-runtime-common", "up-rpc", ] @@ -11949,6 +12108,7 @@ "sp-transaction-pool", "sp-version", "substrate-wasm-builder", + "unique-runtime-common", "up-data-structs", "up-evm-mapping", "up-rpc", @@ -11958,6 +12118,21 @@ ] [[package]] +name = "unique-runtime-common" +version = "0.1.0" +dependencies = [ + "fp-rpc", + "frame-support", + "frame-system", + "pallet-common", + "parity-scale-codec", + "scale-info", + "sp-consensus-aura", + "sp-core", + "sp-runtime", +] + +[[package]] name = "universal-hash" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ 'pallets/*', 'client/*', 'primitives/*', - 'runtime', + 'runtime/*', 'crates/*', ] [profile.release] --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ - [Unique Wallet and UI](https://uniqueapps.usetech.com/#/nft) - [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity) -Please see our [walk-thorugh instructions](doc/hackusama_walk_through.md) to try everything out! +Please see our [walk-through instructions](doc/hackusama_walk_through.md) to try everything out! ## Application Development @@ -158,7 +158,7 @@ ``` assetRegistry -> registerForeignAsset(location, metadata) location: - V0(X2(Parent, Parachain(PARA_ID))) + V0(X2(Parent, Parachain(PARA_ID))) metadata: name OPL symbol OPL @@ -170,19 +170,19 @@ ``` polkadotXcm -> reserveTransferAssets dest: - V0(X2(Parent, Parachain())) + V0(X2(Parent, Parachain())) beneficiary: X1(AccountId(Any, )) assets: V1(Concrete(0,Here), Fungible()) -feeAssetItem: - 0 +feeAssetItem: + 0 weightLimit: -``` +``` -The result will be displayed in ChainState -tokens -> accounts +The result will be displayed in ChainState +tokens -> accounts ### To send tokens from Karura to Opal: ``` @@ -197,7 +197,7 @@ dest: V1 ( - Parents:1, + Parents:1, X2(Parachain(), AccountId(Any, ) ) destWeight: --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -168,6 +168,9 @@ [dependencies.serde_json] version = '1.0.68' +[dependencies.sc-consensus-manual-seal] +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' ################################################################################ # Cumulus dependencies @@ -238,13 +241,32 @@ ################################################################################ # Local dependencies +[dependencies.unique-runtime-common] +default-features = false +path = "../../runtime/common" + [dependencies.unique-runtime] -path = '../../runtime' +path = '../../runtime/unique' +optional = true + +[dependencies.quartz-runtime] +path = '../../runtime/quartz' +optional = true + +[dependencies.opal-runtime] +path = '../../runtime/opal' [dependencies.up-data-structs] path = "../../primitives/data-structs" default-features = false +[dependencies.up-rpc] +path = "../../primitives/rpc" + +[dependencies.pallet-transaction-payment-rpc-runtime-api] +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + ################################################################################ # Package @@ -283,10 +305,10 @@ fp-rpc = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } -unique-rpc = { path = "../rpc" } +unique-rpc = { default-features = false, path = "../rpc" } [features] -default = [] +default = ["unique-runtime", "quartz-runtime"] runtime-benchmarks = [ 'unique-runtime/runtime-benchmarks', 'polkadot-service/runtime-benchmarks', --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -15,7 +15,6 @@ // along with Unique Network. If not, see . use cumulus_primitives_core::ParaId; -use unique_runtime::*; use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; use sc_service::ChainType; use sp_core::{sr25519, Pair, Public}; @@ -25,9 +24,69 @@ use serde::{Deserialize, Serialize}; use serde_json::map::Map; -/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. -pub type ChainSpec = sc_service::GenericChainSpec; +use unique_runtime_common::types::*; + +/// The `ChainSpec` parameterized for the unique runtime. +#[cfg(feature = "unique-runtime")] +pub type UniqueChainSpec = sc_service::GenericChainSpec; + +/// The `ChainSpec` parameterized for the quartz runtime. +#[cfg(feature = "quartz-runtime")] +pub type QuartzChainSpec = sc_service::GenericChainSpec; + +/// The `ChainSpec` parameterized for the opal runtime. +pub type OpalChainSpec = sc_service::GenericChainSpec; +pub enum RuntimeId { + Unique, + Quartz, + Opal, + Unknown(String), +} + +pub trait RuntimeIdentification { + fn runtime_id(&self) -> RuntimeId; +} + +impl RuntimeIdentification for Box { + fn runtime_id(&self) -> RuntimeId { + #[cfg(feature = "unique-runtime")] + if self.id().starts_with("unique") { + return RuntimeId::Unique; + } + + #[cfg(feature = "quartz-runtime")] + if self.id().starts_with("quartz") { + return RuntimeId::Quartz; + } + + if self.id().starts_with("opal") || self.id() == "dev" || self.id() == "local_testnet" { + return RuntimeId::Opal; + } + + RuntimeId::Unknown(self.id().into()) + } +} + +pub enum ServiceId { + Prod, + Dev, +} + +pub trait ServiceIdentification { + fn service_id(&self) -> ServiceId; +} + +impl ServiceIdentification for Box { + fn service_id(&self) -> ServiceId { + if self.id().ends_with("dev") { + ServiceId::Dev + } else { + ServiceId::Prod + } + } +} + /// Helper function to generate a crypto pair from seed pub fn get_from_seed(seed: &str) -> ::Public { TPublic::Pair::from_string(&format!("//{}", seed), None) @@ -62,13 +121,13 @@ AccountPublic::from(get_from_seed::(seed)).into_account() } -pub fn development_config() -> ChainSpec { +pub fn development_config() -> OpalChainSpec { let mut properties = Map::new(); properties.insert("tokenSymbol".into(), "OPL".into()); properties.insert("tokenDecimals".into(), 15.into()); properties.insert("ss58Format".into(), 42.into()); - ChainSpec::from_genesis( + OpalChainSpec::from_genesis( // Name "Development", // ID @@ -107,8 +166,8 @@ ) } -pub fn local_testnet_rococo_config() -> ChainSpec { - ChainSpec::from_genesis( +pub fn local_testnet_rococo_config() -> OpalChainSpec { + OpalChainSpec::from_genesis( // Name "Local Testnet", // ID @@ -157,68 +216,17 @@ ) } -pub fn local_testnet_westend_config() -> ChainSpec { - ChainSpec::from_genesis( - // Name - "Local Testnet", - // ID - "local_testnet", - ChainType::Local, - move || { - testnet_genesis( - // Sudo account - get_account_id_from_seed::("Alice"), - vec![ - get_from_seed::("Alice"), - get_from_seed::("Bob"), - get_from_seed::("Charlie"), - get_from_seed::("Dave"), - get_from_seed::("Eve"), - ], - // Pre-funded accounts - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Charlie"), - get_account_id_from_seed::("Dave"), - get_account_id_from_seed::("Eve"), - get_account_id_from_seed::("Ferdie"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - get_account_id_from_seed::("Charlie//stash"), - get_account_id_from_seed::("Dave//stash"), - get_account_id_from_seed::("Eve//stash"), - get_account_id_from_seed::("Ferdie//stash"), - ], - 1000.into(), - ) - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - None, - None, - // Properties - None, - // Extensions - Extensions { - relay_chain: "westend-local".into(), - para_id: 1000, - }, - ) -} - fn testnet_genesis( root_key: AccountId, initial_authorities: Vec, endowed_accounts: Vec, id: ParaId, -) -> GenesisConfig { +) -> opal_runtime::GenesisConfig { + use opal_runtime::*; + GenesisConfig { - system: unique_runtime::SystemConfig { - code: unique_runtime::WASM_BINARY + system: SystemConfig { + code: WASM_BINARY .expect("WASM binary was not build, please build it!") .to_vec(), }, @@ -235,9 +243,9 @@ key: Some(root_key), }, vesting: VestingConfig { vesting: vec![] }, - parachain_info: unique_runtime::ParachainInfoConfig { parachain_id: id }, + parachain_info: ParachainInfoConfig { parachain_id: id }, parachain_system: Default::default(), - aura: unique_runtime::AuraConfig { + aura: AuraConfig { authorities: initial_authorities, }, aura_ext: Default::default(), --- a/node/cli/src/command.rs +++ b/node/cli/src/command.rs @@ -33,15 +33,23 @@ // limitations under the License. use crate::{ - chain_spec, + chain_spec::{self, RuntimeId, RuntimeIdentification, ServiceId, ServiceIdentification}, cli::{Cli, RelayChainCli, Subcommand}, - service::{new_partial, ParachainRuntimeExecutor}, + service::{new_partial, start_node, start_dev_node}, }; + +#[cfg(feature = "unique-runtime")] +use crate::service::UniqueRuntimeExecutor; + +#[cfg(feature = "quartz-runtime")] +use crate::service::QuartzRuntimeExecutor; + +use crate::service::OpalRuntimeExecutor; + use codec::Encode; use cumulus_primitives_core::ParaId; use cumulus_client_service::genesis::generate_genesis_block; use log::info; -use unique_runtime::Block; use polkadot_parachain::primitives::AccountIdConversion; use sc_cli::{ ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, @@ -54,22 +62,44 @@ use sp_runtime::traits::Block as BlockT; use std::{io::Write, net::SocketAddr}; +use unique_runtime_common::types::Block; + +macro_rules! no_runtime_err { + ($chain_name:expr) => { + format!( + "No runtime valid runtime was found for chain {}", + $chain_name + ) + }; +} + fn load_spec(id: &str) -> std::result::Result, String> { Ok(match id { - "westend-local" => Box::new(chain_spec::local_testnet_westend_config()), - "rococo-local" => Box::new(chain_spec::local_testnet_rococo_config()), "dev" => Box::new(chain_spec::development_config()), "" | "local" => Box::new(chain_spec::local_testnet_rococo_config()), - path => Box::new(chain_spec::ChainSpec::from_json_file( - std::path::PathBuf::from(path), - )?), + path => { + let path = std::path::PathBuf::from(path); + let chain_spec = Box::new(chain_spec::OpalChainSpec::from_json_file(path.clone())?) + as Box; + + match chain_spec.runtime_id() { + #[cfg(feature = "unique-runtime")] + RuntimeId::Unique => Box::new(chain_spec::UniqueChainSpec::from_json_file(path)?), + + #[cfg(feature = "quartz-runtime")] + RuntimeId::Quartz => Box::new(chain_spec::QuartzChainSpec::from_json_file(path)?), + + RuntimeId::Opal => chain_spec, + RuntimeId::Unknown(chain) => return Err(no_runtime_err!(chain)), + } + } }) } impl SubstrateCli for Cli { // TODO use args fn impl_name() -> String { - "Opal Node".into() + "Unique Node".into() } fn impl_version() -> String { @@ -78,7 +108,7 @@ // TODO use args fn description() -> String { format!( - "Opal Node\n\nThe command-line arguments provided first will be \ + "Unique Node\n\nThe command-line arguments provided first will be \ passed to the parachain node, while the arguments provided after -- will be passed \ to the relaychain node.\n\n\ {} [parachain-args] -- [relaychain-args]", @@ -103,15 +133,24 @@ load_spec(id) } - fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { - &unique_runtime::VERSION + fn native_runtime_version(chain_spec: &Box) -> &'static RuntimeVersion { + match chain_spec.runtime_id() { + #[cfg(feature = "unique-runtime")] + RuntimeId::Unique => &unique_runtime::VERSION, + + #[cfg(feature = "quartz-runtime")] + RuntimeId::Quartz => &quartz_runtime::VERSION, + + RuntimeId::Opal => &opal_runtime::VERSION, + RuntimeId::Unknown(chain) => panic!("{}", no_runtime_err!(chain)), + } } } impl SubstrateCli for RelayChainCli { // TODO use args fn impl_name() -> String { - "Opal Node".into() + "Unique Node".into() } fn impl_version() -> String { @@ -119,7 +158,7 @@ } // TODO use args fn description() -> String { - "Opal Node\n\nThe command-line arguments provided first will be \ + "Unique Node\n\nThe command-line arguments provided first will be \ passed to the parachain node, while the arguments provided after -- will be passed \ to the relaychain node.\n\n\ parachain-collator [parachain-args] -- [relaychain-args]" @@ -157,22 +196,81 @@ .ok_or_else(|| "Could not find wasm file in genesis state!".into()) } -macro_rules! construct_async_run { - (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ - let runner = $cli.create_runner($cmd)?; - runner.async_run(|$config| { +macro_rules! async_run_with_runtime { + ( + $runtime_api:path, $executor:path, + $runner:ident, $components:ident, $cli:ident, $cmd:ident, $config:ident, + $( $code:tt )* + ) => { + $runner.async_run(|$config| { let $components = new_partial::< - _ + $runtime_api, $executor, _ >( &$config, crate::service::parachain_build_import_queue, )?; let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) }) + }; +} + +macro_rules! construct_async_run { + (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ + let runner = $cli.create_runner($cmd)?; + + match runner.config().chain_spec.runtime_id() { + #[cfg(feature = "unique-runtime")] + RuntimeId::Unique => async_run_with_runtime!( + unique_runtime::RuntimeApi, UniqueRuntimeExecutor, + runner, $components, $cli, $cmd, $config, $( $code )* + ), + + #[cfg(feature = "quartz-runtime")] + RuntimeId::Quartz => async_run_with_runtime!( + quartz_runtime::RuntimeApi, QuartzRuntimeExecutor, + runner, $components, $cli, $cmd, $config, $( $code )* + ), + + RuntimeId::Opal => async_run_with_runtime!( + opal_runtime::RuntimeApi, OpalRuntimeExecutor, + runner, $components, $cli, $cmd, $config, $( $code )* + ), + + RuntimeId::Unknown(chain) => Err(no_runtime_err!(chain).into()) + } }} } +macro_rules! start_node_using_chain_runtime { + ($start_node_fn:ident($config:expr $(, $($args:expr),+)?) $($code:tt)*) => { + match $config.chain_spec.runtime_id() { + #[cfg(feature = "unique-runtime")] + RuntimeId::Unique => $start_node_fn::< + unique_runtime::Runtime, + unique_runtime::RuntimeApi, + UniqueRuntimeExecutor, + >($config $(, $($args),+)?) $($code)*, + + #[cfg(feature = "quartz-runtime")] + RuntimeId::Quartz => $start_node_fn::< + quartz_runtime::Runtime, + quartz_runtime::RuntimeApi, + QuartzRuntimeExecutor, + >($config $(, $($args),+)?) $($code)*, + + RuntimeId::Opal => $start_node_fn::< + opal_runtime::Runtime, + opal_runtime::RuntimeApi, + OpalRuntimeExecutor, + >($config $(, $($args),+)?) $($code)*, + + RuntimeId::Unknown(chain) => Err(no_runtime_err!(chain).into()), + } + }; +} + /// Parse command line arguments into service configuration. pub fn run() -> Result<()> { let cli = Cli::from_args(); @@ -273,8 +371,16 @@ Some(Subcommand::Benchmark(cmd)) => { if cfg!(feature = "runtime-benchmarks") { let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| match config.chain_spec.runtime_id() { + #[cfg(feature = "unique-runtime")] + RuntimeId::Unique => cmd.run::(config), + + #[cfg(feature = "quartz-runtime")] + RuntimeId::Quartz => cmd.run::(config), - runner.sync_run(|config| cmd.run::(config)) + RuntimeId::Opal => cmd.run::(config), + RuntimeId::Unknown(chain) => Err(no_runtime_err!(chain).into()), + }) } else { Err("Benchmarking wasn't enabled when building the node. \ You can enable it with `--features runtime-benchmarks`." @@ -285,7 +391,22 @@ let runner = cli.create_runner(&cli.run.normalize())?; runner.run_node_until_exit(|config| async move { - let para_id = chain_spec::Extensions::try_get(&*config.chain_spec) + let extensions = chain_spec::Extensions::try_get(&*config.chain_spec); + + let service_id = config.chain_spec.service_id(); + let relay_chain_id = extensions.map(|e| e.relay_chain.clone()); + let is_dev_service = matches![service_id, ServiceId::Dev] + || relay_chain_id == Some("dev-service".into()); + + if is_dev_service { + info!("Running Dev service"); + + return start_node_using_chain_runtime! { + start_dev_node(config).map_err(Into::into) + }; + }; + + let para_id = extensions .map(|e| e.para_id) .ok_or("Could not find parachain ID in chain-spec.")?; @@ -296,10 +417,12 @@ .chain(cli.relaychain_args.iter()), ); - let id = ParaId::from(para_id); + let para_id = ParaId::from(para_id); let parachain_account = - AccountIdConversion::::into_account(&id); + AccountIdConversion::::into_account( + ¶_id, + ); let state_version = RelayChainCli::native_runtime_version(&config.chain_spec).state_version(); @@ -315,7 +438,7 @@ ) .map_err(|err| format!("Relay chain argument error: {}", err))?; - info!("Parachain id: {:?}", id); + info!("Parachain id: {:?}", para_id); info!("Parachain Account: {}", parachain_account); info!("Parachain genesis state: {}", genesis_state); info!("Parachain genesis hash: {}", genesis_hash); @@ -328,10 +451,12 @@ } ); - crate::service::start_node(config, polkadot_config, id) - .await - .map(|r| r.0) - .map_err(Into::into) + start_node_using_chain_runtime! { + start_node(config, polkadot_config, para_id) + .await + .map(|r| r.0) + .map_err(Into::into) + } }) } } --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -25,9 +25,9 @@ use futures::StreamExt; use unique_rpc::overrides_handle; -// Local Runtime Types -use unique_runtime::RuntimeApi; +use serde::{Serialize, Deserialize}; + // Cumulus Imports use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion}; use cumulus_client_consensus_common::ParachainConsensus; @@ -56,16 +56,15 @@ use fc_rpc_core::types::FilterPool; use fc_mapping_sync::{MappingSyncWorker, SyncStrategy}; -// Runtime type overrides -type BlockNumber = u32; -type Header = sp_runtime::generic::Header; -pub type Block = sp_runtime::generic::Block; -type Hash = sp_core::H256; +use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block}; /// Native executor instance. -pub struct ParachainRuntimeExecutor; +pub struct UniqueRuntimeExecutor; +pub struct QuartzRuntimeExecutor; +pub struct OpalRuntimeExecutor; -impl NativeExecutionDispatch for ParachainRuntimeExecutor { +#[cfg(feature = "unique-runtime")] +impl NativeExecutionDispatch for UniqueRuntimeExecutor { type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; fn dispatch(method: &str, data: &[u8]) -> Option> { @@ -77,6 +76,31 @@ } } +#[cfg(feature = "quartz-runtime")] +impl NativeExecutionDispatch for QuartzRuntimeExecutor { + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + + fn dispatch(method: &str, data: &[u8]) -> Option> { + quartz_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + quartz_runtime::native_version() + } +} + +impl NativeExecutionDispatch for OpalRuntimeExecutor { + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + + fn dispatch(method: &str, data: &[u8]) -> Option> { + opal_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + opal_runtime::native_version() + } +} + pub fn open_frontier_backend(config: &Configuration) -> Result>, String> { let config_dir = config .base_path @@ -97,9 +121,7 @@ )?)) } -type ExecutorDispatch = ParachainRuntimeExecutor; - -type FullClient = +type FullClient = sc_service::TFullClient>; type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; @@ -109,16 +131,16 @@ /// Use this macro if you don't actually need the full service, but just the builder in order to /// be able to perform chain operations. #[allow(clippy::type_complexity)] -pub fn new_partial( +pub fn new_partial( config: &Configuration, build_import_queue: BIQ, ) -> Result< PartialComponents< - FullClient, + FullClient, FullBackend, FullSelectChain, - sc_consensus::DefaultImportQueue, - sc_transaction_pool::FullPool, + sc_consensus::DefaultImportQueue>, + sc_transaction_pool::FullPool>, ( Option, Option, @@ -131,13 +153,21 @@ > where sc_client_api::StateBackendFor: sp_api::StateBackend, + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue, ExecutorDispatch: NativeExecutionDispatch + 'static, BIQ: FnOnce( - Arc, + Arc>, &Configuration, Option, &TaskManager, - ) -> Result, sc_service::Error>, + ) -> Result< + sc_consensus::DefaultImportQueue>, + sc_service::Error, + >, { let _telemetry = config .telemetry_endpoints @@ -231,29 +261,50 @@ /// /// This is the actual implementation that is abstract over the executor and the runtime api. #[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node_impl( +async fn start_node_impl( parachain_config: Configuration, polkadot_config: Configuration, id: ParaId, build_import_queue: BIQ, build_consensus: BIC, -) -> sc_service::error::Result<(TaskManager, Arc)> +) -> sc_service::error::Result<(TaskManager, Arc>)> where sc_client_api::StateBackendFor: sp_api::StateBackend, + Runtime: RuntimeInstance + Send + Sync + 'static, + ::CrossAccountId: Serialize, + for<'de> ::CrossAccountId: Deserialize<'de>, + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + fp_rpc::EthereumRuntimeRPCApi + + sp_session::SessionKeys + + sp_block_builder::BlockBuilder + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + sp_api::ApiExt> + + up_rpc::UniqueApi + + substrate_frame_rpc_system::AccountNonceApi + + sp_api::Metadata + + sp_offchain::OffchainWorkerApi + + cumulus_primitives_core::CollectCollationInfo, ExecutorDispatch: NativeExecutionDispatch + 'static, BIQ: FnOnce( - Arc, + Arc>, &Configuration, Option, &TaskManager, - ) -> Result, sc_service::Error>, + ) -> Result< + sc_consensus::DefaultImportQueue>, + sc_service::Error, + >, BIC: FnOnce( - Arc, + Arc>, Option<&Registry>, Option, &TaskManager, Arc, - Arc>, + Arc>>, Arc>, SyncCryptoStorePtr, bool, @@ -265,7 +316,8 @@ let parachain_config = prepare_node_config(parachain_config); - let params = new_partial::(¶chain_config, build_import_queue)?; + let params = + new_partial::(¶chain_config, build_import_queue)?; let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) = params.other; @@ -311,7 +363,7 @@ let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new( task_manager.spawn_handle(), - overrides_handle(client.clone()), + overrides_handle::<_, _, Runtime>(client.clone()), 50, 50, )); @@ -337,10 +389,12 @@ fee_history_limit: 2048, }; - Ok(unique_rpc::create_full::<_, _, _, _, RuntimeApi, _>( - full_deps, - subscription_executor.clone(), - )) + Ok( + unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>( + full_deps, + subscription_executor.clone(), + ), + ) }); task_manager.spawn_essential_handle().spawn( @@ -427,12 +481,26 @@ } /// Build the import queue for the the parachain runtime. -pub fn parachain_build_import_queue( - client: Arc, +pub fn parachain_build_import_queue( + client: Arc>, config: &Configuration, telemetry: Option, task_manager: &TaskManager, -) -> Result, sc_service::Error> { +) -> Result< + sc_consensus::DefaultImportQueue>, + sc_service::Error, +> +where + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_block_builder::BlockBuilder + + sp_consensus_aura::AuraApi + + sp_api::ApiExt>, + ExecutorDispatch: NativeExecutionDispatch + 'static, +{ let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; cumulus_client_consensus_aura::import_queue::< @@ -466,12 +534,34 @@ } /// Start a normal parachain node. -pub async fn start_node( +pub async fn start_node( parachain_config: Configuration, polkadot_config: Configuration, id: ParaId, -) -> sc_service::error::Result<(TaskManager, Arc)> { - start_node_impl::<_, _>( +) -> sc_service::error::Result<(TaskManager, Arc>)> +where + Runtime: RuntimeInstance + Send + Sync + 'static, + ::CrossAccountId: Serialize, + for<'de> ::CrossAccountId: Deserialize<'de>, + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + fp_rpc::EthereumRuntimeRPCApi + + sp_session::SessionKeys + + sp_block_builder::BlockBuilder + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + sp_api::ApiExt> + + up_rpc::UniqueApi + + substrate_frame_rpc_system::AccountNonceApi + + sp_api::Metadata + + sp_offchain::OffchainWorkerApi + + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi, + ExecutorDispatch: NativeExecutionDispatch + 'static, +{ + start_node_impl::( parachain_config, polkadot_config, id, @@ -548,3 +638,250 @@ ) .await } + +fn dev_build_import_queue( + client: Arc>, + config: &Configuration, + _: Option, + task_manager: &TaskManager, +) -> Result< + sc_consensus::DefaultImportQueue>, + sc_service::Error, +> +where + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::ApiExt>, + ExecutorDispatch: NativeExecutionDispatch + 'static, +{ + Ok(sc_consensus_manual_seal::import_queue( + Box::new(client.clone()), + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + )) +} + +/// Builds a new development service. This service uses instant seal, and mocks +/// the parachain inherent +pub fn start_dev_node( + config: Configuration, +) -> sc_service::error::Result +where + Runtime: RuntimeInstance + Send + Sync + 'static, + ::CrossAccountId: Serialize, + for<'de> ::CrossAccountId: Deserialize<'de>, + RuntimeApi: sp_api::ConstructRuntimeApi> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + fp_rpc::EthereumRuntimeRPCApi + + sp_session::SessionKeys + + sp_block_builder::BlockBuilder + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + sp_api::ApiExt> + + up_rpc::UniqueApi + + substrate_frame_rpc_system::AccountNonceApi + + sp_api::Metadata + + sp_offchain::OffchainWorkerApi + + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi, + ExecutorDispatch: NativeExecutionDispatch + 'static, +{ + use futures::Stream; + use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams}; + use fc_consensus::FrontierBlockImport; + use sc_client_api::HeaderBackend; + + let sc_service::PartialComponents { + client, + backend, + mut task_manager, + import_queue, + keystore_container, + select_chain: maybe_select_chain, + transaction_pool, + other: + (telemetry, filter_pool, frontier_backend, _telemetry_worker_handle, fee_history_cache), + } = new_partial::( + &config, + dev_build_import_queue::, + )?; + + let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new( + task_manager.spawn_handle(), + overrides_handle::<_, _, Runtime>(client.clone()), + 50, + 50, + )); + + 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, + block_announce_validator_builder: None, + warp_sync: None, + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, + task_manager.spawn_handle(), + client.clone(), + network.clone(), + ); + } + + let prometheus_registry = config.prometheus_registry().cloned(); + let collator = config.role.is_authority(); + + let select_chain = maybe_select_chain.clone(); + + if collator { + let block_import = + FrontierBlockImport::new(client.clone(), client.clone(), frontier_backend.clone()); + + let env = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool.clone(), + prometheus_registry.as_ref(), + telemetry.as_ref().map(|x| x.handle()), + ); + + let commands_stream: Box> + Send + Sync + Unpin> = + Box::new( + // This bit cribbed from the implementation of instant seal. + transaction_pool + .pool() + .validated_pool() + .import_notification_stream() + .map(|_| EngineCommand::SealNewBlock { + create_empty: true, // was false in Moonbeam + finalize: false, + parent_hash: None, + sender: None, + }), + ); + + let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; + let client_set_aside_for_cidp = client.clone(); + + task_manager.spawn_essential_handle().spawn_blocking( + "authorship_task", + Some("block-authoring"), + run_manual_seal(ManualSealParams { + block_import, + env, + client: client.clone(), + pool: transaction_pool.clone(), + commands_stream, + select_chain: select_chain.clone(), + consensus_data_provider: None, + create_inherent_data_providers: move |block: Hash, ()| { + let current_para_block = client_set_aside_for_cidp + .number(block) + .expect("Header lookup should succeed") + .expect("Header passed in as parent should be present in backend."); + + let client_for_xcm = client_set_aside_for_cidp.clone(); + async move { + let time = sp_timestamp::InherentDataProvider::from_system_time(); + + let mocked_parachain = cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider { + current_para_block, + relay_offset: 1000, + relay_blocks_per_para_block: 2, + xcm_config: cumulus_primitives_parachain_inherent::MockXcmConfig::new( + &*client_for_xcm, + block, + Default::default(), + Default::default(), + ), + raw_downward_messages: vec![], + raw_horizontal_messages: vec![], + }; + + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( + *time, + slot_duration.slot_duration(), + ); + + Ok((time, slot, mocked_parachain)) + } + }, + }), + ); + } + + task_manager.spawn_essential_handle().spawn( + "frontier-mapping-sync-worker", + Some("block-authoring"), + MappingSyncWorker::new( + client.import_notification_stream(), + Duration::new(6, 0), + client.clone(), + backend.clone(), + frontier_backend.clone(), + SyncStrategy::Normal, + ) + .for_each(|()| futures::future::ready(())), + ); + + let subscription_executor = sc_rpc::SubscriptionTaskExecutor::new(task_manager.spawn_handle()); + let rpc_client = client.clone(); + let rpc_pool = transaction_pool.clone(); + let rpc_network = network.clone(); + let rpc_frontier_backend = frontier_backend.clone(); + let rpc_extensions_builder = Box::new(move |deny_unsafe, _| { + let full_deps = unique_rpc::FullDeps { + backend: rpc_frontier_backend.clone(), + deny_unsafe, + client: rpc_client.clone(), + pool: rpc_pool.clone(), + graph: rpc_pool.pool().clone(), + // TODO: Unhardcode + enable_dev_signer: false, + filter_pool: filter_pool.clone(), + network: rpc_network.clone(), + select_chain: select_chain.clone(), + is_authority: collator, + // TODO: Unhardcode + max_past_logs: 10000, + block_data_cache: block_data_cache.clone(), + fee_history_cache: fee_history_cache.clone(), + // TODO: Unhardcode + fee_history_limit: 2048, + }; + + Ok( + unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>( + full_deps, + subscription_executor.clone(), + ), + ) + }); + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + network, + client, + keystore: keystore_container.sync_keystore(), + task_manager: &mut task_manager, + transaction_pool, + rpc_extensions_builder, + backend, + system_rpc_tx, + config, + telemetry: None, + })?; + + network_starter.start_network(); + Ok(task_manager) +} --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -48,10 +48,16 @@ fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-common = { default-features = false, path = "../../pallets/common" } +unique-runtime-common = { default-features = false, path = "../../runtime/common" } pallet-unique = { path = "../../pallets/unique" } uc-rpc = { path = "../../client/rpc" } up-rpc = { path = "../../primitives/rpc" } -unique-runtime = { path = "../../runtime" } +[dependencies.serde] +features = ['derive'] +version = '1.0.130' + [features] +default = [] std = [] --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -15,7 +15,6 @@ // along with Unique Network. If not, see . use sp_runtime::traits::BlakeTwo256; -use unique_runtime::{Hash, AccountId, CrossAccountId, Index, opaque::Block, BlockNumber, Balance}; use fc_rpc::{ EthBlockDataCache, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override, StorageOverride, SchemaV2Override, SchemaV3Override, @@ -41,6 +40,10 @@ use sc_service::TransactionPool; use std::{collections::BTreeMap, marker::PhantomData, sync::Arc}; +use unique_runtime_common::types::{ + Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance, +}; + /// Public io handler for exporting into other modules pub type IoHandler = jsonrpc_core::IoHandler; @@ -90,29 +93,33 @@ pub block_data_cache: Arc>, } -struct AccountCodes { +struct AccountCodes { client: Arc, - _marker: PhantomData, + _blk_marker: PhantomData, + _runtime_marker: PhantomData, } -impl AccountCodes +impl AccountCodes where Block: sp_api::BlockT, C: ProvideRuntimeApi, + R: RuntimeInstance, { fn new(client: Arc) -> Self { Self { client, - _marker: PhantomData, + _blk_marker: PhantomData, + _runtime_marker: PhantomData, } } } -impl fc_rpc::AccountCodeProvider for AccountCodes +impl fc_rpc::AccountCodeProvider for AccountCodes where Block: sp_api::BlockT, C: ProvideRuntimeApi, - C::Api: up_rpc::UniqueApi, + C::Api: up_rpc::UniqueApi::CrossAccountId, AccountId>, + Runtime: RuntimeInstance, { fn code(&self, block: &sp_api::BlockId, account: sp_core::H160) -> Option> { use up_rpc::UniqueApi; @@ -124,22 +131,23 @@ } } -pub fn overrides_handle(client: Arc) -> Arc> +pub fn overrides_handle(client: Arc) -> Arc> where C: ProvideRuntimeApi + StorageProvider + AuxStore, C: HeaderBackend + HeaderMetadata, C: Send + Sync + 'static, C::Api: fp_rpc::EthereumRuntimeRPCApi, - C::Api: up_rpc::UniqueApi, + C::Api: up_rpc::UniqueApi::CrossAccountId, AccountId>, BE: Backend + 'static, BE::State: StateBackend, + R: RuntimeInstance + Send + Sync + 'static, { let mut overrides_map = BTreeMap::new(); overrides_map.insert( EthereumStorageSchema::V1, Box::new(SchemaV1Override::new_with_code_provider( client.clone(), - Arc::new(AccountCodes::::new(client.clone())), + Arc::new(AccountCodes::::new(client.clone())), )) as Box + Send + Sync>, ); overrides_map.insert( @@ -160,7 +168,7 @@ } /// Instantiate all Full RPC extensions. -pub fn create_full( +pub fn create_full( deps: FullDeps, subscription_task_executor: SubscriptionTaskExecutor, ) -> jsonrpc_core::IoHandler @@ -174,11 +182,14 @@ // C::Api: pallet_contracts_rpc::ContractsRuntimeApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: fp_rpc::EthereumRuntimeRPCApi, - C::Api: up_rpc::UniqueApi, + C::Api: up_rpc::UniqueApi::CrossAccountId, AccountId>, B: sc_client_api::Backend + Send + Sync + 'static, B::State: sc_client_api::backend::StateBackend>, P: TransactionPool + 'static, CA: ChainApi + 'static, + R: RuntimeInstance + Send + Sync + 'static, + ::CrossAccountId: serde::Serialize, + for<'de> ::CrossAccountId: serde::Deserialize<'de>, { use fc_rpc::{ EthApi, EthApiServer, EthDevSigner, EthFilterApi, EthFilterApiServer, EthPubSubApi, @@ -225,13 +236,13 @@ signers.push(Box::new(EthDevSigner::new()) as Box); } - let overrides = overrides_handle(client.clone()); + let overrides = overrides_handle::<_, _, R>(client.clone()); io.extend_with(EthApiServer::to_delegate(EthApi::new( client.clone(), pool.clone(), graph, - unique_runtime::TransactionConverter, + ::get_transaction_converter(), network.clone(), signers, overrides.clone(), --- a/runtime/Cargo.toml +++ /dev/null @@ -1,409 +0,0 @@ -################################################################################ -# Package - -[package] -authors = ['Unique Network '] -build = 'build.rs' -description = 'Unique Runtime' -edition = '2021' -homepage = 'https://unique.network' -license = 'GPLv3' -name = 'unique-runtime' -repository = 'https://github.com/UniqueNetwork/unique-chain' -version = '0.9.17' - -[package.metadata.docs.rs] -targets = ['x86_64-unknown-linux-gnu'] - -[features] -default = ['std'] -runtime-benchmarks = [ - 'hex-literal', - 'frame-benchmarking', - 'frame-support/runtime-benchmarks', - 'frame-system-benchmarking', - 'frame-system/runtime-benchmarks', - 'pallet-ethereum/runtime-benchmarks', - 'pallet-evm-migration/runtime-benchmarks', - 'pallet-evm-coder-substrate/runtime-benchmarks', - 'pallet-balances/runtime-benchmarks', - 'pallet-timestamp/runtime-benchmarks', - 'pallet-common/runtime-benchmarks', - 'pallet-fungible/runtime-benchmarks', - 'pallet-refungible/runtime-benchmarks', - 'pallet-nonfungible/runtime-benchmarks', - 'pallet-unique/runtime-benchmarks', - 'pallet-inflation/runtime-benchmarks', - 'pallet-xcm/runtime-benchmarks', - 'sp-runtime/runtime-benchmarks', - 'xcm-builder/runtime-benchmarks', -] -std = [ - 'codec/std', - 'cumulus-pallet-aura-ext/std', - 'cumulus-pallet-parachain-system/std', - 'cumulus-pallet-xcm/std', - 'cumulus-pallet-xcmp-queue/std', - 'cumulus-primitives-core/std', - 'cumulus-primitives-utility/std', - 'frame-executive/std', - 'frame-support/std', - 'frame-system/std', - 'frame-system-rpc-runtime-api/std', - 'pallet-aura/std', - 'pallet-balances/std', - # 'pallet-contracts/std', - # 'pallet-contracts-primitives/std', - # 'pallet-contracts-rpc-runtime-api/std', - # 'pallet-contract-helpers/std', - 'pallet-randomness-collective-flip/std', - 'pallet-sudo/std', - 'pallet-timestamp/std', - 'pallet-transaction-payment/std', - 'pallet-transaction-payment-rpc-runtime-api/std', - 'pallet-treasury/std', - # 'pallet-vesting/std', - 'pallet-evm/std', - 'pallet-evm-migration/std', - 'pallet-evm-contract-helpers/std', - 'pallet-evm-transaction-payment/std', - 'pallet-evm-coder-substrate/std', - 'pallet-ethereum/std', - 'pallet-base-fee/std', - 'fp-rpc/std', - 'up-rpc/std', - 'up-evm-mapping/std', - 'fp-self-contained/std', - 'parachain-info/std', - 'serde', - 'pallet-inflation/std', - 'pallet-common/std', - 'pallet-fungible/std', - 'pallet-refungible/std', - 'pallet-nonfungible/std', - 'pallet-unique/std', - 'pallet-unq-scheduler/std', - 'pallet-charge-transaction/std', - 'up-data-structs/std', - 'sp-api/std', - 'sp-block-builder/std', - "sp-consensus-aura/std", - 'sp-core/std', - 'sp-inherents/std', - 'sp-io/std', - 'sp-offchain/std', - 'sp-runtime/std', - 'sp-session/std', - 'sp-std/std', - 'sp-transaction-pool/std', - 'sp-version/std', - 'xcm/std', - 'xcm-builder/std', - 'xcm-executor/std', - - "orml-vesting/std", -] -limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] - -################################################################################ -# Substrate Dependencies - -[dependencies.codec] -default-features = false -features = ['derive'] -package = 'parity-scale-codec' -version = '2.3.0' - -[dependencies.frame-benchmarking] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -optional = true -branch = 'polkadot-v0.9.17' - -[dependencies.frame-executive] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.frame-support] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.frame-system] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.frame-system-benchmarking] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -optional = true -branch = 'polkadot-v0.9.17' - -[dependencies.frame-system-rpc-runtime-api] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.hex-literal] -optional = true -version = '0.3.3' - -[dependencies.serde] -default-features = false -features = ['derive'] -optional = true -version = '1.0.130' - -[dependencies.pallet-aura] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.pallet-balances] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -# Contracts specific packages -# [dependencies.pallet-contracts] -# git = 'https://github.com/paritytech/substrate.git' -# default-features = false -# branch = 'polkadot-v0.9.17' -# version = '4.0.0-dev' - -# [dependencies.pallet-contracts-primitives] -# git = 'https://github.com/paritytech/substrate.git' -# default-features = false -# branch = 'polkadot-v0.9.17' -# version = '4.0.0-dev' - -# [dependencies.pallet-contracts-rpc-runtime-api] -# git = 'https://github.com/paritytech/substrate.git' -# default-features = false -# branch = 'polkadot-v0.9.17' -# version = '4.0.0-dev' - -[dependencies.pallet-randomness-collective-flip] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.pallet-sudo] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.pallet-timestamp] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.pallet-transaction-payment] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.pallet-transaction-payment-rpc-runtime-api] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.pallet-treasury] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -# [dependencies.pallet-vesting] -# default-features = false -# git = 'https://github.com/paritytech/substrate.git' -# branch = 'polkadot-v0.9.17' - -[dependencies.sp-arithmetic] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-api] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-block-builder] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-core] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-consensus-aura] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-inherents] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-io] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-offchain] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-runtime] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-session] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-std] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-transaction-pool] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.sp-version] -default-features = false -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' - -[dependencies.smallvec] -version = '1.6.1' - -################################################################################ -# Cumulus dependencies - -[dependencies.parachain-info] -default-features = false -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' - -[dependencies.cumulus-pallet-aura-ext] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -[dependencies.cumulus-pallet-parachain-system] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -[dependencies.cumulus-primitives-core] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -[dependencies.cumulus-pallet-xcm] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -[dependencies.cumulus-pallet-dmp-queue] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -[dependencies.cumulus-pallet-xcmp-queue] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -[dependencies.cumulus-primitives-utility] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -[dependencies.cumulus-primitives-timestamp] -git = 'https://github.com/uniqueNetwork/cumulus.git' -branch = 'polkadot-v0.9.17' -default-features = false - -################################################################################ -# Polkadot dependencies - -[dependencies.polkadot-parachain] -git = 'https://github.com/paritytech/polkadot' -branch = 'release-v0.9.17' -default-features = false - -[dependencies.xcm] -git = 'https://github.com/paritytech/polkadot' -branch = 'release-v0.9.17' -default-features = false - -[dependencies.xcm-builder] -git = 'https://github.com/paritytech/polkadot' -branch = 'release-v0.9.17' -default-features = false - -[dependencies.xcm-executor] -git = 'https://github.com/paritytech/polkadot' -branch = 'release-v0.9.17' -default-features = false - -[dependencies.pallet-xcm] -git = 'https://github.com/paritytech/polkadot' -branch = 'release-v0.9.17' -default-features = false - -[dependencies.orml-vesting] -git = 'https://github.com/UniqueNetwork/open-runtime-module-library' -branch = 'unique-polkadot-v0.9.17' -version = "0.4.1-dev" -default-features = false - -################################################################################ -# local dependencies - -[dependencies] -scale-info = { version = "1.0.0", default-features = false, features = [ - "derive", -] } -derivative = "2.2.0" -pallet-unique = { path = '../pallets/unique', default-features = false } -up-rpc = { path = "../primitives/rpc", default-features = false } -up-evm-mapping = { path = "../primitives/evm-mapping", default-features = false } -pallet-inflation = { path = '../pallets/inflation', default-features = false } -up-data-structs = { path = '../primitives/data-structs', default-features = false } -pallet-common = { default-features = false, path = "../pallets/common" } -pallet-fungible = { default-features = false, path = "../pallets/fungible" } -pallet-refungible = { default-features = false, path = "../pallets/refungible" } -pallet-nonfungible = { default-features = false, path = "../pallets/nonfungible" } -pallet-unq-scheduler = { path = '../pallets/scheduler', default-features = false } -# pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' } -pallet-charge-transaction = { git = "https://github.com/UniqueNetwork/pallet-sponsoring", branch = 'polkadot-v0.9.17', package = "pallet-template-transaction-payment", default-features = false, version = '3.0.0' } -pallet-evm-migration = { path = '../pallets/evm-migration', default-features = false } -pallet-evm-contract-helpers = { path = '../pallets/evm-contract-helpers', default-features = false } -pallet-evm-transaction-payment = { path = '../pallets/evm-transaction-payment', default-features = false } -pallet-evm-coder-substrate = { default-features = false, path = "../pallets/evm-coder-substrate" } - -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } -pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } -pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } -fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } -fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } - -################################################################################ -# Build Dependencies - -[build-dependencies.substrate-wasm-builder] -git = 'https://github.com/paritytech/substrate.git' -branch = 'polkadot-v0.9.17' --- a/runtime/build.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network 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. - -// Unique Network 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 Unique Network. If not, see . - -use substrate_wasm_builder::WasmBuilder; - -fn main() { - WasmBuilder::new() - .with_current_project() - .import_memory() - .export_heap_base() - .build() -} --- /dev/null +++ b/runtime/common/Cargo.toml @@ -0,0 +1,72 @@ +[package] +authors = ['Unique Network '] +description = 'Unique Runtime Common' +edition = '2021' +homepage = 'https://unique.network' +license = 'All Rights Reserved' +name = 'unique-runtime-common' +repository = 'https://github.com/UniqueNetwork/unique-chain' +version = '0.1.0' + +[features] +default = ['std'] +std = [ + 'sp-core/std', + 'sp-runtime/std', + 'codec/std', + 'frame-support/std', + 'frame-system/std', + 'sp-consensus-aura/std', + 'pallet-common/std', + 'fp-rpc/std', +] +runtime-benchmarks = [ + 'sp-runtime/runtime-benchmarks', + 'frame-support/runtime-benchmarks', + 'frame-system/runtime-benchmarks' +] + +[dependencies.sp-core] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-runtime] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.codec] +default-features = false +features = ['derive'] +package = 'parity-scale-codec' +version = '2.3.0' + +[dependencies.scale-info] +default-features = false +features = ["derive"] +version = "1.0.0" + +[dependencies.frame-support] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-common] +default-features = false +path = "../../pallets/common" + +[dependencies.sp-consensus-aura] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.fp-rpc] +default-features = false +git = "https://github.com/uniquenetwork/frontier.git" +branch = "unique-polkadot-v0.9.17" --- /dev/null +++ b/runtime/common/src/constants.rs @@ -0,0 +1,40 @@ +use sp_runtime::Perbill; +use frame_support::{ + parameter_types, + weights::{Weight, constants::WEIGHT_PER_SECOND}, +}; +use crate::types::{BlockNumber, Balance}; + +pub const MILLISECS_PER_BLOCK: u64 = 12000; + +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + +// These time units are defined in number of blocks. +pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); +pub const HOURS: BlockNumber = MINUTES * 60; +pub const DAYS: BlockNumber = HOURS * 24; + +pub const MICROUNIQUE: Balance = 1_000_000_000_000; +pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE; +pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE; +pub const UNIQUE: Balance = 100 * CENTIUNIQUE; + +pub const WEIGHT_TO_FEE_COEFF: u32 = 142_688_000; + +// Targeting 0.15 UNQ per transfer +pub const MIN_GAS_PRICE: u64 = 1_018_751_825_264; + +/// 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. +pub 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. +pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +/// We allow for 2 seconds of compute with a 6 second average block time. +pub const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2; + +parameter_types! { + pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS; + + pub const TransactionByteFee: Balance = 501 * MICROUNIQUE; // Targeting 0.1 Unique per NFT transfer +} --- /dev/null +++ b/runtime/common/src/lib.rs @@ -0,0 +1,5 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod constants; +pub mod runtime_apis; +pub mod types; --- /dev/null +++ b/runtime/common/src/runtime_apis.rs @@ -0,0 +1,409 @@ +#[macro_export] +macro_rules! impl_common_runtime_apis { + ( + $( + #![custom_apis] + + $($custom_apis:tt)+ + )? + ) => { + impl_runtime_apis! { + $($($custom_apis)+)? + + impl up_rpc::UniqueApi for Runtime { + fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result, DispatchError> { + dispatch_unique_runtime!(collection.account_tokens(account)) + } + fn token_exists(collection: CollectionId, token: TokenId) -> Result { + dispatch_unique_runtime!(collection.token_exists(token)) + } + + fn token_owner(collection: CollectionId, token: TokenId) -> Result, DispatchError> { + dispatch_unique_runtime!(collection.token_owner(token)) + } + fn const_metadata(collection: CollectionId, token: TokenId) -> Result, DispatchError> { + dispatch_unique_runtime!(collection.const_metadata(token)) + } + fn variable_metadata(collection: CollectionId, token: TokenId) -> Result, DispatchError> { + dispatch_unique_runtime!(collection.variable_metadata(token)) + } + + fn collection_tokens(collection: CollectionId) -> Result { + dispatch_unique_runtime!(collection.collection_tokens()) + } + fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result { + dispatch_unique_runtime!(collection.account_balance(account)) + } + fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result { + dispatch_unique_runtime!(collection.balance(account, token)) + } + fn allowance( + collection: CollectionId, + sender: CrossAccountId, + spender: CrossAccountId, + token: TokenId, + ) -> Result { + dispatch_unique_runtime!(collection.allowance(sender, spender, token)) + } + + fn eth_contract_code(account: H160) -> Option> { + >::get_code(&account) + .or_else(|| >::get_code(&account)) + .or_else(|| >::get_code(&account)) + } + fn adminlist(collection: CollectionId) -> Result, DispatchError> { + Ok(>::adminlist(collection)) + } + fn allowlist(collection: CollectionId) -> Result, DispatchError> { + Ok(>::allowlist(collection)) + } + fn allowed(collection: CollectionId, user: CrossAccountId) -> Result { + Ok(>::allowed(collection, user)) + } + fn last_token_id(collection: CollectionId) -> Result { + dispatch_unique_runtime!(collection.last_token_id()) + } + fn collection_by_id(collection: CollectionId) -> Result>, DispatchError> { + Ok(>::get(collection)) + } + fn collection_stats() -> Result { + Ok(>::collection_stats()) + } + } + + 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_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + } + + 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) + } + + // fn random_seed() -> ::Hash { + // RandomnessCollectiveFlip::random_seed().0 + // } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl fp_rpc::EthereumRuntimeRPCApi for Runtime { + fn chain_id() -> u64 { + ::ChainId::get() + } + + fn account_basic(address: H160) -> EVMAccount { + EVM::account_basic(&address) + } + + fn gas_price() -> U256 { + ::FeeCalculator::min_gas_price() + } + + fn account_code_at(address: H160) -> Vec { + EVM::account_codes(address) + } + + fn author() -> H160 { + >::find_author() + } + + fn storage_at(address: H160, index: U256) -> H256 { + let mut tmp = [0u8; 32]; + index.to_big_endian(&mut tmp); + EVM::account_storages(address, H256::from_slice(&tmp[..])) + } + + #[allow(clippy::redundant_closure)] + fn call( + from: H160, + to: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + ::Runner::call( + from, + to, + data, + value, + gas_limit.low_u64(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + config.as_ref().unwrap_or_else(|| ::config()), + ).map_err(|err| err.into()) + } + + #[allow(clippy::redundant_closure)] + fn create( + from: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + ::Runner::create( + from, + data, + value, + gas_limit.low_u64(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + config.as_ref().unwrap_or_else(|| ::config()), + ).map_err(|err| err.into()) + } + + fn current_transaction_statuses() -> Option> { + Ethereum::current_transaction_statuses() + } + + fn current_block() -> Option { + Ethereum::current_block() + } + + fn current_receipts() -> Option> { + Ethereum::current_receipts() + } + + fn current_all() -> ( + Option, + Option>, + Option> + ) { + ( + Ethereum::current_block(), + Ethereum::current_receipts(), + Ethereum::current_transaction_statuses() + ) + } + + fn extrinsic_filter(xts: Vec<::Extrinsic>) -> Vec { + xts.into_iter().filter_map(|xt| match xt.0.function { + Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction), + _ => None + }).collect() + } + + fn elasticity() -> Option { + None + } + } + + impl sp_session::SessionKeys for Runtime { + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + } + + 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().to_vec() + } + } + + impl cumulus_primitives_core::CollectCollationInfo for Runtime { + fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { + ParachainSystem::collect_collation_info(header) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + } + + /* + impl pallet_contracts_rpc_runtime_api::ContractsApi + for Runtime + { + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: u64, + input_data: Vec, + ) -> pallet_contracts_primitives::ContractExecResult { + Contracts::bare_call(origin, dest, value, gas_limit, input_data, false) + } + + fn instantiate( + origin: AccountId, + endowment: Balance, + gas_limit: u64, + code: pallet_contracts_primitives::Code, + data: Vec, + salt: Vec, + ) -> pallet_contracts_primitives::ContractInstantiateResult + { + Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, false) + } + + fn get_storage( + address: AccountId, + key: [u8; 32], + ) -> pallet_contracts_primitives::GetStorageResult { + Contracts::get_storage(address, key) + } + + fn rent_projection( + address: AccountId, + ) -> pallet_contracts_primitives::RentProjectionResult { + Contracts::rent_projection(address) + } + } + */ + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + let mut list = Vec::::new(); + + list_benchmark!(list, extra, pallet_evm_migration, EvmMigration); + list_benchmark!(list, extra, pallet_unique, Unique); + list_benchmark!(list, extra, pallet_inflation, Inflation); + list_benchmark!(list, extra, pallet_fungible, Fungible); + list_benchmark!(list, extra, pallet_refungible, Refungible); + list_benchmark!(list, extra, pallet_nonfungible, Nonfungible); + // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate); + + let storage_info = AllPalletsReversedWithSystemFirst::storage_info(); + + return (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; + + let allowlist: 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(), + ]; + + let mut batches = Vec::::new(); + let params = (&config, &allowlist); + + add_benchmark!(params, batches, pallet_evm_migration, EvmMigration); + add_benchmark!(params, batches, pallet_unique, Unique); + add_benchmark!(params, batches, pallet_inflation, Inflation); + add_benchmark!(params, batches, pallet_fungible, Fungible); + add_benchmark!(params, batches, pallet_refungible, Refungible); + add_benchmark!(params, batches, pallet_nonfungible, Nonfungible); + // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } + } + } +} --- /dev/null +++ b/runtime/common/src/types.rs @@ -0,0 +1,56 @@ +use sp_runtime::{ + traits::{Verify, IdentifyAccount, BlakeTwo256}, + generic, MultiSignature, +}; + +pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + +/// Opaque block header type. +pub type Header = generic::Header; + +/// Opaque block type. +pub type Block = generic::Block; + +pub type SessionHandlers = (); + +/// An index to a block. +pub type BlockNumber = u32; + +/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. +pub type Signature = 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 IdentifyAccount>::AccountId; + +/// The type for looking up accounts. We don't expect more than 4 billion of them, but you +/// never know... +pub type AccountIndex = u32; + +/// 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; + +/// Digest item type. +pub type DigestItem = generic::DigestItem; + +pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; + +pub trait RuntimeInstance { + type CrossAccountId: pallet_common::account::CrossAccountId + + Send + + Sync + + 'static; + + type TransactionConverter: fp_rpc::ConvertTransaction + + Send + + Sync + + 'static; + + fn get_transaction_converter() -> Self::TransactionConverter; +} --- /dev/null +++ b/runtime/opal/Cargo.toml @@ -0,0 +1,410 @@ +################################################################################ +# Package + +[package] +authors = ['Unique Network '] +build = 'build.rs' +description = 'Opal Runtime' +edition = '2021' +homepage = 'https://unique.network' +license = 'GPLv3' +name = 'opal-runtime' +repository = 'https://github.com/UniqueNetwork/unique-chain' +version = '0.1.0' + +[package.metadata.docs.rs] +targets = ['x86_64-unknown-linux-gnu'] + +[features] +default = ['std'] +runtime-benchmarks = [ + 'hex-literal', + 'frame-benchmarking', + 'frame-support/runtime-benchmarks', + 'frame-system-benchmarking', + 'frame-system/runtime-benchmarks', + 'pallet-ethereum/runtime-benchmarks', + 'pallet-evm-migration/runtime-benchmarks', + 'pallet-evm-coder-substrate/runtime-benchmarks', + 'pallet-balances/runtime-benchmarks', + 'pallet-timestamp/runtime-benchmarks', + 'pallet-common/runtime-benchmarks', + 'pallet-fungible/runtime-benchmarks', + 'pallet-refungible/runtime-benchmarks', + 'pallet-nonfungible/runtime-benchmarks', + 'pallet-unique/runtime-benchmarks', + 'pallet-inflation/runtime-benchmarks', + 'pallet-xcm/runtime-benchmarks', + 'sp-runtime/runtime-benchmarks', + 'xcm-builder/runtime-benchmarks', +] +std = [ + 'codec/std', + 'cumulus-pallet-aura-ext/std', + 'cumulus-pallet-parachain-system/std', + 'cumulus-pallet-xcm/std', + 'cumulus-pallet-xcmp-queue/std', + 'cumulus-primitives-core/std', + 'cumulus-primitives-utility/std', + 'frame-executive/std', + 'frame-support/std', + 'frame-system/std', + 'frame-system-rpc-runtime-api/std', + 'pallet-aura/std', + 'pallet-balances/std', + # 'pallet-contracts/std', + # 'pallet-contracts-primitives/std', + # 'pallet-contracts-rpc-runtime-api/std', + # 'pallet-contract-helpers/std', + 'pallet-randomness-collective-flip/std', + 'pallet-sudo/std', + 'pallet-timestamp/std', + 'pallet-transaction-payment/std', + 'pallet-transaction-payment-rpc-runtime-api/std', + 'pallet-treasury/std', + # 'pallet-vesting/std', + 'pallet-evm/std', + 'pallet-evm-migration/std', + 'pallet-evm-contract-helpers/std', + 'pallet-evm-transaction-payment/std', + 'pallet-evm-coder-substrate/std', + 'pallet-ethereum/std', + 'pallet-base-fee/std', + 'fp-rpc/std', + 'up-rpc/std', + 'up-evm-mapping/std', + 'fp-self-contained/std', + 'parachain-info/std', + 'serde', + 'pallet-inflation/std', + 'pallet-common/std', + 'pallet-fungible/std', + 'pallet-refungible/std', + 'pallet-nonfungible/std', + 'pallet-unique/std', + 'pallet-unq-scheduler/std', + 'pallet-charge-transaction/std', + 'up-data-structs/std', + 'sp-api/std', + 'sp-block-builder/std', + "sp-consensus-aura/std", + 'sp-core/std', + 'sp-inherents/std', + 'sp-io/std', + 'sp-offchain/std', + 'sp-runtime/std', + 'sp-session/std', + 'sp-std/std', + 'sp-transaction-pool/std', + 'sp-version/std', + 'xcm/std', + 'xcm-builder/std', + 'xcm-executor/std', + 'unique-runtime-common/std', + + "orml-vesting/std", +] +limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] + +################################################################################ +# Substrate Dependencies + +[dependencies.codec] +default-features = false +features = ['derive'] +package = 'parity-scale-codec' +version = '2.3.0' + +[dependencies.frame-benchmarking] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +optional = true +branch = 'polkadot-v0.9.17' + +[dependencies.frame-executive] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-support] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system-benchmarking] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +optional = true +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system-rpc-runtime-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.hex-literal] +optional = true +version = '0.3.3' + +[dependencies.serde] +default-features = false +features = ['derive'] +optional = true +version = '1.0.130' + +[dependencies.pallet-aura] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-balances] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +# Contracts specific packages +# [dependencies.pallet-contracts] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +# [dependencies.pallet-contracts-primitives] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +# [dependencies.pallet-contracts-rpc-runtime-api] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +[dependencies.pallet-randomness-collective-flip] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-sudo] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-timestamp] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-transaction-payment] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-transaction-payment-rpc-runtime-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-treasury] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +# [dependencies.pallet-vesting] +# default-features = false +# git = 'https://github.com/paritytech/substrate.git' +# branch = 'polkadot-v0.9.17' + +[dependencies.sp-arithmetic] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-block-builder] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-core] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-consensus-aura] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-inherents] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-io] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-offchain] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-runtime] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-session] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-std] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-transaction-pool] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-version] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.smallvec] +version = '1.6.1' + +################################################################################ +# Cumulus dependencies + +[dependencies.parachain-info] +default-features = false +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' + +[dependencies.cumulus-pallet-aura-ext] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-parachain-system] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-core] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-xcm] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-dmp-queue] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-xcmp-queue] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-utility] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-timestamp] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +################################################################################ +# Polkadot dependencies + +[dependencies.polkadot-parachain] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm-builder] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm-executor] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.pallet-xcm] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.orml-vesting] +git = 'https://github.com/UniqueNetwork/open-runtime-module-library' +branch = 'unique-polkadot-v0.9.17' +version = "0.4.1-dev" +default-features = false + +################################################################################ +# local dependencies + +[dependencies] +unique-runtime-common = { path = "../common", default-features = false } +scale-info = { version = "1.0.0", default-features = false, features = [ + "derive", +] } +derivative = "2.2.0" +pallet-unique = { path = '../../pallets/unique', default-features = false } +up-rpc = { path = "../../primitives/rpc", default-features = false } +up-evm-mapping = { path = "../../primitives/evm-mapping", default-features = false } +pallet-inflation = { path = '../../pallets/inflation', default-features = false } +up-data-structs = { path = '../../primitives/data-structs', default-features = false } +pallet-common = { default-features = false, path = "../../pallets/common" } +pallet-fungible = { default-features = false, path = "../../pallets/fungible" } +pallet-refungible = { default-features = false, path = "../../pallets/refungible" } +pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" } +pallet-unq-scheduler = { path = '../../pallets/scheduler', default-features = false } +# pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' } +pallet-charge-transaction = { git = "https://github.com/UniqueNetwork/pallet-sponsoring", branch = 'polkadot-v0.9.17', package = "pallet-template-transaction-payment", default-features = false, version = '3.0.0' } +pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false } +pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false } +pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false } +pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } + +################################################################################ +# Build Dependencies + +[build-dependencies.substrate-wasm-builder] +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' --- /dev/null +++ b/runtime/opal/build.rs @@ -0,0 +1,25 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network 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. + +// Unique Network 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 Unique Network. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} --- /dev/null +++ b/runtime/opal/src/lib.rs @@ -0,0 +1,1141 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network 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. + +// Unique Network 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 Unique Network. If not, see . + +//! The Substrate Node Template 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 = "1024"] +#![allow(clippy::from_over_into, clippy::identity_op)] +#![allow(clippy::fn_to_numeric_cast_with_truncation)] +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use sp_api::impl_runtime_apis; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160}; +use sp_runtime::DispatchError; +// #[cfg(any(feature = "std", test))] +// pub use sp_runtime::BuildStorage; + +use sp_runtime::{ + Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, RuntimeAppPublic, +}; + +use sp_std::prelude::*; + +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +pub use pallet_transaction_payment::{ + Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo, +}; +// A few exports that help ease life for downstream crates. +pub use pallet_balances::Call as BalancesCall; +pub use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping, Runner}; +pub use frame_support::{ + construct_runtime, match_type, + dispatch::DispatchResult, + PalletId, parameter_types, StorageValue, ConsensusEngineId, + traits::{ + tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything, + Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier, + OnUnbalanced, Randomness, FindAuthor, + }, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight, + WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + }, +}; +use up_data_structs::*; +// use pallet_contracts::weights::WeightInfo; +// #[cfg(any(feature = "std", test))] +use frame_system::{ + self as frame_system, EnsureRoot, EnsureSigned, + limits::{BlockWeights, BlockLength}, +}; +use sp_arithmetic::{ + traits::{BaseArithmetic, Unsigned}, +}; +use smallvec::smallvec; +use codec::{Encode, Decode}; +use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall}; +use fp_rpc::TransactionStatus; +use sp_runtime::{ + traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating}, + transaction_validity::TransactionValidityError, + SaturatedConversion, +}; + +// pub use pallet_timestamp::Call as TimestampCall; +pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; + +// Polkadot imports +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*}; +use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, + EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + ParentIsPreset, +}; +use xcm_executor::{Config, XcmExecutor, Assets}; +use sp_std::{marker::PhantomData}; + +use xcm::latest::{ + // Xcm, + AssetId::{Concrete}, + Fungibility::Fungible as XcmFungible, + MultiAsset, + Error as XcmError, +}; +use xcm_executor::traits::{MatchesFungible, WeightTrader}; +//use xcm_executor::traits::MatchesFungible; +use sp_runtime::traits::CheckedConversion; + +use unique_runtime_common::{impl_common_runtime_apis, types::*, constants::*}; + +pub const RUNTIME_NAME: &str = "Opal"; + +type CrossAccountId = pallet_common::account::BasicCrossAccountId; + +impl RuntimeInstance for Runtime { + type CrossAccountId = self::CrossAccountId; + + type TransactionConverter = self::TransactionConverter; + + fn get_transaction_converter() -> TransactionConverter { + TransactionConverter + } +} + +/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know +/// the specifics of the runtime. They can then be made to be agnostic over specific formats +/// of data like extrinsics, allowing for them to continue syncing the network through upgrades +/// to even the core data structures. +pub mod opaque { + use sp_std::prelude::*; + use sp_runtime::impl_opaque_keys; + use super::Aura; + + pub use unique_runtime_common::types::*; + + impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } + } +} + +/// This runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!(RUNTIME_NAME), + impl_name: create_runtime_str!(RUNTIME_NAME), + authoring_version: 1, + spec_version: 917004, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 0, +}; + +#[derive(codec::Encode, codec::Decode)] +pub enum XCMPMessage { + /// Transfer tokens to the given account from the Parachain account. + TransferToken(XAccountId, XBalance), +} + +/// 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(), + } +} + +type NegativeImbalance = >::NegativeImbalance; + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(mut fees_then_tips: impl Iterator) { + if let Some(fees) = fees_then_tips.next() { + // for fees, 100% to treasury + let mut split = fees.ration(100, 0); + if let Some(tips) = fees_then_tips.next() { + // for tips, if any, 100% to treasury + tips.ration_merge_into(100, 0, &mut split); + } + Treasury::on_unbalanced(split.0); + // Author::on_unbalanced(split.1); + } + } +} + +parameter_types! { + pub const BlockHashCount: BlockNumber = 2400; + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + 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 Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 42; +} + +parameter_types! { + pub const ChainId: u64 = 8882; +} + +pub struct FixedFee; +impl FeeCalculator for FixedFee { + fn min_gas_price() -> U256 { + MIN_GAS_PRICE.into() + } +} + +// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case +// (contract, which only writes a lot of data), +// approximating on top of our real store write weight +parameter_types! { + pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / ::DbWeight::get().write; + pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000; + pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get(); +} + +/// Limiting EVM execution to 50% of block for substrate users and management tasks +/// EVM transaction consumes more weight than substrate's, so we can't rely on them being +/// scheduled fairly +const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50); +parameter_types! { + pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get()); +} + +pub enum FixedGasWeightMapping {} +impl GasWeightMapping for FixedGasWeightMapping { + fn gas_to_weight(gas: u64) -> Weight { + gas.saturating_mul(WeightPerGas::get()) + } + fn weight_to_gas(weight: Weight) -> u64 { + weight / WeightPerGas::get() + } +} + +impl pallet_evm::Config for Runtime { + type BlockGasLimit = BlockGasLimit; + type FeeCalculator = FixedFee; + type GasWeightMapping = FixedGasWeightMapping; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = EnsureAddressTruncated; + type WithdrawOrigin = EnsureAddressTruncated; + type AddressMapping = HashedAddressMapping; + type PrecompilesType = (); + type PrecompilesValue = (); + type Currency = Balances; + type Event = Event; + type OnMethodCall = ( + pallet_evm_migration::OnMethodCall, + pallet_unique::UniqueErcSupport, + pallet_evm_contract_helpers::HelpersOnMethodCall, + ); + type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate; + type ChainId = ChainId; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = pallet_evm_transaction_payment::OnChargeTransaction; + type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack; + type FindAuthor = EthereumFindAuthor; +} + +impl pallet_evm_migration::Config for Runtime { + type WeightInfo = pallet_evm_migration::weights::SubstrateWeight; +} + +pub struct EthereumFindAuthor(core::marker::PhantomData); +impl> FindAuthor for EthereumFindAuthor { + fn find_author<'a, I>(digests: I) -> Option + where + I: 'a + IntoIterator, + { + if let Some(author_index) = F::find_author(digests) { + let authority_id = Aura::authorities()[author_index as usize].clone(); + return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24])); + } + None + } +} + +impl pallet_ethereum::Config for Runtime { + type Event = Event; + type StateRoot = pallet_ethereum::IntermediateStateRoot; +} + +impl pallet_randomness_collective_flip::Config for Runtime {} + +impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The basic call filter to use in dispatchable. + type BaseCallFilter = Everything; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block. + type BlockWeights = RuntimeBlockWeights; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The weight of database operations that the runtime can invoke. + 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 = AccountIdLookup; + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// What to do if a new account is created. + type OnNewAccount = (); + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + /// The ubiquitous origin type. + type Origin = Origin; + /// This type is being generated by `construct_runtime!`. + type PalletInfo = PalletInfo; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = frame_system::weights::SubstrateWeight; + /// Version of the runtime. + type Version = Version; + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} + +impl pallet_timestamp::Config for Runtime { + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + // pub const ExistentialDeposit: u128 = 500; + pub const ExistentialDeposit: u128 = 0; + pub const MaxLocks: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = Treasury; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; +} + +pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE +} + +/* +parameter_types! { + pub TombstoneDeposit: Balance = deposit( + 1, + sp_std::mem::size_of::> as u32, + ); + pub DepositPerContract: Balance = TombstoneDeposit::get(); + pub const DepositPerStorageByte: Balance = deposit(0, 1); + pub const DepositPerStorageItem: Balance = deposit(1, 0); + pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS); + pub const SurchargeReward: Balance = 150 * MILLIUNIQUE; + pub const SignedClaimHandicap: u32 = 2; + pub const MaxDepth: u32 = 32; + pub const MaxValueSize: u32 = 16 * 1024; + pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb + // The lazy deletion runs inside on_initialize. + pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * + RuntimeBlockWeights::get().max_block; + // The weight needed for decoding the queue should be less or equal than a fifth + // of the overall weight dedicated to the lazy deletion. + pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / ( + ::WeightInfo::on_initialize_per_queue_item(1) - + ::WeightInfo::on_initialize_per_queue_item(0) + )) / 5) as u32; + pub Schedule: pallet_contracts::Schedule = Default::default(); +} + +impl pallet_contracts::Config for Runtime { + type Time = Timestamp; + type Randomness = RandomnessCollectiveFlip; + type Currency = Balances; + type Event = Event; + type RentPayment = (); + type SignedClaimHandicap = SignedClaimHandicap; + type TombstoneDeposit = TombstoneDeposit; + type DepositPerContract = DepositPerContract; + type DepositPerStorageByte = DepositPerStorageByte; + type DepositPerStorageItem = DepositPerStorageItem; + type RentFraction = RentFraction; + type SurchargeReward = SurchargeReward; + type WeightPrice = pallet_transaction_payment::Pallet; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type ChainExtension = NFTExtension; + type DeletionQueueDepth = DeletionQueueDepth; + type DeletionWeightLimit = DeletionWeightLimit; + type Schedule = Schedule; + type CallStack = [pallet_contracts::Frame; 31]; +} +*/ + +parameter_types! { + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +/// Linear implementor of `WeightToFeePolynomial` +pub struct LinearFee(sp_std::marker::PhantomData); + +impl WeightToFeePolynomial for LinearFee +where + T: BaseArithmetic + From + Copy + Unsigned, +{ + type Balance = T; + + fn polynomial() -> WeightToFeeCoefficients { + smallvec!(WeightToFeeCoefficient { + // Targeting 0.1 Unique per NFT transfer + coeff_integer: WEIGHT_TO_FEE_COEFF.into(), + coeff_frac: Perbill::zero(), + negative: false, + degree: 1, + }) + } +} + +impl pallet_transaction_payment::Config for Runtime { + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type TransactionByteFee = TransactionByteFee; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = LinearFee; + type FeeMultiplierUpdate = (); +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 1 * UNIQUE; + pub const ProposalBondMaximum: Balance = 1000 * UNIQUE; + pub const SpendPeriod: BlockNumber = 5 * MINUTES; + pub const Burn: Permill = Permill::from_percent(0); + pub const TipCountdown: BlockNumber = 1 * DAYS; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: Balance = 1 * UNIQUE; + pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE; + pub const BountyDepositBase: Balance = 1 * UNIQUE; + pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS; + pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry"); + pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS; + pub const MaximumReasonLength: u32 = 16384; + pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); + pub const BountyValueMinimum: Balance = 5 * UNIQUE; + pub const MaxApprovals: u32 = 100; +} + +impl pallet_treasury::Config for Runtime { + type PalletId = TreasuryModuleId; + type Currency = Balances; + type ApproveOrigin = EnsureRoot; + type RejectOrigin = EnsureRoot; + type Event = Event; + type OnSlash = (); + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type ProposalBondMaximum = ProposalBondMaximum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = (); + type SpendFunds = (); + type WeightInfo = pallet_treasury::weights::SubstrateWeight; + type MaxApprovals = MaxApprovals; +} + +impl pallet_sudo::Config for Runtime { + type Event = Event; + type Call = Call; +} + +pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider + for RelayChainBlockNumberProvider +{ + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + cumulus_pallet_parachain_system::Pallet::::validation_data() + .map(|d| d.relay_parent_number) + .unwrap_or_default() + } +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 10 * UNIQUE; + pub const MaxVestingSchedules: u32 = 28; +} + +impl orml_vesting::Config for Runtime { + type Event = Event; + type Currency = pallet_balances::Pallet; + type MinVestedTransfer = MinVestedTransfer; + type VestedTransferOrigin = EnsureSigned; + type WeightInfo = (); + type MaxVestingSchedules = MaxVestingSchedules; + type BlockNumberProvider = RelayChainBlockNumberProvider; +} + +parameter_types! { + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + type Event = Event; + type SelfParaId = parachain_info::Pallet; + type OnSystemEvent = (); + // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent< + // MaxDownwardMessageWeight, + // XcmExecutor, + // Call, + // >; + type OutboundXcmpMessageSource = XcmpQueue; + type DmpMessageHandler = DmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type XcmpMessageHandler = XcmpQueue; +} + +impl parachain_info::Config for Runtime {} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Polkadot; + pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).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`. + ParentIsPreset, + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +pub struct OnlySelfCurrency; +impl> MatchesFungible for OnlySelfCurrency { + fn matches_fungible(a: &MultiAsset) -> Option { + match (&a.id, &a.fun) { + (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount), + _ => None, + } + } +} + +/// 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: + OnlySelfCurrency, + // 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; + // 1200 UNIQUEs buy 1 second of weight. + pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE); + pub const MaxInstructions: u32 = 100; + pub const MaxAuthorities: u32 = 100_000; +} + +match_type! { + pub type ParentOrParentsUnitPlurality: impl Contains = { + MultiLocation { parents: 1, interior: Here } | + MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } + }; +} + +pub type Barrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + AllowUnpaidExecutionFrom, + // ^^^ Parent & its unit plurality gets free execution +); + +pub struct UsingOnlySelfCurrencyComponents< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, +>( + Weight, + Currency::Balance, + PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, +); +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > WeightTrader + for UsingOnlySelfCurrencyComponents +{ + fn new() -> Self { + Self(0, Zero::zero(), PhantomData) + } + + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { + let amount = WeightToFee::calc(&weight); + let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; + + // location to this parachain through relay chain + let option1: xcm::v1::AssetId = Concrete(MultiLocation { + parents: 1, + interior: X1(Parachain(ParachainInfo::parachain_id().into())), + }); + // direct location + let option2: xcm::v1::AssetId = Concrete(MultiLocation { + parents: 0, + interior: Here, + }); + + let required = if payment.fungible.contains_key(&option1) { + (option1, u128_amount).into() + } else if payment.fungible.contains_key(&option2) { + (option2, u128_amount).into() + } else { + (Concrete(MultiLocation::default()), u128_amount).into() + }; + + let unused = payment + .checked_sub(required) + .map_err(|_| XcmError::TooExpensive)?; + self.0 = self.0.saturating_add(weight); + self.1 = self.1.saturating_add(amount); + Ok(unused) + } + + fn refund_weight(&mut self, weight: Weight) -> Option { + let weight = weight.min(self.0); + let amount = WeightToFee::calc(&weight); + self.0 -= weight; + self.1 = self.1.saturating_sub(amount); + let amount: u128 = amount.saturated_into(); + if amount > 0 { + Some((AssetId::get(), amount).into()) + } else { + None + } + } +} +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > Drop + for UsingOnlySelfCurrencyComponents +{ + fn drop(&mut self) { + OnUnbalanced::on_unbalanced(Currency::issue(self.1)); + } +} + +pub struct XcmConfig; +impl Config for XcmConfig { + type Call = Call; + type XcmSender = XcmRouter; + // How to withdraw and deposit an asset. + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type IsReserve = NativeAsset; + type IsTeleporter = (); // Teleportation is disabled + type LocationInverter = LocationInverter; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = UsingOnlySelfCurrencyComponents< + IdentityFee, + RelayLocation, + AccountId, + Balances, + (), + >; + type ResponseHandler = (); // Don't handle responses for now. + type SubscriptionService = PolkadotXcm; + + type AssetTrap = PolkadotXcm; + type AssetClaims = PolkadotXcm; +} + +// parameter_types! { +// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; +// } + +/// 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_evm_coder_substrate::Config for Runtime { + type EthereumTransactionSender = pallet_ethereum::Pallet; + type GasWeightMapping = FixedGasWeightMapping; +} + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type LocationInverter = LocationInverter; + type Origin = Origin; + type Call = Call; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ParachainSystem; + type VersionWrapper = (); + type ExecuteOverweightOrigin = frame_system::EnsureRoot; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; +} + +impl pallet_aura::Config for Runtime { + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account(); + pub const CollectionCreationPrice: Balance = 2 * UNIQUE; +} + +impl pallet_common::Config for Runtime { + type Event = Event; + type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; + type EvmAddressMapping = HashedAddressMapping; + type CrossAccountId = pallet_common::account::BasicCrossAccountId; + + type Currency = Balances; + type CollectionCreationPrice = CollectionCreationPrice; + type TreasuryAccountId = TreasuryAccountId; +} + +impl pallet_fungible::Config for Runtime { + type WeightInfo = pallet_fungible::weights::SubstrateWeight; +} +impl pallet_refungible::Config for Runtime { + type WeightInfo = pallet_refungible::weights::SubstrateWeight; +} +impl pallet_nonfungible::Config for Runtime { + type WeightInfo = pallet_nonfungible::weights::SubstrateWeight; +} + +impl pallet_unique::Config for Runtime { + type Event = Event; + type WeightInfo = pallet_unique::weights::SubstrateWeight; +} + +parameter_types! { + pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied +} + +/// Used for the pallet inflation +impl pallet_inflation::Config for Runtime { + type Currency = Balances; + type TreasuryAccountId = TreasuryAccountId; + type InflationBlockInterval = InflationBlockInterval; + type BlockNumberProvider = RelayChainBlockNumberProvider; +} + +// parameter_types! { +// pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) * +// RuntimeBlockWeights::get().max_block; +// pub const MaxScheduledPerBlock: u32 = 50; +// } + +type EvmSponsorshipHandler = ( + pallet_unique::UniqueEthSponsorshipHandler, + pallet_evm_contract_helpers::HelpersContractSponsoring, +); +type SponsorshipHandler = ( + pallet_unique::UniqueSponsorshipHandler, + //pallet_contract_helpers::ContractSponsorshipHandler, + pallet_evm_transaction_payment::BridgeSponsorshipHandler, +); + +// impl pallet_unq_scheduler::Config for Runtime { +// type Event = Event; +// type Origin = Origin; +// type PalletsOrigin = OriginCaller; +// type Call = Call; +// type MaximumWeight = MaximumSchedulerWeight; +// type ScheduleOrigin = EnsureSigned; +// type MaxScheduledPerBlock = MaxScheduledPerBlock; +// type SponsorshipHandler = SponsorshipHandler; +// type WeightInfo = (); +// } + +impl pallet_evm_transaction_payment::Config for Runtime { + type EvmSponsorshipHandler = EvmSponsorshipHandler; + type Currency = Balances; + type EvmAddressMapping = HashedAddressMapping; + type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; +} + +impl pallet_charge_transaction::Config for Runtime { + type SponsorshipHandler = SponsorshipHandler; +} + +// impl pallet_contract_helpers::Config for Runtime { +// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; +// } + +parameter_types! { + // 0x842899ECF380553E8a4de75bF534cdf6fBF64049 + pub const HelpersContractAddress: H160 = H160([ + 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49, + ]); +} + +impl pallet_evm_contract_helpers::Config for Runtime { + type ContractAddress = HelpersContractAddress; + type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned} = 20, + ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21, + + Aura: pallet_aura::{Pallet, Config} = 22, + AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23, + + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 30, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 34, + Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event} = 35, + System: frame_system::{Pallet, Call, Storage, Config, Event} = 36, + Vesting: orml_vesting::{Pallet, Storage, Call, Event, Config} = 37, + // Vesting: pallet_vesting::{Pallet, Call, Config, Storage, Event} = 37, + // Contracts: pallet_contracts::{Pallet, Call, Storage, Event} = 38, + + // XCM helpers. + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 50, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin} = 51, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 52, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 53, + + // Unique Pallets + Inflation: pallet_inflation::{Pallet, Call, Storage} = 60, + Unique: pallet_unique::{Pallet, Call, Storage, Event} = 61, + // Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event} = 62, + // free = 63 + Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64, + // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65, + Common: pallet_common::{Pallet, Storage, Event} = 66, + Fungible: pallet_fungible::{Pallet, Storage} = 67, + Refungible: pallet_refungible::{Pallet, Storage} = 68, + Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69, + + // Frontier + EVM: pallet_evm::{Pallet, Config, Call, Storage, Event} = 100, + Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101, + + EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150, + EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151, + EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152, + EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153, + } +); + +pub struct TransactionConverter; + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } +} + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) + .expect("Encoded extrinsic is always valid") + } +} + +/// 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, + // system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_charge_transaction::ChargeTransactionPayment, + //pallet_contract_helpers::ContractHelpersExtension, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + fp_self_contained::UncheckedExtrinsic; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsReversedWithSystemFirst, +>; + +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } +} + +impl fp_self_contained::SelfContainedCall for Call { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + Call::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + Call::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option { + match self { + Call::Ethereum(call) => call.validate_self_contained(info), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + ) -> Option> { + match self { + Call::Ethereum(call) => call.pre_dispatch_self_contained(info), + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch( + Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)), + )), + _ => None, + } + } +} + +macro_rules! dispatch_unique_runtime { + ($collection:ident.$method:ident($($name:ident),*)) => {{ + use pallet_unique::dispatch::Dispatched; + + let collection = Dispatched::dispatch(>::try_get($collection)?); + let dispatch = collection.as_dyn(); + + Ok(dispatch.$method($($name),*)) + }}; +} + +impl_common_runtime_apis!(); + +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, +); --- /dev/null +++ b/runtime/quartz/Cargo.toml @@ -0,0 +1,410 @@ +################################################################################ +# Package + +[package] +authors = ['Unique Network '] +build = 'build.rs' +description = 'Quartz Runtime' +edition = '2021' +homepage = 'https://unique.network' +license = 'GPLv3' +name = 'quartz-runtime' +repository = 'https://github.com/UniqueNetwork/unique-chain' +version = '0.1.0' + +[package.metadata.docs.rs] +targets = ['x86_64-unknown-linux-gnu'] + +[features] +default = ['std'] +runtime-benchmarks = [ + 'hex-literal', + 'frame-benchmarking', + 'frame-support/runtime-benchmarks', + 'frame-system-benchmarking', + 'frame-system/runtime-benchmarks', + 'pallet-ethereum/runtime-benchmarks', + 'pallet-evm-migration/runtime-benchmarks', + 'pallet-evm-coder-substrate/runtime-benchmarks', + 'pallet-balances/runtime-benchmarks', + 'pallet-timestamp/runtime-benchmarks', + 'pallet-common/runtime-benchmarks', + 'pallet-fungible/runtime-benchmarks', + 'pallet-refungible/runtime-benchmarks', + 'pallet-nonfungible/runtime-benchmarks', + 'pallet-unique/runtime-benchmarks', + 'pallet-inflation/runtime-benchmarks', + 'pallet-xcm/runtime-benchmarks', + 'sp-runtime/runtime-benchmarks', + 'xcm-builder/runtime-benchmarks', +] +std = [ + 'codec/std', + 'cumulus-pallet-aura-ext/std', + 'cumulus-pallet-parachain-system/std', + 'cumulus-pallet-xcm/std', + 'cumulus-pallet-xcmp-queue/std', + 'cumulus-primitives-core/std', + 'cumulus-primitives-utility/std', + 'frame-executive/std', + 'frame-support/std', + 'frame-system/std', + 'frame-system-rpc-runtime-api/std', + 'pallet-aura/std', + 'pallet-balances/std', + # 'pallet-contracts/std', + # 'pallet-contracts-primitives/std', + # 'pallet-contracts-rpc-runtime-api/std', + # 'pallet-contract-helpers/std', + 'pallet-randomness-collective-flip/std', + 'pallet-sudo/std', + 'pallet-timestamp/std', + 'pallet-transaction-payment/std', + 'pallet-transaction-payment-rpc-runtime-api/std', + 'pallet-treasury/std', + # 'pallet-vesting/std', + 'pallet-evm/std', + 'pallet-evm-migration/std', + 'pallet-evm-contract-helpers/std', + 'pallet-evm-transaction-payment/std', + 'pallet-evm-coder-substrate/std', + 'pallet-ethereum/std', + 'pallet-base-fee/std', + 'fp-rpc/std', + 'up-rpc/std', + 'up-evm-mapping/std', + 'fp-self-contained/std', + 'parachain-info/std', + 'serde', + 'pallet-inflation/std', + 'pallet-common/std', + 'pallet-fungible/std', + 'pallet-refungible/std', + 'pallet-nonfungible/std', + 'pallet-unique/std', + 'pallet-unq-scheduler/std', + 'pallet-charge-transaction/std', + 'up-data-structs/std', + 'sp-api/std', + 'sp-block-builder/std', + "sp-consensus-aura/std", + 'sp-core/std', + 'sp-inherents/std', + 'sp-io/std', + 'sp-offchain/std', + 'sp-runtime/std', + 'sp-session/std', + 'sp-std/std', + 'sp-transaction-pool/std', + 'sp-version/std', + 'xcm/std', + 'xcm-builder/std', + 'xcm-executor/std', + 'unique-runtime-common/std', + + "orml-vesting/std", +] +limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] + +################################################################################ +# Substrate Dependencies + +[dependencies.codec] +default-features = false +features = ['derive'] +package = 'parity-scale-codec' +version = '2.3.0' + +[dependencies.frame-benchmarking] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +optional = true +branch = 'polkadot-v0.9.17' + +[dependencies.frame-executive] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-support] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system-benchmarking] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +optional = true +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system-rpc-runtime-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.hex-literal] +optional = true +version = '0.3.3' + +[dependencies.serde] +default-features = false +features = ['derive'] +optional = true +version = '1.0.130' + +[dependencies.pallet-aura] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-balances] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +# Contracts specific packages +# [dependencies.pallet-contracts] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +# [dependencies.pallet-contracts-primitives] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +# [dependencies.pallet-contracts-rpc-runtime-api] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +[dependencies.pallet-randomness-collective-flip] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-sudo] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-timestamp] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-transaction-payment] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-transaction-payment-rpc-runtime-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-treasury] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +# [dependencies.pallet-vesting] +# default-features = false +# git = 'https://github.com/paritytech/substrate.git' +# branch = 'polkadot-v0.9.17' + +[dependencies.sp-arithmetic] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-block-builder] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-core] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-consensus-aura] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-inherents] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-io] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-offchain] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-runtime] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-session] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-std] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-transaction-pool] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-version] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.smallvec] +version = '1.6.1' + +################################################################################ +# Cumulus dependencies + +[dependencies.parachain-info] +default-features = false +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' + +[dependencies.cumulus-pallet-aura-ext] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-parachain-system] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-core] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-xcm] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-dmp-queue] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-xcmp-queue] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-utility] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-timestamp] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +################################################################################ +# Polkadot dependencies + +[dependencies.polkadot-parachain] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm-builder] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm-executor] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.pallet-xcm] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.orml-vesting] +git = 'https://github.com/UniqueNetwork/open-runtime-module-library' +branch = 'unique-polkadot-v0.9.17' +version = "0.4.1-dev" +default-features = false + +################################################################################ +# local dependencies + +[dependencies] +unique-runtime-common = { path = "../common", default-features = false } +scale-info = { version = "1.0.0", default-features = false, features = [ + "derive", +] } +derivative = "2.2.0" +pallet-unique = { path = '../../pallets/unique', default-features = false } +up-rpc = { path = "../../primitives/rpc", default-features = false } +up-evm-mapping = { path = "../../primitives/evm-mapping", default-features = false } +pallet-inflation = { path = '../../pallets/inflation', default-features = false } +up-data-structs = { path = '../../primitives/data-structs', default-features = false } +pallet-common = { default-features = false, path = "../../pallets/common" } +pallet-fungible = { default-features = false, path = "../../pallets/fungible" } +pallet-refungible = { default-features = false, path = "../../pallets/refungible" } +pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" } +pallet-unq-scheduler = { path = '../../pallets/scheduler', default-features = false } +# pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' } +pallet-charge-transaction = { git = "https://github.com/UniqueNetwork/pallet-sponsoring", branch = 'polkadot-v0.9.17', package = "pallet-template-transaction-payment", default-features = false, version = '3.0.0' } +pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false } +pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false } +pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false } +pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } + +################################################################################ +# Build Dependencies + +[build-dependencies.substrate-wasm-builder] +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' --- /dev/null +++ b/runtime/quartz/build.rs @@ -0,0 +1,9 @@ +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} --- /dev/null +++ b/runtime/quartz/src/lib.rs @@ -0,0 +1,1141 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network 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. + +// Unique Network 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 Unique Network. If not, see . + +//! The Substrate Node Template 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 = "1024"] +#![allow(clippy::from_over_into, clippy::identity_op)] +#![allow(clippy::fn_to_numeric_cast_with_truncation)] +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use sp_api::impl_runtime_apis; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160}; +use sp_runtime::DispatchError; +// #[cfg(any(feature = "std", test))] +// pub use sp_runtime::BuildStorage; + +use sp_runtime::{ + Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, RuntimeAppPublic, +}; + +use sp_std::prelude::*; + +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +pub use pallet_transaction_payment::{ + Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo, +}; +// A few exports that help ease life for downstream crates. +pub use pallet_balances::Call as BalancesCall; +pub use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping, Runner}; +pub use frame_support::{ + construct_runtime, match_type, + dispatch::DispatchResult, + PalletId, parameter_types, StorageValue, ConsensusEngineId, + traits::{ + tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything, + Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier, + OnUnbalanced, Randomness, FindAuthor, + }, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight, + WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + }, +}; +use up_data_structs::*; +// use pallet_contracts::weights::WeightInfo; +// #[cfg(any(feature = "std", test))] +use frame_system::{ + self as frame_system, EnsureRoot, EnsureSigned, + limits::{BlockWeights, BlockLength}, +}; +use sp_arithmetic::{ + traits::{BaseArithmetic, Unsigned}, +}; +use smallvec::smallvec; +use codec::{Encode, Decode}; +use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall}; +use fp_rpc::TransactionStatus; +use sp_runtime::{ + traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating}, + transaction_validity::TransactionValidityError, + SaturatedConversion, +}; + +// pub use pallet_timestamp::Call as TimestampCall; +pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; + +// Polkadot imports +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*}; +use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, + EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + ParentIsPreset, +}; +use xcm_executor::{Config, XcmExecutor, Assets}; +use sp_std::{marker::PhantomData}; + +use xcm::latest::{ + // Xcm, + AssetId::{Concrete}, + Fungibility::Fungible as XcmFungible, + MultiAsset, + Error as XcmError, +}; +use xcm_executor::traits::{MatchesFungible, WeightTrader}; +//use xcm_executor::traits::MatchesFungible; +use sp_runtime::traits::CheckedConversion; + +use unique_runtime_common::{impl_common_runtime_apis, types::*, constants::*}; + +pub const RUNTIME_NAME: &str = "Quartz"; + +type CrossAccountId = pallet_common::account::BasicCrossAccountId; + +impl RuntimeInstance for Runtime { + type CrossAccountId = self::CrossAccountId; + + type TransactionConverter = self::TransactionConverter; + + fn get_transaction_converter() -> TransactionConverter { + TransactionConverter + } +} + +/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know +/// the specifics of the runtime. They can then be made to be agnostic over specific formats +/// of data like extrinsics, allowing for them to continue syncing the network through upgrades +/// to even the core data structures. +pub mod opaque { + use sp_std::prelude::*; + use sp_runtime::impl_opaque_keys; + use super::Aura; + + pub use unique_runtime_common::types::*; + + impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } + } +} + +/// This runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!(RUNTIME_NAME), + impl_name: create_runtime_str!(RUNTIME_NAME), + authoring_version: 1, + spec_version: 917004, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 0, +}; + +#[derive(codec::Encode, codec::Decode)] +pub enum XCMPMessage { + /// Transfer tokens to the given account from the Parachain account. + TransferToken(XAccountId, XBalance), +} + +/// 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(), + } +} + +type NegativeImbalance = >::NegativeImbalance; + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(mut fees_then_tips: impl Iterator) { + if let Some(fees) = fees_then_tips.next() { + // for fees, 100% to treasury + let mut split = fees.ration(100, 0); + if let Some(tips) = fees_then_tips.next() { + // for tips, if any, 100% to treasury + tips.ration_merge_into(100, 0, &mut split); + } + Treasury::on_unbalanced(split.0); + // Author::on_unbalanced(split.1); + } + } +} + +parameter_types! { + pub const BlockHashCount: BlockNumber = 2400; + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + 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 Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 255; +} + +parameter_types! { + pub const ChainId: u64 = 8881; +} + +pub struct FixedFee; +impl FeeCalculator for FixedFee { + fn min_gas_price() -> U256 { + MIN_GAS_PRICE.into() + } +} + +// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case +// (contract, which only writes a lot of data), +// approximating on top of our real store write weight +parameter_types! { + pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / ::DbWeight::get().write; + pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000; + pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get(); +} + +/// Limiting EVM execution to 50% of block for substrate users and management tasks +/// EVM transaction consumes more weight than substrate's, so we can't rely on them being +/// scheduled fairly +const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50); +parameter_types! { + pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get()); +} + +pub enum FixedGasWeightMapping {} +impl GasWeightMapping for FixedGasWeightMapping { + fn gas_to_weight(gas: u64) -> Weight { + gas.saturating_mul(WeightPerGas::get()) + } + fn weight_to_gas(weight: Weight) -> u64 { + weight / WeightPerGas::get() + } +} + +impl pallet_evm::Config for Runtime { + type BlockGasLimit = BlockGasLimit; + type FeeCalculator = FixedFee; + type GasWeightMapping = FixedGasWeightMapping; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = EnsureAddressTruncated; + type WithdrawOrigin = EnsureAddressTruncated; + type AddressMapping = HashedAddressMapping; + type PrecompilesType = (); + type PrecompilesValue = (); + type Currency = Balances; + type Event = Event; + type OnMethodCall = ( + pallet_evm_migration::OnMethodCall, + pallet_unique::UniqueErcSupport, + pallet_evm_contract_helpers::HelpersOnMethodCall, + ); + type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate; + type ChainId = ChainId; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = pallet_evm_transaction_payment::OnChargeTransaction; + type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack; + type FindAuthor = EthereumFindAuthor; +} + +impl pallet_evm_migration::Config for Runtime { + type WeightInfo = pallet_evm_migration::weights::SubstrateWeight; +} + +pub struct EthereumFindAuthor(core::marker::PhantomData); +impl> FindAuthor for EthereumFindAuthor { + fn find_author<'a, I>(digests: I) -> Option + where + I: 'a + IntoIterator, + { + if let Some(author_index) = F::find_author(digests) { + let authority_id = Aura::authorities()[author_index as usize].clone(); + return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24])); + } + None + } +} + +impl pallet_ethereum::Config for Runtime { + type Event = Event; + type StateRoot = pallet_ethereum::IntermediateStateRoot; +} + +impl pallet_randomness_collective_flip::Config for Runtime {} + +impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The basic call filter to use in dispatchable. + type BaseCallFilter = Everything; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block. + type BlockWeights = RuntimeBlockWeights; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The weight of database operations that the runtime can invoke. + 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 = AccountIdLookup; + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// What to do if a new account is created. + type OnNewAccount = (); + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + /// The ubiquitous origin type. + type Origin = Origin; + /// This type is being generated by `construct_runtime!`. + type PalletInfo = PalletInfo; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = frame_system::weights::SubstrateWeight; + /// Version of the runtime. + type Version = Version; + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} + +impl pallet_timestamp::Config for Runtime { + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + // pub const ExistentialDeposit: u128 = 500; + pub const ExistentialDeposit: u128 = 0; + pub const MaxLocks: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = Treasury; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; +} + +pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE +} + +/* +parameter_types! { + pub TombstoneDeposit: Balance = deposit( + 1, + sp_std::mem::size_of::> as u32, + ); + pub DepositPerContract: Balance = TombstoneDeposit::get(); + pub const DepositPerStorageByte: Balance = deposit(0, 1); + pub const DepositPerStorageItem: Balance = deposit(1, 0); + pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS); + pub const SurchargeReward: Balance = 150 * MILLIUNIQUE; + pub const SignedClaimHandicap: u32 = 2; + pub const MaxDepth: u32 = 32; + pub const MaxValueSize: u32 = 16 * 1024; + pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb + // The lazy deletion runs inside on_initialize. + pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * + RuntimeBlockWeights::get().max_block; + // The weight needed for decoding the queue should be less or equal than a fifth + // of the overall weight dedicated to the lazy deletion. + pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / ( + ::WeightInfo::on_initialize_per_queue_item(1) - + ::WeightInfo::on_initialize_per_queue_item(0) + )) / 5) as u32; + pub Schedule: pallet_contracts::Schedule = Default::default(); +} + +impl pallet_contracts::Config for Runtime { + type Time = Timestamp; + type Randomness = RandomnessCollectiveFlip; + type Currency = Balances; + type Event = Event; + type RentPayment = (); + type SignedClaimHandicap = SignedClaimHandicap; + type TombstoneDeposit = TombstoneDeposit; + type DepositPerContract = DepositPerContract; + type DepositPerStorageByte = DepositPerStorageByte; + type DepositPerStorageItem = DepositPerStorageItem; + type RentFraction = RentFraction; + type SurchargeReward = SurchargeReward; + type WeightPrice = pallet_transaction_payment::Pallet; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type ChainExtension = NFTExtension; + type DeletionQueueDepth = DeletionQueueDepth; + type DeletionWeightLimit = DeletionWeightLimit; + type Schedule = Schedule; + type CallStack = [pallet_contracts::Frame; 31]; +} +*/ + +parameter_types! { + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +/// Linear implementor of `WeightToFeePolynomial` +pub struct LinearFee(sp_std::marker::PhantomData); + +impl WeightToFeePolynomial for LinearFee +where + T: BaseArithmetic + From + Copy + Unsigned, +{ + type Balance = T; + + fn polynomial() -> WeightToFeeCoefficients { + smallvec!(WeightToFeeCoefficient { + // Targeting 0.1 Unique per NFT transfer + coeff_integer: WEIGHT_TO_FEE_COEFF.into(), + coeff_frac: Perbill::zero(), + negative: false, + degree: 1, + }) + } +} + +impl pallet_transaction_payment::Config for Runtime { + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type TransactionByteFee = TransactionByteFee; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = LinearFee; + type FeeMultiplierUpdate = (); +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 1 * UNIQUE; + pub const ProposalBondMaximum: Balance = 1000 * UNIQUE; + pub const SpendPeriod: BlockNumber = 5 * MINUTES; + pub const Burn: Permill = Permill::from_percent(0); + pub const TipCountdown: BlockNumber = 1 * DAYS; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: Balance = 1 * UNIQUE; + pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE; + pub const BountyDepositBase: Balance = 1 * UNIQUE; + pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS; + pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry"); + pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS; + pub const MaximumReasonLength: u32 = 16384; + pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); + pub const BountyValueMinimum: Balance = 5 * UNIQUE; + pub const MaxApprovals: u32 = 100; +} + +impl pallet_treasury::Config for Runtime { + type PalletId = TreasuryModuleId; + type Currency = Balances; + type ApproveOrigin = EnsureRoot; + type RejectOrigin = EnsureRoot; + type Event = Event; + type OnSlash = (); + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type ProposalBondMaximum = ProposalBondMaximum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = (); + type SpendFunds = (); + type WeightInfo = pallet_treasury::weights::SubstrateWeight; + type MaxApprovals = MaxApprovals; +} + +impl pallet_sudo::Config for Runtime { + type Event = Event; + type Call = Call; +} + +pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider + for RelayChainBlockNumberProvider +{ + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + cumulus_pallet_parachain_system::Pallet::::validation_data() + .map(|d| d.relay_parent_number) + .unwrap_or_default() + } +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 10 * UNIQUE; + pub const MaxVestingSchedules: u32 = 28; +} + +impl orml_vesting::Config for Runtime { + type Event = Event; + type Currency = pallet_balances::Pallet; + type MinVestedTransfer = MinVestedTransfer; + type VestedTransferOrigin = EnsureSigned; + type WeightInfo = (); + type MaxVestingSchedules = MaxVestingSchedules; + type BlockNumberProvider = RelayChainBlockNumberProvider; +} + +parameter_types! { + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + type Event = Event; + type SelfParaId = parachain_info::Pallet; + type OnSystemEvent = (); + // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent< + // MaxDownwardMessageWeight, + // XcmExecutor, + // Call, + // >; + type OutboundXcmpMessageSource = XcmpQueue; + type DmpMessageHandler = DmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type XcmpMessageHandler = XcmpQueue; +} + +impl parachain_info::Config for Runtime {} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Polkadot; + pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).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`. + ParentIsPreset, + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +pub struct OnlySelfCurrency; +impl> MatchesFungible for OnlySelfCurrency { + fn matches_fungible(a: &MultiAsset) -> Option { + match (&a.id, &a.fun) { + (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount), + _ => None, + } + } +} + +/// 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: + OnlySelfCurrency, + // 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; + // 1200 UNIQUEs buy 1 second of weight. + pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE); + pub const MaxInstructions: u32 = 100; + pub const MaxAuthorities: u32 = 100_000; +} + +match_type! { + pub type ParentOrParentsUnitPlurality: impl Contains = { + MultiLocation { parents: 1, interior: Here } | + MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } + }; +} + +pub type Barrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + AllowUnpaidExecutionFrom, + // ^^^ Parent & its unit plurality gets free execution +); + +pub struct UsingOnlySelfCurrencyComponents< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, +>( + Weight, + Currency::Balance, + PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, +); +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > WeightTrader + for UsingOnlySelfCurrencyComponents +{ + fn new() -> Self { + Self(0, Zero::zero(), PhantomData) + } + + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { + let amount = WeightToFee::calc(&weight); + let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; + + // location to this parachain through relay chain + let option1: xcm::v1::AssetId = Concrete(MultiLocation { + parents: 1, + interior: X1(Parachain(ParachainInfo::parachain_id().into())), + }); + // direct location + let option2: xcm::v1::AssetId = Concrete(MultiLocation { + parents: 0, + interior: Here, + }); + + let required = if payment.fungible.contains_key(&option1) { + (option1, u128_amount).into() + } else if payment.fungible.contains_key(&option2) { + (option2, u128_amount).into() + } else { + (Concrete(MultiLocation::default()), u128_amount).into() + }; + + let unused = payment + .checked_sub(required) + .map_err(|_| XcmError::TooExpensive)?; + self.0 = self.0.saturating_add(weight); + self.1 = self.1.saturating_add(amount); + Ok(unused) + } + + fn refund_weight(&mut self, weight: Weight) -> Option { + let weight = weight.min(self.0); + let amount = WeightToFee::calc(&weight); + self.0 -= weight; + self.1 = self.1.saturating_sub(amount); + let amount: u128 = amount.saturated_into(); + if amount > 0 { + Some((AssetId::get(), amount).into()) + } else { + None + } + } +} +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > Drop + for UsingOnlySelfCurrencyComponents +{ + fn drop(&mut self) { + OnUnbalanced::on_unbalanced(Currency::issue(self.1)); + } +} + +pub struct XcmConfig; +impl Config for XcmConfig { + type Call = Call; + type XcmSender = XcmRouter; + // How to withdraw and deposit an asset. + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type IsReserve = NativeAsset; + type IsTeleporter = (); // Teleportation is disabled + type LocationInverter = LocationInverter; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = UsingOnlySelfCurrencyComponents< + IdentityFee, + RelayLocation, + AccountId, + Balances, + (), + >; + type ResponseHandler = (); // Don't handle responses for now. + type SubscriptionService = PolkadotXcm; + + type AssetTrap = PolkadotXcm; + type AssetClaims = PolkadotXcm; +} + +// parameter_types! { +// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; +// } + +/// 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_evm_coder_substrate::Config for Runtime { + type EthereumTransactionSender = pallet_ethereum::Pallet; + type GasWeightMapping = FixedGasWeightMapping; +} + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type LocationInverter = LocationInverter; + type Origin = Origin; + type Call = Call; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ParachainSystem; + type VersionWrapper = (); + type ExecuteOverweightOrigin = frame_system::EnsureRoot; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; +} + +impl pallet_aura::Config for Runtime { + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account(); + pub const CollectionCreationPrice: Balance = 2 * UNIQUE; +} + +impl pallet_common::Config for Runtime { + type Event = Event; + type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; + type EvmAddressMapping = HashedAddressMapping; + type CrossAccountId = pallet_common::account::BasicCrossAccountId; + + type Currency = Balances; + type CollectionCreationPrice = CollectionCreationPrice; + type TreasuryAccountId = TreasuryAccountId; +} + +impl pallet_fungible::Config for Runtime { + type WeightInfo = pallet_fungible::weights::SubstrateWeight; +} +impl pallet_refungible::Config for Runtime { + type WeightInfo = pallet_refungible::weights::SubstrateWeight; +} +impl pallet_nonfungible::Config for Runtime { + type WeightInfo = pallet_nonfungible::weights::SubstrateWeight; +} + +impl pallet_unique::Config for Runtime { + type Event = Event; + type WeightInfo = pallet_unique::weights::SubstrateWeight; +} + +parameter_types! { + pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied +} + +/// Used for the pallet inflation +impl pallet_inflation::Config for Runtime { + type Currency = Balances; + type TreasuryAccountId = TreasuryAccountId; + type InflationBlockInterval = InflationBlockInterval; + type BlockNumberProvider = RelayChainBlockNumberProvider; +} + +// parameter_types! { +// pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) * +// RuntimeBlockWeights::get().max_block; +// pub const MaxScheduledPerBlock: u32 = 50; +// } + +type EvmSponsorshipHandler = ( + pallet_unique::UniqueEthSponsorshipHandler, + pallet_evm_contract_helpers::HelpersContractSponsoring, +); +type SponsorshipHandler = ( + pallet_unique::UniqueSponsorshipHandler, + //pallet_contract_helpers::ContractSponsorshipHandler, + pallet_evm_transaction_payment::BridgeSponsorshipHandler, +); + +// impl pallet_unq_scheduler::Config for Runtime { +// type Event = Event; +// type Origin = Origin; +// type PalletsOrigin = OriginCaller; +// type Call = Call; +// type MaximumWeight = MaximumSchedulerWeight; +// type ScheduleOrigin = EnsureSigned; +// type MaxScheduledPerBlock = MaxScheduledPerBlock; +// type SponsorshipHandler = SponsorshipHandler; +// type WeightInfo = (); +// } + +impl pallet_evm_transaction_payment::Config for Runtime { + type EvmSponsorshipHandler = EvmSponsorshipHandler; + type Currency = Balances; + type EvmAddressMapping = HashedAddressMapping; + type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; +} + +impl pallet_charge_transaction::Config for Runtime { + type SponsorshipHandler = SponsorshipHandler; +} + +// impl pallet_contract_helpers::Config for Runtime { +// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; +// } + +parameter_types! { + // 0x842899ECF380553E8a4de75bF534cdf6fBF64049 + pub const HelpersContractAddress: H160 = H160([ + 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49, + ]); +} + +impl pallet_evm_contract_helpers::Config for Runtime { + type ContractAddress = HelpersContractAddress; + type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned} = 20, + ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21, + + Aura: pallet_aura::{Pallet, Config} = 22, + AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23, + + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 30, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 34, + Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event} = 35, + System: frame_system::{Pallet, Call, Storage, Config, Event} = 36, + Vesting: orml_vesting::{Pallet, Storage, Call, Event, Config} = 37, + // Vesting: pallet_vesting::{Pallet, Call, Config, Storage, Event} = 37, + // Contracts: pallet_contracts::{Pallet, Call, Storage, Event} = 38, + + // XCM helpers. + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 50, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin} = 51, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 52, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 53, + + // Unique Pallets + Inflation: pallet_inflation::{Pallet, Call, Storage} = 60, + Unique: pallet_unique::{Pallet, Call, Storage, Event} = 61, + // Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event} = 62, + // free = 63 + Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64, + // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65, + Common: pallet_common::{Pallet, Storage, Event} = 66, + Fungible: pallet_fungible::{Pallet, Storage} = 67, + Refungible: pallet_refungible::{Pallet, Storage} = 68, + Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69, + + // Frontier + EVM: pallet_evm::{Pallet, Config, Call, Storage, Event} = 100, + Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101, + + EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150, + EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151, + EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152, + EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153, + } +); + +pub struct TransactionConverter; + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } +} + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) + .expect("Encoded extrinsic is always valid") + } +} + +/// 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, + // system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_charge_transaction::ChargeTransactionPayment, + //pallet_contract_helpers::ContractHelpersExtension, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + fp_self_contained::UncheckedExtrinsic; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsReversedWithSystemFirst, +>; + +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } +} + +impl fp_self_contained::SelfContainedCall for Call { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + Call::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + Call::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option { + match self { + Call::Ethereum(call) => call.validate_self_contained(info), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + ) -> Option> { + match self { + Call::Ethereum(call) => call.pre_dispatch_self_contained(info), + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch( + Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)), + )), + _ => None, + } + } +} + +macro_rules! dispatch_unique_runtime { + ($collection:ident.$method:ident($($name:ident),*)) => {{ + use pallet_unique::dispatch::Dispatched; + + let collection = Dispatched::dispatch(>::try_get($collection)?); + let dispatch = collection.as_dyn(); + + Ok(dispatch.$method($($name),*)) + }}; +} + +impl_common_runtime_apis!(); + +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, +); --- a/runtime/src/lib.rs +++ /dev/null @@ -1,1592 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network 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. - -// Unique Network 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 Unique Network. If not, see . - -//! The Substrate Node Template 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 = "1024"] -#![allow(clippy::from_over_into, clippy::identity_op)] -#![allow(clippy::fn_to_numeric_cast_with_truncation)] -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); - -use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160}; -use sp_runtime::DispatchError; -// #[cfg(any(feature = "std", test))] -// pub use sp_runtime::BuildStorage; - -use sp_runtime::{ - Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys, - traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify, - AccountIdConversion, Zero, - }, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiSignature, RuntimeAppPublic, -}; - -use sp_std::prelude::*; - -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; -pub use pallet_transaction_payment::{ - Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo, -}; -// A few exports that help ease life for downstream crates. -pub use pallet_balances::Call as BalancesCall; -pub use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping, Runner}; -pub use frame_support::{ - construct_runtime, match_type, - dispatch::DispatchResult, - PalletId, parameter_types, StorageValue, ConsensusEngineId, - traits::{ - tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything, - Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier, - OnUnbalanced, Randomness, FindAuthor, - }, - weights::{ - constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, - DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight, - WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, - }, -}; -use up_data_structs::*; -// use pallet_contracts::weights::WeightInfo; -// #[cfg(any(feature = "std", test))] -use frame_system::{ - self as frame_system, EnsureRoot, EnsureSigned, - limits::{BlockWeights, BlockLength}, -}; -use sp_arithmetic::{ - traits::{BaseArithmetic, Unsigned}, -}; -use smallvec::smallvec; -use codec::{Encode, Decode}; -use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall}; -use fp_rpc::TransactionStatus; -use sp_runtime::{ - traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating}, - transaction_validity::TransactionValidityError, - SaturatedConversion, -}; - -// pub use pallet_timestamp::Call as TimestampCall; -pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; - -// Polkadot imports -use pallet_xcm::XcmPassthrough; -use polkadot_parachain::primitives::Sibling; -use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*}; -use xcm_builder::{ - AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, - EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser, - RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, - ParentIsPreset, -}; -use xcm_executor::{Config, XcmExecutor, Assets}; -use sp_std::{marker::PhantomData}; - -use xcm::latest::{ - // Xcm, - AssetId::{Concrete}, - Fungibility::Fungible as XcmFungible, - MultiAsset, - Error as XcmError, -}; -use xcm_executor::traits::{MatchesFungible, WeightTrader}; -//use xcm_executor::traits::MatchesFungible; -use sp_runtime::traits::CheckedConversion; - -// mod chain_extension; -// use crate::chain_extension::{NFTExtension, Imbalance}; - -/// An index to a block. -pub type BlockNumber = u32; - -/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. -pub type Signature = 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 IdentifyAccount>::AccountId; - -pub type CrossAccountId = pallet_common::account::BasicCrossAccountId; - -/// The type for looking up accounts. We don't expect more than 4 billion of them, but you -/// never know... -pub type AccountIndex = u32; - -/// 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; - -/// Digest item type. -pub type DigestItem = generic::DigestItem; - -/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know -/// the specifics of the runtime. They can then be made to be agnostic over specific formats -/// of data like extrinsics, allowing for them to continue syncing the network through upgrades -/// to even the core data structures. -pub mod opaque { - use super::*; - - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; - - /// Opaque block type. - pub type Block = generic::Block; - - pub type SessionHandlers = (); - - impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - } - } -} - -/// This runtime version. -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("opal"), - impl_name: create_runtime_str!("opal"), - authoring_version: 1, - spec_version: 917004, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 0, -}; - -pub const MILLISECS_PER_BLOCK: u64 = 12000; - -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -// These time units are defined in number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - -parameter_types! { - pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS; -} - -#[derive(codec::Encode, codec::Decode)] -pub enum XCMPMessage { - /// Transfer tokens to the given account from the Parachain account. - TransferToken(XAccountId, XBalance), -} - -/// 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(), - } -} - -type NegativeImbalance = >::NegativeImbalance; - -pub struct DealWithFees; -impl OnUnbalanced for DealWithFees { - fn on_unbalanceds(mut fees_then_tips: impl Iterator) { - if let Some(fees) = fees_then_tips.next() { - // for fees, 100% to treasury - let mut split = fees.ration(100, 0); - if let Some(tips) = fees_then_tips.next() { - // for tips, if any, 100% to treasury - tips.ration_merge_into(100, 0, &mut split); - } - Treasury::on_unbalanced(split.0); - // Author::on_unbalanced(split.1); - } - } -} - -/// 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 = WEIGHT_PER_SECOND / 2; - -parameter_types! { - pub const BlockHashCount: BlockNumber = 2400; - pub RuntimeBlockLength: BlockLength = - BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; - 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 Version: RuntimeVersion = VERSION; - pub const SS58Prefix: u8 = 42; -} - -/* -8880 - Unique -8881 - Quartz -8882 - Opal -*/ -parameter_types! { - pub const ChainId: u64 = 8882; -} - -pub struct FixedFee; -impl FeeCalculator for FixedFee { - fn min_gas_price() -> U256 { - // Targeting 0.15 UNQ per transfer - 1_018_751_825_264u64.into() - } -} - -// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case -// (contract, which only writes a lot of data), -// approximating on top of our real store write weight -parameter_types! { - pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / ::DbWeight::get().write; - pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000; - pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get(); -} - -/// Limiting EVM execution to 50% of block for substrate users and management tasks -/// EVM transaction consumes more weight than substrate's, so we can't rely on them being -/// scheduled fairly -const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50); -parameter_types! { - pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get()); -} - -pub enum FixedGasWeightMapping {} -impl GasWeightMapping for FixedGasWeightMapping { - fn gas_to_weight(gas: u64) -> Weight { - gas.saturating_mul(WeightPerGas::get()) - } - fn weight_to_gas(weight: Weight) -> u64 { - weight / WeightPerGas::get() - } -} - -impl pallet_evm::Config for Runtime { - type BlockGasLimit = BlockGasLimit; - type FeeCalculator = FixedFee; - type GasWeightMapping = FixedGasWeightMapping; - type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; - type CallOrigin = EnsureAddressTruncated; - type WithdrawOrigin = EnsureAddressTruncated; - type AddressMapping = HashedAddressMapping; - type PrecompilesType = (); - type PrecompilesValue = (); - type Currency = Balances; - type Event = Event; - type OnMethodCall = ( - pallet_evm_migration::OnMethodCall, - pallet_unique::UniqueErcSupport, - pallet_evm_contract_helpers::HelpersOnMethodCall, - ); - type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate; - type ChainId = ChainId; - type Runner = pallet_evm::runner::stack::Runner; - type OnChargeTransaction = pallet_evm_transaction_payment::OnChargeTransaction; - type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack; - type FindAuthor = EthereumFindAuthor; -} - -impl pallet_evm_migration::Config for Runtime { - type WeightInfo = pallet_evm_migration::weights::SubstrateWeight; -} - -pub struct EthereumFindAuthor(core::marker::PhantomData); -impl> FindAuthor for EthereumFindAuthor { - fn find_author<'a, I>(digests: I) -> Option - where - I: 'a + IntoIterator, - { - if let Some(author_index) = F::find_author(digests) { - let authority_id = Aura::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24])); - } - None - } -} - -impl pallet_ethereum::Config for Runtime { - type Event = Event; - type StateRoot = pallet_ethereum::IntermediateStateRoot; -} - -impl pallet_randomness_collective_flip::Config for Runtime {} - -impl frame_system::Config for Runtime { - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The basic call filter to use in dispatchable. - type BaseCallFilter = Everything; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// The maximum length of a block (in bytes). - type BlockLength = RuntimeBlockLength; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block. - type BlockWeights = RuntimeBlockWeights; - /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; - /// The weight of database operations that the runtime can invoke. - 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 = AccountIdLookup; - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// What to do if a new account is created. - type OnNewAccount = (); - type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; - /// The ubiquitous origin type. - type Origin = Origin; - /// This type is being generated by `construct_runtime!`. - type PalletInfo = PalletInfo; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = SS58Prefix; - /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = frame_system::weights::SubstrateWeight; - /// Version of the runtime. - type Version = Version; - type MaxConsumers = ConstU32<16>; -} - -parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; -} - -impl pallet_timestamp::Config for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - -parameter_types! { - // pub const ExistentialDeposit: u128 = 500; - pub const ExistentialDeposit: u128 = 0; - pub const MaxLocks: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type MaxLocks = MaxLocks; - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type Event = Event; - type DustRemoval = Treasury; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; -} - -pub const MICROUNIQUE: Balance = 1_000_000_000_000; -pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE; -pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE; -pub const UNIQUE: Balance = 100 * CENTIUNIQUE; - -pub const fn deposit(items: u32, bytes: u32) -> Balance { - items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE -} - -/* -parameter_types! { - pub TombstoneDeposit: Balance = deposit( - 1, - sp_std::mem::size_of::> as u32, - ); - pub DepositPerContract: Balance = TombstoneDeposit::get(); - pub const DepositPerStorageByte: Balance = deposit(0, 1); - pub const DepositPerStorageItem: Balance = deposit(1, 0); - pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS); - pub const SurchargeReward: Balance = 150 * MILLIUNIQUE; - pub const SignedClaimHandicap: u32 = 2; - pub const MaxDepth: u32 = 32; - pub const MaxValueSize: u32 = 16 * 1024; - pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb - // The lazy deletion runs inside on_initialize. - pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * - RuntimeBlockWeights::get().max_block; - // The weight needed for decoding the queue should be less or equal than a fifth - // of the overall weight dedicated to the lazy deletion. - pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / ( - ::WeightInfo::on_initialize_per_queue_item(1) - - ::WeightInfo::on_initialize_per_queue_item(0) - )) / 5) as u32; - pub Schedule: pallet_contracts::Schedule = Default::default(); -} - -impl pallet_contracts::Config for Runtime { - type Time = Timestamp; - type Randomness = RandomnessCollectiveFlip; - type Currency = Balances; - type Event = Event; - type RentPayment = (); - type SignedClaimHandicap = SignedClaimHandicap; - type TombstoneDeposit = TombstoneDeposit; - type DepositPerContract = DepositPerContract; - type DepositPerStorageByte = DepositPerStorageByte; - type DepositPerStorageItem = DepositPerStorageItem; - type RentFraction = RentFraction; - type SurchargeReward = SurchargeReward; - type WeightPrice = pallet_transaction_payment::Pallet; - type WeightInfo = pallet_contracts::weights::SubstrateWeight; - type ChainExtension = NFTExtension; - type DeletionQueueDepth = DeletionQueueDepth; - type DeletionWeightLimit = DeletionWeightLimit; - type Schedule = Schedule; - type CallStack = [pallet_contracts::Frame; 31]; -} -*/ - -parameter_types! { - pub const TransactionByteFee: Balance = 501 * MICROUNIQUE; // Targeting 0.1 Unique per NFT transfer - /// This value increases the priority of `Operational` transactions by adding - /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. - pub const OperationalFeeMultiplier: u8 = 5; -} - -/// Linear implementor of `WeightToFeePolynomial` -pub struct LinearFee(sp_std::marker::PhantomData); - -impl WeightToFeePolynomial for LinearFee -where - T: BaseArithmetic + From + Copy + Unsigned, -{ - type Balance = T; - - fn polynomial() -> WeightToFeeCoefficients { - smallvec!(WeightToFeeCoefficient { - // Targeting 0.1 Unique per NFT transfer - coeff_integer: 142_688_000u32.into(), - coeff_frac: Perbill::zero(), - negative: false, - degree: 1, - }) - } -} - -impl pallet_transaction_payment::Config for Runtime { - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type TransactionByteFee = TransactionByteFee; - type OperationalFeeMultiplier = OperationalFeeMultiplier; - type WeightToFee = LinearFee; - type FeeMultiplierUpdate = (); -} - -parameter_types! { - pub const ProposalBond: Permill = Permill::from_percent(5); - pub const ProposalBondMinimum: Balance = 1 * UNIQUE; - pub const ProposalBondMaximum: Balance = 1000 * UNIQUE; - pub const SpendPeriod: BlockNumber = 5 * MINUTES; - pub const Burn: Permill = Permill::from_percent(0); - pub const TipCountdown: BlockNumber = 1 * DAYS; - pub const TipFindersFee: Percent = Percent::from_percent(20); - pub const TipReportDepositBase: Balance = 1 * UNIQUE; - pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE; - pub const BountyDepositBase: Balance = 1 * UNIQUE; - pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS; - pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry"); - pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS; - pub const MaximumReasonLength: u32 = 16384; - pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); - pub const BountyValueMinimum: Balance = 5 * UNIQUE; - pub const MaxApprovals: u32 = 100; -} - -impl pallet_treasury::Config for Runtime { - type PalletId = TreasuryModuleId; - type Currency = Balances; - type ApproveOrigin = EnsureRoot; - type RejectOrigin = EnsureRoot; - type Event = Event; - type OnSlash = (); - type ProposalBond = ProposalBond; - type ProposalBondMinimum = ProposalBondMinimum; - type ProposalBondMaximum = ProposalBondMaximum; - type SpendPeriod = SpendPeriod; - type Burn = Burn; - type BurnDestination = (); - type SpendFunds = (); - type WeightInfo = pallet_treasury::weights::SubstrateWeight; - type MaxApprovals = MaxApprovals; -} - -impl pallet_sudo::Config for Runtime { - type Event = Event; - type Call = Call; -} - -pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); - -impl BlockNumberProvider - for RelayChainBlockNumberProvider -{ - type BlockNumber = BlockNumber; - - fn current_block_number() -> Self::BlockNumber { - cumulus_pallet_parachain_system::Pallet::::validation_data() - .map(|d| d.relay_parent_number) - .unwrap_or_default() - } -} - -parameter_types! { - pub const MinVestedTransfer: Balance = 10 * UNIQUE; - pub const MaxVestingSchedules: u32 = 28; -} - -impl orml_vesting::Config for Runtime { - type Event = Event; - type Currency = pallet_balances::Pallet; - type MinVestedTransfer = MinVestedTransfer; - type VestedTransferOrigin = EnsureSigned; - type WeightInfo = (); - type MaxVestingSchedules = MaxVestingSchedules; - type BlockNumberProvider = RelayChainBlockNumberProvider; -} - -parameter_types! { - pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; - pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; -} - -impl cumulus_pallet_parachain_system::Config for Runtime { - type Event = Event; - type SelfParaId = parachain_info::Pallet; - type OnSystemEvent = (); - // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent< - // MaxDownwardMessageWeight, - // XcmExecutor, - // Call, - // >; - type OutboundXcmpMessageSource = XcmpQueue; - type DmpMessageHandler = DmpQueue; - type ReservedDmpWeight = ReservedDmpWeight; - type ReservedXcmpWeight = ReservedXcmpWeight; - type XcmpMessageHandler = XcmpQueue; -} - -impl parachain_info::Config for Runtime {} - -impl cumulus_pallet_aura_ext::Config for Runtime {} - -parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); - pub const RelayNetwork: NetworkId = NetworkId::Polkadot; - pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); - pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).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`. - ParentIsPreset, - // Sibling parachain origins convert to AccountId via the `ParaId::into`. - SiblingParachainConvertsVia, - // Straight up local `AccountId32` origins just alias directly to `AccountId`. - AccountId32Aliases, -); - -pub struct OnlySelfCurrency; -impl> MatchesFungible for OnlySelfCurrency { - fn matches_fungible(a: &MultiAsset) -> Option { - match (&a.id, &a.fun) { - (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount), - _ => None, - } - } -} - -/// 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: - OnlySelfCurrency, - // 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; - // 1200 UNIQUEs buy 1 second of weight. - pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE); - pub const MaxInstructions: u32 = 100; - pub const MaxAuthorities: u32 = 100_000; -} - -match_type! { - pub type ParentOrParentsUnitPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } - }; -} - -pub type Barrier = ( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom, - AllowUnpaidExecutionFrom, - // ^^^ Parent & its unit plurality gets free execution -); - -pub struct UsingOnlySelfCurrencyComponents< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, ->( - Weight, - Currency::Balance, - PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, -); -impl< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, - > WeightTrader - for UsingOnlySelfCurrencyComponents -{ - fn new() -> Self { - Self(0, Zero::zero(), PhantomData) - } - - fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { - let amount = WeightToFee::calc(&weight); - let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; - - // location to this parachain through relay chain - let option1: xcm::v1::AssetId = Concrete(MultiLocation { - parents: 1, - interior: X1(Parachain(ParachainInfo::parachain_id().into())), - }); - // direct location - let option2: xcm::v1::AssetId = Concrete(MultiLocation { - parents: 0, - interior: Here, - }); - - let required = if payment.fungible.contains_key(&option1) { - (option1, u128_amount).into() - } else if payment.fungible.contains_key(&option2) { - (option2, u128_amount).into() - } else { - (Concrete(MultiLocation::default()), u128_amount).into() - }; - - let unused = payment - .checked_sub(required) - .map_err(|_| XcmError::TooExpensive)?; - self.0 = self.0.saturating_add(weight); - self.1 = self.1.saturating_add(amount); - Ok(unused) - } - - fn refund_weight(&mut self, weight: Weight) -> Option { - let weight = weight.min(self.0); - let amount = WeightToFee::calc(&weight); - self.0 -= weight; - self.1 = self.1.saturating_sub(amount); - let amount: u128 = amount.saturated_into(); - if amount > 0 { - Some((AssetId::get(), amount).into()) - } else { - None - } - } -} -impl< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, - > Drop - for UsingOnlySelfCurrencyComponents -{ - fn drop(&mut self) { - OnUnbalanced::on_unbalanced(Currency::issue(self.1)); - } -} - -pub struct XcmConfig; -impl Config for XcmConfig { - type Call = Call; - type XcmSender = XcmRouter; - // How to withdraw and deposit an asset. - type AssetTransactor = LocalAssetTransactor; - type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = NativeAsset; - type IsTeleporter = (); // Teleportation is disabled - type LocationInverter = LocationInverter; - type Barrier = Barrier; - type Weigher = FixedWeightBounds; - type Trader = UsingOnlySelfCurrencyComponents< - IdentityFee, - RelayLocation, - AccountId, - Balances, - (), - >; - type ResponseHandler = (); // Don't handle responses for now. - type SubscriptionService = PolkadotXcm; - - type AssetTrap = PolkadotXcm; - type AssetClaims = PolkadotXcm; -} - -// parameter_types! { -// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; -// } - -/// 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_evm_coder_substrate::Config for Runtime { - type EthereumTransactionSender = pallet_ethereum::Pallet; - type GasWeightMapping = FixedGasWeightMapping; -} - -impl pallet_xcm::Config for Runtime { - type Event = Event; - type SendXcmOrigin = EnsureXcmOrigin; - type XcmRouter = XcmRouter; - type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Everything; - type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Everything; - type XcmReserveTransferFilter = Everything; - type Weigher = FixedWeightBounds; - type LocationInverter = LocationInverter; - type Origin = Origin; - type Call = Call; - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; -} - -impl cumulus_pallet_xcm::Config for Runtime { - type Event = Event; - type XcmExecutor = XcmExecutor; -} - -impl cumulus_pallet_xcmp_queue::Config for Runtime { - type Event = Event; - type XcmExecutor = XcmExecutor; - type ChannelInfo = ParachainSystem; - type VersionWrapper = (); - type ExecuteOverweightOrigin = frame_system::EnsureRoot; - type ControllerOrigin = EnsureRoot; - type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; -} - -impl cumulus_pallet_dmp_queue::Config for Runtime { - type Event = Event; - type XcmExecutor = XcmExecutor; - type ExecuteOverweightOrigin = frame_system::EnsureRoot; -} - -impl pallet_aura::Config for Runtime { - type AuthorityId = AuraId; - type DisabledValidators = (); - type MaxAuthorities = MaxAuthorities; -} - -parameter_types! { - pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account(); - pub const CollectionCreationPrice: Balance = 2 * UNIQUE; -} - -impl pallet_common::Config for Runtime { - type Event = Event; - type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; - type EvmAddressMapping = HashedAddressMapping; - type CrossAccountId = pallet_common::account::BasicCrossAccountId; - - type Currency = Balances; - type CollectionCreationPrice = CollectionCreationPrice; - type TreasuryAccountId = TreasuryAccountId; -} - -impl pallet_fungible::Config for Runtime { - type WeightInfo = pallet_fungible::weights::SubstrateWeight; -} -impl pallet_refungible::Config for Runtime { - type WeightInfo = pallet_refungible::weights::SubstrateWeight; -} -impl pallet_nonfungible::Config for Runtime { - type WeightInfo = pallet_nonfungible::weights::SubstrateWeight; -} - -impl pallet_unique::Config for Runtime { - type Event = Event; - type WeightInfo = pallet_unique::weights::SubstrateWeight; -} - -parameter_types! { - pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied -} - -/// Used for the pallet inflation -impl pallet_inflation::Config for Runtime { - type Currency = Balances; - type TreasuryAccountId = TreasuryAccountId; - type InflationBlockInterval = InflationBlockInterval; - type BlockNumberProvider = RelayChainBlockNumberProvider; -} - -// parameter_types! { -// pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) * -// RuntimeBlockWeights::get().max_block; -// pub const MaxScheduledPerBlock: u32 = 50; -// } - -type EvmSponsorshipHandler = ( - pallet_unique::UniqueEthSponsorshipHandler, - pallet_evm_contract_helpers::HelpersContractSponsoring, -); -type SponsorshipHandler = ( - pallet_unique::UniqueSponsorshipHandler, - //pallet_contract_helpers::ContractSponsorshipHandler, - pallet_evm_transaction_payment::BridgeSponsorshipHandler, -); - -// impl pallet_unq_scheduler::Config for Runtime { -// type Event = Event; -// type Origin = Origin; -// type PalletsOrigin = OriginCaller; -// type Call = Call; -// type MaximumWeight = MaximumSchedulerWeight; -// type ScheduleOrigin = EnsureSigned; -// type MaxScheduledPerBlock = MaxScheduledPerBlock; -// type SponsorshipHandler = SponsorshipHandler; -// type WeightInfo = (); -// } - -impl pallet_evm_transaction_payment::Config for Runtime { - type EvmSponsorshipHandler = EvmSponsorshipHandler; - type Currency = Balances; - type EvmAddressMapping = HashedAddressMapping; - type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; -} - -impl pallet_charge_transaction::Config for Runtime { - type SponsorshipHandler = SponsorshipHandler; -} - -// impl pallet_contract_helpers::Config for Runtime { -// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; -// } - -parameter_types! { - // 0x842899ECF380553E8a4de75bF534cdf6fBF64049 - pub const HelpersContractAddress: H160 = H160([ - 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49, - ]); -} - -impl pallet_evm_contract_helpers::Config for Runtime { - type ContractAddress = HelpersContractAddress; - type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; -} - -construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = opaque::Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned} = 20, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21, - - Aura: pallet_aura::{Pallet, Config} = 22, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23, - - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 30, - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 34, - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event} = 35, - System: frame_system::{Pallet, Call, Storage, Config, Event} = 36, - Vesting: orml_vesting::{Pallet, Storage, Call, Event, Config} = 37, - // Vesting: pallet_vesting::{Pallet, Call, Config, Storage, Event} = 37, - // Contracts: pallet_contracts::{Pallet, Call, Storage, Event} = 38, - - // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 50, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin} = 51, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 52, - DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 53, - - // Unique Pallets - Inflation: pallet_inflation::{Pallet, Call, Storage} = 60, - Unique: pallet_unique::{Pallet, Call, Storage, Event} = 61, - // Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event} = 62, - // free = 63 - Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64, - // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65, - Common: pallet_common::{Pallet, Storage, Event} = 66, - Fungible: pallet_fungible::{Pallet, Storage} = 67, - Refungible: pallet_refungible::{Pallet, Storage} = 68, - Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69, - - // Frontier - EVM: pallet_evm::{Pallet, Config, Call, Storage, Event} = 100, - Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101, - - EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150, - EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151, - EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152, - EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153, - } -); - -pub struct TransactionConverter; - -impl fp_rpc::ConvertTransaction for TransactionConverter { - fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { - UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ) - } -} - -impl fp_rpc::ConvertTransaction for TransactionConverter { - fn convert_transaction( - &self, - transaction: pallet_ethereum::Transaction, - ) -> opaque::UncheckedExtrinsic { - let extrinsic = UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ); - let encoded = extrinsic.encode(); - opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) - .expect("Encoded extrinsic is always valid") - } -} - -/// 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, - // system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_charge_transaction::ChargeTransactionPayment, - //pallet_contract_helpers::ContractHelpersExtension, -); -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = - fp_self_contained::UncheckedExtrinsic; -/// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic; -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsReversedWithSystemFirst, ->; - -impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - } -} - -impl fp_self_contained::SelfContainedCall for Call { - type SignedInfo = H160; - - fn is_self_contained(&self) -> bool { - match self { - Call::Ethereum(call) => call.is_self_contained(), - _ => false, - } - } - - fn check_self_contained(&self) -> Option> { - match self { - Call::Ethereum(call) => call.check_self_contained(), - _ => None, - } - } - - fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option { - match self { - Call::Ethereum(call) => call.validate_self_contained(info), - _ => None, - } - } - - fn pre_dispatch_self_contained( - &self, - info: &Self::SignedInfo, - ) -> Option> { - match self { - Call::Ethereum(call) => call.pre_dispatch_self_contained(info), - _ => None, - } - } - - fn apply_self_contained( - self, - info: Self::SignedInfo, - ) -> Option>> { - match self { - call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch( - Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)), - )), - _ => None, - } - } -} - -macro_rules! dispatch_unique_runtime { - ($collection:ident.$method:ident($($name:ident),*)) => {{ - use pallet_unique::dispatch::Dispatched; - - let collection = Dispatched::dispatch(>::try_get($collection)?); - let dispatch = collection.as_dyn(); - - Ok(dispatch.$method($($name),*)) - }}; -} -impl_runtime_apis! { - impl up_rpc::UniqueApi - for Runtime - { - fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result, DispatchError> { - dispatch_unique_runtime!(collection.account_tokens(account)) - } - fn token_exists(collection: CollectionId, token: TokenId) -> Result { - dispatch_unique_runtime!(collection.token_exists(token)) - } - - fn token_owner(collection: CollectionId, token: TokenId) -> Result, DispatchError> { - dispatch_unique_runtime!(collection.token_owner(token)) - } - fn const_metadata(collection: CollectionId, token: TokenId) -> Result, DispatchError> { - dispatch_unique_runtime!(collection.const_metadata(token)) - } - fn variable_metadata(collection: CollectionId, token: TokenId) -> Result, DispatchError> { - dispatch_unique_runtime!(collection.variable_metadata(token)) - } - - fn collection_tokens(collection: CollectionId) -> Result { - dispatch_unique_runtime!(collection.collection_tokens()) - } - fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result { - dispatch_unique_runtime!(collection.account_balance(account)) - } - fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result { - dispatch_unique_runtime!(collection.balance(account, token)) - } - fn allowance( - collection: CollectionId, - sender: CrossAccountId, - spender: CrossAccountId, - token: TokenId, - ) -> Result { - dispatch_unique_runtime!(collection.allowance(sender, spender, token)) - } - - fn eth_contract_code(account: H160) -> Option> { - >::get_code(&account) - .or_else(|| >::get_code(&account)) - .or_else(|| >::get_code(&account)) - } - fn adminlist(collection: CollectionId) -> Result, DispatchError> { - Ok(>::adminlist(collection)) - } - fn allowlist(collection: CollectionId) -> Result, DispatchError> { - Ok(>::allowlist(collection)) - } - fn allowed(collection: CollectionId, user: CrossAccountId) -> Result { - Ok(>::allowed(collection, user)) - } - fn last_token_id(collection: CollectionId) -> Result { - dispatch_unique_runtime!(collection.last_token_id()) - } - fn collection_by_id(collection: CollectionId) -> Result>, DispatchError> { - Ok(>::get(collection)) - } - fn collection_stats() -> Result { - Ok(>::collection_stats()) - } - } - - 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_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - } - - 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) - } - - // fn random_seed() -> ::Hash { - // RandomnessCollectiveFlip::random_seed().0 - // } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl fp_rpc::EthereumRuntimeRPCApi for Runtime { - fn chain_id() -> u64 { - ::ChainId::get() - } - - fn account_basic(address: H160) -> EVMAccount { - EVM::account_basic(&address) - } - - fn gas_price() -> U256 { - ::FeeCalculator::min_gas_price() - } - - fn account_code_at(address: H160) -> Vec { - EVM::account_codes(address) - } - - fn author() -> H160 { - >::find_author() - } - - fn storage_at(address: H160, index: U256) -> H256 { - let mut tmp = [0u8; 32]; - index.to_big_endian(&mut tmp); - EVM::account_storages(address, H256::from_slice(&tmp[..])) - } - - #[allow(clippy::redundant_closure)] - fn call( - from: H160, - to: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - - ::Runner::call( - from, - to, - data, - value, - gas_limit.low_u64(), - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - config.as_ref().unwrap_or_else(|| ::config()), - ).map_err(|err| err.into()) - } - - #[allow(clippy::redundant_closure)] - fn create( - from: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - - ::Runner::create( - from, - data, - value, - gas_limit.low_u64(), - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - config.as_ref().unwrap_or_else(|| ::config()), - ).map_err(|err| err.into()) - } - - fn current_transaction_statuses() -> Option> { - Ethereum::current_transaction_statuses() - } - - fn current_block() -> Option { - Ethereum::current_block() - } - - fn current_receipts() -> Option> { - Ethereum::current_receipts() - } - - fn current_all() -> ( - Option, - Option>, - Option> - ) { - ( - Ethereum::current_block(), - Ethereum::current_receipts(), - Ethereum::current_transaction_statuses() - ) - } - - fn extrinsic_filter(xts: Vec<::Extrinsic>) -> Vec { - xts.into_iter().filter_map(|xt| match xt.0.function { - Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction), - _ => None - }).collect() - } - - fn elasticity() -> Option { - None - } - } - - impl sp_session::SessionKeys for Runtime { - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - } - - 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().to_vec() - } - } - - impl cumulus_primitives_core::CollectCollationInfo for Runtime { - fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { - ParachainSystem::collect_collation_info(header) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - } - - /* - impl pallet_contracts_rpc_runtime_api::ContractsApi - for Runtime - { - fn call( - origin: AccountId, - dest: AccountId, - value: Balance, - gas_limit: u64, - input_data: Vec, - ) -> pallet_contracts_primitives::ContractExecResult { - Contracts::bare_call(origin, dest, value, gas_limit, input_data, false) - } - - fn instantiate( - origin: AccountId, - endowment: Balance, - gas_limit: u64, - code: pallet_contracts_primitives::Code, - data: Vec, - salt: Vec, - ) -> pallet_contracts_primitives::ContractInstantiateResult - { - Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, false) - } - - fn get_storage( - address: AccountId, - key: [u8; 32], - ) -> pallet_contracts_primitives::GetStorageResult { - Contracts::get_storage(address, key) - } - - fn rent_projection( - address: AccountId, - ) -> pallet_contracts_primitives::RentProjectionResult { - Contracts::rent_projection(address) - } - } - */ - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - - let mut list = Vec::::new(); - - list_benchmark!(list, extra, pallet_evm_migration, EvmMigration); - list_benchmark!(list, extra, pallet_unique, Unique); - list_benchmark!(list, extra, pallet_inflation, Inflation); - list_benchmark!(list, extra, pallet_fungible, Fungible); - list_benchmark!(list, extra, pallet_refungible, Refungible); - list_benchmark!(list, extra, pallet_nonfungible, Nonfungible); - // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate); - - let storage_info = AllPalletsReversedWithSystemFirst::storage_info(); - - return (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; - - let allowlist: 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(), - ]; - - let mut batches = Vec::::new(); - let params = (&config, &allowlist); - - add_benchmark!(params, batches, pallet_evm_migration, EvmMigration); - add_benchmark!(params, batches, pallet_unique, Unique); - add_benchmark!(params, batches, pallet_inflation, Inflation); - add_benchmark!(params, batches, pallet_fungible, Fungible); - add_benchmark!(params, batches, pallet_refungible, Refungible); - add_benchmark!(params, batches, pallet_nonfungible, Nonfungible); - // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate); - - 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, -); --- /dev/null +++ b/runtime/unique/Cargo.toml @@ -0,0 +1,410 @@ +################################################################################ +# Package + +[package] +authors = ['Unique Network '] +build = 'build.rs' +description = 'Unique Runtime' +edition = '2021' +homepage = 'https://unique.network' +license = 'GPLv3' +name = 'unique-runtime' +repository = 'https://github.com/UniqueNetwork/unique-chain' +version = '0.9.17' + +[package.metadata.docs.rs] +targets = ['x86_64-unknown-linux-gnu'] + +[features] +default = ['std'] +runtime-benchmarks = [ + 'hex-literal', + 'frame-benchmarking', + 'frame-support/runtime-benchmarks', + 'frame-system-benchmarking', + 'frame-system/runtime-benchmarks', + 'pallet-ethereum/runtime-benchmarks', + 'pallet-evm-migration/runtime-benchmarks', + 'pallet-evm-coder-substrate/runtime-benchmarks', + 'pallet-balances/runtime-benchmarks', + 'pallet-timestamp/runtime-benchmarks', + 'pallet-common/runtime-benchmarks', + 'pallet-fungible/runtime-benchmarks', + 'pallet-refungible/runtime-benchmarks', + 'pallet-nonfungible/runtime-benchmarks', + 'pallet-unique/runtime-benchmarks', + 'pallet-inflation/runtime-benchmarks', + 'pallet-xcm/runtime-benchmarks', + 'sp-runtime/runtime-benchmarks', + 'xcm-builder/runtime-benchmarks', +] +std = [ + 'codec/std', + 'cumulus-pallet-aura-ext/std', + 'cumulus-pallet-parachain-system/std', + 'cumulus-pallet-xcm/std', + 'cumulus-pallet-xcmp-queue/std', + 'cumulus-primitives-core/std', + 'cumulus-primitives-utility/std', + 'frame-executive/std', + 'frame-support/std', + 'frame-system/std', + 'frame-system-rpc-runtime-api/std', + 'pallet-aura/std', + 'pallet-balances/std', + # 'pallet-contracts/std', + # 'pallet-contracts-primitives/std', + # 'pallet-contracts-rpc-runtime-api/std', + # 'pallet-contract-helpers/std', + 'pallet-randomness-collective-flip/std', + 'pallet-sudo/std', + 'pallet-timestamp/std', + 'pallet-transaction-payment/std', + 'pallet-transaction-payment-rpc-runtime-api/std', + 'pallet-treasury/std', + # 'pallet-vesting/std', + 'pallet-evm/std', + 'pallet-evm-migration/std', + 'pallet-evm-contract-helpers/std', + 'pallet-evm-transaction-payment/std', + 'pallet-evm-coder-substrate/std', + 'pallet-ethereum/std', + 'pallet-base-fee/std', + 'fp-rpc/std', + 'up-rpc/std', + 'up-evm-mapping/std', + 'fp-self-contained/std', + 'parachain-info/std', + 'serde', + 'pallet-inflation/std', + 'pallet-common/std', + 'pallet-fungible/std', + 'pallet-refungible/std', + 'pallet-nonfungible/std', + 'pallet-unique/std', + 'pallet-unq-scheduler/std', + 'pallet-charge-transaction/std', + 'up-data-structs/std', + 'sp-api/std', + 'sp-block-builder/std', + "sp-consensus-aura/std", + 'sp-core/std', + 'sp-inherents/std', + 'sp-io/std', + 'sp-offchain/std', + 'sp-runtime/std', + 'sp-session/std', + 'sp-std/std', + 'sp-transaction-pool/std', + 'sp-version/std', + 'xcm/std', + 'xcm-builder/std', + 'xcm-executor/std', + 'unique-runtime-common/std', + + "orml-vesting/std", +] +limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] + +################################################################################ +# Substrate Dependencies + +[dependencies.codec] +default-features = false +features = ['derive'] +package = 'parity-scale-codec' +version = '2.3.0' + +[dependencies.frame-benchmarking] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +optional = true +branch = 'polkadot-v0.9.17' + +[dependencies.frame-executive] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-support] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system-benchmarking] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +optional = true +branch = 'polkadot-v0.9.17' + +[dependencies.frame-system-rpc-runtime-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.hex-literal] +optional = true +version = '0.3.3' + +[dependencies.serde] +default-features = false +features = ['derive'] +optional = true +version = '1.0.130' + +[dependencies.pallet-aura] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-balances] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +# Contracts specific packages +# [dependencies.pallet-contracts] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +# [dependencies.pallet-contracts-primitives] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +# [dependencies.pallet-contracts-rpc-runtime-api] +# git = 'https://github.com/paritytech/substrate.git' +# default-features = false +# branch = 'polkadot-v0.9.17' +# version = '4.0.0-dev' + +[dependencies.pallet-randomness-collective-flip] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-sudo] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-timestamp] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-transaction-payment] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-transaction-payment-rpc-runtime-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.pallet-treasury] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +# [dependencies.pallet-vesting] +# default-features = false +# git = 'https://github.com/paritytech/substrate.git' +# branch = 'polkadot-v0.9.17' + +[dependencies.sp-arithmetic] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-api] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-block-builder] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-core] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-consensus-aura] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-inherents] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-io] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-offchain] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-runtime] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-session] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-std] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-transaction-pool] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.sp-version] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' + +[dependencies.smallvec] +version = '1.6.1' + +################################################################################ +# Cumulus dependencies + +[dependencies.parachain-info] +default-features = false +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' + +[dependencies.cumulus-pallet-aura-ext] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-parachain-system] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-core] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-xcm] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-dmp-queue] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-pallet-xcmp-queue] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-utility] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +[dependencies.cumulus-primitives-timestamp] +git = 'https://github.com/uniqueNetwork/cumulus.git' +branch = 'polkadot-v0.9.17' +default-features = false + +################################################################################ +# Polkadot dependencies + +[dependencies.polkadot-parachain] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm-builder] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.xcm-executor] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.pallet-xcm] +git = 'https://github.com/paritytech/polkadot' +branch = 'release-v0.9.17' +default-features = false + +[dependencies.orml-vesting] +git = 'https://github.com/UniqueNetwork/open-runtime-module-library' +branch = 'unique-polkadot-v0.9.17' +version = "0.4.1-dev" +default-features = false + +################################################################################ +# local dependencies + +[dependencies] +unique-runtime-common = { path = "../common", default-features = false } +scale-info = { version = "1.0.0", default-features = false, features = [ + "derive", +] } +derivative = "2.2.0" +pallet-unique = { path = '../../pallets/unique', default-features = false } +up-rpc = { path = "../../primitives/rpc", default-features = false } +up-evm-mapping = { path = "../../primitives/evm-mapping", default-features = false } +pallet-inflation = { path = '../../pallets/inflation', default-features = false } +up-data-structs = { path = '../../primitives/data-structs', default-features = false } +pallet-common = { default-features = false, path = "../../pallets/common" } +pallet-fungible = { default-features = false, path = "../../pallets/fungible" } +pallet-refungible = { default-features = false, path = "../../pallets/refungible" } +pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" } +pallet-unq-scheduler = { path = '../../pallets/scheduler', default-features = false } +# pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' } +pallet-charge-transaction = { git = "https://github.com/UniqueNetwork/pallet-sponsoring", branch = 'polkadot-v0.9.17', package = "pallet-template-transaction-payment", default-features = false, version = '3.0.0' } +pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false } +pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false } +pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false } +pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } +fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" } + +################################################################################ +# Build Dependencies + +[build-dependencies.substrate-wasm-builder] +git = 'https://github.com/paritytech/substrate.git' +branch = 'polkadot-v0.9.17' --- /dev/null +++ b/runtime/unique/build.rs @@ -0,0 +1,9 @@ +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} --- /dev/null +++ b/runtime/unique/src/lib.rs @@ -0,0 +1,1140 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network 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. + +// Unique Network 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 Unique Network. If not, see . + +//! The Substrate Node Template 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 = "1024"] +#![allow(clippy::from_over_into, clippy::identity_op)] +#![allow(clippy::fn_to_numeric_cast_with_truncation)] +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use sp_api::impl_runtime_apis; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160}; +use sp_runtime::DispatchError; +// #[cfg(any(feature = "std", test))] +// pub use sp_runtime::BuildStorage; + +use sp_runtime::{ + Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, RuntimeAppPublic, +}; + +use sp_std::prelude::*; + +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +pub use pallet_transaction_payment::{ + Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo, +}; +// A few exports that help ease life for downstream crates. +pub use pallet_balances::Call as BalancesCall; +pub use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping, Runner}; +pub use frame_support::{ + construct_runtime, match_type, + dispatch::DispatchResult, + PalletId, parameter_types, StorageValue, ConsensusEngineId, + traits::{ + tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything, + Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier, + OnUnbalanced, Randomness, FindAuthor, + }, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight, + WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + }, +}; +use up_data_structs::*; +// use pallet_contracts::weights::WeightInfo; +// #[cfg(any(feature = "std", test))] +use frame_system::{ + self as frame_system, EnsureRoot, EnsureSigned, + limits::{BlockWeights, BlockLength}, +}; +use sp_arithmetic::{ + traits::{BaseArithmetic, Unsigned}, +}; +use smallvec::smallvec; +use codec::{Encode, Decode}; +use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall}; +use fp_rpc::TransactionStatus; +use sp_runtime::{ + traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating}, + transaction_validity::TransactionValidityError, + SaturatedConversion, +}; + +// pub use pallet_timestamp::Call as TimestampCall; + +// Polkadot imports +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*}; +use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, + EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + ParentIsPreset, +}; +use xcm_executor::{Config, XcmExecutor, Assets}; +use sp_std::{marker::PhantomData}; + +use xcm::latest::{ + // Xcm, + AssetId::{Concrete}, + Fungibility::Fungible as XcmFungible, + MultiAsset, + Error as XcmError, +}; +use xcm_executor::traits::{MatchesFungible, WeightTrader}; +//use xcm_executor::traits::MatchesFungible; +use sp_runtime::traits::CheckedConversion; + +use unique_runtime_common::{impl_common_runtime_apis, types::*, constants::*}; + +pub const RUNTIME_NAME: &str = "Unique"; + +type CrossAccountId = pallet_common::account::BasicCrossAccountId; + +impl RuntimeInstance for Runtime { + type CrossAccountId = self::CrossAccountId; + + type TransactionConverter = self::TransactionConverter; + + fn get_transaction_converter() -> TransactionConverter { + TransactionConverter + } +} + +/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know +/// the specifics of the runtime. They can then be made to be agnostic over specific formats +/// of data like extrinsics, allowing for them to continue syncing the network through upgrades +/// to even the core data structures. +pub mod opaque { + use sp_std::prelude::*; + use sp_runtime::impl_opaque_keys; + use super::Aura; + + pub use unique_runtime_common::types::*; + + impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } + } +} + +/// This runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!(RUNTIME_NAME), + impl_name: create_runtime_str!(RUNTIME_NAME), + authoring_version: 1, + spec_version: 917004, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 0, +}; + +#[derive(codec::Encode, codec::Decode)] +pub enum XCMPMessage { + /// Transfer tokens to the given account from the Parachain account. + TransferToken(XAccountId, XBalance), +} + +/// 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(), + } +} + +type NegativeImbalance = >::NegativeImbalance; + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(mut fees_then_tips: impl Iterator) { + if let Some(fees) = fees_then_tips.next() { + // for fees, 100% to treasury + let mut split = fees.ration(100, 0); + if let Some(tips) = fees_then_tips.next() { + // for tips, if any, 100% to treasury + tips.ration_merge_into(100, 0, &mut split); + } + Treasury::on_unbalanced(split.0); + // Author::on_unbalanced(split.1); + } + } +} + +parameter_types! { + pub const BlockHashCount: BlockNumber = 2400; + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + 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 Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u16 = 7391; +} + +parameter_types! { + pub const ChainId: u64 = 8880; +} + +pub struct FixedFee; +impl FeeCalculator for FixedFee { + fn min_gas_price() -> U256 { + MIN_GAS_PRICE.into() + } +} + +// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case +// (contract, which only writes a lot of data), +// approximating on top of our real store write weight +parameter_types! { + pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / ::DbWeight::get().write; + pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000; + pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get(); +} + +/// Limiting EVM execution to 50% of block for substrate users and management tasks +/// EVM transaction consumes more weight than substrate's, so we can't rely on them being +/// scheduled fairly +const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50); +parameter_types! { + pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get()); +} + +pub enum FixedGasWeightMapping {} +impl GasWeightMapping for FixedGasWeightMapping { + fn gas_to_weight(gas: u64) -> Weight { + gas.saturating_mul(WeightPerGas::get()) + } + fn weight_to_gas(weight: Weight) -> u64 { + weight / WeightPerGas::get() + } +} + +impl pallet_evm::Config for Runtime { + type BlockGasLimit = BlockGasLimit; + type FeeCalculator = FixedFee; + type GasWeightMapping = FixedGasWeightMapping; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = EnsureAddressTruncated; + type WithdrawOrigin = EnsureAddressTruncated; + type AddressMapping = HashedAddressMapping; + type PrecompilesType = (); + type PrecompilesValue = (); + type Currency = Balances; + type Event = Event; + type OnMethodCall = ( + pallet_evm_migration::OnMethodCall, + pallet_unique::UniqueErcSupport, + pallet_evm_contract_helpers::HelpersOnMethodCall, + ); + type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate; + type ChainId = ChainId; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = pallet_evm_transaction_payment::OnChargeTransaction; + type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack; + type FindAuthor = EthereumFindAuthor; +} + +impl pallet_evm_migration::Config for Runtime { + type WeightInfo = pallet_evm_migration::weights::SubstrateWeight; +} + +pub struct EthereumFindAuthor(core::marker::PhantomData); +impl> FindAuthor for EthereumFindAuthor { + fn find_author<'a, I>(digests: I) -> Option + where + I: 'a + IntoIterator, + { + if let Some(author_index) = F::find_author(digests) { + let authority_id = Aura::authorities()[author_index as usize].clone(); + return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24])); + } + None + } +} + +impl pallet_ethereum::Config for Runtime { + type Event = Event; + type StateRoot = pallet_ethereum::IntermediateStateRoot; +} + +impl pallet_randomness_collective_flip::Config for Runtime {} + +impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The basic call filter to use in dispatchable. + type BaseCallFilter = Everything; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block. + type BlockWeights = RuntimeBlockWeights; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The weight of database operations that the runtime can invoke. + 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 = AccountIdLookup; + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// What to do if a new account is created. + type OnNewAccount = (); + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + /// The ubiquitous origin type. + type Origin = Origin; + /// This type is being generated by `construct_runtime!`. + type PalletInfo = PalletInfo; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = frame_system::weights::SubstrateWeight; + /// Version of the runtime. + type Version = Version; + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} + +impl pallet_timestamp::Config for Runtime { + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + // pub const ExistentialDeposit: u128 = 500; + pub const ExistentialDeposit: u128 = 0; + pub const MaxLocks: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = Treasury; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; +} + +pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE +} + +/* +parameter_types! { + pub TombstoneDeposit: Balance = deposit( + 1, + sp_std::mem::size_of::> as u32, + ); + pub DepositPerContract: Balance = TombstoneDeposit::get(); + pub const DepositPerStorageByte: Balance = deposit(0, 1); + pub const DepositPerStorageItem: Balance = deposit(1, 0); + pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS); + pub const SurchargeReward: Balance = 150 * MILLIUNIQUE; + pub const SignedClaimHandicap: u32 = 2; + pub const MaxDepth: u32 = 32; + pub const MaxValueSize: u32 = 16 * 1024; + pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb + // The lazy deletion runs inside on_initialize. + pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * + RuntimeBlockWeights::get().max_block; + // The weight needed for decoding the queue should be less or equal than a fifth + // of the overall weight dedicated to the lazy deletion. + pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / ( + ::WeightInfo::on_initialize_per_queue_item(1) - + ::WeightInfo::on_initialize_per_queue_item(0) + )) / 5) as u32; + pub Schedule: pallet_contracts::Schedule = Default::default(); +} + +impl pallet_contracts::Config for Runtime { + type Time = Timestamp; + type Randomness = RandomnessCollectiveFlip; + type Currency = Balances; + type Event = Event; + type RentPayment = (); + type SignedClaimHandicap = SignedClaimHandicap; + type TombstoneDeposit = TombstoneDeposit; + type DepositPerContract = DepositPerContract; + type DepositPerStorageByte = DepositPerStorageByte; + type DepositPerStorageItem = DepositPerStorageItem; + type RentFraction = RentFraction; + type SurchargeReward = SurchargeReward; + type WeightPrice = pallet_transaction_payment::Pallet; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type ChainExtension = NFTExtension; + type DeletionQueueDepth = DeletionQueueDepth; + type DeletionWeightLimit = DeletionWeightLimit; + type Schedule = Schedule; + type CallStack = [pallet_contracts::Frame; 31]; +} +*/ + +parameter_types! { + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +/// Linear implementor of `WeightToFeePolynomial` +pub struct LinearFee(sp_std::marker::PhantomData); + +impl WeightToFeePolynomial for LinearFee +where + T: BaseArithmetic + From + Copy + Unsigned, +{ + type Balance = T; + + fn polynomial() -> WeightToFeeCoefficients { + smallvec!(WeightToFeeCoefficient { + // Targeting 0.1 Unique per NFT transfer + coeff_integer: WEIGHT_TO_FEE_COEFF.into(), + coeff_frac: Perbill::zero(), + negative: false, + degree: 1, + }) + } +} + +impl pallet_transaction_payment::Config for Runtime { + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type TransactionByteFee = TransactionByteFee; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = LinearFee; + type FeeMultiplierUpdate = (); +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 1 * UNIQUE; + pub const ProposalBondMaximum: Balance = 1000 * UNIQUE; + pub const SpendPeriod: BlockNumber = 5 * MINUTES; + pub const Burn: Permill = Permill::from_percent(0); + pub const TipCountdown: BlockNumber = 1 * DAYS; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: Balance = 1 * UNIQUE; + pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE; + pub const BountyDepositBase: Balance = 1 * UNIQUE; + pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS; + pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry"); + pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS; + pub const MaximumReasonLength: u32 = 16384; + pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); + pub const BountyValueMinimum: Balance = 5 * UNIQUE; + pub const MaxApprovals: u32 = 100; +} + +impl pallet_treasury::Config for Runtime { + type PalletId = TreasuryModuleId; + type Currency = Balances; + type ApproveOrigin = EnsureRoot; + type RejectOrigin = EnsureRoot; + type Event = Event; + type OnSlash = (); + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type ProposalBondMaximum = ProposalBondMaximum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = (); + type SpendFunds = (); + type WeightInfo = pallet_treasury::weights::SubstrateWeight; + type MaxApprovals = MaxApprovals; +} + +impl pallet_sudo::Config for Runtime { + type Event = Event; + type Call = Call; +} + +pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider + for RelayChainBlockNumberProvider +{ + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + cumulus_pallet_parachain_system::Pallet::::validation_data() + .map(|d| d.relay_parent_number) + .unwrap_or_default() + } +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 10 * UNIQUE; + pub const MaxVestingSchedules: u32 = 28; +} + +impl orml_vesting::Config for Runtime { + type Event = Event; + type Currency = pallet_balances::Pallet; + type MinVestedTransfer = MinVestedTransfer; + type VestedTransferOrigin = EnsureSigned; + type WeightInfo = (); + type MaxVestingSchedules = MaxVestingSchedules; + type BlockNumberProvider = RelayChainBlockNumberProvider; +} + +parameter_types! { + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + type Event = Event; + type SelfParaId = parachain_info::Pallet; + type OnSystemEvent = (); + // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent< + // MaxDownwardMessageWeight, + // XcmExecutor, + // Call, + // >; + type OutboundXcmpMessageSource = XcmpQueue; + type DmpMessageHandler = DmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type XcmpMessageHandler = XcmpQueue; +} + +impl parachain_info::Config for Runtime {} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Polkadot; + pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).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`. + ParentIsPreset, + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +pub struct OnlySelfCurrency; +impl> MatchesFungible for OnlySelfCurrency { + fn matches_fungible(a: &MultiAsset) -> Option { + match (&a.id, &a.fun) { + (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount), + _ => None, + } + } +} + +/// 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: + OnlySelfCurrency, + // 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; + // 1200 UNIQUEs buy 1 second of weight. + pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE); + pub const MaxInstructions: u32 = 100; + pub const MaxAuthorities: u32 = 100_000; +} + +match_type! { + pub type ParentOrParentsUnitPlurality: impl Contains = { + MultiLocation { parents: 1, interior: Here } | + MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } + }; +} + +pub type Barrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + AllowUnpaidExecutionFrom, + // ^^^ Parent & its unit plurality gets free execution +); + +pub struct UsingOnlySelfCurrencyComponents< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, +>( + Weight, + Currency::Balance, + PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, +); +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > WeightTrader + for UsingOnlySelfCurrencyComponents +{ + fn new() -> Self { + Self(0, Zero::zero(), PhantomData) + } + + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { + let amount = WeightToFee::calc(&weight); + let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; + + // location to this parachain through relay chain + let option1: xcm::v1::AssetId = Concrete(MultiLocation { + parents: 1, + interior: X1(Parachain(ParachainInfo::parachain_id().into())), + }); + // direct location + let option2: xcm::v1::AssetId = Concrete(MultiLocation { + parents: 0, + interior: Here, + }); + + let required = if payment.fungible.contains_key(&option1) { + (option1, u128_amount).into() + } else if payment.fungible.contains_key(&option2) { + (option2, u128_amount).into() + } else { + (Concrete(MultiLocation::default()), u128_amount).into() + }; + + let unused = payment + .checked_sub(required) + .map_err(|_| XcmError::TooExpensive)?; + self.0 = self.0.saturating_add(weight); + self.1 = self.1.saturating_add(amount); + Ok(unused) + } + + fn refund_weight(&mut self, weight: Weight) -> Option { + let weight = weight.min(self.0); + let amount = WeightToFee::calc(&weight); + self.0 -= weight; + self.1 = self.1.saturating_sub(amount); + let amount: u128 = amount.saturated_into(); + if amount > 0 { + Some((AssetId::get(), amount).into()) + } else { + None + } + } +} +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > Drop + for UsingOnlySelfCurrencyComponents +{ + fn drop(&mut self) { + OnUnbalanced::on_unbalanced(Currency::issue(self.1)); + } +} + +pub struct XcmConfig; +impl Config for XcmConfig { + type Call = Call; + type XcmSender = XcmRouter; + // How to withdraw and deposit an asset. + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type IsReserve = NativeAsset; + type IsTeleporter = (); // Teleportation is disabled + type LocationInverter = LocationInverter; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = UsingOnlySelfCurrencyComponents< + IdentityFee, + RelayLocation, + AccountId, + Balances, + (), + >; + type ResponseHandler = (); // Don't handle responses for now. + type SubscriptionService = PolkadotXcm; + + type AssetTrap = PolkadotXcm; + type AssetClaims = PolkadotXcm; +} + +// parameter_types! { +// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; +// } + +/// 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_evm_coder_substrate::Config for Runtime { + type EthereumTransactionSender = pallet_ethereum::Pallet; + type GasWeightMapping = FixedGasWeightMapping; +} + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type LocationInverter = LocationInverter; + type Origin = Origin; + type Call = Call; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ParachainSystem; + type VersionWrapper = (); + type ExecuteOverweightOrigin = frame_system::EnsureRoot; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; +} + +impl pallet_aura::Config for Runtime { + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account(); + pub const CollectionCreationPrice: Balance = 2 * UNIQUE; +} + +impl pallet_common::Config for Runtime { + type Event = Event; + type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; + type EvmAddressMapping = HashedAddressMapping; + type CrossAccountId = pallet_common::account::BasicCrossAccountId; + + type Currency = Balances; + type CollectionCreationPrice = CollectionCreationPrice; + type TreasuryAccountId = TreasuryAccountId; +} + +impl pallet_fungible::Config for Runtime { + type WeightInfo = pallet_fungible::weights::SubstrateWeight; +} +impl pallet_refungible::Config for Runtime { + type WeightInfo = pallet_refungible::weights::SubstrateWeight; +} +impl pallet_nonfungible::Config for Runtime { + type WeightInfo = pallet_nonfungible::weights::SubstrateWeight; +} + +impl pallet_unique::Config for Runtime { + type Event = Event; + type WeightInfo = pallet_unique::weights::SubstrateWeight; +} + +parameter_types! { + pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied +} + +/// Used for the pallet inflation +impl pallet_inflation::Config for Runtime { + type Currency = Balances; + type TreasuryAccountId = TreasuryAccountId; + type InflationBlockInterval = InflationBlockInterval; + type BlockNumberProvider = RelayChainBlockNumberProvider; +} + +// parameter_types! { +// pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) * +// RuntimeBlockWeights::get().max_block; +// pub const MaxScheduledPerBlock: u32 = 50; +// } + +type EvmSponsorshipHandler = ( + pallet_unique::UniqueEthSponsorshipHandler, + pallet_evm_contract_helpers::HelpersContractSponsoring, +); +type SponsorshipHandler = ( + pallet_unique::UniqueSponsorshipHandler, + //pallet_contract_helpers::ContractSponsorshipHandler, + pallet_evm_transaction_payment::BridgeSponsorshipHandler, +); + +// impl pallet_unq_scheduler::Config for Runtime { +// type Event = Event; +// type Origin = Origin; +// type PalletsOrigin = OriginCaller; +// type Call = Call; +// type MaximumWeight = MaximumSchedulerWeight; +// type ScheduleOrigin = EnsureSigned; +// type MaxScheduledPerBlock = MaxScheduledPerBlock; +// type SponsorshipHandler = SponsorshipHandler; +// type WeightInfo = (); +// } + +impl pallet_evm_transaction_payment::Config for Runtime { + type EvmSponsorshipHandler = EvmSponsorshipHandler; + type Currency = Balances; + type EvmAddressMapping = HashedAddressMapping; + type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated; +} + +impl pallet_charge_transaction::Config for Runtime { + type SponsorshipHandler = SponsorshipHandler; +} + +// impl pallet_contract_helpers::Config for Runtime { +// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; +// } + +parameter_types! { + // 0x842899ECF380553E8a4de75bF534cdf6fBF64049 + pub const HelpersContractAddress: H160 = H160([ + 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49, + ]); +} + +impl pallet_evm_contract_helpers::Config for Runtime { + type ContractAddress = HelpersContractAddress; + type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned} = 20, + ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21, + + Aura: pallet_aura::{Pallet, Config} = 22, + AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23, + + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 30, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 34, + Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event} = 35, + System: frame_system::{Pallet, Call, Storage, Config, Event} = 36, + Vesting: orml_vesting::{Pallet, Storage, Call, Event, Config} = 37, + // Vesting: pallet_vesting::{Pallet, Call, Config, Storage, Event} = 37, + // Contracts: pallet_contracts::{Pallet, Call, Storage, Event} = 38, + + // XCM helpers. + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 50, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin} = 51, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 52, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 53, + + // Unique Pallets + Inflation: pallet_inflation::{Pallet, Call, Storage} = 60, + Unique: pallet_unique::{Pallet, Call, Storage, Event} = 61, + // Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event} = 62, + // free = 63 + Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64, + // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65, + Common: pallet_common::{Pallet, Storage, Event} = 66, + Fungible: pallet_fungible::{Pallet, Storage} = 67, + Refungible: pallet_refungible::{Pallet, Storage} = 68, + Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69, + + // Frontier + EVM: pallet_evm::{Pallet, Config, Call, Storage, Event} = 100, + Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101, + + EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150, + EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151, + EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152, + EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153, + } +); + +pub struct TransactionConverter; + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } +} + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) + .expect("Encoded extrinsic is always valid") + } +} + +/// 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, + // system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_charge_transaction::ChargeTransactionPayment, + //pallet_contract_helpers::ContractHelpersExtension, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + fp_self_contained::UncheckedExtrinsic; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsReversedWithSystemFirst, +>; + +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } +} + +impl fp_self_contained::SelfContainedCall for Call { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + Call::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + Call::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option { + match self { + Call::Ethereum(call) => call.validate_self_contained(info), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + ) -> Option> { + match self { + Call::Ethereum(call) => call.pre_dispatch_self_contained(info), + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch( + Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)), + )), + _ => None, + } + } +} + +macro_rules! dispatch_unique_runtime { + ($collection:ident.$method:ident($($name:ident),*)) => {{ + use pallet_unique::dispatch::Dispatched; + + let collection = Dispatched::dispatch(>::try_get($collection)?); + let dispatch = collection.as_dyn(); + + Ok(dispatch.$method($($name),*)) + }}; +} + +impl_common_runtime_apis!(); + +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, +);