[beta] Backports (#6163)
* Light client improvements (#6156) * no seal checking * import command and --no-seal-check for light client * fix eth_call * tweak registry dapps lookup * ignore failed requests to non-server peers * Fix connecting to wildcard addresses. (#6167) * Don't display an overlay in case the time sync check fails. (#6164) * Small improvements to time estimation. * Temporarily disable NTP time check by default.
This commit is contained in:
@@ -93,6 +93,7 @@ pub struct ImportBlockchain {
|
||||
pub check_seal: bool,
|
||||
pub with_color: bool,
|
||||
pub verifier_settings: VerifierSettings,
|
||||
pub light: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -138,12 +139,165 @@ pub struct ExportState {
|
||||
pub fn execute(cmd: BlockchainCmd) -> Result<(), String> {
|
||||
match cmd {
|
||||
BlockchainCmd::Kill(kill_cmd) => kill_db(kill_cmd),
|
||||
BlockchainCmd::Import(import_cmd) => execute_import(import_cmd),
|
||||
BlockchainCmd::Import(import_cmd) => {
|
||||
if import_cmd.light {
|
||||
execute_import_light(import_cmd)
|
||||
} else {
|
||||
execute_import(import_cmd)
|
||||
}
|
||||
}
|
||||
BlockchainCmd::Export(export_cmd) => execute_export(export_cmd),
|
||||
BlockchainCmd::ExportState(export_cmd) => execute_export_state(export_cmd),
|
||||
}
|
||||
}
|
||||
|
||||
fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> {
|
||||
use light::client::{Service as LightClientService, Config as LightClientConfig};
|
||||
use light::cache::Cache as LightDataCache;
|
||||
|
||||
let timer = Instant::now();
|
||||
|
||||
// load spec file
|
||||
let spec = cmd.spec.spec(&cmd.dirs.cache)?;
|
||||
|
||||
// load genesis hash
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
// database paths
|
||||
let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir.clone());
|
||||
|
||||
// user defaults path
|
||||
let user_defaults_path = db_dirs.user_defaults_path();
|
||||
|
||||
// load user defaults
|
||||
let user_defaults = UserDefaults::load(&user_defaults_path)?;
|
||||
|
||||
fdlimit::raise_fd_limit();
|
||||
|
||||
// select pruning algorithm
|
||||
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
|
||||
|
||||
// prepare client and snapshot paths.
|
||||
let client_path = db_dirs.client_path(algorithm);
|
||||
|
||||
// execute upgrades
|
||||
let compaction = cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path());
|
||||
execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, compaction)?;
|
||||
|
||||
// create dirs used by parity
|
||||
cmd.dirs.create_dirs(false, false, false)?;
|
||||
|
||||
let cache = Arc::new(::util::Mutex::new(
|
||||
LightDataCache::new(Default::default(), ::time::Duration::seconds(0))
|
||||
));
|
||||
|
||||
let mut config = LightClientConfig {
|
||||
queue: Default::default(),
|
||||
chain_column: ::ethcore::db::COL_LIGHT_CHAIN,
|
||||
db_cache_size: Some(cmd.cache_config.blockchain() as usize * 1024 * 1024),
|
||||
db_compaction: compaction,
|
||||
db_wal: cmd.wal,
|
||||
verify_full: true,
|
||||
check_seal: cmd.check_seal,
|
||||
};
|
||||
|
||||
config.queue.max_mem_use = cmd.cache_config.queue() as usize * 1024 * 1024;
|
||||
config.queue.verifier_settings = cmd.verifier_settings;
|
||||
|
||||
let service = LightClientService::start(config, &spec, &client_path, cache)
|
||||
.map_err(|e| format!("Failed to start client: {}", e))?;
|
||||
|
||||
// free up the spec in memory.
|
||||
drop(spec);
|
||||
|
||||
let client = service.client();
|
||||
|
||||
let mut instream: Box<io::Read> = match cmd.file_path {
|
||||
Some(f) => Box::new(fs::File::open(&f).map_err(|_| format!("Cannot open given file: {}", f))?),
|
||||
None => Box::new(io::stdin()),
|
||||
};
|
||||
|
||||
const READAHEAD_BYTES: usize = 8;
|
||||
|
||||
let mut first_bytes: Vec<u8> = vec![0; READAHEAD_BYTES];
|
||||
let mut first_read = 0;
|
||||
|
||||
let format = match cmd.format {
|
||||
Some(format) => format,
|
||||
None => {
|
||||
first_read = instream.read(&mut first_bytes).map_err(|_| "Error reading from the file/stream.")?;
|
||||
match first_bytes[0] {
|
||||
0xf9 => DataFormat::Binary,
|
||||
_ => DataFormat::Hex,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let do_import = |bytes: Vec<u8>| {
|
||||
while client.queue_info().is_full() { sleep(Duration::from_secs(1)); }
|
||||
|
||||
let header: ::ethcore::header::Header = ::rlp::UntrustedRlp::new(&bytes).val_at(0)
|
||||
.map_err(|e| format!("Bad block: {}", e))?;
|
||||
|
||||
if client.best_block_header().number() >= header.number() { return Ok(()) }
|
||||
|
||||
if header.number() % 10000 == 0 {
|
||||
info!("#{}", header.number());
|
||||
}
|
||||
|
||||
match client.import_header(header) {
|
||||
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => {
|
||||
trace!("Skipping block already in chain.");
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(format!("Cannot import block: {:?}", e));
|
||||
},
|
||||
Ok(_) => {},
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
match format {
|
||||
DataFormat::Binary => {
|
||||
loop {
|
||||
let mut bytes = if first_read > 0 {first_bytes.clone()} else {vec![0; READAHEAD_BYTES]};
|
||||
let n = if first_read > 0 {
|
||||
first_read
|
||||
} else {
|
||||
instream.read(&mut bytes).map_err(|_| "Error reading from the file/stream.")?
|
||||
};
|
||||
if n == 0 { break; }
|
||||
first_read = 0;
|
||||
let s = PayloadInfo::from(&bytes).map_err(|e| format!("Invalid RLP in the file/stream: {:?}", e))?.total();
|
||||
bytes.resize(s, 0);
|
||||
instream.read_exact(&mut bytes[n..]).map_err(|_| "Error reading from the file/stream.")?;
|
||||
do_import(bytes)?;
|
||||
}
|
||||
}
|
||||
DataFormat::Hex => {
|
||||
for line in BufReader::new(instream).lines() {
|
||||
let s = line.map_err(|_| "Error reading from the file/stream.")?;
|
||||
let s = if first_read > 0 {from_utf8(&first_bytes).unwrap().to_owned() + &(s[..])} else {s};
|
||||
first_read = 0;
|
||||
let bytes = s.from_hex().map_err(|_| "Invalid hex in file/stream.")?;
|
||||
do_import(bytes)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
client.flush_queue();
|
||||
|
||||
let ms = timer.elapsed().as_milliseconds();
|
||||
let report = client.report();
|
||||
|
||||
info!("Import completed in {} seconds, {} headers, {} hdr/s",
|
||||
ms / 1000,
|
||||
report.blocks_imported,
|
||||
(report.blocks_imported * 1000) as u64 / ms,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_import(cmd: ImportBlockchain) -> Result<(), String> {
|
||||
let timer = Instant::now();
|
||||
|
||||
|
||||
@@ -356,7 +356,7 @@ usage! {
|
||||
or |c: &Config| otry!(c.vm).jit.clone(),
|
||||
|
||||
// -- Miscellaneous Options
|
||||
flag_ntp_server: String = "pool.ntp.org:123",
|
||||
flag_ntp_server: String = "none",
|
||||
or |c: &Config| otry!(c.misc).ntp_server.clone(),
|
||||
flag_logging: Option<String> = None,
|
||||
or |c: &Config| otry!(c.misc).logging.clone().map(Some),
|
||||
@@ -897,7 +897,7 @@ mod tests {
|
||||
flag_dapps_apis_all: None,
|
||||
|
||||
// -- Miscellaneous Options
|
||||
flag_ntp_server: "pool.ntp.org:123".into(),
|
||||
flag_ntp_server: "none".into(),
|
||||
flag_version: false,
|
||||
flag_logging: Some("own_tx=trace".into()),
|
||||
flag_log_file: Some("/var/log/parity.log".into()),
|
||||
|
||||
@@ -243,6 +243,7 @@ impl Configuration {
|
||||
check_seal: !self.args.flag_no_seal_check,
|
||||
with_color: logger_config.color,
|
||||
verifier_settings: self.verifier_settings(),
|
||||
light: self.args.flag_light,
|
||||
};
|
||||
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
||||
} else if self.args.cmd_export {
|
||||
@@ -1179,6 +1180,7 @@ mod tests {
|
||||
check_seal: true,
|
||||
with_color: !cfg!(windows),
|
||||
verifier_settings: Default::default(),
|
||||
light: false,
|
||||
})));
|
||||
}
|
||||
|
||||
@@ -1270,7 +1272,7 @@ mod tests {
|
||||
support_token_api: true
|
||||
}, UiConfiguration {
|
||||
enabled: true,
|
||||
ntp_server: "pool.ntp.org:123".into(),
|
||||
ntp_server: "none".into(),
|
||||
interface: "127.0.0.1".into(),
|
||||
port: 8180,
|
||||
hosts: Some(vec![]),
|
||||
@@ -1511,7 +1513,7 @@ mod tests {
|
||||
assert_eq!(conf0.directories().signer, "signer".to_owned());
|
||||
assert_eq!(conf0.ui_config(), UiConfiguration {
|
||||
enabled: true,
|
||||
ntp_server: "pool.ntp.org:123".into(),
|
||||
ntp_server: "none".into(),
|
||||
interface: "127.0.0.1".into(),
|
||||
port: 8180,
|
||||
hosts: Some(vec![]),
|
||||
@@ -1520,7 +1522,7 @@ mod tests {
|
||||
assert_eq!(conf1.directories().signer, "signer".to_owned());
|
||||
assert_eq!(conf1.ui_config(), UiConfiguration {
|
||||
enabled: true,
|
||||
ntp_server: "pool.ntp.org:123".into(),
|
||||
ntp_server: "none".into(),
|
||||
interface: "127.0.0.1".into(),
|
||||
port: 8180,
|
||||
hosts: Some(vec![]),
|
||||
@@ -1530,7 +1532,7 @@ mod tests {
|
||||
assert_eq!(conf2.directories().signer, "signer".to_owned());
|
||||
assert_eq!(conf2.ui_config(), UiConfiguration {
|
||||
enabled: true,
|
||||
ntp_server: "pool.ntp.org:123".into(),
|
||||
ntp_server: "none".into(),
|
||||
interface: "127.0.0.1".into(),
|
||||
port: 3123,
|
||||
hosts: Some(vec![]),
|
||||
@@ -1539,7 +1541,7 @@ mod tests {
|
||||
assert_eq!(conf3.directories().signer, "signer".to_owned());
|
||||
assert_eq!(conf3.ui_config(), UiConfiguration {
|
||||
enabled: true,
|
||||
ntp_server: "pool.ntp.org:123".into(),
|
||||
ntp_server: "none".into(),
|
||||
interface: "test".into(),
|
||||
port: 8180,
|
||||
hosts: Some(vec![]),
|
||||
|
||||
@@ -47,7 +47,7 @@ impl Default for Configuration {
|
||||
let data_dir = default_data_path();
|
||||
Configuration {
|
||||
enabled: true,
|
||||
ntp_server: "pool.ntp.org:123".into(),
|
||||
ntp_server: "none".into(),
|
||||
dapps_path: replace_home(&data_dir, "$BASE/dapps").into(),
|
||||
extra_dapps: vec![],
|
||||
extra_embed_on: vec![],
|
||||
@@ -114,7 +114,7 @@ impl ContractClient for LightRegistrar {
|
||||
tx: Transaction {
|
||||
nonce: self.client.engine().account_start_nonce(header.number()),
|
||||
action: Action::Call(address),
|
||||
gas: 50_000_000.into(),
|
||||
gas: 50_000.into(), // should be enough for all registry lookups. TODO: exponential backoff
|
||||
gas_price: 0.into(),
|
||||
value: 0.into(),
|
||||
data: data,
|
||||
|
||||
@@ -108,7 +108,7 @@ impl Default for UiConfiguration {
|
||||
fn default() -> Self {
|
||||
UiConfiguration {
|
||||
enabled: true && cfg!(feature = "ui-enabled"),
|
||||
ntp_server: "pool.ntp.org:123".into(),
|
||||
ntp_server: "none".into(),
|
||||
port: 8180,
|
||||
interface: "127.0.0.1".into(),
|
||||
hosts: Some(vec![]),
|
||||
|
||||
@@ -210,6 +210,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
|
||||
db_compaction: compaction,
|
||||
db_wal: cmd.wal,
|
||||
verify_full: true,
|
||||
check_seal: cmd.check_seal,
|
||||
};
|
||||
|
||||
config.queue.max_mem_use = cmd.cache_config.queue() as usize * 1024 * 1024;
|
||||
|
||||
Reference in New Issue
Block a user