,
43 | /// Transaction pool instance.
44 | pub pool: Arc,
45 | /// Whether to deny unsafe calls
46 | pub deny_unsafe: DenyUnsafe,
47 | }
48 |
49 | /// Instantiate all RPC extensions.
50 | pub fn create_full(deps: FullDeps) -> RpcExtension
51 | where
52 | C: ProvideRuntimeApi
53 | + HeaderBackend
54 | + AuxStore
55 | + HeaderMetadata
56 | + Send
57 | + Sync
58 | + 'static,
59 | C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi,
60 | C::Api: substrate_frame_rpc_system::AccountNonceApi,
61 | C::Api: pallet_contracts_rpc::ContractsRuntimeApi,
62 | C::Api: BlockBuilder,
63 | P: TransactionPool + Sync + Send + 'static,
64 | {
65 | use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
66 | use substrate_frame_rpc_system::{FullSystem, SystemApi};
67 |
68 | let mut io = jsonrpc_core::IoHandler::default();
69 | let FullDeps { client, pool, deny_unsafe } = deps;
70 |
71 | io.extend_with(SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)));
72 | io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone())));
73 | io.extend_with(ContractsApi::to_delegate(Contracts::new(client)));
74 |
75 | io
76 | }
77 |
--------------------------------------------------------------------------------
/node/src/service.rs:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2018-2021 Annie Lai.
2 | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3 | //
4 | // This program is free software: you can redistribute it and/or modify
5 | // it under the terms of the GNU General Public License as published by
6 | // the Free Software Foundation, either version 3 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // This program is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU General Public License
15 | // along with this program. If not, see .
16 |
17 | //! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
18 |
19 | // std
20 | use std::{sync::Arc, time::Duration};
21 |
22 | // Local Runtime Types
23 | use thippy_runtime::{
24 | opaque::Block, AccountId, Balance, BlockNumber, Hash, Index as Nonce, RuntimeApi,
25 | };
26 |
27 | // Cumulus Imports
28 | use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};
29 | use cumulus_client_consensus_common::ParachainConsensus;
30 | use cumulus_client_network::BlockAnnounceValidator;
31 | use cumulus_client_service::{
32 | prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,
33 | };
34 | use cumulus_primitives_core::ParaId;
35 | use cumulus_relay_chain_interface::RelayChainInterface;
36 | use cumulus_relay_chain_local::build_relay_chain_interface;
37 |
38 | // Substrate Imports
39 | use sc_client_api::ExecutorProvider;
40 | use sc_executor::NativeElseWasmExecutor;
41 | use sc_network::NetworkService;
42 | use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager};
43 | use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};
44 | use sp_api::ConstructRuntimeApi;
45 | use sp_consensus::SlotData;
46 | use sp_keystore::SyncCryptoStorePtr;
47 | use sp_runtime::traits::BlakeTwo256;
48 | use substrate_prometheus_endpoint::Registry;
49 |
50 | /// Native executor instance.
51 | pub struct ThippyRuntimeExecutor;
52 |
53 | impl sc_executor::NativeExecutionDispatch for ThippyRuntimeExecutor {
54 | type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
55 |
56 | fn dispatch(method: &str, data: &[u8]) -> Option> {
57 | thippy_runtime::api::dispatch(method, data)
58 | }
59 |
60 | fn native_version() -> sc_executor::NativeVersion {
61 | thippy_runtime::native_version()
62 | }
63 | }
64 |
65 | /// Starts a `ServiceBuilder` for a full service.
66 | ///
67 | /// Use this macro if you don't actually need the full service, but just the builder in order to
68 | /// be able to perform chain operations.
69 | #[allow(clippy::type_complexity)]
70 | pub fn new_partial(
71 | config: &Configuration,
72 | build_import_queue: BIQ,
73 | ) -> Result<
74 | PartialComponents<
75 | TFullClient>,
76 | TFullBackend,
77 | (),
78 | sc_consensus::DefaultImportQueue<
79 | Block,
80 | TFullClient>,
81 | >,
82 | sc_transaction_pool::FullPool<
83 | Block,
84 | TFullClient>,
85 | >,
86 | (Option, Option),
87 | >,
88 | sc_service::Error,
89 | >
90 | where
91 | RuntimeApi: ConstructRuntimeApi>>
92 | + Send
93 | + Sync
94 | + 'static,
95 | RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue
96 | + sp_api::Metadata
97 | + sp_session::SessionKeys
98 | + sp_api::ApiExt<
99 | Block,
100 | StateBackend = sc_client_api::StateBackendFor, Block>,
101 | > + sp_offchain::OffchainWorkerApi
102 | + sp_block_builder::BlockBuilder,
103 | sc_client_api::StateBackendFor, Block>: sp_api::StateBackend,
104 | Executor: sc_executor::NativeExecutionDispatch + 'static,
105 | BIQ: FnOnce(
106 | Arc>>,
107 | &Configuration,
108 | Option,
109 | &TaskManager,
110 | ) -> Result<
111 | sc_consensus::DefaultImportQueue<
112 | Block,
113 | TFullClient>,
114 | >,
115 | sc_service::Error,
116 | >,
117 | {
118 | let telemetry = config
119 | .telemetry_endpoints
120 | .clone()
121 | .filter(|x| !x.is_empty())
122 | .map(|endpoints| -> Result<_, sc_telemetry::Error> {
123 | let worker = TelemetryWorker::new(16)?;
124 | let telemetry = worker.handle().new_telemetry(endpoints);
125 | Ok((worker, telemetry))
126 | })
127 | .transpose()?;
128 |
129 | let executor = sc_executor::NativeElseWasmExecutor::::new(
130 | config.wasm_method,
131 | config.default_heap_pages,
132 | config.max_runtime_instances,
133 | config.runtime_cache_size,
134 | );
135 |
136 | let (client, backend, keystore_container, task_manager) =
137 | sc_service::new_full_parts::(
138 | config,
139 | telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
140 | executor,
141 | )?;
142 | let client = Arc::new(client);
143 |
144 | let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());
145 |
146 | let telemetry = telemetry.map(|(worker, telemetry)| {
147 | task_manager.spawn_handle().spawn("telemetry", None, worker.run());
148 | telemetry
149 | });
150 |
151 | let transaction_pool = sc_transaction_pool::BasicPool::new_full(
152 | config.transaction_pool.clone(),
153 | config.role.is_authority().into(),
154 | config.prometheus_registry(),
155 | task_manager.spawn_essential_handle(),
156 | client.clone(),
157 | );
158 |
159 | let import_queue = build_import_queue(
160 | client.clone(),
161 | config,
162 | telemetry.as_ref().map(|telemetry| telemetry.handle()),
163 | &task_manager,
164 | )?;
165 |
166 | let params = PartialComponents {
167 | backend,
168 | client,
169 | import_queue,
170 | keystore_container,
171 | task_manager,
172 | transaction_pool,
173 | select_chain: (),
174 | other: (telemetry, telemetry_worker_handle),
175 | };
176 |
177 | Ok(params)
178 | }
179 |
180 | /// Start a node with the given parachain `Configuration` and relay chain `Configuration`.
181 | ///
182 | /// This is the actual implementation that is abstract over the executor and the runtime api.
183 | #[sc_tracing::logging::prefix_logs_with("Parachain")]
184 | async fn start_node_impl(
185 | parachain_config: Configuration,
186 | polkadot_config: Configuration,
187 | id: ParaId,
188 | _rpc_ext_builder: RB,
189 | build_import_queue: BIQ,
190 | build_consensus: BIC,
191 | ) -> sc_service::error::Result<(
192 | TaskManager,
193 | Arc>>,
194 | )>
195 | where
196 | RuntimeApi: ConstructRuntimeApi>>
197 | + Send
198 | + Sync
199 | + 'static,
200 | RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue
201 | + sp_api::Metadata
202 | + sp_session::SessionKeys
203 | + sp_api::ApiExt<
204 | Block,
205 | StateBackend = sc_client_api::StateBackendFor, Block>,
206 | > + sp_offchain::OffchainWorkerApi
207 | + sp_block_builder::BlockBuilder
208 | + cumulus_primitives_core::CollectCollationInfo
209 | + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi
210 | + substrate_frame_rpc_system::AccountNonceApi
211 | + pallet_contracts_rpc::ContractsRuntimeApi,
212 | sc_client_api::StateBackendFor, Block>: sp_api::StateBackend,
213 | Executor: sc_executor::NativeExecutionDispatch + 'static,
214 | RB: Fn(
215 | Arc>,
216 | ) -> Result, sc_service::Error>
217 | + Send
218 | + 'static,
219 | BIQ: FnOnce(
220 | Arc>>,
221 | &Configuration,
222 | Option,
223 | &TaskManager,
224 | ) -> Result<
225 | sc_consensus::DefaultImportQueue<
226 | Block,
227 | TFullClient>,
228 | >,
229 | sc_service::Error,
230 | > + 'static,
231 | BIC: FnOnce(
232 | Arc>>,
233 | Option<&Registry>,
234 | Option,
235 | &TaskManager,
236 | Arc,
237 | Arc<
238 | sc_transaction_pool::FullPool<
239 | Block,
240 | TFullClient>,
241 | >,
242 | >,
243 | Arc>,
244 | SyncCryptoStorePtr,
245 | bool,
246 | ) -> Result>, sc_service::Error>,
247 | {
248 | if matches!(parachain_config.role, Role::Light) {
249 | return Err("Light client not supported!".into())
250 | }
251 |
252 | let parachain_config = prepare_node_config(parachain_config);
253 |
254 | let params = new_partial::(¶chain_config, build_import_queue)?;
255 | let (mut telemetry, telemetry_worker_handle) = params.other;
256 |
257 | let client = params.client.clone();
258 | let backend = params.backend.clone();
259 | let mut task_manager = params.task_manager;
260 |
261 | let (relay_chain_interface, collator_key) =
262 | build_relay_chain_interface(polkadot_config, telemetry_worker_handle, &mut task_manager)
263 | .map_err(|e| match e {
264 | polkadot_service::Error::Sub(x) => x,
265 | s => format!("{}", s).into(),
266 | })?;
267 |
268 | let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id);
269 |
270 | let force_authoring = parachain_config.force_authoring;
271 | let validator = parachain_config.role.is_authority();
272 | let prometheus_registry = parachain_config.prometheus_registry().cloned();
273 | let transaction_pool = params.transaction_pool.clone();
274 | let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue);
275 | let (network, system_rpc_tx, start_network) =
276 | sc_service::build_network(sc_service::BuildNetworkParams {
277 | config: ¶chain_config,
278 | client: client.clone(),
279 | transaction_pool: transaction_pool.clone(),
280 | spawn_handle: task_manager.spawn_handle(),
281 | import_queue: import_queue.clone(),
282 | block_announce_validator_builder: Some(Box::new(|_| {
283 | Box::new(block_announce_validator)
284 | })),
285 | warp_sync: None,
286 | })?;
287 |
288 | let rpc_extensions_builder = {
289 | let client = client.clone();
290 | let transaction_pool = transaction_pool.clone();
291 |
292 | Box::new(move |deny_unsafe, _| {
293 | let deps = crate::rpc::FullDeps {
294 | client: client.clone(),
295 | pool: transaction_pool.clone(),
296 | deny_unsafe,
297 | };
298 |
299 | Ok(crate::rpc::create_full(deps))
300 | })
301 | };
302 |
303 | sc_service::spawn_tasks(sc_service::SpawnTasksParams {
304 | rpc_extensions_builder,
305 | client: client.clone(),
306 | transaction_pool: transaction_pool.clone(),
307 | task_manager: &mut task_manager,
308 | config: parachain_config,
309 | keystore: params.keystore_container.sync_keystore(),
310 | backend: backend.clone(),
311 | network: network.clone(),
312 | system_rpc_tx,
313 | telemetry: telemetry.as_mut(),
314 | })?;
315 |
316 | let announce_block = {
317 | let network = network.clone();
318 | Arc::new(move |hash, data| network.announce_block(hash, data))
319 | };
320 |
321 | let relay_chain_slot_duration = Duration::from_secs(6);
322 |
323 | if validator {
324 | let parachain_consensus = build_consensus(
325 | client.clone(),
326 | prometheus_registry.as_ref(),
327 | telemetry.as_ref().map(|t| t.handle()),
328 | &task_manager,
329 | relay_chain_interface.clone(),
330 | transaction_pool,
331 | network,
332 | params.keystore_container.sync_keystore(),
333 | force_authoring,
334 | )?;
335 |
336 | let spawner = task_manager.spawn_handle();
337 |
338 | let params = StartCollatorParams {
339 | para_id: id,
340 | block_status: client.clone(),
341 | announce_block,
342 | client: client.clone(),
343 | task_manager: &mut task_manager,
344 | relay_chain_interface,
345 | spawner,
346 | parachain_consensus,
347 | import_queue,
348 | collator_key,
349 | relay_chain_slot_duration,
350 | };
351 |
352 | start_collator(params).await?;
353 | } else {
354 | let params = StartFullNodeParams {
355 | client: client.clone(),
356 | announce_block,
357 | task_manager: &mut task_manager,
358 | para_id: id,
359 | relay_chain_interface,
360 | relay_chain_slot_duration,
361 | import_queue,
362 | };
363 |
364 | start_full_node(params)?;
365 | }
366 |
367 | start_network.start_network();
368 |
369 | Ok((task_manager, client))
370 | }
371 |
372 | /// Build the import queue for the parachain runtime.
373 | #[allow(clippy::type_complexity)]
374 | pub fn parachain_build_import_queue(
375 | client: Arc>>,
376 | config: &Configuration,
377 | telemetry: Option,
378 | task_manager: &TaskManager,
379 | ) -> Result<
380 | sc_consensus::DefaultImportQueue<
381 | Block,
382 | TFullClient>,
383 | >,
384 | sc_service::Error,
385 | > {
386 | let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
387 |
388 | cumulus_client_consensus_aura::import_queue::<
389 | sp_consensus_aura::sr25519::AuthorityPair,
390 | _,
391 | _,
392 | _,
393 | _,
394 | _,
395 | _,
396 | >(cumulus_client_consensus_aura::ImportQueueParams {
397 | block_import: client.clone(),
398 | client: client.clone(),
399 | create_inherent_data_providers: move |_, _| async move {
400 | let time = sp_timestamp::InherentDataProvider::from_system_time();
401 |
402 | let slot =
403 | sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
404 | *time,
405 | slot_duration.slot_duration(),
406 | );
407 |
408 | Ok((time, slot))
409 | },
410 | registry: config.prometheus_registry(),
411 | can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),
412 | spawner: &task_manager.spawn_essential_handle(),
413 | telemetry,
414 | })
415 | .map_err(Into::into)
416 | }
417 |
418 | /// Start a parachain node.
419 | pub async fn start_parachain_node(
420 | parachain_config: Configuration,
421 | polkadot_config: Configuration,
422 | id: ParaId,
423 | ) -> sc_service::error::Result<(
424 | TaskManager,
425 | Arc>>,
426 | )> {
427 | start_node_impl::(
428 | parachain_config,
429 | polkadot_config,
430 | id,
431 | |_| Ok(Default::default()),
432 | parachain_build_import_queue,
433 | |client,
434 | prometheus_registry,
435 | telemetry,
436 | task_manager,
437 | relay_chain_interface,
438 | transaction_pool,
439 | sync_oracle,
440 | keystore,
441 | force_authoring| {
442 | let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
443 |
444 | let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(
445 | task_manager.spawn_handle(),
446 | client.clone(),
447 | transaction_pool,
448 | prometheus_registry,
449 | telemetry.clone(),
450 | );
451 |
452 | Ok(AuraConsensus::build::(
453 | BuildAuraConsensusParams {
454 | proposer_factory,
455 | create_inherent_data_providers: move |_, (relay_parent, validation_data)| {
456 | let relay_chain_interface = relay_chain_interface.clone();
457 | async move {
458 | let parachain_inherent =
459 | cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(
460 | relay_parent,
461 | &relay_chain_interface,
462 | &validation_data,
463 | id,
464 | ).await;
465 | let time = sp_timestamp::InherentDataProvider::from_system_time();
466 |
467 | let slot =
468 | sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
469 | *time,
470 | slot_duration.slot_duration(),
471 | );
472 |
473 | let parachain_inherent = parachain_inherent.ok_or_else(|| {
474 | Box::::from(
475 | "Failed to create parachain inherent",
476 | )
477 | })?;
478 | Ok((time, slot, parachain_inherent))
479 | }
480 | },
481 | block_import: client.clone(),
482 | para_client: client,
483 | backoff_authoring_blocks: Option::<()>::None,
484 | sync_oracle,
485 | keystore,
486 | force_authoring,
487 | slot_duration,
488 | // We got around 500ms for proposing
489 | block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),
490 | // And a maximum of 750ms if slots are skipped
491 | max_block_proposal_slot_portion: Some(SlotProportion::new(1f32 / 16f32)),
492 | telemetry,
493 | },
494 | ))
495 | },
496 | )
497 | .await
498 | }
499 |
--------------------------------------------------------------------------------
/polkadot-launch/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "relaychain": {
3 | "bin": "../../polkadot/target/release/polkadot",
4 | "chain": "rococo-local",
5 | "nodes": [
6 | {
7 | "name": "alice",
8 | "wsPort": 9944,
9 | "port": 30444
10 | },
11 | {
12 | "name": "bob",
13 | "wsPort": 9955,
14 | "port": 30555
15 | }
16 | ]
17 | },
18 | "parachains": [
19 | {
20 | "bin": "../target/release/thippy",
21 | "balance": "1000000000000000000000",
22 | "nodes": [
23 | {
24 | "wsPort": 9988,
25 | "name": "alice",
26 | "port": 31200,
27 | "flags": [
28 | "--",
29 | "--execution=wasm"
30 | ]
31 | }
32 | ]
33 | }
34 | ],
35 | "types": {
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/runtime/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "thippy-runtime"
3 | version = "0.2.0"
4 | authors = ["Annie Lai "]
5 | license = "GPL-3.0-only"
6 | edition = "2021"
7 | rust-version = "1.56.1"
8 |
9 | [package.metadata.docs.rs]
10 | targets = ["x86_64-unknown-linux-gnu"]
11 |
12 | [build-dependencies]
13 | substrate-wasm-builder = { git = "https://github.com/ng8eke/substrate", branch = "master" }
14 |
15 | [dependencies]
16 | hex-literal = { version = '0.3.1', optional = true }
17 | codec = { package = 'parity-scale-codec', version = '2.0.0', default-features = false, features = ['derive']}
18 | log = { version = "0.4.14", default-features = false }
19 | scale-info = { version = "1.0.0", default-features = false, features = ["derive"] }
20 | serde = { version = '1.0.119', optional = true, features = ['derive'] }
21 | smallvec = "1.6.1"
22 |
23 | # Substrate Dependencies
24 | ## Substrate Primitive Dependencies
25 | sp-api = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
26 | sp-block-builder = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
27 | sp-consensus-aura = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
28 | sp-core = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
29 | sp-inherents = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
30 | sp-io = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
31 | sp-offchain = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
32 | sp-runtime = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
33 | sp-session = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
34 | sp-std = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
35 | sp-transaction-pool = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
36 | sp-version = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
37 |
38 | ## Substrate FRAME Dependencies
39 | frame-benchmarking = { git = 'https://github.com/ng8eke/substrate', default-features = false, optional = true , branch = "master" }
40 | frame-try-runtime = { git = "https://github.com/ng8eke/substrate", default-features = false, optional = true , branch = "master" }
41 | frame-executive = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
42 | frame-support = { git = 'https://github.com/ng8eke/substrate', default-features = false, branch = "master" }
43 | frame-system = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
44 | frame-system-benchmarking = { git = 'https://github.com/ng8eke/substrate', default-features = false, optional = true , branch = "master" }
45 | frame-system-rpc-runtime-api = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
46 |
47 | ## Substrate Pallet Dependencies
48 | pallet-aura = { git = "https://github.com/ng8eke/substrate", default-features = false , branch = "master" }
49 | pallet-authorship = { git = "https://github.com/ng8eke/substrate", default-features = false , branch = "master" }
50 | pallet-randomness-collective-flip = { git = "https://github.com/ng8eke/substrate", default-features = false , branch = "master" }
51 | pallet-balances = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
52 | pallet-session = { git = "https://github.com/ng8eke/substrate", default-features = false , branch = "master" }
53 | pallet-timestamp = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
54 | pallet-transaction-payment = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
55 | pallet-transaction-payment-rpc-runtime-api = { git = 'https://github.com/ng8eke/substrate', default-features = false , branch = "master" }
56 |
57 | pallet-sudo = { git = "https://github.com/ng8eke/substrate", default-features = false , branch = "master" }
58 |
59 | # Cumulus Dependencies
60 | cumulus-pallet-aura-ext = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
61 | cumulus-pallet-dmp-queue = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
62 | cumulus-pallet-parachain-system = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
63 | cumulus-pallet-xcm = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
64 | cumulus-pallet-xcmp-queue = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
65 | cumulus-primitives-core = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
66 | cumulus-primitives-timestamp = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
67 | cumulus-primitives-utility = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
68 | pallet-collator-selection = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
69 | parachain-info = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
70 | cumulus-pallet-session-benchmarking = { git = 'https://github.com/ng8eke/cumulus', default-features = false , branch = "master" }
71 |
72 | # Polkadot Dependencies
73 | polkadot-parachain = { git = 'https://github.com/ng8eke/polkadot', default-features = false , branch = "master" }
74 | polkadot-runtime-common = { git = "https://github.com/ng8eke/polkadot", default-features = false, branch = "master" }
75 | xcm = { git = 'https://github.com/ng8eke/polkadot', default-features = false , branch = "master" }
76 | xcm-builder = { git = 'https://github.com/ng8eke/polkadot', default-features = false , branch = "master" }
77 | xcm-executor = { git = 'https://github.com/ng8eke/polkadot', default-features = false , branch = "master" }
78 | pallet-xcm = { git = 'https://github.com/ng8eke/polkadot', default-features = false , branch = "master" }
79 |
80 | # Contracts specific packages
81 | pallet-contracts = { git = "https://github.com/ng8eke/substrate", default-features = false, branch = "master" }
82 | pallet-contracts-primitives = { git = "https://github.com/ng8eke/substrate", default-features = false, branch = "master" }
83 | pallet-contracts-rpc-runtime-api = { git = "https://github.com/ng8eke/substrate", default-features = false, branch = "master" }
84 |
85 | [features]
86 | default = [
87 | "std",
88 | ]
89 | std = [
90 | "codec/std",
91 | "serde",
92 | "scale-info/std",
93 | "log/std",
94 | "sp-api/std",
95 | "sp-block-builder/std",
96 | "sp-consensus-aura/std",
97 | "sp-core/std",
98 | "sp-inherents/std",
99 | "sp-io/std",
100 | "sp-offchain/std",
101 | "sp-runtime/std",
102 | "sp-session/std",
103 | "sp-std/std",
104 | "sp-transaction-pool/std",
105 | "sp-version/std",
106 | "frame-executive/std",
107 | "frame-support/std",
108 | "frame-system/std",
109 | "pallet-authorship/std",
110 | "pallet-aura/std",
111 | "pallet-sudo/std",
112 | "pallet-balances/std",
113 | "pallet-collator-selection/std",
114 | "pallet-randomness-collective-flip/std",
115 | "pallet-contracts-primitives/std",
116 | "pallet-contracts-rpc-runtime-api/std",
117 | "pallet-contracts/std",
118 | "pallet-session/std",
119 | "pallet-timestamp/std",
120 | "pallet-transaction-payment/std",
121 | "pallet-transaction-payment-rpc-runtime-api/std",
122 | "cumulus-pallet-aura-ext/std",
123 | "cumulus-pallet-dmp-queue/std",
124 | "cumulus-pallet-parachain-system/std",
125 | "cumulus-pallet-xcm/std",
126 | "cumulus-pallet-xcmp-queue/std",
127 | "cumulus-primitives-core/std",
128 | "cumulus-primitives-timestamp/std",
129 | "cumulus-primitives-utility/std",
130 | "parachain-info/std",
131 | "polkadot-parachain/std",
132 | "polkadot-runtime-common/std",
133 | "xcm/std",
134 | "xcm-builder/std",
135 | "xcm-executor/std",
136 | ]
137 |
138 | # Make contract callable functions marked as __unstable__ available. Do not enable
139 | # on live chains as those are subject to change.
140 | contracts-unstable-interface = [
141 | "pallet-contracts/unstable-interface"
142 | ]
143 |
144 | runtime-benchmarks = [
145 | 'hex-literal',
146 | 'sp-runtime/runtime-benchmarks',
147 | 'xcm-builder/runtime-benchmarks',
148 | "frame-benchmarking/runtime-benchmarks",
149 | 'frame-system-benchmarking',
150 | 'frame-support/runtime-benchmarks',
151 | 'frame-system/runtime-benchmarks',
152 | 'pallet-balances/runtime-benchmarks',
153 | 'pallet-timestamp/runtime-benchmarks',
154 | 'pallet-xcm/runtime-benchmarks',
155 | 'pallet-collator-selection/runtime-benchmarks',
156 | 'cumulus-pallet-session-benchmarking/runtime-benchmarks',
157 | ]
158 |
159 | try-runtime = [
160 | "frame-try-runtime",
161 | "frame-executive/try-runtime",
162 | ]
163 |
--------------------------------------------------------------------------------
/runtime/build.rs:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2018-2021 Annie Lai.
2 | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3 | //
4 | // This program is free software: you can redistribute it and/or modify
5 | // it under the terms of the GNU General Public License as published by
6 | // the Free Software Foundation, either version 3 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // This program is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU General Public License
15 | // along with this program. If not, see .
16 |
17 | use substrate_wasm_builder::WasmBuilder;
18 |
19 | fn main() {
20 | WasmBuilder::new()
21 | .with_current_project()
22 | .export_heap_base()
23 | .import_memory()
24 | .build()
25 | }
26 |
--------------------------------------------------------------------------------
/runtime/src/lib.rs:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2018-2021 Annie Lai.
2 | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3 | //
4 | // This program is free software: you can redistribute it and/or modify
5 | // it under the terms of the GNU General Public License as published by
6 | // the Free Software Foundation, either version 3 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // This program is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU General Public License
15 | // along with this program. If not, see .
16 |
17 | #![cfg_attr(not(feature = "std"), no_std)]
18 | // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
19 | #![recursion_limit = "256"]
20 |
21 | // Make the WASM binary available.
22 | #[cfg(feature = "std")]
23 | include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
24 |
25 | use pallet_contracts::weights::WeightInfo;
26 | use smallvec::smallvec;
27 | use sp_api::impl_runtime_apis;
28 | use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
29 | use sp_runtime::{
30 | create_runtime_str, generic, impl_opaque_keys,
31 | traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify},
32 | transaction_validity::{TransactionSource, TransactionValidity},
33 | ApplyExtrinsicResult, MultiSignature,
34 | };
35 |
36 | use sp_std::prelude::*;
37 | #[cfg(feature = "std")]
38 | use sp_version::NativeVersion;
39 | use sp_version::RuntimeVersion;
40 |
41 | use frame_support::{
42 | construct_runtime, match_type, parameter_types,
43 | traits::{EnsureOneOf, Everything},
44 | weights::{
45 | constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_PER_SECOND},
46 | DispatchClass, IdentityFee, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients,
47 | WeightToFeePolynomial,
48 | },
49 | PalletId,
50 | };
51 | use frame_system::{
52 | limits::{BlockLength, BlockWeights},
53 | EnsureRoot,
54 | };
55 | pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
56 | pub use sp_runtime::{MultiAddress, Perbill, Permill};
57 |
58 | #[cfg(any(feature = "std", test))]
59 | pub use sp_runtime::BuildStorage;
60 |
61 | // Polkadot Imports
62 | use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough};
63 | use polkadot_parachain::primitives::Sibling;
64 | use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate};
65 |
66 | // XCM Imports
67 | use xcm::latest::prelude::*;
68 | use xcm_builder::{
69 | AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
70 | EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, ParentIsPreset,
71 | RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
72 | SignedAccountId32AsNative, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
73 | };
74 | use xcm_executor::{Config, XcmExecutor};
75 |
76 | /// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
77 | pub type Signature = MultiSignature;
78 |
79 | /// Some way of identifying an account on the chain. We intentionally make it equivalent
80 | /// to the public key of our transaction signing scheme.
81 | pub type AccountId = <::Signer as IdentifyAccount>::AccountId;
82 |
83 | /// Balance of an account.
84 | pub type Balance = u128;
85 |
86 | /// Index of a transaction in the chain.
87 | pub type Index = u32;
88 |
89 | /// A hash of some data used by the chain.
90 | pub type Hash = sp_core::H256;
91 |
92 | /// An index to a block.
93 | pub type BlockNumber = u32;
94 |
95 | /// The address format for describing accounts.
96 | pub type Address = MultiAddress;
97 |
98 | /// Block header type as expected by this runtime.
99 | pub type Header = generic::Header;
100 |
101 | /// Block type as expected by this runtime.
102 | pub type Block = generic::Block;
103 |
104 | /// A Block signed with a Justification
105 | pub type SignedBlock = generic::SignedBlock;
106 |
107 | /// BlockId type as expected by this runtime.
108 | pub type BlockId = generic::BlockId;
109 |
110 | /// The SignedExtension to the basic transaction logic.
111 | pub type SignedExtra = (
112 | frame_system::CheckSpecVersion,
113 | frame_system::CheckTxVersion,
114 | frame_system::CheckGenesis,
115 | frame_system::CheckEra,
116 | frame_system::CheckNonce,
117 | frame_system::CheckWeight,
118 | pallet_transaction_payment::ChargeTransactionPayment,
119 | );
120 |
121 | /// Unchecked extrinsic type as expected by this runtime.
122 | pub type UncheckedExtrinsic = generic::UncheckedExtrinsic;
123 |
124 | /// Extrinsic type that has already been checked.
125 | pub type CheckedExtrinsic = generic::CheckedExtrinsic;
126 |
127 | /// Executive: handles dispatch to the various modules.
128 | pub type Executive = frame_executive::Executive<
129 | Runtime,
130 | Block,
131 | frame_system::ChainContext,
132 | Runtime,
133 | AllPalletsWithSystem,
134 | >;
135 |
136 | /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
137 | /// node's balance type.
138 | ///
139 | /// This should typically create a mapping between the following ranges:
140 | /// - `[0, MAXIMUM_BLOCK_WEIGHT]`
141 | /// - `[Balance::min, Balance::max]`
142 | ///
143 | /// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
144 | /// - Setting it to `0` will essentially disable the weight fee.
145 | /// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
146 | pub struct WeightToFee;
147 | impl WeightToFeePolynomial for WeightToFee {
148 | type Balance = Balance;
149 | fn polynomial() -> WeightToFeeCoefficients {
150 | // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT:
151 | // in Thippy, we map to 1/10 of that, or 1/10 MILLIUNIT
152 | let p = MILLIUNIT / 10;
153 | let q = 100 * Balance::from(ExtrinsicBaseWeight::get());
154 | smallvec![WeightToFeeCoefficient {
155 | degree: 1,
156 | negative: false,
157 | coeff_frac: Perbill::from_rational(p % q, q),
158 | coeff_integer: p / q,
159 | }]
160 | }
161 | }
162 |
163 | /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
164 | /// the specifics of the runtime. They can then be made to be agnostic over specific formats
165 | /// of data like extrinsics, allowing for them to continue syncing the network through upgrades
166 | /// to even the core data structures.
167 | pub mod opaque {
168 | use super::*;
169 | use sp_runtime::{generic, traits::BlakeTwo256};
170 |
171 | pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
172 | /// Opaque block header type.
173 | pub type Header = generic::Header;
174 | /// Opaque block type.
175 | pub type Block = generic::Block;
176 | /// Opaque block identifier type.
177 | pub type BlockId = generic::BlockId;
178 | }
179 |
180 | impl_opaque_keys! {
181 | pub struct SessionKeys {
182 | pub aura: Aura,
183 | }
184 | }
185 |
186 | #[sp_version::runtime_version]
187 | pub const VERSION: RuntimeVersion = RuntimeVersion {
188 | spec_name: create_runtime_str!("thippy"),
189 | impl_name: create_runtime_str!("thippy"),
190 | authoring_version: 1,
191 | spec_version: 15,
192 | impl_version: 1,
193 | apis: RUNTIME_API_VERSIONS,
194 | transaction_version: 1,
195 | // Since Thippy is a "live" chain (on Rococo anyways), we need to set this to `0` until a
196 | // migration path to `state_version = 1` is ready.
197 | //
198 | // See the following PRs for more details:
199 | // - https://github.com/ng8eke/substrate/pull/9732
200 | // - https://github.com/ng8eke/substrate/pull/10073
201 | state_version: 0,
202 | };
203 |
204 | /// This determines the average expected block time that we are targeting.
205 | /// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`.
206 | /// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked
207 | /// up by `pallet_aura` to implement `fn slot_duration()`.
208 | ///
209 | /// Change this to adjust the block time.
210 | pub const MILLISECS_PER_BLOCK: u64 = 12000;
211 |
212 | // NOTE: Currently it is not possible to change the slot duration after the chain has started.
213 | // Attempting to do so will brick block production.
214 | pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
215 |
216 | // Time is measured by number of blocks.
217 | pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
218 | pub const HOURS: BlockNumber = MINUTES * 60;
219 | pub const DAYS: BlockNumber = HOURS * 24;
220 |
221 | // Prints debug output of the `contracts` pallet to stdout if the node is
222 | // started with `-lruntime::contracts=debug`.
223 | pub const CONTRACTS_DEBUG_OUTPUT: bool = true;
224 |
225 | // Unit = the base number of indivisible units for balances
226 | pub const UNIT: Balance = 1_000_000_000_000;
227 | pub const MILLIUNIT: Balance = 1_000_000_000;
228 | pub const MICROUNIT: Balance = 1_000_000;
229 |
230 | /// The existential deposit. Set to 1/10 of the Connected Relay Chain.
231 | pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;
232 |
233 | const fn deposit(items: u32, bytes: u32) -> Balance {
234 | // This is a 1/10 of the deposit on the Rococo Relay Chain
235 | (items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10
236 | }
237 |
238 | /// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is
239 | /// used to limit the maximal weight of a single extrinsic.
240 | const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
241 |
242 | /// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by
243 | /// `Operational` extrinsics.
244 | const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
245 |
246 | /// We allow for 0.5 of a second of compute with a 12 second average block time.
247 | const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2;
248 |
249 | /// The version information used to identify this runtime when compiled natively.
250 | #[cfg(feature = "std")]
251 | pub fn native_version() -> NativeVersion {
252 | NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
253 | }
254 |
255 | parameter_types! {
256 | pub const Version: RuntimeVersion = VERSION;
257 |
258 | // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`.
259 | // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the
260 | // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize
261 | // the lazy contract deletion.
262 | pub RuntimeBlockLength: BlockLength =
263 | BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
264 | pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
265 | .base_block(BlockExecutionWeight::get())
266 | .for_class(DispatchClass::all(), |weights| {
267 | weights.base_extrinsic = ExtrinsicBaseWeight::get();
268 | })
269 | .for_class(DispatchClass::Normal, |weights| {
270 | weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
271 | })
272 | .for_class(DispatchClass::Operational, |weights| {
273 | weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
274 | // Operational transactions have some extra reserved space, so that they
275 | // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
276 | weights.reserved = Some(
277 | MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
278 | );
279 | })
280 | .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
281 | .build_or_panic();
282 | pub const SS58Prefix: u16 = 42;
283 | }
284 |
285 | // Configure FRAME pallets to include in runtime.
286 |
287 | impl frame_system::Config for Runtime {
288 | /// The identifier used to distinguish between accounts.
289 | type AccountId = AccountId;
290 | /// The aggregated dispatch type that is available for extrinsics.
291 | type Call = Call;
292 | /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
293 | type Lookup = AccountIdLookup;
294 | /// The index type for storing how many extrinsics an account has signed.
295 | type Index = Index;
296 | /// The index type for blocks.
297 | type BlockNumber = BlockNumber;
298 | /// The type for hashing blocks and tries.
299 | type Hash = Hash;
300 | /// The hashing algorithm used.
301 | type Hashing = BlakeTwo256;
302 | /// The header type.
303 | type Header = generic::Header;
304 | /// The ubiquitous event type.
305 | type Event = Event;
306 | /// The ubiquitous origin type.
307 | type Origin = Origin;
308 | /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
309 | type BlockHashCount = BlockHashCount;
310 | /// Runtime version.
311 | type Version = Version;
312 | /// Converts a module to an index of this module in the runtime.
313 | type PalletInfo = PalletInfo;
314 | /// The data to be stored in an account.
315 | type AccountData = pallet_balances::AccountData;
316 | /// What to do if a new account is created.
317 | type OnNewAccount = ();
318 | /// What to do if an account is fully reaped from the system.
319 | type OnKilledAccount = ();
320 | /// The weight of database operations that the runtime can invoke.
321 | type DbWeight = RocksDbWeight;
322 | /// The basic call filter to use in dispatchable.
323 | type BaseCallFilter = Everything;
324 | /// Weight information for the extrinsics of this pallet.
325 | type SystemWeightInfo = ();
326 | /// Block & extrinsics weights: base values and limits.
327 | type BlockWeights = RuntimeBlockWeights;
328 | /// The maximum length of a block (in bytes).
329 | type BlockLength = RuntimeBlockLength;
330 | /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
331 | type SS58Prefix = SS58Prefix;
332 | /// The action to take on a Runtime Upgrade
333 | type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode;
334 | /// The maximum number of consumers (e.g locks) system accounts can have.
335 | type MaxConsumers = frame_support::traits::ConstU32<16>;
336 | }
337 |
338 | parameter_types! {
339 | pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
340 | }
341 |
342 | impl pallet_timestamp::Config for Runtime {
343 | /// A timestamp: milliseconds since the unix epoch.
344 | type Moment = u64;
345 | type OnTimestampSet = ();
346 | type MinimumPeriod = MinimumPeriod;
347 | type WeightInfo = (); // TODO: Add benchmarked weights.
348 | }
349 |
350 | parameter_types! {
351 | pub const UncleGenerations: u32 = 0;
352 | }
353 |
354 | impl pallet_authorship::Config for Runtime {
355 | type FindAuthor = pallet_session::FindAccountFromAuthorIndex;
356 | type UncleGenerations = UncleGenerations;
357 | type FilterUncle = ();
358 | type EventHandler = (CollatorSelection,);
359 | }
360 |
361 | parameter_types! {
362 | pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
363 | pub const MaxLocks: u32 = 50;
364 | pub const MaxReserves: u32 = 50;
365 | }
366 |
367 | impl pallet_balances::Config for Runtime {
368 | type MaxLocks = MaxLocks;
369 | /// The type for recording an account's balance.
370 | type Balance = Balance;
371 | /// The ubiquitous event type.
372 | type Event = Event;
373 | type DustRemoval = ();
374 | type ExistentialDeposit = ExistentialDeposit;
375 | type AccountStore = System;
376 | type WeightInfo = pallet_balances::weights::SubstrateWeight;
377 | type MaxReserves = MaxReserves;
378 | type ReserveIdentifier = [u8; 8];
379 | }
380 |
381 | parameter_types! {
382 | /// Relay Chain `TransactionByteFee` / 10
383 | pub const TransactionByteFee: Balance = 10 * MICROUNIT;
384 | pub const OperationalFeeMultiplier: u8 = 5;
385 | }
386 |
387 | impl pallet_transaction_payment::Config for Runtime {
388 | type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter;
389 | type TransactionByteFee = TransactionByteFee;
390 | type WeightToFee = WeightToFee;
391 | type FeeMultiplierUpdate = SlowAdjustingFeeUpdate;
392 | type OperationalFeeMultiplier = OperationalFeeMultiplier;
393 | }
394 |
395 | parameter_types! {
396 | pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
397 | pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
398 | }
399 |
400 | impl cumulus_pallet_parachain_system::Config for Runtime {
401 | type Event = Event;
402 | type OnSystemEvent = ();
403 | type SelfParaId = parachain_info::Pallet;
404 | type DmpMessageHandler = DmpQueue;
405 | type ReservedDmpWeight = ReservedDmpWeight;
406 | type OutboundXcmpMessageSource = XcmpQueue;
407 | type XcmpMessageHandler = XcmpQueue;
408 | type ReservedXcmpWeight = ReservedXcmpWeight;
409 | }
410 |
411 | parameter_types! {
412 | pub const DepositPerItem: Balance = deposit(1, 0);
413 | pub const DepositPerByte: Balance = deposit(0, 1);
414 | // The lazy deletion runs inside on_initialize.
415 | pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
416 | RuntimeBlockWeights::get().max_block;
417 | // The weight needed for decoding the queue should be less or equal than a fifth
418 | // of the overall weight dedicated to the lazy deletion.
419 | pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
420 | ::WeightInfo::on_initialize_per_queue_item(1) -
421 | ::WeightInfo::on_initialize_per_queue_item(0)
422 | )) / 5) as u32;
423 | pub Schedule: pallet_contracts::Schedule = Default::default();
424 | }
425 |
426 | impl pallet_contracts::Config for Runtime {
427 | type Time = Timestamp;
428 | type Randomness = RandomnessCollectiveFlip;
429 | type Currency = Balances;
430 | type Event = Event;
431 | type Call = Call;
432 | /// The safest default is to allow no calls at all.
433 | ///
434 | /// Runtimes should whitelist dispatchables that are allowed to be called from contracts
435 | /// and make sure they are stable. Dispatchables exposed to contracts are not allowed to
436 | /// change because that would break already deployed contracts. The `Call` structure itself
437 | /// is not allowed to change the indices of existing pallets, too.
438 | type CallFilter = frame_support::traits::Nothing;
439 | type DepositPerItem = DepositPerItem;
440 | type DepositPerByte = DepositPerByte;
441 | type WeightPrice = pallet_transaction_payment::Pallet;
442 | type WeightInfo = pallet_contracts::weights::SubstrateWeight;
443 | type ChainExtension = ();
444 | type DeletionQueueDepth = DeletionQueueDepth;
445 | type DeletionWeightLimit = DeletionWeightLimit;
446 | type Schedule = Schedule;
447 | type CallStack = [pallet_contracts::Frame; 31];
448 | type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
449 | }
450 |
451 | impl pallet_randomness_collective_flip::Config for Runtime {}
452 |
453 | impl parachain_info::Config for Runtime {}
454 |
455 | impl cumulus_pallet_aura_ext::Config for Runtime {}
456 |
457 | parameter_types! {
458 | pub const RelayLocation: MultiLocation = MultiLocation::parent();
459 | pub const RelayNetwork: NetworkId = NetworkId::Any;
460 | pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
461 | pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
462 | }
463 |
464 | /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
465 | /// when determining ownership of accounts for asset transacting and when attempting to use XCM
466 | /// `Transact` in order to determine the dispatch Origin.
467 | pub type LocationToAccountId = (
468 | // The parent (Relay-chain) origin converts to the parent `AccountId`.
469 | ParentIsPreset,
470 | // Sibling parachain origins convert to AccountId via the `ParaId::into`.
471 | SiblingParachainConvertsVia,
472 | // Straight up local `AccountId32` origins just alias directly to `AccountId`.
473 | AccountId32Aliases,
474 | );
475 |
476 | /// Means for transacting assets on this chain.
477 | pub type LocalAssetTransactor = CurrencyAdapter<
478 | // Use this currency:
479 | Balances,
480 | // Use this currency when it is a fungible asset matching the given location or name:
481 | IsConcrete,
482 | // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
483 | LocationToAccountId,
484 | // Our chain's account ID type (we can't get away without mentioning it explicitly):
485 | AccountId,
486 | // We don't track any teleports.
487 | (),
488 | >;
489 |
490 | /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
491 | /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
492 | /// biases the kind of local `Origin` it will become.
493 | pub type XcmOriginToTransactDispatchOrigin = (
494 | // Sovereign account converter; this attempts to derive an `AccountId` from the origin location
495 | // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
496 | // foreign chains who want to have a local sovereign account on this chain which they control.
497 | SovereignSignedViaLocation,
498 | // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
499 | // recognized.
500 | RelayChainAsNative,
501 | // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
502 | // recognized.
503 | SiblingParachainAsNative,
504 | // Native signed account converter; this just converts an `AccountId32` origin into a normal
505 | // `Origin::Signed` origin of the same 32-byte value.
506 | SignedAccountId32AsNative,
507 | // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
508 | XcmPassthrough,
509 | );
510 |
511 | parameter_types! {
512 | // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate.
513 | pub UnitWeightCost: Weight = 1_000_000_000;
514 | pub const MaxInstructions: u32 = 100;
515 | }
516 |
517 | match_type! {
518 | pub type ParentOrParentsExecutivePlurality: impl Contains = {
519 | MultiLocation { parents: 1, interior: Here } |
520 | MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }
521 | };
522 | }
523 |
524 | pub type Barrier = (
525 | TakeWeightCredit,
526 | AllowTopLevelPaidExecutionFrom,
527 | AllowUnpaidExecutionFrom,
528 | // ^^^ Parent and its exec plurality get free execution
529 | );
530 |
531 | pub struct XcmConfig;
532 | impl Config for XcmConfig {
533 | type Call = Call;
534 | type XcmSender = XcmRouter;
535 | // How to withdraw and deposit an asset.
536 | type AssetTransactor = LocalAssetTransactor;
537 | type OriginConverter = XcmOriginToTransactDispatchOrigin;
538 | type IsReserve = NativeAsset;
539 | type IsTeleporter = NativeAsset; // Should be enough to allow teleportation of ROC
540 | type LocationInverter = LocationInverter;
541 | type Barrier = Barrier;
542 | type Weigher = FixedWeightBounds;
543 | type Trader = UsingComponents, RelayLocation, AccountId, Balances, ()>;
544 | type ResponseHandler = PolkadotXcm;
545 | type AssetTrap = PolkadotXcm;
546 | type AssetClaims = PolkadotXcm;
547 | type SubscriptionService = PolkadotXcm;
548 | }
549 |
550 | parameter_types! {
551 | pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
552 | }
553 |
554 | /// No local origins on this chain are allowed to dispatch XCM sends/executions.
555 | pub type LocalOriginToLocation = ();
556 |
557 | /// The means for routing XCM messages which are not for local execution into the right message
558 | /// queues.
559 | pub type XcmRouter = (
560 | // Two routers - use UMP to communicate with the relay chain:
561 | cumulus_primitives_utility::ParentAsUmp,
562 | // ..and XCMP to communicate with the sibling chains.
563 | XcmpQueue,
564 | );
565 |
566 | impl pallet_xcm::Config for Runtime {
567 | type Event = Event;
568 | type SendXcmOrigin = EnsureXcmOrigin;
569 | type XcmRouter = XcmRouter;
570 | type ExecuteXcmOrigin = EnsureXcmOrigin;
571 | type XcmExecuteFilter = Everything;
572 | type XcmExecutor = XcmExecutor;
573 | type XcmTeleportFilter = Everything;
574 | type XcmReserveTransferFilter = Everything;
575 | type Weigher = FixedWeightBounds;
576 | type LocationInverter = LocationInverter;
577 | type Origin = Origin;
578 | type Call = Call;
579 |
580 | const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
581 | // ^ Override for AdvertisedXcmVersion default
582 | type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
583 | }
584 |
585 | impl cumulus_pallet_xcm::Config for Runtime {
586 | type Event = Event;
587 | type XcmExecutor = XcmExecutor;
588 | }
589 |
590 | impl cumulus_pallet_xcmp_queue::Config for Runtime {
591 | type Event = Event;
592 | type XcmExecutor = XcmExecutor;
593 | type ChannelInfo = ParachainSystem;
594 | type VersionWrapper = ();
595 | type ExecuteOverweightOrigin = EnsureRoot;
596 | type ControllerOrigin = EnsureOneOf<
597 | EnsureRoot,
598 | EnsureXcm>,
599 | >;
600 | type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
601 | }
602 |
603 | impl cumulus_pallet_dmp_queue::Config for Runtime {
604 | type Event = Event;
605 | type XcmExecutor = XcmExecutor;
606 | type ExecuteOverweightOrigin = EnsureRoot;
607 | }
608 |
609 | parameter_types! {
610 | pub const Period: u32 = 6 * HOURS;
611 | pub const Offset: u32 = 0;
612 | pub const MaxAuthorities: u32 = 100_000;
613 | }
614 |
615 | impl pallet_session::Config for Runtime {
616 | type Event = Event;
617 | type ValidatorId = ::AccountId;
618 | // we don't have stash and controller, thus we don't need the convert as well.
619 | type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
620 | type ShouldEndSession = pallet_session::PeriodicSessions;
621 | type NextSessionRotation = pallet_session::PeriodicSessions;
622 | type SessionManager = CollatorSelection;
623 | // Essentially just Aura, but lets be pedantic.
624 | type SessionHandler = ::KeyTypeIdProviders;
625 | type Keys = SessionKeys;
626 | type WeightInfo = (); // TODO: Add benchmarked weights.
627 | }
628 |
629 | impl pallet_aura::Config for Runtime {
630 | type AuthorityId = AuraId;
631 | type DisabledValidators = ();
632 | type MaxAuthorities = MaxAuthorities;
633 | }
634 |
635 | parameter_types! {
636 | pub const PotId: PalletId = PalletId(*b"PotStake");
637 | pub const MaxCandidates: u32 = 1000;
638 | pub const MinCandidates: u32 = 5;
639 | pub const SessionLength: BlockNumber = 6 * HOURS;
640 | pub const MaxInvulnerables: u32 = 100;
641 | pub const ExecutiveBody: BodyId = BodyId::Executive;
642 | }
643 |
644 | // We allow root and the Relay Chain council to execute privileged collator selection operations.
645 | pub type CollatorSelectionUpdateOrigin =
646 | EnsureOneOf, EnsureXcm>>;
647 |
648 | impl pallet_collator_selection::Config for Runtime {
649 | type Event = Event;
650 | type Currency = Balances;
651 | type UpdateOrigin = CollatorSelectionUpdateOrigin;
652 | type PotId = PotId;
653 | type MaxCandidates = MaxCandidates;
654 | type MinCandidates = MinCandidates;
655 | type MaxInvulnerables = MaxInvulnerables;
656 | // should be a multiple of session or things will get inconsistent
657 | type KickThreshold = Period;
658 | type ValidatorId = ::AccountId;
659 | type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
660 | type ValidatorRegistration = Session;
661 | type WeightInfo = (); // TODO: Add benchmarked weights.
662 | }
663 |
664 | // Create the runtime by composing the FRAME pallets that were previously configured.
665 | construct_runtime!(
666 | pub enum Runtime where
667 | Block = Block,
668 | NodeBlock = opaque::Block,
669 | UncheckedExtrinsic = UncheckedExtrinsic,
670 | {
671 | // System support stuff.
672 | System: frame_system::{Pallet, Call, Config, Storage, Event} = 0,
673 | ParachainSystem: cumulus_pallet_parachain_system::{
674 | Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned,
675 | } = 1,
676 | RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 2,
677 | Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3,
678 | ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4,
679 |
680 | // Monetary stuff.
681 | Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10,
682 | TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 11,
683 |
684 | // Collator support. The order of these 4 are important and shall not change.
685 | Authorship: pallet_authorship::{Pallet, Call, Storage} = 20,
686 | CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21,
687 | Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22,
688 | Aura: pallet_aura::{Pallet, Storage, Config} = 23,
689 | AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24,
690 |
691 | // XCM helpers.
692 | XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30,
693 | PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 31,
694 | CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32,
695 | DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 33,
696 |
697 | // Smart Contracts.
698 | Contracts: pallet_contracts::{Pallet, Call, Storage, Event} = 40,
699 | }
700 | );
701 |
702 | impl_runtime_apis! {
703 | impl sp_consensus_aura::AuraApi for Runtime {
704 | fn slot_duration() -> sp_consensus_aura::SlotDuration {
705 | sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
706 | }
707 |
708 | fn authorities() -> Vec {
709 | Aura::authorities().into_inner()
710 | }
711 | }
712 |
713 | impl sp_api::Core for Runtime {
714 | fn version() -> RuntimeVersion {
715 | VERSION
716 | }
717 |
718 | fn execute_block(block: Block) {
719 | Executive::execute_block(block)
720 | }
721 |
722 | fn initialize_block(header: &::Header) {
723 | Executive::initialize_block(header)
724 | }
725 | }
726 |
727 | impl sp_api::Metadata for Runtime {
728 | fn metadata() -> OpaqueMetadata {
729 | OpaqueMetadata::new(Runtime::metadata().into())
730 | }
731 | }
732 |
733 | impl sp_block_builder::BlockBuilder for Runtime {
734 | fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult {
735 | Executive::apply_extrinsic(extrinsic)
736 | }
737 |
738 | fn finalize_block() -> ::Header {
739 | Executive::finalize_block()
740 | }
741 |
742 | fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> {
743 | data.create_extrinsics()
744 | }
745 |
746 | fn check_inherents(
747 | block: Block,
748 | data: sp_inherents::InherentData,
749 | ) -> sp_inherents::CheckInherentsResult {
750 | data.check_extrinsics(&block)
751 | }
752 | }
753 |
754 | impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime {
755 | fn validate_transaction(
756 | source: TransactionSource,
757 | tx: ::Extrinsic,
758 | block_hash: ::Hash,
759 | ) -> TransactionValidity {
760 | Executive::validate_transaction(source, tx, block_hash)
761 | }
762 | }
763 |
764 | impl sp_offchain::OffchainWorkerApi for Runtime {
765 | fn offchain_worker(header: &::Header) {
766 | Executive::offchain_worker(header)
767 | }
768 | }
769 |
770 | impl sp_session::SessionKeys for Runtime {
771 | fn generate_session_keys(seed: Option>) -> Vec {
772 | SessionKeys::generate(seed)
773 | }
774 |
775 | fn decode_session_keys(
776 | encoded: Vec,
777 | ) -> Option, KeyTypeId)>> {
778 | SessionKeys::decode_into_raw_public_keys(&encoded)
779 | }
780 | }
781 |
782 | impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime {
783 | fn account_nonce(account: AccountId) -> Index {
784 | System::account_nonce(account)
785 | }
786 | }
787 |
788 | impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime {
789 | fn query_info(
790 | uxt: ::Extrinsic,
791 | len: u32,
792 | ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo {
793 | TransactionPayment::query_info(uxt, len)
794 | }
795 | fn query_fee_details(
796 | uxt: ::Extrinsic,
797 | len: u32,
798 | ) -> pallet_transaction_payment::FeeDetails