Adds an offchain call to submit double vote reports (#966)

* Adds an offchain call to submit double vote reports

* Some tweaks

* Remove unnecessary IdentifyAccount impls

* Adds ValidateDoubleVoteReports to test runtime

* sp-application-crypto is only a dev dependency
This commit is contained in:
Fedor Sakharov
2020-04-16 18:19:51 +03:00
committed by GitHub
parent 58f992fa33
commit cf7cf4bd7d
9 changed files with 332 additions and 13 deletions
+77 -3
View File
@@ -57,7 +57,10 @@ use sp_runtime::transaction_validity::InvalidTransaction;
use inherents::{ProvideInherent, InherentData, MakeFatalError, InherentIdentifier};
use system::{ensure_none, ensure_signed};
use system::{
ensure_none, ensure_signed,
offchain::SubmitSignedTransaction,
};
use crate::attestations::{self, IncludedBlocks};
use crate::registrar::Registrar;
@@ -222,7 +225,7 @@ pub trait Trait: attestations::Trait + session::historical::Trait {
type Origin: From<Origin> + From<system::RawOrigin<Self::AccountId>>;
/// The outer call dispatch type.
type Call: Parameter + Dispatchable<Origin=<Self as Trait>::Origin>;
type Call: Parameter + Dispatchable<Origin=<Self as Trait>::Origin> + From<Call<Self>>;
/// Some way of interacting with balances for fees.
type ParachainCurrency: ParachainCurrency<Self::AccountId>;
@@ -290,6 +293,9 @@ pub trait Trait: attestations::Trait + session::historical::Trait {
/// A type that converts the opaque hash type to exact one.
type BlockHashConversion: Convert<Self::Hash, primitives::Hash>;
/// Submit a signed transaction.
type SubmitSignedTransaction: SubmitSignedTransaction<Self, <Self as Trait>::Call>;
}
/// Origin for the parachains module.
@@ -784,6 +790,21 @@ impl<T: Trait> Module<T> {
}
}
/// Submit a double vote report.
pub fn submit_double_vote_report(
report: DoubleVoteReport<T::Proof>,
) -> Option<()> {
let call = Call::report_double_vote(report);
let res = T::SubmitSignedTransaction::submit_signed(call);
if res.iter().any(|(_, r)| r.is_ok()) {
Some(())
} else {
None
}
}
/// Dispatch some messages from a parachain.
fn dispatch_message(
id: ParaId,
@@ -1426,6 +1447,13 @@ impl<T> sp_std::fmt::Debug for ValidateDoubleVoteReports<T> where
}
}
impl<T> ValidateDoubleVoteReports<T> {
/// Create a new `ValidateDoubleVoteReports` struct.
pub fn new() -> Self {
ValidateDoubleVoteReports(sp_std::marker::PhantomData)
}
}
/// Custom validity error used while validating double vote reports.
#[derive(RuntimeDebug)]
#[repr(u8)]
@@ -1522,7 +1550,7 @@ mod tests {
Perbill, curve::PiecewiseLinear,
traits::{
BlakeTwo256, IdentityLookup, SaturatedConversion,
OpaqueKeys,
OpaqueKeys, Extrinsic as ExtrinsicT,
},
testing::TestXt,
};
@@ -1787,6 +1815,31 @@ mod tests {
pub const SlashPeriod: BlockNumber = 50;
}
// This is needed for a custom `AccountId` type which is `u64` in testing here.
pub mod test_keys {
use sp_core::crypto::KeyTypeId;
pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"test");
mod app {
use sp_application_crypto::{app_crypto, sr25519};
use super::super::Parachains;
app_crypto!(sr25519, super::KEY_TYPE);
impl sp_runtime::traits::IdentifyAccount for Public {
type AccountId = u64;
fn into_account(self) -> Self::AccountId {
Parachains::authorities().iter().position(|b| *b == self.0.clone().into()).unwrap() as u64
}
}
}
pub type ReporterId = app::Public;
pub type ReporterSignature = app::Signature;
}
impl Trait for Test {
type Origin = Origin;
type Call = Call;
@@ -1807,6 +1860,27 @@ mod tests {
type ReportOffence = Offences;
type BlockHashConversion = sp_runtime::traits::Identity;
type KeyOwnerProofSystem = Historical;
type SubmitSignedTransaction = system::offchain::TransactionSubmitter<
test_keys::ReporterId,
Test,
Extrinsic,
>;
}
type Extrinsic = TestXt<Call, ()>;
impl system::offchain::CreateTransaction<Test, Extrinsic> for Test {
type Public = test_keys::ReporterId;
type Signature = test_keys::ReporterSignature;
fn create_transaction<F: system::offchain::Signer<Self::Public, Self::Signature>>(
call: <Extrinsic as ExtrinsicT>::Call,
_public: Self::Public,
_account: <Test as system::Trait>::AccountId,
nonce: <Test as system::Trait>::Index,
) -> Option<(<Extrinsic as ExtrinsicT>::Call, <Extrinsic as ExtrinsicT>::SignaturePayload)> {
Some((call, (nonce, ())))
}
}
type Parachains = Module<Test>;