CLI option to skip seal check when importing (#2842)

This commit is contained in:
Arkadiy Paronyan
2016-10-24 15:09:13 +02:00
committed by Gav Wood
parent 9500f2b83d
commit 44a560e964
14 changed files with 55 additions and 19 deletions

View File

@@ -204,7 +204,7 @@ impl Client {
let engine = spec.engine.clone();
let block_queue = BlockQueue::new(config.queue.clone(), engine.clone(), message_channel.clone());
let block_queue = BlockQueue::new(config.queue.clone(), engine.clone(), message_channel.clone(), config.verifier_type.verifying_seal());
let panic_handler = PanicHandler::new_in_arc();
panic_handler.forward_from(&block_queue);

View File

@@ -117,6 +117,8 @@ pub struct ClientConfig {
pub jump_table_size: usize,
/// State pruning history size.
pub history: u64,
/// Check seal valididity on block import
pub check_seal: bool,
}
#[cfg(test)]

View File

@@ -37,6 +37,7 @@ pub use block_import_error::BlockImportError;
pub use transaction_import::TransactionImportResult;
pub use transaction_import::TransactionImportError;
pub use self::traits::{BlockChainClient, MiningBlockChainClient};
pub use verification::VerifierType;
/// IPC interfaces
#[cfg(feature="ipc")]

View File

@@ -31,6 +31,8 @@ pub use self::queue::{BlockQueue, Config as QueueConfig, VerificationQueue, Queu
pub enum VerifierType {
/// Verifies block normally.
Canon,
/// Verifies block normallly, but skips seal verification.
CanonNoSeal,
/// Does not verify block at all.
/// Used in tests.
Noop,
@@ -44,7 +46,17 @@ impl Default for VerifierType {
pub fn new(v: VerifierType) -> Box<Verifier> {
match v {
VerifierType::Canon => Box::new(CanonVerifier),
VerifierType::Canon | VerifierType::CanonNoSeal => Box::new(CanonVerifier),
VerifierType::Noop => Box::new(NoopVerifier),
}
}
impl VerifierType {
/// Check if seal verification is enabled for this verifier type.
pub fn verifying_seal(&self) -> bool {
match *self {
VerifierType::Canon => true,
VerifierType::Noop | VerifierType::CanonNoSeal => false,
}
}
}

View File

@@ -57,7 +57,7 @@ pub trait Kind: 'static + Sized + Send + Sync {
fn create(input: Self::Input, engine: &Engine) -> Result<Self::Unverified, Error>;
/// Attempt to verify the `Unverified` item using the given engine.
fn verify(unverified: Self::Unverified, engine: &Engine) -> Result<Self::Verified, Error>;
fn verify(unverified: Self::Unverified, engine: &Engine, check_seal: bool) -> Result<Self::Verified, Error>;
}
/// The blocks verification module.
@@ -89,9 +89,9 @@ pub mod blocks {
}
}
fn verify(un: Self::Unverified, engine: &Engine) -> Result<Self::Verified, Error> {
fn verify(un: Self::Unverified, engine: &Engine, check_seal: bool) -> Result<Self::Verified, Error> {
let hash = un.hash();
match verify_block_unordered(un.header, un.bytes, engine) {
match verify_block_unordered(un.header, un.bytes, engine, check_seal) {
Ok(verified) => Ok(verified),
Err(e) => {
warn!(target: "client", "Stage 2 block verification failed for {}: {:?}", hash, e);
@@ -176,8 +176,11 @@ pub mod headers {
verify_header_params(&input, engine).map(|_| input)
}
fn verify(unverified: Self::Unverified, engine: &Engine) -> Result<Self::Verified, Error> {
engine.verify_block_unordered(&unverified, None).map(|_| unverified)
fn verify(unverified: Self::Unverified, engine: &Engine, check_seal: bool) -> Result<Self::Verified, Error> {
match check_seal {
true => engine.verify_block_unordered(&unverified, None).map(|_| unverified),
false => Ok(unverified),
}
}
}
}

View File

@@ -159,7 +159,7 @@ struct Verification<K: Kind> {
impl<K: Kind> VerificationQueue<K> {
/// Creates a new queue instance.
pub fn new(config: Config, engine: Arc<Engine>, message_channel: IoChannel<ClientIoMessage>) -> Self {
pub fn new(config: Config, engine: Arc<Engine>, message_channel: IoChannel<ClientIoMessage>, check_seal: bool) -> Self {
let verification = Arc::new(Verification {
unverified: Mutex::new(VecDeque::new()),
verifying: Mutex::new(VecDeque::new()),
@@ -198,7 +198,7 @@ impl<K: Kind> VerificationQueue<K> {
.name(format!("Verifier #{}", i))
.spawn(move || {
panic_handler.catch_panic(move || {
VerificationQueue::verify(verification, engine, more_to_verify, ready_signal, deleting, empty)
VerificationQueue::verify(verification, engine, more_to_verify, ready_signal, deleting, empty, check_seal)
}).unwrap()
})
.expect("Error starting block verification thread")
@@ -219,7 +219,7 @@ impl<K: Kind> VerificationQueue<K> {
}
}
fn verify(verification: Arc<Verification<K>>, engine: Arc<Engine>, wait: Arc<SCondvar>, ready: Arc<QueueSignal>, deleting: Arc<AtomicBool>, empty: Arc<SCondvar>) {
fn verify(verification: Arc<Verification<K>>, engine: Arc<Engine>, wait: Arc<SCondvar>, ready: Arc<QueueSignal>, deleting: Arc<AtomicBool>, empty: Arc<SCondvar>, check_seal: bool) {
while !deleting.load(AtomicOrdering::Acquire) {
{
let mut more_to_verify = verification.more_to_verify.lock().unwrap();
@@ -253,7 +253,7 @@ impl<K: Kind> VerificationQueue<K> {
};
let hash = item.hash();
let is_ready = match K::verify(item, &*engine) {
let is_ready = match K::verify(item, &*engine, check_seal) {
Ok(verified) => {
let mut verifying = verification.verifying.lock();
let mut idx = None;

View File

@@ -66,10 +66,12 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Res
/// Phase 2 verification. Perform costly checks such as transaction signatures and block nonce for ethash.
/// Still operates on a individual block
/// Returns a `PreverifiedBlock` structure populated with transactions
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine) -> Result<PreverifiedBlock, Error> {
try!(engine.verify_block_unordered(&header, Some(&bytes)));
for u in try!(UntrustedRlp::new(&bytes).at(2)).iter().map(|rlp| rlp.as_val::<Header>()) {
try!(engine.verify_block_unordered(&try!(u), None));
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine, check_seal: bool) -> Result<PreverifiedBlock, Error> {
if check_seal {
try!(engine.verify_block_unordered(&header, Some(&bytes)));
for u in try!(UntrustedRlp::new(&bytes).at(2)).iter().map(|rlp| rlp.as_val::<Header>()) {
try!(engine.verify_block_unordered(&try!(u), None));
}
}
// Verify transactions.
let mut transactions = Vec::new();