Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 5 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) {
Comment thread
cmichi marked this conversation as resolved.
Outdated
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