CLI option to skip seal check when importing (#2842)
This commit is contained in:
parent
9500f2b83d
commit
44a560e964
@ -204,7 +204,7 @@ impl Client {
|
|||||||
|
|
||||||
let engine = spec.engine.clone();
|
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();
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
panic_handler.forward_from(&block_queue);
|
panic_handler.forward_from(&block_queue);
|
||||||
|
|
||||||
|
@ -117,6 +117,8 @@ pub struct ClientConfig {
|
|||||||
pub jump_table_size: usize,
|
pub jump_table_size: usize,
|
||||||
/// State pruning history size.
|
/// State pruning history size.
|
||||||
pub history: u64,
|
pub history: u64,
|
||||||
|
/// Check seal valididity on block import
|
||||||
|
pub check_seal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -37,6 +37,7 @@ pub use block_import_error::BlockImportError;
|
|||||||
pub use transaction_import::TransactionImportResult;
|
pub use transaction_import::TransactionImportResult;
|
||||||
pub use transaction_import::TransactionImportError;
|
pub use transaction_import::TransactionImportError;
|
||||||
pub use self::traits::{BlockChainClient, MiningBlockChainClient};
|
pub use self::traits::{BlockChainClient, MiningBlockChainClient};
|
||||||
|
pub use verification::VerifierType;
|
||||||
|
|
||||||
/// IPC interfaces
|
/// IPC interfaces
|
||||||
#[cfg(feature="ipc")]
|
#[cfg(feature="ipc")]
|
||||||
|
@ -31,6 +31,8 @@ pub use self::queue::{BlockQueue, Config as QueueConfig, VerificationQueue, Queu
|
|||||||
pub enum VerifierType {
|
pub enum VerifierType {
|
||||||
/// Verifies block normally.
|
/// Verifies block normally.
|
||||||
Canon,
|
Canon,
|
||||||
|
/// Verifies block normallly, but skips seal verification.
|
||||||
|
CanonNoSeal,
|
||||||
/// Does not verify block at all.
|
/// Does not verify block at all.
|
||||||
/// Used in tests.
|
/// Used in tests.
|
||||||
Noop,
|
Noop,
|
||||||
@ -44,7 +46,17 @@ impl Default for VerifierType {
|
|||||||
|
|
||||||
pub fn new(v: VerifierType) -> Box<Verifier> {
|
pub fn new(v: VerifierType) -> Box<Verifier> {
|
||||||
match v {
|
match v {
|
||||||
VerifierType::Canon => Box::new(CanonVerifier),
|
VerifierType::Canon | VerifierType::CanonNoSeal => Box::new(CanonVerifier),
|
||||||
VerifierType::Noop => Box::new(NoopVerifier),
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -57,7 +57,7 @@ pub trait Kind: 'static + Sized + Send + Sync {
|
|||||||
fn create(input: Self::Input, engine: &Engine) -> Result<Self::Unverified, Error>;
|
fn create(input: Self::Input, engine: &Engine) -> Result<Self::Unverified, Error>;
|
||||||
|
|
||||||
/// Attempt to verify the `Unverified` item using the given engine.
|
/// 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.
|
/// 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();
|
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),
|
Ok(verified) => Ok(verified),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!(target: "client", "Stage 2 block verification failed for {}: {:?}", hash, 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)
|
verify_header_params(&input, engine).map(|_| input)
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
engine.verify_block_unordered(&unverified, None).map(|_| unverified)
|
match check_seal {
|
||||||
|
true => engine.verify_block_unordered(&unverified, None).map(|_| unverified),
|
||||||
|
false => Ok(unverified),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ struct Verification<K: Kind> {
|
|||||||
|
|
||||||
impl<K: Kind> VerificationQueue<K> {
|
impl<K: Kind> VerificationQueue<K> {
|
||||||
/// Creates a new queue instance.
|
/// 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 {
|
let verification = Arc::new(Verification {
|
||||||
unverified: Mutex::new(VecDeque::new()),
|
unverified: Mutex::new(VecDeque::new()),
|
||||||
verifying: Mutex::new(VecDeque::new()),
|
verifying: Mutex::new(VecDeque::new()),
|
||||||
@ -198,7 +198,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
.name(format!("Verifier #{}", i))
|
.name(format!("Verifier #{}", i))
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
panic_handler.catch_panic(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()
|
}).unwrap()
|
||||||
})
|
})
|
||||||
.expect("Error starting block verification thread")
|
.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) {
|
while !deleting.load(AtomicOrdering::Acquire) {
|
||||||
{
|
{
|
||||||
let mut more_to_verify = verification.more_to_verify.lock().unwrap();
|
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 hash = item.hash();
|
||||||
let is_ready = match K::verify(item, &*engine) {
|
let is_ready = match K::verify(item, &*engine, check_seal) {
|
||||||
Ok(verified) => {
|
Ok(verified) => {
|
||||||
let mut verifying = verification.verifying.lock();
|
let mut verifying = verification.verifying.lock();
|
||||||
let mut idx = None;
|
let mut idx = None;
|
||||||
|
@ -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.
|
/// Phase 2 verification. Perform costly checks such as transaction signatures and block nonce for ethash.
|
||||||
/// Still operates on a individual block
|
/// Still operates on a individual block
|
||||||
/// Returns a `PreverifiedBlock` structure populated with transactions
|
/// Returns a `PreverifiedBlock` structure populated with transactions
|
||||||
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine) -> Result<PreverifiedBlock, Error> {
|
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine, check_seal: bool) -> Result<PreverifiedBlock, Error> {
|
||||||
try!(engine.verify_block_unordered(&header, Some(&bytes)));
|
if check_seal {
|
||||||
for u in try!(UntrustedRlp::new(&bytes).at(2)).iter().map(|rlp| rlp.as_val::<Header>()) {
|
try!(engine.verify_block_unordered(&header, Some(&bytes)));
|
||||||
try!(engine.verify_block_unordered(&try!(u), None));
|
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.
|
// Verify transactions.
|
||||||
let mut transactions = Vec::new();
|
let mut transactions = Vec::new();
|
||||||
|
@ -84,6 +84,7 @@ pub struct ImportBlockchain {
|
|||||||
pub tracing: Switch,
|
pub tracing: Switch,
|
||||||
pub fat_db: Switch,
|
pub fat_db: Switch,
|
||||||
pub vm_type: VMType,
|
pub vm_type: VMType,
|
||||||
|
pub check_seal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -103,6 +104,7 @@ pub struct ExportBlockchain {
|
|||||||
pub tracing: Switch,
|
pub tracing: Switch,
|
||||||
pub from_block: BlockID,
|
pub from_block: BlockID,
|
||||||
pub to_block: BlockID,
|
pub to_block: BlockID,
|
||||||
|
pub check_seal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
|
pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
|
||||||
@ -158,7 +160,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||||
|
|
||||||
// prepare client config
|
// prepare client config
|
||||||
let client_config = to_client_config(&cmd.cache_config, cmd.mode, tracing, fat_db, cmd.compaction, cmd.wal, cmd.vm_type, "".into(), algorithm, cmd.pruning_history);
|
let client_config = to_client_config(&cmd.cache_config, cmd.mode, tracing, fat_db, cmd.compaction, cmd.wal, cmd.vm_type, "".into(), algorithm, cmd.pruning_history, cmd.check_seal);
|
||||||
|
|
||||||
// build client
|
// build client
|
||||||
let service = try!(ClientService::start(
|
let service = try!(ClientService::start(
|
||||||
@ -309,7 +311,7 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
|||||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||||
|
|
||||||
// prepare client config
|
// prepare client config
|
||||||
let client_config = to_client_config(&cmd.cache_config, cmd.mode, tracing, fat_db, cmd.compaction, cmd.wal, VMType::default(), "".into(), algorithm, cmd.pruning_history);
|
let client_config = to_client_config(&cmd.cache_config, cmd.mode, tracing, fat_db, cmd.compaction, cmd.wal, VMType::default(), "".into(), algorithm, cmd.pruning_history, cmd.check_seal);
|
||||||
|
|
||||||
let service = try!(ClientService::start(
|
let service = try!(ClientService::start(
|
||||||
client_config,
|
client_config,
|
||||||
|
@ -234,6 +234,7 @@ usage! {
|
|||||||
flag_from: String = "1", or |_| None,
|
flag_from: String = "1", or |_| None,
|
||||||
flag_to: String = "latest", or |_| None,
|
flag_to: String = "latest", or |_| None,
|
||||||
flag_format: Option<String> = None, or |_| None,
|
flag_format: Option<String> = None, or |_| None,
|
||||||
|
flag_no_seal_check: bool = false, or |_| None,
|
||||||
|
|
||||||
// -- Snapshot Optons
|
// -- Snapshot Optons
|
||||||
flag_at: String = "latest", or |_| None,
|
flag_at: String = "latest", or |_| None,
|
||||||
@ -561,6 +562,7 @@ mod tests {
|
|||||||
flag_from: "1".into(),
|
flag_from: "1".into(),
|
||||||
flag_to: "latest".into(),
|
flag_to: "latest".into(),
|
||||||
flag_format: None,
|
flag_format: None,
|
||||||
|
flag_no_seal_check: false,
|
||||||
|
|
||||||
// -- Snapshot Optons
|
// -- Snapshot Optons
|
||||||
flag_at: "latest".into(),
|
flag_at: "latest".into(),
|
||||||
|
@ -247,6 +247,7 @@ Import/Export Options:
|
|||||||
--format FORMAT For import/export in given format. FORMAT must be
|
--format FORMAT For import/export in given format. FORMAT must be
|
||||||
one of 'hex' and 'binary'.
|
one of 'hex' and 'binary'.
|
||||||
(default: {flag_format:?} = Import: auto, Export: binary)
|
(default: {flag_format:?} = Import: auto, Export: binary)
|
||||||
|
--no-seal-check Skip block seal check. (default: {flag_no_seal_check})
|
||||||
|
|
||||||
Snapshot Options:
|
Snapshot Options:
|
||||||
--at BLOCK Take a snapshot at the given block, which may be an
|
--at BLOCK Take a snapshot at the given block, which may be an
|
||||||
|
@ -154,6 +154,7 @@ impl Configuration {
|
|||||||
tracing: tracing,
|
tracing: tracing,
|
||||||
fat_db: fat_db,
|
fat_db: fat_db,
|
||||||
vm_type: vm_type,
|
vm_type: vm_type,
|
||||||
|
check_seal: !self.args.flag_no_seal_check,
|
||||||
};
|
};
|
||||||
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
||||||
} else if self.args.cmd_export {
|
} else if self.args.cmd_export {
|
||||||
@ -173,6 +174,7 @@ impl Configuration {
|
|||||||
fat_db: fat_db,
|
fat_db: fat_db,
|
||||||
from_block: try!(to_block_id(&self.args.flag_from)),
|
from_block: try!(to_block_id(&self.args.flag_from)),
|
||||||
to_block: try!(to_block_id(&self.args.flag_to)),
|
to_block: try!(to_block_id(&self.args.flag_to)),
|
||||||
|
check_seal: !self.args.flag_no_seal_check,
|
||||||
};
|
};
|
||||||
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
|
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
|
||||||
} else if self.args.cmd_snapshot {
|
} else if self.args.cmd_snapshot {
|
||||||
@ -251,6 +253,7 @@ impl Configuration {
|
|||||||
name: self.args.flag_identity,
|
name: self.args.flag_identity,
|
||||||
custom_bootnodes: self.args.flag_bootnodes.is_some(),
|
custom_bootnodes: self.args.flag_bootnodes.is_some(),
|
||||||
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
||||||
|
check_seal: !self.args.flag_no_seal_check,
|
||||||
};
|
};
|
||||||
Cmd::Run(run_cmd)
|
Cmd::Run(run_cmd)
|
||||||
};
|
};
|
||||||
@ -738,6 +741,7 @@ mod tests {
|
|||||||
tracing: Default::default(),
|
tracing: Default::default(),
|
||||||
fat_db: Default::default(),
|
fat_db: Default::default(),
|
||||||
vm_type: VMType::Interpreter,
|
vm_type: VMType::Interpreter,
|
||||||
|
check_seal: true,
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,6 +765,7 @@ mod tests {
|
|||||||
fat_db: Default::default(),
|
fat_db: Default::default(),
|
||||||
from_block: BlockID::Number(1),
|
from_block: BlockID::Number(1),
|
||||||
to_block: BlockID::Latest,
|
to_block: BlockID::Latest,
|
||||||
|
check_seal: true,
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,6 +789,7 @@ mod tests {
|
|||||||
fat_db: Default::default(),
|
fat_db: Default::default(),
|
||||||
from_block: BlockID::Number(1),
|
from_block: BlockID::Number(1),
|
||||||
to_block: BlockID::Latest,
|
to_block: BlockID::Latest,
|
||||||
|
check_seal: true,
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,6 +838,7 @@ mod tests {
|
|||||||
custom_bootnodes: false,
|
custom_bootnodes: false,
|
||||||
fat_db: Default::default(),
|
fat_db: Default::default(),
|
||||||
no_periodic_snapshot: false,
|
no_periodic_snapshot: false,
|
||||||
|
check_seal: true,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ use std::path::Path;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use util::{clean_0x, U256, Uint, Address, path, CompactionProfile};
|
use util::{clean_0x, U256, Uint, Address, path, CompactionProfile};
|
||||||
use util::journaldb::Algorithm;
|
use util::journaldb::Algorithm;
|
||||||
use ethcore::client::{Mode, BlockID, VMType, DatabaseCompactionProfile, ClientConfig};
|
use ethcore::client::{Mode, BlockID, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType};
|
||||||
use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy};
|
use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy};
|
||||||
use cache::CacheConfig;
|
use cache::CacheConfig;
|
||||||
use dir::DatabaseDirectories;
|
use dir::DatabaseDirectories;
|
||||||
@ -215,6 +215,7 @@ pub fn to_client_config(
|
|||||||
name: String,
|
name: String,
|
||||||
pruning: Algorithm,
|
pruning: Algorithm,
|
||||||
pruning_history: u64,
|
pruning_history: u64,
|
||||||
|
check_seal: bool,
|
||||||
) -> ClientConfig {
|
) -> ClientConfig {
|
||||||
let mut client_config = ClientConfig::default();
|
let mut client_config = ClientConfig::default();
|
||||||
|
|
||||||
@ -247,6 +248,7 @@ pub fn to_client_config(
|
|||||||
client_config.db_wal = wal;
|
client_config.db_wal = wal;
|
||||||
client_config.vm_type = vm_type;
|
client_config.vm_type = vm_type;
|
||||||
client_config.name = name;
|
client_config.name = name;
|
||||||
|
client_config.verifier_type = if check_seal { VerifierType::Canon } else { VerifierType::CanonNoSeal };
|
||||||
client_config
|
client_config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ pub struct RunCmd {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub custom_bootnodes: bool,
|
pub custom_bootnodes: bool,
|
||||||
pub no_periodic_snapshot: bool,
|
pub no_periodic_snapshot: bool,
|
||||||
|
pub check_seal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||||
@ -197,6 +198,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
|||||||
cmd.name,
|
cmd.name,
|
||||||
algorithm,
|
algorithm,
|
||||||
cmd.pruning_history,
|
cmd.pruning_history,
|
||||||
|
cmd.check_seal,
|
||||||
);
|
);
|
||||||
|
|
||||||
// set up bootnodes
|
// set up bootnodes
|
||||||
|
@ -163,7 +163,7 @@ impl SnapshotCommand {
|
|||||||
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||||
|
|
||||||
// prepare client config
|
// prepare client config
|
||||||
let client_config = to_client_config(&self.cache_config, self.mode, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history);
|
let client_config = to_client_config(&self.cache_config, self.mode, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
|
||||||
|
|
||||||
let service = try!(ClientService::start(
|
let service = try!(ClientService::start(
|
||||||
client_config,
|
client_config,
|
||||||
|
Loading…
Reference in New Issue
Block a user