lib.rs 16 KB
Newer Older
Gav's avatar
Gav committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot 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.

// Polkadot 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.

17
//! The Polkadot runtime. This can be compiled with ``#[no_std]`, ready for Wasm.
Gav's avatar
Gav committed
18
19

#![cfg_attr(not(feature = "std"), no_std)]
20
21
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit="256"]
Gav Wood's avatar
Gav Wood committed
22

23
mod curated_grandpa;
24
mod parachains;
Gav Wood's avatar
Gav Wood committed
25
mod claims;
Gavin Wood's avatar
Gavin Wood committed
26
27
mod slot_range;
mod slots;
Gav Wood's avatar
Gav Wood committed
28

29
use rstd::prelude::*;
30
use substrate_primitives::u32_trait::{_1, _2, _3, _4};
31
use primitives::{
32
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, SessionKey, Signature,
33
	parachain, AuraId
34
};
35
use client::{
36
	block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult},
37
	runtime_api as client_api, impl_runtime_apis,
38
};
Gav Wood's avatar
Gav Wood committed
39
use sr_primitives::{
40
	ApplyResult, generic, transaction_validity::TransactionValidity, create_runtime_str, key_types,
41
	traits::{BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Convert}, impl_opaque_keys
Gav Wood's avatar
Gav Wood committed
42
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
43
use version::RuntimeVersion;
44
use grandpa::{AuthorityId as GrandpaId, fg_primitives::{self, ScheduledChange}};
45
use council::motions as council_motions;
46
#[cfg(feature = "std")]
47
48
49
50
use council::seats as council_seats;
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
use substrate_primitives::OpaqueMetadata;
Gavin Wood's avatar
Gavin Wood committed
51
52
53
use srml_support::{
	parameter_types, construct_runtime, traits::{SplitTwoWays, Currency, OnUnbalanced}
};
54

Gav Wood's avatar
Gav Wood committed
55
56
#[cfg(feature = "std")]
pub use staking::StakerStatus;
57
58
#[cfg(any(feature = "std", test))]
pub use sr_primitives::BuildStorage;
59
pub use timestamp::Call as TimestampCall;
60
pub use balances::Call as BalancesCall;
61
pub use parachains::{Call as ParachainsCall, INHERENT_IDENTIFIER as PARACHAIN_INHERENT_IDENTIFIER};
62
63
pub use sr_primitives::{Permill, Perbill};
pub use timestamp::BlockPeriod;
64
pub use srml_support::StorageValue;
65

66
67
68
69
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

70
/// Runtime version.
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
71
pub const VERSION: RuntimeVersion = RuntimeVersion {
72
73
	spec_name: create_runtime_str!("polkadot"),
	impl_name: create_runtime_str!("parity-polkadot"),
Gav Wood's avatar
Gav Wood committed
74
	authoring_version: 1,
André Silva's avatar
André Silva committed
75
	spec_version: 1000,
76
	impl_version: 0,
77
	apis: RUNTIME_API_VERSIONS,
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
78
79
};

80
81
82
83
84
85
86
87
88
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

Gavin Wood's avatar
Gavin Wood committed
89
90
91
92
93
94
95
96
97
98
const DOTS: Balance = 1_000_000_000_000;
const BUCKS: Balance = DOTS / 100;
const CENTS: Balance = BUCKS / 100;
const MILLICENTS: Balance = CENTS / 1_000;

const SECS_PER_BLOCK: BlockNumber = 10;
const MINUTES: BlockNumber = 60 / SECS_PER_BLOCK;
const HOURS: BlockNumber = MINUTES * 60;
const DAYS: BlockNumber = HOURS * 24;

99
100
impl system::Trait for Runtime {
	type Origin = Origin;
Gav Wood's avatar
Gav Wood committed
101
	type Index = Nonce;
102
103
104
105
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
Gav Wood's avatar
Gav Wood committed
106
	type Lookup = Indices;
107
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
108
	type Event = Event;
109
110
}

111
112
impl aura::Trait for Runtime {
	type HandleReport = aura::StakingSlasher<Runtime>;
113
	type AuthorityId = AuraId;
114
115
}

Gav Wood's avatar
Gav Wood committed
116
117
118
119
120
121
122
impl indices::Trait for Runtime {
	type IsDeadAccount = Balances;
	type AccountIndex = AccountIndex;
	type ResolveHint = indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
parameter_types! {
	pub const ExistentialDeposit: Balance = 1 * BUCKS;
	pub const TransferFee: Balance = 1 * CENTS;
	pub const CreationFee: Balance = 1 * CENTS;
	pub const TransactionBaseFee: Balance = 1 * CENTS;
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
}


/// Logic for the author to get a portion of fees.
pub struct ToAuthor;

type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
impl OnUnbalanced<NegativeImbalance> for ToAuthor {
	fn on_unbalanced(amount: NegativeImbalance) {
		Balances::resolve_creating(&Authorship::author(), amount);
	}
}

/// Splits fees 80/20 between treasury and block author.
pub type DealWithFees = SplitTwoWays<
	Balance,
	NegativeImbalance,
	_4, Treasury,   // 4 parts (80%) goes to the treasury.
	_1, ToAuthor,     // 1 part (20%) goes to the block author.
>;

150
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
151
152
	type Balance = Balance;
	type OnFreeBalanceZero = Staking;
Gav Wood's avatar
Gav Wood committed
153
	type OnNewAccount = Indices;
Gav's avatar
Gav committed
154
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
155
	type TransactionPayment = DealWithFees;
156
157
	type DustRemoval = ();
	type TransferPayment = ();
Gavin Wood's avatar
Gavin Wood committed
158
159
160
161
162
	type ExistentialDeposit = ExistentialDeposit;
	type TransferFee = TransferFee;
	type CreationFee = CreationFee;
	type TransactionBaseFee = TransactionBaseFee;
	type TransactionByteFee = TransactionByteFee;
Gav's avatar
Gav committed
163
164
}

165
impl timestamp::Trait for Runtime {
166
	type Moment = u64;
167
	type OnTimestampSet = Aura;
168
169
}

Gavin Wood's avatar
Gavin Wood committed
170
171
172
173
174
175
176
177
178
179
180
181
parameter_types! {
	pub const UncleGenerations: u64 = 0;
}

// TODO: substrate#2986 implement this properly
impl authorship::Trait for Runtime {
	type FindAuthor = ();
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
	type EventHandler = ();
}

182
183
184
185
186
187
188
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

type SessionHandlers = (Grandpa, Aura);
impl_opaque_keys! {
189
190
191
192
	pub struct SessionKeys {
		#[id(key_types::ED25519)]
		pub ed25519: GrandpaId,
	}
193
194
195
196
197
198
199
200
}

// NOTE: `SessionHandler` and `SessionKeys` are co-dependent: One key will be used for each handler.
// The number and order of items in `SessionHandler` *MUST* be the same number and order of keys in
// `SessionKeys`.
// TODO: Introduce some structure to tie these together to make it a bit less of a footgun. This
// should be easy, since OneSessionHandler trait provides the `Key` as an associated type. #2858

201
impl session::Trait for Runtime {
202
203
204
	type OnSessionEnding = Staking;
	type SessionHandler = SessionHandlers;
	type ShouldEndSession = session::PeriodicSessions<Period, Offset>;
Gav's avatar
Gav committed
205
	type Event = Event;
206
	type Keys = SessionKeys;
207
208
209
210
211
212
213
214
	type SelectInitialValidators = Staking;
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = staking::ExposureOf<Self>;
215
216
}

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/// Converter for currencies to votes.
pub struct CurrencyToVoteHandler;

impl CurrencyToVoteHandler {
	fn factor() -> u128 { (Balances::total_issuance() / u64::max_value() as u128).max(1) }
}

impl Convert<u128, u64> for CurrencyToVoteHandler {
	fn convert(x: u128) -> u64 { (x / Self::factor()) as u64 }
}

impl Convert<u128, u128> for CurrencyToVoteHandler {
	fn convert(x: u128) -> u128 { x * Self::factor() }
}

232
233
234
235
parameter_types! {
	pub const SessionsPerEra: session::SessionIndex = 6;
	pub const BondingDuration: staking::EraIndex = 24 * 28;
}
236

237
238
impl staking::Trait for Runtime {
	type OnRewardMinted = Treasury;
239
	type CurrencyToVote = CurrencyToVoteHandler;
Gav's avatar
Gav committed
240
	type Event = Event;
241
	type Currency = Balances;
242
243
	type Slash = ();
	type Reward = ();
244
245
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
246
	type SessionInterface = Self;
247
248
}

249
250
251
parameter_types! {
	pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
	pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
252
	pub const EmergencyVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
253
254
	pub const MinimumDeposit: Balance = 100 * BUCKS;
	pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
255
	pub const CooloffPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
256
257
}

258
259
260
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
261
	type Currency = Balances;
262
263
264
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
265
	type EmergencyVotingPeriod = EmergencyVotingPeriod;
266
	type MinimumDeposit = MinimumDeposit;
267
268
269
270
271
272
	type ExternalOrigin = council_motions::EnsureProportionAtLeast<_1, _2, AccountId>;
	type ExternalMajorityOrigin = council_motions::EnsureProportionAtLeast<_2, _3, AccountId>;
	type EmergencyOrigin = council_motions::EnsureProportionAtLeast<_1, _1, AccountId>;
	type CancellationOrigin = council_motions::EnsureProportionAtLeast<_2, _3, AccountId>;
	type VetoOrigin = council_motions::EnsureMember<AccountId>;
	type CooloffPeriod = CooloffPeriod;
273
}
274

