diff --git a/srml/consensus/src/lib.rs b/srml/consensus/src/lib.rs
index dfcc6805dc8de..4c2a57b83c1de 100644
--- a/srml/consensus/src/lib.rs
+++ b/srml/consensus/src/lib.rs
@@ -14,7 +14,105 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
-//! Consensus module for runtime; manages the authority set ready for the native code.
+//! # Consensus Module
+//!
+//! ## Overview
+//!
+//! The consensus module manages the authority set for the native code. It provides support for reporting offline
+//! behavior among validators and logging changes in the validator authority set.
+//!
+//! ## Interface
+//!
+//! ### Dispatchable Functions
+//!
+//! - `report_misbehavior` - Report some misbehavior. The origin of this call must be signed.
+//! - `note_offline` - Note that the previous block's validator missed its opportunity to propose a block.
+//! The origin of this call must be an inherent.
+//! - `remark` - Make some on-chain remark. The origin of this call must be signed.
+//! - `set_heap_pages` - Set the number of pages in the WebAssembly environment's heap.
+//! - `set_code` - Set the new code.
+//! - `set_storage` - Set some items of storage.
+//!
+//! Please refer to the [`Call`](./enum.Call.html) enum and its associated variants for documentation on each function.
+//!
+//! ### Public Functions
+//!
+//! See the [module](./struct.Module.html) for details on publicly available functions.
+//!
+//! ## Usage
+//!
+//! ### Prerequisites
+//!
+//! To use functionality from the consensus module, implement the specific Trait or function that you are invoking
+//! from the module:
+//!
+//! ```rust,ignore
+//! impl for consensus::SomeTrait for Module {
+//! /// required functions and types for trait included here
+//! /// more comprehensive example included below
+//! }
+//! ```
+//!
+//! Alternatively, to set the authorities:
+//!
+//! ```rust,ignore
+//! consensus::set_authorities(&[]) // example included below
+//! ```
+//!
+//! ### Simple Code Snippet
+//!
+//! Set authorities:
+//!
+//! ```rust,ignore
+//! >::set_authorities(&[UintAuthorityId(4), UintAuthorityId(5), UintAuthorityId(6)])
+//! ```
+//!
+//! Log changes in the authorities set:
+//!
+//! ```rust,ignore
+//! >::on_finalise(5); // finalize UintAuthorityId(5)
+//! ```
+//!
+//! ### Example from SRML
+//!
+//! In the staking module, the `consensus::OnOfflineReport` is implemented to monitor offline
+//! reporting among validators:
+//!
+//! ```rust,ignore
+//! impl consensus::OnOfflineReport> for Module {
+//! fn handle_report(reported_indices: Vec) {
+//! for validator_index in reported_indices {
+//! let v = >::validators()[validator_index as usize].clone();
+//! Self::on_offline_validator(v, 1);
+//! }
+//! }
+//! }
+//! ```
+//!
+//! In the GRANDPA module, we use `srml-consensus` to get the set of `next_authorities` before changing
+//! this set according to the consensus algorithm (which does not rotate sessions in the *normal* way):
+//!
+//! ```rust,ignore
+//! let next_authorities = >::authorities()
+//! .into_iter()
+//! .map(|key| (key, 1)) // evenly-weighted.
+//! .collect::::SessionKey, u64)>>();
+//! ```
+//!
+//! ## Related Modules
+//!
+//! - [`staking`](../srml_staking/index.html): This module uses `srml-consensus` to monitor offline
+//! reporting among validators.
+//! - [`aura`](../srml_aura/index.html): This module does not relate directly to `srml-consensus`,
+//! but serves to manage offline reporting for the Aura consensus algorithm with its own `handle_report` method.
+//! - [`grandpa`](../srml_grandpa/index.html): Although GRANDPA does its own voter-set management,
+//! it has a mode where it can track `consensus`, if desired.
+//!
+//! ## References
+//!
+//! If you're interested in hacking on this module, it is useful to understand the interaction with
+//! `substrate/core/inherents/src/lib.rs` and, specifically, the required implementation of `ProvideInherent`
+//! to create and check inherents.
#![cfg_attr(not(feature = "std"), no_std)]
@@ -88,9 +186,9 @@ impl InherentOfflineReport for () {
}
}
-/// A variant of the `OfflineReport` which is useful for instant-finality blocks.
+/// A variant of the `OfflineReport` that is useful for instant-finality blocks.
///
-/// This assumes blocks are only finalized
+/// This assumes blocks are only finalized.
pub struct InstantFinalityReportVec(::rstd::marker::PhantomData);
impl>> InherentOfflineReport for InstantFinalityReportVec {
@@ -117,7 +215,7 @@ pub type Log = RawLog<
::SessionKey,
>;
-/// A logs in this module.
+/// Logs in this module.
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog {
@@ -159,7 +257,7 @@ pub trait Trait: system::Trait {
decl_storage! {
trait Store for Module as Consensus {
- // Authorities set actual at the block execution start. IsSome only if
+ // Actual authorities set at the block execution start. Is `Some` iff
// the set has been changed.
OriginalAuthorities: Option>;
}
@@ -188,7 +286,7 @@ decl_module! {
ensure_signed(origin)?;
}
- /// Note the previous block's validator missed their opportunity to propose a block.
+ /// Note that the previous block's validator missed its opportunity to propose a block.
fn note_offline(origin, offline: ::Inherent) {
ensure_inherent(origin)?;
@@ -243,7 +341,7 @@ impl Module {
/// Set the current set of authorities' session keys.
///
- /// Called by `next_session` only.
+ /// Called by `rotate_session` only.
pub fn set_authorities(authorities: &[T::SessionKey]) {
let current_authorities = AuthorityStorageVec::::items();
if current_authorities != authorities {
@@ -284,11 +382,16 @@ impl Module {
}
}
+/// Implementing `ProvideInherent` enables this module to create and check inherents.
impl ProvideInherent for Module {
+ /// The call type of the module.
type Call = Call;
+ /// The error returned by `check_inherent`.
type Error = MakeFatalError;
+ /// The inherent identifier used by this inherent.
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
+ /// Creates an inherent from the `InherentData`.
fn create_inherent(data: &InherentData) -> Option {
if let Ok(Some(data)) =
data.get_data::<::Inherent>(
@@ -305,6 +408,7 @@ impl ProvideInherent for Module {
}
}
+ /// Verify the validity of the given inherent.
fn check_inherent(call: &Self::Call, data: &InherentData) -> Result<(), Self::Error> {
let offline = match call {
Call::note_offline(ref offline) => offline,
diff --git a/srml/consensus/src/tests.rs b/srml/consensus/src/tests.rs
index ff60660b0a475..4fb5bb614d5f4 100644
--- a/srml/consensus/src/tests.rs
+++ b/srml/consensus/src/tests.rs
@@ -44,6 +44,27 @@ fn authorities_change_logged() {
});
}
+#[test]
+fn partial_authorities_change_logged() {
+ with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
+ System::initialise(&2, &Default::default(), &Default::default());
+ Consensus::set_authorities(&[UintAuthorityId(2), UintAuthorityId(4), UintAuthorityId(5)]);
+ Consensus::on_finalise(2);
+ let header = System::finalise();
+ assert_eq!(header.digest, testing::Digest {
+ logs: vec![
+ generic::DigestItem::AuthoritiesChange(
+ vec![
+ UintAuthorityId(2).into(),
+ UintAuthorityId(4).into(),
+ UintAuthorityId(5).into()
+ ]
+ ),
+ ],
+ });
+ });
+}
+
#[test]
fn authorities_change_is_not_logged_when_not_changed() {
with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs
index 3d07b53e2e444..204eaccc1f94b 100644
--- a/srml/session/src/lib.rs
+++ b/srml/session/src/lib.rs
@@ -103,7 +103,7 @@ decl_storage! {
/// Timestamp when current session started.
pub CurrentStart get(current_start) build(|_| T::Moment::zero()): T::Moment;
- /// New session is being forced is this entry exists; in which case, the boolean value is whether
+ /// New session is being forced if this entry exists; in which case, the boolean value is whether
/// the new session should be considered a normal rotation (rewardable) or exceptional (slashable).
pub ForcingNewSession get(forcing_new_session): Option;
/// Block at which the session length last changed.
@@ -121,12 +121,12 @@ decl_storage! {
}
impl Module {
- /// The number of validators currently.
+ /// The current number of validators.
pub fn validator_count() -> u32 {
>::get().len() as u32
}
- /// The last length change, if there was one, zero if not.
+ /// The last length change if there was one, zero if not.
pub fn last_length_change() -> T::BlockNumber {
>::get().unwrap_or_else(T::BlockNumber::zero)
}
@@ -140,7 +140,7 @@ impl Module {
/// Set the current set of validators.
///
- /// Called by `staking::new_era()` only. `rotate_session` must be called after this in order to
+ /// Called by `staking::new_era` only. `rotate_session` must be called after this in order to
/// update the session keys to the next validator set.
pub fn set_validators(new: &[T::AccountId]) {
>::put(&new.to_vec());
@@ -148,9 +148,9 @@ impl Module {
/// Hook to be called after transaction processing.
pub fn check_rotate_session(block_number: T::BlockNumber) {
- // do this last, after the staking system has had chance to switch out the authorities for the
+ // Do this last, after the staking system has had the chance to switch out the authorities for the
// new set.
- // check block number and call next_session if necessary.
+ // Check block number and call `rotate_session` if necessary.
let is_final_block = ((block_number - Self::last_length_change()) % Self::length()).is_zero();
let (should_end_session, apply_rewards) = >::take()
.map_or((is_final_block, is_final_block), |apply_rewards| (true, apply_rewards));
@@ -159,7 +159,7 @@ impl Module {
}
}
- /// Move onto next session: register the new authority set.
+ /// Move on to next session: register the new authority set.
pub fn rotate_session(is_final_block: bool, apply_rewards: bool) {
let now = >::get();
let time_elapsed = now.clone() - Self::current_start();
@@ -206,7 +206,7 @@ impl Module {
}
/// Number of blocks remaining in this session, not counting this one. If the session is
- /// due to rotate at the end of this block, then it will return 0. If the just began, then
+ /// due to rotate at the end of this block, then it will return 0. If the session just began, then
/// it will return `Self::length() - 1`.
pub fn blocks_remaining() -> T::BlockNumber {
let length = Self::length();