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

Integrate srml/im-online with slashing #3193

Closed
Closed
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
6 changes: 6 additions & 0 deletions core/sr-primitives/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,12 @@ pub trait IsMember<MemberId> {
fn is_member(member_id: &MemberId) -> bool;
}

/// Determine if an `AuthorityId` is online in the current session.
pub trait IsOnline<AuthorityId> {
/// Is the given `AuthorityId` online in the current session?
fn is_online_in_current_session(authority_id: &AuthorityId) -> bool;
}

/// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`,
/// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and
/// `parent_hash`, as well as a `digest` and a block `number`.
Expand Down
12 changes: 11 additions & 1 deletion node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use primitives::bytes;
use primitives::{ed25519, sr25519, OpaqueMetadata};
use sr_primitives::{
ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
traits::{self, NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify}, weights::Weight,
traits::{
self, NumberFor, BlakeTwo256, Block as BlockT, IsOnline, StaticLookup, Verify,
},
weights::Weight,
};
use client::{
block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
Expand Down Expand Up @@ -138,6 +141,13 @@ impl system::Trait for Runtime {
impl aura::Trait for Runtime {
type HandleReport = ();
type AuthorityId = AuraId;
type IsOnline = Runtime;
}

impl IsOnline<AuraId> for Runtime {
fn is_online_in_current_session(authority_id: &AuraId) -> bool {
true
}
}

impl indices::Trait for Runtime {
Expand Down
13 changes: 10 additions & 3 deletions node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use runtime_primitives::{ApplyResult, impl_opaque_keys, generic, create_runtime_
use runtime_primitives::transaction_validity::TransactionValidity;
use runtime_primitives::weights::Weight;
use runtime_primitives::traits::{
BlakeTwo256, Block as BlockT, DigestFor, NumberFor, StaticLookup,
BlakeTwo256, Block as BlockT, DigestFor, IsOnline, NumberFor, StaticLookup,
};
use version::RuntimeVersion;
use elections::VoteIndex;
Expand Down Expand Up @@ -78,8 +78,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to equal spec_version. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 118,
impl_version: 118,
spec_version: 119,
impl_version: 119,
apis: RUNTIME_API_VERSIONS,
};

Expand Down Expand Up @@ -143,6 +143,7 @@ impl system::Trait for Runtime {
impl aura::Trait for Runtime {
type HandleReport = aura::StakingSlasher<Runtime>;
type AuthorityId = AuraId;
type IsOnline = Runtime;
}

impl indices::Trait for Runtime {
Expand Down Expand Up @@ -388,6 +389,12 @@ impl im_online::Trait for Runtime {
type IsValidAuthorityId = Aura;
}

impl IsOnline<AuraId> for Runtime {
fn is_online_in_current_session(authority_id: &AuraId) -> bool {
ImOnline::is_online_in_current_session(authority_id)
}
}

impl grandpa::Trait for Runtime {
type Event = Event;
}
Expand Down
20 changes: 17 additions & 3 deletions srml/aura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use rstd::{result, prelude::*};
use parity_codec::Encode;
use srml_support::{decl_storage, decl_module, Parameter, storage::StorageValue, traits::Get};
use primitives::{
traits::{SaturatedConversion, Saturating, Zero, One, Member, IsMember, TypedKey},
traits::{SaturatedConversion, Saturating, Zero, One, Member, IsMember, IsOnline, TypedKey},
generic::DigestItem,
};
use timestamp::OnTimestampSet;
Expand Down Expand Up @@ -157,6 +157,9 @@ pub trait Trait: timestamp::Trait {

/// The identifier type for an authority.
type AuthorityId: Member + Parameter + TypedKey + Default;

/// Determine if an `AuthorityId` is online.
type IsOnline: IsOnline<Self::AuthorityId>;
}

decl_storage! {
Expand Down Expand Up @@ -297,8 +300,19 @@ impl<T: staking::Trait + Trait> HandleReport for StakingSlasher<T> {
report.punish(
validators.len(),
|idx, slash_count| {
let v = validators[idx].clone();
staking::Module::<T>::on_offline_validator(v, slash_count);
// slash only if the validator isn't marked as online in the current session
// TODO maybe define AuthorityOf(AccountId) instead of putting this here
let account_id = validators[idx].clone();
let keys = T::SessionInterface::current_keys::<T::AuthorityId>();
let maybe_aura_id = keys
.iter()
.find(|(k, _)| *k == account_id)
.map(|(_, a)| a);
if let Some(aura_id) = maybe_aura_id {
if !T::IsOnline::is_online_in_current_session(aura_id) {
staking::Module::<T>::on_offline_validator(account_id, slash_count);
}
}
}
);
}
Expand Down
9 changes: 8 additions & 1 deletion srml/aura/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#![cfg(test)]

use primitives::{
traits::IdentityLookup,
traits::{IdentityLookup, IsOnline},
testing::{Header, UintAuthorityId},
};
use srml_support::{impl_outer_origin, parameter_types};
Expand Down Expand Up @@ -67,6 +67,13 @@ impl timestamp::Trait for Test {
impl Trait for Test {
type HandleReport = ();
type AuthorityId = UintAuthorityId;
type IsOnline = Test;
}

impl IsOnline<UintAuthorityId> for Test {
fn is_online_in_current_session(authority_id: &UintAuthorityId) -> bool {
true
}
}

pub fn new_test_ext(authorities: Vec<u64>) -> runtime_io::TestExternalities<Blake2Hasher> {
Expand Down
16 changes: 16 additions & 0 deletions srml/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ decl_storage! {
/// will be used to determine the validator's session keys.
QueuedKeys get(queued_keys): Vec<(T::ValidatorId, T::Keys)>;

/// Returns the keys of the current session for all validators.
CurrentKeys get(current_keys): Vec<(T::ValidatorId, T::Keys)>;

}
add_extra_genesis {
config(keys): Vec<(T::ValidatorId, T::Keys)>;
Expand Down Expand Up @@ -439,6 +442,19 @@ impl<T: Trait> Module<T> {

// Tell everyone about the new session keys.
T::SessionHandler::on_new_session::<T::Keys>(changed, &session_keys, &queued_amalgamated);

<CurrentKeys<T>>::put(session_keys);
}

pub fn get_current_keys<Key: Decode + Default + TypedKey>() -> Vec<(T::ValidatorId, Key)> {
<CurrentKeys<T>>::get()
.into_iter()
.map(|(v, k)| {
let tk= k.get::<Key>(<Key as TypedKey>::KEY_TYPE)
.unwrap_or_default();
(v, tk)
})
.collect()
}

/// Disable the validator of index `i`.
Expand Down
9 changes: 9 additions & 0 deletions srml/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ use session::{historical::OnSessionEnding, SelectInitialValidators, SessionIndex
use primitives::Perbill;
use primitives::traits::{
Convert, Zero, One, StaticLookup, CheckedSub, CheckedShl, Saturating, Bounded,
TypedKey,
};
#[cfg(feature = "std")]
use primitives::{Serialize, Deserialize};
Expand Down Expand Up @@ -455,6 +456,8 @@ pub trait SessionInterface<AccountId>: system::Trait {
fn validators() -> Vec<AccountId>;
/// Prune historical session tries up to but not including the given index.
fn prune_historical_up_to(up_to: session::SessionIndex);
/// Get the keys of the current session.
fn current_keys<Key: Decode + Default + TypedKey>() -> Vec<(AccountId, Key)>;
}

impl<T: Trait> SessionInterface<<T as system::Trait>::AccountId> for T where
Expand All @@ -476,6 +479,12 @@ impl<T: Trait> SessionInterface<<T as system::Trait>::AccountId> for T where
<session::Module<T>>::validators()
}

fn current_keys<Key>() -> Vec<(<T as system::Trait>::AccountId, Key)>
where Key: Decode + Default + TypedKey
{
<session::Module<T>>::get_current_keys::<Key>()
}

fn prune_historical_up_to(up_to: session::SessionIndex) {
<session::historical::Module<T>>::prune_up_to(up_to);
}
Expand Down