Merge branch 'master' into td-evm-json
This commit is contained in:
commit
1253a5c577
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::io::{Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::str::{self, Lines};
|
use std::str::{self, Lines};
|
||||||
use std::net::{TcpStream, SocketAddr};
|
use std::net::{TcpStream, SocketAddr};
|
||||||
|
|
||||||
@ -83,9 +83,18 @@ pub fn request(address: &SocketAddr, request: &str) -> Response {
|
|||||||
req.set_read_timeout(Some(Duration::from_secs(2))).unwrap();
|
req.set_read_timeout(Some(Duration::from_secs(2))).unwrap();
|
||||||
req.write_all(request.as_bytes()).unwrap();
|
req.write_all(request.as_bytes()).unwrap();
|
||||||
|
|
||||||
let mut response = String::new();
|
let mut response = Vec::new();
|
||||||
let _ = req.read_to_string(&mut response);
|
loop {
|
||||||
|
let mut chunk = [0; 32 *1024];
|
||||||
|
match req.read(&mut chunk) {
|
||||||
|
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => break,
|
||||||
|
Err(err) => panic!("Unable to read response: {:?}", err),
|
||||||
|
Ok(0) => break,
|
||||||
|
Ok(read) => response.extend_from_slice(&chunk[..read]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = String::from_utf8_lossy(&response).into_owned();
|
||||||
let mut lines = response.lines();
|
let mut lines = response.lines();
|
||||||
let status = lines.next().expect("Expected a response").to_owned();
|
let status = lines.next().expect("Expected a response").to_owned();
|
||||||
let headers_raw = read_block(&mut lines, false);
|
let headers_raw = read_block(&mut lines, false);
|
||||||
|
@ -269,7 +269,7 @@ impl AccountProvider {
|
|||||||
|
|
||||||
/// Checks whether an account with a given address is present.
|
/// Checks whether an account with a given address is present.
|
||||||
pub fn has_account(&self, address: Address) -> Result<bool, Error> {
|
pub fn has_account(&self, address: Address) -> Result<bool, Error> {
|
||||||
Ok(self.accounts()?.iter().any(|&a| a == address))
|
Ok(self.sstore.account_ref(&address).is_ok() && !self.blacklisted_accounts.contains(&address))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns addresses of all accounts.
|
/// Returns addresses of all accounts.
|
||||||
|
@ -647,10 +647,6 @@ impl Miner {
|
|||||||
condition: Option<TransactionCondition>,
|
condition: Option<TransactionCondition>,
|
||||||
transaction_queue: &mut BanningTransactionQueue,
|
transaction_queue: &mut BanningTransactionQueue,
|
||||||
) -> Vec<Result<TransactionImportResult, Error>> {
|
) -> Vec<Result<TransactionImportResult, Error>> {
|
||||||
let accounts = self.accounts.as_ref()
|
|
||||||
.and_then(|provider| provider.accounts().ok())
|
|
||||||
.map(|accounts| accounts.into_iter().collect::<HashSet<_>>());
|
|
||||||
|
|
||||||
let best_block_header = client.best_block_header().decode();
|
let best_block_header = client.best_block_header().decode();
|
||||||
let insertion_time = client.chain_info().best_block_number;
|
let insertion_time = client.chain_info().best_block_number;
|
||||||
|
|
||||||
@ -669,8 +665,8 @@ impl Miner {
|
|||||||
Err(e)
|
Err(e)
|
||||||
},
|
},
|
||||||
Ok(transaction) => {
|
Ok(transaction) => {
|
||||||
let origin = accounts.as_ref().and_then(|accounts| {
|
let origin = self.accounts.as_ref().and_then(|accounts| {
|
||||||
match accounts.contains(&transaction.sender()) {
|
match accounts.has_account(transaction.sender()).unwrap_or(false) {
|
||||||
true => Some(TransactionOrigin::Local),
|
true => Some(TransactionOrigin::Local),
|
||||||
false => None,
|
false => None,
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,13 @@ impl<T> DiskDirectory<T> where T: KeyFileManager {
|
|||||||
Ok(hasher.finish())
|
Ok(hasher.finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn last_modification_date(&self) -> Result<u64, Error> {
|
||||||
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
let duration = fs::metadata(&self.path)?.modified()?.duration_since(UNIX_EPOCH).unwrap_or(Duration::default());
|
||||||
|
let timestamp = duration.as_secs() ^ (duration.subsec_nanos() as u64);
|
||||||
|
Ok(timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
/// all accounts found in keys directory
|
/// all accounts found in keys directory
|
||||||
fn files_content(&self) -> Result<HashMap<PathBuf, SafeAccount>, Error> {
|
fn files_content(&self) -> Result<HashMap<PathBuf, SafeAccount>, Error> {
|
||||||
// it's not done using one iterator cause
|
// it's not done using one iterator cause
|
||||||
@ -226,7 +233,7 @@ impl<T> KeyDirectory for DiskDirectory<T> where T: KeyFileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn unique_repr(&self) -> Result<u64, Error> {
|
fn unique_repr(&self) -> Result<u64, Error> {
|
||||||
self.files_hash()
|
self.last_modification_date()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ use std::collections::{BTreeMap, HashMap};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
|
use std::time::{Instant, Duration};
|
||||||
|
|
||||||
use crypto::KEY_ITERATIONS;
|
use crypto::KEY_ITERATIONS;
|
||||||
use random::Random;
|
use random::Random;
|
||||||
@ -28,6 +29,8 @@ use presale::PresaleWallet;
|
|||||||
use json::{self, Uuid, OpaqueKeyFile};
|
use json::{self, Uuid, OpaqueKeyFile};
|
||||||
use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret};
|
use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret};
|
||||||
|
|
||||||
|
const REFRESH_TIME_SEC: u64 = 5;
|
||||||
|
|
||||||
/// Accounts store.
|
/// Accounts store.
|
||||||
pub struct EthStore {
|
pub struct EthStore {
|
||||||
store: EthMultiStore,
|
store: EthMultiStore,
|
||||||
@ -245,7 +248,12 @@ pub struct EthMultiStore {
|
|||||||
// order lock: cache, then vaults
|
// order lock: cache, then vaults
|
||||||
cache: RwLock<BTreeMap<StoreAccountRef, Vec<SafeAccount>>>,
|
cache: RwLock<BTreeMap<StoreAccountRef, Vec<SafeAccount>>>,
|
||||||
vaults: Mutex<HashMap<String, Box<VaultKeyDirectory>>>,
|
vaults: Mutex<HashMap<String, Box<VaultKeyDirectory>>>,
|
||||||
dir_hash: Mutex<Option<u64>>,
|
timestamp: Mutex<Timestamp>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Timestamp {
|
||||||
|
dir_hash: Option<u64>,
|
||||||
|
last_checked: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EthMultiStore {
|
impl EthMultiStore {
|
||||||
@ -261,20 +269,27 @@ impl EthMultiStore {
|
|||||||
vaults: Mutex::new(HashMap::new()),
|
vaults: Mutex::new(HashMap::new()),
|
||||||
iterations: iterations,
|
iterations: iterations,
|
||||||
cache: Default::default(),
|
cache: Default::default(),
|
||||||
dir_hash: Default::default(),
|
timestamp: Mutex::new(Timestamp {
|
||||||
|
dir_hash: None,
|
||||||
|
last_checked: Instant::now(),
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
store.reload_accounts()?;
|
store.reload_accounts()?;
|
||||||
Ok(store)
|
Ok(store)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reload_if_changed(&self) -> Result<(), Error> {
|
fn reload_if_changed(&self) -> Result<(), Error> {
|
||||||
let mut last_dir_hash = self.dir_hash.lock();
|
let mut last_timestamp = self.timestamp.lock();
|
||||||
|
let now = Instant::now();
|
||||||
|
if (now - last_timestamp.last_checked) > Duration::from_secs(REFRESH_TIME_SEC) {
|
||||||
let dir_hash = Some(self.dir.unique_repr()?);
|
let dir_hash = Some(self.dir.unique_repr()?);
|
||||||
if *last_dir_hash == dir_hash {
|
last_timestamp.last_checked = now;
|
||||||
|
if last_timestamp.dir_hash == dir_hash {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
self.reload_accounts()?;
|
self.reload_accounts()?;
|
||||||
*last_dir_hash = dir_hash;
|
last_timestamp.dir_hash = dir_hash;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,11 +470,11 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error> {
|
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error> {
|
||||||
|
use std::collections::Bound;
|
||||||
self.reload_if_changed()?;
|
self.reload_if_changed()?;
|
||||||
self.cache.read().keys()
|
let cache = self.cache.read();
|
||||||
.find(|r| &r.address == address)
|
let mut r = cache.range((Bound::Included(*address), Bound::Included(*address)));
|
||||||
.cloned()
|
r.next().ok_or(Error::InvalidAccount).map(|(k, _)| k.clone())
|
||||||
.ok_or(Error::InvalidAccount)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error> {
|
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error> {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use ethkey::{Address, Message, Signature, Secret, Public};
|
use ethkey::{Address, Message, Signature, Secret, Public};
|
||||||
use Error;
|
use Error;
|
||||||
use json::{Uuid, OpaqueKeyFile};
|
use json::{Uuid, OpaqueKeyFile};
|
||||||
@ -32,12 +33,24 @@ pub enum SecretVaultRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Stored account reference
|
/// Stored account reference
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, Ord)]
|
||||||
pub struct StoreAccountRef {
|
pub struct StoreAccountRef {
|
||||||
/// Vault reference
|
|
||||||
pub vault: SecretVaultRef,
|
|
||||||
/// Account address
|
/// Account address
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
|
/// Vault reference
|
||||||
|
pub vault: SecretVaultRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for StoreAccountRef {
|
||||||
|
fn partial_cmp(&self, other: &StoreAccountRef) -> Option<Ordering> {
|
||||||
|
Some(self.address.cmp(&other.address).then_with(|| self.vault.cmp(&other.vault)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::borrow::Borrow<Address> for StoreAccountRef {
|
||||||
|
fn borrow(&self) -> &Address {
|
||||||
|
&self.address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simple Secret Store API
|
/// Simple Secret Store API
|
||||||
|
Loading…
Reference in New Issue
Block a user