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

Commit 595f18e

Browse files
authored
Add events for im_online (#3991)
* Add AllGood event for im_online * Another event just in case. * Bump runtime
1 parent c63610a commit 595f18e

File tree

6 files changed

+47
-58
lines changed

6 files changed

+47
-58
lines changed

core/network/src/protocol.rs

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use sr_primitives::traits::{
3535
};
3636
use message::{BlockAnnounce, BlockAttributes, Direction, FromBlock, Message, RequestId};
3737
use message::generic::{Message as GenericMessage, ConsensusMessage};
38-
use event::Event;
3938
use consensus_gossip::{ConsensusGossip, MessageRecipient as GossipMessageRecipient};
4039
use light_dispatch::{LightDispatch, LightDispatchNetwork, RequestData};
4140
use specialization::NetworkSpecialization;

core/network/src/protocol/specialization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub trait NetworkSpecialization<B: BlockT>: Send + Sync + 'static {
4343

4444
/// Called when a network-specific event arrives.
4545
#[deprecated(note = "This method is never called; please use `with_dht_event_tx` when building the service")]
46-
fn on_event(&mut self, event: Event) {}
46+
fn on_event(&mut self, _event: Event) {}
4747

4848
/// Called on abort.
4949
#[deprecated(note = "This method is never called; aborting corresponds to dropping the object")]

core/sr-primitives/src/generic/checked_extrinsic.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ pub struct CheckedExtrinsic<AccountId, Call, Extra> {
3636
pub function: Call,
3737
}
3838

39-
impl<AccountId, Call, Extra, Origin> traits::Applyable
40-
for
39+
impl<AccountId, Call, Extra, Origin> traits::Applyable for
4140
CheckedExtrinsic<AccountId, Call, Extra>
4241
where
4342
AccountId: Member + MaybeDisplay,

node/runtime/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
8181
// and set impl_version to equal spec_version. If only runtime
8282
// implementation changes and behavior does not, then leave spec_version as
8383
// is and increment impl_version.
84-
spec_version: 190,
84+
spec_version: 191,
8585
impl_version: 191,
8686
apis: RUNTIME_API_VERSIONS,
8787
};

srml/im-online/src/lib.rs

