Backporting to beta (#3229)

* Use ethcore_dappsPort when constructing URLs (#3139)

* Upon connect, retrieve the available api ports

* Update dapps to load from dappsPort

* Update dapps summary with dappsPort

* Allow proxy to use dappsPort

* Replace /api/ping with HEAD /

* Dynamic port for available apps

* Retrieve content images with dappsPort

* Fix /

* Transfer token dropdown image fix

* IdentityIcon loads images via contentHash

* Update apps fetch to cater for dev & prod

* DRY up 127.0.0.1:${dappsPort} with ${dappsUrl}

* Cleaning up polluted namespaces (#3143)

* Renaming ethcore_ to parity_

* Renaming files

* Renaming poluted EthSigning

* Tidy up the namespaces

* Renaming files to match new structure

* Splitting EthSigning into separate traits

* jsapi move ethcore.* -> parity.*

* Move jsonrpc parity definitions

* Update UI API calls for parity interfaces

* Move jsapi signer interfaces from personal to signer

* Update UI to use signer.* where applicable

* Updsate jsapi subscriptions for signer

* Fix dodgy merge.

* Update README.

* Fix some tests.

* Move parity-only personal.* to parity.*

* Update UI for personal -> parity API moves

* Update subscription APIs after personal -> parity move

* personal. generateAuthorizationToken -> parity. generateAuthorizationToken (UI)

* enode, dappsPort & signerPort (UI)

* Update subscription tests (accountsInfo)

* subscription update

* personal -> parity

* Additional error logging on method failures

* move postTransaction to parity

* Additional debug info with method failures

* Fix personal tests.

* Console wrning shows parameters, error object does not

* Include parity_ signing methods.

* Console log http transport info

* Fix failing tests

* Add RPC stubs for parity_accounts.

* Allow some secure built-in dapps

* Use parity_accounts in place of accountsInfo

* Improve error reporting

* Cleanup GHH error handling


Former-commit-id: 5a094ccb9f0596d0e07abc23504b80dc099ad584
This commit is contained in:
Arkadiy Paronyan
2016-11-07 14:46:41 +01:00
committed by GitHub
parent aea995cf55
commit 043ca21863
106 changed files with 1974 additions and 1485 deletions

View File

@@ -27,13 +27,14 @@ macro_rules! take_weak {
mod eth;
mod eth_filter;
mod eth_signing;
mod ethcore;
mod ethcore_set;
mod net;
mod parity;
mod parity_accounts;
mod parity_set;
mod personal;
mod personal_accounts;
mod personal_signer;
mod signer;
mod signing;
mod signing_unsafe;
mod rpc;
mod traces;
mod web3;
@@ -41,12 +42,13 @@ mod web3;
pub use self::web3::Web3Client;
pub use self::eth::{EthClient, EthClientOptions};
pub use self::eth_filter::EthFilterClient;
pub use self::eth_signing::{EthSigningUnsafeClient, EthSigningQueueClient};
pub use self::net::NetClient;
pub use self::parity::ParityClient;
pub use self::parity_accounts::ParityAccountsClient;
pub use self::parity_set::ParitySetClient;
pub use self::personal::PersonalClient;
pub use self::personal_accounts::PersonalAccountsClient;
pub use self::personal_signer::SignerClient;
pub use self::ethcore::EthcoreClient;
pub use self::ethcore_set::EthcoreSetClient;
pub use self::signer::SignerClient;
pub use self::signing::SigningQueueClient;
pub use self::signing_unsafe::SigningUnsafeClient;
pub use self::traces::TracesClient;
pub use self::rpc::RpcClient;

View File

@@ -14,16 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore-specific rpc implementation.
use std::{fs, io};
use std::sync::{mpsc, Arc, Weak};
//! Parity-specific rpc implementation.
use std::sync::{Arc, Weak};
use std::str::FromStr;
use std::collections::BTreeMap;
use util::{RotatingLogger, Address, Mutex, sha3};
use util::{RotatingLogger, Address};
use util::misc::version_data;
use crypto::ecies;
use fetch::{Client as FetchClient, Fetch};
use ethkey::{Brain, Generator};
use ethstore::random_phrase;
use ethsync::{SyncProvider, ManageNetwork};
@@ -31,77 +30,57 @@ use ethcore::miner::MinerService;
use ethcore::client::{MiningBlockChainClient};
use ethcore::ids::BlockID;
use ethcore::mode::Mode;
use ethcore::account_provider::AccountProvider;
use jsonrpc_core::Error;
use v1::traits::Ethcore;
use v1::traits::Parity;
use v1::types::{Bytes, U256, H160, H256, H512, Peers, Transaction, RpcSettings, Histogram};
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
use v1::helpers::dispatch::DEFAULT_MAC;
use v1::helpers::auto_args::Ready;
/// Ethcore implementation.
pub struct EthcoreClient<C, M, S: ?Sized, F=FetchClient> where
/// Parity implementation.
pub struct ParityClient<C, M, S: ?Sized> where
C: MiningBlockChainClient,
M: MinerService,
S: SyncProvider,
F: Fetch {
{
client: Weak<C>,
miner: Weak<M>,
sync: Weak<S>,
net: Weak<ManageNetwork>,
accounts: Weak<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
signer: Option<Arc<SignerService>>,
fetch: Mutex<F>,
dapps_port: Option<u16>,
}
impl<C, M, S: ?Sized> EthcoreClient<C, M, S> where
impl<C, M, S: ?Sized> ParityClient<C, M, S> where
C: MiningBlockChainClient,
M: MinerService,
S: SyncProvider, {
/// Creates new `EthcoreClient` with default `Fetch`.
S: SyncProvider,
{
/// Creates new `ParityClient`.
pub fn new(
client: &Arc<C>,
miner: &Arc<M>,
sync: &Arc<S>,
net: &Arc<ManageNetwork>,
store: &Arc<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
signer: Option<Arc<SignerService>>,
dapps_port: Option<u16>,
) -> Self {
Self::with_fetch(client, miner, sync, net, logger, settings, signer, dapps_port)
}
}
impl<C, M, S: ?Sized, F> EthcoreClient<C, M, S, F> where
C: MiningBlockChainClient,
M: MinerService,
S: SyncProvider,
F: Fetch, {
/// Creates new `EthcoreClient` with customizable `Fetch`.
pub fn with_fetch(
client: &Arc<C>,
miner: &Arc<M>,
sync: &Arc<S>,
net: &Arc<ManageNetwork>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
signer: Option<Arc<SignerService>>,
dapps_port: Option<u16>,
) -> Self {
EthcoreClient {
ParityClient {
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
sync: Arc::downgrade(sync),
net: Arc::downgrade(net),
accounts: Arc::downgrade(store),
logger: logger,
settings: settings,
signer: signer,
fetch: Mutex::new(F::default()),
dapps_port: dapps_port,
}
}
@@ -113,11 +92,10 @@ impl<C, M, S: ?Sized, F> EthcoreClient<C, M, S, F> where
}
}
impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
impl<C, M, S: ?Sized> Parity for ParityClient<C, M, S> where
M: MinerService + 'static,
C: MiningBlockChainClient + 'static,
S: SyncProvider + 'static,
F: Fetch + 'static {
S: SyncProvider + 'static {
fn transactions_limit(&self) -> Result<usize, Error> {
try!(self.active());
@@ -278,48 +256,6 @@ impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
Ok(take_weak!(self.miner).all_transactions().into_iter().map(Into::into).collect::<Vec<_>>())
}
fn hash_content(&self, ready: Ready<H256>, url: String) {
let res = self.active();
let hash_content = |result| {
let path = try!(result);
let mut file = io::BufReader::new(try!(fs::File::open(&path)));
// Try to hash
let result = sha3(&mut file);
// Remove file (always)
try!(fs::remove_file(&path));
// Return the result
Ok(try!(result))
};
match res {
Err(e) => ready.ready(Err(e)),
Ok(()) => {
let (tx, rx) = mpsc::channel();
let res = self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| {
let result = hash_content(result)
.map_err(errors::from_fetch_error)
.map(Into::into);
// Receive ready and invoke with result.
let ready: Ready<H256> = rx.recv().expect(
"recv() fails when `tx` has been dropped, if this closure is invoked `tx` is not dropped (`res == Ok()`); qed"
);
ready.ready(result);
}));
// Either invoke ready right away or transfer it to the closure.
if let Err(e) = res {
ready.ready(Err(errors::from_fetch_error(e)));
} else {
tx.send(ready).expect(
"send() fails when `rx` end is dropped, if `res == Ok()`: `rx` is moved to the closure; qed"
);
}
}
}
}
fn signer_port(&self) -> Result<u16, Error> {
try!(self.active());
@@ -361,4 +297,22 @@ impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
fn enode(&self) -> Result<String, Error> {
take_weak!(self.sync).enode().ok_or_else(errors::network_disabled)
}
fn accounts(&self) -> Result<BTreeMap<String, BTreeMap<String, String>>, Error> {
try!(self.active());
let store = take_weak!(self.accounts);
let info = try!(store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e)));
let other = store.addresses_info().expect("addresses_info always returns Ok; qed");
Ok(info.into_iter().chain(other.into_iter()).map(|(a, v)| {
let mut m = map![
"name".to_owned() => v.name,
"meta".to_owned() => v.meta
];
if let &Some(ref uuid) = &v.uuid {
m.insert("uuid".to_owned(), format!("{}", uuid));
}
(format!("0x{}", a.hex()), m)
}).collect())
}
}

View File

@@ -16,33 +16,30 @@
//! Account management (personal) rpc implementation
use std::sync::{Arc, Weak};
use std::collections::BTreeMap;
use util::{Address};
use jsonrpc_core::*;
use ethkey::{Brain, Generator};
use v1::traits::PersonalAccounts;
use v1::types::{H160 as RpcH160, H256 as RpcH256, TransactionRequest};
use v1::helpers::errors;
use v1::helpers::dispatch::sign_and_dispatch;
use ethcore::account_provider::AccountProvider;
use ethcore::client::MiningBlockChainClient;
use ethcore::miner::MinerService;
use jsonrpc_core::{Value, Error, to_value};
use v1::traits::ParityAccounts;
use v1::types::{H160 as RpcH160, H256 as RpcH256};
use v1::helpers::errors;
/// Account management (personal) rpc implementation.
pub struct PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: MinerService {
pub struct ParityAccountsClient<C> where C: MiningBlockChainClient {
accounts: Weak<AccountProvider>,
client: Weak<C>,
miner: Weak<M>,
allow_perm_unlock: bool,
}
impl<C, M> PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: MinerService {
impl<C> ParityAccountsClient<C> where C: MiningBlockChainClient {
/// Creates new PersonalClient
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>, miner: &Arc<M>, allow_perm_unlock: bool) -> Self {
PersonalAccountsClient {
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>) -> Self {
ParityAccountsClient {
accounts: Arc::downgrade(store),
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
allow_perm_unlock: allow_perm_unlock,
}
}
@@ -53,15 +50,25 @@ impl<C, M> PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: Mine
}
}
impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: MinerService {
fn new_account(&self, pass: String) -> Result<RpcH160, Error> {
impl<C: 'static> ParityAccounts for ParityAccountsClient<C> where C: MiningBlockChainClient {
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error> {
try!(self.active());
let store = take_weak!(self.accounts);
let info = try!(store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e)));
let other = store.addresses_info().expect("addresses_info always returns Ok; qed");
store.new_account(&pass)
.map(Into::into)
.map_err(|e| errors::account("Could not create account.", e))
Ok(info.into_iter().chain(other.into_iter()).map(|(a, v)| {
let m = map![
"name".to_owned() => to_value(&v.name),
"meta".to_owned() => to_value(&v.meta),
"uuid".to_owned() => if let &Some(ref uuid) = &v.uuid {
to_value(uuid)
} else {
Value::Null
}
];
(format!("0x{}", a.hex()), Value::Object(m))
}).collect())
}
fn new_account_from_phrase(&self, phrase: String, pass: String) -> Result<RpcH160, Error> {
@@ -92,24 +99,6 @@ impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> w
.map_err(|e| errors::account("Could not create account.", e))
}
fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option<u64>) -> Result<bool, Error> {
try!(self.active());
let account: Address = account.into();
let store = take_weak!(self.accounts);
let r = match (self.allow_perm_unlock, duration) {
(false, _) => store.unlock_account_temporarily(account, account_pass),
(true, Some(0)) => store.unlock_account_permanently(account, account_pass),
(true, Some(d)) => store.unlock_account_timed(account, account_pass, d as u32 * 1000),
(true, None) => store.unlock_account_timed(account, account_pass, 300_000),
};
match r {
Ok(_) => Ok(true),
// TODO [ToDr] Proper error here?
Err(_) => Ok(false),
}
}
fn test_password(&self, account: RpcH160, password: String) -> Result<bool, Error> {
try!(self.active());
let account: Address = account.into();
@@ -128,18 +117,6 @@ impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> w
.map_err(|e| errors::account("Could not fetch account info.", e))
}
fn sign_and_send_transaction(&self, request: TransactionRequest, password: String) -> Result<RpcH256, Error> {
try!(self.active());
sign_and_dispatch(
&*take_weak!(self.client),
&*take_weak!(self.miner),
&*take_weak!(self.accounts),
request.into(),
Some(password)
)
}
fn set_account_name(&self, addr: RpcH160, name: String) -> Result<bool, Error> {
try!(self.active());
let store = take_weak!(self.accounts);
@@ -162,6 +139,10 @@ impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> w
Ok(true)
}
fn set_account_visibility(&self, _address: RpcH160, _dapp: RpcH256, _visible: bool) -> Result<bool, Error> {
Ok(false)
}
fn import_geth_accounts(&self, addresses: Vec<RpcH160>) -> Result<Vec<RpcH160>, Error> {
let store = take_weak!(self.accounts);

View File

@@ -14,36 +14,57 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
/// Ethcore-specific rpc interface for operations altering the settings.
use std::sync::{Arc, Weak};
use jsonrpc_core::*;
/// Parity-specific rpc interface for operations altering the settings.
use std::{fs, io};
use std::sync::{Arc, Weak, mpsc};
use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient;
use ethcore::mode::Mode;
use ethsync::ManageNetwork;
use v1::helpers::errors;
use v1::traits::EthcoreSet;
use v1::types::{Bytes, H160, U256};
use fetch::{Client as FetchClient, Fetch};
use util::{Mutex, sha3};
/// Ethcore-specific rpc interface for operations altering the settings.
pub struct EthcoreSetClient<C, M> where
use jsonrpc_core::Error;
use v1::helpers::auto_args::Ready;
use v1::helpers::errors;
use v1::traits::ParitySet;
use v1::types::{Bytes, H160, H256, U256};
/// Parity-specific rpc interface for operations altering the settings.
pub struct ParitySetClient<C, M, F=FetchClient> where
C: MiningBlockChainClient,
M: MinerService
M: MinerService,
F: Fetch,
{
client: Weak<C>,
miner: Weak<M>,
net: Weak<ManageNetwork>,
fetch: Mutex<F>,
}
impl<C, M> EthcoreSetClient<C, M> where
impl<C, M> ParitySetClient<C, M, FetchClient> where
C: MiningBlockChainClient,
M: MinerService {
/// Creates new `EthcoreSetClient`.
M: MinerService
{
/// Creates new `ParitySetClient` with default `FetchClient`.
pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self {
EthcoreSetClient {
Self::with_fetch(client, miner, net)
}
}
impl<C, M, F> ParitySetClient<C, M, F> where
C: MiningBlockChainClient,
M: MinerService,
F: Fetch,
{
/// Creates new `ParitySetClient` with default `FetchClient`.
pub fn with_fetch(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self {
ParitySetClient {
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
net: Arc::downgrade(net),
fetch: Mutex::new(F::default()),
}
}
@@ -54,9 +75,11 @@ impl<C, M> EthcoreSetClient<C, M> where
}
}
impl<C, M> EthcoreSet for EthcoreSetClient<C, M> where
impl<C, M, F> ParitySet for ParitySetClient<C, M, F> where
C: MiningBlockChainClient + 'static,
M: MinerService + 'static {
M: MinerService + 'static,
F: Fetch + 'static,
{
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool, Error> {
try!(self.active());
@@ -159,4 +182,46 @@ impl<C, M> EthcoreSet for EthcoreSetClient<C, M> where
});
Ok(true)
}
fn hash_content(&self, ready: Ready<H256>, url: String) {
let res = self.active();
let hash_content = |result| {
let path = try!(result);
let mut file = io::BufReader::new(try!(fs::File::open(&path)));
// Try to hash
let result = sha3(&mut file);
// Remove file (always)
try!(fs::remove_file(&path));
// Return the result
Ok(try!(result))
};
match res {
Err(e) => ready.ready(Err(e)),
Ok(()) => {
let (tx, rx) = mpsc::channel();
let res = self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| {
let result = hash_content(result)
.map_err(errors::from_fetch_error)
.map(Into::into);
// Receive ready and invoke with result.
let ready: Ready<H256> = rx.recv().expect(
"recv() fails when `tx` has been dropped, if this closure is invoked `tx` is not dropped (`res == Ok()`); qed"
);
ready.ready(result);
}));
// Either invoke ready right away or transfer it to the closure.
if let Err(e) = res {
ready.ready(Err(errors::from_fetch_error(e)));
} else {
tx.send(ready).expect(
"send() fails when `rx` end is dropped, if `res == Ok()`: `rx` is moved to the closure; qed"
);
}
}
}
}
}

View File

@@ -16,26 +16,34 @@
//! Account management (personal) rpc implementation
use std::sync::{Arc, Weak};
use std::collections::{BTreeMap};
use jsonrpc_core::*;
use v1::traits::Personal;
use v1::types::{H160 as RpcH160};
use v1::helpers::errors;
use ethcore::account_provider::AccountProvider;
use ethcore::client::MiningBlockChainClient;
use ethcore::miner::MinerService;
use util::Address;
use jsonrpc_core::Error;
use v1::traits::Personal;
use v1::types::{H160 as RpcH160, H256 as RpcH256, TransactionRequest};
use v1::helpers::errors;
use v1::helpers::dispatch::sign_and_dispatch;
/// Account management (personal) rpc implementation.
pub struct PersonalClient<C> where C: MiningBlockChainClient {
pub struct PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
accounts: Weak<AccountProvider>,
client: Weak<C>,
miner: Weak<M>,
allow_perm_unlock: bool,
}
impl<C> PersonalClient<C> where C: MiningBlockChainClient {
impl<C, M> PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
/// Creates new PersonalClient
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>) -> Self {
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>, miner: &Arc<M>, allow_perm_unlock: bool) -> Self {
PersonalClient {
accounts: Arc::downgrade(store),
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
allow_perm_unlock: allow_perm_unlock,
}
}
@@ -46,8 +54,7 @@ impl<C> PersonalClient<C> where C: MiningBlockChainClient {
}
}
impl<C: 'static> Personal for PersonalClient<C> where C: MiningBlockChainClient {
impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
fn accounts(&self) -> Result<Vec<RpcH160>, Error> {
try!(self.active());
@@ -56,23 +63,42 @@ impl<C: 'static> Personal for PersonalClient<C> where C: MiningBlockChainClient
Ok(accounts.into_iter().map(Into::into).collect::<Vec<RpcH160>>())
}
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error> {
fn new_account(&self, pass: String) -> Result<RpcH160, Error> {
try!(self.active());
let store = take_weak!(self.accounts);
let info = try!(store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e)));
let other = store.addresses_info().expect("addresses_info always returns Ok; qed");
Ok(info.into_iter().chain(other.into_iter()).map(|(a, v)| {
let m = map![
"name".to_owned() => to_value(&v.name),
"meta".to_owned() => to_value(&v.meta),
"uuid".to_owned() => if let &Some(ref uuid) = &v.uuid {
to_value(uuid)
} else {
Value::Null
}
];
(format!("0x{}", a.hex()), Value::Object(m))
}).collect())
store.new_account(&pass)
.map(Into::into)
.map_err(|e| errors::account("Could not create account.", e))
}
fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option<u64>) -> Result<bool, Error> {
try!(self.active());
let account: Address = account.into();
let store = take_weak!(self.accounts);
let r = match (self.allow_perm_unlock, duration) {
(false, _) => store.unlock_account_temporarily(account, account_pass),
(true, Some(0)) => store.unlock_account_permanently(account, account_pass),
(true, Some(d)) => store.unlock_account_timed(account, account_pass, d as u32 * 1000),
(true, None) => store.unlock_account_timed(account, account_pass, 300_000),
};
match r {
Ok(_) => Ok(true),
// TODO [ToDr] Proper error here?
Err(_) => Ok(false),
}
}
fn sign_and_send_transaction(&self, request: TransactionRequest, password: String) -> Result<RpcH256, Error> {
try!(self.active());
sign_and_dispatch(
&*take_weak!(self.client),
&*take_weak!(self.miner),
&*take_weak!(self.accounts),
request.into(),
Some(password)
)
}
}

