Merge branch 'master' into jsonrpc2
This commit is contained in:
commit
2748e770e4
12
CONTRIBUTING.md
Normal file
12
CONTRIBUTING.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Contributing to Parity
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing to Parity, you agree that your contributions will be
|
||||||
|
licensed under the [BSD License](LICENSE).
|
||||||
|
|
||||||
|
At the top of every source code file you alter, after the initial
|
||||||
|
licence section, please append a second section that reads:
|
||||||
|
|
||||||
|
Portions contributed by YOUR NAME are hereby placed under the BSD licence.
|
||||||
|
|
@ -12,7 +12,7 @@ rustc-serialize = "0.3"
|
|||||||
docopt = "0.6"
|
docopt = "0.6"
|
||||||
docopt_macros = "0.6"
|
docopt_macros = "0.6"
|
||||||
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
|
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
|
||||||
clippy = "0.0.37"
|
clippy = "0.0.41"
|
||||||
ethcore-util = { path = "util" }
|
ethcore-util = { path = "util" }
|
||||||
ethcore = { path = "ethcore" }
|
ethcore = { path = "ethcore" }
|
||||||
ethsync = { path = "sync" }
|
ethsync = { path = "sync" }
|
||||||
|
@ -18,7 +18,7 @@ ethcore-util = { path = "../util" }
|
|||||||
evmjit = { path = "../evmjit", optional = true }
|
evmjit = { path = "../evmjit", optional = true }
|
||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
num_cpus = "0.2"
|
num_cpus = "0.2"
|
||||||
clippy = "0.0.37"
|
clippy = "0.0.41"
|
||||||
crossbeam = "0.1.5"
|
crossbeam = "0.1.5"
|
||||||
lazy_static = "0.1"
|
lazy_static = "0.1"
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ pub struct Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const HISTORY: u64 = 1000;
|
const HISTORY: u64 = 1000;
|
||||||
const CLIENT_DB_VER_STR: &'static str = "2.0";
|
const CLIENT_DB_VER_STR: &'static str = "2.1";
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
/// Create a new client with given spec and DB path.
|
/// Create a new client with given spec and DB path.
|
||||||
@ -319,12 +319,11 @@ impl Client {
|
|||||||
self.report.write().unwrap().accrue_block(&block);
|
self.report.write().unwrap().accrue_block(&block);
|
||||||
trace!(target: "client", "Imported #{} ({})", header.number(), header.hash());
|
trace!(target: "client", "Imported #{} ({})", header.number(), header.hash());
|
||||||
ret += 1;
|
ret += 1;
|
||||||
|
|
||||||
if self.block_queue.read().unwrap().queue_info().is_empty() {
|
|
||||||
io.send(NetworkIoMessage::User(SyncMessage::BlockVerified)).unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.block_queue.write().unwrap().mark_as_good(&good_blocks);
|
self.block_queue.write().unwrap().mark_as_good(&good_blocks);
|
||||||
|
if !good_blocks.is_empty() && self.block_queue.read().unwrap().queue_info().is_empty() {
|
||||||
|
io.send(NetworkIoMessage::User(SyncMessage::BlockVerified)).unwrap();
|
||||||
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,12 +352,12 @@ impl Client {
|
|||||||
self.chain.write().unwrap().configure_cache(pref_cache_size, max_cache_size);
|
self.chain.write().unwrap().configure_cache(pref_cache_size, max_cache_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_hash(&self, id: BlockId) -> Option<H256> {
|
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> {
|
||||||
match id {
|
match id {
|
||||||
BlockId::Hash(hash) => Some(hash),
|
BlockId::Hash(hash) => Some(hash),
|
||||||
BlockId::Number(number) => self.chain.read().unwrap().block_hash(number),
|
BlockId::Number(number) => chain.block_hash(number),
|
||||||
BlockId::Earliest => self.chain.read().unwrap().block_hash(0),
|
BlockId::Earliest => chain.block_hash(0),
|
||||||
BlockId::Latest => Some(self.chain.read().unwrap().best_block_hash())
|
BlockId::Latest => Some(chain.best_block_hash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,12 +373,14 @@ impl Client {
|
|||||||
|
|
||||||
impl BlockChainClient for Client {
|
impl BlockChainClient for Client {
|
||||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||||
self.block_hash(id).and_then(|hash| self.chain.read().unwrap().block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
|
let chain = self.chain.read().unwrap();
|
||||||
|
Self::block_hash(&chain, id).and_then(|hash| chain.block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||||
self.block_hash(id).and_then(|hash| {
|
let chain = self.chain.read().unwrap();
|
||||||
self.chain.read().unwrap().block(&hash).map(|bytes| {
|
Self::block_hash(&chain, id).and_then(|hash| {
|
||||||
|
chain.block(&hash).map(|bytes| {
|
||||||
let rlp = Rlp::new(&bytes);
|
let rlp = Rlp::new(&bytes);
|
||||||
let mut body = RlpStream::new_list(2);
|
let mut body = RlpStream::new_list(2);
|
||||||
body.append_raw(rlp.at(1).as_raw(), 1);
|
body.append_raw(rlp.at(1).as_raw(), 1);
|
||||||
@ -390,21 +391,24 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn block(&self, id: BlockId) -> Option<Bytes> {
|
fn block(&self, id: BlockId) -> Option<Bytes> {
|
||||||
self.block_hash(id).and_then(|hash| {
|
let chain = self.chain.read().unwrap();
|
||||||
self.chain.read().unwrap().block(&hash)
|
Self::block_hash(&chain, id).and_then(|hash| {
|
||||||
|
chain.block(&hash)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_status(&self, id: BlockId) -> BlockStatus {
|
fn block_status(&self, id: BlockId) -> BlockStatus {
|
||||||
match self.block_hash(id) {
|
let chain = self.chain.read().unwrap();
|
||||||
Some(ref hash) if self.chain.read().unwrap().is_known(hash) => BlockStatus::InChain,
|
match Self::block_hash(&chain, id) {
|
||||||
|
Some(ref hash) if chain.is_known(hash) => BlockStatus::InChain,
|
||||||
Some(hash) => self.block_queue.read().unwrap().block_status(&hash),
|
Some(hash) => self.block_queue.read().unwrap().block_status(&hash),
|
||||||
None => BlockStatus::Unknown
|
None => BlockStatus::Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_total_difficulty(&self, id: BlockId) -> Option<U256> {
|
fn block_total_difficulty(&self, id: BlockId) -> Option<U256> {
|
||||||
self.block_hash(id).and_then(|hash| self.chain.read().unwrap().block_details(&hash)).map(|d| d.total_difficulty)
|
let chain = self.chain.read().unwrap();
|
||||||
|
Self::block_hash(&chain, id).and_then(|hash| chain.block_details(&hash)).map(|d| d.total_difficulty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn code(&self, address: &Address) -> Option<Bytes> {
|
fn code(&self, address: &Address) -> Option<Bytes> {
|
||||||
@ -412,13 +416,14 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
|
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
|
||||||
|
let chain = self.chain.read().unwrap();
|
||||||
match id {
|
match id {
|
||||||
TransactionId::Hash(ref hash) => self.chain.read().unwrap().transaction_address(hash),
|
TransactionId::Hash(ref hash) => chain.transaction_address(hash),
|
||||||
TransactionId::Location(id, index) => self.block_hash(id).map(|hash| TransactionAddress {
|
TransactionId::Location(id, index) => Self::block_hash(&chain, id).map(|hash| TransactionAddress {
|
||||||
block_hash: hash,
|
block_hash: hash,
|
||||||
index: index
|
index: index
|
||||||
})
|
})
|
||||||
}.and_then(|address| self.chain.read().unwrap().transaction(&address))
|
}.and_then(|address| chain.transaction(&address))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> {
|
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> {
|
||||||
|
@ -24,7 +24,7 @@ pub mod ethash;
|
|||||||
/// Export the denominations module.
|
/// Export the denominations module.
|
||||||
pub mod denominations;
|
pub mod denominations;
|
||||||
|
|
||||||
pub use self::ethash::*;
|
pub use self::ethash::{Ethash};
|
||||||
pub use self::denominations::*;
|
pub use self::denominations::*;
|
||||||
|
|
||||||
use super::spec::*;
|
use super::spec::*;
|
||||||
|
@ -688,7 +688,7 @@ function run_installer()
|
|||||||
info "- Run tests with:"
|
info "- Run tests with:"
|
||||||
info " ${b}cargo test --release --features ethcore/json-tests -p ethcore${reset}"
|
info " ${b}cargo test --release --features ethcore/json-tests -p ethcore${reset}"
|
||||||
info "- Install the client with:"
|
info "- Install the client with:"
|
||||||
info " ${b}sudo cp parity/target/release/parity${reset}"
|
info " ${b}sudo cp parity/target/release/parity${reset} /usr/local/bin"
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,17 +55,19 @@ Parity. Ethereum Client.
|
|||||||
Copyright 2015, 2016 Ethcore (UK) Limited
|
Copyright 2015, 2016 Ethcore (UK) Limited
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
parity [options] [ <enode>... ]
|
parity [options] [ --no-bootstrap | <enode>... ]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file
|
--chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file
|
||||||
or frontier, mainnet, morden, or testnet [default: frontier].
|
or frontier, mainnet, morden, or testnet [default: frontier].
|
||||||
-d --db-path PATH Specify the database & configuration directory path [default: $HOME/.parity]
|
-d --db-path PATH Specify the database & configuration directory path [default: $HOME/.parity]
|
||||||
|
|
||||||
|
--no-bootstrap Don't bother trying to connect to any nodes initially.
|
||||||
--listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304].
|
--listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304].
|
||||||
--public-address URL Specify the IP/port on which peers may connect [default: 0.0.0.0:30304].
|
--public-address URL Specify the IP/port on which peers may connect [default: 0.0.0.0:30304].
|
||||||
--address URL Equivalent to --listen-address URL --public-address URL.
|
--address URL Equivalent to --listen-address URL --public-address URL.
|
||||||
--upnp Use UPnP to try to figure out the correct network settings.
|
--upnp Use UPnP to try to figure out the correct network settings.
|
||||||
|
--node-key KEY Specify node secret key as hex string.
|
||||||
|
|
||||||
--cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384].
|
--cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384].
|
||||||
--cache-max-size BYTES Specify the maximum size of the blockchain cache in bytes [default: 262144].
|
--cache-max-size BYTES Specify the maximum size of the blockchain cache in bytes [default: 262144].
|
||||||
@ -76,7 +78,7 @@ Options:
|
|||||||
-l --logging LOGGING Specify the logging level.
|
-l --logging LOGGING Specify the logging level.
|
||||||
-v --version Show information about version.
|
-v --version Show information about version.
|
||||||
-h --help Show this screen.
|
-h --help Show this screen.
|
||||||
", flag_cache_pref_size: usize, flag_cache_max_size: usize, flag_address: Option<String>);
|
", flag_cache_pref_size: usize, flag_cache_max_size: usize, flag_address: Option<String>, flag_node_key: Option<String>);
|
||||||
|
|
||||||
fn setup_log(init: &str) {
|
fn setup_log(init: &str) {
|
||||||
let mut builder = LogBuilder::new();
|
let mut builder = LogBuilder::new();
|
||||||
@ -144,9 +146,11 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init_nodes(&self, spec: &Spec) -> Vec<String> {
|
fn init_nodes(&self, spec: &Spec) -> Vec<String> {
|
||||||
match self.args.arg_enode.len() {
|
if self.args.flag_no_bootstrap { Vec::new() } else {
|
||||||
0 => spec.nodes().clone(),
|
match self.args.arg_enode.len() {
|
||||||
_ => self.args.arg_enode.clone(),
|
0 => spec.nodes().clone(),
|
||||||
|
_ => self.args.arg_enode.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +206,7 @@ fn main() {
|
|||||||
let (listen, public) = conf.net_addresses();
|
let (listen, public) = conf.net_addresses();
|
||||||
net_settings.listen_address = listen;
|
net_settings.listen_address = listen;
|
||||||
net_settings.public_address = public;
|
net_settings.public_address = public;
|
||||||
|
net_settings.use_secret = conf.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).expect("Invalid key string"));
|
||||||
|
|
||||||
// Build client
|
// Build client
|
||||||
let mut service = ClientService::start(spec, net_settings, &Path::new(&conf.path())).unwrap();
|
let mut service = ClientService::start(spec, net_settings, &Path::new(&conf.path())).unwrap();
|
||||||
@ -256,7 +261,7 @@ impl Informant {
|
|||||||
let sync_info = sync.status();
|
let sync_info = sync.status();
|
||||||
|
|
||||||
if let (_, &Some(ref last_cache_info), &Some(ref last_report)) = (self.chain_info.read().unwrap().deref(), self.cache_info.read().unwrap().deref(), self.report.read().unwrap().deref()) {
|
if let (_, &Some(ref last_cache_info), &Some(ref last_report)) = (self.chain_info.read().unwrap().deref(), self.cache_info.read().unwrap().deref(), self.report.read().unwrap().deref()) {
|
||||||
println!("[ {} {} ]---[ {} blk/s | {} tx/s | {} gas/s //··· {}/{} peers, {} downloaded, {}+{} queued ···// {} ({}) bl {} ({}) ex ]",
|
println!("[ #{} {} ]---[ {} blk/s | {} tx/s | {} gas/s //··· {}/{} peers, #{}, {}+{} queued ···// {} ({}) bl {} ({}) ex ]",
|
||||||
chain_info.best_block_number,
|
chain_info.best_block_number,
|
||||||
chain_info.best_block_hash,
|
chain_info.best_block_hash,
|
||||||
(report.blocks_imported - last_report.blocks_imported) / dur,
|
(report.blocks_imported - last_report.blocks_imported) / dur,
|
||||||
@ -265,7 +270,7 @@ impl Informant {
|
|||||||
|
|
||||||
sync_info.num_active_peers,
|
sync_info.num_active_peers,
|
||||||
sync_info.num_peers,
|
sync_info.num_peers,
|
||||||
sync_info.blocks_received,
|
sync_info.last_imported_block_number.unwrap_or(chain_info.best_block_number),
|
||||||
queue_info.unverified_queue_size,
|
queue_info.unverified_queue_size,
|
||||||
queue_info.verified_queue_size,
|
queue_info.verified_queue_size,
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@ jsonrpc-http-server = "1.1"
|
|||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore = { path = "../ethcore" }
|
ethcore = { path = "../ethcore" }
|
||||||
ethsync = { path = "../sync" }
|
ethsync = { path = "../sync" }
|
||||||
clippy = "0.0.37"
|
clippy = "0.0.41"
|
||||||
target_info = "0.1.0"
|
target_info = "0.1.0"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
|
@ -10,7 +10,7 @@ authors = ["Ethcore <admin@ethcore.io"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore = { path = ".." }
|
ethcore = { path = ".." }
|
||||||
clippy = "0.0.37"
|
clippy = "0.0.41"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
time = "0.1.34"
|
time = "0.1.34"
|
||||||
|
@ -583,7 +583,7 @@ impl ChainSync {
|
|||||||
trace!(target: "sync", "Starting sync with better chain");
|
trace!(target: "sync", "Starting sync with better chain");
|
||||||
self.request_headers_by_hash(io, peer_id, &peer_latest, 1, 0, false);
|
self.request_headers_by_hash(io, peer_id, &peer_latest, 1, 0, false);
|
||||||
}
|
}
|
||||||
else if self.state == SyncState::Blocks {
|
else if self.state == SyncState::Blocks && io.chain().block_status(BlockId::Hash(peer_latest)) == BlockStatus::Unknown {
|
||||||
self.request_blocks(io, peer_id);
|
self.request_blocks(io, peer_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,7 +607,7 @@ impl ChainSync {
|
|||||||
|
|
||||||
if self.have_common_block && !self.headers.is_empty() && self.headers.range_iter().next().unwrap().0 == self.current_base_block() + 1 {
|
if self.have_common_block && !self.headers.is_empty() && self.headers.range_iter().next().unwrap().0 == self.current_base_block() + 1 {
|
||||||
for (start, ref items) in self.headers.range_iter() {
|
for (start, ref items) in self.headers.range_iter() {
|
||||||
if needed_bodies.len() > MAX_BODIES_TO_REQUEST {
|
if needed_bodies.len() >= MAX_BODIES_TO_REQUEST {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let mut index: BlockNumber = 0;
|
let mut index: BlockNumber = 0;
|
||||||
@ -654,7 +654,7 @@ impl ChainSync {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut block = prev;
|
let mut block = prev;
|
||||||
while block < next && headers.len() <= MAX_HEADERS_TO_REQUEST {
|
while block < next && headers.len() < MAX_HEADERS_TO_REQUEST {
|
||||||
if !self.downloading_headers.contains(&(block as BlockNumber)) {
|
if !self.downloading_headers.contains(&(block as BlockNumber)) {
|
||||||
headers.push(block as BlockNumber);
|
headers.push(block as BlockNumber);
|
||||||
self.downloading_headers.insert(block as BlockNumber);
|
self.downloading_headers.insert(block as BlockNumber);
|
||||||
@ -1045,7 +1045,7 @@ impl ChainSync {
|
|||||||
|
|
||||||
fn check_resume(&mut self, io: &mut SyncIo) {
|
fn check_resume(&mut self, io: &mut SyncIo) {
|
||||||
if !io.chain().queue_info().is_full() && self.state == SyncState::Waiting {
|
if !io.chain().queue_info().is_full() && self.state == SyncState::Waiting {
|
||||||
self.state = SyncState::Idle;
|
self.state = SyncState::Blocks;
|
||||||
self.continue_sync(io);
|
self.continue_sync(io);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ pub trait RangeCollection<K, V> {
|
|||||||
fn get_tail(&mut self, key: &K) -> Range<K>;
|
fn get_tail(&mut self, key: &K) -> Range<K>;
|
||||||
/// Remove all elements < `start` in the range that contains `start` - 1
|
/// Remove all elements < `start` in the range that contains `start` - 1
|
||||||
fn remove_head(&mut self, start: &K);
|
fn remove_head(&mut self, start: &K);
|
||||||
/// Remove all elements >= `start` in the range that contains `start`
|
/// Remove all elements >= `start` in the range that contains `start`
|
||||||
fn remove_tail(&mut self, start: &K);
|
fn remove_tail(&mut self, start: &K);
|
||||||
/// Remove all elements >= `tail`
|
/// Remove all elements >= `tail`
|
||||||
fn insert_item(&mut self, key: K, value: V);
|
fn insert_item(&mut self, key: K, value: V);
|
||||||
@ -168,6 +168,7 @@ impl<K, V> RangeCollection<K, V> for Vec<(K, Vec<V>)> where K: Ord + PartialEq +
|
|||||||
fn insert_item(&mut self, key: K, value: V) {
|
fn insert_item(&mut self, key: K, value: V) {
|
||||||
assert!(!self.have_item(&key));
|
assert!(!self.have_item(&key));
|
||||||
|
|
||||||
|
// todo: fix warning
|
||||||
let lower = match self.binary_search_by(|&(k, _)| k.cmp(&key).reverse()) {
|
let lower = match self.binary_search_by(|&(k, _)| k.cmp(&key).reverse()) {
|
||||||
Ok(index) => index,
|
Ok(index) => index,
|
||||||
Err(index) => index,
|
Err(index) => index,
|
||||||
|
@ -26,7 +26,7 @@ crossbeam = "0.2"
|
|||||||
slab = { git = "https://github.com/arkpar/slab.git" }
|
slab = { git = "https://github.com/arkpar/slab.git" }
|
||||||
sha3 = { path = "sha3" }
|
sha3 = { path = "sha3" }
|
||||||
serde = "0.6.7"
|
serde = "0.6.7"
|
||||||
clippy = "0.0.37"
|
clippy = "0.0.41"
|
||||||
json-tests = { path = "json-tests" }
|
json-tests = { path = "json-tests" }
|
||||||
target_info = "0.1.0"
|
target_info = "0.1.0"
|
||||||
igd = "0.4.2"
|
igd = "0.4.2"
|
||||||
|
@ -47,10 +47,10 @@ impl Clone for JournalDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const LAST_ERA_KEY : [u8; 4] = [ b'l', b'a', b's', b't' ];
|
const LATEST_ERA_KEY : [u8; 4] = [ b'l', b'a', b's', b't' ];
|
||||||
const VERSION_KEY : [u8; 4] = [ b'j', b'v', b'e', b'r' ];
|
const VERSION_KEY : [u8; 4] = [ b'j', b'v', b'e', b'r' ];
|
||||||
|
|
||||||
const DB_VERSION: u32 = 1;
|
const DB_VERSION: u32 = 2;
|
||||||
|
|
||||||
impl JournalDB {
|
impl JournalDB {
|
||||||
/// Create a new instance given a `backing` database.
|
/// Create a new instance given a `backing` database.
|
||||||
@ -87,7 +87,7 @@ impl JournalDB {
|
|||||||
|
|
||||||
/// Check if this database has any commits
|
/// Check if this database has any commits
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.backing.get(&LAST_ERA_KEY).expect("Low level database error").is_none()
|
self.backing.get(&LATEST_ERA_KEY).expect("Low level database error").is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commit all recent insert operations and historical removals from the old era
|
/// Commit all recent insert operations and historical removals from the old era
|
||||||
@ -144,6 +144,7 @@ impl JournalDB {
|
|||||||
r.append(&inserts);
|
r.append(&inserts);
|
||||||
r.append(&removes);
|
r.append(&removes);
|
||||||
try!(batch.put(&last, r.as_raw()));
|
try!(batch.put(&last, r.as_raw()));
|
||||||
|
try!(batch.put(&LATEST_ERA_KEY, &encode(&now)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply old commits' details
|
// apply old commits' details
|
||||||
@ -181,7 +182,6 @@ impl JournalDB {
|
|||||||
try!(batch.delete(&h));
|
try!(batch.delete(&h));
|
||||||
deletes += 1;
|
deletes += 1;
|
||||||
}
|
}
|
||||||
try!(batch.put(&LAST_ERA_KEY, &encode(&end_era)));
|
|
||||||
trace!("JournalDB: delete journal for time #{}.{}, (canon was {}): {} entries", end_era, index, canon_id, deletes);
|
trace!("JournalDB: delete journal for time #{}.{}, (canon was {}): {} entries", end_era, index, canon_id, deletes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,8 +228,8 @@ impl JournalDB {
|
|||||||
|
|
||||||
fn read_counters(db: &DB) -> HashMap<H256, i32> {
|
fn read_counters(db: &DB) -> HashMap<H256, i32> {
|
||||||
let mut res = HashMap::new();
|
let mut res = HashMap::new();
|
||||||
if let Some(val) = db.get(&LAST_ERA_KEY).expect("Low-level database error.") {
|
if let Some(val) = db.get(&LATEST_ERA_KEY).expect("Low-level database error.") {
|
||||||
let mut era = decode::<u64>(&val) + 1;
|
let mut era = decode::<u64>(&val);
|
||||||
loop {
|
loop {
|
||||||
let mut index = 0usize;
|
let mut index = 0usize;
|
||||||
while let Some(rlp_data) = db.get({
|
while let Some(rlp_data) = db.get({
|
||||||
@ -245,10 +245,10 @@ impl JournalDB {
|
|||||||
}
|
}
|
||||||
index += 1;
|
index += 1;
|
||||||
};
|
};
|
||||||
if index == 0 {
|
if index == 0 || era == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
era += 1;
|
era -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trace!("Recovered {} counters", res.len());
|
trace!("Recovered {} counters", res.len());
|
||||||
@ -426,4 +426,32 @@ mod tests {
|
|||||||
jdb.commit(2, &b"2a".sha3(), Some((1, b"1a".sha3()))).unwrap();
|
jdb.commit(2, &b"2a".sha3(), Some((1, b"1a".sha3()))).unwrap();
|
||||||
assert!(jdb.exists(&foo));
|
assert!(jdb.exists(&foo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reopen() {
|
||||||
|
use rocksdb::DB;
|
||||||
|
let mut dir = ::std::env::temp_dir();
|
||||||
|
dir.push(H32::random().hex());
|
||||||
|
|
||||||
|
let foo = {
|
||||||
|
let mut jdb = JournalDB::new(DB::open_default(dir.to_str().unwrap()).unwrap());
|
||||||
|
// history is 1
|
||||||
|
let foo = jdb.insert(b"foo");
|
||||||
|
jdb.commit(0, &b"0".sha3(), None).unwrap();
|
||||||
|
foo
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut jdb = JournalDB::new(DB::open_default(dir.to_str().unwrap()).unwrap());
|
||||||
|
jdb.remove(&foo);
|
||||||
|
jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut jdb = JournalDB::new(DB::open_default(dir.to_str().unwrap()).unwrap());
|
||||||
|
assert!(jdb.exists(&foo));
|
||||||
|
jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap();
|
||||||
|
assert!(!jdb.exists(&foo));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +412,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
|||||||
let mut to_kill = Vec::new();
|
let mut to_kill = Vec::new();
|
||||||
for e in self.connections.write().unwrap().iter_mut() {
|
for e in self.connections.write().unwrap().iter_mut() {
|
||||||
if let ConnectionEntry::Session(ref mut s) = *e.lock().unwrap().deref_mut() {
|
if let ConnectionEntry::Session(ref mut s) = *e.lock().unwrap().deref_mut() {
|
||||||
if !s.keep_alive() {
|
if !s.keep_alive(io) {
|
||||||
s.disconnect(DisconnectReason::PingTimeout);
|
s.disconnect(DisconnectReason::PingTimeout);
|
||||||
to_kill.push(s.token());
|
to_kill.push(s.token());
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ impl Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Keep this session alive. Returns false if ping timeout happened
|
/// Keep this session alive. Returns false if ping timeout happened
|
||||||
pub fn keep_alive(&mut self) -> bool {
|
pub fn keep_alive<Message>(&mut self, io: &IoContext<Message>) -> bool where Message: Send + Sync + Clone {
|
||||||
let timed_out = if let Some(pong) = self.pong_time_ns {
|
let timed_out = if let Some(pong) = self.pong_time_ns {
|
||||||
pong - self.ping_time_ns > PING_TIMEOUT_SEC * 1000_000_000
|
pong - self.ping_time_ns > PING_TIMEOUT_SEC * 1000_000_000
|
||||||
} else {
|
} else {
|
||||||
@ -191,6 +191,7 @@ impl Session {
|
|||||||
if let Err(e) = self.send_ping() {
|
if let Err(e) = self.send_ping() {
|
||||||
debug!("Error sending ping message: {:?}", e);
|
debug!("Error sending ping message: {:?}", e);
|
||||||
}
|
}
|
||||||
|
io.update_registration(self.token()).unwrap_or_else(|e| debug!(target: "net", "Session registration error: {:?}", e));
|
||||||
}
|
}
|
||||||
!timed_out
|
!timed_out
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user