Gavin Wood's avatar
Gavin Wood committed
275
276
277
278
279
280
281
282
283
284
285
286
parameter_types! {
	pub const CandidacyBond: Balance = 10 * BUCKS;
	pub const VotingBond: Balance = 1 * BUCKS;
	pub const VotingFee: Balance = 2 * BUCKS;
	pub const PresentSlashPerVoter: Balance = 1 * CENTS;
	pub const CarryCount: u32 = 6;
	// one additional vote should go by before an inactive voter can be reaped.
	pub const InactiveGracePeriod: council::VoteIndex = 1;
	pub const CouncilVotingPeriod: BlockNumber = 2 * DAYS;
	pub const DecayRatio: u32 = 0;
}

287
288
impl council::Trait for Runtime {
	type Event = Event;
289
290
	type BadPresentation = ();
	type BadReaper = ();
291
292
293
	type BadVoterIndex = ();
	type LoserCandidate = ();
	type OnMembersChanged = CouncilMotions;
Gavin Wood's avatar
Gavin Wood committed
294
295
296
297
298
299
300
301
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
	type VotingFee = VotingFee;
	type PresentSlashPerVoter = PresentSlashPerVoter;
	type CarryCount = CarryCount;
	type InactiveGracePeriod = InactiveGracePeriod;
	type CouncilVotingPeriod = CouncilVotingPeriod;
	type DecayRatio = DecayRatio;
302
303
304
305
306
307
308
309
}