View File

@@ -14,14 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Transactions Confirmations (personal) rpc implementation
//! Transactions Confirmations rpc implementation
use std::sync::{Arc, Weak};
use jsonrpc_core::*;
use ethcore::account_provider::AccountProvider;
use ethcore::client::MiningBlockChainClient;
use ethcore::miner::MinerService;
use v1::traits::PersonalSigner;
use v1::traits::Signer;
use v1::types::{TransactionModification, ConfirmationRequest, U256};
use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload};
use v1::helpers::dispatch::{sign_and_dispatch, sign, decrypt};
@@ -58,7 +58,7 @@ impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient,
}
}
impl<C: 'static, M: 'static> PersonalSigner for SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
impl<C: 'static, M: 'static> Signer for SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error> {
try!(self.active());

View File

@@ -14,43 +14,22 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Eth Signing RPC implementation.
//! Signing RPC implementation.
use std::sync::{Arc, Weak};
use jsonrpc_core::*;
use ethcore::account_provider::AccountProvider;
use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient;
use util::{U256, Address, H256, Mutex};
use transient_hashmap::TransientHashMap;
use ethcore::account_provider::AccountProvider;
use util::{U256, Address, H256, Mutex};
use jsonrpc_core::*;
use v1::helpers::{errors, SigningQueue, ConfirmationPromise, ConfirmationResult, ConfirmationPayload, TransactionRequest as TRequest, FilledTransactionRequest as FilledRequest, SignerService};
use v1::helpers::dispatch::{default_gas_price, sign_and_dispatch, sign, decrypt};
use v1::traits::EthSigning;
use v1::traits::{EthSigning, ParitySigning};
use v1::types::{TransactionRequest, H160 as RpcH160, H256 as RpcH256, U256 as RpcU256, Bytes as RpcBytes};
fn fill_optional_fields<C, M>(request: TRequest, client: &C, miner: &M) -> FilledRequest
where C: MiningBlockChainClient, M: MinerService {
FilledRequest {
from: request.from,
to: request.to,
nonce: request.nonce,
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(client, miner)),
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
value: request.value.unwrap_or_else(|| 0.into()),
data: request.data.unwrap_or_else(Vec::new),
}
}
/// Implementation of functions that require signing when no trusted signer is used.
pub struct EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
signer: Weak<SignerService>,
accounts: Weak<AccountProvider>,
client: Weak<C>,
miner: Weak<M>,
pending: Mutex<TransientHashMap<U256, ConfirmationPromise>>,
}
const MAX_PENDING_DURATION: u64 = 60 * 60;
pub enum DispatchResult {
@@ -58,10 +37,23 @@ pub enum DispatchResult {
Value(Value),
}
impl<C, M> EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
/// Implementation of functions that require signing when no trusted signer is used.
pub struct SigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
signer: Weak<SignerService>,
accounts: Weak<AccountProvider>,
client: Weak<C>,
miner: Weak<M>,
pending: Mutex<TransientHashMap<U256, ConfirmationPromise>>,
}
impl<C, M> SigningQueueClient<C, M> where
C: MiningBlockChainClient,
M: MinerService,
{
/// Creates a new signing queue client given shared signing queue.
pub fn new(signer: &Arc<SignerService>, client: &Arc<C>, miner: &Arc<M>, accounts: &Arc<AccountProvider>) -> Self {
EthSigningQueueClient {
SigningQueueClient {
signer: Arc::downgrade(signer),
accounts: Arc::downgrade(accounts),
client: Arc::downgrade(client),
@@ -132,10 +124,10 @@ impl<C, M> EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: Miner
}
}
impl<C, M> EthSigning for EthSigningQueueClient<C, M>
where C: MiningBlockChainClient + 'static, M: MinerService + 'static
impl<C: 'static, M: 'static> ParitySigning for SigningQueueClient<C, M> where
C: MiningBlockChainClient,
M: MinerService,
{
fn post_sign(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
self.dispatch_sign(params).map(|result| match result {
@@ -178,16 +170,6 @@ impl<C, M> EthSigning for EthSigningQueueClient<C, M>
})
}
fn sign(&self, params: Params, ready: Ready) {
let res = self.active().and_then(|_| self.dispatch_sign(params));
self.handle_dispatch(res, ready);
}
fn send_transaction(&self, params: Params, ready: Ready) {
let res = self.active().and_then(|_| self.dispatch_transaction(params));
self.handle_dispatch(res, ready);
}
fn decrypt_message(&self, params: Params, ready: Ready) {
let res = self.active()
.and_then(|_| from_params::<(RpcH160, RpcBytes)>(params))
@@ -205,76 +187,30 @@ impl<C, M> EthSigning for EthSigningQueueClient<C, M>
}
}
/// Implementation of functions that require signing when no trusted signer is used.
pub struct EthSigningUnsafeClient<C, M> where
impl<C: 'static, M: 'static> EthSigning for SigningQueueClient<C, M> where
C: MiningBlockChainClient,
M: MinerService {
client: Weak<C>,
accounts: Weak<AccountProvider>,
miner: Weak<M>,
}
impl<C, M> EthSigningUnsafeClient<C, M> where
C: MiningBlockChainClient,
M: MinerService {
/// Creates new EthClient.
pub fn new(client: &Arc<C>, accounts: &Arc<AccountProvider>, miner: &Arc<M>)
-> Self {
EthSigningUnsafeClient {
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
accounts: Arc::downgrade(accounts),
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C, M> EthSigning for EthSigningUnsafeClient<C, M> where
C: MiningBlockChainClient + 'static,
M: MinerService + 'static {
M: MinerService,
{
fn sign(&self, params: Params, ready: Ready) {
ready.ready(self.active()
.and_then(|_| from_params::<(RpcH160, RpcH256)>(params))
.and_then(|(address, msg)| {
sign(&*take_weak!(self.accounts), address.into(), None, msg.into())
}))
let res = self.active().and_then(|_| self.dispatch_sign(params));
self.handle_dispatch(res, ready);
}
fn send_transaction(&self, params: Params, ready: Ready) {
ready.ready(self.active()
.and_then(|_| from_params::<(TransactionRequest, )>(params))
.and_then(|(request, )| {
sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), &*take_weak!(self.accounts), request.into(), None).map(to_value)
}))
}
fn decrypt_message(&self, params: Params, ready: Ready) {
ready.ready(self.active()
.and_then(|_| from_params::<(RpcH160, RpcBytes)>(params))
.and_then(|(address, ciphertext)| {
decrypt(&*take_weak!(self.accounts), address.into(), None, ciphertext.0)
}))
}
fn post_sign(&self, _: Params) -> Result<Value, Error> {
// We don't support this in non-signer mode.
Err(errors::signer_disabled())
}
fn post_transaction(&self, _: Params) -> Result<Value, Error> {
// We don't support this in non-signer mode.
Err(errors::signer_disabled())
}
fn check_request(&self, _: Params) -> Result<Value, Error> {
// We don't support this in non-signer mode.
Err(errors::signer_disabled())
let res = self.active().and_then(|_| self.dispatch_transaction(params));
self.handle_dispatch(res, ready);
}
}
fn fill_optional_fields<C, M>(request: TRequest, client: &C, miner: &M) -> FilledRequest
where C: MiningBlockChainClient, M: MinerService {
FilledRequest {
from: request.from,
to: request.to,
nonce: request.nonce,
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(client, miner)),
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
value: request.value.unwrap_or_else(|| 0.into()),
data: request.data.unwrap_or_else(Vec::new),
}
}

View File

@@ -0,0 +1,110 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Unsafe Signing RPC implementation.
use std::sync::{Arc, Weak};
use ethcore::account_provider::AccountProvider;
use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient;
use jsonrpc_core::*;
use v1::helpers::errors;
use v1::helpers::dispatch::{sign_and_dispatch, sign, decrypt};
use v1::traits::{EthSigning, ParitySigning};
use v1::types::{TransactionRequest, H160 as RpcH160, H256 as RpcH256, Bytes as RpcBytes};
/// Implementation of functions that require signing when no trusted signer is used.
pub struct SigningUnsafeClient<C, M> where
C: MiningBlockChainClient,
M: MinerService,
{
accounts: Weak<AccountProvider>,
client: Weak<C>,
miner: Weak<M>,
}
impl<C, M> SigningUnsafeClient<C, M> where
C: MiningBlockChainClient,
M: MinerService,
{
/// Creates new SigningUnsafeClient.
pub fn new(client: &Arc<C>, accounts: &Arc<AccountProvider>, miner: &Arc<M>)
-> Self {
SigningUnsafeClient {
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
accounts: Arc::downgrade(accounts),
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C: 'static, M: 'static> EthSigning for SigningUnsafeClient<C, M> where
C: MiningBlockChainClient,
M: MinerService,
{
fn sign(&self, params: Params, ready: Ready) {
ready.ready(self.active()
.and_then(|_| from_params::<(RpcH160, RpcH256)>(params))
.and_then(|(address, msg)| {
sign(&*take_weak!(self.accounts), address.into(), None, msg.into())
}))
}
fn send_transaction(&self, params: Params, ready: Ready) {
ready.ready(self.active()
.and_then(|_| from_params::<(TransactionRequest, )>(params))
.and_then(|(request, )| {
sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), &*take_weak!(self.accounts), request.into(), None).map(to_value)
}))
}
}
impl<C: 'static, M: 'static> ParitySigning for SigningUnsafeClient<C, M> where
C: MiningBlockChainClient,
M: MinerService,
{
fn decrypt_message(&self, params: Params, ready: Ready) {
ready.ready(self.active()
.and_then(|_| from_params::<(RpcH160, RpcBytes)>(params))
.and_then(|(address, ciphertext)| {
decrypt(&*take_weak!(self.accounts), address.into(), None, ciphertext.0)
}))
}
fn post_sign(&self, _: Params) -> Result<Value, Error> {
// We don't support this in non-signer mode.
Err(errors::signer_disabled())
}
fn post_transaction(&self, _: Params) -> Result<Value, Error> {
// We don't support this in non-signer mode.
Err(errors::signer_disabled())
}
fn check_request(&self, _: Params) -> Result<Value, Error> {
// We don't support this in non-signer mode.
Err(errors::signer_disabled())
}
}

View File

@@ -26,6 +26,6 @@ pub mod traits;
pub mod tests;
pub mod types;
pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, PersonalAccounts, PersonalSigner, Net, Ethcore, EthcoreSet, Traces, Rpc};
pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Net, Parity, ParityAccounts, ParitySet, ParitySigning, Signer, Personal, Traces, Rpc};
pub use self::impls::*;
pub use self::helpers::{SigningQueue, SignerService, ConfirmationsQueue, NetworkSettings, block_import};

View File

@@ -33,7 +33,7 @@ use util::{U256, H256, Uint, Address};
use jsonrpc_core::IoHandler;
use ethjson::blockchain::BlockChain;
use v1::impls::{EthClient, EthSigningUnsafeClient};
use v1::impls::{EthClient, SigningUnsafeClient};
use v1::types::U256 as NU256;
use v1::traits::eth::Eth;
use v1::traits::eth_signing::EthSigning;
@@ -140,7 +140,7 @@ impl EthTester {
&external_miner,
Default::default(),
);
let eth_sign = EthSigningUnsafeClient::new(
let eth_sign = SigningUnsafeClient::new(
&client,
&account_provider,
&miner_service

View File

@@ -27,7 +27,7 @@ use ethcore::receipt::LocalizedReceipt;
use ethcore::transaction::{Transaction, Action};
use ethcore::miner::{ExternalMiner, MinerService};
use ethsync::SyncState;
use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, EthSigningUnsafeClient};
use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, SigningUnsafeClient};
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestSnapshotService};
use rustc_serialize::hex::ToHex;
use time::get_time;
@@ -83,7 +83,7 @@ impl EthTester {
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
let eth = EthClient::new(&client, &snapshot, &sync, &ap, &miner, &external_miner, options).to_delegate();
let filter = EthFilterClient::new(&client, &miner).to_delegate();
let sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
let sign = SigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
let io = IoHandler::new();
io.add_delegate(eth);
io.add_delegate(sign);

View File

@@ -18,12 +18,13 @@
//! method calls properly.
mod eth;
mod eth_signing;
mod net;
mod web3;
mod personal;
mod personal_signer;
mod ethcore;
mod ethcore_set;
mod parity;
mod parity_accounts;
mod parity_set;
mod rpc;
mod signer;
mod signing;
mod manage_network;

View File

@@ -16,19 +16,19 @@
use std::sync::Arc;
use util::log::RotatingLogger;
use util::{Address};
use util::Address;
use ethsync::ManageNetwork;
use ethcore::client::{TestBlockChainClient};
use ethcore::account_provider::AccountProvider;
use ethstore::ethkey::{Generator, Random};
use jsonrpc_core::IoHandler;
use v1::{Ethcore, EthcoreClient};
use v1::{Parity, ParityClient};
use v1::helpers::{SignerService, NetworkSettings};
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestFetch};
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
use super::manage_network::TestManageNetwork;
pub type TestEthcoreClient = EthcoreClient<TestBlockChainClient, TestMinerService, TestSyncProvider, TestFetch>;
pub type TestParityClient = ParityClient<TestBlockChainClient, TestMinerService, TestSyncProvider>;
pub struct Dependencies {
pub miner: Arc<TestMinerService>,
@@ -37,6 +37,7 @@ pub struct Dependencies {
pub logger: Arc<RotatingLogger>,
pub settings: Arc<NetworkSettings>,
pub network: Arc<ManageNetwork>,
pub accounts: Arc<AccountProvider>,
pub dapps_port: Option<u16>,
}
@@ -59,16 +60,18 @@ impl Dependencies {
rpc_port: 8545,
}),
network: Arc::new(TestManageNetwork),
accounts: Arc::new(AccountProvider::transient_provider()),
dapps_port: Some(18080),
}
}
pub fn client(&self, signer: Option<Arc<SignerService>>) -> TestEthcoreClient {
EthcoreClient::with_fetch(
pub fn client(&self, signer: Option<Arc<SignerService>>) -> TestParityClient {
ParityClient::new(
&self.client,
&self.miner,
&self.sync,
&self.network,
&self.accounts,
self.logger.clone(),
self.settings.clone(),
signer,
@@ -90,105 +93,105 @@ impl Dependencies {
}
#[test]
fn rpc_ethcore_extra_data() {
fn rpc_parity_extra_data() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_extraData", "params": [], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_extraData", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x01020304","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_default_extra_data() {
fn rpc_parity_default_extra_data() {
use util::misc;
use util::ToPretty;
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_defaultExtraData", "params": [], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultExtraData", "params": [], "id": 1}"#;
let response = format!(r#"{{"jsonrpc":"2.0","result":"0x{}","id":1}}"#, misc::version_data().to_hex());
assert_eq!(io.handle_request_sync(request), Some(response));
}
#[test]
fn rpc_ethcore_gas_floor_target() {
fn rpc_parity_gas_floor_target() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_gasFloorTarget", "params": [], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_gasFloorTarget", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x3039","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_min_gas_price() {
fn rpc_parity_min_gas_price() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_minGasPrice", "params": [], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_minGasPrice", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x1312d00","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_dev_logs() {
fn rpc_parity_dev_logs() {
let deps = Dependencies::new();
deps.logger.append("a".to_owned());
deps.logger.append("b".to_owned());
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogs", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_devLogs", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":["b","a"],"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_dev_logs_levels() {
fn rpc_parity_dev_logs_levels() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogsLevels", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_devLogsLevels", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"rpc=trace","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_transactions_limit() {
fn rpc_parity_transactions_limit() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_transactionsLimit", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_transactionsLimit", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":1024,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_net_chain() {
fn rpc_parity_net_chain() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netChain", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_netChain", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"testchain","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_net_peers() {
fn rpc_parity_net_peers() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netPeers", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
let response = "{\"jsonrpc\":\"2.0\",\"result\":{\"active\":0,\"connected\":120,\"max\":50,\"peers\":[{\"caps\":[\"eth/62\",\"eth/63\"],\
\"id\":\"node1\",\"name\":\"Parity/1\",\"network\":{\"localAddress\":\"127.0.0.1:8888\",\"remoteAddress\":\"127.0.0.1:7777\"}\
,\"protocols\":{\"eth\":{\"difficulty\":\"0x28\",\"head\":\"0000000000000000000000000000000000000000000000000000000000000032\"\
@@ -200,101 +203,90 @@ fn rpc_ethcore_net_peers() {
}
#[test]
fn rpc_ethcore_net_port() {
fn rpc_parity_net_port() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netPort", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPort", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":30303,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_rpc_settings() {
fn rpc_parity_rpc_settings() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_rpcSettings", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_rpcSettings", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"enabled":true,"interface":"all","port":8545},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_node_name() {
fn rpc_parity_node_name() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_nodeName", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_nodeName", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"mynode","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_unsigned_transactions_count() {
fn rpc_parity_unsigned_transactions_count() {
let deps = Dependencies::new();
let io = deps.with_signer(SignerService::new_test(Some(18180)));
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":0,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_unsigned_transactions_count_when_signer_disabled() {
fn rpc_parity_unsigned_transactions_count_when_signer_disabled() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_hash_content() {
fn rpc_parity_pending_transactions() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_hashContent", "params":["https://ethcore.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_pending_transactions() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_pendingTransactions", "params":[], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_pendingTransactions", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":[],"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_ethcore_encrypt() {
fn rpc_parity_encrypt() {
let deps = Dependencies::new();
let io = deps.default_client();
let key = format!("{:?}", Random.generate().unwrap().public());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_encryptMessage", "params":["0x"#.to_owned() + &key + r#"", "0x01"], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_encryptMessage", "params":["0x"#.to_owned() + &key + r#"", "0x01"], "id": 1}"#;
assert!(io.handle_request_sync(&request).unwrap().contains("result"), "Should return success.");
}
#[test]
fn rpc_ethcore_signer_port() {
fn rpc_parity_signer_port() {
// given
let deps = Dependencies::new();
let io1 = deps.with_signer(SignerService::new_test(Some(18180)));
let io2 = deps.default_client();
// when
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_signerPort", "params": [], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_signerPort", "params": [], "id": 1}"#;
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
@@ -304,7 +296,7 @@ fn rpc_ethcore_signer_port() {
}
#[test]
fn rpc_ethcore_dapps_port() {
fn rpc_parity_dapps_port() {
// given
let mut deps = Dependencies::new();
let io1 = deps.default_client();
@@ -312,7 +304,7 @@ fn rpc_ethcore_dapps_port() {
let io2 = deps.default_client();
// when
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_dappsPort", "params": [], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsPort", "params": [], "id": 1}"#;
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
@@ -322,7 +314,7 @@ fn rpc_ethcore_dapps_port() {
}
#[test]
fn rpc_ethcore_next_nonce() {
fn rpc_parity_next_nonce() {
let deps = Dependencies::new();
let address = Address::default();
let io1 = deps.default_client();
@@ -332,7 +324,7 @@ fn rpc_ethcore_next_nonce() {
let request = r#"{
"jsonrpc": "2.0",
"method": "ethcore_nextNonce",
"method": "parity_nextNonce",
"params": [""#.to_owned() + &format!("0x{:?}", address) + r#""],
"id": 1
}"#;

View File

@@ -0,0 +1,118 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::Arc;
use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient;
use jsonrpc_core::IoHandler;
use v1::{ParityAccounts, ParityAccountsClient};
struct ParityAccountsTester {
accounts: Arc<AccountProvider>,
io: IoHandler,
// these unused fields are necessary to keep the data alive
// as the handler has only weak pointers.
_client: Arc<TestBlockChainClient>,
}
fn blockchain_client() -> Arc<TestBlockChainClient> {
let client = TestBlockChainClient::new();
Arc::new(client)
}
fn accounts_provider() -> Arc<AccountProvider> {
Arc::new(AccountProvider::transient_provider())
}
fn setup() -> ParityAccountsTester {
let accounts = accounts_provider();
let client = blockchain_client();
let parity_accounts = ParityAccountsClient::new(&accounts, &client);
let io = IoHandler::new();
io.add_delegate(parity_accounts.to_delegate());
let tester = ParityAccountsTester {
accounts: accounts,
io: io,
_client: client,
};
tester
}
#[test]
fn should_be_able_to_get_account_info() {
let tester = setup();
tester.accounts.new_account("").unwrap();
let accounts = tester.accounts.accounts().unwrap();
assert_eq!(accounts.len(), 1);
let address = accounts[0];
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
tester.accounts.set_account_name(address.clone(), "Test".to_owned()).unwrap();
tester.accounts.set_account_meta(address.clone(), "{foo: 69}".to_owned()).unwrap();
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
let res = tester.io.handle_request_sync(request);
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
assert_eq!(res, Some(response));
}
#[test]
fn should_be_able_to_set_name() {
let tester = setup();
tester.accounts.new_account("").unwrap();
let accounts = tester.accounts.accounts().unwrap();
assert_eq!(accounts.len(), 1);
let address = accounts[0];
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_setAccountName", "params": ["0x{}", "Test"], "id": 1}}"#, address.hex());
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
let res = tester.io.handle_request_sync(&request);
assert_eq!(res, Some(response.into()));
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
let res = tester.io.handle_request_sync(request);
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
assert_eq!(res, Some(response));
}
#[test]
fn should_be_able_to_set_meta() {
let tester = setup();
tester.accounts.new_account("").unwrap();
let accounts = tester.accounts.accounts().unwrap();
assert_eq!(accounts.len(), 1);
let address = accounts[0];
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_setAccountMeta", "params": ["0x{}", "{{foo: 69}}"], "id": 1}}"#, address.hex());
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
let res = tester.io.handle_request_sync(&request);
assert_eq!(res, Some(response.into()));
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
let res = tester.io.handle_request_sync(request);
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"{}\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid, uuid);
assert_eq!(res, Some(response));
}

View File

@@ -16,16 +16,18 @@
use std::sync::Arc;
use std::str::FromStr;
use jsonrpc_core::IoHandler;
use v1::{EthcoreSet, EthcoreSetClient};
use rustc_serialize::hex::FromHex;
use util::{U256, Address};
use ethcore::miner::MinerService;
use ethcore::client::TestBlockChainClient;
use v1::tests::helpers::TestMinerService;
use util::{U256, Address};
use rustc_serialize::hex::FromHex;
use super::manage_network::TestManageNetwork;
use ethsync::ManageNetwork;
use jsonrpc_core::IoHandler;
use v1::{ParitySet, ParitySetClient};
use v1::tests::helpers::{TestMinerService, TestFetch};
use super::manage_network::TestManageNetwork;
fn miner_service() -> Arc<TestMinerService> {
Arc::new(TestMinerService::default())
}
@@ -38,19 +40,21 @@ fn network_service() -> Arc<TestManageNetwork> {
Arc::new(TestManageNetwork)
}
fn ethcore_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, net: &Arc<TestManageNetwork>) -> EthcoreSetClient<TestBlockChainClient, TestMinerService> {
EthcoreSetClient::new(client, miner, &(net.clone() as Arc<ManageNetwork>))
pub type TestParitySetClient = ParitySetClient<TestBlockChainClient, TestMinerService, TestFetch>;
fn parity_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, net: &Arc<TestManageNetwork>) -> TestParitySetClient {
ParitySetClient::with_fetch(client, miner, &(net.clone() as Arc<ManageNetwork>))
}
#[test]
fn rpc_ethcore_set_min_gas_price() {
fn rpc_parity_set_min_gas_price() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
@@ -58,14 +62,14 @@ fn rpc_ethcore_set_min_gas_price() {
}
#[test]
fn rpc_ethcore_set_gas_floor_target() {
fn rpc_parity_set_gas_floor_target() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
@@ -73,14 +77,14 @@ fn rpc_ethcore_set_gas_floor_target() {
}
#[test]
fn rpc_ethcore_set_extra_data() {
fn rpc_parity_set_extra_data() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
@@ -88,14 +92,14 @@ fn rpc_ethcore_set_extra_data() {
}
#[test]
fn rpc_ethcore_set_author() {
fn rpc_parity_set_author() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
@@ -103,16 +107,31 @@ fn rpc_ethcore_set_author() {
}
#[test]
fn rpc_ethcore_set_transactions_limit() {
fn rpc_parity_set_transactions_limit() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#;
let request = r#"{"jsonrpc": "2.0", "method": "parity_setTransactionsLimit", "params":[10240240], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
assert_eq!(miner.transactions_limit(), 10_240_240);
}
}
#[test]
fn rpc_parity_set_hash_content() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_hashContent", "params":["https://ethcore.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}

View File

@@ -19,7 +19,7 @@ use std::str::FromStr;
use jsonrpc_core::IoHandler;
use util::{U256, Uint, Address};
use ethcore::account_provider::AccountProvider;
use v1::{PersonalClient, PersonalAccountsClient, PersonalAccounts, Personal};
use v1::{PersonalClient, Personal};
use v1::tests::helpers::TestMinerService;
use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Action, Transaction};
@@ -50,12 +50,10 @@ fn setup() -> PersonalTester {
let accounts = accounts_provider();
let client = blockchain_client();
let miner = miner_service();
let personal = PersonalClient::new(&accounts, &client);
let personal_accounts = PersonalAccountsClient::new(&accounts, &client, &miner, false);
let personal = PersonalClient::new(&accounts, &client, &miner, false);
let io = IoHandler::new();
io.add_delegate(personal.to_delegate());
io.add_delegate(personal_accounts.to_delegate());
let tester = PersonalTester {
accounts: accounts,
@@ -92,66 +90,6 @@ fn new_account() {
assert_eq!(res, Some(response));
}
#[test]
fn should_be_able_to_get_account_info() {
let tester = setup();
tester.accounts.new_account("").unwrap();
let accounts = tester.accounts.accounts().unwrap();
assert_eq!(accounts.len(), 1);
let address = accounts[0];
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
tester.accounts.set_account_name(address.clone(), "Test".to_owned()).unwrap();
tester.accounts.set_account_meta(address.clone(), "{foo: 69}".to_owned()).unwrap();
let request = r#"{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"#;
let res = tester.io.handle_request_sync(request);
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
assert_eq!(res, Some(response));
}
#[test]
fn should_be_able_to_set_name() {
let tester = setup();
tester.accounts.new_account("").unwrap();
let accounts = tester.accounts.accounts().unwrap();
assert_eq!(accounts.len(), 1);
let address = accounts[0];
let request = format!(r#"{{"jsonrpc": "2.0", "method": "personal_setAccountName", "params": ["0x{}", "Test"], "id": 1}}"#, address.hex());
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
let res = tester.io.handle_request_sync(&request);
assert_eq!(res, Some(response.into()));
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
let request = r#"{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"#;
let res = tester.io.handle_request_sync(request);
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
assert_eq!(res, Some(response));
}
#[test]
fn should_be_able_to_set_meta() {
let tester = setup();
tester.accounts.new_account("").unwrap();
let accounts = tester.accounts.accounts().unwrap();
assert_eq!(accounts.len(), 1);
let address = accounts[0];
let request = format!(r#"{{"jsonrpc": "2.0", "method": "personal_setAccountMeta", "params": ["0x{}", "{{foo: 69}}"], "id": 1}}"#, address.hex());
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
let res = tester.io.handle_request_sync(&request);
assert_eq!(res, Some(response.into()));
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
let request = r#"{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"#;
let res = tester.io.handle_request_sync(request);
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"{}\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid, uuid);
assert_eq!(res, Some(response));
}
#[test]
fn sign_and_send_transaction_with_invalid_password() {
let tester = setup();

View File

@@ -21,11 +21,11 @@ use util::{U256, Uint, Address};
use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Transaction, Action};
use v1::{SignerClient, PersonalSigner};
use v1::{SignerClient, Signer};
use v1::tests::helpers::TestMinerService;
use v1::helpers::{SigningQueue, SignerService, FilledTransactionRequest, ConfirmationPayload};
struct PersonalSignerTester {
struct SignerTester {
signer: Arc<SignerService>,
accounts: Arc<AccountProvider>,
io: IoHandler,
@@ -48,7 +48,7 @@ fn miner_service() -> Arc<TestMinerService> {
Arc::new(TestMinerService::default())
}
fn signer_tester() -> PersonalSignerTester {
fn signer_tester() -> SignerTester {
let signer = Arc::new(SignerService::new_test(None));
let accounts = accounts_provider();
let client = blockchain_client();
@@ -57,7 +57,7 @@ fn signer_tester() -> PersonalSignerTester {
let io = IoHandler::new();
io.add_delegate(SignerClient::new(&accounts, &client, &miner, &signer).to_delegate());
PersonalSignerTester {
SignerTester {
signer: signer,
accounts: accounts,
io: io,
@@ -83,7 +83,7 @@ fn should_return_list_of_items_to_confirm() {
tester.signer.add_request(ConfirmationPayload::Sign(1.into(), 5.into())).unwrap();
// when
let request = r#"{"jsonrpc":"2.0","method":"personal_requestsToConfirm","params":[],"id":1}"#;
let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#;
let response = concat!(
r#"{"jsonrpc":"2.0","result":["#,
r#"{"id":"0x1","payload":{"transaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
@@ -112,7 +112,7 @@ fn should_reject_transaction_from_queue_without_dispatching() {
assert_eq!(tester.signer.requests().len(), 1);
// when
let request = r#"{"jsonrpc":"2.0","method":"personal_rejectRequest","params":["0x1"],"id":1}"#;
let request = r#"{"jsonrpc":"2.0","method":"signer_rejectRequest","params":["0x1"],"id":1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
// then
@@ -137,7 +137,7 @@ fn should_not_remove_transaction_if_password_is_invalid() {
assert_eq!(tester.signer.requests().len(), 1);
// when
let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
let request = r#"{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
// then
@@ -153,7 +153,7 @@ fn should_not_remove_sign_if_password_is_invalid() {
assert_eq!(tester.signer.requests().len(), 1);
// when
let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
let request = r#"{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
// then
@@ -194,7 +194,7 @@ fn should_confirm_transaction_and_dispatch() {
// when
let request = r#"{
"jsonrpc":"2.0",
"method":"personal_confirmRequest",
"method":"signer_confirmRequest",
"params":["0x1", {"gasPrice":"0x1000"}, "test"],
"id":1
}"#;
@@ -214,7 +214,7 @@ fn should_generate_new_token() {
// when
let request = r#"{
"jsonrpc":"2.0",
"method":"personal_generateAuthorizationToken",
"method":"signer_generateAuthorizationToken",
"params":[],
"id":1
}"#;

View File

@@ -17,12 +17,12 @@
use std::str::FromStr;
use std::sync::Arc;
use jsonrpc_core::{IoHandler, to_value, Success};
use v1::impls::EthSigningQueueClient;
use v1::traits::{EthSigning, Ethcore};
use v1::impls::SigningQueueClient;
use v1::traits::{EthSigning, ParitySigning, Parity};
use v1::helpers::{SignerService, SigningQueue};
use v1::types::{H256 as RpcH256, H520 as RpcH520, Bytes};
use v1::tests::helpers::TestMinerService;
use v1::tests::mocked::ethcore;
use v1::tests::mocked::parity;
use util::{Address, FixedHash, Uint, U256, H256, H520};
use ethcore::account_provider::AccountProvider;
@@ -31,7 +31,7 @@ use ethcore::transaction::{Transaction, Action};
use ethstore::ethkey::{Generator, Random};
use serde_json;
struct EthSigningTester {
struct SigningTester {
pub signer: Arc<SignerService>,
pub client: Arc<TestBlockChainClient>,
pub miner: Arc<TestMinerService>,
@@ -39,16 +39,19 @@ struct EthSigningTester {
pub io: IoHandler,
}
impl Default for EthSigningTester {
impl Default for SigningTester {
fn default() -> Self {
let signer = Arc::new(SignerService::new_test(None));
let client = Arc::new(TestBlockChainClient::default());
let miner = Arc::new(TestMinerService::default());
let accounts = Arc::new(AccountProvider::transient_provider());
let io = IoHandler::new();
io.add_delegate(EthSigningQueueClient::new(&signer, &client, &miner, &accounts).to_delegate());
let rpc = SigningQueueClient::new(&signer, &client, &miner, &accounts);
io.add_delegate(EthSigning::to_delegate(rpc));
let rpc = SigningQueueClient::new(&signer, &client, &miner, &accounts);
io.add_delegate(ParitySigning::to_delegate(rpc));
EthSigningTester {
SigningTester {
signer: signer,
client: client,
miner: miner,
@@ -58,8 +61,8 @@ impl Default for EthSigningTester {
}
}
fn eth_signing() -> EthSigningTester {
EthSigningTester::default()
fn eth_signing() -> SigningTester {
SigningTester::default()
}
#[test]
@@ -101,7 +104,7 @@ fn should_post_sign_to_queue() {
// when
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_postSign",
"method": "parity_postSign",
"params": [
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
"0x0000000000000000000000000000000000000000000000000000000000000005"
@@ -122,7 +125,7 @@ fn should_check_status_of_request() {
let address = Address::random();
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_postSign",
"method": "parity_postSign",
"params": [
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
"0x0000000000000000000000000000000000000000000000000000000000000005"
@@ -134,7 +137,7 @@ fn should_check_status_of_request() {
// when
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_checkRequest",
"method": "parity_checkRequest",
"params": ["0x1"],
"id": 1
}"#;
@@ -151,7 +154,7 @@ fn should_check_status_of_request_when_its_resolved() {
let address = Address::random();
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_postSign",
"method": "parity_postSign",
"params": [
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
"0x0000000000000000000000000000000000000000000000000000000000000005"
@@ -164,7 +167,7 @@ fn should_check_status_of_request_when_its_resolved() {
// when
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_checkRequest",
"method": "parity_checkRequest",
"params": ["0x1"],
"id": 1
}"#;
@@ -272,15 +275,15 @@ fn should_dispatch_transaction_if_account_is_unlock() {
fn should_decrypt_message_if_account_is_unlocked() {
// given
let tester = eth_signing();
let ethcore = ethcore::Dependencies::new();
tester.io.add_delegate(ethcore.client(None).to_delegate());
let parity = parity::Dependencies::new();
tester.io.add_delegate(parity.client(None).to_delegate());
let (address, public) = tester.accounts.new_account_and_public("test").unwrap();
tester.accounts.unlock_account_permanently(address, "test".into()).unwrap();
// First encrypt message
let request = format!("{}0x{:?}{}",
r#"{"jsonrpc": "2.0", "method": "ethcore_encryptMessage", "params":[""#,
r#"{"jsonrpc": "2.0", "method": "parity_encryptMessage", "params":[""#,
public,
r#"", "0x01020304"], "id": 1}"#
);
@@ -288,7 +291,7 @@ fn should_decrypt_message_if_account_is_unlocked() {
// then call decrypt
let request = format!("{}{:?}{}{:?}{}",
r#"{"jsonrpc": "2.0", "method": "ethcore_decryptMessage", "params":["0x"#,
r#"{"jsonrpc": "2.0", "method": "parity_decryptMessage", "params":["0x"#,
address,
r#"","#,
encrypted.result,
@@ -311,7 +314,7 @@ fn should_add_decryption_to_the_queue() {
// when
let request = r#"{
"jsonrpc": "2.0",
"method": "ethcore_decryptMessage",
"method": "parity_decryptMessage",
"params": ["0x"#.to_owned() + &format!("{:?}", acc.address()) + r#"",
"0x012345"],
"id": 1

View File

@@ -23,41 +23,18 @@ pub trait EthSigning: Sized + Send + Sync + 'static {
/// Signs the data with given address signature.
fn sign(&self, _: Params, _: Ready);
/// Posts sign request asynchronously.
/// Will return a confirmation ID for later use with check_transaction.
fn post_sign(&self, _: Params) -> Result<Value, Error>;
/// Sends transaction; will block for 20s to try to return the
/// transaction hash.
/// If it cannot yet be signed, it will return a transaction ID for
/// later use with check_transaction.
fn send_transaction(&self, _: Params, _: Ready);
/// Posts transaction asynchronously.
/// Will return a transaction ID for later use with check_transaction.
fn post_transaction(&self, _: Params) -> Result<Value, Error>;
/// Checks the progress of a previously posted request (transaction/sign).
/// Should be given a valid send_transaction ID.
/// Returns the transaction hash, the zero hash (not yet available),
/// or the signature,
/// or an error.
fn check_request(&self, _: Params) -> Result<Value, Error>;
/// Decrypt some ECIES-encrypted message.
/// First parameter is the address with which it is encrypted, second is the ciphertext.
fn decrypt_message(&self, _: Params, _: Ready);
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
delegate.add_async_method("eth_sign", EthSigning::sign);
delegate.add_async_method("eth_sendTransaction", EthSigning::send_transaction);
delegate.add_async_method("ethcore_decryptMessage", EthSigning::decrypt_message);
delegate.add_method("eth_postSign", EthSigning::post_sign);
delegate.add_method("eth_postTransaction", EthSigning::post_transaction);
delegate.add_method("eth_checkRequest", EthSigning::check_request);
delegate
}
}

View File

@@ -20,9 +20,12 @@ pub mod web3;
pub mod eth;
pub mod eth_signing;
pub mod net;
pub mod parity;
pub mod parity_accounts;
pub mod parity_set;
pub mod parity_signing;
pub mod personal;
pub mod ethcore;
pub mod ethcore_set;
pub mod signer;
pub mod traces;
pub mod rpc;
@@ -30,9 +33,12 @@ pub use self::web3::Web3;
pub use self::eth::{Eth, EthFilter};
pub use self::eth_signing::EthSigning;
pub use self::net::Net;
pub use self::personal::{Personal, PersonalAccounts, PersonalSigner};
pub use self::ethcore::Ethcore;
pub use self::ethcore_set::EthcoreSet;
pub use self::parity::Parity;
pub use self::parity_accounts::ParityAccounts;
pub use self::parity_set::ParitySet;
pub use self::parity_signing::ParitySigning;
pub use self::personal::Personal;
pub use self::signer::Signer;
pub use self::traces::Traces;
pub use self::rpc::Rpc;

View File

@@ -14,128 +14,129 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore-specific rpc interface.
//! Parity-specific rpc interface.
use jsonrpc_core::Error;
use v1::helpers::auto_args::{Wrap, WrapAsync, Ready};
use std::collections::BTreeMap;
use v1::helpers::auto_args::Wrap;
use v1::types::{H160, H256, H512, U256, Bytes, Peers, Transaction, RpcSettings, Histogram};
build_rpc_trait! {
/// Ethcore-specific rpc interface.
pub trait Ethcore {
/// Parity-specific rpc interface.
pub trait Parity {
/// Returns current transactions limit.
#[rpc(name = "ethcore_transactionsLimit")]
#[rpc(name = "parity_transactionsLimit")]
fn transactions_limit(&self) -> Result<usize, Error>;
/// Returns mining extra data.
#[rpc(name = "ethcore_extraData")]
#[rpc(name = "parity_extraData")]
fn extra_data(&self) -> Result<Bytes, Error>;
/// Returns mining gas floor target.
#[rpc(name = "ethcore_gasFloorTarget")]
#[rpc(name = "parity_gasFloorTarget")]
fn gas_floor_target(&self) -> Result<U256, Error>;
/// Returns mining gas floor cap.
#[rpc(name = "ethcore_gasCeilTarget")]
#[rpc(name = "parity_gasCeilTarget")]
fn gas_ceil_target(&self) -> Result<U256, Error>;
/// Returns minimal gas price for transaction to be included in queue.
#[rpc(name = "ethcore_minGasPrice")]
#[rpc(name = "parity_minGasPrice")]
fn min_gas_price(&self) -> Result<U256, Error>;
/// Returns latest logs
#[rpc(name = "ethcore_devLogs")]
#[rpc(name = "parity_devLogs")]
fn dev_logs(&self) -> Result<Vec<String>, Error>;
/// Returns logs levels
#[rpc(name = "ethcore_devLogsLevels")]
#[rpc(name = "parity_devLogsLevels")]
fn dev_logs_levels(&self) -> Result<String, Error>;
/// Returns chain name
#[rpc(name = "ethcore_netChain")]
#[rpc(name = "parity_netChain")]
fn net_chain(&self) -> Result<String, Error>;
/// Returns peers details
#[rpc(name = "ethcore_netPeers")]
#[rpc(name = "parity_netPeers")]
fn net_peers(&self) -> Result<Peers, Error>;
/// Returns network port
#[rpc(name = "ethcore_netPort")]
#[rpc(name = "parity_netPort")]
fn net_port(&self) -> Result<u16, Error>;
/// Returns rpc settings
#[rpc(name = "ethcore_rpcSettings")]
#[rpc(name = "parity_rpcSettings")]
fn rpc_settings(&self) -> Result<RpcSettings, Error>;
/// Returns node name
#[rpc(name = "ethcore_nodeName")]
#[rpc(name = "parity_nodeName")]
fn node_name(&self) -> Result<String, Error>;
/// Returns default extra data
#[rpc(name = "ethcore_defaultExtraData")]
#[rpc(name = "parity_defaultExtraData")]
fn default_extra_data(&self) -> Result<Bytes, Error>;
/// Returns distribution of gas price in latest blocks.
#[rpc(name = "ethcore_gasPriceHistogram")]
#[rpc(name = "parity_gasPriceHistogram")]
fn gas_price_histogram(&self) -> Result<Histogram, Error>;
/// Returns number of unsigned transactions waiting in the signer queue (if signer enabled)
/// Returns error when signer is disabled
#[rpc(name = "ethcore_unsignedTransactionsCount")]
#[rpc(name = "parity_unsignedTransactionsCount")]
fn unsigned_transactions_count(&self) -> Result<usize, Error>;
/// Returns a cryptographically random phrase sufficient for securely seeding a secret key.
#[rpc(name = "ethcore_generateSecretPhrase")]
#[rpc(name = "parity_generateSecretPhrase")]
fn generate_secret_phrase(&self) -> Result<String, Error>;
/// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet.
#[rpc(name = "ethcore_phraseToAddress")]
#[rpc(name = "parity_phraseToAddress")]
fn phrase_to_address(&self, String) -> Result<H160, Error>;
/// Returns the value of the registrar for this network.
#[rpc(name = "ethcore_registryAddress")]
#[rpc(name = "parity_registryAddress")]
fn registry_address(&self) -> Result<Option<H160>, Error>;
/// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not.
#[rpc(name = "ethcore_listAccounts")]
#[rpc(name = "parity_listAccounts")]
fn list_accounts(&self) -> Result<Option<Vec<H160>>, Error>;
/// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`),
/// or null if not.
#[rpc(name = "ethcore_listStorageKeys")]
#[rpc(name = "parity_listStorageKeys")]
fn list_storage_keys(&self, H160) -> Result<Option<Vec<H256>>, Error>;
/// Encrypt some data with a public key under ECIES.
/// First parameter is the 512-byte destination public key, second is the message.
#[rpc(name = "ethcore_encryptMessage")]
#[rpc(name = "parity_encryptMessage")]
fn encrypt_message(&self, H512, Bytes) -> Result<Bytes, Error>;
/// Returns all pending transactions from transaction queue.
#[rpc(name = "ethcore_pendingTransactions")]
#[rpc(name = "parity_pendingTransactions")]
fn pending_transactions(&self) -> Result<Vec<Transaction>, Error>;
/// Hash a file content under given URL.
#[rpc(async, name = "ethcore_hashContent")]
fn hash_content(&self, Ready<H256>, String);
/// Returns current Trusted Signer port or an error if signer is disabled.
#[rpc(name = "ethcore_signerPort")]
#[rpc(name = "parity_signerPort")]
fn signer_port(&self) -> Result<u16, Error>;
/// Returns current Dapps Server port or an error if dapps server is disabled.
#[rpc(name = "ethcore_dappsPort")]
#[rpc(name = "parity_dappsPort")]
fn dapps_port(&self) -> Result<u16, Error>;
/// Returns next nonce for particular sender. Should include all transactions in the queue.
#[rpc(name = "ethcore_nextNonce")]
#[rpc(name = "parity_nextNonce")]
fn next_nonce(&self, H160) -> Result<U256, Error>;
/// Get the mode. Results one of: "active", "passive", "dark", "offline".
#[rpc(name = "ethcore_mode")]
#[rpc(name = "parity_mode")]
fn mode(&self) -> Result<String, Error>;
/// Get the enode of this node.
#[rpc(name = "ethcore_enode")]
#[rpc(name = "parity_enode")]
fn enode(&self) -> Result<String, Error>;
/// Returns accounts information.
#[rpc(name = "parity_accounts")]
fn accounts(&self) -> Result<BTreeMap<String, BTreeMap<String, String>>, Error>;
}
}

View File

@@ -0,0 +1,77 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Parity Accounts-related rpc interface.
use std::collections::BTreeMap;
use jsonrpc_core::{Value, Error};
use v1::helpers::auto_args::Wrap;
use v1::types::{H160, H256};
build_rpc_trait! {
/// Personal Parity rpc interface.
pub trait ParityAccounts {
/// Returns accounts information.
#[rpc(name = "parity_accountsInfo")]
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error>;
/// Creates new account from the given phrase using standard brainwallet mechanism.
/// Second parameter is password for the new account.
#[rpc(name = "parity_newAccountFromPhrase")]
fn new_account_from_phrase(&self, String, String) -> Result<H160, Error>;
/// Creates new account from the given JSON wallet.
/// Second parameter is password for the wallet and the new account.
#[rpc(name = "parity_newAccountFromWallet")]
fn new_account_from_wallet(&self, String, String) -> Result<H160, Error>;
/// Creates new account from the given raw secret.
/// Second parameter is password for the new account.
#[rpc(name = "parity_newAccountFromSecret")]
fn new_account_from_secret(&self, H256, String) -> Result<H160, Error>;
/// Returns true if given `password` would unlock given `account`.
/// Arguments: `account`, `password`.
#[rpc(name = "parity_testPassword")]
fn test_password(&self, H160, String) -> Result<bool, Error>;
/// Changes an account's password.
/// Arguments: `account`, `password`, `new_password`.
#[rpc(name = "parity_changePassword")]
fn change_password(&self, H160, String, String) -> Result<bool, Error>;
/// Set an account's name.
#[rpc(name = "parity_setAccountName")]
fn set_account_name(&self, H160, String) -> Result<bool, Error>;
/// Set an account's metadata string.
#[rpc(name = "parity_setAccountMeta")]
fn set_account_meta(&self, H160, String) -> Result<bool, Error>;
/// Returns accounts information.
#[rpc(name = "parity_setAccountVisiblity")]
fn set_account_visibility(&self, H160, H256, bool) -> Result<bool, Error>;
/// Imports a number of Geth accounts, with the list provided as the argument.
#[rpc(name = "parity_importGethAccounts")]
fn import_geth_accounts(&self, Vec<H160>) -> Result<Vec<H160>, Error>;
/// Returns the accounts available for importing from Geth.
#[rpc(name = "parity_listGethAccounts")]
fn geth_accounts(&self) -> Result<Vec<H160>, Error>;
}
}

View File

@@ -14,74 +14,78 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore-specific rpc interface for operations altering the settings.
//! Parity-specific rpc interface for operations altering the settings.
use jsonrpc_core::Error;
use v1::helpers::auto_args::Wrap;
use v1::types::{Bytes, H160, U256};
use v1::helpers::auto_args::{Wrap, WrapAsync, Ready};
use v1::types::{Bytes, H160, H256, U256};
build_rpc_trait! {
/// Ethcore-specific rpc interface for operations altering the settings.
pub trait EthcoreSet {
/// Parity-specific rpc interface for operations altering the settings.
pub trait ParitySet {
/// Sets new minimal gas price for mined blocks.
#[rpc(name = "ethcore_setMinGasPrice")]
#[rpc(name = "parity_setMinGasPrice")]
fn set_min_gas_price(&self, U256) -> Result<bool, Error>;
/// Sets new gas floor target for mined blocks.
#[rpc(name = "ethcore_setGasFloorTarget")]
#[rpc(name = "parity_setGasFloorTarget")]
fn set_gas_floor_target(&self, U256) -> Result<bool, Error>;
/// Sets new gas ceiling target for mined blocks.
#[rpc(name = "ethcore_setGasCeilTarget")]
#[rpc(name = "parity_setGasCeilTarget")]
fn set_gas_ceil_target(&self, U256) -> Result<bool, Error>;
/// Sets new extra data for mined blocks.
#[rpc(name = "ethcore_setExtraData")]
#[rpc(name = "parity_setExtraData")]
fn set_extra_data(&self, Bytes) -> Result<bool, Error>;
/// Sets new author for mined block.
#[rpc(name = "ethcore_setAuthor")]
#[rpc(name = "parity_setAuthor")]
fn set_author(&self, H160) -> Result<bool, Error>;
/// Sets the limits for transaction queue.
#[rpc(name = "ethcore_setTransactionsLimit")]
#[rpc(name = "parity_setTransactionsLimit")]
fn set_transactions_limit(&self, usize) -> Result<bool, Error>;
/// Sets the maximum amount of gas a single transaction may consume.
#[rpc(name = "ethcore_setMaxTransactionGas")]
#[rpc(name = "parity_setMaxTransactionGas")]
fn set_tx_gas_limit(&self, U256) -> Result<bool, Error>;
/// Add a reserved peer.
#[rpc(name = "ethcore_addReservedPeer")]
#[rpc(name = "parity_addReservedPeer")]
fn add_reserved_peer(&self, String) -> Result<bool, Error>;
/// Remove a reserved peer.
#[rpc(name = "ethcore_removeReservedPeer")]
#[rpc(name = "parity_removeReservedPeer")]
fn remove_reserved_peer(&self, String) -> Result<bool, Error>;
/// Drop all non-reserved peers.
#[rpc(name = "ethcore_dropNonReservedPeers")]
#[rpc(name = "parity_dropNonReservedPeers")]
fn drop_non_reserved_peers(&self) -> Result<bool, Error>;
/// Accept non-reserved peers (default behavior)
#[rpc(name = "ethcore_acceptNonReservedPeers")]
#[rpc(name = "parity_acceptNonReservedPeers")]
fn accept_non_reserved_peers(&self) -> Result<bool, Error>;
/// Start the network.
///
///
/// Deprecated. Use `set_mode("active")` instead.
#[rpc(name = "ethcore_startNetwork")]
#[rpc(name = "parity_startNetwork")]
fn start_network(&self) -> Result<bool, Error>;
/// Stop the network.
///
/// Deprecated. Use `set_mode("offline")` instead.
#[rpc(name = "ethcore_stopNetwork")]
#[rpc(name = "parity_stopNetwork")]
fn stop_network(&self) -> Result<bool, Error>;
/// Set the mode. Argument must be one of: "active", "passive", "dark", "offline".
#[rpc(name = "ethcore_setMode")]
#[rpc(name = "parity_setMode")]
fn set_mode(&self, String) -> Result<bool, Error>;
/// Hash a file content under given URL.
#[rpc(async, name = "parity_hashContent")]
fn hash_content(&self, Ready<H256>, String);
}
}
}

View File

@@ -0,0 +1,52 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! ParitySigning rpc interface.
use std::sync::Arc;
use jsonrpc_core::*;
/// Signing methods implementation relying on unlocked accounts.
pub trait ParitySigning: Sized + Send + Sync + 'static {
/// Posts sign request asynchronously.
/// Will return a confirmation ID for later use with check_transaction.
fn post_sign(&self, _: Params) -> Result<Value, Error>;
/// Posts transaction asynchronously.
/// Will return a transaction ID for later use with check_transaction.
fn post_transaction(&self, _: Params) -> Result<Value, Error>;
/// Checks the progress of a previously posted request (transaction/sign).
/// Should be given a valid send_transaction ID.
/// Returns the transaction hash, the zero hash (not yet available),
/// or the signature,
/// or an error.
fn check_request(&self, _: Params) -> Result<Value, Error>;
/// Decrypt some ECIES-encrypted message.
/// First parameter is the address with which it is encrypted, second is the ciphertext.
fn decrypt_message(&self, _: Params, _: Ready);
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
delegate.add_method("parity_postSign", ParitySigning::post_sign);
delegate.add_method("parity_postTransaction", ParitySigning::post_transaction);
delegate.add_method("parity_checkRequest", ParitySigning::check_request);
delegate.add_async_method("parity_decryptMessage", ParitySigning::decrypt_message);
delegate
}
}

View File

@@ -15,11 +15,10 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Personal rpc interface.
use std::collections::BTreeMap;
use jsonrpc_core::{Value, Error};
use jsonrpc_core::Error;
use v1::helpers::auto_args::Wrap;
use v1::types::{H160, H256, U256, TransactionRequest, TransactionModification, ConfirmationRequest};
use v1::types::{H160, H256, TransactionRequest};
build_rpc_trait! {
/// Personal rpc interface. Safe (read-only) functions.
@@ -28,91 +27,17 @@ build_rpc_trait! {
#[rpc(name = "personal_listAccounts")]
fn accounts(&self) -> Result<Vec<H160>, Error>;
/// Returns accounts information.
#[rpc(name = "personal_accountsInfo")]
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error>;
}
}
build_rpc_trait! {
/// Personal rpc methods altering stored accounts or their settings.
pub trait PersonalAccounts {
/// Creates new account (it becomes new current unlocked account)
/// Param is the password for the account.
#[rpc(name = "personal_newAccount")]
fn new_account(&self, String) -> Result<H160, Error>;
/// Creates new account from the given phrase using standard brainwallet mechanism.
/// Second parameter is password for the new account.
#[rpc(name = "personal_newAccountFromPhrase")]
fn new_account_from_phrase(&self, String, String) -> Result<H160, Error>;
/// Creates new account from the given JSON wallet.
/// Second parameter is password for the wallet and the new account.
#[rpc(name = "personal_newAccountFromWallet")]
fn new_account_from_wallet(&self, String, String) -> Result<H160, Error>;
/// Creates new account from the given raw secret.
/// Second parameter is password for the new account.
#[rpc(name = "personal_newAccountFromSecret")]
fn new_account_from_secret(&self, H256, String) -> Result<H160, Error>;
/// Unlocks specified account for use (can only be one unlocked account at one moment)
#[rpc(name = "personal_unlockAccount")]
fn unlock_account(&self, H160, String, Option<u64>) -> Result<bool, Error>;
/// Returns true if given `password` would unlock given `account`.
/// Arguments: `account`, `password`.
#[rpc(name = "personal_testPassword")]
fn test_password(&self, H160, String) -> Result<bool, Error>;
/// Changes an account's password.
/// Arguments: `account`, `password`, `new_password`.
#[rpc(name = "personal_changePassword")]
fn change_password(&self, H160, String, String) -> Result<bool, Error>;
/// Sends transaction and signs it in single call. The account is not unlocked in such case.
#[rpc(name = "personal_signAndSendTransaction")]
fn sign_and_send_transaction(&self, TransactionRequest, String) -> Result<H256, Error>;
/// Set an account's name.
#[rpc(name = "personal_setAccountName")]
fn set_account_name(&self, H160, String) -> Result<bool, Error>;
/// Set an account's metadata string.
#[rpc(name = "personal_setAccountMeta")]
fn set_account_meta(&self, H160, String) -> Result<bool, Error>;
/// Imports a number of Geth accounts, with the list provided as the argument.
#[rpc(name = "personal_importGethAccounts")]
fn import_geth_accounts(&self, Vec<H160>) -> Result<Vec<H160>, Error>;
/// Returns the accounts available for importing from Geth.
#[rpc(name = "personal_listGethAccounts")]
fn geth_accounts(&self) -> Result<Vec<H160>, Error>;
}
}
build_rpc_trait! {
/// Personal extension for confirmations rpc interface.
pub trait PersonalSigner {
/// Returns a list of items to confirm.
#[rpc(name = "personal_requestsToConfirm")]
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error>;
/// Confirm specific request.
#[rpc(name = "personal_confirmRequest")]
fn confirm_request(&self, U256, TransactionModification, String) -> Result<Value, Error>;
/// Reject the confirmation request.
#[rpc(name = "personal_rejectRequest")]
fn reject_request(&self, U256) -> Result<bool, Error>;
/// Generates new authorization token.
#[rpc(name = "personal_generateAuthorizationToken")]
fn generate_token(&self) -> Result<String, Error>;
}
}

View File

@@ -0,0 +1,44 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Parity Signer-related rpc interface.
use jsonrpc_core::{Value, Error};
use v1::helpers::auto_args::Wrap;
use v1::types::{U256, TransactionModification, ConfirmationRequest};
build_rpc_trait! {
/// Signer extension for confirmations rpc interface.
pub trait Signer {
/// Returns a list of items to confirm.
#[rpc(name = "signer_requestsToConfirm")]
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error>;
/// Confirm specific request.
#[rpc(name = "signer_confirmRequest")]
fn confirm_request(&self, U256, TransactionModification, String) -> Result<Value, Error>;
/// Reject the confirmation request.
#[rpc(name = "signer_rejectRequest")]
fn reject_request(&self, U256) -> Result<bool, Error>;
/// Generates new authorization token.
#[rpc(name = "signer_generateAuthorizationToken")]
fn generate_token(&self) -> Result<String, Error>;
}
}