secret store separated from util (#1304)

* bump rust-crypto

* initial version of account provider utilizing secret store

* update lazy_static to latest version

* AccountProvider accounts method

* new AccountProvider tests in progress

* basic tests for new AccountProvider

* ethcore compiles with new account provider and secret store

* ethcore-rpc build now compiling with new AccountProvider

* most rpc tests passing with new accounts_provider

* fixed basic_authority tests

* fixed eth_transaction_count rpc test

* fixed mocked/eth.rs tests

* fixed personal tests

* fixed personal signer rpc tests

* removed warnings

* parity compiling fine with new sstore

* fixed import direction

* do not unlock temporarily when we have the password

* removed TODO in account import

* display warning on auto account import failure

* fixed compiling of ethstore on windows

* ethstore as a part of parity repo

* added ethkey
This commit is contained in:
Marek Kotewicz
2016-06-20 00:10:34 +02:00
committed by Gav Wood
parent 08522eec37
commit 6b074e8fb2
84 changed files with 4027 additions and 2682 deletions

View File

@@ -26,7 +26,7 @@ use jsonrpc_core::*;
use util::numbers::*;
use util::sha3::*;
use util::rlp::{encode, decode, UntrustedRlp, View};
use util::keys::store::AccountProvider;
use ethcore::account_provider::AccountProvider;
use ethcore::client::{MiningBlockChainClient, BlockID, TransactionID, UncleID};
use ethcore::block::IsBlock;
use ethcore::views::*;
@@ -41,32 +41,30 @@ use v1::impls::{dispatch_transaction, error_codes};
use serde;
/// Eth rpc implementation.
pub struct EthClient<C, S, A, M, EM> where
pub struct EthClient<C, S, M, EM> where
C: MiningBlockChainClient,
S: SyncProvider,
A: AccountProvider,
M: MinerService,
EM: ExternalMinerService {
client: Weak<C>,
sync: Weak<S>,
accounts: Weak<A>,
accounts: Weak<AccountProvider>,
miner: Weak<M>,
external_miner: Arc<EM>,
seed_compute: Mutex<SeedHashCompute>,
allow_pending_receipt_query: bool,
}
impl<C, S, A, M, EM> EthClient<C, S, A, M, EM> where
impl<C, S, M, EM> EthClient<C, S, M, EM> where
C: MiningBlockChainClient,
S: SyncProvider,
A: AccountProvider,
M: MinerService,
EM: ExternalMinerService {
/// Creates new EthClient.
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>, em: &Arc<EM>, allow_pending_receipt_query: bool)
-> EthClient<C, S, A, M, EM> {
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<AccountProvider>, miner: &Arc<M>, em: &Arc<EM>, allow_pending_receipt_query: bool)
-> EthClient<C, S, M, EM> {
EthClient {
client: Arc::downgrade(client),
sync: Arc::downgrade(sync),
@@ -236,10 +234,9 @@ fn no_work_err() -> Error {
}
}
impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
C: MiningBlockChainClient + 'static,
S: SyncProvider + 'static,
A: AccountProvider + 'static,
M: MinerService + 'static,
EM: ExternalMinerService + 'static {
@@ -306,10 +303,7 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
fn accounts(&self, _: Params) -> Result<Value, Error> {
let store = take_weak!(self.accounts);
match store.accounts() {
Ok(account_list) => to_value(&account_list),
Err(_) => Err(Error::internal_error())
}
to_value(&store.accounts())
}
fn block_number(&self, params: Params) -> Result<Value, Error> {

View File

@@ -21,12 +21,11 @@ use jsonrpc_core::*;
use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient;
use util::numbers::*;
use util::keys::store::AccountProvider;
use ethcore::account_provider::AccountProvider;
use v1::helpers::{SigningQueue, ConfirmationsQueue};
use v1::traits::EthSigning;
use v1::types::{TransactionRequest, Bytes};
use v1::impls::{sign_and_dispatch, error_codes};
use v1::impls::sign_and_dispatch;
/// Implementation of functions that require signing when no trusted signer is used.
pub struct EthSigningQueueClient<M: MinerService> {
@@ -79,22 +78,20 @@ impl<M: MinerService + 'static> EthSigning for EthSigningQueueClient<M> {
}
/// Implementation of functions that require signing when no trusted signer is used.
pub struct EthSigningUnsafeClient<C, A, M> where
pub struct EthSigningUnsafeClient<C, M> where
C: MiningBlockChainClient,
A: AccountProvider,
M: MinerService {
client: Weak<C>,
accounts: Weak<A>,
accounts: Weak<AccountProvider>,
miner: Weak<M>,
}
impl<C, A, M> EthSigningUnsafeClient<C, A, M> where
impl<C, M> EthSigningUnsafeClient<C, M> where
C: MiningBlockChainClient,
A: AccountProvider,
M: MinerService {
/// Creates new EthClient.
pub fn new(client: &Arc<C>, accounts: &Arc<A>, miner: &Arc<M>)
pub fn new(client: &Arc<C>, accounts: &Arc<AccountProvider>, miner: &Arc<M>)
-> Self {
EthSigningUnsafeClient {
client: Arc::downgrade(client),
@@ -104,35 +101,24 @@ impl<C, A, M> EthSigningUnsafeClient<C, A, M> where
}
}
impl<C, A, M> EthSigning for EthSigningUnsafeClient<C, A, M> where
impl<C, M> EthSigning for EthSigningUnsafeClient<C, M> where
C: MiningBlockChainClient + 'static,
A: AccountProvider + 'static,
M: MinerService + 'static {
fn sign(&self, params: Params) -> Result<Value, Error> {
from_params::<(Address, H256)>(params).and_then(|(addr, msg)| {
take_weak!(self.accounts).sign(&addr, &msg)
.map(|v| to_value(&v))
.unwrap_or_else(|e| Err(account_locked(format!("Error: {:?}", e))))
to_value(&take_weak!(self.accounts).sign(addr, msg).unwrap_or(H520::zero()))
})
}
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
from_params::<(TransactionRequest, )>(params)
.and_then(|(request, )| {
let accounts = take_weak!(self.accounts);
match accounts.account_secret(&request.from) {
Ok(secret) => sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret),
Err(e) => Err(account_locked(format!("Error: {:?}", e))),
let sender = request.from;
match sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, &*take_weak!(self.accounts), sender) {
Ok(hash) => to_value(&hash),
_ => to_value(&H256::zero()),
}
})
}
}
fn account_locked(data: String) -> Error {
Error {
code: ErrorCode::ServerError(error_codes::ACCOUNT_LOCKED),
message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(),
data: Some(Value::String(data)),
}
}

View File

@@ -58,6 +58,7 @@ use ethcore::error::Error as EthcoreError;
use ethcore::miner::{AccountDetails, MinerService};
use ethcore::client::MiningBlockChainClient;
use ethcore::transaction::{Action, SignedTransaction, Transaction};
use ethcore::account_provider::{AccountProvider, Error as AccountError};
use util::numbers::*;
use util::rlp::encode;
use util::bytes::ToPretty;
@@ -88,29 +89,58 @@ fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: SignedT
.and_then(|_| to_value(&hash))
}
fn sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionRequest, secret: H256) -> Result<Value, Error>
fn prepare_transaction<C, M>(client: &C, miner: &M, request: TransactionRequest) -> Transaction where C: MiningBlockChainClient, M: MinerService {
Transaction {
nonce: request.nonce
.or_else(|| miner
.last_nonce(&request.from)
.map(|nonce| nonce + U256::one()))
.unwrap_or_else(|| client.latest_nonce(&request.from)),
action: request.to.map_or(Action::Create, Action::Call),
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()),
value: request.value.unwrap_or_else(U256::zero),
data: request.data.map_or_else(Vec::new, |b| b.to_vec()),
}
}
fn unlock_sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionRequest, account_provider: &AccountProvider, address: Address, password: String) -> Result<Value, Error>
where C: MiningBlockChainClient, M: MinerService {
let signed_transaction = {
Transaction {
nonce: request.nonce
.or_else(|| miner
.last_nonce(&request.from)
.map(|nonce| nonce + U256::one()))
.unwrap_or_else(|| client.latest_nonce(&request.from)),
action: request.to.map_or(Action::Create, Action::Call),
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()),
value: request.value.unwrap_or_else(U256::zero),
data: request.data.map_or_else(Vec::new, |b| b.to_vec()),
}.sign(&secret)
let t = prepare_transaction(client, miner, request);
let hash = t.hash();
let signature = try!(account_provider.sign_with_password(address, password, hash).map_err(signing_error));
t.with_signature(signature)
};
trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty());
dispatch_transaction(&*client, &*miner, signed_transaction)
}
fn sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionRequest, account_provider: &AccountProvider, address: Address) -> Result<Value, Error>
where C: MiningBlockChainClient, M: MinerService {
let signed_transaction = {
let t = prepare_transaction(client, miner, request);
let hash = t.hash();
let signature = try!(account_provider.sign(address, hash).map_err(signing_error));
t.with_signature(signature)
};
trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty());
dispatch_transaction(&*client, &*miner, signed_transaction)
}
fn signing_error(error: AccountError) -> Error {
Error {
code: ErrorCode::ServerError(error_codes::ACCOUNT_LOCKED),
message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(),
data: Some(Value::String(format!("{:?}", error))),
}
}
fn transaction_error(error: EthcoreError) -> Error {
use ethcore::error::TransactionError::*;

View File

@@ -19,25 +19,23 @@ use std::sync::{Arc, Weak};
use jsonrpc_core::*;
use v1::traits::Personal;
use v1::types::TransactionRequest;
use v1::impls::sign_and_dispatch;
use util::keys::store::AccountProvider;
use v1::impls::unlock_sign_and_dispatch;
use ethcore::account_provider::AccountProvider;
use util::numbers::*;
use ethcore::client::MiningBlockChainClient;
use ethcore::miner::MinerService;
/// Account management (personal) rpc implementation.
pub struct PersonalClient<A, C, M>
where A: AccountProvider, C: MiningBlockChainClient, M: MinerService {
accounts: Weak<A>,
pub struct PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
accounts: Weak<AccountProvider>,
client: Weak<C>,
miner: Weak<M>,
signer_port: Option<u16>,
}
impl<A, C, M> PersonalClient<A, C, M>
where A: AccountProvider, C: MiningBlockChainClient, M: MinerService {
impl<C, M> PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
/// Creates new PersonalClient
pub fn new(store: &Arc<A>, client: &Arc<C>, miner: &Arc<M>, signer_port: Option<u16>) -> Self {
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>, miner: &Arc<M>, signer_port: Option<u16>) -> Self {
PersonalClient {
accounts: Arc::downgrade(store),
client: Arc::downgrade(client),
@@ -47,8 +45,7 @@ impl<A, C, M> PersonalClient<A, C, M>
}
}
impl<A: 'static, C: 'static, M: 'static> Personal for PersonalClient<A, C, M>
where A: AccountProvider, C: MiningBlockChainClient, M: MinerService {
impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
fn signer_enabled(&self, _: Params) -> Result<Value, Error> {
self.signer_port
@@ -58,10 +55,7 @@ impl<A: 'static, C: 'static, M: 'static> Personal for PersonalClient<A, C, M>
fn accounts(&self, _: Params) -> Result<Value, Error> {
let store = take_weak!(self.accounts);
match store.accounts() {
Ok(account_list) => to_value(&account_list),
Err(_) => Err(Error::internal_error())
}
to_value(&store.accounts())
}
fn new_account(&self, params: Params) -> Result<Value, Error> {
@@ -80,7 +74,7 @@ impl<A: 'static, C: 'static, M: 'static> Personal for PersonalClient<A, C, M>
from_params::<(Address, String, u64)>(params).and_then(
|(account, account_pass, _)|{
let store = take_weak!(self.accounts);
match store.unlock_account_temp(&account, &account_pass) {
match store.unlock_account_temporarily(account, account_pass) {
Ok(_) => Ok(Value::Bool(true)),
Err(_) => Ok(Value::Bool(false)),
}
@@ -90,10 +84,12 @@ impl<A: 'static, C: 'static, M: 'static> Personal for PersonalClient<A, C, M>
fn sign_and_send_transaction(&self, params: Params) -> Result<Value, Error> {
from_params::<(TransactionRequest, String)>(params)
.and_then(|(request, password)| {
let sender = request.from;
let accounts = take_weak!(self.accounts);
match accounts.locked_account_secret(&request.from, &password) {
Ok(secret) => sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret),
Err(_) => to_value(&H256::zero()),
match unlock_sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, &*accounts, sender, password) {
Ok(hash) => to_value(&hash),
_ => to_value(&H256::zero()),
}
})
}

View File

@@ -20,27 +20,25 @@ use std::sync::{Arc, Weak};
use jsonrpc_core::*;
use v1::traits::PersonalSigner;
use v1::types::TransactionModification;
use v1::impls::sign_and_dispatch;
use v1::impls::unlock_sign_and_dispatch;
use v1::helpers::{SigningQueue, ConfirmationsQueue};
use util::keys::store::AccountProvider;
use ethcore::account_provider::AccountProvider;
use util::numbers::*;
use ethcore::client::MiningBlockChainClient;
use ethcore::miner::MinerService;
/// Transactions confirmation (personal) rpc implementation.
pub struct SignerClient<A, C, M>
where A: AccountProvider, C: MiningBlockChainClient, M: MinerService {
pub struct SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
queue: Weak<ConfirmationsQueue>,
accounts: Weak<A>,
accounts: Weak<AccountProvider>,
client: Weak<C>,
miner: Weak<M>,
}
impl<A: 'static, C: 'static, M: 'static> SignerClient<A, C, M>
where A: AccountProvider, C: MiningBlockChainClient, M: MinerService {
impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
/// Create new instance of signer client.
pub fn new(store: &Arc<A>, client: &Arc<C>, miner: &Arc<M>, queue: &Arc<ConfirmationsQueue>) -> Self {
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>, miner: &Arc<M>, queue: &Arc<ConfirmationsQueue>) -> Self {
SignerClient {
queue: Arc::downgrade(queue),
accounts: Arc::downgrade(store),
@@ -50,8 +48,7 @@ impl<A: 'static, C: 'static, M: 'static> SignerClient<A, C, M>
}
}
impl<A: 'static, C: 'static, M: 'static> PersonalSigner for SignerClient<A, C, M>
where A: AccountProvider, C: MiningBlockChainClient, M: MinerService {
impl<C: 'static, M: 'static> PersonalSigner for SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
fn transactions_to_confirm(&self, _params: Params) -> Result<Value, Error> {
let queue = take_weak!(self.queue);
@@ -71,13 +68,15 @@ impl<A: 'static, C: 'static, M: 'static> PersonalSigner for SignerClient<A, C, M
if let Some(gas_price) = modification.gas_price {
request.gas_price = Some(gas_price);
}
match accounts.locked_account_secret(&request.from, &pass) {
Ok(secret) => {
let res = sign_and_dispatch(&*client, &*miner, request, secret);
queue.request_confirmed(id, res.clone());
Some(res)
let sender = request.from;
match unlock_sign_and_dispatch(&*client, &*miner, request, &*accounts, sender, pass) {
Ok(hash) => {
queue.request_confirmed(id, Ok(hash.clone()));
Some(to_value(&hash))
},
Err(_) => None
_ => None
}
})
.unwrap_or_else(|| {

View File

@@ -15,7 +15,6 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! rpc integration tests.
use std::collections::HashMap;
use std::sync::Arc;
use std::str::FromStr;
@@ -26,12 +25,11 @@ use ethcore::block::Block;
use ethcore::views::BlockView;
use ethcore::ethereum;
use ethcore::miner::{MinerService, ExternalMiner, Miner};
use ethcore::account_provider::AccountProvider;
use devtools::RandomTempPath;
use util::Hashable;
use util::io::IoChannel;
use util::hash::{Address, H256};
use util::numbers::U256;
use util::keys::{AccountProvider, TestAccount, TestAccountProvider};
use util::{U256, H256};
use jsonrpc_core::IoHandler;
use ethjson::blockchain::BlockChain;
@@ -39,11 +37,8 @@ use v1::traits::eth::{Eth, EthSigning};
use v1::impls::{EthClient, EthSigningUnsafeClient};
use v1::tests::helpers::{TestSyncProvider, Config};
fn account_provider() -> Arc<TestAccountProvider> {
let mut accounts = HashMap::new();
accounts.insert(Address::from(1), TestAccount::new("test"));
let ap = TestAccountProvider::new(accounts);
Arc::new(ap)
fn account_provider() -> Arc<AccountProvider> {
Arc::new(AccountProvider::transient_provider())
}
fn sync_provider() -> Arc<TestSyncProvider> {
@@ -70,7 +65,7 @@ fn make_spec(chain: &BlockChain) -> Spec {
struct EthTester {
client: Arc<Client>,
_miner: Arc<MinerService>,
accounts: Arc<TestAccountProvider>,
accounts: Arc<AccountProvider>,
handler: IoHandler,
}
@@ -226,15 +221,10 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
fn eth_transaction_count() {
use util::crypto::Secret;
let address = Address::from_str("faa34835af5c2ea724333018a515fbb7d5bc0b33").unwrap();
let secret = Secret::from_str("8a283037bb19c4fed7b1c569e40c7dcff366165eb869110a1b11532963eb9cb2").unwrap();
let tester = EthTester::from_spec_provider(|| Spec::load(TRANSACTION_COUNT_SPEC));
tester.accounts.accounts.write().unwrap().insert(address, TestAccount {
unlocked: false,
password: "123".into(),
secret: secret
});
let address = tester.accounts.insert_account(secret, "").unwrap();
tester.accounts.unlock_account_permanently(address, "".into()).unwrap();
let req_before = r#"{
"jsonrpc": "2.0",

View File

@@ -20,7 +20,7 @@ use std::sync::{Arc, RwLock};
use jsonrpc_core::IoHandler;
use util::hash::{Address, H256, FixedHash};
use util::numbers::{Uint, U256};
use util::keys::{AccountProvider, TestAccount, TestAccountProvider};
use ethcore::account_provider::AccountProvider;
use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionID};
use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
use ethcore::receipt::LocalizedReceipt;
@@ -36,11 +36,8 @@ fn blockchain_client() -> Arc<TestBlockChainClient> {
Arc::new(client)
}
fn accounts_provider() -> Arc<TestAccountProvider> {
let mut accounts = HashMap::new();
accounts.insert(Address::from(1), TestAccount::new("test"));
let ap = TestAccountProvider::new(accounts);
Arc::new(ap)
fn accounts_provider() -> Arc<AccountProvider> {
Arc::new(AccountProvider::transient_provider())
}
fn sync_provider() -> Arc<TestSyncProvider> {
@@ -57,7 +54,7 @@ fn miner_service() -> Arc<TestMinerService> {
struct EthTester {
pub client: Arc<TestBlockChainClient>,
pub sync: Arc<TestSyncProvider>,
pub accounts_provider: Arc<TestAccountProvider>,
pub accounts_provider: Arc<AccountProvider>,
miner: Arc<TestMinerService>,
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
pub io: IoHandler,
@@ -169,8 +166,9 @@ fn rpc_eth_sign() {
let tester = EthTester::default();
let account = tester.accounts_provider.new_account("abcd").unwrap();
tester.accounts_provider.unlock_account_permanently(account, "abcd".into()).unwrap();
let message = H256::from("0x0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f");
let signed = tester.accounts_provider.sign(&account, &message).unwrap();
let signed = tester.accounts_provider.sign(account, message).unwrap();
let req = r#"{
"jsonrpc": "2.0",
@@ -233,10 +231,13 @@ fn rpc_eth_gas_price() {
#[test]
fn rpc_eth_accounts() {
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#;
let tester = EthTester::default();
let address = tester.accounts_provider.new_account("").unwrap();
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:?}", address) + r#""],"id":1}"#;
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
}
#[test]
@@ -558,12 +559,9 @@ fn rpc_eth_estimate_gas_default_block() {
#[test]
fn rpc_eth_send_transaction() {
let account = TestAccount::new("123");
let address = account.address();
let secret = account.secret.clone();
let tester = EthTester::default();
tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account);
let address = tester.accounts_provider.new_account("").unwrap();
tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap();
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_sendTransaction",
@@ -584,7 +582,9 @@ fn rpc_eth_send_transaction() {
action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
value: U256::from(0x9184e72au64),
data: vec![]
}.sign(&secret);
};
let signature = tester.accounts_provider.sign(address, t.hash()).unwrap();
let t = t.with_signature(signature);
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
@@ -599,7 +599,9 @@ fn rpc_eth_send_transaction() {
action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
value: U256::from(0x9184e72au64),
data: vec![]
}.sign(&secret);
};
let signature = tester.accounts_provider.sign(address, t.hash()).unwrap();
let t = t.with_signature(signature);
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
@@ -610,7 +612,7 @@ fn rpc_eth_send_transaction() {
fn rpc_eth_send_raw_transaction() {
let tester = EthTester::default();
let address = tester.accounts_provider.new_account("abcd").unwrap();
let secret = tester.accounts_provider.account_secret(&address).unwrap();
tester.accounts_provider.unlock_account_permanently(address, "abcd".into()).unwrap();
let t = Transaction {
nonce: U256::zero(),
@@ -619,7 +621,9 @@ fn rpc_eth_send_raw_transaction() {
action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
value: U256::from(0x9184e72au64),
data: vec![]
}.sign(&secret);
};
let signature = tester.accounts_provider.sign(address, t.hash()).unwrap();
let t = t.with_signature(signature);
let rlp = ::util::rlp::encode(&t).to_vec().to_hex();

View File

@@ -20,7 +20,7 @@ use v1::impls::EthSigningQueueClient;
use v1::traits::EthSigning;
use v1::helpers::{ConfirmationsQueue, SigningQueue};
use v1::tests::helpers::TestMinerService;
use util::keys::TestAccount;
use util::{Address, FixedHash};
struct EthSigningTester {
pub queue: Arc<ConfirmationsQueue>,
@@ -52,8 +52,7 @@ fn eth_signing() -> EthSigningTester {
fn should_add_transaction_to_queue() {
// given
let tester = eth_signing();
let account = TestAccount::new("123");
let address = account.address();
let address = Address::random();
assert_eq!(tester.queue.requests().len(), 0);
// when

View File

@@ -16,17 +16,16 @@
use std::sync::Arc;
use std::str::FromStr;
use std::collections::HashMap;
use jsonrpc_core::IoHandler;
use util::numbers::*;
use util::keys::{TestAccount, TestAccountProvider};
use ethcore::account_provider::AccountProvider;
use v1::{PersonalClient, Personal};
use v1::tests::helpers::TestMinerService;
use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Action, Transaction};
struct PersonalTester {
accounts: Arc<TestAccountProvider>,
accounts: Arc<AccountProvider>,
io: IoHandler,
miner: Arc<TestMinerService>,
// these unused fields are necessary to keep the data alive
@@ -39,10 +38,8 @@ fn blockchain_client() -> Arc<TestBlockChainClient> {
Arc::new(client)
}
fn accounts_provider() -> Arc<TestAccountProvider> {
let accounts = HashMap::new();
let ap = TestAccountProvider::new(accounts);
Arc::new(ap)
fn accounts_provider() -> Arc<AccountProvider> {
Arc::new(AccountProvider::transient_provider())
}
fn miner_service() -> Arc<TestMinerService> {
@@ -99,13 +96,9 @@ fn should_return_port_number_if_signer_is_enabled() {
#[test]
fn accounts() {
let tester = setup(None);
tester.accounts.accounts
.write()
.unwrap()
.insert(Address::from(1), TestAccount::new("test"));
let address = tester.accounts.new_account("").unwrap();
let request = r#"{"jsonrpc": "2.0", "method": "personal_listAccounts", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#;
let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:?}", address) + r#""],"id":1}"#;
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
}
@@ -117,15 +110,9 @@ fn new_account() {
let res = tester.io.handle_request(request);
let accounts = tester.accounts.accounts.read().unwrap();
let accounts = tester.accounts.accounts();
assert_eq!(accounts.len(), 1);
let address = accounts
.keys()
.nth(0)
.cloned()
.unwrap();
let address = accounts[0];
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"","id":1}"#;
assert_eq!(res, Some(response));
@@ -133,11 +120,8 @@ fn new_account() {
#[test]
fn sign_and_send_transaction_with_invalid_password() {
let account = TestAccount::new("password123");
let address = account.address();
let tester = setup(None);
tester.accounts.accounts.write().unwrap().insert(address.clone(), account);
let address = tester.accounts.new_account("password123").unwrap();
let request = r#"{
"jsonrpc": "2.0",
"method": "personal_signAndSendTransaction",
@@ -158,12 +142,9 @@ fn sign_and_send_transaction_with_invalid_password() {
#[test]
fn sign_and_send_transaction() {
let account = TestAccount::new("password123");
let address = account.address();
let secret = account.secret.clone();
let tester = setup(None);
tester.accounts.accounts.write().unwrap().insert(address.clone(), account);
let address = tester.accounts.new_account("password123").unwrap();
let request = r#"{
"jsonrpc": "2.0",
"method": "personal_signAndSendTransaction",
@@ -184,7 +165,10 @@ fn sign_and_send_transaction() {
action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
value: U256::from(0x9184e72au64),
data: vec![]
}.sign(&secret);
};
tester.accounts.unlock_account_temporarily(address, "password123".into()).unwrap();
let signature = tester.accounts.sign(address, t.hash()).unwrap();
let t = t.with_signature(signature);
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
@@ -199,7 +183,10 @@ fn sign_and_send_transaction() {
action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
value: U256::from(0x9184e72au64),
data: vec![]
}.sign(&secret);
};
tester.accounts.unlock_account_temporarily(address, "password123".into()).unwrap();
let signature = tester.accounts.sign(address, t.hash()).unwrap();
let t = t.with_signature(signature);
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;

View File

@@ -16,10 +16,9 @@
use std::sync::Arc;
use std::str::FromStr;
use std::collections::HashMap;
use jsonrpc_core::IoHandler;
use util::numbers::*;
use util::keys::{TestAccount, TestAccountProvider};
use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Transaction, Action};
use v1::{SignerClient, PersonalSigner};
@@ -30,7 +29,7 @@ use v1::types::TransactionRequest;
struct PersonalSignerTester {
queue: Arc<ConfirmationsQueue>,
accounts: Arc<TestAccountProvider>,
accounts: Arc<AccountProvider>,
io: IoHandler,
miner: Arc<TestMinerService>,
// these unused fields are necessary to keep the data alive
@@ -43,10 +42,8 @@ fn blockchain_client() -> Arc<TestBlockChainClient> {
Arc::new(client)
}
fn accounts_provider() -> Arc<TestAccountProvider> {
let accounts = HashMap::new();
let ap = TestAccountProvider::new(accounts);
Arc::new(ap)
fn accounts_provider() -> Arc<AccountProvider> {
Arc::new(AccountProvider::transient_provider())
}
fn miner_service() -> Arc<TestMinerService> {
@@ -146,16 +143,10 @@ fn should_not_remove_transaction_if_password_is_invalid() {
#[test]
fn should_confirm_transaction_and_dispatch() {
// given
//// given
let tester = signer_tester();
let account = TestAccount::new("test");
let address = account.address();
let secret = account.secret.clone();
let address = tester.accounts.new_account("test").unwrap();
let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap();
tester.accounts.accounts
.write()
.unwrap()
.insert(address, account);
tester.queue.add_request(TransactionRequest {
from: address,
to: Some(recipient),
@@ -165,6 +156,7 @@ fn should_confirm_transaction_and_dispatch() {
data: None,
nonce: None,
});
let t = Transaction {
nonce: U256::zero(),
gas_price: U256::from(0x1000),
@@ -172,7 +164,10 @@ fn should_confirm_transaction_and_dispatch() {
action: Action::Call(recipient),
value: U256::from(0x1),
data: vec![]
}.sign(&secret);
};
tester.accounts.unlock_account_temporarily(address, "test".into()).unwrap();
let signature = tester.accounts.sign(address, t.hash()).unwrap();
let t = t.with_signature(signature);
assert_eq!(tester.queue.requests().len(), 1);