lib.rs 16.7 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 elections::VoteIndex;
46
47
48
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
use substrate_primitives::OpaqueMetadata;
Gavin Wood's avatar
Gavin Wood committed
49
50
51
use srml_support::{
	parameter_types, construct_runtime, traits::{SplitTwoWays, Currency, OnUnbalanced}
};
52

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

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

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

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

86
87
88
pub const MILLICENTS: Balance = 1_000_000_000;
pub const CENTS: Balance = 1_000 * MILLICENTS;    // assume this is worth about a cent.
pub const DOLLARS: Balance = 100 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
89

90
91
92
93
pub const SECS_PER_BLOCK: BlockNumber = 6;
pub const MINUTES: BlockNumber = 60 / SECS_PER_BLOCK;
pub const HOURS: BlockNumber = MINUTES * 60;
pub const DAYS: BlockNumber = HOURS * 24;
Gavin Wood's avatar
Gavin Wood committed
94

95
96
97
98
parameter_types! {
	pub const BlockHashCount: u64 = 250;
}

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
	type BlockHashCount = BlockHashCount;
110
111
}

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

Gav Wood's avatar
Gav Wood committed
117
118
119
120
121
122
123
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
124
parameter_types! {
125
	pub const ExistentialDeposit: Balance = 1 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
	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.
>;

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

166
167
168
169
parameter_types! {
	pub const MinimumPeriod: u64 = SECS_PER_BLOCK / 2;
}

170
impl timestamp::Trait for Runtime {
171
	type Moment = u64;
172
	type OnTimestampSet = Aura;
173
	type MinimumPeriod = MinimumPeriod;
174
175
}

Gavin Wood's avatar
Gavin Wood committed
176
177
178
179
180
181
182
183
184
185
186
187
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 = ();
}

188
189
190
191
192
193
194
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

type SessionHandlers = (Grandpa, Aura);
impl_opaque_keys! {
195
196
197
198
	pub struct SessionKeys {
		#[id(key_types::ED25519)]
		pub ed25519: GrandpaId,
	}
199
200
201
202
203
204
205
206
}

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

207
impl session::Trait for Runtime {
208
209
210
	type OnSessionEnding = Staking;
	type SessionHandler = SessionHandlers;
	type ShouldEndSession = session::PeriodicSessions<Period, Offset>;
Gav's avatar
Gav committed
211
	type Event = Event;
212
	type Keys = SessionKeys;
213
214
215
216
217
218
219
220
	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>;
221
222
}

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/// 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() }
}

238
239
240
241
parameter_types! {
	pub const SessionsPerEra: session::SessionIndex = 6;
	pub const BondingDuration: staking::EraIndex = 24 * 28;
}
242

243
244
impl staking::Trait for Runtime {
	type OnRewardMinted = Treasury;
245
	type CurrencyToVote = CurrencyToVoteHandler;
Gav's avatar
Gav committed
246
	type Event = Event;
247
	type Currency = Balances;
248
249
	type Slash = ();
	type Reward = ();
250
251
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
252
	type SessionInterface = Self;
253
254
}

255
256
257
parameter_types! {
	pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
	pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
258
	pub const EmergencyVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
259
	pub const MinimumDeposit: Balance = 100 * DOLLARS;
260
	pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
261
	pub const CooloffPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
262
263
}

264
265
266
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
267
	type Currency = Balances;
268
269
270
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
271
	type EmergencyVotingPeriod = EmergencyVotingPeriod;
272
	type MinimumDeposit = MinimumDeposit;
273
274
275
276
277
278
	type ExternalOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilInstance>;
	type ExternalMajorityOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilInstance>;
	type ExternalPushOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalInstance>;
	type EmergencyOrigin = collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilInstance>;
	type CancellationOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilInstance>;
	type VetoOrigin = collective::EnsureMember<AccountId, CouncilInstance>;
279
	type CooloffPeriod = CooloffPeriod;
280
}
281

