Merge branch 'lightcli' into light-filters

This commit is contained in:
Robert Habermeier
2017-04-03 09:03:12 +02:00
469 changed files with 9459 additions and 11074 deletions

View File

@@ -12,7 +12,7 @@ futures = "0.1"
log = "0.3"
order-stat = "0.1"
rustc-serialize = "0.3"
semver = "0.5"
semver = "0.6"
serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"

View File

@@ -6,8 +6,8 @@ license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
docopt = "0.6"
ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" }
docopt = "0.7"
rustc-serialize = "0.3"
ethcore = { path = "../../ethcore" }
ethcore-devtools = { path = "../../devtools" }

View File

@@ -0,0 +1,27 @@
// Copyright 2015-2017 Parity Technologies (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, Weak};
use ethcore::account_provider::AccountProvider;
use jsonrpc_core::Error;
use v1::helpers::errors;
pub fn unwrap_provider(provider: &Option<Weak<AccountProvider>>) -> Result<Arc<AccountProvider>, Error> {
match *provider {
Some(ref weak) => weak.upgrade().ok_or_else(Error::internal_error),
None => Err(errors::public_unsupported(None)),
}
}

View File

@@ -65,6 +65,14 @@ pub fn light_unimplemented(details: Option<String>) -> Error {
}
}
pub fn public_unsupported(details: Option<String>) -> Error {
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "Method disallowed when running parity as a public node.".into(),
data: details.map(Value::String),
}
}
pub fn request_not_found() -> Error {
Error {
code: ErrorCode::ServerError(codes::REQUEST_NOT_FOUND),

View File

@@ -17,6 +17,7 @@
#[macro_use]
pub mod errors;
pub mod accounts;
pub mod block_import;
pub mod dispatch;
pub mod fake_sign;

View File

@@ -46,6 +46,7 @@ use jsonrpc_macros::Trailing;
use v1::helpers::{errors, limit_logs, fake_sign};
use v1::helpers::dispatch::{Dispatcher, FullDispatcher, default_gas_price};
use v1::helpers::block_import::is_major_importing;
use v1::helpers::accounts::unwrap_provider;
use v1::traits::Eth;
use v1::types::{
RichBlock, Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo,
@@ -97,7 +98,7 @@ pub struct EthClient<C, SN: ?Sized, S: ?Sized, M, EM> where
client: Weak<C>,
snapshot: Weak<SN>,
sync: Weak<S>,
accounts: Weak<AccountProvider>,
accounts: Option<Weak<AccountProvider>>,
miner: Weak<M>,
external_miner: Arc<EM>,
seed_compute: Mutex<SeedHashCompute>,
@@ -116,7 +117,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
client: &Arc<C>,
snapshot: &Arc<SN>,
sync: &Arc<S>,
accounts: &Arc<AccountProvider>,
accounts: &Option<Arc<AccountProvider>>,
miner: &Arc<M>,
em: &Arc<EM>,
options: EthClientOptions
@@ -126,13 +127,19 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
snapshot: Arc::downgrade(snapshot),
sync: Arc::downgrade(sync),
miner: Arc::downgrade(miner),
accounts: Arc::downgrade(accounts),
accounts: accounts.as_ref().map(Arc::downgrade),
external_miner: em.clone(),
seed_compute: Mutex::new(SeedHashCompute::new()),
options: options,
}
}
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
/// set, or if upgrading the weak reference failed.
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
unwrap_provider(&self.accounts)
}
fn block(&self, id: BlockId, include_txs: bool) -> Result<Option<RichBlock>, Error> {
let client = take_weak!(self.client);
match (client.block(id.clone()), client.block_total_difficulty(id)) {
@@ -223,7 +230,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
}
fn dapp_accounts(&self, dapp: DappId) -> Result<Vec<H160>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store
.note_dapp_used(dapp.clone())
.and_then(|_| store.dapp_addresses(dapp))

View File

@@ -40,7 +40,7 @@ use v1::types::{
TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, DappId, ChainStatus,
AccountInfo, HwAccountInfo
AccountInfo, HwAccountInfo,
};
/// Parity implementation for light client.
@@ -333,4 +333,13 @@ impl Parity for ParityClient {
block_gap: gap.map(|(x, y)| (x.into(), y.into())),
})
}
fn node_kind(&self) -> Result<::v1::types::NodeKind, Error> {
use ::v1::types::{NodeKind, Availability, Capability};
Ok(NodeKind {
availability: Availability::Personal,
capability: Capability::Light,
})
}
}

