Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions bin/node/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ pub type BlockId = generic::BlockId<Block>;
pub mod report {
use super::{Signature, Verify};
use frame_system::offchain::AppCrypto;
use sp_core::crypto::KeyTypeId;
use sp_core::crypto::{key_types, KeyTypeId};

/// Key type for the reporting module. Used for reporting BABE and GRANDPA
/// equivocations.
pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"fish");
pub const KEY_TYPE: KeyTypeId = key_types::REPORTING;

mod app {
use sp_application_crypto::{app_crypto, sr25519};
Expand Down
10 changes: 8 additions & 2 deletions frame/grandpa/src/equivocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
//! And in a runtime context, so that the GRANDPA module can validate the
//! equivocation proofs in the extrinsic and report the offences.
//!
//! IMPORTANT:
//! When using this module for enabling equivocation reporting it is required
//! that the `ValidateEquivocationReport` signed extension is used in the runtime
//! definition. Failure to do so will allow invalid equivocation reports to be
//! accepted by the runtime.
//!

use sp_std::prelude::*;

Expand Down Expand Up @@ -395,12 +401,12 @@ impl GetValidatorCount for frame_support::Void {

impl GetSessionNumber for sp_session::MembershipProof {
fn session(&self) -> SessionIndex {
self.session()
self.session
}
}

impl GetValidatorCount for sp_session::MembershipProof {
fn validator_count(&self) -> sp_session::ValidatorCount {
self.validator_count()
self.validator_count
}
}
24 changes: 13 additions & 11 deletions frame/grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ decl_error! {
ChangePending,
/// Cannot signal forced change so soon after last.
TooSoon,
/// A key ownership proof provided as part of an equivocation report is invalid.
InvalidKeyOwnershipProof,
/// A given equivocation report is valid but already previously reported.
DuplicateOffenceReport,
}
}

Expand Down Expand Up @@ -228,8 +232,9 @@ decl_module! {
/// against the extracted offender. If both are valid, the offence
/// will be reported.
///
/// Since the weight is 0 in order to avoid DoS pre-validation is implemented in a
/// `SignedExtension`.
/// Since the weight of the extrinsic is 0, in order to avoid DoS by
/// submission of invalid equivocation reports, a mandatory pre-validation of
/// the extrinsic is implemented in a `SignedExtension`.
#[weight = 0]
fn report_equivocation(
origin,
Expand All @@ -249,7 +254,7 @@ decl_module! {
T::KeyOwnerProofSystem::check_proof(
(fg_primitives::KEY_TYPE, equivocation_proof.offender().clone()),
key_owner_proof,
).ok_or("Invalid key ownership proof.")?;
).ok_or(Error::<T>::InvalidKeyOwnershipProof)?;

// the set id and round when the offence happened
let set_id = equivocation_proof.set_id();
Expand All @@ -265,7 +270,7 @@ decl_module! {
set_id,
round,
),
).map_err(|_| "Duplicate offence report.")?;
).map_err(|_| Error::<T>::DuplicateOffenceReport)?;
}

fn on_finalize(block_number: T::BlockNumber) {
Expand Down Expand Up @@ -440,9 +445,9 @@ impl<T: Trait> Module<T> {
Self::set_grandpa_authorities(authorities);
}

// NOTE: initialize first session of first set. this is necessary
// because we only update this `on_new_session` which isn't called
// for the genesis session.
// NOTE: initialize first session of first set. this is necessary for
// the genesis set and session since we only update the set -> session
// mapping whenever a new session starts, i.e. through `on_new_session`.
SetIdSession::insert(0, 0);
}

Expand All @@ -454,10 +459,7 @@ impl<T: Trait> Module<T> {
equivocation_proof: EquivocationProof<T::Hash, T::BlockNumber>,
key_owner_proof: T::KeyOwnerProof,
) -> Option<()> {
T::HandleEquivocation::submit_equivocation_report(equivocation_proof, key_owner_proof)
.ok()?;

Some(())
T::HandleEquivocation::submit_equivocation_report(equivocation_proof, key_owner_proof).ok()
}
}

Expand Down
2 changes: 2 additions & 0 deletions primitives/core/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,8 @@ pub mod key_types {
pub const AUTHORITY_DISCOVERY: KeyTypeId = KeyTypeId(*b"audi");
/// Key type for staking, built-in. Identified as `stak`.
pub const STAKING: KeyTypeId = KeyTypeId(*b"stak");
/// Key type for equivocation reporting, built-in. Identified as `fish`.
pub const REPORTING: KeyTypeId = KeyTypeId(*b"fish");
/// A key type ID useful for tests.
pub const DUMMY: KeyTypeId = KeyTypeId(*b"dumy");
}
Expand Down
21 changes: 7 additions & 14 deletions primitives/finality-grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,21 +352,11 @@ where
H: Encode,
N: Encode,
{
localized_payload_with_buffer(round, set_id, message, buf);

#[cfg(not(feature = "std"))]
let verify = || {
use sp_application_crypto::RuntimeAppPublic;
id.verify(&buf, signature)
};
use sp_application_crypto::RuntimeAppPublic;

#[cfg(feature = "std")]
let verify = || {
use sp_application_crypto::Pair;
AuthorityPair::verify(signature, &buf, &id)
};
localized_payload_with_buffer(round, set_id, message, buf);

if verify() {
if id.verify(&buf, signature) {
Ok(())
} else {
#[cfg(feature = "std")]
Expand Down Expand Up @@ -501,7 +491,10 @@ sp_api::decl_runtime_apis! {
/// provide the equivocation proof and a key ownership proof (should be
/// obtained using `generate_key_ownership_proof`). This method will
/// sign the extrinsic with any reporting keys available in the keystore
/// and will push the transaction to the pool.
/// and will push the transaction to the pool. This method returns `None`
/// when creation of the extrinsic fails, either due to unavailability
/// of keys to sign, or because equivocation reporting is disabled for
/// the given runtime (i.e. this method is hardcoded to return `None`).
/// Only useful in an offchain context.
fn submit_report_equivocation_extrinsic(
equivocation_proof: EquivocationProof<Block::Hash, NumberFor<Block>>,
Expand Down
12 changes: 0 additions & 12 deletions primitives/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,6 @@ pub struct MembershipProof {
pub validator_count: ValidatorCount,
}

impl MembershipProof {
/// Returns a session this proof was generated for.
pub fn session(&self) -> SessionIndex {
self.session
}

/// Returns the validator count of the session this proof was generated for.
pub fn validator_count(&self) -> ValidatorCount {
self.validator_count
}
}

/// Generate the initial session keys with the given seeds, at the given block and store them in
/// the client's keystore.
#[cfg(feature = "std")]
Expand Down