282
283
284
285
286
287
288
type CouncilInstance = collective::Instance1;
impl collective::Trait<CouncilInstance> for Runtime {
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
289
parameter_types! {
290
291
292
	pub const CandidacyBond: Balance = 10 * DOLLARS;
	pub const VotingBond: Balance = 1 * DOLLARS;
	pub const VotingFee: Balance = 2 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
293
294
295
	pub const PresentSlashPerVoter: Balance = 1 * CENTS;
	pub const CarryCount: u32 = 6;
	// one additional vote should go by before an inactive voter can be reaped.
296
297
	pub const InactiveGracePeriod: VoteIndex = 1;
	pub const ElectionsVotingPeriod: BlockNumber = 2 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
298
299
300
	pub const DecayRatio: u32 = 0;
}

301
impl elections::Trait for Runtime {
302
	type Event = Event;
303
	type Currency = Balances;
304
305
	type BadPresentation = ();
	type BadReaper = ();
306
307
	type BadVoterIndex = ();
	type LoserCandidate = ();
308
	type ChangeMembers = Council;
Gavin Wood's avatar
Gavin Wood committed
309
310
311
312
313
314
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
	type VotingFee = VotingFee;
	type PresentSlashPerVoter = PresentSlashPerVoter;
	type CarryCount = CarryCount;
	type InactiveGracePeriod = InactiveGracePeriod;
315
	type VotingPeriod = ElectionsVotingPeriod;
Gavin Wood's avatar
Gavin Wood committed
316
	type DecayRatio = DecayRatio;
317
318
}

319
320
type TechnicalInstance = collective::Instance2;
impl collective::Trait<TechnicalInstance> for Runtime {
321
322
323
324
325
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
326
327
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
328
	pub const ProposalBondMinimum: Balance = 1 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
329
330
331
332
	pub const SpendPeriod: BlockNumber = 1 * DAYS;
	pub const Burn: Permill = Permill::from_percent(50);
}

333
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
334
	type Currency = Balances;
335
336
	type ApproveOrigin = collective::EnsureMembers<_4, AccountId, CouncilInstance>;
	type RejectOrigin = collective::EnsureMembers<_2, AccountId, CouncilInstance>;
337
	type Event = Event;
338
339
	type MintedForSpending = ();
	type ProposalRejection = ();
Gavin Wood's avatar
Gavin Wood committed
340
341
342
343
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
344
}
345

346
347
348
349
impl grandpa::Trait for Runtime {
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
350
351
352
353
354
355
356
357
358
359
360
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;
}

361
362
363
impl parachains::Trait for Runtime {
	type Origin = Origin;
	type Call = Call;
364
	type ParachainCurrency = Balances;
365
}
366

Gavin Wood's avatar
Gavin Wood committed
367
parameter_types!{
368
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
369
370
371
372
373
374
375
376
377
378
379
	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;
}

380
381
impl curated_grandpa::Trait for Runtime { }

Gav Wood's avatar
Gav Wood committed
382
383
384
385
386
impl sudo::Trait for Runtime {
	type Event = Event;
	type Proposal = Call;
}

