Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Documentation for Aura Consensus Extension #2074

Merged
merged 19 commits into from
Apr 16, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 61 additions & 13 deletions srml/aura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,54 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

//! Consensus extension module for Aura consensus. This manages offline reporting.
//! # Aura Module
//!
//! ## Overview
//!
//! The Aura module extends Aura consensus by managing offline reporting.
//!
//! ## Interface
//!
//! ### Public Functions
//!
//! See the [`Module`](./struct.Module.html) struct for details on publicly available functions.
//!
//! ## Usage
//!
//! ### Prerequisites
//!
//! Use of this module implies selection of the Aura algorithm.
//!
//! ### Simple Code Snippet
//!
//! Instantiate a report of skipped authorities:
//!
//! ```rust,ignore
//! let mut report = AuraReport {
//! start_slot: 6, // The first skipped slot
//! skipped: 3, // The number of authorities skipped
//! }
//! ```
//!
//! See the `tests.rs` file in this module's directory for other simple code snippets that may make this module's
//! functionalities clearer.
//!
//! ## Related Modules
//!
//! - [`staking`](../srml_staking/index.html): The Staking module is called in Aura to enforce slashing
//! if validators miss a certain number of slots (see the [`StakingSlasher`](./struct.StakingSlasher.html)
//! struct and associated method).
//! - [`timestamp`](../srml_timestamp/index.html): The Timestamp module is used in Aura to track
//! consensus rounds (via `slots`).
//! - [`consensus`](../srml_consensus/index.html): The Consensus module does not relate directly to Aura,
//! but serves to manage offline reporting by implementing `ProvideInherent` in a similar way.
//!
//! ## 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`](../substrate_inherents/trait.ProvideInherent.html) and
//! [`ProvideInherentData`](../substrate_inherents/trait.ProvideInherentData.html) to create and check inherents.

#![cfg_attr(not(feature = "std"), no_std)]

Expand All @@ -35,13 +82,13 @@ use inherents::{InherentDataProviders, ProvideInherentData};
mod mock;
mod tests;

/// The aura inherent identifier.
/// The Aura inherent identifier.
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"auraslot";

/// The type of the aura inherent.
/// The type of the Aura inherent.
pub type InherentType = u64;

/// Auxiliary trait to extract aura inherent data.
/// Auxiliary trait to extract Aura inherent data.
pub trait AuraInherentData {
/// Get aura inherent data.
fn aura_inherent_data(&self) -> result::Result<InherentType, RuntimeString>;
Expand Down Expand Up @@ -107,7 +154,7 @@ impl ProvideInherentData for InherentDataProvider {
}
}

/// Something which can handle Aura consensus reports.
/// Something that can handle Aura consensus reports.
pub trait HandleReport {
fn handle_report(report: AuraReport);
}
Expand All @@ -123,7 +170,7 @@ pub trait Trait: timestamp::Trait {

decl_storage! {
trait Store for Module<T: Trait> as Aura {
// The last timestamp.
/// The last timestamp.
LastTimestamp get(last) build(|_| T::Moment::sa(0)): T::Moment;
}
}
Expand All @@ -132,7 +179,7 @@ decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin { }
}

/// A report of skipped authorities in aura.
/// A report of skipped authorities in Aura.
#[derive(Clone, Encode, Decode, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct AuraReport {
Expand All @@ -143,14 +190,14 @@ pub struct AuraReport {
}

impl AuraReport {
/// Call the closure with (validator_indices, punishment_count) for each
/// Call the closure with (`validator_indices`, `punishment_count`) for each
/// validator to punish.
pub fn punish<F>(&self, validator_count: usize, mut punish_with: F)
where F: FnMut(usize, usize)
{
// If all validators have been skipped, then it implies some sort of
// If all validators have been skipped, then it implies some sort of
// systematic problem common to all rather than a minority of validators
// unfulfilling their specific duties. In this case, it doesn't make
// not fulfilling their specific duties. In this case, it doesn't make
// sense to punish anyone, so we guard against it.
if self.skipped < validator_count {
for index in 0..self.skipped {
Expand All @@ -161,10 +208,10 @@ impl AuraReport {
}

impl<T: Trait> Module<T> {
/// Determine the Aura slot-duration based on the timestamp module configuration.
/// Determine the Aura slot-duration based on the Timestamp module configuration.
pub fn slot_duration() -> u64 {
// we double the minimum block-period so each author can always propose within
// the majority of their slot.
// the majority of its slot.
<timestamp::Module<T>>::minimum_period().as_().saturating_mul(2)
}

Expand Down Expand Up @@ -202,7 +249,7 @@ impl<T: Trait> OnTimestampSet<T::Moment> for Module<T> {
}
}

/// A type for performing slashing based on aura reports.
/// A type for performing slashing based on Aura reports.
pub struct StakingSlasher<T>(::rstd::marker::PhantomData<T>);

impl<T: staking::Trait + Trait> HandleReport for StakingSlasher<T> {
Expand All @@ -228,6 +275,7 @@ impl<T: Trait> ProvideInherent for Module<T> {
None
}

/// Verify the validity of the inherent using the timestamp.
fn check_inherent(call: &Self::Call, data: &InherentData) -> result::Result<(), Self::Error> {
let timestamp = match call {
timestamp::Call::set(ref timestamp) => timestamp.clone(),
Expand Down