+29-38
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
//!
3838
//! ### Public Functions
3939
//!
40-
//! - `is_online_in_current_session` - True if the validator sent a heartbeat in the current session.
40+
//! - `is_online` - True if the validator sent a heartbeat in the current session.
4141
//!
4242
//! ## Usage
4343
//!
@@ -52,7 +52,7 @@
5252
//! pub struct Module<T: Trait> for enum Call where origin: T::Origin {
5353
//! pub fn is_online(origin, authority_index: u32) -> Result {
5454
//! let _sender = ensure_signed(origin)?;
55-
//! let _is_online = <im_online::Module<T>>::is_online_in_current_session(authority_index);
55+
//! let _is_online = <im_online::Module<T>>::is_online(authority_index);
5656
//! Ok(())
5757
//! }
5858
//! }
@@ -200,9 +200,14 @@ pub trait Trait: system::Trait + session::historical::Trait {
200200
decl_event!(
201201
pub enum Event<T> where
202202
<T as Trait>::AuthorityId,
203+
IdentificationTuple = IdentificationTuple<T>,
203204
{
204205
/// A new heartbeat was received from `AuthorityId`
205206
HeartbeatReceived(AuthorityId),
207+
/// At the end of the session, no offence was committed.
208+
AllGood,
209+
/// At the end of the session, at least once validator was found to be offline.
210+
SomeOffline(Vec<IdentificationTuple>),
206211
}
207212
);
208213

@@ -217,7 +222,7 @@ decl_storage! {
217222
/// For each session index, we keep a mapping of `AuthIndex`
218223
/// to `offchain::OpaqueNetworkState`.
219224
ReceivedHeartbeats get(fn received_heartbeats): double_map SessionIndex,
220-
blake2_256(AuthIndex) => Vec<u8>;
225+
blake2_256(AuthIndex) => Option<Vec<u8>>;
221226

222227
/// For each session index, we keep a mapping of `T::ValidatorId` to the
223228
/// number of blocks authored by the given authority.
@@ -249,8 +254,8 @@ decl_module! {
249254
&heartbeat.authority_index
250255
);
251256
let keys = Keys::<T>::get();
252-
let public = keys.get(heartbeat.authority_index as usize);
253-
if let (true, Some(public)) = (!exists, public) {
257+
let maybe_public = keys.get(heartbeat.authority_index as usize);
258+
if let (false, Some(public)) = (exists, maybe_public) {
254259
let signature_valid = heartbeat.using_encoded(|encoded_heartbeat| {
255260
public.verify(&encoded_heartbeat, &signature)
256261
});
@@ -300,7 +305,7 @@ impl<T: Trait> Module<T> {
300305
/// `authority_index` in the authorities series or if the authority has
301306
/// authored at least one block, during the current session. Otherwise
302307
/// `false`.
303-
pub fn is_online_in_current_session(authority_index: AuthIndex) -> bool {
308+
pub fn is_online(authority_index: AuthIndex) -> bool {
304309
let current_validators = <session::Module<T>>::validators();
305310

306311
if authority_index >= current_validators.len() as u32 {
@@ -309,10 +314,10 @@ impl<T: Trait> Module<T> {
309314

310315
let authority = &current_validators[authority_index as usize];
311316

312-
Self::is_online_in_current_session_aux(authority_index, authority)
317+
Self::is_online_aux(authority_index, authority)
313318
}
314319

315-
fn is_online_in_current_session_aux(authority_index: AuthIndex, authority: &T::ValidatorId) -> bool {
320+
fn is_online_aux(authority_index: AuthIndex, authority: &T::ValidatorId) -> bool {
316321
let current_session = <session::Module<T>>::current_index();
317322

318323
<ReceivedHeartbeats>::exists(&current_session, &authority_index) ||
@@ -507,46 +512,32 @@ impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
507512
}
508513

509514
fn on_before_session_ending() {
510-
let mut unresponsive = vec![];
511-
512-
let current_session = <session::Module<T>>::current_index();
513-
515+
let session_index = <session::Module<T>>::current_index();
514516
let keys = Keys::<T>::get();
515517
let current_validators = <session::Module<T>>::validators();
516518

517-
for (auth_idx, validator_id) in current_validators.into_iter().enumerate() {
518-
if !Self::is_online_in_current_session_aux(auth_idx as u32, &validator_id) {
519-
let full_identification = T::FullIdentificationOf::convert(validator_id.clone())
520-
.expect(
521-
"we got the validator_id from current_validators;
522-
current_validators is set of currently acting validators;
523-
the mapping between the validator id and its full identification should be valid;
524-
thus `FullIdentificationOf::convert` can't return `None`;
525-
qed",
526-
);
527-
528-
unresponsive.push((validator_id, full_identification));
529-
}
530-
}
519+
let offenders = current_validators.into_iter().enumerate()
520+
.filter(|(index, id)|
521+
!Self::is_online_aux(*index as u32, id)
522+
).filter_map(|(_, id)|
523+
T::FullIdentificationOf::convert(id.clone()).map(|full_id| (id, full_id))
524+
).collect::<Vec<IdentificationTuple<T>>>();
531525

532526
// Remove all received heartbeats and number of authored blocks from the
533527
// current session, they have already been processed and won't be needed
534528
// anymore.
535529
<ReceivedHeartbeats>::remove_prefix(&<session::Module<T>>::current_index());
536530
<AuthoredBlocks<T>>::remove_prefix(&<session::Module<T>>::current_index());
537531

538-
if unresponsive.is_empty() {
539-
return;
540-
}
541-
542-
let validator_set_count = keys.len() as u32;
543-
let offence = UnresponsivenessOffence {
544-
session_index: current_session,
545-
validator_set_count,
546-
offenders: unresponsive,
547-
};
532+
if offenders.is_empty() {
533+
Self::deposit_event(RawEvent::AllGood);
534+
} else {
535+
Self::deposit_event(RawEvent::SomeOffline(offenders.clone()));
548536

549-
T::ReportUnresponsiveness::report_offence(vec![], offence);
537+
let validator_set_count = keys.len() as u32;
538+
let offence = UnresponsivenessOffence { session_index, validator_set_count, offenders };
539+
T::ReportUnresponsiveness::report_offence(vec![], offence);
540+
}
550541
}
551542

552543
fn on_disabled(_i: usize) {
@@ -559,7 +550,7 @@ impl<T: Trait> support::unsigned::ValidateUnsigned for Module<T> {
559550

560551
fn validate_unsigned(call: &Self::Call) -> TransactionValidity {
561552
if let Call::heartbeat(heartbeat, signature) = call {
562-
if <Module<T>>::is_online_in_current_session(heartbeat.authority_index) {
553+
if <Module<T>>::is_online(heartbeat.authority_index) {
563554
// we already received a heartbeat for this authority
564555
return InvalidTransaction::Stale.into();
565556
}

srml/im-online/src/tests.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -134,25 +134,25 @@ fn should_mark_online_validator_when_heartbeat_is_received() {
134134
assert_eq!(Session::current_index(), 2);
135135
assert_eq!(Session::validators(), vec![1, 2, 3]);
136136

137-
assert!(!ImOnline::is_online_in_current_session(0));
138-
assert!(!ImOnline::is_online_in_current_session(1));
139-
assert!(!ImOnline::is_online_in_current_session(2));
137+
assert!(!ImOnline::is_online(0));
138+
assert!(!ImOnline::is_online(1));
139+
assert!(!ImOnline::is_online(2));
140140

141141
// when
142142
let _ = heartbeat(1, 2, 0, 1.into()).unwrap();
143143

144144
// then
145-
assert!(ImOnline::is_online_in_current_session(0));
146-
assert!(!ImOnline::is_online_in_current_session(1));
147-
assert!(!ImOnline::is_online_in_current_session(2));
145+
assert!(ImOnline::is_online(0));
146+
assert!(!ImOnline::is_online(1));
147+
assert!(!ImOnline::is_online(2));
148148

149149
// and when
150150
let _ = heartbeat(1, 2, 2, 3.into()).unwrap();
151151

152152
// then
153-
assert!(ImOnline::is_online_in_current_session(0));
154-
assert!(!ImOnline::is_online_in_current_session(1));
155-
assert!(ImOnline::is_online_in_current_session(2));
153+
assert!(ImOnline::is_online(0));
154+
assert!(!ImOnline::is_online(1));
155+
assert!(ImOnline::is_online(2));
156156
});
157157
}
158158

@@ -233,14 +233,14 @@ fn should_cleanup_received_heartbeats_on_session_end() {
233233
let _ = heartbeat(1, 2, 0, 1.into()).unwrap();
234234

235235
// the heartbeat is stored
236-
assert!(!ImOnline::received_heartbeats(&2, &0).is_empty());
236+
assert!(!ImOnline::received_heartbeats(&2, &0).is_none());
237237

238238
advance_session();
239239

240240
// after the session has ended we have already processed the heartbeat
241241
// message, so any messages received on the previous session should have
242242
// been pruned.
243-
assert!(ImOnline::received_heartbeats(&2, &0).is_empty());
243+
assert!(ImOnline::received_heartbeats(&2, &0).is_none());
244244
});
245245
}
246246

@@ -260,16 +260,16 @@ fn should_mark_online_validator_when_block_is_authored() {
260260
assert_eq!(Session::validators(), vec![1, 2, 3]);
261261

262262
for i in 0..3 {
263-
assert!(!ImOnline::is_online_in_current_session(i));
263+
assert!(!ImOnline::is_online(i));
264264
}
265265

266266
// when
267267
ImOnline::note_author(1);
268268
ImOnline::note_uncle(2, 0);
269269

270270
// then
271-
assert!(ImOnline::is_online_in_current_session(0));
272-
assert!(ImOnline::is_online_in_current_session(1));
273-
assert!(!ImOnline::is_online_in_current_session(2));
271+
assert!(ImOnline::is_online(0));
272+
assert!(ImOnline::is_online(1));
273+
assert!(!ImOnline::is_online(2));
274274
});
275275
}

0 commit comments

Comments
 (0)