lib.rs 15.6 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,
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::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
/// Runtime version.
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
67
pub const VERSION: RuntimeVersion = RuntimeVersion {
68
69
	spec_name: create_runtime_str!("polkadot"),
	impl_name: create_runtime_str!("parity-polkadot"),
Gav Wood's avatar
Gav Wood committed
70
	authoring_version: 1,
André Silva's avatar
André Silva committed
71
	spec_version: 1000,
72
	impl_version: 0,
73
	apis: RUNTIME_API_VERSIONS,
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
74
75
};

76
77
78
79
80
81
82
83
84
/// 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
85
86
87
88
89
90
91
92
93
94
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;

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

107
108
impl aura::Trait for Runtime {
	type HandleReport = aura::StakingSlasher<Runtime>;
109
	type AuthorityId = AuraId;
110
111
}

Gav Wood's avatar
Gav Wood committed
112
113
114
115
116
117
118
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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.
>;

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

161
impl timestamp::Trait for Runtime {
162
	type Moment = u64;
163
	type OnTimestampSet = Aura;
164
165
}

Gavin Wood's avatar
Gavin Wood committed
166
167
168
169
170
171
172
173
174
175
176
177
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 = ();
}

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

type SessionHandlers = (Grandpa, Aura);
impl_opaque_keys! {
	pub struct SessionKeys(grandpa::AuthorityId, AuraId);
}

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

194
impl session::Trait for Runtime {
195
196
197
	type OnSessionEnding = Staking;
	type SessionHandler = SessionHandlers;
	type ShouldEndSession = session::PeriodicSessions<Period, Offset>;
Gav's avatar
Gav committed
198
	type Event = Event;
199
	type Keys = SessionKeys;
200
201
}

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/// 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() }
}

217
218
219
220
parameter_types! {
	pub const SessionsPerEra: session::SessionIndex = 6;
	pub const BondingDuration: staking::EraIndex = 24 * 28;
}
221

222
223
impl staking::Trait for Runtime {
	type OnRewardMinted = Treasury;
224
	type CurrencyToVote = CurrencyToVoteHandler;
Gav's avatar
Gav committed
225
	type Event = Event;
226
	type Currency = Balances;
227
228
	type Slash = ();
	type Reward = ();
229
230
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
231
232
}

233
234
235
parameter_types! {
	pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
	pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
236
	pub const EmergencyVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
237
238
	pub const MinimumDeposit: Balance = 100 * BUCKS;
	pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
239
	pub const CooloffPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
240
241
}

242
243
244
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
245
	type Currency = Balances;
246
247
248
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
249
	type EmergencyVotingPeriod = EmergencyVotingPeriod;
250
	type MinimumDeposit = MinimumDeposit;
251
252
253
254
255
256
	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;
257
}
258

Gavin Wood's avatar
Gavin Wood committed
259
260
261
262
263
264
265
266
267
268
269
270
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;
}

271
272
impl council::Trait for Runtime {
	type Event = Event;
273
274
	type BadPresentation = ();
	type BadReaper = ();
275
276
277
	type BadVoterIndex = ();
	type LoserCandidate = ();
	type OnMembersChanged = CouncilMotions;
Gavin Wood's avatar
Gavin Wood committed
278
279
280
281
282
283
284
285
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
	type VotingFee = VotingFee;
	type PresentSlashPerVoter = PresentSlashPerVoter;
	type CarryCount = CarryCount;
	type InactiveGracePeriod = InactiveGracePeriod;
	type CouncilVotingPeriod = CouncilVotingPeriod;
	type DecayRatio = DecayRatio;
286
287
288
289
290
291
292
293
}

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

Gavin Wood's avatar
Gavin Wood committed
294
295
296
297
298
299
300
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);
}

301
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
302
	type Currency = Balances;
303
304
	type ApproveOrigin = council_motions::EnsureMembers<_4, AccountId>;
	type RejectOrigin = council_motions::EnsureMembers<_2, AccountId>;
305
	type Event = Event;
306
307
	type MintedForSpending = ();
	type ProposalRejection = ();
Gavin Wood's avatar
Gavin Wood committed
308
309
310
311
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
312
}
313

314
315
316
317
impl grandpa::Trait for Runtime {
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
318
319
320
321
322
323
324
325
326
327
328
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;
}

329
330
331
impl parachains::Trait for Runtime {
	type Origin = Origin;
	type Call = Call;
332
	type ParachainCurrency = Balances;
333
}
334

Gavin Wood's avatar
Gavin Wood committed
335
336
337
338
339
340
341
342
343
344
345
346
347
parameter_types!{
	pub const LeasePeriod: BlockNumber = 100000;
	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;
}

348
349
impl curated_grandpa::Trait for Runtime { }

Gav Wood's avatar
Gav Wood committed
350
351
352
353
354
impl sudo::Trait for Runtime {
	type Event = Event;
	type Proposal = Call;
}

