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

Commit ce018b8

Browse files
authored
babe, grandpa: set longevity for equivocation report transactions (#8076)
* babe: set longevity for equivocation report transactions * grandpa: set longevity for equivocation report transaction * babe, grandpa: fix tests * node: add ReportLongevity to babe and grandpa modules * node: bump spec_version
1 parent 22441aa commit ce018b8

File tree

7 files changed

+70
-23
lines changed

7 files changed

+70
-23
lines changed

bin/node/runtime/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
112112
// and set impl_version to 0. If only runtime
113113
// implementation changes and behavior does not, then leave spec_version as
114114
// is and increment impl_version.
115-
spec_version: 263,
115+
spec_version: 264,
116116
impl_version: 0,
117117
apis: RUNTIME_API_VERSIONS,
118118
transaction_version: 2,
@@ -319,6 +319,8 @@ impl pallet_scheduler::Config for Runtime {
319319
parameter_types! {
320320
pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS;
321321
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
322+
pub const ReportLongevity: u64 =
323+
BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
322324
}
323325

324326
impl pallet_babe::Config for Runtime {
@@ -339,7 +341,7 @@ impl pallet_babe::Config for Runtime {
339341
)>>::IdentificationTuple;
340342

341343
type HandleEquivocation =
342-
pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
344+
pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
343345

344346
type WeightInfo = ();
345347
}
@@ -866,7 +868,7 @@ impl pallet_grandpa::Config for Runtime {
866868
)>>::IdentificationTuple;
867869

868870
type HandleEquivocation =
869-
pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
871+
pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
870872

871873
type WeightInfo = ();
872874
}

frame/babe/src/equivocation.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@
3535
//! definition.
3636
//!
3737
38-
use frame_support::{debug, traits::KeyOwnerProofSystem};
38+
use frame_support::{
39+
debug,
40+
traits::{Get, KeyOwnerProofSystem},
41+
};
3942
use sp_consensus_babe::{EquivocationProof, Slot};
4043
use sp_runtime::transaction_validity::{
4144
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
@@ -56,6 +59,10 @@ use crate::{Call, Module, Config};
5659
/// reporter), and also for creating and submitting equivocation report
5760
/// extrinsics (useful only in offchain context).
5861
pub trait HandleEquivocation<T: Config> {
62+
/// The longevity, in blocks, that the equivocation report is valid for. When using the staking
63+
/// pallet this should be equal to the bonding duration (in blocks, not eras).
64+
type ReportLongevity: Get<u64>;
65+
5966
/// Report an offence proved by the given reporters.
6067
fn report_offence(
6168
reporters: Vec<T::AccountId>,
@@ -76,6 +83,8 @@ pub trait HandleEquivocation<T: Config> {
7683
}
7784

7885
impl<T: Config> HandleEquivocation<T> for () {
86+
type ReportLongevity = ();
87+
7988
fn report_offence(
8089
_reporters: Vec<T::AccountId>,
8190
_offence: BabeEquivocationOffence<T::KeyOwnerIdentification>,
@@ -103,19 +112,19 @@ impl<T: Config> HandleEquivocation<T> for () {
103112
/// using existing subsystems that are part of frame (type bounds described
104113
/// below) and will dispatch to them directly, it's only purpose is to wire all
105114
/// subsystems together.
106-
pub struct EquivocationHandler<I, R> {
107-
_phantom: sp_std::marker::PhantomData<(I, R)>,
115+
pub struct EquivocationHandler<I, R, L> {
116+
_phantom: sp_std::marker::PhantomData<(I, R, L)>,
108117
}
109118

110-
impl<I, R> Default for EquivocationHandler<I, R> {
119+
impl<I, R, L> Default for EquivocationHandler<I, R, L> {
111120
fn default() -> Self {
112121
Self {
113122
_phantom: Default::default(),
114123
}
115124
}
116125
}
117126

118-
impl<T, R> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R>
127+
impl<T, R, L> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R, L>
119128
where
120129
// We use the authorship pallet to fetch the current block author and use
121130
// `offchain::SendTransactionTypes` for unsigned extrinsic creation and
@@ -128,7 +137,12 @@ where
128137
T::KeyOwnerIdentification,
129138
BabeEquivocationOffence<T::KeyOwnerIdentification>,
130139
>,
140+
// The longevity (in blocks) that the equivocation report is valid for. When using the staking
141+
// pallet this should be the bonding duration.
142+
L: Get<u64>,
131143
{
144+
type ReportLongevity = L;
145+
132146
fn report_offence(
133147
reporters: Vec<T::AccountId>,
134148
offence: BabeEquivocationOffence<T::KeyOwnerIdentification>,
@@ -184,6 +198,8 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
184198
// check report staleness
185199
is_known_offence::<T>(equivocation_proof, key_owner_proof)?;
186200

201+
let longevity = <T::HandleEquivocation as HandleEquivocation<T>>::ReportLongevity::get();
202+
187203
ValidTransaction::with_tag_prefix("BabeEquivocation")
188204
// We assign the maximum priority for any equivocation report.
189205
.priority(TransactionPriority::max_value())
@@ -192,6 +208,7 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
192208
equivocation_proof.offender.clone(),
193209
*equivocation_proof.slot,
194210
))
211+
.longevity(longevity)
195212
// We don't propagate this. This can never be included on a remote node.
196213
.propagate(false)
197214
.build()

frame/babe/src/mock.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ frame_support::construct_runtime!(
6363

6464
parameter_types! {
6565
pub const BlockHashCount: u64 = 250;
66-
pub const EpochDuration: u64 = 3;
67-
pub const ExpectedBlockTime: u64 = 1;
6866
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16);
6967
pub BlockWeights: frame_system::limits::BlockWeights =
7068
frame_system::limits::BlockWeights::simple_max(1024);
@@ -222,6 +220,13 @@ impl pallet_offences::Config for Test {
222220
type WeightSoftLimit = OffencesWeightSoftLimit;
223221
}
224222

223+
parameter_types! {
224+
pub const EpochDuration: u64 = 3;
225+
pub const ExpectedBlockTime: u64 = 1;
226+
pub const ReportLongevity: u64 =
227+
BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
228+
}
229+
225230
impl Config for Test {
226231
type EpochDuration = EpochDuration;
227232
type ExpectedBlockTime = ExpectedBlockTime;
@@ -237,7 +242,9 @@ impl Config for Test {
237242
AuthorityId,
238243
)>>::IdentificationTuple;
239244

240-
type HandleEquivocation = super::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
245+
type HandleEquivocation =
246+
super::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
247+
241248
type WeightInfo = ();
242249
}
243250

frame/babe/src/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,8 @@ fn report_equivocation_invalid_equivocation_proof() {
611611
#[test]
612612
fn report_equivocation_validate_unsigned_prevents_duplicates() {
613613
use sp_runtime::transaction_validity::{
614-
InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource,
615-
TransactionValidity, ValidTransaction,
614+
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
615+
ValidTransaction,
616616
};
617617

618618
let (pairs, mut ext) = new_test_ext_with_pairs(3);
@@ -664,7 +664,7 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() {
664664
priority: TransactionPriority::max_value(),
665665
requires: vec![],
666666
provides: vec![("BabeEquivocation", tx_tag).encode()],
667-
longevity: TransactionLongevity::max_value(),
667+
longevity: ReportLongevity::get(),
668668
propagate: false,
669669
})
670670
);

frame/grandpa/src/equivocation.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@
4040
use sp_std::prelude::*;
4141

4242
use codec::{self as codec, Decode, Encode};
43-
use frame_support::{debug, traits::KeyOwnerProofSystem};
43+
use frame_support::{
44+
debug,
45+
traits::{Get, KeyOwnerProofSystem},
46+
};
4447
use sp_finality_grandpa::{EquivocationProof, RoundNumber, SetId};
4548
use sp_runtime::{
4649
transaction_validity::{
@@ -64,6 +67,10 @@ pub trait HandleEquivocation<T: Config> {
6467
/// The offence type used for reporting offences on valid equivocation reports.
6568
type Offence: GrandpaOffence<T::KeyOwnerIdentification>;
6669

70+
/// The longevity, in blocks, that the equivocation report is valid for. When using the staking
71+
/// pallet this should be equal to the bonding duration (in blocks, not eras).
72+
type ReportLongevity: Get<u64>;
73+
6774
/// Report an offence proved by the given reporters.
6875
fn report_offence(
6976
reporters: Vec<T::AccountId>,
@@ -88,6 +95,7 @@ pub trait HandleEquivocation<T: Config> {
8895

8996
impl<T: Config> HandleEquivocation<T> for () {
9097
type Offence = GrandpaEquivocationOffence<T::KeyOwnerIdentification>;
98+
type ReportLongevity = ();
9199

92100
fn report_offence(
93101
_reporters: Vec<T::AccountId>,
@@ -119,19 +127,19 @@ impl<T: Config> HandleEquivocation<T> for () {
119127
/// using existing subsystems that are part of frame (type bounds described
120128
/// below) and will dispatch to them directly, it's only purpose is to wire all
121129
/// subsystems together.
122-
pub struct EquivocationHandler<I, R, O = GrandpaEquivocationOffence<I>> {
123-
_phantom: sp_std::marker::PhantomData<(I, R, O)>,
130+
pub struct EquivocationHandler<I, R, L, O = GrandpaEquivocationOffence<I>> {
131+
_phantom: sp_std::marker::PhantomData<(I, R, L, O)>,
124132
}
125133

126-
impl<I, R, O> Default for EquivocationHandler<I, R, O> {
134+
impl<I, R, L, O> Default for EquivocationHandler<I, R, L, O> {
127135
fn default() -> Self {
128136
Self {
129137
_phantom: Default::default(),
130138
}
131139
}
132140
}
133141

134-
impl<T, R, O> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R, O>
142+
impl<T, R, L, O> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R, L, O>
135143
where
136144
// We use the authorship pallet to fetch the current block author and use
137145
// `offchain::SendTransactionTypes` for unsigned extrinsic creation and
@@ -140,10 +148,14 @@ where
140148
// A system for reporting offences after valid equivocation reports are
141149
// processed.
142150
R: ReportOffence<T::AccountId, T::KeyOwnerIdentification, O>,
151+
// The longevity (in blocks) that the equivocation report is valid for. When using the staking
152+
// pallet this should be the bonding duration.
153+
L: Get<u64>,
143154
// The offence type that should be used when reporting.
144155
O: GrandpaOffence<T::KeyOwnerIdentification>,
145156
{
146157
type Offence = O;
158+
type ReportLongevity = L;
147159

148160
fn report_offence(reporters: Vec<T::AccountId>, offence: O) -> Result<(), OffenceError> {
149161
R::report_offence(reporters, offence)
@@ -207,6 +219,8 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
207219
// check report staleness
208220
is_known_offence::<T>(equivocation_proof, key_owner_proof)?;
209221

222+
let longevity = <T::HandleEquivocation as HandleEquivocation<T>>::ReportLongevity::get();
223+
210224
ValidTransaction::with_tag_prefix("GrandpaEquivocation")
211225
// We assign the maximum priority for any equivocation report.
212226
.priority(TransactionPriority::max_value())
@@ -216,6 +230,7 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
216230
equivocation_proof.set_id(),
217231
equivocation_proof.round(),
218232
))
233+
.longevity(longevity)
219234
// We don't propagate this. This can never be included on a remote node.
220235
.propagate(false)
221236
.build()

frame/grandpa/src/mock.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,11 @@ impl pallet_offences::Config for Test {
226226
type WeightSoftLimit = OffencesWeightSoftLimit;
227227
}
228228

229+
parameter_types! {
230+
pub const ReportLongevity: u64 =
231+
BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * Period::get();
232+
}
233+
229234
impl Config for Test {
230235
type Event = Event;
231236
type Call = Call;
@@ -240,7 +245,8 @@ impl Config for Test {
240245
AuthorityId,
241246
)>>::IdentificationTuple;
242247

243-
type HandleEquivocation = super::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
248+
type HandleEquivocation =
249+
super::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
244250

245251
type WeightInfo = ();
246252
}

frame/grandpa/src/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,8 @@ fn report_equivocation_invalid_equivocation_proof() {
706706
#[test]
707707
fn report_equivocation_validate_unsigned_prevents_duplicates() {
708708
use sp_runtime::transaction_validity::{
709-
InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource,
710-
TransactionValidity, ValidTransaction,
709+
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
710+
ValidTransaction,
711711
};
712712

713713
let authorities = test_authorities();
@@ -762,7 +762,7 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() {
762762
priority: TransactionPriority::max_value(),
763763
requires: vec![],
764764
provides: vec![("GrandpaEquivocation", tx_tag).encode()],
765-
longevity: TransactionLongevity::max_value(),
765+
longevity: ReportLongevity::get(),
766766
propagate: false,
767767
})
768768
);

0 commit comments

Comments
 (0)