mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 21:41:12 +00:00
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
This commit is contained in:
@@ -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<Self::KeyOwnerIdentification, Offences>;
|
||||
pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
|
||||
|
||||
type WeightInfo = ();
|
||||
}
|
||||
@@ -866,7 +868,7 @@ impl pallet_grandpa::Config for Runtime {
|
||||
)>>::IdentificationTuple;
|
||||
|
||||
type HandleEquivocation =
|
||||
pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
|
||||
pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
|
||||
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
@@ -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<T: Config> {
|
||||
/// 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<u64>;
|
||||
|
||||
/// Report an offence proved by the given reporters.
|
||||
fn report_offence(
|
||||
reporters: Vec<T::AccountId>,
|
||||
@@ -76,6 +83,8 @@ pub trait HandleEquivocation<T: Config> {
|
||||
}
|
||||
|
||||
impl<T: Config> HandleEquivocation<T> for () {
|
||||
type ReportLongevity = ();
|
||||
|
||||
fn report_offence(
|
||||
_reporters: Vec<T::AccountId>,
|
||||
_offence: BabeEquivocationOffence<T::KeyOwnerIdentification>,
|
||||
@@ -103,11 +112,11 @@ impl<T: Config> HandleEquivocation<T> 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<I, R> {
|
||||
_phantom: sp_std::marker::PhantomData<(I, R)>,
|
||||
pub struct EquivocationHandler<I, R, L> {
|
||||
_phantom: sp_std::marker::PhantomData<(I, R, L)>,
|
||||
}
|
||||
|
||||
impl<I, R> Default for EquivocationHandler<I, R> {
|
||||
impl<I, R, L> Default for EquivocationHandler<I, R, L> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
_phantom: Default::default(),
|
||||
@@ -115,7 +124,7 @@ impl<I, R> Default for EquivocationHandler<I, R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R>
|
||||
impl<T, R, L> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R, L>
|
||||
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<T::KeyOwnerIdentification>,
|
||||
>,
|
||||
// The longevity (in blocks) that the equivocation report is valid for. When using the staking
|
||||
// pallet this should be the bonding duration.
|
||||
L: Get<u64>,
|
||||
{
|
||||
type ReportLongevity = L;
|
||||
|
||||
fn report_offence(
|
||||
reporters: Vec<T::AccountId>,
|
||||
offence: BabeEquivocationOffence<T::KeyOwnerIdentification>,
|
||||
@@ -184,6 +198,8 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
// check report staleness
|
||||
is_known_offence::<T>(equivocation_proof, key_owner_proof)?;
|
||||
|
||||
let longevity = <T::HandleEquivocation as HandleEquivocation<T>>::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<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
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()
|
||||
|
||||
@@ -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<Self::KeyOwnerIdentification, Offences>;
|
||||
type HandleEquivocation =
|
||||
super::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
|
||||
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -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<T: Config> {
|
||||
/// The offence type used for reporting offences on valid equivocation reports.
|
||||
type Offence: GrandpaOffence<T::KeyOwnerIdentification>;
|
||||
|
||||
/// 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<u64>;
|
||||
|
||||
/// Report an offence proved by the given reporters.
|
||||
fn report_offence(
|
||||
reporters: Vec<T::AccountId>,
|
||||
@@ -88,6 +95,7 @@ pub trait HandleEquivocation<T: Config> {
|
||||
|
||||
impl<T: Config> HandleEquivocation<T> for () {
|
||||
type Offence = GrandpaEquivocationOffence<T::KeyOwnerIdentification>;
|
||||
type ReportLongevity = ();
|
||||
|
||||
fn report_offence(
|
||||
_reporters: Vec<T::AccountId>,
|
||||
@@ -119,11 +127,11 @@ impl<T: Config> HandleEquivocation<T> 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<I, R, O = GrandpaEquivocationOffence<I>> {
|
||||
_phantom: sp_std::marker::PhantomData<(I, R, O)>,
|
||||
pub struct EquivocationHandler<I, R, L, O = GrandpaEquivocationOffence<I>> {
|
||||
_phantom: sp_std::marker::PhantomData<(I, R, L, O)>,
|
||||
}
|
||||
|
||||
impl<I, R, O> Default for EquivocationHandler<I, R, O> {
|
||||
impl<I, R, L, O> Default for EquivocationHandler<I, R, L, O> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
_phantom: Default::default(),
|
||||
@@ -131,7 +139,7 @@ impl<I, R, O> Default for EquivocationHandler<I, R, O> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R, O> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R, O>
|
||||
impl<T, R, L, O> HandleEquivocation<T> for EquivocationHandler<T::KeyOwnerIdentification, R, L, O>
|
||||
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<T::AccountId, T::KeyOwnerIdentification, O>,
|
||||
// The longevity (in blocks) that the equivocation report is valid for. When using the staking
|
||||
// pallet this should be the bonding duration.
|
||||
L: Get<u64>,
|
||||
// The offence type that should be used when reporting.
|
||||
O: GrandpaOffence<T::KeyOwnerIdentification>,
|
||||
{
|
||||
type Offence = O;
|
||||
type ReportLongevity = L;
|
||||
|
||||
fn report_offence(reporters: Vec<T::AccountId>, offence: O) -> Result<(), OffenceError> {
|
||||
R::report_offence(reporters, offence)
|
||||
@@ -207,6 +219,8 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
// check report staleness
|
||||
is_known_offence::<T>(equivocation_proof, key_owner_proof)?;
|
||||
|
||||
let longevity = <T::HandleEquivocation as HandleEquivocation<T>>::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<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
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()
|
||||
|
||||
@@ -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<Self::KeyOwnerIdentification, Offences>;
|
||||
type HandleEquivocation =
|
||||
super::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
|
||||
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user