387
construct_runtime!(
388
	pub enum Runtime where
389
		Block = Block,
390
		NodeBlock = primitives::Block,
391
		UncheckedExtrinsic = UncheckedExtrinsic
392
	{
Gavin Wood's avatar
Gavin Wood committed
393
		System: system::{Module, Call, Storage, Config, Event},
394
		Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
395
		Timestamp: timestamp::{Module, Call, Storage, Inherent},
Gavin Wood's avatar
Gavin Wood committed
396
		Authorship: authorship::{Module, Call, Storage},
Gav Wood's avatar
Gav Wood committed
397
		Indices: indices,
398
		Balances: balances,
Gavin Wood's avatar
Gavin Wood committed
399
		Staking: staking::{default, OfflineWorker},
400
		Session: session::{Module, Call, Storage, Event, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
401
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
402
403
404
		Council: collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		TechnicalCommittee: collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		Elections: elections::{Module, Call, Storage, Event<T>, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
405
406
407
408
		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>},
409
		Parachains: parachains::{Module, Call, Storage, Config<T>, Inherent, Origin},
Gavin Wood's avatar
Gavin Wood committed
410
		Slots: slots::{Module, Call, Storage, Event<T>},
Gav Wood's avatar
Gav Wood committed
411
		Sudo: sudo,
Gav's avatar
Gav committed
412
	}
413
414
415
);

/// The address format for describing accounts.
Gav Wood's avatar
Gav Wood committed
416
pub type Address = <Indices as StaticLookup>::Source;
417
/// Block header type as expected by this runtime.
418
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
419
420
421
422
423
424
425
/// 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
426
pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address, Nonce, Call, Signature>;
427
/// Extrinsic type that has already been checked.
Gav Wood's avatar
Gav Wood committed
428
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
429
/// Executive: handles dispatch to the various modules.
thiolliere's avatar
thiolliere committed
430
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Balances, Runtime, AllModules>;
431
432

impl_runtime_apis! {
433
	impl client_api::Core<Block> for Runtime {
434
435
436
437
438
439
440
		fn version() -> RuntimeVersion {
			VERSION
		}

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

442
443
		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
444
445
		}
	}
Gav's avatar
Gav committed
446

447
	impl client_api::Metadata<Block> for Runtime {
448
449
450
		fn metadata() -> OpaqueMetadata {
			Runtime::metadata().into()
		}
Gav's avatar
Gav committed
451
452
	}

453
	impl block_builder_api::BlockBuilder<Block> for Runtime {
454
455
456
457
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
			Executive::apply_extrinsic(extrinsic)
		}

458
459
		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
460
		}
461

462
463
		fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
464
		}
465

466
467
		fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
			data.check_extrinsics(&block)
468
		}
469

470
471
472
		fn random_seed() -> <Block as BlockT>::Hash {
			System::random_seed()
		}
473
474
	}

475
	impl client_api::TaggedTransactionQueue<Block> for Runtime {
476
477
478
		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
			Executive::validate_transaction(tx)
		}
Gav's avatar
Gav committed
479
	}
480

481
482
483
484
485
486
	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(number: sr_primitives::traits::NumberFor<Block>) {
			Executive::offchain_worker(number)
		}
	}

487
	impl parachain::ParachainHost<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
488
		fn validators() -> Vec<parachain::ValidatorId> {
489
			Aura::authorities()  // only possible as long as parachain validator crypto === aura crypto
490
491
492
493
494
495
496
		}
		fn duty_roster() -> parachain::DutyRoster {
			Parachains::calculate_duty_roster()
		}
		fn active_parachains() -> Vec<parachain::Id> {
			Parachains::active_parachains()
		}
497
498
		fn parachain_status(id: parachain::Id) -> Option<parachain::Status> {
			Parachains::parachain_status(&id)
499
500
501
502
		}
		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
			Parachains::parachain_code(&id)
		}
503
504
		fn ingress(to: parachain::Id) -> Option<parachain::StructuredUnroutedIngress> {
			Parachains::ingress(to).map(parachain::StructuredUnroutedIngress)
505
		}
506
	}
507
508

	impl fg_primitives::GrandpaApi<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
509
		fn grandpa_pending_change(digest: &DigestFor<Block>)
510
511
			-> Option<ScheduledChange<BlockNumber>>
		{
512
			Grandpa::pending_change(digest)
513
514
		}

515
516
517
518
519
520
		fn grandpa_forced_change(_digest: &DigestFor<Block>)
			-> Option<(BlockNumber, ScheduledChange<BlockNumber>)>
		{
			None // disable forced changes.
		}

521
522
523
524
525
		fn grandpa_authorities() -> Vec<(SessionKey, u64)> {
			Grandpa::grandpa_authorities()
		}
	}

526
	impl consensus_aura::AuraApi<Block, AuraId> for Runtime {
527
528
529
		fn slot_duration() -> u64 {
			Aura::slot_duration()
		}
530

531
532
		fn authorities() -> Vec<AuraId> {
			Aura::authorities()
533
534
535
		}
	}

Gav's avatar
Gav committed
536
}