View File

@@ -37,6 +37,7 @@ use updater::{Service as UpdateService};
use jsonrpc_core::Error;
use jsonrpc_macros::Trailing;
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
use v1::helpers::accounts::unwrap_provider;
use v1::helpers::dispatch::DEFAULT_MAC;
use v1::metadata::Metadata;
use v1::traits::Parity;
@@ -46,7 +47,7 @@ use v1::types::{
TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, DappId, ChainStatus,
AccountInfo, HwAccountInfo
AccountInfo, HwAccountInfo,
};
/// Parity implementation.
@@ -61,7 +62,7 @@ pub struct ParityClient<C, M, S: ?Sized, U> where
sync: Weak<S>,
updater: Weak<U>,
net: Weak<ManageNetwork>,
accounts: Weak<AccountProvider>,
accounts: Option<Weak<AccountProvider>>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
signer: Option<Arc<SignerService>>,
@@ -82,7 +83,7 @@ impl<C, M, S: ?Sized, U> ParityClient<C, M, S, U> where
sync: &Arc<S>,
updater: &Arc<U>,
net: &Arc<ManageNetwork>,
store: &Arc<AccountProvider>,
store: &Option<Arc<AccountProvider>>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
signer: Option<Arc<SignerService>>,
@@ -95,7 +96,7 @@ impl<C, M, S: ?Sized, U> ParityClient<C, M, S, U> where
sync: Arc::downgrade(sync),
updater: Arc::downgrade(updater),
net: Arc::downgrade(net),
accounts: Arc::downgrade(store),
accounts: store.as_ref().map(Arc::downgrade),
logger: logger,
settings: settings,
signer: signer,
@@ -103,6 +104,12 @@ impl<C, M, S: ?Sized, U> ParityClient<C, M, S, U> where
dapps_port: dapps_port,
}
}
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
/// set, or if upgrading the weak reference failed.
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
unwrap_provider(&self.accounts)
}
}
impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
@@ -116,7 +123,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
fn accounts_info(&self, dapp: Trailing<DappId>) -> Result<BTreeMap<H160, AccountInfo>, Error> {
let dapp = dapp.0;
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let dapp_accounts = store
.note_dapp_used(dapp.clone().into())
.and_then(|_| store.dapp_addresses(dapp.into()))
@@ -136,7 +143,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
}
fn hardware_accounts_info(&self) -> Result<BTreeMap<H160, HwAccountInfo>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let info = store.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
Ok(info
.into_iter()
@@ -148,7 +155,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
fn default_account(&self, meta: Self::Metadata) -> BoxFuture<H160, Error> {
let dapp_id = meta.dapp_id();
future::ok(
take_weakf!(self.accounts)
try_bf!(self.account_provider())
.dapp_default_address(dapp_id.into())
.map(Into::into)
.ok()
@@ -372,4 +379,18 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
block_gap: gap.map(|(x, y)| (x.into(), y.into())),
})
}
fn node_kind(&self) -> Result<::v1::types::NodeKind, Error> {
use ::v1::types::{NodeKind, Availability, Capability};
let availability = match self.accounts {
Some(_) => Availability::Personal,
None => Availability::Public
};
Ok(NodeKind {
availability: availability,
capability: Capability::Full,
})
}
}

View File