impl council::motions::Trait for Runtime {
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
310
311
312
313
314
315
316
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
	pub const ProposalBondMinimum: Balance = 1 * BUCKS;
	pub const SpendPeriod: BlockNumber = 1 * DAYS;
	pub const Burn: Permill = Permill::from_percent(50);
}

317
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
318
	type Currency = Balances;
319
320
	type ApproveOrigin = council_motions::EnsureMembers<_4, AccountId>;
	type RejectOrigin = council_motions::EnsureMembers<_2, AccountId>;
321
	type Event = Event;
322
323
	type MintedForSpending = ();
	type ProposalRejection = ();
Gavin Wood's avatar
Gavin Wood committed
324
325
326
327
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
328
}
329

330
331
332
333
impl grandpa::Trait for Runtime {
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
334
335
336
337
338
339
340
341
342
343
344
parameter_types! {
	pub const WindowSize: BlockNumber = finality_tracker::DEFAULT_WINDOW_SIZE.into();
	pub const ReportLatency: BlockNumber = finality_tracker::DEFAULT_REPORT_LATENCY.into();
}

impl finality_tracker::Trait for Runtime {
	type OnFinalizationStalled = Grandpa;
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

345
346
347
impl parachains::Trait for Runtime {
	type Origin = Origin;
	type Call = Call;
348
	type ParachainCurrency = Balances;
349
}
350

Gavin Wood's avatar
Gavin Wood committed
351
parameter_types!{
352
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
353
354
355
356
357
358
359
360
361
362
363
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
	type Currency = balances::Module<Self>;
	type Parachains = parachains::Module<Self>;
	type LeasePeriod = LeasePeriod;
	type EndingPeriod = EndingPeriod;
}

364
365
impl curated_grandpa::Trait for Runtime { }

Gav Wood's avatar
Gav Wood committed
366
367
368
369
370
impl sudo::Trait for Runtime {
	type Event = Event;
	type Proposal = Call;
}

371
construct_runtime!(
372
	pub enum Runtime where
373
		Block = Block,
374
		NodeBlock = primitives::Block,
375
		UncheckedExtrinsic = UncheckedExtrinsic
376
	{
Gavin Wood's avatar
Gavin Wood committed
377
		System: system::{Module, Call, Storage, Config, Event},
378
		Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
379
		Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
Gavin Wood's avatar
Gavin Wood committed
380
		Authorship: authorship::{Module, Call, Storage},
Gav Wood's avatar
Gav Wood committed
381
		Indices: indices,
382
		Balances: balances,
Gavin Wood's avatar
Gavin Wood committed
383
		Staking: staking::{default, OfflineWorker},
384
		Session: session::{Module, Call, Storage, Event, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
385
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
386
		Council: council::{Module, Call, Storage, Event<T>},
387
		CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin<T>},
388
		CouncilSeats: council_seats::{Config<T>},
Gavin Wood's avatar
Gavin Wood committed
389
390
391
392
		FinalityTracker: finality_tracker::{Module, Call, Inherent},
		Grandpa: grandpa::{Module, Call, Storage, Config, Event},
		CuratedGrandpa: curated_grandpa::{Module, Call, Config<T>, Storage},
		Treasury: treasury::{Module, Call, Storage, Event<T>},
393
		Parachains: parachains::{Module, Call, Storage, Config<T>, Inherent, Origin},
Gavin Wood's avatar
Gavin Wood committed
394
		Slots: slots::{Module, Call, Storage, Event<T>},
Gav Wood's avatar
Gav Wood committed
395
		Sudo: sudo,
Gav's avatar
Gav committed
396
	}
397
398
399
);

/// The address format for describing accounts.
Gav Wood's avatar
Gav Wood committed
400
pub type Address = <Indices as StaticLookup>::Source;
401
/// Block header type as expected by this runtime.
402
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
403
404
405
406
407
408
409
/// 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>;
/// Unchecked extrinsic type as expected by this runtime.
Gav Wood's avatar
Gav Wood committed
410
pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address, Nonce, Call, Signature>;
411
/// Extrinsic type that has already been checked.
Gav Wood's avatar
Gav Wood committed
412
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
413
/// Executive: handles dispatch to the various modules.
thiolliere's avatar
thiolliere committed
414
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Balances, Runtime, AllModules>;
415
416

impl_runtime_apis! {
417
	impl client_api::Core<Block> for Runtime {
418
419
420
421
422
423
424
		fn version() -> RuntimeVersion {
			VERSION
		}

		fn execute_block(block: Block) {
			Executive::execute_block(block)
		}
425

426
427
		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
428
429
		}
	}
Gav's avatar
Gav committed
430

431
	impl client_api::Metadata<Block> for Runtime {
432
433
434
		fn metadata() -> OpaqueMetadata {
			Runtime::metadata().into()
		}
Gav's avatar
Gav committed
435
436
	}

437
	impl block_builder_api::BlockBuilder<Block> for Runtime {
438
439
440
441
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
			Executive::apply_extrinsic(extrinsic)
		}

442
443
		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
444
		}
445

446
447
		fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
448
		}
