Unverified Commit 872bd4fd authored by André Silva's avatar André Silva Committed by GitHub
Browse files

grandpa: report equivocations on all runtimes (#1000)

* grandpa: report equivocations on all runtimes

* runtime: fix test-runtime compilation

* runtime: enable historical session manager on all runtimes

* runtime: fix indentation

* runtime: use strong key types in KeyOwnerProofSystem definitions

* update substrate

* bump spec_version of runtimes
parent c322ca43
Pipeline #91435 passed with stages
in 22 minutes and 26 seconds
This diff is collapsed.
...@@ -8,6 +8,7 @@ edition = "2018" ...@@ -8,6 +8,7 @@ edition = "2018"
serde = { version = "1.0.102", optional = true, features = ["derive"] } serde = { version = "1.0.102", optional = true, features = ["derive"] }
parity-scale-codec = { version = "1.3.0", default-features = false, features = ["bit-vec", "derive"] } parity-scale-codec = { version = "1.3.0", default-features = false, features = ["bit-vec", "derive"] }
primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
system = { package = "frame-system", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
...@@ -28,6 +29,7 @@ default = ["std"] ...@@ -28,6 +29,7 @@ default = ["std"]
std = [ std = [
"parity-scale-codec/std", "parity-scale-codec/std",
"primitives/std", "primitives/std",
"system/std",
"inherents/std", "inherents/std",
"trie/std", "trie/std",
"sp-api/std", "sp-api/std",
......
...@@ -92,3 +92,32 @@ impl From<ValidityError> for u8 { ...@@ -92,3 +92,32 @@ impl From<ValidityError> for u8 {
err as u8 err as u8
} }
} }
/// App-specific crypto used for reporting equivocation/misbehavior in BABE,
/// GRANDPA and Parachains, described in the white paper as the fisherman role.
/// Any rewards for misbehavior reporting will be paid out to this account.
pub mod fisherman {
use super::{Signature, Verify};
use primitives::crypto::KeyTypeId;
/// Key type for the reporting module. Used for reporting BABE, GRANDPA
/// and Parachain equivocations.
pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"fish");
mod app {
use application_crypto::{app_crypto, sr25519};
app_crypto!(sr25519, super::KEY_TYPE);
}
/// Identity of the equivocation/misbehavior reporter.
pub type FishermanId = app::Public;
/// An `AppCrypto` type to allow submitting signed transactions using the fisherman
/// application key as signer.
pub struct FishermanAppCrypto;
impl system::offchain::AppCrypto<<Signature as Verify>::Signer, Signature> for FishermanAppCrypto {
type RuntimeAppPublic = FishermanId;
type GenericSignature = primitives::sr25519::Signature;
type GenericPublic = primitives::sr25519::Public;
}
}
...@@ -88,17 +88,6 @@ application_crypto::with_pair! { ...@@ -88,17 +88,6 @@ application_crypto::with_pair! {
/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto. /// so we define it to be the same type as `SessionKey`. In the future it may have different crypto.
pub type ValidatorSignature = validator_app::Signature; pub type ValidatorSignature = validator_app::Signature;
/// The key type ID for a fisherman key.
pub const FISHERMAN_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"fish");
mod fisherman_app {
use application_crypto::{app_crypto, sr25519};
app_crypto!(sr25519, super::FISHERMAN_KEY_TYPE_ID);
}
/// Identity that fishermen use when generating reports.
pub type FishermanId = fisherman_app::Public;
/// Retriability for a given active para. /// Retriability for a given active para.
#[derive(Clone, Eq, PartialEq, Encode, Decode)] #[derive(Clone, Eq, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))] #[cfg_attr(feature = "std", derive(Debug))]
......
...@@ -17,6 +17,7 @@ inherents = { package = "sp-inherents", git = "https://github.com/paritytech/sub ...@@ -17,6 +17,7 @@ inherents = { package = "sp-inherents", git = "https://github.com/paritytech/sub
sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
...@@ -67,6 +68,7 @@ std = [ ...@@ -67,6 +68,7 @@ std = [
"authorship/std", "authorship/std",
"balances/std", "balances/std",
"sp-runtime/std", "sp-runtime/std",
"sp-session/std",
"sp-staking/std", "sp-staking/std",
"session/std", "session/std",
"staking/std", "staking/std",
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
use sp_std::prelude::*; use sp_std::prelude::*;
use sp_std::result; use sp_std::result;
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use sp_core::sr25519;
use sp_runtime::{ use sp_runtime::{
KeyTypeId, Perbill, RuntimeDebug, KeyTypeId, Perbill, RuntimeDebug,
traits::{ traits::{
...@@ -41,13 +40,12 @@ use frame_support::{ ...@@ -41,13 +40,12 @@ use frame_support::{
use primitives::{ use primitives::{
Balance, Balance,
BlockNumber, BlockNumber,
Signature,
parachain::{ parachain::{
Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement, ParachainDispatchOrigin, Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement, ParachainDispatchOrigin,
UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData, UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData,
CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt, CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt,
LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID, LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID,
ValidatorSignature, SigningContext, HeadData, ValidationCode, FishermanId, ValidatorSignature, SigningContext, HeadData, ValidationCode,
}, },
}; };
use frame_support::{ use frame_support::{
...@@ -56,7 +54,6 @@ use frame_support::{ ...@@ -56,7 +54,6 @@ use frame_support::{
}; };
use sp_runtime::{ use sp_runtime::{
transaction_validity::InvalidTransaction, transaction_validity::InvalidTransaction,
traits::Verify,
}; };
use inherents::{ProvideInherent, InherentData, MakeFatalError, InherentIdentifier}; use inherents::{ProvideInherent, InherentData, MakeFatalError, InherentIdentifier};
...@@ -68,14 +65,6 @@ use system::{ ...@@ -68,14 +65,6 @@ use system::{
use crate::attestations::{self, IncludedBlocks}; use crate::attestations::{self, IncludedBlocks};
use crate::registrar::Registrar; use crate::registrar::Registrar;
// An `AppCrypto` type to facilitate submitting signed transactions.
pub struct FishermanAuthorityId;
impl system::offchain::AppCrypto<<Signature as Verify>::Signer, Signature> for FishermanAuthorityId {
type RuntimeAppPublic = FishermanId;
type GenericSignature = sr25519::Signature;
type GenericPublic = sp_core::sr25519::Public;
}
// ranges for iteration of general block number don't work, so this // ranges for iteration of general block number don't work, so this
// is a utility to get around that. // is a utility to get around that.
struct BlockNumberRange<N> { struct BlockNumberRange<N> {
...@@ -221,12 +210,12 @@ impl<T: session::Trait> Get<Vec<T::ValidatorId>> for ValidatorIdentities<T> { ...@@ -221,12 +210,12 @@ impl<T: session::Trait> Get<Vec<T::ValidatorId>> for ValidatorIdentities<T> {
} }
} }
/// A trait to get a session number the `Proof` belongs to. /// A trait to get a session number the `MembershipProof` belongs to.
pub trait GetSessionNumber { pub trait GetSessionNumber {
fn session(&self) -> SessionIndex; fn session(&self) -> SessionIndex;
} }
impl GetSessionNumber for session::historical::Proof { impl GetSessionNumber for sp_session::MembershipProof {
fn session(&self) -> SessionIndex { fn session(&self) -> SessionIndex {
self.session() self.session()
} }
...@@ -1996,7 +1985,7 @@ mod tests { ...@@ -1996,7 +1985,7 @@ mod tests {
} }
fn report_double_vote( fn report_double_vote(
report: DoubleVoteReport<session::historical::Proof>, report: DoubleVoteReport<sp_session::MembershipProof>,
) -> Result<ParachainsCall<Test>, TransactionValidityError> { ) -> Result<ParachainsCall<Test>, TransactionValidityError> {
let inner = ParachainsCall::report_double_vote(report); let inner = ParachainsCall::report_double_vote(report);
let call = Call::Parachains(inner.clone()); let call = Call::Parachains(inner.clone());
......
...@@ -904,9 +904,12 @@ mod tests { ...@@ -904,9 +904,12 @@ mod tests {
type ValidationUpgradeFrequency = ValidationUpgradeFrequency; type ValidationUpgradeFrequency = ValidationUpgradeFrequency;
type ValidationUpgradeDelay = ValidationUpgradeDelay; type ValidationUpgradeDelay = ValidationUpgradeDelay;
type SlashPeriod = SlashPeriod; type SlashPeriod = SlashPeriod;
type Proof = session::historical::Proof; type Proof = sp_session::MembershipProof;
type KeyOwnerProofSystem = session::historical::Module<Test>; type KeyOwnerProofSystem = session::historical::Module<Test>;
type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple; type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
Vec<u8>,
)>>::IdentificationTuple;
type ReportOffence = (); type ReportOffence = ();
type BlockHashConversion = sp_runtime::traits::Identity; type BlockHashConversion = sp_runtime::traits::Identity;
} }
......
...@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { ...@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("kusama"), spec_name: create_runtime_str!("kusama"),
impl_name: create_runtime_str!("parity-kusama"), impl_name: create_runtime_str!("parity-kusama"),
authoring_version: 2, authoring_version: 2,
spec_version: 1062, spec_version: 1063,
impl_version: 0, impl_version: 0,
apis: RUNTIME_API_VERSIONS, apis: RUNTIME_API_VERSIONS,
transaction_version: 1, transaction_version: 1,
...@@ -267,7 +267,7 @@ impl session::Trait for Runtime { ...@@ -267,7 +267,7 @@ impl session::Trait for Runtime {
type ValidatorIdOf = staking::StashOf<Self>; type ValidatorIdOf = staking::StashOf<Self>;
type ShouldEndSession = Babe; type ShouldEndSession = Babe;
type NextSessionRotation = Babe; type NextSessionRotation = Babe;
type SessionManager = Staking; type SessionManager = session::historical::NoteHistoricalRoot<Self, Staking>;
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders; type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys; type Keys = SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
...@@ -490,6 +490,24 @@ impl im_online::Trait for Runtime { ...@@ -490,6 +490,24 @@ impl im_online::Trait for Runtime {
impl grandpa::Trait for Runtime { impl grandpa::Trait for Runtime {
type Event = Event; type Event = Event;
type Call = Call;
type KeyOwnerProofSystem = Historical;
type KeyOwnerProof =
<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
GrandpaId,
)>>::IdentificationTuple;
type HandleEquivocation = grandpa::EquivocationHandler<
Self::KeyOwnerIdentification,
primitives::fisherman::FishermanAppCrypto,
Runtime,
Offences,
>;
} }
parameter_types! { parameter_types! {
...@@ -522,7 +540,7 @@ parameter_types! { ...@@ -522,7 +540,7 @@ parameter_types! {
} }
impl parachains::Trait for Runtime { impl parachains::Trait for Runtime {
type AuthorityId = parachains::FishermanAuthorityId; type AuthorityId = primitives::fisherman::FishermanAppCrypto;
type Origin = Origin; type Origin = Origin;
type Call = Call; type Call = Call;
type ParachainCurrency = Balances; type ParachainCurrency = Balances;
...@@ -537,13 +555,15 @@ impl parachains::Trait for Runtime { ...@@ -537,13 +555,15 @@ impl parachains::Trait for Runtime {
type ValidationUpgradeDelay = ValidationUpgradeDelay; type ValidationUpgradeDelay = ValidationUpgradeDelay;
type SlashPeriod = SlashPeriod; type SlashPeriod = SlashPeriod;
type Proof = session::historical::Proof; type Proof = sp_session::MembershipProof;
type KeyOwnerProofSystem = session::historical::Module<Self>; type KeyOwnerProofSystem = session::historical::Module<Self>;
type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple; type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
type ReportOffence = Offences; type ReportOffence = Offences;
type BlockHashConversion = sp_runtime::traits::Identity; type BlockHashConversion = sp_runtime::traits::Identity;
} }
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime where impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
Call: From<LocalCall>, Call: From<LocalCall>,
{ {
...@@ -553,6 +573,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime ...@@ -553,6 +573,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime
account: AccountId, account: AccountId,
nonce: <Runtime as system::Trait>::Index, nonce: <Runtime as system::Trait>::Index,
) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> { ) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
// take the biggest period possible.
let period = BlockHashCount::get() let period = BlockHashCount::get()
.checked_next_power_of_two() .checked_next_power_of_two()
.map(|c| c / 2) .map(|c| c / 2)
...@@ -560,6 +581,8 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime ...@@ -560,6 +581,8 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime
let current_block = System::block_number() let current_block = System::block_number()
.saturated_into::<u64>() .saturated_into::<u64>()
// The `System::block_number` is initialized with `n+1`,
// so the actual block number is `n`.
.saturating_sub(1); .saturating_sub(1);
let tip = 0; let tip = 0;
let extra: SignedExtra = ( let extra: SignedExtra = (
...@@ -572,6 +595,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime ...@@ -572,6 +595,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime
transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip), transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
registrar::LimitParathreadCommits::<Runtime>::new(), registrar::LimitParathreadCommits::<Runtime>::new(),
parachains::ValidateDoubleVoteReports::<Runtime>::new(), parachains::ValidateDoubleVoteReports::<Runtime>::new(),
grandpa::ValidateEquivocationReport::<Runtime>::new(),
); );
let raw_payload = SignedPayload::new(call, extra).map_err(|e| { let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
debug::warn!("Unable to create signed payload: {:?}", e); debug::warn!("Unable to create signed payload: {:?}", e);
...@@ -818,9 +842,10 @@ pub type SignedExtra = ( ...@@ -818,9 +842,10 @@ pub type SignedExtra = (
system::CheckEra<Runtime>, system::CheckEra<Runtime>,
system::CheckNonce<Runtime>, system::CheckNonce<Runtime>,
system::CheckWeight<Runtime>, system::CheckWeight<Runtime>,
transaction_payment::ChargeTransactionPayment::<Runtime>, transaction_payment::ChargeTransactionPayment<Runtime>,
registrar::LimitParathreadCommits<Runtime>, registrar::LimitParathreadCommits<Runtime>,
parachains::ValidateDoubleVoteReports<Runtime>, parachains::ValidateDoubleVoteReports<Runtime>,
grandpa::ValidateEquivocationReport<Runtime>,
); );
/// Unchecked extrinsic type as expected by this runtime. /// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
...@@ -935,6 +960,32 @@ sp_api::impl_runtime_apis! { ...@@ -935,6 +960,32 @@ sp_api::impl_runtime_apis! {
fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
Grandpa::grandpa_authorities() Grandpa::grandpa_authorities()
} }
fn submit_report_equivocation_extrinsic(
equivocation_proof: fg_primitives::EquivocationProof<
<Block as BlockT>::Hash,
sp_runtime::traits::NumberFor<Block>,
>,
key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
) -> Option<()> {
let key_owner_proof = key_owner_proof.decode()?;
Grandpa::submit_report_equivocation_extrinsic(
equivocation_proof,
key_owner_proof,
)
}
fn generate_key_ownership_proof(
_set_id: fg_primitives::SetId,
authority_id: fg_primitives::AuthorityId,
) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
use codec::Encode;
Historical::prove((fg_primitives::KEY_TYPE, authority_id))
.map(|p| p.encode())
.map(fg_primitives::OpaqueKeyOwnershipProof::new)
}
} }
impl babe_primitives::BabeApi<Block> for Runtime { impl babe_primitives::BabeApi<Block> for Runtime {
......
...@@ -86,7 +86,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { ...@@ -86,7 +86,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("polkadot"), spec_name: create_runtime_str!("polkadot"),
impl_name: create_runtime_str!("parity-polkadot"), impl_name: create_runtime_str!("parity-polkadot"),
authoring_version: 2, authoring_version: 2,
spec_version: 1009, spec_version: 1010,
impl_version: 0, impl_version: 0,
apis: RUNTIME_API_VERSIONS, apis: RUNTIME_API_VERSIONS,
transaction_version: 1, transaction_version: 1,
...@@ -273,7 +273,7 @@ impl session::Trait for Runtime { ...@@ -273,7 +273,7 @@ impl session::Trait for Runtime {
type ValidatorIdOf = staking::StashOf<Self>; type ValidatorIdOf = staking::StashOf<Self>;
type ShouldEndSession = Babe; type ShouldEndSession = Babe;
type NextSessionRotation = Babe; type NextSessionRotation = Babe;
type SessionManager = Staking; type SessionManager = session::historical::NoteHistoricalRoot<Self, Staking>;
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders; type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys; type Keys = SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
...@@ -496,6 +496,24 @@ impl im_online::Trait for Runtime { ...@@ -496,6 +496,24 @@ impl im_online::Trait for Runtime {
impl grandpa::Trait for Runtime { impl grandpa::Trait for Runtime {
type Event = Event; type Event = Event;
type Call = Call;
type KeyOwnerProofSystem = Historical;
type KeyOwnerProof =
<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
GrandpaId,
)>>::IdentificationTuple;
type HandleEquivocation = grandpa::EquivocationHandler<
Self::KeyOwnerIdentification,
primitives::fisherman::FishermanAppCrypto,
Runtime,
Offences,
>;
} }
parameter_types! { parameter_types! {
...@@ -529,7 +547,7 @@ parameter_types! { ...@@ -529,7 +547,7 @@ parameter_types! {
} }
impl parachains::Trait for Runtime { impl parachains::Trait for Runtime {
type AuthorityId = parachains::FishermanAuthorityId; type AuthorityId = primitives::fisherman::FishermanAppCrypto;
type Origin = Origin; type Origin = Origin;
type Call = Call; type Call = Call;
type ParachainCurrency = Balances; type ParachainCurrency = Balances;
...@@ -544,13 +562,15 @@ impl parachains::Trait for Runtime { ...@@ -544,13 +562,15 @@ impl parachains::Trait for Runtime {
type ValidationUpgradeDelay = ValidationUpgradeDelay; type ValidationUpgradeDelay = ValidationUpgradeDelay;
type SlashPeriod = SlashPeriod; type SlashPeriod = SlashPeriod;
type Proof = session::historical::Proof; type Proof = sp_session::MembershipProof;
type KeyOwnerProofSystem = session::historical::Module<Self>; type KeyOwnerProofSystem = session::historical::Module<Self>;
type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple; type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
type ReportOffence = Offences; type ReportOffence = Offences;
type BlockHashConversion = sp_runtime::traits::Identity; type BlockHashConversion = sp_runtime::traits::Identity;
} }
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime where impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
Call: From<LocalCall>, Call: From<LocalCall>,
{ {
...@@ -560,6 +580,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime ...@@ -560,6 +580,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime
account: AccountId, account: AccountId,
nonce: <Runtime as system::Trait>::Index, nonce: <Runtime as system::Trait>::Index,
) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> { ) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
// take the biggest period possible.
let period = BlockHashCount::get() let period = BlockHashCount::get()
.checked_next_power_of_two() .checked_next_power_of_two()
.map(|c| c / 2) .map(|c| c / 2)
...@@ -567,6 +588,8 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime ...@@ -567,6 +588,8 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime
let current_block = System::block_number() let current_block = System::block_number()
.saturated_into::<u64>() .saturated_into::<u64>()
// The `System::block_number` is initialized with `n+1`,
// so the actual block number is `n`.
.saturating_sub(1); .saturating_sub(1);
let tip = 0; let tip = 0;
let extra: SignedExtra = ( let extra: SignedExtra = (
...@@ -579,6 +602,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime ...@@ -579,6 +602,7 @@ impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime
transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip), transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
registrar::LimitParathreadCommits::<Runtime>::new(), registrar::LimitParathreadCommits::<Runtime>::new(),
parachains::ValidateDoubleVoteReports::<Runtime>::new(), parachains::ValidateDoubleVoteReports::<Runtime>::new(),
grandpa::ValidateEquivocationReport::<Runtime>::new(),
); );
let raw_payload = SignedPayload::new(call, extra).map_err(|e| { let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
debug::warn!("Unable to create signed payload: {:?}", e); debug::warn!("Unable to create signed payload: {:?}", e);
...@@ -733,9 +757,10 @@ pub type SignedExtra = ( ...@@ -733,9 +757,10 @@ pub type SignedExtra = (
system::CheckEra<Runtime>, system::CheckEra<Runtime>,
system::CheckNonce<Runtime>, system::CheckNonce<Runtime>,
system::CheckWeight<Runtime>, system::CheckWeight<Runtime>,
transaction_payment::ChargeTransactionPayment::<Runtime>, transaction_payment::ChargeTransactionPayment<Runtime>,
registrar::LimitParathreadCommits<Runtime>, registrar::LimitParathreadCommits<Runtime>,
parachains::ValidateDoubleVoteReports<Runtime> parachains::ValidateDoubleVoteReports<Runtime>,
grandpa::ValidateEquivocationReport<Runtime>,
); );
/// Unchecked extrinsic type as expected by this runtime. /// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
...@@ -850,6 +875,32 @@ sp_api::impl_runtime_apis! { ...@@ -850,6 +875,32 @@ sp_api::impl_runtime_apis! {
fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
Grandpa::grandpa_authorities() Grandpa::grandpa_authorities()
} }
fn submit_report_equivocation_extrinsic(
equivocation_proof: fg_primitives::EquivocationProof<
<Block as BlockT>::Hash,
sp_runtime::traits::NumberFor<Block>,
>,
key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
) -> Option<()> {
let key_owner_proof = key_owner_proof.decode()?;
Grandpa::submit_report_equivocation_extrinsic(
equivocation_proof,
key_owner_proof,
)