Merge branch 'master' into softforktrigger
This commit is contained in:
@@ -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,31 +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>)
|
||||
-> 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),
|
||||
@@ -73,6 +72,7 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM> where
|
||||
accounts: Arc::downgrade(accounts),
|
||||
external_miner: em.clone(),
|
||||
seed_compute: Mutex::new(SeedHashCompute::new()),
|
||||
allow_pending_receipt_query: allow_pending_receipt_query,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,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 {
|
||||
|
||||
@@ -304,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> {
|
||||
@@ -423,8 +419,8 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
|
||||
.and_then(|(hash,)| {
|
||||
let miner = take_weak!(self.miner);
|
||||
match miner.pending_receipts().get(&hash) {
|
||||
Some(receipt) => to_value(&Receipt::from(receipt.clone())),
|
||||
None => {
|
||||
Some(receipt) if self.allow_pending_receipt_query => to_value(&Receipt::from(receipt.clone())),
|
||||
_ => {
|
||||
let client = take_weak!(self.client);
|
||||
let receipt = client.transaction_receipt(TransactionID::Hash(hash));
|
||||
to_value(&receipt.map(Receipt::from))
|
||||
|
||||
@@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
|
||||
@@ -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()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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(|| {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -107,7 +102,8 @@ impl EthTester {
|
||||
&sync_provider,
|
||||
&account_provider,
|
||||
&miner_service,
|
||||
&external_miner
|
||||
&external_miner,
|
||||
true
|
||||
);
|
||||
let eth_sign = EthSigningUnsafeClient::new(
|
||||
&client,
|
||||
@@ -226,15 +222,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",
|
||||
|
||||
@@ -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,
|
||||
@@ -71,7 +68,7 @@ impl Default for EthTester {
|
||||
let miner = miner_service();
|
||||
let hashrates = Arc::new(RwLock::new(HashMap::new()));
|
||||
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
|
||||
let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate();
|
||||
let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner, true).to_delegate();
|
||||
let sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(eth);
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}"#;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user