Skip to content
Snippets Groups Projects
Commit e45a68a0 authored by asynchronous rob's avatar asynchronous rob Committed by GitHub
Browse files

add extra verification for aura (#1126)

* add extra verification for aura

* fix tests

* adjust documentation wording
parent 5d5bbccc
No related merge requests found
......@@ -286,7 +286,6 @@ enum CheckedHeader<H> {
Checked(H, u64, ed25519::Signature),
}
/// check a header has been signed by the right key. If the slot is too far in the future, an error will be returned.
/// if it's successful, returns the pre-header, the slot number, and the signat.
//
......@@ -328,15 +327,37 @@ fn check_header<B: Block>(slot_now: u64, mut header: B::Header, hash: B::Hash, a
}
}
/// Extra verification for Aura blocks.
pub trait ExtraVerification<B: Block>: Send + Sync {
/// Future that resolves when the block is verified or fails with error if not.
type Verified: IntoFuture<Item=(),Error=String>;
/// Do additional verification for this block.
fn verify(&self, header: &B::Header, body: Option<&[B::Extrinsic]>) -> Self::Verified;
}
/// No-op extra verification.
#[derive(Debug, Clone, Copy)]
pub struct NothingExtra;
impl<B: Block> ExtraVerification<B> for NothingExtra {
type Verified = Result<(), String>;
fn verify(&self, _: &B::Header, _: Option<&[B::Extrinsic]>) -> Self::Verified {
Ok(())
}
}
/// A verifier for Aura blocks.
pub struct AuraVerifier<C> {
pub struct AuraVerifier<C, E> {
config: Config,
client: Arc<C>,
extra: E,
}
impl<B: Block, C> Verifier<B> for AuraVerifier<C> where
impl<B: Block, C, E> Verifier<B> for AuraVerifier<C, E> where
C: Authorities<B> + BlockImport<B> + Send + Sync,
DigestItemFor<B>: CompatibleDigestItem,
E: ExtraVerification<B>,
{
fn verify(
&self,
......@@ -352,6 +373,8 @@ impl<B: Block, C> Verifier<B> for AuraVerifier<C> where
let authorities = self.client.authorities(&BlockId::Hash(parent_hash))
.map_err(|e| format!("Could not fetch authorities at {:?}: {:?}", parent_hash, e))?;
let extra_verification = self.extra.verify(&header, body.as_ref().map(|x| &x[..]));
// we add one to allow for some small drift.
// FIXME: in the future, alter this queue to allow deferring of headers
// https://github.com/paritytech/substrate/issues/1019
......@@ -362,6 +385,7 @@ impl<B: Block, C> Verifier<B> for AuraVerifier<C> where
debug!(target: "aura", "Checked {:?}; importing.", pre_header);
extra_verification.into_future().wait()?;
let import_block = ImportBlock {
origin,
header: pre_header,
......@@ -384,20 +408,19 @@ impl<B: Block, C> Verifier<B> for AuraVerifier<C> where
}
/// The Aura import queue type.
pub type AuraImportQueue<B, C> = BasicQueue<B, AuraVerifier<C>>;
pub type AuraImportQueue<B, C, E> = BasicQueue<B, AuraVerifier<C, E>>;
/// Start an import queue for the Aura consensus algorithm.
pub fn import_queue<B, C>(config: Config, client: Arc<C>) -> AuraImportQueue<B, C> where
pub fn import_queue<B, C, E>(config: Config, client: Arc<C>, extra: E) -> AuraImportQueue<B, C, E> where
B: Block,
C: Authorities<B> + BlockImport<B,Error=client::error::Error> + Send + Sync,
DigestItemFor<B>: CompatibleDigestItem,
E: ExtraVerification<B>,
{
let verifier = Arc::new(AuraVerifier { config, client: client.clone() });
let verifier = Arc::new(AuraVerifier { config, client: client.clone(), extra, });
BasicQueue::new(verifier, client)
}
#[cfg(test)]
mod tests {
use super::*;
......@@ -443,12 +466,12 @@ mod tests {
const TEST_ROUTING_INTERVAL: Duration = Duration::from_millis(50);
pub struct AuraTestNet {
peers: Vec<Arc<Peer<AuraVerifier<PeersClient>, ()>>>,
peers: Vec<Arc<Peer<AuraVerifier<PeersClient, NothingExtra>, ()>>>,
started: bool
}
impl TestNetFactory for AuraTestNet {
type Verifier = AuraVerifier<PeersClient>;
type Verifier = AuraVerifier<PeersClient, NothingExtra>;
type PeerData = ();
/// Create new test network with peers and given config.
......@@ -463,7 +486,7 @@ mod tests {
-> Arc<Self::Verifier>
{
let config = Config { local_key: None, slot_duration: SLOT_DURATION };
Arc::new(AuraVerifier { client, config })
Arc::new(AuraVerifier { client, config, extra: NothingExtra })
}
fn peer(&self, i: usize) -> &Peer<Self::Verifier, ()> {
......
......@@ -28,7 +28,7 @@ use substrate_service::{
Roles, TaskExecutor,
};
use node_executor;
use consensus::{import_queue, start_aura, Config as AuraConfig, AuraImportQueue};
use consensus::{import_queue, start_aura, Config as AuraConfig, AuraImportQueue, NothingExtra};
use client;
const AURA_SLOT_DURATION: u64 = 6;
......@@ -79,17 +79,25 @@ construct_service_factory! {
},
LightService = LightComponents<Self>
{ |config, executor| <LightComponents<Factory>>::new(config, executor) },
FullImportQueue = AuraImportQueue<Self::Block, FullClient<Self>>
{ |config, client| Ok(import_queue(AuraConfig {
local_key: None,
slot_duration: 5
}, client)) },
LightImportQueue = AuraImportQueue<Self::Block, LightClient<Self>>
{ |config, client| Ok(
import_queue(AuraConfig {
FullImportQueue = AuraImportQueue<Self::Block, FullClient<Self>, NothingExtra>
{ |config, client| Ok(import_queue(
AuraConfig {
local_key: None,
slot_duration: 5
}, client))
},
client,
NothingExtra,
))
},
LightImportQueue = AuraImportQueue<Self::Block, LightClient<Self>, NothingExtra>
{ |config, client| Ok(import_queue(
AuraConfig {
local_key: None,
slot_duration: 5
},
client,
NothingExtra,
))
},
}
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment