Merge pull request #845 from ethcore/beta-staging
Merge fixes from master to beta
This commit is contained in:
commit
fe313677b3
36
Cargo.lock
generated
36
Cargo.lock
generated
@ -1,18 +1,18 @@
|
||||
[root]
|
||||
name = "parity"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"clippy 0.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ctrlc 1.1.1 (git+https://github.com/tomusdrw/rust-ctrlc.git)",
|
||||
"daemonize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.0.0",
|
||||
"ethcore 1.0.1",
|
||||
"ethcore-devtools 1.0.0",
|
||||
"ethcore-rpc 1.0.0",
|
||||
"ethcore-util 1.0.0",
|
||||
"ethcore-rpc 1.0.1",
|
||||
"ethcore-util 1.0.1",
|
||||
"ethminer 1.0.0",
|
||||
"ethsync 1.0.0",
|
||||
"ethsync 1.0.1",
|
||||
"fdlimit 0.1.0",
|
||||
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -208,14 +208,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"clippy 0.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethash 1.0.0",
|
||||
"ethcore-devtools 1.0.0",
|
||||
"ethcore-util 1.0.0",
|
||||
"ethcore-util 1.0.1",
|
||||
"ethjson 0.1.0",
|
||||
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -235,14 +235,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-rpc"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"clippy 0.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethash 1.0.0",
|
||||
"ethcore 1.0.0",
|
||||
"ethcore-util 1.0.0",
|
||||
"ethcore 1.0.1",
|
||||
"ethcore-util 1.0.1",
|
||||
"ethminer 1.0.0",
|
||||
"ethsync 1.0.0",
|
||||
"ethsync 1.0.1",
|
||||
"jsonrpc-core 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-http-server 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -256,7 +256,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-util"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bigint 0.1.0",
|
||||
@ -293,7 +293,7 @@ dependencies = [
|
||||
name = "ethjson"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-util 1.0.0",
|
||||
"ethcore-util 1.0.1",
|
||||
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -307,8 +307,8 @@ version = "1.0.0"
|
||||
dependencies = [
|
||||
"clippy 0.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.0.0",
|
||||
"ethcore-util 1.0.0",
|
||||
"ethcore 1.0.1",
|
||||
"ethcore-util 1.0.1",
|
||||
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -317,12 +317,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethsync"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"clippy 0.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.0.0",
|
||||
"ethcore-util 1.0.0",
|
||||
"ethcore 1.0.1",
|
||||
"ethcore-util 1.0.1",
|
||||
"ethminer 1.0.0",
|
||||
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Ethcore client."
|
||||
name = "parity"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
build = "build.rs"
|
||||
|
@ -3,7 +3,7 @@ description = "Ethcore library"
|
||||
homepage = "http://ethcore.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -105,6 +105,9 @@ pub trait MinerService : Send + Sync {
|
||||
/// Submit `seal` as a valid solution for the header of `pow_hash`.
|
||||
/// Will check the seal, but not actually insert the block into the chain.
|
||||
fn submit_seal(&self, chain: &BlockChainClient, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error>;
|
||||
|
||||
/// Query pending transactions for hash
|
||||
fn transaction(&self, hash: &H256) -> Option<SignedTransaction>;
|
||||
}
|
||||
|
||||
/// Mining status
|
||||
|
@ -165,6 +165,11 @@ impl MinerService for Miner {
|
||||
transaction_queue.pending_hashes()
|
||||
}
|
||||
|
||||
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||
let queue = self.transaction_queue.lock().unwrap();
|
||||
queue.find(hash)
|
||||
}
|
||||
|
||||
fn update_sealing(&self, chain: &BlockChainClient) {
|
||||
if self.sealing_enabled.load(atomic::Ordering::Relaxed) {
|
||||
let current_no = chain.chain_info().best_block_number;
|
||||
|
@ -505,6 +505,11 @@ impl TransactionQueue {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Finds transaction in the queue by hash (if any)
|
||||
pub fn find(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||
match self.by_hash.get(hash) { Some(transaction_ref) => Some(transaction_ref.transaction.clone()), None => None }
|
||||
}
|
||||
|
||||
/// Removes all elements (in any state) from the queue
|
||||
pub fn clear(&mut self) {
|
||||
self.current.clear();
|
||||
|
@ -39,6 +39,8 @@ extern crate rpassword;
|
||||
#[cfg(feature = "rpc")]
|
||||
extern crate ethcore_rpc as rpc;
|
||||
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::fs::File;
|
||||
use std::net::{SocketAddr, IpAddr};
|
||||
use std::env;
|
||||
use std::process::exit;
|
||||
@ -89,6 +91,11 @@ Protocol Options:
|
||||
[default: $HOME/.web3/keys].
|
||||
--identity NAME Specify your node's name.
|
||||
|
||||
Account Options:
|
||||
--unlock ACCOUNT Unlock ACCOUNT for the duration of the execution.
|
||||
--password FILE Provide a file containing a password for unlocking
|
||||
an account.
|
||||
|
||||
Networking Options:
|
||||
--port PORT Override the port on which the node should listen
|
||||
[default: 30303].
|
||||
@ -176,6 +183,8 @@ struct Args {
|
||||
flag_chain: String,
|
||||
flag_db_path: String,
|
||||
flag_identity: String,
|
||||
flag_unlock: Vec<String>,
|
||||
flag_password: Vec<String>,
|
||||
flag_cache: Option<usize>,
|
||||
flag_keys_path: String,
|
||||
flag_bootnodes: Option<String>,
|
||||
@ -490,6 +499,28 @@ impl Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
fn account_service(&self) -> AccountService {
|
||||
// Secret Store
|
||||
let passwords = self.args.flag_password.iter().flat_map(|filename| {
|
||||
BufReader::new(&File::open(filename).unwrap_or_else(|_| die!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)))
|
||||
.lines()
|
||||
.map(|l| l.unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
let account_service = AccountService::new();
|
||||
for d in &self.args.flag_unlock {
|
||||
let a = Address::from_str(clean_0x(&d)).unwrap_or_else(|_| {
|
||||
die!("{}: Invalid address for --unlock. Must be 40 hex characters, without the 0x at the beginning.", d)
|
||||
});
|
||||
if passwords.iter().find(|p| account_service.unlock_account_no_expire(&a, p).is_ok()).is_none() {
|
||||
die!("No password given to unlock account {}. Pass the password using `--password`.", a);
|
||||
}
|
||||
}
|
||||
account_service
|
||||
}
|
||||
|
||||
#[cfg_attr(feature="dev", allow(useless_format))]
|
||||
fn execute_client(&self) {
|
||||
// Setup panic handler
|
||||
@ -504,6 +535,9 @@ impl Configuration {
|
||||
let net_settings = self.net_settings(&spec);
|
||||
let sync_config = self.sync_config(&spec);
|
||||
|
||||
// Secret Store
|
||||
let account_service = Arc::new(self.account_service());
|
||||
|
||||
// Build client
|
||||
let mut service = ClientService::start(self.client_config(), spec, net_settings, &Path::new(&self.path())).unwrap();
|
||||
panic_handler.forward_from(&service);
|
||||
@ -519,9 +553,6 @@ impl Configuration {
|
||||
// Sync
|
||||
let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone());
|
||||
|
||||
// Secret Store
|
||||
let account_service = Arc::new(AccountService::new());
|
||||
|
||||
// Setup rpc
|
||||
if self.args.flag_jsonrpc || self.args.flag_rpc {
|
||||
let url = format!("{}:{}",
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Ethcore jsonrpc"
|
||||
name = "ethcore-rpc"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Ethcore <admin@ethcore.io"]
|
||||
build = "build.rs"
|
||||
|
@ -348,7 +348,13 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
|
||||
fn transaction_by_hash(&self, params: Params) -> Result<Value, Error> {
|
||||
from_params::<(H256,)>(params)
|
||||
.and_then(|(hash,)| self.transaction(TransactionId::Hash(hash)))
|
||||
.and_then(|(hash,)| {
|
||||
let miner = take_weak!(self.miner);
|
||||
match miner.transaction(&hash) {
|
||||
Some(pending_tx) => to_value(&Transaction::from(pending_tx)),
|
||||
None => self.transaction(TransactionId::Hash(hash))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn transaction_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||
@ -476,11 +482,11 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
Ok(_) => to_value(&hash),
|
||||
Err(e) => {
|
||||
warn!("Error sending transaction: {:?}", e);
|
||||
to_value(&U256::zero())
|
||||
to_value(&H256::zero())
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => { to_value(&U256::zero()) }
|
||||
Err(_) => { to_value(&H256::zero()) }
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -503,11 +509,11 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
Ok(_) => to_value(&hash),
|
||||
Err(e) => {
|
||||
warn!("Error sending transaction: {:?}", e);
|
||||
to_value(&U256::zero())
|
||||
to_value(&H256::zero())
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => { to_value(&U256::zero()) }
|
||||
Err(_) => { to_value(&H256::zero()) }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ struct EthTester {
|
||||
pub client: Arc<TestBlockChainClient>,
|
||||
pub sync: Arc<TestSyncProvider>,
|
||||
_accounts_provider: Arc<TestAccountProvider>,
|
||||
_miner: Arc<TestMinerService>,
|
||||
miner: Arc<TestMinerService>,
|
||||
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
|
||||
pub io: IoHandler,
|
||||
}
|
||||
@ -73,7 +73,7 @@ impl Default for EthTester {
|
||||
client: client,
|
||||
sync: sync,
|
||||
_accounts_provider: ap,
|
||||
_miner: miner,
|
||||
miner: miner,
|
||||
io: io,
|
||||
hashrates: hashrates,
|
||||
}
|
||||
@ -258,6 +258,27 @@ fn rpc_eth_transaction_count_by_number_pending() {
|
||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_eth_pending_transaction_by_hash() {
|
||||
use util::*;
|
||||
use ethcore::transaction::*;
|
||||
|
||||
let tester = EthTester::default();
|
||||
{
|
||||
let tx: SignedTransaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
|
||||
tester.miner.pending_transactions.lock().unwrap().insert(H256::zero(), tx);
|
||||
}
|
||||
|
||||
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x01","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x00","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"value":"0x0a"},"id":1}"#;
|
||||
let request = r#"{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "eth_getTransactionByHash",
|
||||
"params": ["0x0000000000000000000000000000000000000000000000000000000000000000"],
|
||||
"id": 1
|
||||
}"#;
|
||||
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn rpc_eth_uncle_count_by_block_hash() {
|
||||
|
@ -30,6 +30,8 @@ pub struct TestMinerService {
|
||||
pub imported_transactions: RwLock<Vec<H256>>,
|
||||
/// Latest closed block.
|
||||
pub latest_closed_block: Mutex<Option<ClosedBlock>>,
|
||||
/// Pre-existed pending transactions
|
||||
pub pending_transactions: Mutex<HashMap<H256, SignedTransaction>>,
|
||||
}
|
||||
|
||||
impl Default for TestMinerService {
|
||||
@ -37,6 +39,7 @@ impl Default for TestMinerService {
|
||||
TestMinerService {
|
||||
imported_transactions: RwLock::new(Vec::new()),
|
||||
latest_closed_block: Mutex::new(None),
|
||||
pending_transactions: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,6 +76,10 @@ impl MinerService for TestMinerService {
|
||||
&self.latest_closed_block
|
||||
}
|
||||
|
||||
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||
self.pending_transactions.lock().unwrap().get(hash).and_then(|tx_ref| Some(tx_ref.clone()))
|
||||
}
|
||||
|
||||
/// Submit `seal` as a valid solution for the header of `pow_hash`.
|
||||
/// Will check the seal, but not actually insert the block into the chain.
|
||||
fn submit_seal(&self, _chain: &BlockChainClient, _pow_hash: H256, _seal: Vec<Bytes>) -> Result<(), Error> { unimplemented!(); }
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use util::numbers::*;
|
||||
use ethcore::transaction::{LocalizedTransaction, Action};
|
||||
use ethcore::transaction::{LocalizedTransaction, Action, SignedTransaction};
|
||||
use v1::types::{Bytes, OptionalValue};
|
||||
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
@ -58,6 +58,27 @@ impl From<LocalizedTransaction> for Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SignedTransaction> for Transaction {
|
||||
fn from(t: SignedTransaction) -> Transaction {
|
||||
Transaction {
|
||||
hash: t.hash(),
|
||||
nonce: t.nonce,
|
||||
block_hash: OptionalValue::Null,
|
||||
block_number: OptionalValue::Null,
|
||||
transaction_index: OptionalValue::Null,
|
||||
from: t.sender().unwrap(),
|
||||
to: match t.action {
|
||||
Action::Create => OptionalValue::Null,
|
||||
Action::Call(ref address) => OptionalValue::Value(address.clone())
|
||||
},
|
||||
value: t.value,
|
||||
gas_price: t.gas_price,
|
||||
gas: t.gas,
|
||||
input: Bytes::new(t.data.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -102,4 +102,27 @@ mod tests {
|
||||
nonce: None,
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transaction_request_deserialize_test() {
|
||||
let s = r#"{
|
||||
"from":"0xb5f7502a2807cb23615c7456055e1d65b2508625",
|
||||
"to":"0x895d32f2db7d01ebb50053f9e48aacf26584fe40",
|
||||
"data":"0x8595bab1",
|
||||
"gas":"0x2fd618",
|
||||
"gasPrice":"0x0ba43b7400"
|
||||
}"#;
|
||||
|
||||
let deserialized: TransactionRequest = serde_json::from_str(s).unwrap();
|
||||
|
||||
assert_eq!(deserialized, TransactionRequest {
|
||||
from: Address::from_str("b5f7502a2807cb23615c7456055e1d65b2508625").unwrap(),
|
||||
to: Some(Address::from_str("895d32f2db7d01ebb50053f9e48aacf26584fe40").unwrap()),
|
||||
gas_price: Some(U256::from_str("0ba43b7400").unwrap()),
|
||||
gas: Some(U256::from_str("2fd618").unwrap()),
|
||||
value: None,
|
||||
data: Some(Bytes::new(vec![0x85, 0x95, 0xba, 0xb1])),
|
||||
nonce: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Ethcore blockchain sync"
|
||||
name = "ethsync"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Ethcore <admin@ethcore.io"]
|
||||
|
||||
|
@ -3,7 +3,7 @@ description = "Ethcore utility library"
|
||||
homepage = "http://ethcore.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore-util"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
@ -75,7 +75,8 @@ pub struct SecretStore {
|
||||
|
||||
struct AccountUnlock {
|
||||
secret: H256,
|
||||
expires: DateTime<UTC>,
|
||||
/// expiration datetime (None - never)
|
||||
expires: Option<DateTime<UTC>>,
|
||||
}
|
||||
|
||||
/// Basic account management trait
|
||||
@ -148,6 +149,11 @@ impl AccountService {
|
||||
pub fn tick(&self) {
|
||||
self.secret_store.write().unwrap().collect_garbage();
|
||||
}
|
||||
|
||||
/// Unlocks account for use (no expiration of unlock)
|
||||
pub fn unlock_account_no_expire(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> {
|
||||
self.secret_store.write().unwrap().unlock_account_with_expiration(account, pass, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -226,14 +232,23 @@ impl SecretStore {
|
||||
|
||||
/// Unlocks account for use
|
||||
pub fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> {
|
||||
self.unlock_account_with_expiration(account, pass, Some(UTC::now() + Duration::minutes(20)))
|
||||
}
|
||||
|
||||
/// Unlocks account for use (no expiration of unlock)
|
||||
pub fn unlock_account_no_expire(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> {
|
||||
self.unlock_account_with_expiration(account, pass, None)
|
||||
}
|
||||
|
||||
fn unlock_account_with_expiration(&self, account: &Address, pass: &str, expiration: Option<DateTime<UTC>>) -> Result<(), EncryptedHashMapError> {
|
||||
let secret_id = try!(self.account(&account).ok_or(EncryptedHashMapError::UnknownIdentifier));
|
||||
let secret = try!(self.get(&secret_id, pass));
|
||||
{
|
||||
let mut write_lock = self.unlocks.write().unwrap();
|
||||
let mut unlock = write_lock.entry(*account)
|
||||
.or_insert_with(|| AccountUnlock { secret: secret, expires: UTC::now() });
|
||||
.or_insert_with(|| AccountUnlock { secret: secret, expires: Some(UTC::now()) });
|
||||
unlock.secret = secret;
|
||||
unlock.expires = UTC::now() + Duration::minutes(20);
|
||||
unlock.expires = expiration;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -277,7 +292,7 @@ impl SecretStore {
|
||||
self.directory.collect_garbage();
|
||||
let utc = UTC::now();
|
||||
let expired_addresses = garbage_lock.iter()
|
||||
.filter(|&(_, unlock)| unlock.expires < utc)
|
||||
.filter(|&(_, unlock)| match unlock.expires { Some(ref expire_val) => expire_val < &utc, _ => false })
|
||||
.map(|(address, _)| address.clone()).collect::<Vec<Address>>();
|
||||
|
||||
for expired in expired_addresses { garbage_lock.remove(&expired); }
|
||||
@ -629,7 +644,7 @@ mod tests {
|
||||
let ss_rw = svc.secret_store.write().unwrap();
|
||||
let mut ua_rw = ss_rw.unlocks.write().unwrap();
|
||||
let entry = ua_rw.entry(address);
|
||||
if let Entry::Occupied(mut occupied) = entry { occupied.get_mut().expires = UTC::now() - Duration::minutes(1); }
|
||||
if let Entry::Occupied(mut occupied) = entry { occupied.get_mut().expires = Some(UTC::now() - Duration::minutes(1)) }
|
||||
}
|
||||
|
||||
svc.tick();
|
||||
|
Loading…
Reference in New Issue
Block a user