@@ -25,26 +25,33 @@ use ethcore::account_provider::AccountProvider;
use jsonrpc_core::Error;
use v1::helpers::errors;
use v1::helpers::accounts::unwrap_provider;
use v1::traits::ParityAccounts;
use v1::types::{H160 as RpcH160, H256 as RpcH256, DappId, Derive, DeriveHierarchical, DeriveHash};
/// Account management (personal) rpc implementation.
pub struct ParityAccountsClient {
accounts: Weak<AccountProvider>,
accounts: Option<Weak<AccountProvider>>,
}
impl ParityAccountsClient {
/// Creates new PersonalClient
pub fn new(store: &Arc<AccountProvider>) -> Self {
pub fn new(store: &Option<Arc<AccountProvider>>) -> Self {
ParityAccountsClient {
accounts: Arc::downgrade(store),
accounts: store.as_ref().map(Arc::downgrade),
}
}
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
/// set, or if upgrading the weak reference failed.
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
unwrap_provider(&self.accounts)
}
}
impl ParityAccounts for ParityAccountsClient {
fn all_accounts_info(&self) -> Result<BTreeMap<RpcH160, BTreeMap<String, String>>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let info = store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
let other = store.addresses_info();
@@ -66,7 +73,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn new_account_from_phrase(&self, phrase: String, pass: String) -> Result<RpcH160, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let brain = Brain::new(phrase).generate().unwrap();
store.insert_account(brain.secret().clone(), &pass)
@@ -75,7 +82,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn new_account_from_wallet(&self, json: String, pass: String) -> Result<RpcH160, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.import_presale(json.as_bytes(), &pass)
.or_else(|_| store.import_wallet(json.as_bytes(), &pass))
@@ -84,7 +91,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn new_account_from_secret(&self, secret: RpcH256, pass: String) -> Result<RpcH160, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let secret = Secret::from_slice(&secret.0)
.map_err(|e| errors::account("Could not create account.", e))?;
@@ -96,14 +103,14 @@ impl ParityAccounts for ParityAccountsClient {
fn test_password(&self, account: RpcH160, password: String) -> Result<bool, Error> {
let account: Address = account.into();
take_weak!(self.accounts)
self.account_provider()?
.test_password(&account, &password)
.map_err(|e| errors::account("Could not fetch account info.", e))
}
fn change_password(&self, account: RpcH160, password: String, new_password: String) -> Result<bool, Error> {
let account: Address = account.into();
take_weak!(self.accounts)
self.account_provider()?
.change_password(&account, password, new_password)
.map(|_| true)
.map_err(|e| errors::account("Could not fetch account info.", e))
@@ -111,14 +118,14 @@ impl ParityAccounts for ParityAccountsClient {
fn kill_account(&self, account: RpcH160, password: String) -> Result<bool, Error> {
let account: Address = account.into();
take_weak!(self.accounts)
self.account_provider()?
.kill_account(&account, &password)
.map(|_| true)
.map_err(|e| errors::account("Could not delete account.", e))
}
fn remove_address(&self, addr: RpcH160) -> Result<bool, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let addr: Address = addr.into();
store.remove_address(addr);
@@ -126,7 +133,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn set_account_name(&self, addr: RpcH160, name: String) -> Result<bool, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let addr: Address = addr.into();
store.set_account_name(addr.clone(), name.clone())
@@ -135,7 +142,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn set_account_meta(&self, addr: RpcH160, meta: String) -> Result<bool, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let addr: Address = addr.into();
store.set_account_meta(addr.clone(), meta.clone())
@@ -144,7 +151,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<RpcH160>>) -> Result<bool, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.set_dapp_addresses(dapp.into(), addresses.map(into_vec))
.map_err(|e| errors::account("Couldn't set dapp addresses.", e))
@@ -152,7 +159,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<RpcH160>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.dapp_addresses(dapp.into())
.map_err(|e| errors::account("Couldn't get dapp addresses.", e))
@@ -160,7 +167,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn set_dapp_default_address(&self, dapp: DappId, address: RpcH160) -> Result<bool, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.set_dapp_default_address(dapp.into(), address.into())
.map_err(|e| errors::account("Couldn't set dapp default address.", e))
@@ -168,7 +175,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn dapp_default_address(&self, dapp: DappId) -> Result<RpcH160, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.dapp_default_address(dapp.into())
.map_err(|e| errors::account("Couldn't get dapp default address.", e))
@@ -176,7 +183,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn set_new_dapps_addresses(&self, addresses: Option<Vec<RpcH160>>) -> Result<bool, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store
.set_new_dapps_addresses(addresses.map(into_vec))
@@ -185,7 +192,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn new_dapps_addresses(&self) -> Result<Option<Vec<RpcH160>>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.new_dapps_addresses()
.map_err(|e| errors::account("Couldn't get dapps addresses.", e))
@@ -193,7 +200,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn set_new_dapps_default_address(&self, address: RpcH160) -> Result<bool, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.set_new_dapps_default_address(address.into())
.map_err(|e| errors::account("Couldn't set new dapps default address.", e))
@@ -201,7 +208,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn new_dapps_default_address(&self) -> Result<RpcH160, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.new_dapps_default_address()
.map_err(|e| errors::account("Couldn't get new dapps default address.", e))
@@ -209,7 +216,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn recent_dapps(&self) -> Result<BTreeMap<DappId, u64>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.recent_dapps()
.map_err(|e| errors::account("Couldn't get recent dapps.", e))
@@ -217,7 +224,7 @@ impl ParityAccounts for ParityAccountsClient {
}
fn import_geth_accounts(&self, addresses: Vec<RpcH160>) -> Result<Vec<RpcH160>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store
.import_geth_accounts(into_vec(addresses), false)
@@ -226,66 +233,66 @@ impl ParityAccounts for ParityAccountsClient {
}
fn geth_accounts(&self) -> Result<Vec<RpcH160>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
Ok(into_vec(store.list_geth_accounts(false)))
}
fn create_vault(&self, name: String, password: String) -> Result<bool, Error> {
take_weak!(self.accounts)
self.account_provider()?
.create_vault(&name, &password)
.map_err(|e| errors::account("Could not create vault.", e))
.map(|_| true)
}
fn open_vault(&self, name: String, password: String) -> Result<bool, Error> {
take_weak!(self.accounts)
self.account_provider()?
.open_vault(&name, &password)
.map_err(|e| errors::account("Could not open vault.", e))
.map(|_| true)
}
fn close_vault(&self, name: String) -> Result<bool, Error> {
take_weak!(self.accounts)
self.account_provider()?
.close_vault(&name)
.map_err(|e| errors::account("Could not close vault.", e))
.map(|_| true)
}
fn list_vaults(&self) -> Result<Vec<String>, Error> {
take_weak!(self.accounts)
self.account_provider()?
.list_vaults()
.map_err(|e| errors::account("Could not list vaults.", e))
}
fn list_opened_vaults(&self) -> Result<Vec<String>, Error> {
take_weak!(self.accounts)
self.account_provider()?
.list_opened_vaults()
.map_err(|e| errors::account("Could not list vaults.", e))
}
fn change_vault_password(&self, name: String, new_password: String) -> Result<bool, Error> {
take_weak!(self.accounts)
self.account_provider()?
.change_vault_password(&name, &new_password)
.map_err(|e| errors::account("Could not change vault password.", e))
.map(|_| true)
}
fn change_vault(&self, address: RpcH160, new_vault: String) -> Result<bool, Error> {
take_weak!(self.accounts)
self.account_provider()?
.change_vault(address.into(), &new_vault)
.map_err(|e| errors::account("Could not change vault.", e))
.map(|_| true)
}
fn get_vault_meta(&self, name: String) -> Result<String, Error> {
take_weak!(self.accounts)
self.account_provider()?
.get_vault_meta(&name)
.map_err(|e| errors::account("Could not get vault metadata.", e))
}
fn set_vault_meta(&self, name: String, meta: String) -> Result<bool, Error> {
take_weak!(self.accounts)
self.account_provider()?
.set_vault_meta(&name, &meta)
.map_err(|e| errors::account("Could not update vault metadata.", e))
.map(|_| true)
@@ -293,7 +300,7 @@ impl ParityAccounts for ParityAccountsClient {
fn derive_key_index(&self, addr: RpcH160, password: String, derivation: DeriveHierarchical, save_as_account: bool) -> Result<RpcH160, Error> {
let addr: Address = addr.into();
take_weak!(self.accounts)
self.account_provider()?
.derive_account(
&addr,
Some(password),
@@ -306,7 +313,7 @@ impl ParityAccounts for ParityAccountsClient {
fn derive_key_hash(&self, addr: RpcH160, password: String, derivation: DeriveHash, save_as_account: bool) -> Result<RpcH160, Error> {
let addr: Address = addr.into();
take_weak!(self.accounts)
self.account_provider()?
.derive_account(
&addr,
Some(password),
@@ -319,7 +326,7 @@ impl ParityAccounts for ParityAccountsClient {
fn export_account(&self, addr: RpcH160, password: String) -> Result<KeyFile, Error> {
let addr = addr.into();
take_weak!(self.accounts)
self.account_provider()?
.export_account(
&addr,
password,

View File

@@ -26,39 +26,44 @@ use futures::{future, Future, BoxFuture};
use jsonrpc_core::Error;
use v1::helpers::errors;
use v1::helpers::dispatch::{Dispatcher, SignWith};
use v1::helpers::accounts::unwrap_provider;
use v1::traits::Personal;
use v1::types::{H160 as RpcH160, H256 as RpcH256, U128 as RpcU128, TransactionRequest};
use v1::metadata::Metadata;
/// Account management (personal) rpc implementation.
pub struct PersonalClient<D: Dispatcher> {
accounts: Weak<AccountProvider>,
accounts: Option<Weak<AccountProvider>>,
dispatcher: D,
allow_perm_unlock: bool,
}
impl<D: Dispatcher> PersonalClient<D> {
/// Creates new PersonalClient
pub fn new(store: &Arc<AccountProvider>, dispatcher: D, allow_perm_unlock: bool) -> Self {
pub fn new(store: &Option<Arc<AccountProvider>>, dispatcher: D, allow_perm_unlock: bool) -> Self {
PersonalClient {
accounts: Arc::downgrade(store),
accounts: store.as_ref().map(Arc::downgrade),
dispatcher: dispatcher,
allow_perm_unlock: allow_perm_unlock,
}
}
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
unwrap_provider(&self.accounts)
}
}
impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
type Metadata = Metadata;
fn accounts(&self) -> Result<Vec<RpcH160>, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let accounts = store.accounts().map_err(|e| errors::account("Could not fetch accounts.", e))?;
Ok(accounts.into_iter().map(Into::into).collect::<Vec<RpcH160>>())
}
fn new_account(&self, pass: String) -> Result<RpcH160, Error> {
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
store.new_account(&pass)
.map(Into::into)
@@ -67,7 +72,7 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option<RpcU128>) -> Result<bool, Error> {
let account: Address = account.into();
let store = take_weak!(self.accounts);
let store = self.account_provider()?;
let duration = match duration {
None => None,
Some(duration) => {
@@ -96,7 +101,7 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<RpcH256, Error> {
let dispatcher = self.dispatcher.clone();
let accounts = take_weakf!(self.accounts);
let accounts = try_bf!(self.account_provider());
let default = match request.from.as_ref() {
Some(account) => Ok(account.clone().into()),

View File

@@ -26,13 +26,14 @@ use futures::{future, BoxFuture, Future, IntoFuture};
use jsonrpc_core::Error;
use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload};
use v1::helpers::dispatch::{self, Dispatcher, WithToken};
use v1::helpers::accounts::unwrap_provider;
use v1::traits::Signer;
use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, U256, Bytes};
/// Transactions confirmation (personal) rpc implementation.
pub struct SignerClient<D: Dispatcher> {
signer: Weak<SignerService>,
accounts: Weak<AccountProvider>,
accounts: Option<Weak<AccountProvider>>,
dispatcher: D
}
@@ -40,17 +41,21 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
/// Create new instance of signer client.
pub fn new(
store: &Arc<AccountProvider>,
store: &Option<Arc<AccountProvider>>,
dispatcher: D,
signer: &Arc<SignerService>,
) -> Self {
SignerClient {
signer: Arc::downgrade(signer),
accounts: Arc::downgrade(store),
accounts: store.as_ref().map(Arc::downgrade),
dispatcher: dispatcher,
}
}
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
unwrap_provider(&self.accounts)
}
fn confirm_internal<F, T>(&self, id: U256, modification: TransactionModification, f: F) -> BoxFuture<WithToken<ConfirmationResponse>, Error> where
F: FnOnce(D, Arc<AccountProvider>, ConfirmationPayload) -> T,
T: IntoFuture<Item=WithToken<ConfirmationResponse>, Error=Error>,
@@ -60,7 +65,7 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
let dispatcher = self.dispatcher.clone();
let setup = || {
Ok((take_weak!(self.accounts), take_weak!(self.signer)))
Ok((self.account_provider()?, take_weak!(self.signer)))
};
let (accounts, signer) = match setup() {

View File

@@ -30,6 +30,7 @@ use v1::helpers::{
SIGNING_QUEUE_LIMIT, SigningQueue, ConfirmationPromise, ConfirmationResult, SignerService
};
use v1::helpers::dispatch::{self, Dispatcher};
use v1::helpers::accounts::unwrap_provider;
use v1::metadata::Metadata;
use v1::traits::{EthSigning, ParitySigning};
use v1::types::{
@@ -55,7 +56,7 @@ enum DispatchResult {
/// Implementation of functions that require signing when no trusted signer is used.
pub struct SigningQueueClient<D> {
signer: Weak<SignerService>,
accounts: Weak<AccountProvider>,
accounts: Option<Weak<AccountProvider>>,
dispatcher: D,
pending: Arc<Mutex<TransientHashMap<U256, ConfirmationPromise>>>,
}
@@ -91,17 +92,21 @@ fn collect_garbage(map: &mut TransientHashMap<U256, ConfirmationPromise>) {
impl<D: Dispatcher + 'static> SigningQueueClient<D> {
/// Creates a new signing queue client given shared signing queue.
pub fn new(signer: &Arc<SignerService>, dispatcher: D, accounts: &Arc<AccountProvider>) -> Self {
pub fn new(signer: &Arc<SignerService>, dispatcher: D, accounts: &Option<Arc<AccountProvider>>) -> Self {
SigningQueueClient {
signer: Arc::downgrade(signer),
accounts: Arc::downgrade(accounts),
accounts: accounts.as_ref().map(Arc::downgrade),
dispatcher: dispatcher,
pending: Arc::new(Mutex::new(TransientHashMap::new(MAX_PENDING_DURATION_SEC))),
}
}
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
unwrap_provider(&self.accounts)
}
fn dispatch(&self, payload: RpcConfirmationPayload, default_account: DefaultAccount, origin: Origin) -> BoxFuture<DispatchResult, Error> {
let accounts = take_weakf!(self.accounts);
let accounts = try_bf!(self.account_provider());
let default_account = match default_account {
DefaultAccount::Provided(acc) => acc,
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),

View File

@@ -24,6 +24,7 @@ use futures::{future, BoxFuture, Future};
use jsonrpc_core::Error;
use v1::helpers::{errors, DefaultAccount};
use v1::helpers::dispatch::{self, Dispatcher};
use v1::helpers::accounts::unwrap_provider;
use v1::metadata::Metadata;
use v1::traits::{EthSigning, ParitySigning};
use v1::types::{
@@ -38,21 +39,25 @@ use v1::types::{
/// Implementation of functions that require signing when no trusted signer is used.
pub struct SigningUnsafeClient<D> {
accounts: Weak<AccountProvider>,
accounts: Option<Weak<AccountProvider>>,
dispatcher: D,
}
impl<D: Dispatcher + 'static> SigningUnsafeClient<D> {
/// Creates new SigningUnsafeClient.
pub fn new(accounts: &Arc<AccountProvider>, dispatcher: D) -> Self {
pub fn new(accounts: &Option<Arc<AccountProvider>>, dispatcher: D) -> Self {
SigningUnsafeClient {
accounts: Arc::downgrade(accounts),
accounts: accounts.as_ref().map(Arc::downgrade),
dispatcher: dispatcher,
}
}
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
unwrap_provider(&self.accounts)
}
fn handle(&self, payload: RpcConfirmationPayload, account: DefaultAccount) -> BoxFuture<RpcConfirmationResponse, Error> {
let accounts = take_weakf!(self.accounts);
let accounts = try_bf!(self.account_provider());
let default = match account {
DefaultAccount::Provided(acc) => acc,
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),

View File

@@ -117,6 +117,7 @@ impl EthTester {
fn from_spec(spec: Spec) -> Self {
let account_provider = account_provider();
let opt_account_provider = Some(account_provider.clone());
let miner_service = miner_service(&spec, account_provider.clone());
let snapshot_service = snapshot_service();
@@ -134,7 +135,7 @@ impl EthTester {
&client,
&snapshot_service,
&sync_provider,
&account_provider,
&opt_account_provider,
&miner_service,
&external_miner,
Default::default(),
@@ -142,7 +143,7 @@ impl EthTester {
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner_service));
let eth_sign = SigningUnsafeClient::new(
&account_provider,
&opt_account_provider,
dispatcher,
);

View File

@@ -84,15 +84,16 @@ impl EthTester {
let client = blockchain_client();
let sync = sync_provider();
let ap = accounts_provider();
let opt_ap = Some(ap.clone());
let miner = miner_service();
let snapshot = snapshot_service();
let hashrates = Arc::new(Mutex::new(HashMap::new()));
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
let eth = EthClient::new(&client, &snapshot, &sync, &ap, &miner, &external_miner, options).to_delegate();
let eth = EthClient::new(&client, &snapshot, &sync, &opt_ap, &miner, &external_miner, options).to_delegate();
let filter = EthFilterClient::new(client.clone(), miner.clone()).to_delegate();
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
let sign = SigningUnsafeClient::new(&ap, dispatcher).to_delegate();
let sign = SigningUnsafeClient::new(&opt_ap, dispatcher).to_delegate();
let mut io: IoHandler<Metadata> = IoHandler::default();
io.extend_with(eth);
io.extend_with(sign);

View File

@@ -72,13 +72,15 @@ impl Dependencies {
}
pub fn client(&self, signer: Option<Arc<SignerService>>) -> TestParityClient {
let opt_accounts = Some(self.accounts.clone());
ParityClient::new(
&self.client,
&self.miner,
&self.sync,
&self.updater,
&self.network,
&self.accounts,
&opt_accounts,
self.logger.clone(),
self.settings.clone(),
signer,
@@ -497,3 +499,14 @@ fn rpc_parity_chain_status() {
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_parity_node_kind() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "parity_nodeKind", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"availability":"personal","capability":"full"},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}

View File

@@ -40,7 +40,8 @@ fn accounts_provider_with_vaults_support(temp_path: &str) -> Arc<AccountProvider
}
fn setup_with_accounts_provider(accounts_provider: Arc<AccountProvider>) -> ParityAccountsTester {
let parity_accounts = ParityAccountsClient::new(&accounts_provider);
let opt_ap = Some(accounts_provider.clone());
let parity_accounts = ParityAccountsClient::new(&opt_ap);
let mut io = IoHandler::default();
io.extend_with(parity_accounts.to_delegate());

View File

@@ -51,11 +51,12 @@ fn miner_service() -> Arc<TestMinerService> {
fn setup() -> PersonalTester {
let accounts = accounts_provider();
let opt_accounts = Some(accounts.clone());
let client = blockchain_client();
let miner = miner_service();
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
let personal = PersonalClient::new(&accounts, dispatcher, false);
let personal = PersonalClient::new(&opt_accounts, dispatcher, false);
let mut io = IoHandler::default();
io.extend_with(personal.to_delegate());

View File

@@ -57,12 +57,13 @@ fn miner_service() -> Arc<TestMinerService> {
fn signer_tester() -> SignerTester {
let signer = Arc::new(SignerService::new_test(None));
let accounts = accounts_provider();
let opt_accounts = Some(accounts.clone());
let client = blockchain_client();
let miner = miner_service();
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
let mut io = IoHandler::default();
io.extend_with(SignerClient::new(&accounts, dispatcher, &signer).to_delegate());
io.extend_with(SignerClient::new(&opt_accounts, dispatcher, &signer).to_delegate());
SignerTester {
signer: signer,

View File

@@ -51,13 +51,14 @@ impl Default for SigningTester {
let client = Arc::new(TestBlockChainClient::default());
let miner = Arc::new(TestMinerService::default());
let accounts = Arc::new(AccountProvider::transient_provider());
let opt_accounts = Some(accounts.clone());
let mut io = IoHandler::default();
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), &accounts);
let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), &opt_accounts);
io.extend_with(EthSigning::to_delegate(rpc));
let rpc = SigningQueueClient::new(&signer, dispatcher, &accounts);
let rpc = SigningQueueClient::new(&signer, dispatcher, &opt_accounts);
io.extend_with(ParitySigning::to_delegate(rpc));
SigningTester {

View File

@@ -194,5 +194,9 @@ build_rpc_trait! {
/// Get the current chain status.
#[rpc(name = "parity_chainStatus")]
fn chain_status(&self) -> Result<ChainStatus, Error>;
/// Get node kind info.
#[rpc(name = "parity_nodeKind")]
fn node_kind(&self) -> Result<::v1::types::NodeKind, Error>;
}
}

View File

@@ -30,6 +30,7 @@ mod hash;
mod histogram;
mod index;
mod log;
mod node_kind;
mod provenance;
mod receipt;
mod rpc_settings;
@@ -58,6 +59,7 @@ pub use self::hash::{H64, H160, H256, H512, H520, H2048};
pub use self::histogram::Histogram;
pub use self::index::Index;
pub use self::log::Log;
pub use self::node_kind::{NodeKind, Availability, Capability};
pub use self::provenance::{Origin, DappId};
pub use self::receipt::Receipt;
pub use self::rpc_settings::RpcSettings;

View File

@@ -0,0 +1,92 @@
// Copyright 2015-2017 Parity Technologies (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/>.
//! Description of the node.
/// Describes the kind of node. This information can provide a hint to
/// applications about how to utilize the RPC.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NodeKind {
/// The capability of the node.
pub capability: Capability,
/// Who the node is available to.
pub availability: Availability,
}
/// Who the node is available to.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Availability {
/// A personal node, not intended to be available to everyone.
#[serde(rename="personal")]
Personal,
/// A public, open node.
#[serde(rename="public")]
Public,
}
/// The capability of the node.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Capability {
/// A full node stores the full state and fully enacts incoming blocks.
#[serde(rename="full")]
Full,
/// A light node does a minimal header sync and fetches data as needed
/// from the network.
#[serde(rename="light")]
Light,
}
#[cfg(test)]
mod tests {
use super::{NodeKind, Availability, Capability};
use serde_json;
#[test]
fn availability() {
let personal = r#""personal""#;
let public = r#""public""#;
assert_eq!(serde_json::to_string(&Availability::Personal).unwrap(), personal);
assert_eq!(serde_json::to_string(&Availability::Public).unwrap(), public);
assert_eq!(serde_json::from_str::<Availability>(personal).unwrap(), Availability::Personal);
assert_eq!(serde_json::from_str::<Availability>(public).unwrap(), Availability::Public);
}
#[test]
fn capability() {
let light = r#""light""#;
let full = r#""full""#;
assert_eq!(serde_json::to_string(&Capability::Light).unwrap(), light);
assert_eq!(serde_json::to_string(&Capability::Full).unwrap(), full);
assert_eq!(serde_json::from_str::<Capability>(light).unwrap(), Capability::Light);
assert_eq!(serde_json::from_str::<Capability>(full).unwrap(), Capability::Full);
}
#[test]
fn node_kind() {
let kind = NodeKind {
capability: Capability::Full,
availability: Availability::Public,
};
let s = r#"{"capability":"full","availability":"public"}"#;
assert_eq!(serde_json::to_string(&kind).unwrap(), s);
assert_eq!(serde_json::from_str::<NodeKind>(s).unwrap(), kind);
}
}

View File

@@ -91,6 +91,8 @@ pub enum LocalTransactionStatus {
Rejected(Transaction, String),
/// Transaction is invalid.
Invalid(Transaction),
/// Transaction was canceled.
Canceled(Transaction),
}
impl Serialize for LocalTransactionStatus {
@@ -101,7 +103,7 @@ impl Serialize for LocalTransactionStatus {
let elems = match *self {
Pending | Future => 1,
Mined(..) | Dropped(..) | Invalid(..) => 2,
Mined(..) | Dropped(..) | Invalid(..) | Canceled(..) => 2,
Rejected(..) => 3,
Replaced(..) => 4,
};
@@ -121,6 +123,10 @@ impl Serialize for LocalTransactionStatus {
struc.serialize_field(status, "dropped")?;
struc.serialize_field(transaction, tx)?;
},
Canceled(ref tx) => {
struc.serialize_field(status, "canceled")?;
struc.serialize_field(transaction, tx)?;
},
Invalid(ref tx) => {
struc.serialize_field(status, "invalid")?;
struc.serialize_field(transaction, tx)?;
@@ -249,6 +255,7 @@ impl From<miner::LocalTransactionStatus> for LocalTransactionStatus {
Rejected(tx, err) => LocalTransactionStatus::Rejected(tx.into(), errors::transaction_message(err)),
Replaced(tx, gas_price, hash) => LocalTransactionStatus::Replaced(tx.into(), gas_price.into(), hash.into()),
Invalid(tx) => LocalTransactionStatus::Invalid(tx.into()),
Canceled(tx) => LocalTransactionStatus::Canceled(tx.into()),
}
}
}