449

450
451
		fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
			data.check_extrinsics(&block)
452
		}
453

454
455
456
		fn random_seed() -> <Block as BlockT>::Hash {
			System::random_seed()
		}
457
458
	}

459
	impl client_api::TaggedTransactionQueue<Block> for Runtime {
460
461
462
		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
			Executive::validate_transaction(tx)
		}
Gav's avatar
Gav committed
463
	}
464

465
466
467
468
469
470
	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(number: sr_primitives::traits::NumberFor<Block>) {
			Executive::offchain_worker(number)
		}
	}

471
	impl parachain::ParachainHost<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
472
		fn validators() -> Vec<parachain::ValidatorId> {
473
			Aura::authorities()  // only possible as long as parachain validator crypto === aura crypto
474
475
476
477
478
479
480
		}
		fn duty_roster() -> parachain::DutyRoster {
			Parachains::calculate_duty_roster()
		}
		fn active_parachains() -> Vec<parachain::Id> {
			Parachains::active_parachains()
		}
481
482
		fn parachain_status(id: parachain::Id) -> Option<parachain::Status> {
			Parachains::parachain_status(&id)
483
484
485
486
		}
		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
			Parachains::parachain_code(&id)
		}
487
488
		fn ingress(to: parachain::Id) -> Option<parachain::StructuredUnroutedIngress> {
			Parachains::ingress(to).map(parachain::StructuredUnroutedIngress)
489
		}
490
	}
491
492

	impl fg_primitives::GrandpaApi<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
493
		fn grandpa_pending_change(digest: &DigestFor<Block>)
494
495
			-> Option<ScheduledChange<BlockNumber>>
		{
496
			Grandpa::pending_change(digest)
497
498
		}

499
500
501
502
503
504
		fn grandpa_forced_change(_digest: &DigestFor<Block>)
			-> Option<(BlockNumber, ScheduledChange<BlockNumber>)>
		{
			None // disable forced changes.
		}

505
506
507
508
509
		fn grandpa_authorities() -> Vec<(SessionKey, u64)> {
			Grandpa::grandpa_authorities()
		}
	}

510
	impl consensus_aura::AuraApi<Block, AuraId> for Runtime {
511
512
513
		fn slot_duration() -> u64 {
			Aura::slot_duration()
		}
514

515
516
		fn authorities() -> Vec<AuraId> {
			Aura::authorities()
517
518
519
		}
	}

Gav's avatar
Gav committed
520
}