diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 4b0998c122..58c98e529c 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -112,7 +112,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 263, + spec_version: 264, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, @@ -319,6 +319,8 @@ impl pallet_scheduler::Config for Runtime { parameter_types! { pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; + pub const ReportLongevity: u64 = + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); } impl pallet_babe::Config for Runtime { @@ -339,7 +341,7 @@ impl pallet_babe::Config for Runtime { )>>::IdentificationTuple; type HandleEquivocation = - pallet_babe::EquivocationHandler; + pallet_babe::EquivocationHandler; type WeightInfo = (); } @@ -866,7 +868,7 @@ impl pallet_grandpa::Config for Runtime { )>>::IdentificationTuple; type HandleEquivocation = - pallet_grandpa::EquivocationHandler; + pallet_grandpa::EquivocationHandler; type WeightInfo = (); } diff --git a/substrate/frame/babe/src/equivocation.rs b/substrate/frame/babe/src/equivocation.rs index a0a1ff4fa0..b7275d0473 100644 --- a/substrate/frame/babe/src/equivocation.rs +++ b/substrate/frame/babe/src/equivocation.rs @@ -35,7 +35,10 @@ //! definition. //! -use frame_support::{debug, traits::KeyOwnerProofSystem}; +use frame_support::{ + debug, + traits::{Get, KeyOwnerProofSystem}, +}; use sp_consensus_babe::{EquivocationProof, Slot}; use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, @@ -56,6 +59,10 @@ use crate::{Call, Module, Config}; /// reporter), and also for creating and submitting equivocation report /// extrinsics (useful only in offchain context). pub trait HandleEquivocation { + /// The longevity, in blocks, that the equivocation report is valid for. When using the staking + /// pallet this should be equal to the bonding duration (in blocks, not eras). + type ReportLongevity: Get; + /// Report an offence proved by the given reporters. fn report_offence( reporters: Vec, @@ -76,6 +83,8 @@ pub trait HandleEquivocation { } impl HandleEquivocation for () { + type ReportLongevity = (); + fn report_offence( _reporters: Vec, _offence: BabeEquivocationOffence, @@ -103,11 +112,11 @@ impl HandleEquivocation for () { /// using existing subsystems that are part of frame (type bounds described /// below) and will dispatch to them directly, it's only purpose is to wire all /// subsystems together. -pub struct EquivocationHandler { - _phantom: sp_std::marker::PhantomData<(I, R)>, +pub struct EquivocationHandler { + _phantom: sp_std::marker::PhantomData<(I, R, L)>, } -impl Default for EquivocationHandler { +impl Default for EquivocationHandler { fn default() -> Self { Self { _phantom: Default::default(), @@ -115,7 +124,7 @@ impl Default for EquivocationHandler { } } -impl HandleEquivocation for EquivocationHandler +impl HandleEquivocation for EquivocationHandler where // We use the authorship pallet to fetch the current block author and use // `offchain::SendTransactionTypes` for unsigned extrinsic creation and @@ -128,7 +137,12 @@ where T::KeyOwnerIdentification, BabeEquivocationOffence, >, + // The longevity (in blocks) that the equivocation report is valid for. When using the staking + // pallet this should be the bonding duration. + L: Get, { + type ReportLongevity = L; + fn report_offence( reporters: Vec, offence: BabeEquivocationOffence, @@ -184,6 +198,8 @@ impl frame_support::unsigned::ValidateUnsigned for Module { // check report staleness is_known_offence::(equivocation_proof, key_owner_proof)?; + let longevity = >::ReportLongevity::get(); + ValidTransaction::with_tag_prefix("BabeEquivocation") // We assign the maximum priority for any equivocation report. .priority(TransactionPriority::max_value()) @@ -192,6 +208,7 @@ impl frame_support::unsigned::ValidateUnsigned for Module { equivocation_proof.offender.clone(), *equivocation_proof.slot, )) + .longevity(longevity) // We don't propagate this. This can never be included on a remote node. .propagate(false) .build() diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index 75d4703b0d..e3d2eb19ef 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -63,8 +63,6 @@ frame_support::construct_runtime!( parameter_types! { pub const BlockHashCount: u64 = 250; - pub const EpochDuration: u64 = 3; - pub const ExpectedBlockTime: u64 = 1; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights::simple_max(1024); @@ -222,6 +220,13 @@ impl pallet_offences::Config for Test { type WeightSoftLimit = OffencesWeightSoftLimit; } +parameter_types! { + pub const EpochDuration: u64 = 3; + pub const ExpectedBlockTime: u64 = 1; + pub const ReportLongevity: u64 = + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); +} + impl Config for Test { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; @@ -237,7 +242,9 @@ impl Config for Test { AuthorityId, )>>::IdentificationTuple; - type HandleEquivocation = super::EquivocationHandler; + type HandleEquivocation = + super::EquivocationHandler; + type WeightInfo = (); } diff --git a/substrate/frame/babe/src/tests.rs b/substrate/frame/babe/src/tests.rs index e4649d253c..8576389af3 100644 --- a/substrate/frame/babe/src/tests.rs +++ b/substrate/frame/babe/src/tests.rs @@ -611,8 +611,8 @@ fn report_equivocation_invalid_equivocation_proof() { #[test] fn report_equivocation_validate_unsigned_prevents_duplicates() { use sp_runtime::transaction_validity::{ - InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, - TransactionValidity, ValidTransaction, + InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, + ValidTransaction, }; let (pairs, mut ext) = new_test_ext_with_pairs(3); @@ -664,7 +664,7 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() { priority: TransactionPriority::max_value(), requires: vec![], provides: vec![("BabeEquivocation", tx_tag).encode()], - longevity: TransactionLongevity::max_value(), + longevity: ReportLongevity::get(), propagate: false, }) ); diff --git a/substrate/frame/grandpa/src/equivocation.rs b/substrate/frame/grandpa/src/equivocation.rs index bf05868481..b8bff59d39 100644 --- a/substrate/frame/grandpa/src/equivocation.rs +++ b/substrate/frame/grandpa/src/equivocation.rs @@ -40,7 +40,10 @@ use sp_std::prelude::*; use codec::{self as codec, Decode, Encode}; -use frame_support::{debug, traits::KeyOwnerProofSystem}; +use frame_support::{ + debug, + traits::{Get, KeyOwnerProofSystem}, +}; use sp_finality_grandpa::{EquivocationProof, RoundNumber, SetId}; use sp_runtime::{ transaction_validity::{ @@ -64,6 +67,10 @@ pub trait HandleEquivocation { /// The offence type used for reporting offences on valid equivocation reports. type Offence: GrandpaOffence; + /// The longevity, in blocks, that the equivocation report is valid for. When using the staking + /// pallet this should be equal to the bonding duration (in blocks, not eras). + type ReportLongevity: Get; + /// Report an offence proved by the given reporters. fn report_offence( reporters: Vec, @@ -88,6 +95,7 @@ pub trait HandleEquivocation { impl HandleEquivocation for () { type Offence = GrandpaEquivocationOffence; + type ReportLongevity = (); fn report_offence( _reporters: Vec, @@ -119,11 +127,11 @@ impl HandleEquivocation for () { /// using existing subsystems that are part of frame (type bounds described /// below) and will dispatch to them directly, it's only purpose is to wire all /// subsystems together. -pub struct EquivocationHandler> { - _phantom: sp_std::marker::PhantomData<(I, R, O)>, +pub struct EquivocationHandler> { + _phantom: sp_std::marker::PhantomData<(I, R, L, O)>, } -impl Default for EquivocationHandler { +impl Default for EquivocationHandler { fn default() -> Self { Self { _phantom: Default::default(), @@ -131,7 +139,7 @@ impl Default for EquivocationHandler { } } -impl HandleEquivocation for EquivocationHandler +impl HandleEquivocation for EquivocationHandler where // We use the authorship pallet to fetch the current block author and use // `offchain::SendTransactionTypes` for unsigned extrinsic creation and @@ -140,10 +148,14 @@ where // A system for reporting offences after valid equivocation reports are // processed. R: ReportOffence, + // The longevity (in blocks) that the equivocation report is valid for. When using the staking + // pallet this should be the bonding duration. + L: Get, // The offence type that should be used when reporting. O: GrandpaOffence, { type Offence = O; + type ReportLongevity = L; fn report_offence(reporters: Vec, offence: O) -> Result<(), OffenceError> { R::report_offence(reporters, offence) @@ -207,6 +219,8 @@ impl frame_support::unsigned::ValidateUnsigned for Module { // check report staleness is_known_offence::(equivocation_proof, key_owner_proof)?; + let longevity = >::ReportLongevity::get(); + ValidTransaction::with_tag_prefix("GrandpaEquivocation") // We assign the maximum priority for any equivocation report. .priority(TransactionPriority::max_value()) @@ -216,6 +230,7 @@ impl frame_support::unsigned::ValidateUnsigned for Module { equivocation_proof.set_id(), equivocation_proof.round(), )) + .longevity(longevity) // We don't propagate this. This can never be included on a remote node. .propagate(false) .build() diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index 4aeaa5a237..e8703dba50 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -226,6 +226,11 @@ impl pallet_offences::Config for Test { type WeightSoftLimit = OffencesWeightSoftLimit; } +parameter_types! { + pub const ReportLongevity: u64 = + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * Period::get(); +} + impl Config for Test { type Event = Event; type Call = Call; @@ -240,7 +245,8 @@ impl Config for Test { AuthorityId, )>>::IdentificationTuple; - type HandleEquivocation = super::EquivocationHandler; + type HandleEquivocation = + super::EquivocationHandler; type WeightInfo = (); } diff --git a/substrate/frame/grandpa/src/tests.rs b/substrate/frame/grandpa/src/tests.rs index cd5e0c3563..50462d3347 100644 --- a/substrate/frame/grandpa/src/tests.rs +++ b/substrate/frame/grandpa/src/tests.rs @@ -706,8 +706,8 @@ fn report_equivocation_invalid_equivocation_proof() { #[test] fn report_equivocation_validate_unsigned_prevents_duplicates() { use sp_runtime::transaction_validity::{ - InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, - TransactionValidity, ValidTransaction, + InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, + ValidTransaction, }; let authorities = test_authorities(); @@ -762,7 +762,7 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() { priority: TransactionPriority::max_value(), requires: vec![], provides: vec![("GrandpaEquivocation", tx_tag).encode()], - longevity: TransactionLongevity::max_value(), + longevity: ReportLongevity::get(), propagate: false, }) );