355
construct_runtime!(
356
	pub enum Runtime where
357
		Block = Block,
358
		NodeBlock = primitives::Block,
359
		UncheckedExtrinsic = UncheckedExtrinsic
360
	{
Gavin Wood's avatar
Gavin Wood committed
361
		System: system::{Module, Call, Storage, Config, Event},
362
		Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
363
		Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
Gavin Wood's avatar
Gavin Wood committed
364
		Authorship: authorship::{Module, Call, Storage},
Gav Wood's avatar
Gav Wood committed
365
		Indices: indices,
366
		Balances: balances,
367
		Session: session::{Module, Call, Storage, Event, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
368
369
		Staking: staking::{default, OfflineWorker},
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
370
		Council: council::{Module, Call, Storage, Event<T>},
371
		CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin<T>},
372
		CouncilSeats: council_seats::{Config<T>},
Gavin Wood's avatar
Gavin Wood committed
373
374
375
376
		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>},
377
		Parachains: parachains::{Module, Call, Storage, Config<T>, Inherent, Origin},
Gavin Wood's avatar
Gavin Wood committed
378
		Slots: slots::{Module, Call, Storage, Event<T>},
Gav Wood's avatar
Gav Wood committed
379
		Sudo: sudo,
Gav's avatar
Gav committed
380
	}
381
382
383
);

/// The address format for describing accounts.
Gav Wood's avatar
Gav Wood committed
384
pub type Address = <Indices as StaticLookup>::Source;
385
/// Block header type as expected by this runtime.
386
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
387
388
389
390
391
392
393
/// 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
394
pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address, Nonce, Call, Signature>;
395
/// Extrinsic type that has already been checked.
Gav Wood's avatar
Gav Wood committed
396
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
397
/// Executive: handles dispatch to the various modules.
thiolliere's avatar
thiolliere committed
398
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Balances, Runtime, AllModules>;
399
400

impl_runtime_apis! {
401
	impl client_api::Core<Block> for Runtime {
402
403
404
405
406
407
408
		fn version() -> RuntimeVersion {
			VERSION
		}

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

410
411
		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
412
413
		}
	}
Gav's avatar
Gav committed
414

415
	impl client_api::Metadata<Block> for Runtime {
416
417
418
		fn metadata() -> OpaqueMetadata {
			Runtime::metadata().into()
		}
Gav's avatar
Gav committed
419
420
	}

421
	impl block_builder_api::BlockBuilder<Block> for Runtime {
422
423
424
425
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
			Executive::apply_extrinsic(extrinsic)
		}

426
427
		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
428
		}
429

430
431
		fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
432
		}
433

434
435
		fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
			data.check_extrinsics(&block)
436
		}
437

438
439
440
		fn random_seed() -> <Block as BlockT>::Hash {
			System::random_seed()
		}
441
442
	}

443
	impl client_api::TaggedTransactionQueue<Block> for Runtime {
444
445
446
		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
			Executive::validate_transaction(tx)
		}
Gav's avatar
Gav committed
447
	}
448

449
450
451
452
453
454
	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(number: sr_primitives::traits::NumberFor<Block>) {
			Executive::offchain_worker(number)
		}
	}

455
	impl parachain::ParachainHost<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
456
		fn validators() -> Vec<parachain::ValidatorId> {
457
			Aura::authorities()  // only possible as long as parachain validator crypto === aura crypto
458
459
460
461
462
463
464
		}
		fn duty_roster() -> parachain::DutyRoster {
			Parachains::calculate_duty_roster()
		}
		fn active_parachains() -> Vec<parachain::Id> {
			Parachains::active_parachains()
		}
465
466
		fn parachain_status(id: parachain::Id) -> Option<parachain::Status> {
			Parachains::parachain_status(&id)
467
468
469
470
		}
		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
			Parachains::parachain_code(&id)
		}
471
472
		fn ingress(to: parachain::Id) -> Option<parachain::StructuredUnroutedIngress> {
			Parachains::ingress(to).map(parachain::StructuredUnroutedIngress)
473
		}
474
	}
475
476

	impl fg_primitives::GrandpaApi<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
477
		fn grandpa_pending_change(digest: &DigestFor<Block>)
478
479
			-> Option<ScheduledChange<BlockNumber>>
		{
480
			Grandpa::pending_change(digest)
481
482
		}

483
484
485
486
487
488
		fn grandpa_forced_change(_digest: &DigestFor<Block>)
			-> Option<(BlockNumber, ScheduledChange<BlockNumber>)>
		{
			None // disable forced changes.
		}

489
490
491
492
493
		fn grandpa_authorities() -> Vec<(SessionKey, u64)> {
			Grandpa::grandpa_authorities()
		}
	}

494
	impl consensus_aura::AuraApi<Block, AuraId> for Runtime {
495
496
497
		fn slot_duration() -> u64 {
			Aura::slot_duration()
		}
498

499
500
		fn authorities() -> Vec<AuraId> {
			Aura::authorities()
501
502
503
		}
	}

Gav's avatar
Gav committed
504
}