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

Commit 675f6b0

Browse files
authored
Offence reporting returns a result (#5082)
* Offence reporting returns a result * Bump spec_version * Use unwrap instead of assertions * Fix more review grumbles
1 parent 3beb09d commit 675f6b0

File tree

7 files changed

+51
-22
lines changed

7 files changed

+51
-22
lines changed

bin/node/runtime/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
8282
// and set impl_version to 0. If only runtime
8383
// implementation changes and behavior does not, then leave spec_version as
8484
// is and increment impl_version.
85-
spec_version: 226,
85+
spec_version: 227,
8686
impl_version: 0,
8787
apis: RUNTIME_API_VERSIONS,
8888
};

frame/im-online/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,9 @@ impl<T: Trait> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
608608

609609
let validator_set_count = keys.len() as u32;
610610
let offence = UnresponsivenessOffence { session_index, validator_set_count, offenders };
611-
T::ReportUnresponsiveness::report_offence(vec![], offence);
611+
if let Err(e) = T::ReportUnresponsiveness::report_offence(vec![], offence) {
612+
sp_runtime::print(e);
613+
}
612614
}
613615
}
614616

frame/im-online/src/mock.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::cell::RefCell;
2222

2323
use crate::{Module, Trait};
2424
use sp_runtime::Perbill;
25-
use sp_staking::{SessionIndex, offence::ReportOffence};
25+
use sp_staking::{SessionIndex, offence::{ReportOffence, OffenceError}};
2626
use sp_runtime::testing::{Header, UintAuthorityId, TestXt};
2727
use sp_runtime::traits::{IdentityLookup, BlakeTwo256, ConvertInto};
2828
use sp_core::H256;
@@ -77,8 +77,9 @@ thread_local! {
7777
/// A mock offence report handler.
7878
pub struct OffenceHandler;
7979
impl ReportOffence<u64, IdentificationTuple, Offence> for OffenceHandler {
80-
fn report_offence(reporters: Vec<u64>, offence: Offence) {
80+
fn report_offence(reporters: Vec<u64>, offence: Offence) -> Result<(), OffenceError> {
8181
OFFENCES.with(|l| l.borrow_mut().push((reporters, offence)));
82+
Ok(())
8283
}
8384
}
8485

frame/offences/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use frame_support::{
3030
};
3131
use sp_runtime::traits::Hash;
3232
use sp_staking::{
33-
offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails},
33+
offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails, OffenceError},
3434
};
3535
use codec::{Encode, Decode};
3636
use frame_system as system;
@@ -90,7 +90,7 @@ impl<T: Trait, O: Offence<T::IdentificationTuple>>
9090
where
9191
T::IdentificationTuple: Clone,
9292
{
93-
fn report_offence(reporters: Vec<T::AccountId>, offence: O) {
93+
fn report_offence(reporters: Vec<T::AccountId>, offence: O) -> Result<(), OffenceError> {
9494
let offenders = offence.offenders();
9595
let time_slot = offence.time_slot();
9696
let validator_set_count = offence.validator_set_count();
@@ -104,7 +104,7 @@ where
104104
) {
105105
Some(triage) => triage,
106106
// The report contained only duplicates, so there is no need to slash again.
107-
None => return,
107+
None => return Err(OffenceError::DuplicateReport),
108108
};
109109

110110
// Deposit the event.
@@ -123,6 +123,8 @@ where
123123
&slash_perbill,
124124
offence.session_index(),
125125
);
126+
127+
Ok(())
126128
}
127129
}
128130

frame/offences/src/tests.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn should_report_an_authority_and_trigger_on_offence() {
4040
};
4141

4242
// when
43-
Offences::report_offence(vec![], offence);
43+
Offences::report_offence(vec![], offence).unwrap();
4444

