difftreelog
refactor imporve runtime separation
in: master
48 files changed
client/rpc/Cargo.tomldiffbeforeafterboth--- a/client/rpc/Cargo.toml
+++ b/client/rpc/Cargo.toml
@@ -5,7 +5,6 @@
edition = "2021"
[dependencies]
-unique-runtime-common = { default-features = false, path = "../../runtime/common" }
pallet-common = { default-features = false, path = '../../pallets/common' }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
up-rpc = { path = "../../primitives/rpc" }
common-types/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/common-types/Cargo.toml
@@ -0,0 +1,50 @@
+[package]
+authors = ['Unique Network <support@uniquenetwork.io>']
+description = 'Unique Runtime Common'
+edition = '2021'
+homepage = 'https://unique.network'
+license = 'All Rights Reserved'
+name = 'common-types'
+repository = 'https://github.com/UniqueNetwork/unique-chain'
+version = '0.9.24'
+
+[features]
+default = ['std']
+std = [
+ 'sp-std/std',
+ 'sp-runtime/std',
+ 'sp-core/std',
+ 'sp-consensus-aura/std',
+ 'fp-rpc/std',
+ 'pallet-evm/std',
+]
+
+[dependencies.sp-std]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.sp-runtime]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.sp-core]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.sp-consensus-aura]
+default-features = false
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.24"
+
+[dependencies.fp-rpc]
+default-features = false
+git = "https://github.com/uniquenetwork/frontier"
+branch = "unique-polkadot-v0.9.24"
+
+[dependencies.pallet-evm]
+default-features = false
+git = "https://github.com/uniquenetwork/frontier"
+branch = "unique-polkadot-v0.9.24"
common-types/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/common-types/src/lib.rs
@@ -0,0 +1,86 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use sp_runtime::{
+ generic,
+ traits::{Verify, IdentifyAccount}, MultiSignature,
+};
+
+/// 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 {
+ pub use sp_runtime::{
+ generic,
+ traits::BlakeTwo256,
+ OpaqueExtrinsic as UncheckedExtrinsic
+ };
+
+ pub use super::{BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId};
+
+ /// Opaque block header type.
+ pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+
+ /// Opaque block type.
+ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+
+ pub trait RuntimeInstance {
+ type CrossAccountId: pallet_evm::account::CrossAccountId<sp_runtime::AccountId32>
+ + Send
+ + Sync
+ + 'static;
+
+ type TransactionConverter: fp_rpc::ConvertTransaction<UncheckedExtrinsic>
+ + Send
+ + Sync
+ + 'static;
+
+ fn get_transaction_converter() -> Self::TransactionConverter;
+ }
+}
+
+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 = <<Signature as Verify>::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;
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -253,9 +253,8 @@
################################################################################
# Local dependencies
-[dependencies.unique-runtime-common]
-default-features = false
-path = "../../runtime/common"
+[dependencies.common-types]
+path = "../../common-types"
[dependencies.unique-runtime]
path = '../../runtime/unique'
node/cli/src/chain_spec.rsdiffbeforeafterboth--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -23,7 +23,7 @@
use serde::{Deserialize, Serialize};
use serde_json::map::Map;
-use unique_runtime_common::types::*;
+use common_types::opaque::*;
#[cfg(feature = "unique-runtime")]
pub use unique_runtime as default_runtime;
node/cli/src/command.rsdiffbeforeafterboth--- a/node/cli/src/command.rs
+++ b/node/cli/src/command.rs
@@ -64,7 +64,7 @@
use sp_runtime::traits::{AccountIdConversion, Block as BlockT};
use std::{io::Write, net::SocketAddr, time::Duration};
-use unique_runtime_common::types::Block;
+use common_types::opaque::Block;
macro_rules! no_runtime_err {
($chain_name:expr) => {
node/cli/src/service.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// std18use std::sync::Arc;19use std::sync::Mutex;20use std::collections::BTreeMap;21use std::time::Duration;22use std::pin::Pin;23use fc_rpc_core::types::FeeHistoryCache;24use futures::{25 Stream, StreamExt,26 stream::select,27 task::{Context, Poll},28};29use tokio::time::Interval;3031use unique_rpc::overrides_handle;3233use serde::{Serialize, Deserialize};3435// Cumulus Imports36use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};37use cumulus_client_consensus_common::ParachainConsensus;38use cumulus_client_service::{39 prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,40};41use cumulus_client_cli::CollatorOptions;42use cumulus_client_network::BlockAnnounceValidator;43use cumulus_primitives_core::ParaId;44use cumulus_relay_chain_inprocess_interface::build_inprocess_relay_chain;45use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayChainResult};46use cumulus_relay_chain_rpc_interface::RelayChainRPCInterface;4748// Substrate Imports49use sc_client_api::ExecutorProvider;50use sc_executor::NativeElseWasmExecutor;51use sc_executor::NativeExecutionDispatch;52use sc_network::NetworkService;53use sc_service::{BasePath, Configuration, PartialComponents, Role, TaskManager};54use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};55use sp_keystore::SyncCryptoStorePtr;56use sp_runtime::traits::BlakeTwo256;57use substrate_prometheus_endpoint::Registry;58use sc_client_api::BlockchainEvents;5960use polkadot_service::CollatorPair;6162// Frontier Imports63use fc_rpc_core::types::FilterPool;64use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};6566use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};6768// RMRK69use up_data_structs::{70 RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,71 RmrkPartType, RmrkTheme,72};7374/// Unique native executor instance.75#[cfg(feature = "unique-runtime")]76pub struct UniqueRuntimeExecutor;7778#[cfg(feature = "quartz-runtime")]79/// Quartz native executor instance.80pub struct QuartzRuntimeExecutor;8182/// Opal native executor instance.83pub struct OpalRuntimeExecutor;8485#[cfg(feature = "unique-runtime")]86pub type DefaultRuntimeExecutor = UniqueRuntimeExecutor;8788#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]89pub type DefaultRuntimeExecutor = QuartzRuntimeExecutor;9091#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]92pub type DefaultRuntimeExecutor = OpalRuntimeExecutor;9394#[cfg(feature = "unique-runtime")]95impl NativeExecutionDispatch for UniqueRuntimeExecutor {96 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;9798 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {99 unique_runtime::api::dispatch(method, data)100 }101102 fn native_version() -> sc_executor::NativeVersion {103 unique_runtime::native_version()104 }105}106107#[cfg(feature = "quartz-runtime")]108impl NativeExecutionDispatch for QuartzRuntimeExecutor {109 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;110111 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {112 quartz_runtime::api::dispatch(method, data)113 }114115 fn native_version() -> sc_executor::NativeVersion {116 quartz_runtime::native_version()117 }118}119120impl NativeExecutionDispatch for OpalRuntimeExecutor {121 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;122123 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {124 opal_runtime::api::dispatch(method, data)125 }126127 fn native_version() -> sc_executor::NativeVersion {128 opal_runtime::native_version()129 }130}131132pub struct AutosealInterval {133 interval: Interval,134}135136impl AutosealInterval {137 pub fn new(config: &Configuration, interval: Duration) -> Self {138 let _tokio_runtime = config.tokio_handle.enter();139 let interval = tokio::time::interval(interval);140141 Self { interval }142 }143}144145impl Stream for AutosealInterval {146 type Item = tokio::time::Instant;147148 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {149 self.interval.poll_tick(cx).map(Some)150 }151}152153pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {154 let config_dir = config155 .base_path156 .as_ref()157 .map(|base_path| base_path.config_dir(config.chain_spec.id()))158 .unwrap_or_else(|| {159 BasePath::from_project("", "", "unique").config_dir(config.chain_spec.id())160 });161 let database_dir = config_dir.join("frontier").join("db");162163 Ok(Arc::new(fc_db::Backend::<Block>::new(164 &fc_db::DatabaseSettings {165 source: fc_db::DatabaseSource::RocksDb {166 path: database_dir,167 cache_size: 0,168 },169 },170 )?))171}172173type FullClient<RuntimeApi, ExecutorDispatch> =174 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;175type FullBackend = sc_service::TFullBackend<Block>;176type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;177178/// Starts a `ServiceBuilder` for a full service.179///180/// Use this macro if you don't actually need the full service, but just the builder in order to181/// be able to perform chain operations.182#[allow(clippy::type_complexity)]183pub fn new_partial<RuntimeApi, ExecutorDispatch, BIQ>(184 config: &Configuration,185 build_import_queue: BIQ,186) -> Result<187 PartialComponents<188 FullClient<RuntimeApi, ExecutorDispatch>,189 FullBackend,190 FullSelectChain,191 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,192 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,193 (194 Option<Telemetry>,195 Option<FilterPool>,196 Arc<fc_db::Backend<Block>>,197 Option<TelemetryWorkerHandle>,198 FeeHistoryCache,199 ),200 >,201 sc_service::Error,202>203where204 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,205 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>206 + Send207 + Sync208 + 'static,209 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,210 ExecutorDispatch: NativeExecutionDispatch + 'static,211 BIQ: FnOnce(212 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,213 &Configuration,214 Option<TelemetryHandle>,215 &TaskManager,216 ) -> Result<217 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,218 sc_service::Error,219 >,220{221 let _telemetry = config222 .telemetry_endpoints223 .clone()224 .filter(|x| !x.is_empty())225 .map(|endpoints| -> Result<_, sc_telemetry::Error> {226 let worker = TelemetryWorker::new(16)?;227 let telemetry = worker.handle().new_telemetry(endpoints);228 Ok((worker, telemetry))229 })230 .transpose()?;231232 let telemetry = config233 .telemetry_endpoints234 .clone()235 .filter(|x| !x.is_empty())236 .map(|endpoints| -> Result<_, sc_telemetry::Error> {237 let worker = TelemetryWorker::new(16)?;238 let telemetry = worker.handle().new_telemetry(endpoints);239 Ok((worker, telemetry))240 })241 .transpose()?;242243 let executor = NativeElseWasmExecutor::<ExecutorDispatch>::new(244 config.wasm_method,245 config.default_heap_pages,246 config.max_runtime_instances,247 config.runtime_cache_size,248 );249250 let (client, backend, keystore_container, task_manager) =251 sc_service::new_full_parts::<Block, RuntimeApi, _>(252 config,253 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),254 executor,255 )?;256 let client = Arc::new(client);257258 let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());259260 let telemetry = telemetry.map(|(worker, telemetry)| {261 task_manager262 .spawn_handle()263 .spawn("telemetry", None, worker.run());264 telemetry265 });266267 let select_chain = sc_consensus::LongestChain::new(backend.clone());268269 let transaction_pool = sc_transaction_pool::BasicPool::new_full(270 config.transaction_pool.clone(),271 config.role.is_authority().into(),272 config.prometheus_registry(),273 task_manager.spawn_essential_handle(),274 client.clone(),275 );276277 let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));278279 let frontier_backend = open_frontier_backend(config)?;280281 let import_queue = build_import_queue(282 client.clone(),283 config,284 telemetry.as_ref().map(|telemetry| telemetry.handle()),285 &task_manager,286 )?;287 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));288289 let params = PartialComponents {290 backend,291 client,292 import_queue,293 keystore_container,294 task_manager,295 transaction_pool,296 select_chain,297 other: (298 telemetry,299 filter_pool,300 frontier_backend,301 telemetry_worker_handle,302 fee_history_cache,303 ),304 };305306 Ok(params)307}308309async fn build_relay_chain_interface(310 polkadot_config: Configuration,311 parachain_config: &Configuration,312 telemetry_worker_handle: Option<TelemetryWorkerHandle>,313 task_manager: &mut TaskManager,314 collator_options: CollatorOptions,315 hwbench: Option<sc_sysinfo::HwBench>,316) -> RelayChainResult<(317 Arc<(dyn RelayChainInterface + 'static)>,318 Option<CollatorPair>,319)> {320 match collator_options.relay_chain_rpc_url {321 Some(relay_chain_url) => Ok((322 Arc::new(RelayChainRPCInterface::new(relay_chain_url).await?) as Arc<_>,323 None,324 )),325 None => build_inprocess_relay_chain(326 polkadot_config,327 parachain_config,328 telemetry_worker_handle,329 task_manager,330 hwbench,331 ),332 }333}334335/// Start a node with the given parachain `Configuration` and relay chain `Configuration`.336///337/// This is the actual implementation that is abstract over the executor and the runtime api.338#[sc_tracing::logging::prefix_logs_with("Parachain")]339async fn start_node_impl<Runtime, RuntimeApi, ExecutorDispatch, BIQ, BIC>(340 parachain_config: Configuration,341 polkadot_config: Configuration,342 collator_options: CollatorOptions,343 id: ParaId,344 build_import_queue: BIQ,345 build_consensus: BIC,346 hwbench: Option<sc_sysinfo::HwBench>,347) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>348where349 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,350 Runtime: RuntimeInstance + Send + Sync + 'static,351 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,352 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,353 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>354 + Send355 + Sync356 + 'static,357 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>358 + fp_rpc::EthereumRuntimeRPCApi<Block>359 + fp_rpc::ConvertTransactionRuntimeApi<Block>360 + sp_session::SessionKeys<Block>361 + sp_block_builder::BlockBuilder<Block>362 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>363 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>364 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>365 + rmrk_rpc::RmrkApi<366 Block,367 AccountId,368 RmrkCollectionInfo<AccountId>,369 RmrkInstanceInfo<AccountId>,370 RmrkResourceInfo,371 RmrkPropertyInfo,372 RmrkBaseInfo<AccountId>,373 RmrkPartType,374 RmrkTheme,375 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>376 + sp_api::Metadata<Block>377 + sp_offchain::OffchainWorkerApi<Block>378 + cumulus_primitives_core::CollectCollationInfo<Block>,379 ExecutorDispatch: NativeExecutionDispatch + 'static,380 BIQ: FnOnce(381 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,382 &Configuration,383 Option<TelemetryHandle>,384 &TaskManager,385 ) -> Result<386 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,387 sc_service::Error,388 >,389 BIC: FnOnce(390 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,391 Option<&Registry>,392 Option<TelemetryHandle>,393 &TaskManager,394 Arc<dyn RelayChainInterface>,395 Arc<sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>>,396 Arc<NetworkService<Block, Hash>>,397 SyncCryptoStorePtr,398 bool,399 ) -> Result<Box<dyn ParachainConsensus<Block>>, sc_service::Error>,400{401 if matches!(parachain_config.role, Role::Light) {402 return Err("Light client not supported!".into());403 }404405 let parachain_config = prepare_node_config(parachain_config);406407 let params =408 new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(¶chain_config, build_import_queue)?;409 let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =410 params.other;411412 let client = params.client.clone();413 let backend = params.backend.clone();414 let mut task_manager = params.task_manager;415416 let (relay_chain_interface, collator_key) = build_relay_chain_interface(417 polkadot_config,418 ¶chain_config,419 telemetry_worker_handle,420 &mut task_manager,421 collator_options.clone(),422 hwbench.clone(),423 )424 .await425 .map_err(|e| match e {426 RelayChainError::ServiceError(polkadot_service::Error::Sub(x)) => x,427 s => s.to_string().into(),428 })?;429430 let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id);431432 let force_authoring = parachain_config.force_authoring;433 let validator = parachain_config.role.is_authority();434 let prometheus_registry = parachain_config.prometheus_registry().cloned();435 let transaction_pool = params.transaction_pool.clone();436 let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue);437438 let (network, system_rpc_tx, start_network) =439 sc_service::build_network(sc_service::BuildNetworkParams {440 config: ¶chain_config,441 client: client.clone(),442 transaction_pool: transaction_pool.clone(),443 spawn_handle: task_manager.spawn_handle(),444 import_queue: import_queue.clone(),445 block_announce_validator_builder: Some(Box::new(|_| {446 Box::new(block_announce_validator)447 })),448 warp_sync: None,449 })?;450451 let rpc_client = client.clone();452 let rpc_pool = transaction_pool.clone();453 let select_chain = params.select_chain.clone();454 let rpc_network = network.clone();455456 let rpc_frontier_backend = frontier_backend.clone();457458 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(459 task_manager.spawn_handle(),460 overrides_handle::<_, _, Runtime>(client.clone()),461 50,462 50,463 prometheus_registry.clone(),464 ));465466 task_manager.spawn_essential_handle().spawn(467 "frontier-mapping-sync-worker",468 None,469 MappingSyncWorker::new(470 client.import_notification_stream(),471 Duration::new(6, 0),472 client.clone(),473 backend.clone(),474 frontier_backend.clone(),475 3,476 0,477 SyncStrategy::Normal,478 )479 .for_each(|()| futures::future::ready(())),480 );481482 let rpc_builder = Box::new(move |deny_unsafe, subscription_task_executor| {483 let full_deps = unique_rpc::FullDeps {484 backend: rpc_frontier_backend.clone(),485 deny_unsafe,486 client: rpc_client.clone(),487 pool: rpc_pool.clone(),488 graph: rpc_pool.pool().clone(),489 // TODO: Unhardcode490 enable_dev_signer: false,491 filter_pool: filter_pool.clone(),492 network: rpc_network.clone(),493 select_chain: select_chain.clone(),494 is_authority: validator,495 // TODO: Unhardcode496 max_past_logs: 10000,497 block_data_cache: block_data_cache.clone(),498 fee_history_cache: fee_history_cache.clone(),499 // TODO: Unhardcode500 fee_history_limit: 2048,501 };502503 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(504 full_deps,505 subscription_task_executor,506 )507 .map_err(Into::into)508 });509510 sc_service::spawn_tasks(sc_service::SpawnTasksParams {511 rpc_builder,512 client: client.clone(),513 transaction_pool: transaction_pool.clone(),514 task_manager: &mut task_manager,515 config: parachain_config,516 keystore: params.keystore_container.sync_keystore(),517 backend: backend.clone(),518 network: network.clone(),519 system_rpc_tx,520 telemetry: telemetry.as_mut(),521 })?;522523 if let Some(hwbench) = hwbench {524 sc_sysinfo::print_hwbench(&hwbench);525526 if let Some(ref mut telemetry) = telemetry {527 let telemetry_handle = telemetry.handle();528 task_manager.spawn_handle().spawn(529 "telemetry_hwbench",530 None,531 sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench),532 );533 }534 }535536 let announce_block = {537 let network = network.clone();538 Arc::new(move |hash, data| network.announce_block(hash, data))539 };540541 let relay_chain_slot_duration = Duration::from_secs(6);542543 if validator {544 let parachain_consensus = build_consensus(545 client.clone(),546 prometheus_registry.as_ref(),547 telemetry.as_ref().map(|t| t.handle()),548 &task_manager,549 relay_chain_interface.clone(),550 transaction_pool,551 network,552 params.keystore_container.sync_keystore(),553 force_authoring,554 )?;555556 let spawner = task_manager.spawn_handle();557558 let params = StartCollatorParams {559 para_id: id,560 block_status: client.clone(),561 announce_block,562 client: client.clone(),563 task_manager: &mut task_manager,564 spawner,565 parachain_consensus,566 import_queue,567 collator_key: collator_key.expect("Command line arguments do not allow this. qed"),568 relay_chain_interface,569 relay_chain_slot_duration,570 };571572 start_collator(params).await?;573 } else {574 let params = StartFullNodeParams {575 client: client.clone(),576 announce_block,577 task_manager: &mut task_manager,578 para_id: id,579 import_queue,580 relay_chain_interface,581 relay_chain_slot_duration,582 collator_options,583 };584585 start_full_node(params)?;586 }587588 start_network.start_network();589590 Ok((task_manager, client))591}592593/// Build the import queue for the the parachain runtime.594pub fn parachain_build_import_queue<RuntimeApi, ExecutorDispatch>(595 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,596 config: &Configuration,597 telemetry: Option<TelemetryHandle>,598 task_manager: &TaskManager,599) -> Result<600 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,601 sc_service::Error,602>603where604 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>605 + Send606 + Sync607 + 'static,608 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>609 + sp_block_builder::BlockBuilder<Block>610 + sp_consensus_aura::AuraApi<Block, AuraId>611 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,612 ExecutorDispatch: NativeExecutionDispatch + 'static,613{614 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;615616 cumulus_client_consensus_aura::import_queue::<617 sp_consensus_aura::sr25519::AuthorityPair,618 _,619 _,620 _,621 _,622 _,623 _,624 >(cumulus_client_consensus_aura::ImportQueueParams {625 block_import: client.clone(),626 client: client.clone(),627 create_inherent_data_providers: move |_, _| async move {628 let time = sp_timestamp::InherentDataProvider::from_system_time();629630 let slot =631 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(632 *time,633 slot_duration,634 );635636 Ok((time, slot))637 },638 registry: config.prometheus_registry(),639 can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),640 spawner: &task_manager.spawn_essential_handle(),641 telemetry,642 })643 .map_err(Into::into)644}645646/// Start a normal parachain node.647pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(648 parachain_config: Configuration,649 polkadot_config: Configuration,650 collator_options: CollatorOptions,651 id: ParaId,652 hwbench: Option<sc_sysinfo::HwBench>,653) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>654where655 Runtime: RuntimeInstance + Send + Sync + 'static,656 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,657 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,658 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>659 + Send660 + Sync661 + 'static,662 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>663 + fp_rpc::EthereumRuntimeRPCApi<Block>664 + fp_rpc::ConvertTransactionRuntimeApi<Block>665 + sp_session::SessionKeys<Block>666 + sp_block_builder::BlockBuilder<Block>667 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>668 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>669 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>670 + rmrk_rpc::RmrkApi<671 Block,672 AccountId,673 RmrkCollectionInfo<AccountId>,674 RmrkInstanceInfo<AccountId>,675 RmrkResourceInfo,676 RmrkPropertyInfo,677 RmrkBaseInfo<AccountId>,678 RmrkPartType,679 RmrkTheme,680 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>681 + sp_api::Metadata<Block>682 + sp_offchain::OffchainWorkerApi<Block>683 + cumulus_primitives_core::CollectCollationInfo<Block>684 + sp_consensus_aura::AuraApi<Block, AuraId>,685 ExecutorDispatch: NativeExecutionDispatch + 'static,686{687 start_node_impl::<Runtime, RuntimeApi, ExecutorDispatch, _, _>(688 parachain_config,689 polkadot_config,690 collator_options,691 id,692 parachain_build_import_queue,693 |client,694 prometheus_registry,695 telemetry,696 task_manager,697 relay_chain_interface,698 transaction_pool,699 sync_oracle,700 keystore,701 force_authoring| {702 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;703704 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(705 task_manager.spawn_handle(),706 client.clone(),707 transaction_pool,708 prometheus_registry,709 telemetry.clone(),710 );711712 Ok(AuraConsensus::build::<713 sp_consensus_aura::sr25519::AuthorityPair,714 _,715 _,716 _,717 _,718 _,719 _,720 >(BuildAuraConsensusParams {721 proposer_factory,722 create_inherent_data_providers: move |_, (relay_parent, validation_data)| {723 let relay_chain_interface = relay_chain_interface.clone();724 async move {725 let parachain_inherent =726 cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(727 relay_parent,728 &relay_chain_interface,729 &validation_data,730 id,731 ).await;732733 let time = sp_timestamp::InherentDataProvider::from_system_time();734735 let slot =736 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(737 *time,738 slot_duration,739 );740741 let parachain_inherent = parachain_inherent.ok_or_else(|| {742 Box::<dyn std::error::Error + Send + Sync>::from(743 "Failed to create parachain inherent",744 )745 })?;746 Ok((time, slot, parachain_inherent))747 }748 },749 block_import: client.clone(),750 para_client: client,751 backoff_authoring_blocks: Option::<()>::None,752 sync_oracle,753 keystore,754 force_authoring,755 slot_duration,756 // We got around 500ms for proposing757 block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),758 telemetry,759 max_block_proposal_slot_portion: None,760 }))761 },762 hwbench,763 )764 .await765}766767fn dev_build_import_queue<RuntimeApi, ExecutorDispatch>(768 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,769 config: &Configuration,770 _: Option<TelemetryHandle>,771 task_manager: &TaskManager,772) -> Result<773 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,774 sc_service::Error,775>776where777 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>778 + Send779 + Sync780 + 'static,781 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>782 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,783 ExecutorDispatch: NativeExecutionDispatch + 'static,784{785 Ok(sc_consensus_manual_seal::import_queue(786 Box::new(client.clone()),787 &task_manager.spawn_essential_handle(),788 config.prometheus_registry(),789 ))790}791792/// Builds a new development service. This service uses instant seal, and mocks793/// the parachain inherent794pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(795 config: Configuration,796 autoseal_interval: Duration,797) -> sc_service::error::Result<TaskManager>798where799 Runtime: RuntimeInstance + Send + Sync + 'static,800 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,801 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,802 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>803 + Send804 + Sync805 + 'static,806 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>807 + fp_rpc::EthereumRuntimeRPCApi<Block>808 + fp_rpc::ConvertTransactionRuntimeApi<Block>809 + sp_session::SessionKeys<Block>810 + sp_block_builder::BlockBuilder<Block>811 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>812 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>813 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>814 + rmrk_rpc::RmrkApi<815 Block,816 AccountId,817 RmrkCollectionInfo<AccountId>,818 RmrkInstanceInfo<AccountId>,819 RmrkResourceInfo,820 RmrkPropertyInfo,821 RmrkBaseInfo<AccountId>,822 RmrkPartType,823 RmrkTheme,824 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>825 + sp_api::Metadata<Block>826 + sp_offchain::OffchainWorkerApi<Block>827 + cumulus_primitives_core::CollectCollationInfo<Block>828 + sp_consensus_aura::AuraApi<Block, AuraId>,829 ExecutorDispatch: NativeExecutionDispatch + 'static,830{831 use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams};832 use fc_consensus::FrontierBlockImport;833 use sc_client_api::HeaderBackend;834835 let sc_service::PartialComponents {836 client,837 backend,838 mut task_manager,839 import_queue,840 keystore_container,841 select_chain: maybe_select_chain,842 transaction_pool,843 other:844 (telemetry, filter_pool, frontier_backend, _telemetry_worker_handle, fee_history_cache),845 } = new_partial::<RuntimeApi, ExecutorDispatch, _>(846 &config,847 dev_build_import_queue::<RuntimeApi, ExecutorDispatch>,848 )?;849 let prometheus_registry = config.prometheus_registry().cloned();850851 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(852 task_manager.spawn_handle(),853 overrides_handle::<_, _, Runtime>(client.clone()),854 50,855 50,856 prometheus_registry.clone(),857 ));858859 let (network, system_rpc_tx, network_starter) =860 sc_service::build_network(sc_service::BuildNetworkParams {861 config: &config,862 client: client.clone(),863 transaction_pool: transaction_pool.clone(),864 spawn_handle: task_manager.spawn_handle(),865 import_queue,866 block_announce_validator_builder: None,867 warp_sync: None,868 })?;869870 if config.offchain_worker.enabled {871 sc_service::build_offchain_workers(872 &config,873 task_manager.spawn_handle(),874 client.clone(),875 network.clone(),876 );877 }878879 let collator = config.role.is_authority();880881 let select_chain = maybe_select_chain.clone();882883 if collator {884 let block_import =885 FrontierBlockImport::new(client.clone(), client.clone(), frontier_backend.clone());886887 let env = sc_basic_authorship::ProposerFactory::new(888 task_manager.spawn_handle(),889 client.clone(),890 transaction_pool.clone(),891 prometheus_registry.as_ref(),892 telemetry.as_ref().map(|x| x.handle()),893 );894895 let transactions_commands_stream: Box<896 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,897 > = Box::new(898 transaction_pool899 .pool()900 .validated_pool()901 .import_notification_stream()902 .map(|_| EngineCommand::SealNewBlock {903 create_empty: true,904 finalize: false,905 parent_hash: None,906 sender: None,907 }),908 );909910 let autoseal_interval = Box::pin(AutosealInterval::new(&config, autoseal_interval));911 let idle_commands_stream: Box<912 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,913 > = Box::new(autoseal_interval.map(|_| EngineCommand::SealNewBlock {914 create_empty: true,915 finalize: false,916 parent_hash: None,917 sender: None,918 }));919920 let commands_stream = select(transactions_commands_stream, idle_commands_stream);921922 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;923 let client_set_aside_for_cidp = client.clone();924925 task_manager.spawn_essential_handle().spawn_blocking(926 "authorship_task",927 Some("block-authoring"),928 run_manual_seal(ManualSealParams {929 block_import,930 env,931 client: client.clone(),932 pool: transaction_pool.clone(),933 commands_stream,934 select_chain: select_chain.clone(),935 consensus_data_provider: None,936 create_inherent_data_providers: move |block: Hash, ()| {937 let current_para_block = client_set_aside_for_cidp938 .number(block)939 .expect("Header lookup should succeed")940 .expect("Header passed in as parent should be present in backend.");941942 let client_for_xcm = client_set_aside_for_cidp.clone();943 async move {944 let time = sp_timestamp::InherentDataProvider::from_system_time();945946 let mocked_parachain = cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider {947 current_para_block,948 relay_offset: 1000,949 relay_blocks_per_para_block: 2,950 xcm_config: cumulus_primitives_parachain_inherent::MockXcmConfig::new(951 &*client_for_xcm,952 block,953 Default::default(),954 Default::default(),955 ),956 raw_downward_messages: vec![],957 raw_horizontal_messages: vec![],958 };959960 let slot =961 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(962 *time,963 slot_duration,964 );965966 Ok((time, slot, mocked_parachain))967 }968 },969 }),970 );971 }972973 task_manager.spawn_essential_handle().spawn(974 "frontier-mapping-sync-worker",975 Some("block-authoring"),976 MappingSyncWorker::new(977 client.import_notification_stream(),978 Duration::new(6, 0),979 client.clone(),980 backend.clone(),981 frontier_backend.clone(),982 3,983 0,984 SyncStrategy::Normal,985 )986 .for_each(|()| futures::future::ready(())),987 );988989 let rpc_client = client.clone();990 let rpc_pool = transaction_pool.clone();991 let rpc_network = network.clone();992 let rpc_frontier_backend = frontier_backend.clone();993 let rpc_builder = Box::new(move |deny_unsafe, subscription_executor| {994 let full_deps = unique_rpc::FullDeps {995 backend: rpc_frontier_backend.clone(),996 deny_unsafe,997 client: rpc_client.clone(),998 pool: rpc_pool.clone(),999 graph: rpc_pool.pool().clone(),1000 // TODO: Unhardcode1001 enable_dev_signer: false,1002 filter_pool: filter_pool.clone(),1003 network: rpc_network.clone(),1004 select_chain: select_chain.clone(),1005 is_authority: collator,1006 // TODO: Unhardcode1007 max_past_logs: 10000,1008 block_data_cache: block_data_cache.clone(),1009 fee_history_cache: fee_history_cache.clone(),1010 // TODO: Unhardcode1011 fee_history_limit: 2048,1012 };10131014 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(1015 full_deps,1016 subscription_executor,1017 )1018 .map_err(Into::into)1019 });10201021 sc_service::spawn_tasks(sc_service::SpawnTasksParams {1022 network,1023 client,1024 keystore: keystore_container.sync_keystore(),1025 task_manager: &mut task_manager,1026 transaction_pool,1027 rpc_builder,1028 backend,1029 system_rpc_tx,1030 config,1031 telemetry: None,1032 })?;10331034 network_starter.start_network();1035 Ok(task_manager)1036}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// std18use std::sync::Arc;19use std::sync::Mutex;20use std::collections::BTreeMap;21use std::time::Duration;22use std::pin::Pin;23use fc_rpc_core::types::FeeHistoryCache;24use futures::{25 Stream, StreamExt,26 stream::select,27 task::{Context, Poll},28};29use tokio::time::Interval;3031use unique_rpc::overrides_handle;3233use serde::{Serialize, Deserialize};3435// Cumulus Imports36use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};37use cumulus_client_consensus_common::ParachainConsensus;38use cumulus_client_service::{39 prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,40};41use cumulus_client_cli::CollatorOptions;42use cumulus_client_network::BlockAnnounceValidator;43use cumulus_primitives_core::ParaId;44use cumulus_relay_chain_inprocess_interface::build_inprocess_relay_chain;45use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayChainResult};46use cumulus_relay_chain_rpc_interface::RelayChainRPCInterface;4748// Substrate Imports49use sc_client_api::ExecutorProvider;50use sc_executor::NativeElseWasmExecutor;51use sc_executor::NativeExecutionDispatch;52use sc_network::NetworkService;53use sc_service::{BasePath, Configuration, PartialComponents, Role, TaskManager};54use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};55use sp_keystore::SyncCryptoStorePtr;56use sp_runtime::traits::BlakeTwo256;57use substrate_prometheus_endpoint::Registry;58use sc_client_api::BlockchainEvents;5960use polkadot_service::CollatorPair;6162// Frontier Imports63use fc_rpc_core::types::FilterPool;64use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};6566use common_types::opaque::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};6768// RMRK69use up_data_structs::{70 RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,71 RmrkPartType, RmrkTheme,72};7374/// Unique native executor instance.75#[cfg(feature = "unique-runtime")]76pub struct UniqueRuntimeExecutor;7778#[cfg(feature = "quartz-runtime")]79/// Quartz native executor instance.80pub struct QuartzRuntimeExecutor;8182/// Opal native executor instance.83pub struct OpalRuntimeExecutor;8485#[cfg(feature = "unique-runtime")]86pub type DefaultRuntimeExecutor = UniqueRuntimeExecutor;8788#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]89pub type DefaultRuntimeExecutor = QuartzRuntimeExecutor;9091#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]92pub type DefaultRuntimeExecutor = OpalRuntimeExecutor;9394#[cfg(feature = "unique-runtime")]95impl NativeExecutionDispatch for UniqueRuntimeExecutor {96 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;9798 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {99 unique_runtime::api::dispatch(method, data)100 }101102 fn native_version() -> sc_executor::NativeVersion {103 unique_runtime::native_version()104 }105}106107#[cfg(feature = "quartz-runtime")]108impl NativeExecutionDispatch for QuartzRuntimeExecutor {109 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;110111 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {112 quartz_runtime::api::dispatch(method, data)113 }114115 fn native_version() -> sc_executor::NativeVersion {116 quartz_runtime::native_version()117 }118}119120impl NativeExecutionDispatch for OpalRuntimeExecutor {121 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;122123 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {124 opal_runtime::api::dispatch(method, data)125 }126127 fn native_version() -> sc_executor::NativeVersion {128 opal_runtime::native_version()129 }130}131132pub struct AutosealInterval {133 interval: Interval,134}135136impl AutosealInterval {137 pub fn new(config: &Configuration, interval: Duration) -> Self {138 let _tokio_runtime = config.tokio_handle.enter();139 let interval = tokio::time::interval(interval);140141 Self { interval }142 }143}144145impl Stream for AutosealInterval {146 type Item = tokio::time::Instant;147148 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {149 self.interval.poll_tick(cx).map(Some)150 }151}152153pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {154 let config_dir = config155 .base_path156 .as_ref()157 .map(|base_path| base_path.config_dir(config.chain_spec.id()))158 .unwrap_or_else(|| {159 BasePath::from_project("", "", "unique").config_dir(config.chain_spec.id())160 });161 let database_dir = config_dir.join("frontier").join("db");162163 Ok(Arc::new(fc_db::Backend::<Block>::new(164 &fc_db::DatabaseSettings {165 source: fc_db::DatabaseSource::RocksDb {166 path: database_dir,167 cache_size: 0,168 },169 },170 )?))171}172173type FullClient<RuntimeApi, ExecutorDispatch> =174 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;175type FullBackend = sc_service::TFullBackend<Block>;176type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;177178/// Starts a `ServiceBuilder` for a full service.179///180/// Use this macro if you don't actually need the full service, but just the builder in order to181/// be able to perform chain operations.182#[allow(clippy::type_complexity)]183pub fn new_partial<RuntimeApi, ExecutorDispatch, BIQ>(184 config: &Configuration,185 build_import_queue: BIQ,186) -> Result<187 PartialComponents<188 FullClient<RuntimeApi, ExecutorDispatch>,189 FullBackend,190 FullSelectChain,191 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,192 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,193 (194 Option<Telemetry>,195 Option<FilterPool>,196 Arc<fc_db::Backend<Block>>,197 Option<TelemetryWorkerHandle>,198 FeeHistoryCache,199 ),200 >,201 sc_service::Error,202>203where204 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,205 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>206 + Send207 + Sync208 + 'static,209 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,210 ExecutorDispatch: NativeExecutionDispatch + 'static,211 BIQ: FnOnce(212 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,213 &Configuration,214 Option<TelemetryHandle>,215 &TaskManager,216 ) -> Result<217 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,218 sc_service::Error,219 >,220{221 let _telemetry = config222 .telemetry_endpoints223 .clone()224 .filter(|x| !x.is_empty())225 .map(|endpoints| -> Result<_, sc_telemetry::Error> {226 let worker = TelemetryWorker::new(16)?;227 let telemetry = worker.handle().new_telemetry(endpoints);228 Ok((worker, telemetry))229 })230 .transpose()?;231232 let telemetry = config233 .telemetry_endpoints234 .clone()235 .filter(|x| !x.is_empty())236 .map(|endpoints| -> Result<_, sc_telemetry::Error> {237 let worker = TelemetryWorker::new(16)?;238 let telemetry = worker.handle().new_telemetry(endpoints);239 Ok((worker, telemetry))240 })241 .transpose()?;242243 let executor = NativeElseWasmExecutor::<ExecutorDispatch>::new(244 config.wasm_method,245 config.default_heap_pages,246 config.max_runtime_instances,247 config.runtime_cache_size,248 );249250 let (client, backend, keystore_container, task_manager) =251 sc_service::new_full_parts::<Block, RuntimeApi, _>(252 config,253 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),254 executor,255 )?;256 let client = Arc::new(client);257258 let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());259260 let telemetry = telemetry.map(|(worker, telemetry)| {261 task_manager262 .spawn_handle()263 .spawn("telemetry", None, worker.run());264 telemetry265 });266267 let select_chain = sc_consensus::LongestChain::new(backend.clone());268269 let transaction_pool = sc_transaction_pool::BasicPool::new_full(270 config.transaction_pool.clone(),271 config.role.is_authority().into(),272 config.prometheus_registry(),273 task_manager.spawn_essential_handle(),274 client.clone(),275 );276277 let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));278279 let frontier_backend = open_frontier_backend(config)?;280281 let import_queue = build_import_queue(282 client.clone(),283 config,284 telemetry.as_ref().map(|telemetry| telemetry.handle()),285 &task_manager,286 )?;287 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));288289 let params = PartialComponents {290 backend,291 client,292 import_queue,293 keystore_container,294 task_manager,295 transaction_pool,296 select_chain,297 other: (298 telemetry,299 filter_pool,300 frontier_backend,301 telemetry_worker_handle,302 fee_history_cache,303 ),304 };305306 Ok(params)307}308309async fn build_relay_chain_interface(310 polkadot_config: Configuration,311 parachain_config: &Configuration,312 telemetry_worker_handle: Option<TelemetryWorkerHandle>,313 task_manager: &mut TaskManager,314 collator_options: CollatorOptions,315 hwbench: Option<sc_sysinfo::HwBench>,316) -> RelayChainResult<(317 Arc<(dyn RelayChainInterface + 'static)>,318 Option<CollatorPair>,319)> {320 match collator_options.relay_chain_rpc_url {321 Some(relay_chain_url) => Ok((322 Arc::new(RelayChainRPCInterface::new(relay_chain_url).await?) as Arc<_>,323 None,324 )),325 None => build_inprocess_relay_chain(326 polkadot_config,327 parachain_config,328 telemetry_worker_handle,329 task_manager,330 hwbench,331 ),332 }333}334335/// Start a node with the given parachain `Configuration` and relay chain `Configuration`.336///337/// This is the actual implementation that is abstract over the executor and the runtime api.338#[sc_tracing::logging::prefix_logs_with("Parachain")]339async fn start_node_impl<Runtime, RuntimeApi, ExecutorDispatch, BIQ, BIC>(340 parachain_config: Configuration,341 polkadot_config: Configuration,342 collator_options: CollatorOptions,343 id: ParaId,344 build_import_queue: BIQ,345 build_consensus: BIC,346 hwbench: Option<sc_sysinfo::HwBench>,347) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>348where349 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,350 Runtime: RuntimeInstance + Send + Sync + 'static,351 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,352 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,353 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>354 + Send355 + Sync356 + 'static,357 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>358 + fp_rpc::EthereumRuntimeRPCApi<Block>359 + fp_rpc::ConvertTransactionRuntimeApi<Block>360 + sp_session::SessionKeys<Block>361 + sp_block_builder::BlockBuilder<Block>362 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>363 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>364 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>365 + rmrk_rpc::RmrkApi<366 Block,367 AccountId,368 RmrkCollectionInfo<AccountId>,369 RmrkInstanceInfo<AccountId>,370 RmrkResourceInfo,371 RmrkPropertyInfo,372 RmrkBaseInfo<AccountId>,373 RmrkPartType,374 RmrkTheme,375 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>376 + sp_api::Metadata<Block>377 + sp_offchain::OffchainWorkerApi<Block>378 + cumulus_primitives_core::CollectCollationInfo<Block>,379 ExecutorDispatch: NativeExecutionDispatch + 'static,380 BIQ: FnOnce(381 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,382 &Configuration,383 Option<TelemetryHandle>,384 &TaskManager,385 ) -> Result<386 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,387 sc_service::Error,388 >,389 BIC: FnOnce(390 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,391 Option<&Registry>,392 Option<TelemetryHandle>,393 &TaskManager,394 Arc<dyn RelayChainInterface>,395 Arc<sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>>,396 Arc<NetworkService<Block, Hash>>,397 SyncCryptoStorePtr,398 bool,399 ) -> Result<Box<dyn ParachainConsensus<Block>>, sc_service::Error>,400{401 if matches!(parachain_config.role, Role::Light) {402 return Err("Light client not supported!".into());403 }404405 let parachain_config = prepare_node_config(parachain_config);406407 let params =408 new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(¶chain_config, build_import_queue)?;409 let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =410 params.other;411412 let client = params.client.clone();413 let backend = params.backend.clone();414 let mut task_manager = params.task_manager;415416 let (relay_chain_interface, collator_key) = build_relay_chain_interface(417 polkadot_config,418 ¶chain_config,419 telemetry_worker_handle,420 &mut task_manager,421 collator_options.clone(),422 hwbench.clone(),423 )424 .await425 .map_err(|e| match e {426 RelayChainError::ServiceError(polkadot_service::Error::Sub(x)) => x,427 s => s.to_string().into(),428 })?;429430 let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id);431432 let force_authoring = parachain_config.force_authoring;433 let validator = parachain_config.role.is_authority();434 let prometheus_registry = parachain_config.prometheus_registry().cloned();435 let transaction_pool = params.transaction_pool.clone();436 let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue);437438 let (network, system_rpc_tx, start_network) =439 sc_service::build_network(sc_service::BuildNetworkParams {440 config: ¶chain_config,441 client: client.clone(),442 transaction_pool: transaction_pool.clone(),443 spawn_handle: task_manager.spawn_handle(),444 import_queue: import_queue.clone(),445 block_announce_validator_builder: Some(Box::new(|_| {446 Box::new(block_announce_validator)447 })),448 warp_sync: None,449 })?;450451 let rpc_client = client.clone();452 let rpc_pool = transaction_pool.clone();453 let select_chain = params.select_chain.clone();454 let rpc_network = network.clone();455456 let rpc_frontier_backend = frontier_backend.clone();457458 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(459 task_manager.spawn_handle(),460 overrides_handle::<_, _, Runtime>(client.clone()),461 50,462 50,463 prometheus_registry.clone(),464 ));465466 task_manager.spawn_essential_handle().spawn(467 "frontier-mapping-sync-worker",468 None,469 MappingSyncWorker::new(470 client.import_notification_stream(),471 Duration::new(6, 0),472 client.clone(),473 backend.clone(),474 frontier_backend.clone(),475 3,476 0,477 SyncStrategy::Normal,478 )479 .for_each(|()| futures::future::ready(())),480 );481482 let rpc_builder = Box::new(move |deny_unsafe, subscription_task_executor| {483 let full_deps = unique_rpc::FullDeps {484 backend: rpc_frontier_backend.clone(),485 deny_unsafe,486 client: rpc_client.clone(),487 pool: rpc_pool.clone(),488 graph: rpc_pool.pool().clone(),489 // TODO: Unhardcode490 enable_dev_signer: false,491 filter_pool: filter_pool.clone(),492 network: rpc_network.clone(),493 select_chain: select_chain.clone(),494 is_authority: validator,495 // TODO: Unhardcode496 max_past_logs: 10000,497 block_data_cache: block_data_cache.clone(),498 fee_history_cache: fee_history_cache.clone(),499 // TODO: Unhardcode500 fee_history_limit: 2048,501 };502503 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(504 full_deps,505 subscription_task_executor,506 )507 .map_err(Into::into)508 });509510 sc_service::spawn_tasks(sc_service::SpawnTasksParams {511 rpc_builder,512 client: client.clone(),513 transaction_pool: transaction_pool.clone(),514 task_manager: &mut task_manager,515 config: parachain_config,516 keystore: params.keystore_container.sync_keystore(),517 backend: backend.clone(),518 network: network.clone(),519 system_rpc_tx,520 telemetry: telemetry.as_mut(),521 })?;522523 if let Some(hwbench) = hwbench {524 sc_sysinfo::print_hwbench(&hwbench);525526 if let Some(ref mut telemetry) = telemetry {527 let telemetry_handle = telemetry.handle();528 task_manager.spawn_handle().spawn(529 "telemetry_hwbench",530 None,531 sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench),532 );533 }534 }535536 let announce_block = {537 let network = network.clone();538 Arc::new(move |hash, data| network.announce_block(hash, data))539 };540541 let relay_chain_slot_duration = Duration::from_secs(6);542543 if validator {544 let parachain_consensus = build_consensus(545 client.clone(),546 prometheus_registry.as_ref(),547 telemetry.as_ref().map(|t| t.handle()),548 &task_manager,549 relay_chain_interface.clone(),550 transaction_pool,551 network,552 params.keystore_container.sync_keystore(),553 force_authoring,554 )?;555556 let spawner = task_manager.spawn_handle();557558 let params = StartCollatorParams {559 para_id: id,560 block_status: client.clone(),561 announce_block,562 client: client.clone(),563 task_manager: &mut task_manager,564 spawner,565 parachain_consensus,566 import_queue,567 collator_key: collator_key.expect("Command line arguments do not allow this. qed"),568 relay_chain_interface,569 relay_chain_slot_duration,570 };571572 start_collator(params).await?;573 } else {574 let params = StartFullNodeParams {575 client: client.clone(),576 announce_block,577 task_manager: &mut task_manager,578 para_id: id,579 import_queue,580 relay_chain_interface,581 relay_chain_slot_duration,582 collator_options,583 };584585 start_full_node(params)?;586 }587588 start_network.start_network();589590 Ok((task_manager, client))591}592593/// Build the import queue for the the parachain runtime.594pub fn parachain_build_import_queue<RuntimeApi, ExecutorDispatch>(595 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,596 config: &Configuration,597 telemetry: Option<TelemetryHandle>,598 task_manager: &TaskManager,599) -> Result<600 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,601 sc_service::Error,602>603where604 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>605 + Send606 + Sync607 + 'static,608 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>609 + sp_block_builder::BlockBuilder<Block>610 + sp_consensus_aura::AuraApi<Block, AuraId>611 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,612 ExecutorDispatch: NativeExecutionDispatch + 'static,613{614 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;615616 cumulus_client_consensus_aura::import_queue::<617 sp_consensus_aura::sr25519::AuthorityPair,618 _,619 _,620 _,621 _,622 _,623 _,624 >(cumulus_client_consensus_aura::ImportQueueParams {625 block_import: client.clone(),626 client: client.clone(),627 create_inherent_data_providers: move |_, _| async move {628 let time = sp_timestamp::InherentDataProvider::from_system_time();629630 let slot =631 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(632 *time,633 slot_duration,634 );635636 Ok((time, slot))637 },638 registry: config.prometheus_registry(),639 can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),640 spawner: &task_manager.spawn_essential_handle(),641 telemetry,642 })643 .map_err(Into::into)644}645646/// Start a normal parachain node.647pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(648 parachain_config: Configuration,649 polkadot_config: Configuration,650 collator_options: CollatorOptions,651 id: ParaId,652 hwbench: Option<sc_sysinfo::HwBench>,653) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>654where655 Runtime: RuntimeInstance + Send + Sync + 'static,656 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,657 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,658 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>659 + Send660 + Sync661 + 'static,662 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>663 + fp_rpc::EthereumRuntimeRPCApi<Block>664 + fp_rpc::ConvertTransactionRuntimeApi<Block>665 + sp_session::SessionKeys<Block>666 + sp_block_builder::BlockBuilder<Block>667 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>668 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>669 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>670 + rmrk_rpc::RmrkApi<671 Block,672 AccountId,673 RmrkCollectionInfo<AccountId>,674 RmrkInstanceInfo<AccountId>,675 RmrkResourceInfo,676 RmrkPropertyInfo,677 RmrkBaseInfo<AccountId>,678 RmrkPartType,679 RmrkTheme,680 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>681 + sp_api::Metadata<Block>682 + sp_offchain::OffchainWorkerApi<Block>683 + cumulus_primitives_core::CollectCollationInfo<Block>684 + sp_consensus_aura::AuraApi<Block, AuraId>,685 ExecutorDispatch: NativeExecutionDispatch + 'static,686{687 start_node_impl::<Runtime, RuntimeApi, ExecutorDispatch, _, _>(688 parachain_config,689 polkadot_config,690 collator_options,691 id,692 parachain_build_import_queue,693 |client,694 prometheus_registry,695 telemetry,696 task_manager,697 relay_chain_interface,698 transaction_pool,699 sync_oracle,700 keystore,701 force_authoring| {702 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;703704 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(705 task_manager.spawn_handle(),706 client.clone(),707 transaction_pool,708 prometheus_registry,709 telemetry.clone(),710 );711712 Ok(AuraConsensus::build::<713 sp_consensus_aura::sr25519::AuthorityPair,714 _,715 _,716 _,717 _,718 _,719 _,720 >(BuildAuraConsensusParams {721 proposer_factory,722 create_inherent_data_providers: move |_, (relay_parent, validation_data)| {723 let relay_chain_interface = relay_chain_interface.clone();724 async move {725 let parachain_inherent =726 cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(727 relay_parent,728 &relay_chain_interface,729 &validation_data,730 id,731 ).await;732733 let time = sp_timestamp::InherentDataProvider::from_system_time();734735 let slot =736 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(737 *time,738 slot_duration,739 );740741 let parachain_inherent = parachain_inherent.ok_or_else(|| {742 Box::<dyn std::error::Error + Send + Sync>::from(743 "Failed to create parachain inherent",744 )745 })?;746 Ok((time, slot, parachain_inherent))747 }748 },749 block_import: client.clone(),750 para_client: client,751 backoff_authoring_blocks: Option::<()>::None,752 sync_oracle,753 keystore,754 force_authoring,755 slot_duration,756 // We got around 500ms for proposing757 block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),758 telemetry,759 max_block_proposal_slot_portion: None,760 }))761 },762 hwbench,763 )764 .await765}766767fn dev_build_import_queue<RuntimeApi, ExecutorDispatch>(768 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,769 config: &Configuration,770 _: Option<TelemetryHandle>,771 task_manager: &TaskManager,772) -> Result<773 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,774 sc_service::Error,775>776where777 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>778 + Send779 + Sync780 + 'static,781 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>782 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,783 ExecutorDispatch: NativeExecutionDispatch + 'static,784{785 Ok(sc_consensus_manual_seal::import_queue(786 Box::new(client.clone()),787 &task_manager.spawn_essential_handle(),788 config.prometheus_registry(),789 ))790}791792/// Builds a new development service. This service uses instant seal, and mocks793/// the parachain inherent794pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(795 config: Configuration,796 autoseal_interval: Duration,797) -> sc_service::error::Result<TaskManager>798where799 Runtime: RuntimeInstance + Send + Sync + 'static,800 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,801 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,802 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>803 + Send804 + Sync805 + 'static,806 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>807 + fp_rpc::EthereumRuntimeRPCApi<Block>808 + fp_rpc::ConvertTransactionRuntimeApi<Block>809 + sp_session::SessionKeys<Block>810 + sp_block_builder::BlockBuilder<Block>811 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>812 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>813 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>814 + rmrk_rpc::RmrkApi<815 Block,816 AccountId,817 RmrkCollectionInfo<AccountId>,818 RmrkInstanceInfo<AccountId>,819 RmrkResourceInfo,820 RmrkPropertyInfo,821 RmrkBaseInfo<AccountId>,822 RmrkPartType,823 RmrkTheme,824 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>825 + sp_api::Metadata<Block>826 + sp_offchain::OffchainWorkerApi<Block>827 + cumulus_primitives_core::CollectCollationInfo<Block>828 + sp_consensus_aura::AuraApi<Block, AuraId>,829 ExecutorDispatch: NativeExecutionDispatch + 'static,830{831 use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams};832 use fc_consensus::FrontierBlockImport;833 use sc_client_api::HeaderBackend;834835 let sc_service::PartialComponents {836 client,837 backend,838 mut task_manager,839 import_queue,840 keystore_container,841 select_chain: maybe_select_chain,842 transaction_pool,843 other:844 (telemetry, filter_pool, frontier_backend, _telemetry_worker_handle, fee_history_cache),845 } = new_partial::<RuntimeApi, ExecutorDispatch, _>(846 &config,847 dev_build_import_queue::<RuntimeApi, ExecutorDispatch>,848 )?;849 let prometheus_registry = config.prometheus_registry().cloned();850851 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(852 task_manager.spawn_handle(),853 overrides_handle::<_, _, Runtime>(client.clone()),854 50,855 50,856 prometheus_registry.clone(),857 ));858859 let (network, system_rpc_tx, network_starter) =860 sc_service::build_network(sc_service::BuildNetworkParams {861 config: &config,862 client: client.clone(),863 transaction_pool: transaction_pool.clone(),864 spawn_handle: task_manager.spawn_handle(),865 import_queue,866 block_announce_validator_builder: None,867 warp_sync: None,868 })?;869870 if config.offchain_worker.enabled {871 sc_service::build_offchain_workers(872 &config,873 task_manager.spawn_handle(),874 client.clone(),875 network.clone(),876 );877 }878879 let collator = config.role.is_authority();880881 let select_chain = maybe_select_chain.clone();882883 if collator {884 let block_import =885 FrontierBlockImport::new(client.clone(), client.clone(), frontier_backend.clone());886887 let env = sc_basic_authorship::ProposerFactory::new(888 task_manager.spawn_handle(),889 client.clone(),890 transaction_pool.clone(),891 prometheus_registry.as_ref(),892 telemetry.as_ref().map(|x| x.handle()),893 );894895 let transactions_commands_stream: Box<896 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,897 > = Box::new(898 transaction_pool899 .pool()900 .validated_pool()901 .import_notification_stream()902 .map(|_| EngineCommand::SealNewBlock {903 create_empty: true,904 finalize: false,905 parent_hash: None,906 sender: None,907 }),908 );909910 let autoseal_interval = Box::pin(AutosealInterval::new(&config, autoseal_interval));911 let idle_commands_stream: Box<912 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,913 > = Box::new(autoseal_interval.map(|_| EngineCommand::SealNewBlock {914 create_empty: true,915 finalize: false,916 parent_hash: None,917 sender: None,918 }));919920 let commands_stream = select(transactions_commands_stream, idle_commands_stream);921922 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;923 let client_set_aside_for_cidp = client.clone();924925 task_manager.spawn_essential_handle().spawn_blocking(926 "authorship_task",927 Some("block-authoring"),928 run_manual_seal(ManualSealParams {929 block_import,930 env,931 client: client.clone(),932 pool: transaction_pool.clone(),933 commands_stream,934 select_chain: select_chain.clone(),935 consensus_data_provider: None,936 create_inherent_data_providers: move |block: Hash, ()| {937 let current_para_block = client_set_aside_for_cidp938 .number(block)939 .expect("Header lookup should succeed")940 .expect("Header passed in as parent should be present in backend.");941942 let client_for_xcm = client_set_aside_for_cidp.clone();943 async move {944 let time = sp_timestamp::InherentDataProvider::from_system_time();945946 let mocked_parachain = cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider {947 current_para_block,948 relay_offset: 1000,949 relay_blocks_per_para_block: 2,950 xcm_config: cumulus_primitives_parachain_inherent::MockXcmConfig::new(951 &*client_for_xcm,952 block,953 Default::default(),954 Default::default(),955 ),956 raw_downward_messages: vec![],957 raw_horizontal_messages: vec![],958 };959960 let slot =961 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(962 *time,963 slot_duration,964 );965966 Ok((time, slot, mocked_parachain))967 }968 },969 }),970 );971 }972973 task_manager.spawn_essential_handle().spawn(974 "frontier-mapping-sync-worker",975 Some("block-authoring"),976 MappingSyncWorker::new(977 client.import_notification_stream(),978 Duration::new(6, 0),979 client.clone(),980 backend.clone(),981 frontier_backend.clone(),982 3,983 0,984 SyncStrategy::Normal,985 )986 .for_each(|()| futures::future::ready(())),987 );988989 let rpc_client = client.clone();990 let rpc_pool = transaction_pool.clone();991 let rpc_network = network.clone();992 let rpc_frontier_backend = frontier_backend.clone();993 let rpc_builder = Box::new(move |deny_unsafe, subscription_executor| {994 let full_deps = unique_rpc::FullDeps {995 backend: rpc_frontier_backend.clone(),996 deny_unsafe,997 client: rpc_client.clone(),998 pool: rpc_pool.clone(),999 graph: rpc_pool.pool().clone(),1000 // TODO: Unhardcode1001 enable_dev_signer: false,1002 filter_pool: filter_pool.clone(),1003 network: rpc_network.clone(),1004 select_chain: select_chain.clone(),1005 is_authority: collator,1006 // TODO: Unhardcode1007 max_past_logs: 10000,1008 block_data_cache: block_data_cache.clone(),1009 fee_history_cache: fee_history_cache.clone(),1010 // TODO: Unhardcode1011 fee_history_limit: 2048,1012 };10131014 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(1015 full_deps,1016 subscription_executor,1017 )1018 .map_err(Into::into)1019 });10201021 sc_service::spawn_tasks(sc_service::SpawnTasksParams {1022 network,1023 client,1024 keystore: keystore_container.sync_keystore(),1025 task_manager: &mut task_manager,1026 transaction_pool,1027 rpc_builder,1028 backend,1029 system_rpc_tx,1030 config,1031 telemetry: None,1032 })?;10331034 network_starter.start_network();1035 Ok(task_manager)1036}node/rpc/Cargo.tomldiffbeforeafterboth--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -49,7 +49,7 @@
fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
pallet-common = { default-features = false, path = "../../pallets/common" }
-unique-runtime-common = { default-features = false, path = "../../runtime/common" }
+common-types = { path = "../../common-types" }
pallet-unique = { path = "../../pallets/unique" }
uc-rpc = { path = "../../client/rpc" }
up-rpc = { path = "../../primitives/rpc" }
node/rpc/src/lib.rsdiffbeforeafterboth--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -40,9 +40,10 @@
use sc_service::TransactionPool;
use std::{collections::BTreeMap, sync::Arc};
-use unique_runtime_common::types::{
+use common_types::opaque::{
Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance,
};
+
// RMRK
use up_data_structs::{
RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
runtime/common/Cargo.tomldiffbeforeafterboth--- a/runtime/common/Cargo.toml
+++ /dev/null
@@ -1,121 +0,0 @@
-[package]
-authors = ['Unique Network <support@uniquenetwork.io>']
-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.9.24'
-
-[features]
-default = ['std']
-std = [
- 'sp-core/std',
- 'sp-std/std',
- 'sp-runtime/std',
- 'codec/std',
- 'frame-support/std',
- 'frame-system/std',
- 'sp-consensus-aura/std',
- 'pallet-common/std',
- 'pallet-unique/std',
- 'pallet-fungible/std',
- 'pallet-nonfungible/std',
- 'pallet-refungible/std',
- 'up-data-structs/std',
- 'pallet-evm/std',
- 'fp-rpc/std',
-]
-runtime-benchmarks = [
- 'sp-runtime/runtime-benchmarks',
- 'frame-support/runtime-benchmarks',
- 'frame-system/runtime-benchmarks',
-]
-
-opal-runtime = []
-quartz-runtime = []
-unique-runtime = []
-
-refungible = []
-
-[dependencies.sp-core]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.sp-std]
-default-features = false
-git = 'https://github.com/paritytech/substrate'
-branch = 'polkadot-v0.9.24'
-
-[dependencies.sp-runtime]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '3.1.2'
-
-[dependencies.scale-info]
-default-features = false
-features = ["derive"]
-version = "2.0.1"
-
-[dependencies.frame-support]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.frame-system]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.pallet-common]
-default-features = false
-path = "../../pallets/common"
-
-[dependencies.pallet-unique]
-default-features = false
-path = "../../pallets/unique"
-
-[dependencies.pallet-fungible]
-default-features = false
-path = "../../pallets/fungible"
-
-[dependencies.pallet-nonfungible]
-default-features = false
-path = "../../pallets/nonfungible"
-
-[dependencies.pallet-refungible]
-default-features = false
-path = "../../pallets/refungible"
-
-[dependencies.pallet-unique-scheduler]
-default-features = false
-path = "../../pallets/scheduler"
-
-[dependencies.up-data-structs]
-default-features = false
-path = "../../primitives/data-structs"
-
-[dependencies.sp-consensus-aura]
-default-features = false
-git = "https://github.com/paritytech/substrate"
-branch = "polkadot-v0.9.24"
-
-[dependencies.fp-rpc]
-default-features = false
-git = "https://github.com/uniquenetwork/frontier"
-branch = "unique-polkadot-v0.9.24"
-
-[dependencies]
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
-evm-coder = { default-features = false, path = '../../crates/evm-coder' }
-up-sponsorship = { default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
-
-rmrk-rpc = { default-features = false, path = "../../primitives/rmrk-rpc" }
runtime/common/config/ethereum.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/ethereum.rs
@@ -0,0 +1,140 @@
+use sp_core::{U256, H160};
+use frame_support::{
+ weights::{Weight, constants::WEIGHT_PER_SECOND},
+ traits::{FindAuthor},
+ parameter_types, ConsensusEngineId,
+};
+use sp_runtime::{RuntimeAppPublic, Perbill};
+use crate::{
+ runtime_common::{
+ constants::*,
+ dispatch::CollectionDispatchT,
+ ethereum::{EvmSponsorshipHandler},
+ config::sponsoring::DefaultSponsoringRateLimit,
+ DealWithFees,
+ },
+ Runtime,
+ Aura,
+ Balances,
+ Event,
+ ChainId,
+};
+use pallet_evm::{
+ EnsureAddressTruncated,
+ HashedAddressMapping,
+};
+
+pub type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
+
+impl pallet_evm::account::Config for Runtime {
+ type CrossAccountId = CrossAccountId;
+ type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
+ type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
+}
+
+// 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 / <Runtime as frame_system::Config>::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 pallet_evm::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()
+ }
+}
+
+pub struct FixedFee;
+impl pallet_evm::FeeCalculator for FixedFee {
+ fn min_gas_price() -> (U256, u64) {
+ (MIN_GAS_PRICE.into(), 0)
+ }
+}
+
+pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
+impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
+ fn find_author<'a, I>(digests: I) -> Option<H160>
+ where
+ I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
+ {
+ 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_evm::Config for Runtime {
+ type BlockGasLimit = BlockGasLimit;
+ type FeeCalculator = FixedFee;
+ type GasWeightMapping = FixedGasWeightMapping;
+ type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
+ type CallOrigin = EnsureAddressTruncated<Self>;
+ type WithdrawOrigin = EnsureAddressTruncated<Self>;
+ type AddressMapping = HashedAddressMapping<Self::Hashing>;
+ type PrecompilesType = ();
+ type PrecompilesValue = ();
+ type Currency = Balances;
+ type Event = Event;
+ type OnMethodCall = (
+ pallet_evm_migration::OnMethodCall<Self>,
+ pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
+ CollectionDispatchT<Self>,
+ pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
+ );
+ type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
+ type ChainId = ChainId;
+ type Runner = pallet_evm::runner::stack::Runner<Self>;
+ type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
+ type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
+ type FindAuthor = EthereumFindAuthor<Aura>;
+}
+
+impl pallet_evm_migration::Config for Runtime {
+ type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
+}
+
+impl pallet_ethereum::Config for Runtime {
+ type Event = Event;
+ type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
+}
+
+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,
+ ]);
+
+ // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
+ pub const EvmCollectionHelpersAddress: H160 = H160([
+ 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
+ ]);
+}
+
+impl pallet_evm_contract_helpers::Config for Runtime {
+ type ContractAddress = HelpersContractAddress;
+ type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
+}
+
+impl pallet_evm_coder_substrate::Config for Runtime {}
+
+impl pallet_evm_transaction_payment::Config for Runtime {
+ type EvmSponsorshipHandler = EvmSponsorshipHandler;
+ type Currency = Balances;
+}
runtime/common/config/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/mod.rs
@@ -0,0 +1,33 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+pub mod substrate;
+pub mod ethereum;
+pub mod sponsoring;
+pub mod pallets;
+pub mod parachain;
+pub mod xcm;
+pub mod orml;
+
+pub use {
+ substrate::*,
+ ethereum::*,
+ sponsoring::*,
+ pallets::*,
+ parachain::*,
+ self::xcm::*,
+ orml::*,
+};
runtime/common/config/orml.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/orml.rs
@@ -0,0 +1,38 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::parameter_types;
+use frame_system::EnsureSigned;
+use crate::{
+ runtime_common::constants::*,
+ Runtime, Event, RelayChainBlockNumberProvider,
+};
+use common_types::{AccountId, Balance};
+
+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<Runtime>;
+ type MinVestedTransfer = MinVestedTransfer;
+ type VestedTransferOrigin = EnsureSigned<AccountId>;
+ type WeightInfo = ();
+ type MaxVestingSchedules = MaxVestingSchedules;
+ type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
+}
runtime/common/config/pallets/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/pallets/mod.rs
@@ -0,0 +1,100 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::{
+ // weights::{Weight, constants::WEIGHT_PER_SECOND},
+ parameter_types,
+};
+use sp_runtime::traits::AccountIdConversion;
+use crate::{
+ runtime_common::{
+ constants::*,
+ dispatch::CollectionDispatchT,
+ config::{
+ substrate::TreasuryModuleId,
+ ethereum::EvmCollectionHelpersAddress,
+ },
+ weights::CommonWeights,
+ RelayChainBlockNumberProvider,
+ },
+ Runtime,
+ Event,
+ Call,
+ Balances,
+};
+use common_types::{AccountId, Balance, BlockNumber};
+use up_data_structs::{
+ mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
+};
+
+#[cfg(feature = "rmrk")]
+pub mod rmrk;
+
+#[cfg(feature = "scheduler")]
+pub mod scheduler;
+
+parameter_types! {
+ pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
+ pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
+}
+
+impl pallet_common::Config for Runtime {
+ type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
+ type Event = Event;
+ type Currency = Balances;
+ type CollectionCreationPrice = CollectionCreationPrice;
+ type TreasuryAccountId = TreasuryAccountId;
+ type CollectionDispatch = CollectionDispatchT<Self>;
+
+ type EvmTokenAddressMapping = EvmTokenAddressMapping;
+ type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
+ type ContractAddress = EvmCollectionHelpersAddress;
+}
+
+impl pallet_structure::Config for Runtime {
+ type Event = Event;
+ type Call = Call;
+ type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
+}
+
+impl pallet_fungible::Config for Runtime {
+ type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
+}
+impl pallet_refungible::Config for Runtime {
+ type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
+}
+impl pallet_nonfungible::Config for Runtime {
+ type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
+}
+
+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<Runtime>;
+}
+
+impl pallet_unique::Config for Runtime {
+ type Event = Event;
+ type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
+ type CommonWeightInfo = CommonWeights<Self>;
+ type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
+}
runtime/common/config/pallets/rmrk.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/pallets/rmrk.rs
@@ -0,0 +1,27 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use crate::{Runtime, Event};
+
+impl pallet_proxy_rmrk_core::Config for Runtime {
+ type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
+ type Event = Event;
+}
+
+impl pallet_proxy_rmrk_equip::Config for Runtime {
+ type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
+ type Event = Event;
+}
runtime/common/config/pallets/scheduler.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/pallets/scheduler.rs
@@ -0,0 +1,66 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::{
+ traits::PrivilegeCmp,
+ weights::Weight,
+ parameter_types
+};
+use frame_system::EnsureSigned;
+use sp_runtime::Perbill;
+use sp_std::cmp::Ordering;
+use crate::{
+ runtime_common::{
+ scheduler::SchedulerPaymentExecutor,
+ config::substrate::RuntimeBlockWeights,
+ },
+ Runtime, Call, Event, Origin, OriginCaller, Balances
+};
+use common_types::AccountId;
+
+parameter_types! {
+ pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
+ RuntimeBlockWeights::get().max_block;
+ pub const MaxScheduledPerBlock: u32 = 50;
+
+ pub const NoPreimagePostponement: Option<u32> = Some(10);
+ pub const Preimage: Option<u32> = Some(10);
+}
+
+/// Used the compare the privilege of an origin inside the scheduler.
+pub struct OriginPrivilegeCmp;
+
+impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
+ fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
+ Some(Ordering::Equal)
+ }
+}
+
+impl pallet_unique_scheduler::Config for Runtime {
+ type Event = Event;
+ type Origin = Origin;
+ type Currency = Balances;
+ type PalletsOrigin = OriginCaller;
+ type Call = Call;
+ type MaximumWeight = MaximumSchedulerWeight;
+ type ScheduleOrigin = EnsureSigned<AccountId>;
+ type MaxScheduledPerBlock = MaxScheduledPerBlock;
+ type WeightInfo = ();
+ type CallExecutor = SchedulerPaymentExecutor;
+ type OriginPrivilegeCmp = OriginPrivilegeCmp;
+ type PreimageProvider = ();
+ type NoPreimagePostponement = NoPreimagePostponement;
+}
runtime/common/config/parachain.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/parachain.rs
@@ -0,0 +1,52 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::{
+ weights::Weight,
+ parameter_types,
+};
+use crate::{
+ runtime_common::constants::*,
+ Runtime,
+ Event,
+ XcmpQueue,
+ DmpQueue,
+};
+
+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<Self>;
+ type OnSystemEvent = ();
+ // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
+ // MaxDownwardMessageWeight,
+ // XcmExecutor<XcmConfig>,
+ // 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 {}
runtime/common/config/sponsoring.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/sponsoring.rs
@@ -0,0 +1,38 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::parameter_types;
+use crate::{
+ runtime_common::{
+ constants::*,
+ sponsoring::UniqueSponsorshipHandler,
+ },
+ Runtime,
+};
+use common_types::BlockNumber;
+
+parameter_types! {
+ pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;
+}
+
+type SponsorshipHandler = (
+ UniqueSponsorshipHandler<Runtime>,
+ pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
+);
+
+impl pallet_charge_transaction::Config for Runtime {
+ type SponsorshipHandler = SponsorshipHandler;
+}
runtime/common/config/substrate.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/substrate.rs
@@ -0,0 +1,250 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::{
+ traits::{Everything, ConstU32},
+ weights::{
+ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight},
+ DispatchClass, WeightToFeePolynomial, WeightToFeeCoefficients,
+ ConstantMultiplier, WeightToFeeCoefficient,
+ },
+ parameter_types,
+ PalletId,
+};
+use sp_runtime::{
+ generic,
+ traits::{BlakeTwo256, AccountIdLookup},
+ Perbill, Permill, Percent,
+};
+use frame_system::{
+ limits::{BlockLength, BlockWeights},
+ EnsureRoot,
+};
+use sp_arithmetic::traits::{BaseArithmetic, Unsigned};
+use smallvec::smallvec;
+use crate::{
+ runtime_common::{
+ DealWithFees,
+ constants::*,
+ },
+ Runtime,
+ Event,
+ Call,
+ Origin,
+ PalletInfo,
+ System,
+ Balances,
+ Treasury,
+ SS58Prefix,
+ Version,
+};
+use common_types::*;
+
+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();
+}
+
+impl frame_system::Config for Runtime {
+ /// The data to be stored in an account.
+ type AccountData = pallet_balances::AccountData<Balance>;
+ /// 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<BlockNumber, BlakeTwo256>;
+ /// 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<AccountId, ()>;
+ /// 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<Self>;
+ /// 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<Self>;
+ /// Version of the runtime.
+ type Version = Version;
+ type MaxConsumers = ConstU32<16>;
+}
+
+impl pallet_randomness_collective_flip::Config for Runtime {}
+
+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;
+ pub const MaxReserves: u32 = 50;
+}
+
+impl pallet_balances::Config for Runtime {
+ type MaxLocks = MaxLocks;
+ type MaxReserves = MaxReserves;
+ type ReserveIdentifier = [u8; 16];
+ /// 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<Self>;
+}
+
+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<T>(sp_std::marker::PhantomData<T>);
+
+impl<T> WeightToFeePolynomial for LinearFee<T>
+where
+ T: BaseArithmetic + From<u32> + Copy + Unsigned,
+{
+ type Balance = T;
+
+ fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
+ smallvec!(WeightToFeeCoefficient {
+ 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<Balances, DealWithFees>;
+ type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
+ type OperationalFeeMultiplier = OperationalFeeMultiplier;
+ type WeightToFee = LinearFee<Balance>;
+ 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<AccountId>;
+ type RejectOrigin = EnsureRoot<AccountId>;
+ 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<Self>;
+ type MaxApprovals = MaxApprovals;
+}
+
+impl pallet_sudo::Config for Runtime {
+ type Event = Event;
+ type Call = Call;
+}
+
+parameter_types! {
+ pub const MaxAuthorities: u32 = 100_000;
+}
+
+impl pallet_aura::Config for Runtime {
+ type AuthorityId = AuraId;
+ type DisabledValidators = ();
+ type MaxAuthorities = MaxAuthorities;
+}
runtime/common/config/xcm.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/xcm.rs
@@ -0,0 +1,308 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::{
+ traits::{
+ tokens::currency::Currency as CurrencyT,
+ OnUnbalanced as OnUnbalancedT,
+ Get, Everything
+ },
+ weights::{Weight, WeightToFeePolynomial, WeightToFee},
+ parameter_types, match_types,
+};
+use frame_system::EnsureRoot;
+use sp_runtime::{
+ traits::{
+ Saturating, CheckedConversion, Zero,
+ },
+ SaturatedConversion,
+};
+use pallet_xcm::XcmPassthrough;
+use polkadot_parachain::primitives::Sibling;
+use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
+use xcm::latest::{
+ AssetId::{Concrete},
+ Fungibility::Fungible as XcmFungible,
+ MultiAsset,
+ Error as XcmError,
+};
+use xcm_executor::traits::{MatchesFungible, WeightTrader};
+use xcm_builder::{
+ AccountId32Aliases, AllowTopLevelPaidExecutionFrom, 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 crate::{
+ runtime_common::{
+ constants::*,
+ config::substrate::LinearFee
+ },
+ Runtime,
+ Call,
+ Event,
+ Origin,
+ Balances,
+ ParachainInfo,
+ ParachainSystem,
+ PolkadotXcm,
+ XcmpQueue,
+};
+use common_types::{AccountId, Balance};
+
+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<AccountId>,
+ // Sibling parachain origins convert to AccountId via the `ParaId::into`.
+ SiblingParachainConvertsVia<Sibling, AccountId>,
+ // Straight up local `AccountId32` origins just alias directly to `AccountId`.
+ AccountId32Aliases<RelayNetwork, AccountId>,
+);
+
+pub struct OnlySelfCurrency;
+impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
+ fn matches_fungible(a: &MultiAsset) -> Option<B> {
+ 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.
+ (),
+>;
+
+/// No local origins on this chain are allowed to dispatch XCM sends/executions.
+pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);
+
+/// 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<ParachainSystem, ()>,
+ // ..and XCMP to communicate with the sibling chains.
+ XcmpQueue,
+);
+
+/// 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<LocationToAccountId, Origin>,
+ // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
+ // recognised.
+ RelayChainAsNative<RelayOrigin, Origin>,
+ // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
+ // recognised.
+ SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
+ // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
+ // transaction from the Root origin.
+ ParentAsSuperuser<Origin>,
+ // Native signed account converter; this just converts an `AccountId32` origin into a normal
+ // `Origin::Signed` origin of the same 32-byte value.
+ SignedAccountId32AsNative<RelayNetwork, Origin>,
+ // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
+ XcmPassthrough<Origin>,
+);
+
+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;
+}
+
+match_types! {
+ pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
+ MultiLocation { parents: 1, interior: Here } |
+ MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
+ };
+}
+
+pub type Barrier = (
+ TakeWeightCredit,
+ AllowTopLevelPaidExecutionFrom<Everything>,
+ // ^^^ Parent & its unit plurality gets free execution
+);
+
+pub struct UsingOnlySelfCurrencyComponents<
+ WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+ AssetId: Get<MultiLocation>,
+ AccountId,
+ Currency: CurrencyT<AccountId>,
+ OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+>(
+ Weight,
+ Currency::Balance,
+ PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
+);
+impl<
+ WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+ AssetId: Get<MultiLocation>,
+ AccountId,
+ Currency: CurrencyT<AccountId>,
+ OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+ > WeightTrader
+ for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
+ fn new() -> Self {
+ Self(0, Zero::zero(), PhantomData)
+ }
+
+ fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
+ let amount = WeightToFee::weight_to_fee(&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<MultiAsset> {
+ let weight = weight.min(self.0);
+ let amount = WeightToFee::weight_to_fee(&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<Balance = Currency::Balance>,
+ AssetId: Get<MultiLocation>,
+ AccountId,
+ Currency: CurrencyT<AccountId>,
+ OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+ > Drop
+ for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
+ 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<Ancestry>;
+ type Barrier = Barrier;
+ type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
+ type Trader =
+ UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;
+ type ResponseHandler = (); // Don't handle responses for now.
+ type SubscriptionService = PolkadotXcm;
+
+ type AssetTrap = PolkadotXcm;
+ type AssetClaims = PolkadotXcm;
+}
+
+impl pallet_xcm::Config for Runtime {
+ type Event = Event;
+ type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
+ type XcmRouter = XcmRouter;
+ type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
+ type XcmExecuteFilter = Everything;
+ type XcmExecutor = XcmExecutor<XcmConfig>;
+ type XcmTeleportFilter = Everything;
+ type XcmReserveTransferFilter = Everything;
+ type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
+ type LocationInverter = LocationInverter<Ancestry>;
+ 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<XcmConfig>;
+}
+
+impl cumulus_pallet_xcmp_queue::Config for Runtime {
+ type WeightInfo = ();
+ type Event = Event;
+ type XcmExecutor = XcmExecutor<XcmConfig>;
+ type ChannelInfo = ParachainSystem;
+ type VersionWrapper = ();
+ type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
+ type ControllerOrigin = EnsureRoot<AccountId>;
+ type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
+}
+
+impl cumulus_pallet_dmp_queue::Config for Runtime {
+ type Event = Event;
+ type XcmExecutor = XcmExecutor<XcmConfig>;
+ type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
+}
runtime/common/constants.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/constants.rs
@@ -0,0 +1,55 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use sp_runtime::Perbill;
+use frame_support::{
+ parameter_types,
+ weights::{Weight, constants::WEIGHT_PER_SECOND},
+};
+use common_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;
+
+// Targeting 0.1 UNQ per transfer
+pub const WEIGHT_TO_FEE_COEFF: u32 = 207_890_902;
+
+// Targeting 0.15 UNQ per transfer via ETH
+pub const MIN_GAS_PRICE: u64 = 1_019_493_469_850;
+
+/// 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 TransactionByteFee: Balance = 501 * MICROUNIQUE;
+}
runtime/common/construct_runtime/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/construct_runtime/mod.rs
@@ -0,0 +1,90 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+mod util;
+
+#[macro_export]
+macro_rules! construct_runtime {
+ ($select_runtime:ident) => {
+ $crate::construct_runtime_impl! {
+ select_runtime($select_runtime);
+
+ pub enum Runtime where
+ Block = Block,
+ NodeBlock = opaque::Block,
+ UncheckedExtrinsic = UncheckedExtrinsic
+ {
+ ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
+ ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
+
+ Aura: pallet_aura::{Pallet, Config<T>} = 22,
+ AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
+
+ Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 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<T>} = 34,
+ Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
+ System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
+ Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
+ // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
+ // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
+
+ // XCM helpers.
+ XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
+ PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
+ CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
+ DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
+
+ // Unique Pallets
+ Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
+ Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
+
+ #[runtimes(opal)]
+ Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 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<T>} = 66,
+ Fungible: pallet_fungible::{Pallet, Storage} = 67,
+
+ #[runtimes(opal)]
+ Refungible: pallet_refungible::{Pallet, Storage} = 68,
+
+ Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
+ Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
+
+ #[runtimes(opal)]
+ RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
+
+ #[runtimes(opal)]
+ RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
+
+ // Frontier
+ EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 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,
+ }
+ }
+ }
+}
runtime/common/construct_runtime/util.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/construct_runtime/util.rs
@@ -0,0 +1,222 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#[macro_export]
+macro_rules! construct_runtime_impl {
+ (
+ select_runtime($select_runtime:ident);
+
+ pub enum Runtime where
+ $($where_ident:ident = $where_ty:ty),* $(,)?
+ {
+ $(
+ $(#[runtimes($($pallet_runtimes:ident),+ $(,)?)])?
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal
+ ),*
+ $(,)?
+ }
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime($select_runtime),
+ selected_pallets(),
+
+ where_clause($($where_ident = $where_ty),*),
+ pallets(
+ $(
+ $(#[runtimes($($pallet_runtimes),+)])?
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index
+ ),*,
+ )
+ }
+ }
+}
+
+#[macro_export]
+macro_rules! construct_runtime_helper {
+ (
+ select_runtime($select_runtime:ident),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ #[runtimes($($pallet_runtimes:ident),+)]
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::add_runtime_specific_pallets! {
+ select_runtime($select_runtime),
+ runtimes($($pallet_runtimes),+,),
+ selected_pallets($($selected_pallets)*),
+
+ where_clause($($where_clause)*),
+ pallets(
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ $($pallets_tl)*
+ )
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime($select_runtime),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets()
+ ) => {
+ frame_support::construct_runtime! {
+ pub enum Runtime where
+ $($where_clause)*
+ {
+ $($selected_pallets)*
+ }
+ }
+ };
+}
+
+#[macro_export]
+macro_rules! add_runtime_specific_pallets {
+ (
+ select_runtime(opal),
+ runtimes(opal, $($_runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime(opal),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime(quartz),
+ runtimes(quartz, $($_runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime(quartz),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime(unique),
+ runtimes(unique, $($_runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime(unique),
+ selected_pallets(
+ $($selected_pallets)*
+ $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
+ ),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ runtimes($_current_runtime:ident, $($runtime_tl:tt)*),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets($($pallets:tt)*)
+ ) => {
+ $crate::add_runtime_specific_pallets! {
+ select_runtime($select_runtime),
+ runtimes($($runtime_tl)*),
+ selected_pallets($($selected_pallets)*),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets)*)
+ }
+ };
+
+ (
+ select_runtime($select_runtime:ident),
+ runtimes(),
+ selected_pallets($($selected_pallets:tt)*),
+
+ where_clause($($where_clause:tt)*),
+ pallets(
+ $_pallet_name:ident: $_pallet_mod:ident::{$($_pallet_parts:ty),*} = $_index:literal,
+ $($pallets_tl:tt)*
+ )
+ ) => {
+ $crate::construct_runtime_helper! {
+ select_runtime($select_runtime),
+ selected_pallets($($selected_pallets)*),
+
+ where_clause($($where_clause)*),
+ pallets($($pallets_tl)*)
+ }
+ };
+}
runtime/common/dispatch.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/dispatch.rs
@@ -0,0 +1,187 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::{dispatch::DispatchResult, ensure};
+use pallet_evm::{PrecompileHandle, PrecompileResult};
+use sp_core::H160;
+use sp_runtime::DispatchError;
+use sp_std::{borrow::ToOwned, vec::Vec};
+use pallet_common::{
+ CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,
+ eth::map_eth_to_id,
+};
+pub use pallet_common::dispatch::CollectionDispatch;
+use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};
+use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};
+use pallet_refungible::{
+ Pallet as PalletRefungible, RefungibleHandle, erc_token::RefungibleTokenHandle,
+};
+use up_data_structs::{
+ CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,
+ CollectionId,
+};
+
+pub enum CollectionDispatchT<T>
+where
+ T: pallet_fungible::Config + pallet_nonfungible::Config + pallet_refungible::Config,
+{
+ Fungible(FungibleHandle<T>),
+ Nonfungible(NonfungibleHandle<T>),
+ Refungible(RefungibleHandle<T>),
+}
+impl<T> CollectionDispatch<T> for CollectionDispatchT<T>
+where
+ T: pallet_common::Config
+ + pallet_unique::Config
+ + pallet_fungible::Config
+ + pallet_nonfungible::Config
+ + pallet_refungible::Config,
+{
+ fn create(
+ sender: T::CrossAccountId,
+ data: CreateCollectionData<T::AccountId>,
+ ) -> Result<CollectionId, DispatchError> {
+ let id = match data.mode {
+ CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data, false)?,
+ CollectionMode::Fungible(decimal_points) => {
+ // check params
+ ensure!(
+ decimal_points <= MAX_DECIMAL_POINTS,
+ pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded
+ );
+ <PalletFungible<T>>::init_collection(sender, data)?
+ }
+ #[cfg(feature = "refungible")]
+ CollectionMode::ReFungible => <PalletRefungible<T>>::init_collection(sender, data)?,
+
+ #[cfg(not(feature = "refungible"))]
+ CollectionMode::ReFungible => {
+ return Err(DispatchError::Other("Refunginle pallet is not supported"))
+ }
+ };
+ Ok(id)
+ }
+
+ fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {
+ match collection.mode {
+ CollectionMode::ReFungible => {
+ PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?
+ }
+ CollectionMode::Fungible(_) => {
+ PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?
+ }
+ CollectionMode::NFT => {
+ PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?
+ }
+ }
+ Ok(())
+ }
+
+ fn dispatch(handle: CollectionHandle<T>) -> Self {
+ match handle.mode {
+ CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),
+ CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),
+ CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),
+ }
+ }
+
+ fn into_inner(self) -> CollectionHandle<T> {
+ match self {
+ Self::Fungible(f) => f.into_inner(),
+ Self::Nonfungible(f) => f.into_inner(),
+ Self::Refungible(f) => f.into_inner(),
+ }
+ }
+
+ fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {
+ match self {
+ Self::Fungible(h) => h,
+ Self::Nonfungible(h) => h,
+ Self::Refungible(h) => h,
+ }
+ }
+}
+
+impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>
+where
+ T: pallet_common::Config
+ + pallet_unique::Config
+ + pallet_fungible::Config
+ + pallet_nonfungible::Config
+ + pallet_refungible::Config,
+ T::AccountId: From<[u8; 32]>,
+{
+ fn is_reserved(target: &H160) -> bool {
+ map_eth_to_id(target).is_some()
+ }
+ fn is_used(target: &H160) -> bool {
+ map_eth_to_id(target)
+ .map(<CollectionById<T>>::contains_key)
+ .unwrap_or(false)
+ }
+ fn get_code(target: &H160) -> Option<Vec<u8>> {
+ if let Some(collection_id) = map_eth_to_id(target) {
+ let collection = <CollectionById<T>>::get(collection_id)?;
+ Some(
+ match collection.mode {
+ CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,
+ CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,
+ CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,
+ }
+ .to_owned(),
+ )
+ } else if let Some((collection_id, _token_id)) =
+ <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)
+ {
+ let collection = <CollectionById<T>>::get(collection_id)?;
+ if collection.mode != CollectionMode::ReFungible {
+ return None;
+ }
+ // TODO: check token existence
+ Some(<RefungibleTokenHandle<T>>::CODE.to_owned())
+ } else {
+ None
+ }
+ }
+ fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
+ if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {
+ let collection =
+ <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
+ let dispatched = Self::dispatch(collection);
+
+ match dispatched {
+ Self::Fungible(h) => h.call(handle),
+ Self::Nonfungible(h) => h.call(handle),
+ Self::Refungible(h) => h.call(handle),
+ }
+ } else if let Some((collection_id, token_id)) =
+ <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(
+ &handle.code_address(),
+ ) {
+ let collection =
+ <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
+ if collection.mode != CollectionMode::ReFungible {
+ return None;
+ }
+
+ let h = RefungibleHandle::cast(collection);
+ // TODO: check token existence
+ RefungibleTokenHandle(h, token_id).call(handle)
+ } else {
+ None
+ }
+ }
+}
runtime/common/ethereum/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/mod.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 <http://www.gnu.org/licenses/>.
+
+pub mod sponsoring;
+pub mod transaction_converter;
+pub mod self_contained_call;
+
+pub use {
+ sponsoring::*,
+ transaction_converter::*,
+ self_contained_call::*,
+};
runtime/common/ethereum/self_contained_call.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/self_contained_call.rs
@@ -0,0 +1,74 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use sp_core::H160;
+use sp_runtime::{
+ traits::{Dispatchable, DispatchInfoOf, PostDispatchInfoOf},
+ transaction_validity::{TransactionValidityError, TransactionValidity},
+};
+use crate::{Origin, Call};
+
+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<Result<Self::SignedInfo, TransactionValidityError>> {
+ match self {
+ Call::Ethereum(call) => call.check_self_contained(),
+ _ => None,
+ }
+ }
+
+ fn validate_self_contained(
+ &self,
+ info: &Self::SignedInfo,
+ dispatch_info: &DispatchInfoOf<Call>,
+ len: usize,
+ ) -> Option<TransactionValidity> {
+ match self {
+ Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
+ _ => None,
+ }
+ }
+
+ fn pre_dispatch_self_contained(
+ &self,
+ info: &Self::SignedInfo,
+ ) -> Option<Result<(), TransactionValidityError>> {
+ match self {
+ Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
+ _ => None,
+ }
+ }
+
+ fn apply_self_contained(
+ self,
+ info: Self::SignedInfo,
+ ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
+ match self {
+ call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(
+ Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),
+ )),
+ _ => None,
+ }
+ }
+}
runtime/common/ethereum/sponsoring.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/sponsoring.rs
@@ -0,0 +1,130 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+//! Implements EVM sponsoring logic via TransactionValidityHack
+
+use evm_coder::{Call, abi::AbiReader};
+use pallet_common::{CollectionHandle, eth::map_eth_to_id};
+use sp_core::H160;
+use sp_std::prelude::*;
+use up_sponsorship::SponsorshipHandler;
+use core::marker::PhantomData;
+use core::convert::TryInto;
+use pallet_evm::account::CrossAccountId;
+use up_data_structs::{TokenId, CreateItemData, CreateNftData, CollectionMode};
+use pallet_unique::Config as UniqueConfig;
+
+use crate::{
+ Runtime,
+ runtime_common::sponsoring::*
+};
+
+use pallet_nonfungible::erc::{
+ UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call, TokenPropertiesCall,
+};
+use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
+use pallet_fungible::Config as FungibleConfig;
+use pallet_nonfungible::Config as NonfungibleConfig;
+use pallet_refungible::Config as RefungibleConfig;
+
+pub type EvmSponsorshipHandler = (
+ UniqueEthSponsorshipHandler<Runtime>,
+ pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
+);
+
+pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);
+impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>
+ SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)> for UniqueEthSponsorshipHandler<T>
+{
+ fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {
+ let collection_id = map_eth_to_id(&call.0)?;
+ let collection = <CollectionHandle<T>>::new(collection_id)?;
+ let sponsor = collection.sponsorship.sponsor()?.clone();
+ let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
+ Some(T::CrossAccountId::from_sub(match &collection.mode {
+ CollectionMode::NFT => {
+ let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
+ match call {
+ UniqueNFTCall::TokenProperties(TokenPropertiesCall::SetProperty {
+ token_id,
+ key,
+ value,
+ ..
+ }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_set_token_property::<T>(
+ &collection,
+ &who,
+ &token_id,
+ key.len() + value.len(),
+ )
+ .map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721UniqueExtensions(
+ ERC721UniqueExtensionsCall::Transfer { token_id, .. },
+ ) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721Mintable(
+ ERC721MintableCall::Mint { token_id, .. }
+ | ERC721MintableCall::MintWithTokenUri { token_id, .. },
+ ) => {
+ let _token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_create_item::<T>(
+ &collection,
+ &who,
+ &CreateItemData::NFT(CreateNftData::default()),
+ )
+ .map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, from, .. }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ let from = T::CrossAccountId::from_eth(from);
+ withdraw_transfer::<T>(&collection, &from, &token_id).map(|()| sponsor)
+ }
+ UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_approve::<T>(&collection, who.as_sub(), &token_id)
+ .map(|()| sponsor)
+ }
+ _ => None,
+ }
+ }
+ CollectionMode::Fungible(_) => {
+ let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
+ #[allow(clippy::single_match)]
+ match call {
+ UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
+ withdraw_transfer::<T>(&collection, who, &TokenId::default())
+ .map(|()| sponsor)
+ }
+ UniqueFungibleCall::ERC20(ERC20Call::TransferFrom { from, .. }) => {
+ let from = T::CrossAccountId::from_eth(from);
+ withdraw_transfer::<T>(&collection, &from, &TokenId::default())
+ .map(|()| sponsor)
+ }
+ UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
+ withdraw_approve::<T>(&collection, who.as_sub(), &TokenId::default())
+ .map(|()| sponsor)
+ }
+ _ => None,
+ }
+ }
+ _ => None,
+ }?))
+ }
+}
runtime/common/ethereum/transaction_converter.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/transaction_converter.rs
@@ -0,0 +1,46 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use codec::{Encode, Decode};
+use crate::{
+ opaque,
+ Runtime,
+ UncheckedExtrinsic,
+};
+
+pub struct TransactionConverter;
+
+impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
+ fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
+ UncheckedExtrinsic::new_unsigned(
+ pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
+ )
+ }
+}
+
+impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
+ fn convert_transaction(
+ &self,
+ transaction: pallet_ethereum::Transaction,
+ ) -> opaque::UncheckedExtrinsic {
+ let extrinsic = UncheckedExtrinsic::new_unsigned(
+ pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
+ );
+ let encoded = extrinsic.encode();
+ opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
+ .expect("Encoded extrinsic is always valid")
+ }
+}
runtime/common/instance.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/instance.rs
@@ -0,0 +1,17 @@
+use crate::{
+ runtime_common::{
+ config::ethereum::CrossAccountId,
+ ethereum::TransactionConverter
+ },
+ Runtime,
+};
+use common_types::opaque::RuntimeInstance;
+
+impl RuntimeInstance for Runtime {
+ type CrossAccountId = CrossAccountId;
+ type TransactionConverter = TransactionConverter;
+
+ fn get_transaction_converter() -> TransactionConverter {
+ TransactionConverter
+ }
+}
runtime/common/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/mod.rs
@@ -0,0 +1,171 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+mod constants;
+mod construct_runtime;
+mod dispatch;
+mod runtime_apis;
+mod sponsoring;
+mod weights;
+mod config;
+mod instance;
+mod ethereum;
+mod scheduler;
+
+pub use {
+ constants::*,
+ dispatch::*,
+ sponsoring::*,
+ weights::*,
+ config::*,
+ instance::*,
+ ethereum::*,
+};
+
+use sp_core::H160;
+use frame_support::traits::{Currency, OnUnbalanced, Imbalance};
+use sp_runtime::{
+ generic,
+ traits::{BlakeTwo256, BlockNumberProvider},
+ impl_opaque_keys,
+};
+use sp_std::vec::Vec;
+
+#[cfg(feature = "std")]
+use sp_version::NativeVersion;
+
+use crate::{
+ Runtime, Call, Balances, Treasury, Aura, Signature, AllPalletsReversedWithSystemFirst,
+ InherentDataExt,
+};
+use common_types::{AccountId, BlockNumber};
+
+/// The address format for describing accounts.
+pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
+/// Block header type as expected by this runtime.
+pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+/// Block type as expected by this runtime.
+pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+/// A Block signed with a Justification
+pub type SignedBlock = generic::SignedBlock<Block>;
+/// BlockId type as expected by this runtime.
+pub type BlockId = generic::BlockId<Block>;
+
+impl_opaque_keys! {
+ pub struct SessionKeys {
+ pub aura: Aura,
+ }
+}
+
+/// The version information used to identify this runtime when compiled natively.
+#[cfg(feature = "std")]
+pub fn native_version() -> NativeVersion {
+ NativeVersion {
+ runtime_version: crate::VERSION,
+ can_author_with: Default::default(),
+ }
+}
+
+pub type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
+
+pub type SignedExtra = (
+ frame_system::CheckSpecVersion<Runtime>,
+ // system::CheckTxVersion<Runtime>,
+ frame_system::CheckGenesis<Runtime>,
+ frame_system::CheckEra<Runtime>,
+ frame_system::CheckNonce<Runtime>,
+ frame_system::CheckWeight<Runtime>,
+ ChargeTransactionPayment,
+ //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
+ pallet_ethereum::FakeTransactionFinalizer<Runtime>,
+);
+
+/// Unchecked extrinsic type as expected by this runtime.
+pub type UncheckedExtrinsic =
+ fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
+
+/// Extrinsic type that has already been checked.
+pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
+
+/// Executive: handles dispatch to the various modules.
+pub type Executive = frame_executive::Executive<
+ Runtime,
+ Block,
+ frame_system::ChainContext<Runtime>,
+ Runtime,
+ AllPalletsReversedWithSystemFirst,
+>;
+
+type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
+
+pub struct DealWithFees;
+impl OnUnbalanced<NegativeImbalance> for DealWithFees {
+ fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
+ 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);
+ }
+ }
+}
+
+pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
+
+impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
+ for RelayChainBlockNumberProvider<T>
+{
+ type BlockNumber = BlockNumber;
+
+ fn current_block_number() -> Self::BlockNumber {
+ cumulus_pallet_parachain_system::Pallet::<T>::validation_data()
+ .map(|d| d.relay_parent_number)
+ .unwrap_or_default()
+ }
+}
+
+pub(crate) struct CheckInherents;
+
+impl cumulus_pallet_parachain_system::CheckInherents<Block> 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)
+ }
+}
+
+#[derive(codec::Encode, codec::Decode)]
+pub enum XCMPMessage<XAccountId, XBalance> {
+ /// Transfer tokens to the given account from the Parachain account.
+ TransferToken(XAccountId, XBalance),
+}
runtime/common/runtime_apis.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/runtime_apis.rs
@@ -0,0 +1,708 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+#[macro_export]
+macro_rules! dispatch_unique_runtime {
+ ($collection:ident.$method:ident($($name:ident),*)) => {{
+ let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
+ let dispatch = collection.as_dyn();
+
+ Ok::<_, DispatchError>(dispatch.$method($($name),*))
+ }};
+}
+
+#[macro_export]
+macro_rules! impl_common_runtime_apis {
+ (
+ $(
+ #![custom_apis]
+
+ $($custom_apis:tt)+
+ )?
+ ) => {
+ use sp_std::prelude::*;
+ use sp_api::impl_runtime_apis;
+ use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};
+ use sp_runtime::{
+ Permill,
+ traits::Block as BlockT,
+ transaction_validity::{TransactionSource, TransactionValidity},
+ ApplyExtrinsicResult, DispatchError,
+ };
+ use fp_rpc::TransactionStatus;
+ use pallet_transaction_payment::{
+ FeeDetails, RuntimeDispatchInfo,
+ };
+ use pallet_evm::{
+ Runner, account::CrossAccountId as _,
+ Account as EVMAccount, FeeCalculator,
+ };
+ use up_data_structs::*;
+
+
+ impl_runtime_apis! {
+ $($($custom_apis)+)?
+
+ impl up_rpc::UniqueApi<Block, CrossAccountId, AccountId> for Runtime {
+ fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>, DispatchError> {
+ dispatch_unique_runtime!(collection.account_tokens(account))
+ }
+ fn collection_tokens(collection: CollectionId) -> Result<Vec<TokenId>, DispatchError> {
+ dispatch_unique_runtime!(collection.collection_tokens())
+ }
+ fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool, DispatchError> {
+ dispatch_unique_runtime!(collection.token_exists(token))
+ }
+
+ fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
+ dispatch_unique_runtime!(collection.token_owner(token))
+ }
+
+ fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec::<CrossAccountId>, DispatchError> {
+ dispatch_unique_runtime!(collection.token_owners(token))
+ }
+
+ fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
+ let budget = up_data_structs::budget::Value::new(10);
+
+ Ok(Some(<pallet_structure::Pallet<Runtime>>::find_topmost_owner(collection, token, &budget)?))
+ }
+ fn token_children(collection: CollectionId, token: TokenId) -> Result<Vec<TokenChild>, DispatchError> {
+ Ok(<pallet_nonfungible::Pallet<Runtime>>::token_children_ids(collection, token))
+ }
+ fn collection_properties(
+ collection: CollectionId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<Vec<Property>, DispatchError> {
+ let keys = keys.map(
+ |keys| Common::bytes_keys_to_property_keys(keys)
+ ).transpose()?;
+
+ Common::filter_collection_properties(collection, keys)
+ }
+
+ fn token_properties(
+ collection: CollectionId,
+ token_id: TokenId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<Vec<Property>, DispatchError> {
+ let keys = keys.map(
+ |keys| Common::bytes_keys_to_property_keys(keys)
+ ).transpose()?;
+
+ dispatch_unique_runtime!(collection.token_properties(token_id, keys))
+ }
+
+ fn property_permissions(
+ collection: CollectionId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {
+ let keys = keys.map(
+ |keys| Common::bytes_keys_to_property_keys(keys)
+ ).transpose()?;
+
+ Common::filter_property_permissions(collection, keys)
+ }
+
+ fn token_data(
+ collection: CollectionId,
+ token_id: TokenId,
+ keys: Option<Vec<Vec<u8>>>
+ ) -> Result<TokenData<CrossAccountId>, DispatchError> {
+ let token_data = TokenData {
+ properties: Self::token_properties(collection, token_id, keys)?,
+ owner: Self::token_owner(collection, token_id)?,
+ pieces: Self::total_pieces(collection, token_id)?.unwrap_or(0),
+ };
+
+ Ok(token_data)
+ }
+
+ fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {
+ dispatch_unique_runtime!(collection.total_supply())
+ }
+ fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32, DispatchError> {
+ dispatch_unique_runtime!(collection.account_balance(account))
+ }
+ fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128, DispatchError> {
+ dispatch_unique_runtime!(collection.balance(account, token))
+ }
+ fn allowance(
+ collection: CollectionId,
+ sender: CrossAccountId,
+ spender: CrossAccountId,
+ token: TokenId,
+ ) -> Result<u128, DispatchError> {
+ dispatch_unique_runtime!(collection.allowance(sender, spender, token))
+ }
+
+ fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::adminlist(collection))
+ }
+ fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::allowlist(collection))
+ }
+ fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::allowed(collection, user))
+ }
+ fn last_token_id(collection: CollectionId) -> Result<TokenId, DispatchError> {
+ dispatch_unique_runtime!(collection.last_token_id())
+ }
+ fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::rpc_collection(collection))
+ }
+ fn collection_stats() -> Result<CollectionStats, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::collection_stats())
+ }
+ fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {
+ Ok(<UniqueSponsorshipPredict<Runtime> as SponsorshipPredict<Runtime>>::predict(
+ collection,
+ account,
+ token
+ ))
+ }
+
+ fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {
+ Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))
+ }
+
+ fn total_pieces(collection: CollectionId, token_id: TokenId) -> Result<Option<u128>, DispatchError> {
+ dispatch_unique_runtime!(collection.total_pieces(token_id))
+ }
+ }
+
+ #[allow(unused_variables)]
+ impl rmrk_rpc::RmrkApi<
+ Block,
+ AccountId,
+ RmrkCollectionInfo<AccountId>,
+ RmrkInstanceInfo<AccountId>,
+ RmrkResourceInfo,
+ RmrkPropertyInfo,
+ RmrkBaseInfo<AccountId>,
+ RmrkPartType,
+ RmrkTheme
+ > for Runtime {
+ fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::last_collection_idx::<Runtime>();
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default());
+ }
+
+ fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::collection_by_id::<Runtime>(collection_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::nft_by_id::<Runtime>(collection_id, nft_by_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::account_tokens::<Runtime>(account_id, collection_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::nft_children::<Runtime>(collection_id, nft_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn collection_properties(
+ collection_id: RmrkCollectionId,
+ filter_keys: Option<Vec<RmrkPropertyKey>>
+ ) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::collection_properties::<Runtime>(collection_id, filter_keys);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn nft_properties(
+ collection_id: RmrkCollectionId,
+ nft_id: RmrkNftId,
+ filter_keys: Option<Vec<RmrkPropertyKey>>
+ ) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::nft_properties::<Runtime>(collection_id, nft_id, filter_keys);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn nft_resources(collection_id: RmrkCollectionId,nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::nft_resources::<Runtime>(collection_id, nft_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn nft_resource_priority(
+ collection_id: RmrkCollectionId,
+ nft_id: RmrkNftId,
+ resource_id: RmrkResourceId
+ ) -> Result<Option<u32>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_core::rpc::nft_resource_priority::<Runtime>(collection_id, nft_id, resource_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_equip::rpc::base::<Runtime>(base_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_equip::rpc::base_parts::<Runtime>(base_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+
+ fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_equip::rpc::theme_names::<Runtime>(base_id);
+
+ #[cfg(not(feature = "rmrk"))]
+ Ok(Default::default())
+ }
+
+ fn theme(
+ base_id: RmrkBaseId,
+ theme_name: RmrkThemeName,
+ filter_keys: Option<Vec<RmrkPropertyKey>>
+ ) -> Result<Option<RmrkTheme>, DispatchError> {
+ #[cfg(feature = "rmrk")]
+ return pallet_proxy_rmrk_equip::rpc::theme::<Runtime>(base_id, theme_name, filter_keys);
+
+ #[cfg(not(feature = "rmrk"))]
+ return Ok(Default::default())
+ }
+ }
+
+ impl sp_api::Core<Block> for Runtime {
+ fn version() -> RuntimeVersion {
+ VERSION
+ }
+
+ fn execute_block(block: Block) {
+ Executive::execute_block(block)
+ }
+
+ fn initialize_block(header: &<Block as BlockT>::Header) {
+ Executive::initialize_block(header)
+ }
+ }
+
+ impl sp_api::Metadata<Block> for Runtime {
+ fn metadata() -> OpaqueMetadata {
+ OpaqueMetadata::new(Runtime::metadata().into())
+ }
+ }
+
+ impl sp_block_builder::BlockBuilder<Block> for Runtime {
+ fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
+ Executive::apply_extrinsic(extrinsic)
+ }
+
+ fn finalize_block() -> <Block as BlockT>::Header {
+ Executive::finalize_block()
+ }
+
+ fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
+ data.create_extrinsics()
+ }
+
+ fn check_inherents(
+ block: Block,
+ data: sp_inherents::InherentData,
+ ) -> sp_inherents::CheckInherentsResult {
+ data.check_extrinsics(&block)
+ }
+
+ // fn random_seed() -> <Block as BlockT>::Hash {
+ // RandomnessCollectiveFlip::random_seed().0
+ // }
+ }
+
+ impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
+ fn validate_transaction(
+ source: TransactionSource,
+ tx: <Block as BlockT>::Extrinsic,
+ hash: <Block as BlockT>::Hash,
+ ) -> TransactionValidity {
+ Executive::validate_transaction(source, tx, hash)
+ }
+ }
+
+ impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
+ fn offchain_worker(header: &<Block as BlockT>::Header) {
+ Executive::offchain_worker(header)
+ }
+ }
+
+ impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {
+ fn chain_id() -> u64 {
+ <Runtime as pallet_evm::Config>::ChainId::get()
+ }
+
+ fn account_basic(address: H160) -> EVMAccount {
+ let (account, _) = EVM::account_basic(&address);
+ account
+ }
+
+ fn gas_price() -> U256 {
+ let (price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
+ price
+ }
+
+ fn account_code_at(address: H160) -> Vec<u8> {
+ EVM::account_codes(address)
+ }
+
+ fn author() -> H160 {
+ <pallet_evm::Pallet<Runtime>>::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<u8>,
+ value: U256,
+ gas_limit: U256,
+ max_fee_per_gas: Option<U256>,
+ max_priority_fee_per_gas: Option<U256>,
+ nonce: Option<U256>,
+ estimate: bool,
+ access_list: Option<Vec<(H160, Vec<H256>)>>,
+ ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {
+ let config = if estimate {
+ let mut config = <Runtime as pallet_evm::Config>::config().clone();
+ config.estimate = true;
+ Some(config)
+ } else {
+ None
+ };
+
+ let is_transactional = false;
+ <Runtime as pallet_evm::Config>::Runner::call(
+ CrossAccountId::from_eth(from),
+ to,
+ data,
+ value,
+ gas_limit.low_u64(),
+ max_fee_per_gas,
+ max_priority_fee_per_gas,
+ nonce,
+ access_list.unwrap_or_default(),
+ is_transactional,
+ config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
+ ).map_err(|err| err.error.into())
+ }
+
+ #[allow(clippy::redundant_closure)]
+ fn create(
+ from: H160,
+ data: Vec<u8>,
+ value: U256,
+ gas_limit: U256,
+ max_fee_per_gas: Option<U256>,
+ max_priority_fee_per_gas: Option<U256>,
+ nonce: Option<U256>,
+ estimate: bool,
+ access_list: Option<Vec<(H160, Vec<H256>)>>,
+ ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {
+ let config = if estimate {
+ let mut config = <Runtime as pallet_evm::Config>::config().clone();
+ config.estimate = true;
+ Some(config)
+ } else {
+ None
+ };
+
+ let is_transactional = false;
+ <Runtime as pallet_evm::Config>::Runner::create(
+ CrossAccountId::from_eth(from),
+ data,
+ value,
+ gas_limit.low_u64(),
+ max_fee_per_gas,
+ max_priority_fee_per_gas,
+ nonce,
+ access_list.unwrap_or_default(),
+ is_transactional,
+ config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
+ ).map_err(|err| err.error.into())
+ }
+
+ fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {
+ Ethereum::current_transaction_statuses()
+ }
+
+ fn current_block() -> Option<pallet_ethereum::Block> {
+ Ethereum::current_block()
+ }
+
+ fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {
+ Ethereum::current_receipts()
+ }
+
+ fn current_all() -> (
+ Option<pallet_ethereum::Block>,
+ Option<Vec<pallet_ethereum::Receipt>>,
+ Option<Vec<TransactionStatus>>
+ ) {
+ (
+ Ethereum::current_block(),
+ Ethereum::current_receipts(),
+ Ethereum::current_transaction_statuses()
+ )
+ }
+
+ fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {
+ xts.into_iter().filter_map(|xt| match xt.0.function {
+ Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
+ _ => None
+ }).collect()
+ }
+
+ fn elasticity() -> Option<Permill> {
+ None
+ }
+ }
+
+ impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {
+ fn convert_transaction(transaction: pallet_ethereum::Transaction) -> <Block as BlockT>::Extrinsic {
+ UncheckedExtrinsic::new_unsigned(
+ pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
+ )
+ }
+ }
+
+ impl sp_session::SessionKeys<Block> for Runtime {
+ fn decode_session_keys(
+ encoded: Vec<u8>,
+ ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
+ SessionKeys::decode_into_raw_public_keys(&encoded)
+ }
+
+ fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
+ SessionKeys::generate(seed)
+ }
+ }
+
+ impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
+ fn slot_duration() -> sp_consensus_aura::SlotDuration {
+ sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
+ }
+
+ fn authorities() -> Vec<AuraId> {
+ Aura::authorities().to_vec()
+ }
+ }
+
+ impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
+ fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
+ ParachainSystem::collect_collation_info(header)
+ }
+ }
+
+ impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
+ fn account_nonce(account: AccountId) -> Index {
+ System::account_nonce(account)
+ }
+ }
+
+ impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
+ fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
+ TransactionPayment::query_info(uxt, len)
+ }
+ fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
+ TransactionPayment::query_fee_details(uxt, len)
+ }
+ }
+
+ /*
+ impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>
+ for Runtime
+ {
+ fn call(
+ origin: AccountId,
+ dest: AccountId,
+ value: Balance,
+ gas_limit: u64,
+ input_data: Vec<u8>,
+ ) -> 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<Hash>,
+ data: Vec<u8>,
+ salt: Vec<u8>,
+ ) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>
+ {
+ 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<BlockNumber> {
+ Contracts::rent_projection(address)
+ }
+ }
+ */
+
+ #[cfg(feature = "runtime-benchmarks")]
+ impl frame_benchmarking::Benchmark<Block> for Runtime {
+ fn benchmark_metadata(extra: bool) -> (
+ Vec<frame_benchmarking::BenchmarkList>,
+ Vec<frame_support::traits::StorageInfo>,
+ ) {
+ use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};
+ use frame_support::traits::StorageInfoTrait;
+
+ let mut list = Vec::<BenchmarkList>::new();
+
+ list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);
+ list_benchmark!(list, extra, pallet_common, Common);
+ list_benchmark!(list, extra, pallet_unique, Unique);
+ list_benchmark!(list, extra, pallet_structure, Structure);
+ 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_unique_scheduler, Scheduler);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ list_benchmark!(list, extra, pallet_proxy_rmrk_core, RmrkCore);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ list_benchmark!(list, extra, pallet_proxy_rmrk_equip, RmrkEquip);
+
+ // 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<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
+ use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};
+
+ let allowlist: Vec<TrackedStorageKey> = vec![
+ // Total Issuance
+ hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),
+
+ // Block Number
+ hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").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(),
+
+ // Evm CurrentLogs
+ hex_literal::hex!("1da53b775b270400e7e61ed5cbc5a146547f210cec367e9af919603343b9cb56").to_vec().into(),
+
+ // Transactional depth
+ hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a").to_vec().into(),
+ ];
+
+ let mut batches = Vec::<BenchmarkBatch>::new();
+ let params = (&config, &allowlist);
+
+ add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);
+ add_benchmark!(params, batches, pallet_common, Common);
+ add_benchmark!(params, batches, pallet_unique, Unique);
+ add_benchmark!(params, batches, pallet_structure, Structure);
+ 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_unique_scheduler, Scheduler);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ add_benchmark!(params, batches, pallet_proxy_rmrk_core, RmrkCore);
+
+ #[cfg(not(feature = "unique-runtime"))]
+ add_benchmark!(params, batches, pallet_proxy_rmrk_equip, RmrkEquip);
+
+ // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);
+
+ if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
+ Ok(batches)
+ }
+ }
+
+ #[cfg(feature = "try-runtime")]
+ impl frame_try_runtime::TryRuntime<Block> for Runtime {
+ fn on_runtime_upgrade() -> (Weight, Weight) {
+ log::info!("try-runtime::on_runtime_upgrade unique-chain.");
+ let weight = Executive::try_runtime_upgrade().unwrap();
+ (weight, RuntimeBlockWeights::get().max_block)
+ }
+
+ fn execute_block_no_check(block: Block) -> Weight {
+ Executive::execute_block_no_check(block)
+ }
+ }
+ }
+ }
+}
runtime/common/scheduler.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/scheduler.rs
@@ -0,0 +1,144 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use frame_support::{
+ traits::NamedReservableCurrency,
+ weights::{GetDispatchInfo, PostDispatchInfo, DispatchInfo},
+};
+use sp_runtime::{
+ traits::{Dispatchable, Applyable, Member},
+ generic::Era,
+ transaction_validity::TransactionValidityError,
+ DispatchErrorWithPostInfo, DispatchError,
+};
+use crate::{
+ Runtime, Call, Origin, Balances,
+ ChargeTransactionPayment,
+};
+use common_types::{AccountId, Balance};
+use fp_self_contained::SelfContainedCall;
+use pallet_unique_scheduler::DispatchCall;
+
+/// The SignedExtension to the basic transaction logic.
+pub type SignedExtraScheduler = (
+ frame_system::CheckSpecVersion<Runtime>,
+ frame_system::CheckGenesis<Runtime>,
+ frame_system::CheckEra<Runtime>,
+ frame_system::CheckNonce<Runtime>,
+ frame_system::CheckWeight<Runtime>,
+);
+
+fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
+ (
+ frame_system::CheckSpecVersion::<Runtime>::new(),
+ frame_system::CheckGenesis::<Runtime>::new(),
+ frame_system::CheckEra::<Runtime>::from(Era::Immortal),
+ frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
+ from,
+ )),
+ frame_system::CheckWeight::<Runtime>::new(),
+ // sponsoring transaction logic
+ // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
+ )
+}
+
+pub struct SchedulerPaymentExecutor;
+
+impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
+ DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
+where
+ <T as frame_system::Config>::Call: Member
+ + Dispatchable<Origin = Origin, Info = DispatchInfo>
+ + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
+ + GetDispatchInfo
+ + From<frame_system::Call<Runtime>>,
+ SelfContainedSignedInfo: Send + Sync + 'static,
+ Call: From<<T as frame_system::Config>::Call>
+ + From<<T as pallet_unique_scheduler::Config>::Call>
+ + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
+ sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
+{
+ fn dispatch_call(
+ signer: <T as frame_system::Config>::AccountId,
+ call: <T as pallet_unique_scheduler::Config>::Call,
+ ) -> Result<
+ Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
+ TransactionValidityError,
+ > {
+ let dispatch_info = call.get_dispatch_info();
+ let extrinsic = fp_self_contained::CheckedExtrinsic::<
+ AccountId,
+ Call,
+ SignedExtraScheduler,
+ SelfContainedSignedInfo,
+ > {
+ signed:
+ fp_self_contained::CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
+ signer.clone().into(),
+ get_signed_extras(signer.into()),
+ ),
+ function: call.into(),
+ };
+
+ extrinsic.apply::<Runtime>(&dispatch_info, 0)
+ }
+
+ fn reserve_balance(
+ id: [u8; 16],
+ sponsor: <T as frame_system::Config>::AccountId,
+ call: <T as pallet_unique_scheduler::Config>::Call,
+ count: u32,
+ ) -> Result<(), DispatchError> {
+ let dispatch_info = call.get_dispatch_info();
+ let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
+ .saturating_mul(count.into());
+
+ <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
+ &id,
+ &(sponsor.into()),
+ weight,
+ )
+ }
+
+ fn pay_for_call(
+ id: [u8; 16],
+ sponsor: <T as frame_system::Config>::AccountId,
+ call: <T as pallet_unique_scheduler::Config>::Call,
+ ) -> Result<u128, DispatchError> {
+ let dispatch_info = call.get_dispatch_info();
+ let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
+ Ok(
+ <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
+ &id,
+ &(sponsor.into()),
+ weight,
+ ),
+ )
+ }
+
+ fn cancel_reserve(
+ id: [u8; 16],
+ sponsor: <T as frame_system::Config>::AccountId,
+ ) -> Result<u128, DispatchError> {
+ Ok(
+ <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
+ &id,
+ &(sponsor.into()),
+ u128::MAX,
+ ),
+ )
+ }
+}
runtime/common/sponsoring.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/sponsoring.rs
@@ -0,0 +1,359 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use core::marker::PhantomData;
+use up_sponsorship::SponsorshipHandler;
+use frame_support::{
+ traits::{IsSubType},
+ storage::{StorageMap, StorageDoubleMap, StorageNMap},
+};
+use up_data_structs::{
+ CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, NFT_SPONSOR_TRANSFER_TIMEOUT,
+ REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode, CreateItemData,
+};
+use sp_runtime::traits::Saturating;
+use pallet_common::{CollectionHandle};
+use pallet_evm::account::CrossAccountId;
+use pallet_unique::{
+ Call as UniqueCall, Config as UniqueConfig, FungibleApproveBasket, RefungibleApproveBasket,
+ NftApproveBasket, CreateItemBasket, ReFungibleTransferBasket, FungibleTransferBasket,
+ NftTransferBasket, TokenPropertyBasket,
+};
+use pallet_fungible::Config as FungibleConfig;
+use pallet_nonfungible::Config as NonfungibleConfig;
+use pallet_refungible::Config as RefungibleConfig;
+
+pub trait Config: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
+impl<T> Config for T where T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
+
+// TODO: permission check?
+pub fn withdraw_set_token_property<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::CrossAccountId,
+ item_id: &TokenId,
+ data_size: usize,
+) -> Option<()> {
+ // preliminary sponsoring correctness check
+ match collection.mode {
+ CollectionMode::NFT => {
+ let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
+ if !owner.conv_eq(who) {
+ return None;
+ }
+ }
+ CollectionMode::Fungible(_) => {
+ // Fungible tokens have no properties
+ return None;
+ }
+ CollectionMode::ReFungible => {
+ if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
+ return None;
+ }
+ }
+ }
+
+ if data_size > collection.limits.sponsored_data_size() as usize {
+ return None;
+ }
+
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection.limits.sponsored_data_rate_limit()?;
+
+ if let Some(last_tx_block) = TokenPropertyBasket::<T>::get(collection.id, item_id) {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ <TokenPropertyBasket<T>>::insert(collection.id, item_id, block_number);
+
+ Some(())
+}
+
+pub fn withdraw_transfer<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::CrossAccountId,
+ item_id: &TokenId,
+) -> Option<()> {
+ // preliminary sponsoring correctness check
+ match collection.mode {
+ CollectionMode::NFT => {
+ let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
+ if !owner.conv_eq(who) {
+ return None;
+ }
+ }
+ CollectionMode::Fungible(_) => {
+ if item_id != &TokenId::default() {
+ return None;
+ }
+ if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {
+ return None;
+ }
+ }
+ CollectionMode::ReFungible => {
+ if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
+ return None;
+ }
+ }
+ }
+
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match collection.mode {
+ CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
+
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
+ }
+ CollectionMode::ReFungible => {
+ <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who.as_sub()))
+ }
+ };
+
+ if let Some(last_tx_block) = last_tx_block {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::insert(collection.id, who.as_sub(), block_number)
+ }
+ CollectionMode::ReFungible => <ReFungibleTransferBasket<T>>::insert(
+ (collection.id, item_id, who.as_sub()),
+ block_number,
+ ),
+ };
+
+ Some(())
+}
+
+pub fn withdraw_create_item<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::CrossAccountId,
+ properties: &CreateItemData,
+) -> Option<()> {
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match properties {
+ CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
+
+ if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, who.as_sub())) {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ CreateItemBasket::<T>::insert((collection.id, who.as_sub()), block_number);
+
+ Some(())
+}
+
+pub fn withdraw_approve<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::AccountId,
+ item_id: &TokenId,
+) -> Option<()> {
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection.limits.sponsor_approve_timeout();
+
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),
+ CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),
+ CollectionMode::ReFungible => {
+ <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))
+ }
+ };
+
+ if let Some(last_tx_block) = last_tx_block {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
+
+ match collection.mode {
+ CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),
+ CollectionMode::Fungible(_) => {
+ <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)
+ }
+ CollectionMode::ReFungible => {
+ <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)
+ }
+ };
+
+ Some(())
+}
+
+fn load<T: UniqueConfig>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {
+ let collection = CollectionHandle::new(id)?;
+ let sponsor = collection.sponsorship.sponsor().cloned()?;
+ Some((sponsor, collection))
+}
+
+pub struct UniqueSponsorshipHandler<T>(PhantomData<T>);
+impl<T, C> SponsorshipHandler<T::AccountId, C> for UniqueSponsorshipHandler<T>
+where
+ T: Config,
+ C: IsSubType<UniqueCall<T>>,
+{
+ fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {
+ match IsSubType::<UniqueCall<T>>::is_sub_type(call)? {
+ UniqueCall::set_token_properties {
+ collection_id,
+ token_id,
+ properties,
+ ..
+ } => {
+ let (sponsor, collection) = load::<T>(*collection_id)?;
+ withdraw_set_token_property(
+ &collection,
+ &T::CrossAccountId::from_sub(who.clone()),
+ &token_id,
+ // No overflow may happen, as data larger than usize can't reach here
+ properties.iter().map(|p| p.key.len() + p.value.len()).sum(),
+ )
+ .map(|()| sponsor)
+ }
+ UniqueCall::create_item {
+ collection_id,
+ data,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_create_item::<T>(
+ &collection,
+ &T::CrossAccountId::from_sub(who.clone()),
+ data,
+ )
+ .map(|()| sponsor)
+ }
+ UniqueCall::transfer {
+ collection_id,
+ item_id,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_transfer::<T>(
+ &collection,
+ &T::CrossAccountId::from_sub(who.clone()),
+ item_id,
+ )
+ .map(|()| sponsor)
+ }
+ UniqueCall::transfer_from {
+ collection_id,
+ item_id,
+ from,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_transfer::<T>(&collection, from, item_id).map(|()| sponsor)
+ }
+ UniqueCall::approve {
+ collection_id,
+ item_id,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)
+ }
+ _ => None,
+ }
+ }
+}
+
+pub trait SponsorshipPredict<T: Config> {
+ fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>
+ where
+ u64: From<<T as frame_system::Config>::BlockNumber>;
+}
+
+pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);
+
+impl<T: Config> SponsorshipPredict<T> for UniqueSponsorshipPredict<T> {
+ fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>
+ where
+ u64: From<<T as frame_system::Config>::BlockNumber>,
+ {
+ let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;
+ let _ = collection.sponsorship.sponsor()?;
+
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match collection.mode {
+ CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
+
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
+ }
+ CollectionMode::ReFungible => {
+ <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))
+ }
+ };
+
+ if let Some(last_tx_block) = last_tx_block {
+ return Some(
+ last_tx_block
+ .saturating_add(limit.into())
+ .saturating_sub(block_number)
+ .into(),
+ );
+ }
+
+ let token_exists = match collection.mode {
+ CollectionMode::NFT => {
+ <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))
+ }
+ CollectionMode::Fungible(_) => token == TokenId::default(),
+ CollectionMode::ReFungible => {
+ <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))
+ }
+ };
+
+ if token_exists {
+ Some(0)
+ } else {
+ None
+ }
+ }
+}
runtime/common/src/constants.rsdiffbeforeafterboth--- a/runtime/common/src/constants.rs
+++ /dev/null
@@ -1,57 +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 <http://www.gnu.org/licenses/>.
-
-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;
-
-// Targeting 0.1 UNQ per transfer
-pub const WEIGHT_TO_FEE_COEFF: u32 = 207_890_902;
-
-// Targeting 0.15 UNQ per transfer via ETH
-pub const MIN_GAS_PRICE: u64 = 1_019_493_469_850;
-
-/// 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;
-}
runtime/common/src/construct_runtime/mod.rsdiffbeforeafterboth--- a/runtime/common/src/construct_runtime/mod.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-mod util;
-
-#[macro_export]
-macro_rules! construct_runtime {
- ($select_runtime:ident) => {
- $crate::construct_runtime_impl! {
- select_runtime($select_runtime);
-
- pub enum Runtime where
- Block = Block,
- NodeBlock = opaque::Block,
- UncheckedExtrinsic = UncheckedExtrinsic
- {
- ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
- ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
-
- Aura: pallet_aura::{Pallet, Config<T>} = 22,
- AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
-
- Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 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<T>} = 34,
- Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
- System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,
- Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,
- // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
- // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
-
- // XCM helpers.
- XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
- PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
- CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
- DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
-
- // Unique Pallets
- Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
- Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,
-
- #[runtimes(opal)]
- Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event<T>} = 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<T>} = 66,
- Fungible: pallet_fungible::{Pallet, Storage} = 67,
-
- #[runtimes(opal)]
- Refungible: pallet_refungible::{Pallet, Storage} = 68,
-
- Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,
- Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,
-
- #[runtimes(opal)]
- RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,
-
- #[runtimes(opal)]
- RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,
-
- // Frontier
- EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 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,
- }
- }
- }
-}
runtime/common/src/construct_runtime/util.rsdiffbeforeafterboth--- a/runtime/common/src/construct_runtime/util.rs
+++ /dev/null
@@ -1,206 +0,0 @@
-#[macro_export]
-macro_rules! construct_runtime_impl {
- (
- select_runtime($select_runtime:ident);
-
- pub enum Runtime where
- $($where_ident:ident = $where_ty:ty),* $(,)?
- {
- $(
- $(#[runtimes($($pallet_runtimes:ident),+ $(,)?)])?
- $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal
- ),*
- $(,)?
- }
- ) => {
- $crate::construct_runtime_helper! {
- select_runtime($select_runtime),
- selected_pallets(),
-
- where_clause($($where_ident = $where_ty),*),
- pallets(
- $(
- $(#[runtimes($($pallet_runtimes),+)])?
- $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index
- ),*,
- )
- }
- }
-}
-
-#[macro_export]
-macro_rules! construct_runtime_helper {
- (
- select_runtime($select_runtime:ident),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets(
- #[runtimes($($pallet_runtimes:ident),+)]
- $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
-
- $($pallets_tl:tt)*
- )
- ) => {
- $crate::add_runtime_specific_pallets! {
- select_runtime($select_runtime),
- runtimes($($pallet_runtimes),+,),
- selected_pallets($($selected_pallets)*),
-
- where_clause($($where_clause)*),
- pallets(
- $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
- $($pallets_tl)*
- )
- }
- };
-
- (
- select_runtime($select_runtime:ident),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets(
- $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
-
- $($pallets_tl:tt)*
- )
- ) => {
- $crate::construct_runtime_helper! {
- select_runtime($select_runtime),
- selected_pallets(
- $($selected_pallets)*
- $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
- ),
-
- where_clause($($where_clause)*),
- pallets($($pallets_tl)*)
- }
- };
-
- (
- select_runtime($select_runtime:ident),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets()
- ) => {
- frame_support::construct_runtime! {
- pub enum Runtime where
- $($where_clause)*
- {
- $($selected_pallets)*
- }
- }
- };
-}
-
-#[macro_export]
-macro_rules! add_runtime_specific_pallets {
- (
- select_runtime(opal),
- runtimes(opal, $($_runtime_tl:tt)*),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets(
- $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
- $($pallets_tl:tt)*
- )
- ) => {
- $crate::construct_runtime_helper! {
- select_runtime(opal),
- selected_pallets(
- $($selected_pallets)*
- $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
- ),
-
- where_clause($($where_clause)*),
- pallets($($pallets_tl)*)
- }
- };
-
- (
- select_runtime(quartz),
- runtimes(quartz, $($_runtime_tl:tt)*),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets(
- $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
- $($pallets_tl:tt)*
- )
- ) => {
- $crate::construct_runtime_helper! {
- select_runtime(quartz),
- selected_pallets(
- $($selected_pallets)*
- $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
- ),
-
- where_clause($($where_clause)*),
- pallets($($pallets_tl)*)
- }
- };
-
- (
- select_runtime(unique),
- runtimes(unique, $($_runtime_tl:tt)*),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets(
- $pallet_name:ident: $pallet_mod:ident::{$($pallet_parts:ty),*} = $index:literal,
- $($pallets_tl:tt)*
- )
- ) => {
- $crate::construct_runtime_helper! {
- select_runtime(unique),
- selected_pallets(
- $($selected_pallets)*
- $pallet_name: $pallet_mod::{$($pallet_parts),*} = $index,
- ),
-
- where_clause($($where_clause)*),
- pallets($($pallets_tl)*)
- }
- };
-
- (
- select_runtime($select_runtime:ident),
- runtimes($_current_runtime:ident, $($runtime_tl:tt)*),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets($($pallets:tt)*)
- ) => {
- $crate::add_runtime_specific_pallets! {
- select_runtime($select_runtime),
- runtimes($($runtime_tl)*),
- selected_pallets($($selected_pallets)*),
-
- where_clause($($where_clause)*),
- pallets($($pallets)*)
- }
- };
-
- (
- select_runtime($select_runtime:ident),
- runtimes(),
- selected_pallets($($selected_pallets:tt)*),
-
- where_clause($($where_clause:tt)*),
- pallets(
- $_pallet_name:ident: $_pallet_mod:ident::{$($_pallet_parts:ty),*} = $_index:literal,
- $($pallets_tl:tt)*
- )
- ) => {
- $crate::construct_runtime_helper! {
- select_runtime($select_runtime),
- selected_pallets($($selected_pallets)*),
-
- where_clause($($where_clause)*),
- pallets($($pallets_tl)*)
- }
- };
-}
runtime/common/src/dispatch.rsdiffbeforeafterboth--- a/runtime/common/src/dispatch.rs
+++ /dev/null
@@ -1,187 +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 <http://www.gnu.org/licenses/>.
-
-use frame_support::{dispatch::DispatchResult, ensure};
-use pallet_evm::{PrecompileHandle, PrecompileResult};
-use sp_core::H160;
-use sp_runtime::DispatchError;
-use sp_std::{borrow::ToOwned, vec::Vec};
-use pallet_common::{
- CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,
- eth::map_eth_to_id,
-};
-pub use pallet_common::dispatch::CollectionDispatch;
-use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};
-use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};
-use pallet_refungible::{
- Pallet as PalletRefungible, RefungibleHandle, erc_token::RefungibleTokenHandle,
-};
-use up_data_structs::{
- CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,
- CollectionId,
-};
-
-pub enum CollectionDispatchT<T>
-where
- T: pallet_fungible::Config + pallet_nonfungible::Config + pallet_refungible::Config,
-{
- Fungible(FungibleHandle<T>),
- Nonfungible(NonfungibleHandle<T>),
- Refungible(RefungibleHandle<T>),
-}
-impl<T> CollectionDispatch<T> for CollectionDispatchT<T>
-where
- T: pallet_common::Config
- + pallet_unique::Config
- + pallet_fungible::Config
- + pallet_nonfungible::Config
- + pallet_refungible::Config,
-{
- fn create(
- sender: T::CrossAccountId,
- data: CreateCollectionData<T::AccountId>,
- ) -> Result<CollectionId, DispatchError> {
- let id = match data.mode {
- CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data, false)?,
- CollectionMode::Fungible(decimal_points) => {
- // check params
- ensure!(
- decimal_points <= MAX_DECIMAL_POINTS,
- pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded
- );
- <PalletFungible<T>>::init_collection(sender, data)?
- }
- #[cfg(feature = "refungible")]
- CollectionMode::ReFungible => <PalletRefungible<T>>::init_collection(sender, data)?,
-
- #[cfg(not(feature = "refungible"))]
- CollectionMode::ReFungible => {
- return Err(DispatchError::Other("Refunginle pallet is not supported"))
- }
- };
- Ok(id)
- }
-
- fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {
- match collection.mode {
- CollectionMode::ReFungible => {
- PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?
- }
- CollectionMode::Fungible(_) => {
- PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?
- }
- CollectionMode::NFT => {
- PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?
- }
- }
- Ok(())
- }
-
- fn dispatch(handle: CollectionHandle<T>) -> Self {
- match handle.mode {
- CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),
- CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),
- CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),
- }
- }
-
- fn into_inner(self) -> CollectionHandle<T> {
- match self {
- Self::Fungible(f) => f.into_inner(),
- Self::Nonfungible(f) => f.into_inner(),
- Self::Refungible(f) => f.into_inner(),
- }
- }
-
- fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {
- match self {
- Self::Fungible(h) => h,
- Self::Nonfungible(h) => h,
- Self::Refungible(h) => h,
- }
- }
-}
-
-impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>
-where
- T: pallet_common::Config
- + pallet_unique::Config
- + pallet_fungible::Config
- + pallet_nonfungible::Config
- + pallet_refungible::Config,
- T::AccountId: From<[u8; 32]>,
-{
- fn is_reserved(target: &H160) -> bool {
- map_eth_to_id(target).is_some()
- }
- fn is_used(target: &H160) -> bool {
- map_eth_to_id(target)
- .map(<CollectionById<T>>::contains_key)
- .unwrap_or(false)
- }
- fn get_code(target: &H160) -> Option<Vec<u8>> {
- if let Some(collection_id) = map_eth_to_id(target) {
- let collection = <CollectionById<T>>::get(collection_id)?;
- Some(
- match collection.mode {
- CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,
- CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,
- CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,
- }
- .to_owned(),
- )
- } else if let Some((collection_id, _token_id)) =
- <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)
- {
- let collection = <CollectionById<T>>::get(collection_id)?;
- if collection.mode != CollectionMode::ReFungible {
- return None;
- }
- // TODO: check token existence
- Some(<RefungibleTokenHandle<T>>::CODE.to_owned())
- } else {
- None
- }
- }
- fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
- if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {
- let collection =
- <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
- let dispatched = Self::dispatch(collection);
-
- match dispatched {
- Self::Fungible(h) => h.call(handle),
- Self::Nonfungible(h) => h.call(handle),
- Self::Refungible(h) => h.call(handle),
- }
- } else if let Some((collection_id, token_id)) =
- <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(
- &handle.code_address(),
- ) {
- let collection =
- <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
- if collection.mode != CollectionMode::ReFungible {
- return None;
- }
-
- let h = RefungibleHandle::cast(collection);
- // TODO: check token existence
- RefungibleTokenHandle(h, token_id).call(handle)
- } else {
- None
- }
- }
-}
runtime/common/src/eth_sponsoring.rsdiffbeforeafterboth--- a/runtime/common/src/eth_sponsoring.rs
+++ /dev/null
@@ -1,122 +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 <http://www.gnu.org/licenses/>.
-
-//! Implements EVM sponsoring logic via TransactionValidityHack
-
-use evm_coder::{Call, abi::AbiReader};
-use pallet_common::{CollectionHandle, eth::map_eth_to_id};
-use sp_core::H160;
-use sp_std::prelude::*;
-use up_sponsorship::SponsorshipHandler;
-use core::marker::PhantomData;
-use core::convert::TryInto;
-use pallet_evm::account::CrossAccountId;
-use up_data_structs::{TokenId, CreateItemData, CreateNftData, CollectionMode};
-use pallet_unique::Config as UniqueConfig;
-
-use crate::sponsoring::*;
-
-use pallet_nonfungible::erc::{
- UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call, TokenPropertiesCall,
-};
-use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
-use pallet_fungible::Config as FungibleConfig;
-use pallet_nonfungible::Config as NonfungibleConfig;
-use pallet_refungible::Config as RefungibleConfig;
-
-pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);
-impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>
- SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)> for UniqueEthSponsorshipHandler<T>
-{
- fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {
- let collection_id = map_eth_to_id(&call.0)?;
- let collection = <CollectionHandle<T>>::new(collection_id)?;
- let sponsor = collection.sponsorship.sponsor()?.clone();
- let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
- Some(T::CrossAccountId::from_sub(match &collection.mode {
- CollectionMode::NFT => {
- let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
- match call {
- UniqueNFTCall::TokenProperties(TokenPropertiesCall::SetProperty {
- token_id,
- key,
- value,
- ..
- }) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- withdraw_set_token_property::<T>(
- &collection,
- &who,
- &token_id,
- key.len() + value.len(),
- )
- .map(|()| sponsor)
- }
- UniqueNFTCall::ERC721UniqueExtensions(
- ERC721UniqueExtensionsCall::Transfer { token_id, .. },
- ) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
- }
- UniqueNFTCall::ERC721Mintable(
- ERC721MintableCall::Mint { token_id, .. }
- | ERC721MintableCall::MintWithTokenUri { token_id, .. },
- ) => {
- let _token_id: TokenId = token_id.try_into().ok()?;
- withdraw_create_item::<T>(
- &collection,
- &who,
- &CreateItemData::NFT(CreateNftData::default()),
- )
- .map(|()| sponsor)
- }
- UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, from, .. }) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- let from = T::CrossAccountId::from_eth(from);
- withdraw_transfer::<T>(&collection, &from, &token_id).map(|()| sponsor)
- }
- UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
- let token_id: TokenId = token_id.try_into().ok()?;
- withdraw_approve::<T>(&collection, who.as_sub(), &token_id)
- .map(|()| sponsor)
- }
- _ => None,
- }
- }
- CollectionMode::Fungible(_) => {
- let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
- #[allow(clippy::single_match)]
- match call {
- UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
- withdraw_transfer::<T>(&collection, who, &TokenId::default())
- .map(|()| sponsor)
- }
- UniqueFungibleCall::ERC20(ERC20Call::TransferFrom { from, .. }) => {
- let from = T::CrossAccountId::from_eth(from);
- withdraw_transfer::<T>(&collection, &from, &TokenId::default())
- .map(|()| sponsor)
- }
- UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
- withdraw_approve::<T>(&collection, who.as_sub(), &TokenId::default())
- .map(|()| sponsor)
- }
- _ => None,
- }
- }
- _ => None,
- }?))
- }
-}
runtime/common/src/lib.rsdiffbeforeafterboth--- a/runtime/common/src/lib.rs
+++ /dev/null
@@ -1,26 +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 <http://www.gnu.org/licenses/>.
-
-#![cfg_attr(not(feature = "std"), no_std)]
-
-pub mod constants;
-pub mod construct_runtime;
-pub mod dispatch;
-pub mod eth_sponsoring;
-pub mod runtime_apis;
-pub mod sponsoring;
-pub mod types;
-pub mod weights;
runtime/common/src/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/src/runtime_apis.rs
+++ /dev/null
@@ -1,678 +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 <http://www.gnu.org/licenses/>.
-
-#[macro_export]
-macro_rules! impl_common_runtime_apis {
- (
- $(
- #![custom_apis]
-
- $($custom_apis:tt)+
- )?
- ) => {
- impl_runtime_apis! {
- $($($custom_apis)+)?
-
- impl up_rpc::UniqueApi<Block, CrossAccountId, AccountId> for Runtime {
- fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>, DispatchError> {
- dispatch_unique_runtime!(collection.account_tokens(account))
- }
- fn collection_tokens(collection: CollectionId) -> Result<Vec<TokenId>, DispatchError> {
- dispatch_unique_runtime!(collection.collection_tokens())
- }
- fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool, DispatchError> {
- dispatch_unique_runtime!(collection.token_exists(token))
- }
-
- fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
- dispatch_unique_runtime!(collection.token_owner(token))
- }
-
- fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec::<CrossAccountId>, DispatchError> {
- dispatch_unique_runtime!(collection.token_owners(token))
- }
-
- fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
- let budget = up_data_structs::budget::Value::new(10);
-
- Ok(Some(<pallet_structure::Pallet<Runtime>>::find_topmost_owner(collection, token, &budget)?))
- }
- fn token_children(collection: CollectionId, token: TokenId) -> Result<Vec<TokenChild>, DispatchError> {
- Ok(<pallet_nonfungible::Pallet<Runtime>>::token_children_ids(collection, token))
- }
- fn collection_properties(
- collection: CollectionId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<Vec<Property>, DispatchError> {
- let keys = keys.map(
- |keys| Common::bytes_keys_to_property_keys(keys)
- ).transpose()?;
-
- Common::filter_collection_properties(collection, keys)
- }
-
- fn token_properties(
- collection: CollectionId,
- token_id: TokenId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<Vec<Property>, DispatchError> {
- let keys = keys.map(
- |keys| Common::bytes_keys_to_property_keys(keys)
- ).transpose()?;
-
- dispatch_unique_runtime!(collection.token_properties(token_id, keys))
- }
-
- fn property_permissions(
- collection: CollectionId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {
- let keys = keys.map(
- |keys| Common::bytes_keys_to_property_keys(keys)
- ).transpose()?;
-
- Common::filter_property_permissions(collection, keys)
- }
-
- fn token_data(
- collection: CollectionId,
- token_id: TokenId,
- keys: Option<Vec<Vec<u8>>>
- ) -> Result<TokenData<CrossAccountId>, DispatchError> {
- let token_data = TokenData {
- properties: Self::token_properties(collection, token_id, keys)?,
- owner: Self::token_owner(collection, token_id)?,
- pieces: Self::total_pieces(collection, token_id)?.unwrap_or(0),
- };
-
- Ok(token_data)
- }
-
- fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {
- dispatch_unique_runtime!(collection.total_supply())
- }
- fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32, DispatchError> {
- dispatch_unique_runtime!(collection.account_balance(account))
- }
- fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128, DispatchError> {
- dispatch_unique_runtime!(collection.balance(account, token))
- }
- fn allowance(
- collection: CollectionId,
- sender: CrossAccountId,
- spender: CrossAccountId,
- token: TokenId,
- ) -> Result<u128, DispatchError> {
- dispatch_unique_runtime!(collection.allowance(sender, spender, token))
- }
-
- fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::adminlist(collection))
- }
- fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::allowlist(collection))
- }
- fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::allowed(collection, user))
- }
- fn last_token_id(collection: CollectionId) -> Result<TokenId, DispatchError> {
- dispatch_unique_runtime!(collection.last_token_id())
- }
- fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::rpc_collection(collection))
- }
- fn collection_stats() -> Result<CollectionStats, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::collection_stats())
- }
- fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {
- Ok(<$crate::sponsoring::UniqueSponsorshipPredict<Runtime> as
- $crate::sponsoring::SponsorshipPredict<Runtime>>::predict(
- collection,
- account,
- token))
- }
-
- fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {
- Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))
- }
-
- fn total_pieces(collection: CollectionId, token_id: TokenId) -> Result<Option<u128>, DispatchError> {
- dispatch_unique_runtime!(collection.total_pieces(token_id))
- }
- }
-
- #[allow(unused_variables)]
- impl rmrk_rpc::RmrkApi<
- Block,
- AccountId,
- RmrkCollectionInfo<AccountId>,
- RmrkInstanceInfo<AccountId>,
- RmrkResourceInfo,
- RmrkPropertyInfo,
- RmrkBaseInfo<AccountId>,
- RmrkPartType,
- RmrkTheme
- > for Runtime {
- fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::last_collection_idx::<Runtime>();
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default());
- }
-
- fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::collection_by_id::<Runtime>(collection_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_by_id::<Runtime>(collection_id, nft_by_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::account_tokens::<Runtime>(account_id, collection_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_children::<Runtime>(collection_id, nft_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn collection_properties(
- collection_id: RmrkCollectionId,
- filter_keys: Option<Vec<RmrkPropertyKey>>
- ) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::collection_properties::<Runtime>(collection_id, filter_keys);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn nft_properties(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- filter_keys: Option<Vec<RmrkPropertyKey>>
- ) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_properties::<Runtime>(collection_id, nft_id, filter_keys);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn nft_resources(collection_id: RmrkCollectionId,nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_resources::<Runtime>(collection_id, nft_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn nft_resource_priority(
- collection_id: RmrkCollectionId,
- nft_id: RmrkNftId,
- resource_id: RmrkResourceId
- ) -> Result<Option<u32>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_core::rpc::nft_resource_priority::<Runtime>(collection_id, nft_id, resource_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::base::<Runtime>(base_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::base_parts::<Runtime>(base_id);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
-
- fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::theme_names::<Runtime>(base_id);
-
- #[cfg(not(feature = "rmrk"))]
- Ok(Default::default())
- }
-
- fn theme(
- base_id: RmrkBaseId,
- theme_name: RmrkThemeName,
- filter_keys: Option<Vec<RmrkPropertyKey>>
- ) -> Result<Option<RmrkTheme>, DispatchError> {
- #[cfg(feature = "rmrk")]
- return pallet_proxy_rmrk_equip::rpc::theme::<Runtime>(base_id, theme_name, filter_keys);
-
- #[cfg(not(feature = "rmrk"))]
- return Ok(Default::default())
- }
- }
-
- impl sp_api::Core<Block> for Runtime {
- fn version() -> RuntimeVersion {
- VERSION
- }
-
- fn execute_block(block: Block) {
- Executive::execute_block(block)
- }
-
- fn initialize_block(header: &<Block as BlockT>::Header) {
- Executive::initialize_block(header)
- }
- }
-
- impl sp_api::Metadata<Block> for Runtime {
- fn metadata() -> OpaqueMetadata {
- OpaqueMetadata::new(Runtime::metadata().into())
- }
- }
-
- impl sp_block_builder::BlockBuilder<Block> for Runtime {
- fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
- Executive::apply_extrinsic(extrinsic)
- }
-
- fn finalize_block() -> <Block as BlockT>::Header {
- Executive::finalize_block()
- }
-
- fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
- data.create_extrinsics()
- }
-
- fn check_inherents(
- block: Block,
- data: sp_inherents::InherentData,
- ) -> sp_inherents::CheckInherentsResult {
- data.check_extrinsics(&block)
- }
-
- // fn random_seed() -> <Block as BlockT>::Hash {
- // RandomnessCollectiveFlip::random_seed().0
- // }
- }
-
- impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
- fn validate_transaction(
- source: TransactionSource,
- tx: <Block as BlockT>::Extrinsic,
- hash: <Block as BlockT>::Hash,
- ) -> TransactionValidity {
- Executive::validate_transaction(source, tx, hash)
- }
- }
-
- impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
- fn offchain_worker(header: &<Block as BlockT>::Header) {
- Executive::offchain_worker(header)
- }
- }
-
- impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {
- fn chain_id() -> u64 {
- <Runtime as pallet_evm::Config>::ChainId::get()
- }
-
- fn account_basic(address: H160) -> EVMAccount {
- let (account, _) = EVM::account_basic(&address);
- account
- }
-
- fn gas_price() -> U256 {
- let (price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
- price
- }
-
- fn account_code_at(address: H160) -> Vec<u8> {
- EVM::account_codes(address)
- }
-
- fn author() -> H160 {
- <pallet_evm::Pallet<Runtime>>::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<u8>,
- value: U256,
- gas_limit: U256,
- max_fee_per_gas: Option<U256>,
- max_priority_fee_per_gas: Option<U256>,
- nonce: Option<U256>,
- estimate: bool,
- access_list: Option<Vec<(H160, Vec<H256>)>>,
- ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {
- let config = if estimate {
- let mut config = <Runtime as pallet_evm::Config>::config().clone();
- config.estimate = true;
- Some(config)
- } else {
- None
- };
-
- let is_transactional = false;
- <Runtime as pallet_evm::Config>::Runner::call(
- CrossAccountId::from_eth(from),
- to,
- data,
- value,
- gas_limit.low_u64(),
- max_fee_per_gas,
- max_priority_fee_per_gas,
- nonce,
- access_list.unwrap_or_default(),
- is_transactional,
- config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
- ).map_err(|err| err.error.into())
- }
-
- #[allow(clippy::redundant_closure)]
- fn create(
- from: H160,
- data: Vec<u8>,
- value: U256,
- gas_limit: U256,
- max_fee_per_gas: Option<U256>,
- max_priority_fee_per_gas: Option<U256>,
- nonce: Option<U256>,
- estimate: bool,
- access_list: Option<Vec<(H160, Vec<H256>)>>,
- ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {
- let config = if estimate {
- let mut config = <Runtime as pallet_evm::Config>::config().clone();
- config.estimate = true;
- Some(config)
- } else {
- None
- };
-
- let is_transactional = false;
- <Runtime as pallet_evm::Config>::Runner::create(
- CrossAccountId::from_eth(from),
- data,
- value,
- gas_limit.low_u64(),
- max_fee_per_gas,
- max_priority_fee_per_gas,
- nonce,
- access_list.unwrap_or_default(),
- is_transactional,
- config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
- ).map_err(|err| err.error.into())
- }
-
- fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {
- Ethereum::current_transaction_statuses()
- }
-
- fn current_block() -> Option<pallet_ethereum::Block> {
- Ethereum::current_block()
- }
-
- fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {
- Ethereum::current_receipts()
- }
-
- fn current_all() -> (
- Option<pallet_ethereum::Block>,
- Option<Vec<pallet_ethereum::Receipt>>,
- Option<Vec<TransactionStatus>>
- ) {
- (
- Ethereum::current_block(),
- Ethereum::current_receipts(),
- Ethereum::current_transaction_statuses()
- )
- }
-
- fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {
- xts.into_iter().filter_map(|xt| match xt.0.function {
- Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),
- _ => None
- }).collect()
- }
-
- fn elasticity() -> Option<Permill> {
- None
- }
- }
-
- impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {
- fn convert_transaction(transaction: pallet_ethereum::Transaction) -> <Block as BlockT>::Extrinsic {
- UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- )
- }
- }
-
- impl sp_session::SessionKeys<Block> for Runtime {
- fn decode_session_keys(
- encoded: Vec<u8>,
- ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
- SessionKeys::decode_into_raw_public_keys(&encoded)
- }
-
- fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
- SessionKeys::generate(seed)
- }
- }
-
- impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
- fn slot_duration() -> sp_consensus_aura::SlotDuration {
- sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
- }
-
- fn authorities() -> Vec<AuraId> {
- Aura::authorities().to_vec()
- }
- }
-
- impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
- fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
- ParachainSystem::collect_collation_info(header)
- }
- }
-
- impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
- fn account_nonce(account: AccountId) -> Index {
- System::account_nonce(account)
- }
- }
-
- impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
- fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
- TransactionPayment::query_info(uxt, len)
- }
- fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
- TransactionPayment::query_fee_details(uxt, len)
- }
- }
-
- /*
- impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>
- for Runtime
- {
- fn call(
- origin: AccountId,
- dest: AccountId,
- value: Balance,
- gas_limit: u64,
- input_data: Vec<u8>,
- ) -> 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<Hash>,
- data: Vec<u8>,
- salt: Vec<u8>,
- ) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>
- {
- 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<BlockNumber> {
- Contracts::rent_projection(address)
- }
- }
- */
-
- #[cfg(feature = "runtime-benchmarks")]
- impl frame_benchmarking::Benchmark<Block> for Runtime {
- fn benchmark_metadata(extra: bool) -> (
- Vec<frame_benchmarking::BenchmarkList>,
- Vec<frame_support::traits::StorageInfo>,
- ) {
- use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};
- use frame_support::traits::StorageInfoTrait;
-
- let mut list = Vec::<BenchmarkList>::new();
-
- list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);
- list_benchmark!(list, extra, pallet_common, Common);
- list_benchmark!(list, extra, pallet_unique, Unique);
- list_benchmark!(list, extra, pallet_structure, Structure);
- 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_unique_scheduler, Scheduler);
-
- #[cfg(not(feature = "unique-runtime"))]
- list_benchmark!(list, extra, pallet_proxy_rmrk_core, RmrkCore);
-
- #[cfg(not(feature = "unique-runtime"))]
- list_benchmark!(list, extra, pallet_proxy_rmrk_equip, RmrkEquip);
-
- // 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<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
- use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};
-
- let allowlist: Vec<TrackedStorageKey> = vec![
- // Total Issuance
- hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),
-
- // Block Number
- hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").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(),
-
- // Evm CurrentLogs
- hex_literal::hex!("1da53b775b270400e7e61ed5cbc5a146547f210cec367e9af919603343b9cb56").to_vec().into(),
-
- // Transactional depth
- hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a").to_vec().into(),
- ];
-
- let mut batches = Vec::<BenchmarkBatch>::new();
- let params = (&config, &allowlist);
-
- add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);
- add_benchmark!(params, batches, pallet_common, Common);
- add_benchmark!(params, batches, pallet_unique, Unique);
- add_benchmark!(params, batches, pallet_structure, Structure);
- 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_unique_scheduler, Scheduler);
-
- #[cfg(not(feature = "unique-runtime"))]
- add_benchmark!(params, batches, pallet_proxy_rmrk_core, RmrkCore);
-
- #[cfg(not(feature = "unique-runtime"))]
- add_benchmark!(params, batches, pallet_proxy_rmrk_equip, RmrkEquip);
-
- // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);
-
- if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
- Ok(batches)
- }
- }
-
- #[cfg(feature = "try-runtime")]
- impl frame_try_runtime::TryRuntime<Block> for Runtime {
- fn on_runtime_upgrade() -> (Weight, Weight) {
- log::info!("try-runtime::on_runtime_upgrade unique-chain.");
- let weight = Executive::try_runtime_upgrade().unwrap();
- (weight, RuntimeBlockWeights::get().max_block)
- }
-
- fn execute_block_no_check(block: Block) -> Weight {
- Executive::execute_block_no_check(block)
- }
- }
- }
- }
-}
runtime/common/src/sponsoring.rsdiffbeforeafterboth--- a/runtime/common/src/sponsoring.rs
+++ /dev/null
@@ -1,359 +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 <http://www.gnu.org/licenses/>.
-
-use core::marker::PhantomData;
-use up_sponsorship::SponsorshipHandler;
-use frame_support::{
- traits::{IsSubType},
- storage::{StorageMap, StorageDoubleMap, StorageNMap},
-};
-use up_data_structs::{
- CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, NFT_SPONSOR_TRANSFER_TIMEOUT,
- REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode, CreateItemData,
-};
-use sp_runtime::traits::Saturating;
-use pallet_common::{CollectionHandle};
-use pallet_evm::account::CrossAccountId;
-use pallet_unique::{
- Call as UniqueCall, Config as UniqueConfig, FungibleApproveBasket, RefungibleApproveBasket,
- NftApproveBasket, CreateItemBasket, ReFungibleTransferBasket, FungibleTransferBasket,
- NftTransferBasket, TokenPropertyBasket,
-};
-use pallet_fungible::Config as FungibleConfig;
-use pallet_nonfungible::Config as NonfungibleConfig;
-use pallet_refungible::Config as RefungibleConfig;
-
-pub trait Config: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
-impl<T> Config for T where T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}
-
-// TODO: permission check?
-pub fn withdraw_set_token_property<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::CrossAccountId,
- item_id: &TokenId,
- data_size: usize,
-) -> Option<()> {
- // preliminary sponsoring correctness check
- match collection.mode {
- CollectionMode::NFT => {
- let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
- if !owner.conv_eq(who) {
- return None;
- }
- }
- CollectionMode::Fungible(_) => {
- // Fungible tokens have no properties
- return None;
- }
- CollectionMode::ReFungible => {
- if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
- return None;
- }
- }
- }
-
- if data_size > collection.limits.sponsored_data_size() as usize {
- return None;
- }
-
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection.limits.sponsored_data_rate_limit()?;
-
- if let Some(last_tx_block) = TokenPropertyBasket::<T>::get(collection.id, item_id) {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- <TokenPropertyBasket<T>>::insert(collection.id, item_id, block_number);
-
- Some(())
-}
-
-pub fn withdraw_transfer<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::CrossAccountId,
- item_id: &TokenId,
-) -> Option<()> {
- // preliminary sponsoring correctness check
- match collection.mode {
- CollectionMode::NFT => {
- let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
- if !owner.conv_eq(who) {
- return None;
- }
- }
- CollectionMode::Fungible(_) => {
- if item_id != &TokenId::default() {
- return None;
- }
- if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {
- return None;
- }
- }
- CollectionMode::ReFungible => {
- if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
- return None;
- }
- }
- }
-
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection
- .limits
- .sponsor_transfer_timeout(match collection.mode {
- CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- });
-
- let last_tx_block = match collection.mode {
- CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),
- CollectionMode::Fungible(_) => {
- <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
- }
- CollectionMode::ReFungible => {
- <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who.as_sub()))
- }
- };
-
- if let Some(last_tx_block) = last_tx_block {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- match collection.mode {
- CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),
- CollectionMode::Fungible(_) => {
- <FungibleTransferBasket<T>>::insert(collection.id, who.as_sub(), block_number)
- }
- CollectionMode::ReFungible => <ReFungibleTransferBasket<T>>::insert(
- (collection.id, item_id, who.as_sub()),
- block_number,
- ),
- };
-
- Some(())
-}
-
-pub fn withdraw_create_item<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::CrossAccountId,
- properties: &CreateItemData,
-) -> Option<()> {
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection
- .limits
- .sponsor_transfer_timeout(match properties {
- CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
- CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- });
-
- if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, who.as_sub())) {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- CreateItemBasket::<T>::insert((collection.id, who.as_sub()), block_number);
-
- Some(())
-}
-
-pub fn withdraw_approve<T: Config>(
- collection: &CollectionHandle<T>,
- who: &T::AccountId,
- item_id: &TokenId,
-) -> Option<()> {
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection.limits.sponsor_approve_timeout();
-
- let last_tx_block = match collection.mode {
- CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),
- CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),
- CollectionMode::ReFungible => {
- <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))
- }
- };
-
- if let Some(last_tx_block) = last_tx_block {
- let timeout = last_tx_block + limit.into();
- if block_number < timeout {
- return None;
- }
- }
-
- match collection.mode {
- CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),
- CollectionMode::Fungible(_) => {
- <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)
- }
- CollectionMode::ReFungible => {
- <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)
- }
- };
-
- Some(())
-}
-
-fn load<T: UniqueConfig>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {
- let collection = CollectionHandle::new(id)?;
- let sponsor = collection.sponsorship.sponsor().cloned()?;
- Some((sponsor, collection))
-}
-
-pub struct UniqueSponsorshipHandler<T>(PhantomData<T>);
-impl<T, C> SponsorshipHandler<T::AccountId, C> for UniqueSponsorshipHandler<T>
-where
- T: Config,
- C: IsSubType<UniqueCall<T>>,
-{
- fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {
- match IsSubType::<UniqueCall<T>>::is_sub_type(call)? {
- UniqueCall::set_token_properties {
- collection_id,
- token_id,
- properties,
- ..
- } => {
- let (sponsor, collection) = load::<T>(*collection_id)?;
- withdraw_set_token_property(
- &collection,
- &T::CrossAccountId::from_sub(who.clone()),
- &token_id,
- // No overflow may happen, as data larger than usize can't reach here
- properties.iter().map(|p| p.key.len() + p.value.len()).sum(),
- )
- .map(|()| sponsor)
- }
- UniqueCall::create_item {
- collection_id,
- data,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_create_item::<T>(
- &collection,
- &T::CrossAccountId::from_sub(who.clone()),
- data,
- )
- .map(|()| sponsor)
- }
- UniqueCall::transfer {
- collection_id,
- item_id,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_transfer::<T>(
- &collection,
- &T::CrossAccountId::from_sub(who.clone()),
- item_id,
- )
- .map(|()| sponsor)
- }
- UniqueCall::transfer_from {
- collection_id,
- item_id,
- from,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_transfer::<T>(&collection, from, item_id).map(|()| sponsor)
- }
- UniqueCall::approve {
- collection_id,
- item_id,
- ..
- } => {
- let (sponsor, collection) = load(*collection_id)?;
- withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)
- }
- _ => None,
- }
- }
-}
-
-pub trait SponsorshipPredict<T: Config> {
- fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>
- where
- u64: From<<T as frame_system::Config>::BlockNumber>;
-}
-
-pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);
-
-impl<T: Config> SponsorshipPredict<T> for UniqueSponsorshipPredict<T> {
- fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>
- where
- u64: From<<T as frame_system::Config>::BlockNumber>,
- {
- let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;
- let _ = collection.sponsorship.sponsor()?;
-
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection
- .limits
- .sponsor_transfer_timeout(match collection.mode {
- CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- });
-
- let last_tx_block = match collection.mode {
- CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),
- CollectionMode::Fungible(_) => {
- <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())
- }
- CollectionMode::ReFungible => {
- <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))
- }
- };
-
- if let Some(last_tx_block) = last_tx_block {
- return Some(
- last_tx_block
- .saturating_add(limit.into())
- .saturating_sub(block_number)
- .into(),
- );
- }
-
- let token_exists = match collection.mode {
- CollectionMode::NFT => {
- <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))
- }
- CollectionMode::Fungible(_) => token == TokenId::default(),
- CollectionMode::ReFungible => {
- <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))
- }
- };
-
- if token_exists {
- Some(0)
- } else {
- None
- }
- }
-}
runtime/common/src/types.rsdiffbeforeafterboth--- a/runtime/common/src/types.rs
+++ /dev/null
@@ -1,72 +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 <http://www.gnu.org/licenses/>.
-
-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<BlockNumber, BlakeTwo256>;
-
-/// Opaque block type.
-pub type Block = generic::Block<Header, UncheckedExtrinsic>;
-
-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 = <<Signature as Verify>::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_evm::account::CrossAccountId<sp_runtime::AccountId32>
- + Send
- + Sync
- + 'static;
-
- type TransactionConverter: fp_rpc::ConvertTransaction<UncheckedExtrinsic>
- + Send
- + Sync
- + 'static;
-
- fn get_transaction_converter() -> Self::TransactionConverter;
-}
runtime/common/src/weights.rsdiffbeforeafterboth--- a/runtime/common/src/weights.rs
+++ /dev/null
@@ -1,139 +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 <http://www.gnu.org/licenses/>.
-
-use core::marker::PhantomData;
-use frame_support::{weights::Weight};
-use pallet_common::{CommonWeightInfo, dispatch::dispatch_weight, RefungibleExtensionsWeightInfo};
-
-use pallet_fungible::{Config as FungibleConfig, common::CommonWeights as FungibleWeights};
-use pallet_nonfungible::{Config as NonfungibleConfig, common::CommonWeights as NonfungibleWeights};
-
-#[cfg(feature = "refungible")]
-use pallet_refungible::{
- Config as RefungibleConfig, weights::WeightInfo, common::CommonWeights as RefungibleWeights,
-};
-use up_data_structs::{CreateItemExData, CreateItemData};
-
-macro_rules! max_weight_of {
- ($method:ident ( $($args:tt)* )) => {{
- let max_weight = <FungibleWeights<T>>::$method($($args)*)
- .max(<NonfungibleWeights<T>>::$method($($args)*));
-
- #[cfg(feature = "refungible")]
- let max_weight = max_weight.max(<RefungibleWeights<T>>::$method($($args)*));
-
- max_weight
- }};
-}
-
-#[cfg(not(feature = "refungible"))]
-pub trait CommonWeightConfigs: FungibleConfig + NonfungibleConfig {}
-
-#[cfg(not(feature = "refungible"))]
-impl<T: FungibleConfig + NonfungibleConfig> CommonWeightConfigs for T {}
-
-#[cfg(feature = "refungible")]
-pub trait CommonWeightConfigs: FungibleConfig + NonfungibleConfig + RefungibleConfig {}
-
-#[cfg(feature = "refungible")]
-impl<T: FungibleConfig + NonfungibleConfig + RefungibleConfig> CommonWeightConfigs for T {}
-
-pub struct CommonWeights<T>(PhantomData<T>);
-
-impl<T> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T>
-where
- T: CommonWeightConfigs,
-{
- fn create_item() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(create_item())
- }
-
- fn create_multiple_items(data: &[CreateItemData]) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(create_multiple_items(data))
- }
-
- fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(create_multiple_items_ex(data))
- }
-
- fn burn_item() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(burn_item())
- }
-
- fn set_collection_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(set_collection_properties(amount))
- }
-
- fn delete_collection_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(delete_collection_properties(amount))
- }
-
- fn set_token_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(set_token_properties(amount))
- }
-
- fn delete_token_properties(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(delete_token_properties(amount))
- }
-
- fn set_token_property_permissions(amount: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(set_token_property_permissions(amount))
- }
-
- fn transfer() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(transfer())
- }
-
- fn approve() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(approve())
- }
-
- fn transfer_from() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(transfer_from())
- }
-
- fn burn_from() -> Weight {
- dispatch_weight::<T>() + max_weight_of!(burn_from())
- }
-
- fn burn_recursively_self_raw() -> Weight {
- max_weight_of!(burn_recursively_self_raw())
- }
-
- fn burn_recursively_breadth_raw(amount: u32) -> Weight {
- max_weight_of!(burn_recursively_breadth_raw(amount))
- }
-}
-
-#[cfg(feature = "refungible")]
-impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>
-where
- T: FungibleConfig + NonfungibleConfig + RefungibleConfig,
-{
- fn repartition() -> Weight {
- dispatch_weight::<T>() + <<T as RefungibleConfig>::WeightInfo>::repartition_item()
- }
-}
-
-#[cfg(not(feature = "refungible"))]
-impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>
-where
- T: FungibleConfig + NonfungibleConfig,
-{
- fn repartition() -> Weight {
- dispatch_weight::<T>()
- }
-}
runtime/common/weights.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/weights.rs
@@ -0,0 +1,139 @@
+// 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 <http://www.gnu.org/licenses/>.
+
+use core::marker::PhantomData;
+use frame_support::{weights::Weight};
+use pallet_common::{CommonWeightInfo, dispatch::dispatch_weight, RefungibleExtensionsWeightInfo};
+
+use pallet_fungible::{Config as FungibleConfig, common::CommonWeights as FungibleWeights};
+use pallet_nonfungible::{Config as NonfungibleConfig, common::CommonWeights as NonfungibleWeights};
+
+#[cfg(feature = "refungible")]
+use pallet_refungible::{
+ Config as RefungibleConfig, weights::WeightInfo, common::CommonWeights as RefungibleWeights,
+};
+use up_data_structs::{CreateItemExData, CreateItemData};
+
+macro_rules! max_weight_of {
+ ($method:ident ( $($args:tt)* )) => {{
+ let max_weight = <FungibleWeights<T>>::$method($($args)*)
+ .max(<NonfungibleWeights<T>>::$method($($args)*));
+
+ #[cfg(feature = "refungible")]
+ let max_weight = max_weight.max(<RefungibleWeights<T>>::$method($($args)*));
+
+ max_weight
+ }};
+}
+
+#[cfg(not(feature = "refungible"))]
+pub trait CommonWeightConfigs: FungibleConfig + NonfungibleConfig {}
+
+#[cfg(not(feature = "refungible"))]
+impl<T: FungibleConfig + NonfungibleConfig> CommonWeightConfigs for T {}
+
+#[cfg(feature = "refungible")]
+pub trait CommonWeightConfigs: FungibleConfig + NonfungibleConfig + RefungibleConfig {}
+
+#[cfg(feature = "refungible")]
+impl<T: FungibleConfig + NonfungibleConfig + RefungibleConfig> CommonWeightConfigs for T {}
+
+pub struct CommonWeights<T>(PhantomData<T>);
+
+impl<T> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T>
+where
+ T: CommonWeightConfigs,
+{
+ fn create_item() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(create_item())
+ }
+
+ fn create_multiple_items(data: &[CreateItemData]) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(create_multiple_items(data))
+ }
+
+ fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(create_multiple_items_ex(data))
+ }
+
+ fn burn_item() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(burn_item())
+ }
+
+ fn set_collection_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(set_collection_properties(amount))
+ }
+
+ fn delete_collection_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(delete_collection_properties(amount))
+ }
+
+ fn set_token_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(set_token_properties(amount))
+ }
+
+ fn delete_token_properties(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(delete_token_properties(amount))
+ }
+
+ fn set_token_property_permissions(amount: u32) -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(set_token_property_permissions(amount))
+ }
+
+ fn transfer() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(transfer())
+ }
+
+ fn approve() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(approve())
+ }
+
+ fn transfer_from() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(transfer_from())
+ }
+
+ fn burn_from() -> Weight {
+ dispatch_weight::<T>() + max_weight_of!(burn_from())
+ }
+
+ fn burn_recursively_self_raw() -> Weight {
+ max_weight_of!(burn_recursively_self_raw())
+ }
+
+ fn burn_recursively_breadth_raw(amount: u32) -> Weight {
+ max_weight_of!(burn_recursively_breadth_raw(amount))
+ }
+}
+
+#[cfg(feature = "refungible")]
+impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>
+where
+ T: FungibleConfig + NonfungibleConfig + RefungibleConfig,
+{
+ fn repartition() -> Weight {
+ dispatch_weight::<T>() + <<T as RefungibleConfig>::WeightInfo>::repartition_item()
+ }
+}
+
+#[cfg(not(feature = "refungible"))]
+impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>
+where
+ T: FungibleConfig + NonfungibleConfig,
+{
+ fn repartition() -> Weight {
+ dispatch_weight::<T>()
+ }
+}
runtime/opal/Cargo.tomldiffbeforeafterboth--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -113,13 +113,15 @@
'xcm/std',
'xcm-builder/std',
'xcm-executor/std',
- 'unique-runtime-common/std',
+ 'common-types/std',
'rmrk-rpc/std',
+ 'evm-coder/std',
+ 'up-sponsorship/std',
"orml-vesting/std",
]
limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
-opal-runtime = ['scheduler', 'rmrk']
+opal-runtime = ['rmrk', 'scheduler']
scheduler = []
rmrk = []
@@ -400,7 +402,7 @@
[dependencies]
log = { version = "0.4.16", default-features = false }
-unique-runtime-common = { path = "../common", default-features = false, features = ['refungible'] }
+common-types = { path = "../../common-types", default-features = false }
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
@@ -430,6 +432,8 @@
pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.24" }
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
################################################################################
# Build Dependencies
runtime/opal/src/lib.rsdiffbeforeafterboth--- a/runtime/opal/src/lib.rs
+++ b/runtime/opal/src/lib.rs
@@ -25,174 +25,20 @@
#[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(feature = "scheduler")]
-use fp_self_contained::*;
-
-#[cfg(feature = "scheduler")]
-use sp_runtime::{
- traits::{Applyable, Member},
- generic::Era,
- DispatchErrorWithPostInfo,
-};
-// #[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::*;
+use frame_support::parameter_types;
-#[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, account::CrossAccountId as _,
- OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,
-};
-pub use frame_support::{
- match_types,
- 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, ConstU32, Imbalance, PrivilegeCmp,
- },
- weights::{
- constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
- DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,
- WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,
- WeightToFee,
- },
-};
+use sp_runtime::create_runtime_str;
-#[cfg(feature = "scheduler")]
-use pallet_unique_scheduler::DispatchCall;
+use common_types::*;
-use up_data_structs::{
- CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,
- CollectionStats, RpcCollection,
- mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
- TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
- RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,
- RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,
-};
+#[path = "../../common/mod.rs"]
+mod runtime_common;
-// 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 fp_rpc::TransactionStatus;
-use sp_runtime::{
- traits::{
- BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf, Saturating,
- CheckedConversion,
- },
- 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, CurrencyAdapter, EnsureXcmOrigin,
- FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser, RelayChainAsNative,
- SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
- SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, ParentIsPreset,
-};
-use xcm_executor::{Config, XcmExecutor, Assets};
-use sp_std::{cmp::Ordering, marker::PhantomData};
-
-use xcm::latest::{
- // Xcm,
- AssetId::{Concrete},
- Fungibility::Fungible as XcmFungible,
- MultiAsset,
- Error as XcmError,
-};
-use xcm_executor::traits::{MatchesFungible, WeightTrader};
-
-use unique_runtime_common::{
- construct_runtime, impl_common_runtime_apis,
- types::*,
- constants::*,
- dispatch::{CollectionDispatchT, CollectionDispatch},
- sponsoring::UniqueSponsorshipHandler,
- eth_sponsoring::UniqueEthSponsorshipHandler,
- weights::CommonWeights,
-};
+pub use runtime_common::*;
pub const RUNTIME_NAME: &str = "opal";
pub const TOKEN_SYMBOL: &str = "OPL";
-
-type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
-
-impl RuntimeInstance for Runtime {
- type CrossAccountId = self::CrossAccountId;
- type TransactionConverter = self::TransactionConverter;
-
- fn get_transaction_converter() -> TransactionConverter {
- TransactionConverter
- }
-}
-
-/// 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 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 {
@@ -205,1096 +51,16 @@
transaction_version: 1,
state_version: 0,
};
-
-#[derive(codec::Encode, codec::Decode)]
-pub enum XCMPMessage<XAccountId, XBalance> {
- /// 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 = <Balances as Currency<AccountId>>::NegativeImbalance;
-
-pub struct DealWithFees;
-impl OnUnbalanced<NegativeImbalance> for DealWithFees {
- fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
- 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, u64) {
- (MIN_GAS_PRICE.into(), 0)
- }
-}
-
-// 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 / <Runtime as frame_system::Config>::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::account::Config for Runtime {
- type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;
- type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
- type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
-}
-
-impl pallet_evm::Config for Runtime {
- type BlockGasLimit = BlockGasLimit;
- type FeeCalculator = FixedFee;
- type GasWeightMapping = FixedGasWeightMapping;
- type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
- type CallOrigin = EnsureAddressTruncated<Self>;
- type WithdrawOrigin = EnsureAddressTruncated<Self>;
- type AddressMapping = HashedAddressMapping<Self::Hashing>;
- type PrecompilesType = ();
- type PrecompilesValue = ();
- type Currency = Balances;
- type Event = Event;
- type OnMethodCall = (
- pallet_evm_migration::OnMethodCall<Self>,
- pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
- CollectionDispatchT<Self>,
- pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,
- );
- type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
- type ChainId = ChainId;
- type Runner = pallet_evm::runner::stack::Runner<Self>;
- type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;
- type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
- type FindAuthor = EthereumFindAuthor<Aura>;
-}
-
-impl pallet_evm_migration::Config for Runtime {
- type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
-}
-
-pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
-impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
- fn find_author<'a, I>(digests: I) -> Option<H160>
- where
- I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
- {
- 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<Self>;
-}
-
-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<Balance>;
- /// 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<BlockNumber, BlakeTwo256>;
- /// 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<AccountId, ()>;
- /// 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<Self>;
- /// 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<Self>;
- /// 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;
- pub const MaxReserves: u32 = 50;
-}
-
-impl pallet_balances::Config for Runtime {
- type MaxLocks = MaxLocks;
- type MaxReserves = MaxReserves;
- type ReserveIdentifier = [u8; 16];
- /// 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<Self>;
-}
-
-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::<pallet_contracts::Pallet<Runtime>> 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() / (
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
- <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
- )) / 5) as u32;
- pub Schedule: pallet_contracts::Schedule<Runtime> = 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<Self>;
- type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
- type ChainExtension = NFTExtension;
- type DeletionQueueDepth = DeletionQueueDepth;
- type DeletionWeightLimit = DeletionWeightLimit;
- type Schedule = Schedule;
- type CallStack = [pallet_contracts::Frame<Self>; 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<T>(sp_std::marker::PhantomData<T>);
-
-impl<T> WeightToFeePolynomial for LinearFee<T>
-where
- T: BaseArithmetic + From<u32> + Copy + Unsigned,
-{
- type Balance = T;
-
- fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
- smallvec!(WeightToFeeCoefficient {
- 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<Balances, DealWithFees>;
- type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
- type OperationalFeeMultiplier = OperationalFeeMultiplier;
- type WeightToFee = LinearFee<Balance>;
- 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<AccountId>;
- type RejectOrigin = EnsureRoot<AccountId>;
- 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<Self>;
- type MaxApprovals = MaxApprovals;
-}
-
-impl pallet_sudo::Config for Runtime {
- type Event = Event;
- type Call = Call;
-}
-
-pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
-
-impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider
- for RelayChainBlockNumberProvider<T>
-{
- type BlockNumber = BlockNumber;
-
- fn current_block_number() -> Self::BlockNumber {
- cumulus_pallet_parachain_system::Pallet::<T>::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<Runtime>;
- type MinVestedTransfer = MinVestedTransfer;
- type VestedTransferOrigin = EnsureSigned<AccountId>;
- type WeightInfo = ();
- type MaxVestingSchedules = MaxVestingSchedules;
- type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
-}
-
-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<Self>;
- type OnSystemEvent = ();
- // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
- // MaxDownwardMessageWeight,
- // XcmExecutor<XcmConfig>,
- // 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<AccountId>,
- // Sibling parachain origins convert to AccountId via the `ParaId::into`.
- SiblingParachainConvertsVia<Sibling, AccountId>,
- // Straight up local `AccountId32` origins just alias directly to `AccountId`.
- AccountId32Aliases<RelayNetwork, AccountId>,
-);
-
-pub struct OnlySelfCurrency;
-impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
- fn matches_fungible(a: &MultiAsset) -> Option<B> {
- 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<LocationToAccountId, Origin>,
- // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
- // recognised.
- RelayChainAsNative<RelayOrigin, Origin>,
- // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
- // recognised.
- SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
- // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
- // transaction from the Root origin.
- ParentAsSuperuser<Origin>,
- // Native signed account converter; this just converts an `AccountId32` origin into a normal
- // `Origin::Signed` origin of the same 32-byte value.
- SignedAccountId32AsNative<RelayNetwork, Origin>,
- // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
- XcmPassthrough<Origin>,
-);
-
-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_types! {
- pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
- MultiLocation { parents: 1, interior: Here } |
- MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
- };
-}
-
-pub type Barrier = (
- TakeWeightCredit,
- AllowTopLevelPaidExecutionFrom<Everything>,
- // ^^^ Parent & its unit plurality gets free execution
-);
-
-pub struct UsingOnlySelfCurrencyComponents<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
->(
- Weight,
- Currency::Balance,
- PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
-);
-impl<
- WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > WeightTrader
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- fn new() -> Self {
- Self(0, Zero::zero(), PhantomData)
- }
-
- fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
- let amount = WeightToFee::weight_to_fee(&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<MultiAsset> {
- let weight = weight.min(self.0);
- let amount = WeightToFee::weight_to_fee(&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<Balance = Currency::Balance>,
- AssetId: Get<MultiLocation>,
- AccountId,
- Currency: CurrencyT<AccountId>,
- OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
- > Drop
- for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
-{
- 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<Ancestry>;
- type Barrier = Barrier;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type Trader =
- UsingOnlySelfCurrencyComponents<LinearFee<Balance>, 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<Origin, AccountId, RelayNetwork>,);
-
-/// 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<ParachainSystem, ()>,
- // ..and XCMP to communicate with the sibling chains.
- XcmpQueue,
-);
-
-impl pallet_evm_coder_substrate::Config for Runtime {}
-
-impl pallet_xcm::Config for Runtime {
- type Event = Event;
- type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmRouter = XcmRouter;
- type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
- type XcmExecuteFilter = Everything;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type XcmTeleportFilter = Everything;
- type XcmReserveTransferFilter = Everything;
- type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
- type LocationInverter = LocationInverter<Ancestry>;
- 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<XcmConfig>;
-}
-
-impl cumulus_pallet_xcmp_queue::Config for Runtime {
- type WeightInfo = ();
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ChannelInfo = ParachainSystem;
- type VersionWrapper = ();
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
- type ControllerOrigin = EnsureRoot<AccountId>;
- type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
-}
-
-impl cumulus_pallet_dmp_queue::Config for Runtime {
- type Event = Event;
- type XcmExecutor = XcmExecutor<XcmConfig>;
- type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;
-}
-
-impl pallet_aura::Config for Runtime {
- type AuthorityId = AuraId;
- type DisabledValidators = ();
- type MaxAuthorities = MaxAuthorities;
-}
-
-parameter_types! {
- pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
- pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
-}
-
-impl pallet_common::Config for Runtime {
- type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;
- type Event = Event;
- type Currency = Balances;
- type CollectionCreationPrice = CollectionCreationPrice;
- type TreasuryAccountId = TreasuryAccountId;
- type CollectionDispatch = CollectionDispatchT<Self>;
-
- type EvmTokenAddressMapping = EvmTokenAddressMapping;
- type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
- type ContractAddress = EvmCollectionHelpersAddress;
-}
-
-impl pallet_structure::Config for Runtime {
- type Event = Event;
- type Call = Call;
- type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;
-}
-
-impl pallet_fungible::Config for Runtime {
- type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_refungible::Config for Runtime {
- type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;
-}
-impl pallet_nonfungible::Config for Runtime {
- type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;
-}
-
-#[cfg(feature = "rmrk")]
-impl pallet_proxy_rmrk_core::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_core::weights::SubstrateWeight<Self>;
- type Event = Event;
-}
-
-#[cfg(feature = "rmrk")]
-impl pallet_proxy_rmrk_equip::Config for Runtime {
- type WeightInfo = pallet_proxy_rmrk_equip::weights::SubstrateWeight<Self>;
- type Event = Event;
-}
-
-impl pallet_unique::Config for Runtime {
- type Event = Event;
- type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
- type CommonWeightInfo = CommonWeights<Self>;
- type RefungibleExtensionsWeightInfo = CommonWeights<Self>;
-}
-
-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<Runtime>;
-}
-
-parameter_types! {
- pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *
- RuntimeBlockWeights::get().max_block;
- pub const MaxScheduledPerBlock: u32 = 50;
}
-
-type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
-
-#[cfg(feature = "scheduler")]
-use frame_support::traits::NamedReservableCurrency;
-#[cfg(feature = "scheduler")]
-fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
- (
- frame_system::CheckSpecVersion::<Runtime>::new(),
- frame_system::CheckGenesis::<Runtime>::new(),
- frame_system::CheckEra::<Runtime>::from(Era::Immortal),
- frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(
- from,
- )),
- frame_system::CheckWeight::<Runtime>::new(),
- // sponsoring transaction logic
- // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
- )
-}
-
-#[cfg(feature = "scheduler")]
-pub struct SchedulerPaymentExecutor;
-
-#[cfg(feature = "scheduler")]
-impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
- DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
-where
- <T as frame_system::Config>::Call: Member
- + Dispatchable<Origin = Origin, Info = DispatchInfo>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
- + GetDispatchInfo
- + From<frame_system::Call<Runtime>>,
- SelfContainedSignedInfo: Send + Sync + 'static,
- Call: From<<T as frame_system::Config>::Call>
- + From<<T as pallet_unique_scheduler::Config>::Call>
- + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
- sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
-{
- fn dispatch_call(
- signer: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<
- Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
- TransactionValidityError,
- > {
- let dispatch_info = call.get_dispatch_info();
- let extrinsic = fp_self_contained::CheckedExtrinsic::<
- AccountId,
- Call,
- SignedExtraScheduler,
- SelfContainedSignedInfo,
- > {
- signed:
- CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(
- signer.clone().into(),
- get_signed_extras(signer.into()),
- ),
- function: call.into(),
- };
-
- extrinsic.apply::<Runtime>(&dispatch_info, 0)
- }
-
- fn reserve_balance(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- count: u32,
- ) -> Result<(), DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
- .saturating_mul(count.into());
-
- <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
- &id,
- &(sponsor.into()),
- weight,
- )
- }
-
- fn pay_for_call(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- call: <T as pallet_unique_scheduler::Config>::Call,
- ) -> Result<u128, DispatchError> {
- let dispatch_info = call.get_dispatch_info();
- let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- weight,
- ),
- )
- }
-
- fn cancel_reserve(
- id: [u8; 16],
- sponsor: <T as frame_system::Config>::AccountId,
- ) -> Result<u128, DispatchError> {
- Ok(
- <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
- &id,
- &(sponsor.into()),
- u128::MAX,
- ),
- )
- }
-}
-
-parameter_types! {
- pub const NoPreimagePostponement: Option<u32> = Some(10);
- pub const Preimage: Option<u32> = Some(10);
-}
-
-/// Used the compare the privilege of an origin inside the scheduler.
-pub struct OriginPrivilegeCmp;
-
-impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
- fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {
- Some(Ordering::Equal)
- }
-}
-
-#[cfg(feature = "scheduler")]
-impl pallet_unique_scheduler::Config for Runtime {
- type Event = Event;
- type Origin = Origin;
- type Currency = Balances;
- type PalletsOrigin = OriginCaller;
- type Call = Call;
- type MaximumWeight = MaximumSchedulerWeight;
- type ScheduleOrigin = EnsureSigned<AccountId>;
- type MaxScheduledPerBlock = MaxScheduledPerBlock;
- type WeightInfo = ();
- type CallExecutor = SchedulerPaymentExecutor;
- type OriginPrivilegeCmp = OriginPrivilegeCmp;
- type PreimageProvider = ();
- type NoPreimagePostponement = NoPreimagePostponement;
-}
-
-type EvmSponsorshipHandler = (
- UniqueEthSponsorshipHandler<Runtime>,
- pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
-);
-type SponsorshipHandler = (
- UniqueSponsorshipHandler<Runtime>,
- //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
- pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
-);
-
-impl pallet_evm_transaction_payment::Config for Runtime {
- type EvmSponsorshipHandler = EvmSponsorshipHandler;
- type Currency = Balances;
-}
-
-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,
- ]);
-
- // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
- pub const EvmCollectionHelpersAddress: H160 = H160([
- 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
- ]);
-}
-
-impl pallet_evm_contract_helpers::Config for Runtime {
- type ContractAddress = HelpersContractAddress;
- type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-}
-
construct_runtime!(opal);
-
-pub struct TransactionConverter;
-impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
- UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
- )
- }
-}
-
-impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
- fn convert_transaction(
- &self,
- transaction: pallet_ethereum::Transaction,
- ) -> opaque::UncheckedExtrinsic {
- let extrinsic = UncheckedExtrinsic::new_unsigned(
- pallet_ethereum::Call::<Runtime>::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<AccountId, ()>;
-/// Block header type as expected by this runtime.
-pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
-/// Block type as expected by this runtime.
-pub type Block = generic::Block<Header, UncheckedExtrinsic>;
-/// A Block signed with a Justification
-pub type SignedBlock = generic::SignedBlock<Block>;
-/// BlockId type as expected by this runtime.
-pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
- frame_system::CheckSpecVersion<Runtime>,
- // system::CheckTxVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
- ChargeTransactionPayment,
- //pallet_contract_helpers::ContractHelpersExtension<Runtime>,
- pallet_ethereum::FakeTransactionFinalizer<Runtime>,
-);
-pub type SignedExtraScheduler = (
- frame_system::CheckSpecVersion<Runtime>,
- frame_system::CheckGenesis<Runtime>,
- frame_system::CheckEra<Runtime>,
- frame_system::CheckNonce<Runtime>,
- frame_system::CheckWeight<Runtime>,
-);
-/// Unchecked extrinsic type as expected by this runtime.
-pub type UncheckedExtrinsic =
- fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
-/// Extrinsic type that has already been checked.
-pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;
-/// Executive: handles dispatch to the various modules.
-pub type Executive = frame_executive::Executive<
- Runtime,
- Block,
- frame_system::ChainContext<Runtime>,
- 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<Result<Self::SignedInfo, TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.check_self_contained(),
- _ => None,
- }
- }
-
- fn validate_self_contained(
- &self,
- info: &Self::SignedInfo,
- dispatch_info: &DispatchInfoOf<Call>,
- len: usize,
- ) -> Option<TransactionValidity> {
- match self {
- Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
- _ => None,
- }
- }
-
- fn pre_dispatch_self_contained(
- &self,
- info: &Self::SignedInfo,
- ) -> Option<Result<(), TransactionValidityError>> {
- match self {
- Call::Ethereum(call) => call.pre_dispatch_self_contained(info),
- _ => None,
- }
- }
-
- fn apply_self_contained(
- self,
- info: Self::SignedInfo,
- ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {
- 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),*)) => {{
- let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
- let dispatch = collection.as_dyn();
-
- Ok::<_, DispatchError>(dispatch.$method($($name),*))
- }};
-}
-
impl_common_runtime_apis!();
-
-struct CheckInherents;
-
-impl cumulus_pallet_parachain_system::CheckInherents<Block> 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,
runtime/tests/Cargo.tomldiffbeforeafterboth--- a/runtime/tests/Cargo.toml
+++ b/runtime/tests/Cargo.toml
@@ -4,7 +4,6 @@
edition = "2021"
[dependencies]
-unique-runtime-common = { path = '../common' }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
sp-core = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.24' }
@@ -37,3 +36,7 @@
"derive",
] }
scale-info = "*"
+
+common-types = { path = "../../common-types", default-features = false }
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.24' }
runtime/tests/src/lib.rsdiffbeforeafterboth--- a/runtime/tests/src/lib.rs
+++ b/runtime/tests/src/lib.rs
@@ -35,9 +35,18 @@
use parity_scale_codec::{Encode, Decode, MaxEncodedLen};
use scale_info::TypeInfo;
-use unique_runtime_common::{dispatch::CollectionDispatchT, weights::CommonWeights};
use up_data_structs::mapping::{CrossTokenAddressMapping, EvmTokenAddressMapping};
+#[path = "../../common/dispatch.rs"]
+mod dispatch;
+
+use dispatch::CollectionDispatchT;
+
+#[path = "../../common/weights.rs"]
+mod weights;
+
+use weights::CommonWeights;
+
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;