4545
// then
4646
with_on_offence_fractions(|f| {
@@ -61,15 +61,15 @@ fn should_not_report_the_same_authority_twice_in_the_same_slot() {
6161
time_slot,
6262
offenders: vec![5],
6363
};
64-
Offences::report_offence(vec![], offence.clone());
64+
Offences::report_offence(vec![], offence.clone()).unwrap();
6565
with_on_offence_fractions(|f| {
6666
assert_eq!(f.clone(), vec![Perbill::from_percent(25)]);
6767
f.clear();
6868
});
6969

7070
// when
7171
// report for the second time
72-
Offences::report_offence(vec![], offence);
72+
assert_eq!(Offences::report_offence(vec![], offence), Err(OffenceError::DuplicateReport));
7373

7474
// then
7575
with_on_offence_fractions(|f| {
@@ -91,7 +91,7 @@ fn should_report_in_different_time_slot() {
9191
time_slot,
9292
offenders: vec![5],
9393
};
94-
Offences::report_offence(vec![], offence.clone());
94+
Offences::report_offence(vec![], offence.clone()).unwrap();
9595
with_on_offence_fractions(|f| {
9696
assert_eq!(f.clone(), vec![Perbill::from_percent(25)]);
9797
f.clear();
@@ -100,7 +100,7 @@ fn should_report_in_different_time_slot() {
100100
// when
101101
// report for the second time
102102
offence.time_slot += 1;
103-
Offences::report_offence(vec![], offence);
103+
Offences::report_offence(vec![], offence).unwrap();
104104

105105
// then
106106
with_on_offence_fractions(|f| {
@@ -123,7 +123,7 @@ fn should_deposit_event() {
123123
};
124124

125125
// when
126-
Offences::report_offence(vec![], offence);
126+
Offences::report_offence(vec![], offence).unwrap();
127127

128128
// then
129129
assert_eq!(
@@ -149,15 +149,15 @@ fn doesnt_deposit_event_for_dups() {
149149
time_slot,
150150
offenders: vec![5],
151151
};
152-
Offences::report_offence(vec![], offence.clone());
152+
Offences::report_offence(vec![], offence.clone()).unwrap();
153153
with_on_offence_fractions(|f| {
154154
assert_eq!(f.clone(), vec![Perbill::from_percent(25)]);
155155
f.clear();
156156
});
157157

158158
// when
159159
// report for the second time
160-
Offences::report_offence(vec![], offence);
160+
assert_eq!(Offences::report_offence(vec![], offence), Err(OffenceError::DuplicateReport));
161161

162162
// then
163163
// there is only one event.
@@ -191,15 +191,15 @@ fn should_properly_count_offences() {
191191
time_slot,
192192
offenders: vec![4],
193193
};
194-
Offences::report_offence(vec![], offence1);
194+
Offences::report_offence(vec![], offence1).unwrap();
195195
with_on_offence_fractions(|f| {
196196
assert_eq!(f.clone(), vec![Perbill::from_percent(25)]);
197197
f.clear();
198198
});
199199

200200
// when
201201
// report for the second time
202-
Offences::report_offence(vec![], offence2);
202+
Offences::report_offence(vec![], offence2).unwrap();
203203

204204
// then
205205
// the 1st authority should have count 2 and the 2nd one should be reported only once.

frame/staking/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ use sp_runtime::{
276276
};
277277
use sp_staking::{
278278
SessionIndex,
279-
offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence},
279+
offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence, OffenceError},
280280
};
281281
#[cfg(feature = "std")]
282282
use sp_runtime::{Serialize, Deserialize};
@@ -1828,7 +1828,7 @@ impl<T, Reporter, Offender, R, O> ReportOffence<Reporter, Offender, O>
18281828
R: ReportOffence<Reporter, Offender, O>,
18291829
O: Offence<Offender>,
18301830
{
1831-
fn report_offence(reporters: Vec<Reporter>, offence: O) {
1831+
fn report_offence(reporters: Vec<Reporter>, offence: O) -> Result<(), OffenceError> {
18321832
<Module<T>>::ensure_storage_upgraded();
18331833

18341834
// disallow any slashing from before the current bonding period.
@@ -1840,7 +1840,8 @@ impl<T, Reporter, Offender, R, O> ReportOffence<Reporter, Offender, O>
18401840
} else {
18411841
<Module<T>>::deposit_event(
18421842
RawEvent::OldSlashingReportDiscarded(offence_session)
1843-
)
1843+
);
1844+
Ok(())
18441845
}
18451846
}
18461847
}

primitives/staking/src/offence.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,37 @@ pub trait Offence<Offender> {
9191
) -> Perbill;
9292
}
9393

94+
/// Errors that may happen on offence reports.
95+
#[derive(PartialEq, sp_runtime::RuntimeDebug)]
96+
pub enum OffenceError {
97+
/// The report has already been sumbmitted.
98+
DuplicateReport,
99+
100+
/// Other error has happened.
101+
Other(u8),
102+
}
103+
104+
impl sp_runtime::traits::Printable for OffenceError {
105+
fn print(&self) {
106+
"OffenceError".print();
107+
match self {
108+
Self::DuplicateReport => "DuplicateReport".print(),
109+
Self::Other(e) => {
110+
"Other".print();
111+
e.print();
112+
}
113+
}
114+
}
115+
}
116+
94117
/// A trait for decoupling offence reporters from the actual handling of offence reports.
95118
pub trait ReportOffence<Reporter, Offender, O: Offence<Offender>> {
96119
/// Report an `offence` and reward given `reporters`.
97-
fn report_offence(reporters: Vec<Reporter>, offence: O);
120+
fn report_offence(reporters: Vec<Reporter>, offence: O) -> Result<(), OffenceError>;
98121
}
99122

100123
impl<Reporter, Offender, O: Offence<Offender>> ReportOffence<Reporter, Offender, O> for () {
101-
fn report_offence(_reporters: Vec<Reporter>, _offence: O) {}
124+
fn report_offence(_reporters: Vec<Reporter>, _offence: O) -> Result<(), OffenceError> { Ok(()) }
102125
}
103126

104127
/// A trait to take action on an offence.

0 commit comments

Comments
 (0)