2.4.4 more beta backports (#10554)

* fix(rpc-types): replace uint and hash with `ethereum_types v0.4` (#10217)

* fix(rpc-types): remove uint and hash wrappers

* fix(tests)

* fix(cleanup)

* grumbles(rpc-api): revert `verify_signature`

* revert change of `U64` -> `u64`

* fix(cleanup after bad merge)

* chore(bump ethereum-types)

* fix(bad merge)

* feat(tests ethereum-types): add tests

* chore(update `ethereum-types` to 0.4.2)

* feat(tests for h256)

* chore(rpc): remove `ethbloom` import

Use re-export from `ethereum-types` instead

* fix(bad merge): remove `DefaultAccount` type

* doc(add TODO with issue link)

* chore(bump ethereum-types) (#10396)

Fixes a de-serialization bug in `ethereum-tyes`

* fix(light eth_gasPrice): ask network if not in cache (#10535)

* fix(light eth_gasPrice): ask N/W if not in cache

* fix(bad rebase)

* fix(light account response): update `tx_queue` (#10545)

* fix(bump dependencies) (#10540)

* cargo update -p log:0.4.5

* cargo update -p regex:1.0.5

* cargo update -p parking_lot

* cargo update -p serde_derive

* cargo update -p serde_json

* cargo update -p serde

* cargo update -p lazy_static

* cargo update -p num_cpus

* cargo update -p toml

# Conflicts:
#	Cargo.lock

* tx-pool: check transaction readiness before replacing (#10526)

* Update to vanilla tx pool error

* Prevent a non ready tx replacing a ready tx

* Make tests compile

* Test ready tx not replaced by future tx

* Transaction indirection

* Use StateReadiness to calculate Ready in `should_replace`

* Test existing txs from same sender are used to compute Readiness

* private-tx: Wire up ShouldReplace

* Revert "Use StateReadiness to calculate Ready in `should_replace`"

This reverts commit af9e69c8

* Make replace generic so it works with private-tx

* Rename Replace and add missing docs

* ShouldReplace no longer mutable

* tx-pool: update to transaction-pool 2.0 from crates.io

* tx-pool: generic error type alias

* Exit early for first unmatching nonce

* Fix private-tx test, use existing write lock

* Use read lock for pool scoring

* fix #10390 (#10391)

* private-tx: replace error_chain (#10510)

* Update to vanilla tx pool error

* private-tx: remove error-chain, implement Error, derive Display

* private-tx: replace ErrorKind and bail!

* private-tx: add missing From impls and other compiler errors

* private-tx: use original tx-pool error

* Don't be silly cargo
This commit is contained in:
Niklas Adolfsson 2019-04-01 17:04:50 +02:00 committed by Talha Cross
parent d30610621f
commit 8f6911af20
87 changed files with 1367 additions and 1353 deletions

637
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ name = "cli-signer"
version = "1.4.0" version = "1.4.0"
[dependencies] [dependencies]
ethereum-types = "0.4"
futures = "0.1" futures = "0.1"
rpassword = "1.0" rpassword = "1.0"
parity-rpc = { path = "../rpc" } parity-rpc = { path = "../rpc" }

View File

@ -7,6 +7,7 @@ name = "parity-rpc-client"
version = "1.4.0" version = "1.4.0"
[dependencies] [dependencies]
ethereum-types = "0.4"
futures = "0.1" futures = "0.1"
log = "0.4" log = "0.4"
serde = "1.0" serde = "1.0"

View File

@ -17,6 +17,7 @@
pub mod client; pub mod client;
pub mod signer_client; pub mod signer_client;
extern crate ethereum_types;
extern crate futures; extern crate futures;
extern crate jsonrpc_core; extern crate jsonrpc_core;
extern crate jsonrpc_ws_server as ws; extern crate jsonrpc_ws_server as ws;

View File

@ -15,7 +15,8 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use client::{Rpc, RpcError}; use client::{Rpc, RpcError};
use rpc::signer::{ConfirmationRequest, TransactionModification, U256, TransactionCondition}; use ethereum_types::U256;
use rpc::signer::{ConfirmationRequest, TransactionModification, TransactionCondition};
use serde; use serde;
use serde_json::{Value as JsonValue, to_value}; use serde_json::{Value as JsonValue, to_value};
use std::path::PathBuf; use std::path::PathBuf;

View File

@ -14,13 +14,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
extern crate ethereum_types;
extern crate futures; extern crate futures;
extern crate rpassword; extern crate rpassword;
extern crate parity_rpc as rpc; extern crate parity_rpc as rpc;
extern crate parity_rpc_client as client; extern crate parity_rpc_client as client;
use rpc::signer::{U256, ConfirmationRequest}; use ethereum_types::U256;
use rpc::signer::ConfirmationRequest;
use client::signer_client::SignerRpc; use client::signer_client::SignerRpc;
use std::io::{Write, BufRead, BufReader, stdout, stdin}; use std::io::{Write, BufRead, BufReader, stdout, stdin};
use std::path::PathBuf; use std::path::PathBuf;

View File

@ -7,7 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
common-types = { path = "../types" } common-types = { path = "../types" }
error-chain = { version = "0.12", default-features = false } derive_more = "0.14.0"
ethabi = "6.0" ethabi = "6.0"
ethabi-contract = "6.0" ethabi-contract = "6.0"
ethabi-derive = "6.0" ethabi-derive = "6.0"
@ -36,7 +36,7 @@ serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0" serde_json = "1.0"
tiny-keccak = "1.4" tiny-keccak = "1.4"
transaction-pool = "1.13.2" transaction-pool = "2.0"
url = "1" url = "1"
[dev-dependencies] [dev-dependencies]

View File

@ -31,7 +31,7 @@ use crypto;
use futures::Future; use futures::Future;
use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request}; use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request};
use bytes::{Bytes, ToPretty}; use bytes::{Bytes, ToPretty};
use error::{Error, ErrorKind}; use error::Error;
use url::Url; use url::Url;
use super::Signer; use super::Signer;
use super::key_server_keys::address_to_key; use super::key_server_keys::address_to_key;
@ -111,11 +111,11 @@ impl SecretStoreEncryptor {
return Ok(key); return Ok(key);
} }
let contract_address_signature = self.sign_contract_address(contract_address)?; let contract_address_signature = self.sign_contract_address(contract_address)?;
let requester = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?; let requester = self.config.key_server_account.ok_or_else(|| Error::KeyServerAccountNotSet)?;
// key id in SS is H256 && we have H160 here => expand with assitional zeros // key id in SS is H256 && we have H160 here => expand with assitional zeros
let contract_address_extended: H256 = contract_address.into(); let contract_address_extended: H256 = contract_address.into();
let base_url = self.config.base_url.clone().ok_or_else(|| ErrorKind::KeyServerNotSet)?; let base_url = self.config.base_url.clone().ok_or_else(|| Error::KeyServerNotSet)?;
// prepare request url // prepare request url
let url = format!("{}/{}/{}{}", let url = format!("{}/{}/{}{}",
@ -132,16 +132,16 @@ impl SecretStoreEncryptor {
Method::GET Method::GET
}; };
let url = Url::from_str(&url).map_err(|e| ErrorKind::Encrypt(e.to_string()))?; let url = Url::from_str(&url).map_err(|e| Error::Encrypt(e.to_string()))?;
let response = self.client.fetch(Request::new(url, method), Default::default()).wait() let response = self.client.fetch(Request::new(url, method), Default::default()).wait()
.map_err(|e| ErrorKind::Encrypt(e.to_string()))?; .map_err(|e| Error::Encrypt(e.to_string()))?;
if response.is_not_found() { if response.is_not_found() {
bail!(ErrorKind::EncryptionKeyNotFound(*contract_address)); return Err(Error::EncryptionKeyNotFound(*contract_address));
} }
if !response.is_success() { if !response.is_success() {
bail!(ErrorKind::Encrypt(response.status().canonical_reason().unwrap_or("unknown").into())); return Err(Error::Encrypt(response.status().canonical_reason().unwrap_or("unknown").into()));
} }
// read HTTP response // read HTTP response
@ -149,7 +149,7 @@ impl SecretStoreEncryptor {
BodyReader::new(response).read_to_string(&mut result)?; BodyReader::new(response).read_to_string(&mut result)?;
// response is JSON string (which is, in turn, hex-encoded, encrypted Public) // response is JSON string (which is, in turn, hex-encoded, encrypted Public)
let encrypted_bytes: ethjson::bytes::Bytes = result.trim_matches('\"').parse().map_err(|e| ErrorKind::Encrypt(e))?; let encrypted_bytes: ethjson::bytes::Bytes = result.trim_matches('\"').parse().map_err(|e| Error::Encrypt(e))?;
// decrypt Public // decrypt Public
let decrypted_bytes = self.signer.decrypt(requester, &crypto::DEFAULT_MAC, &encrypted_bytes)?; let decrypted_bytes = self.signer.decrypt(requester, &crypto::DEFAULT_MAC, &encrypted_bytes)?;
@ -189,7 +189,7 @@ impl SecretStoreEncryptor {
} }
fn sign_contract_address(&self, contract_address: &Address) -> Result<Signature, Error> { fn sign_contract_address(&self, contract_address: &Address) -> Result<Signature, Error> {
let key_server_account = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?; let key_server_account = self.config.key_server_account.ok_or_else(|| Error::KeyServerAccountNotSet)?;
Ok(self.signer.sign(key_server_account, address_to_key(contract_address))?) Ok(self.signer.sign(key_server_account, address_to_key(contract_address))?)
} }
} }
@ -204,7 +204,7 @@ impl Encryptor for SecretStoreEncryptor {
// retrieve the key, try to generate it if it doesn't exist yet // retrieve the key, try to generate it if it doesn't exist yet
let key = match self.retrieve_key("", false, contract_address) { let key = match self.retrieve_key("", false, contract_address) {
Ok(key) => Ok(key), Ok(key) => Ok(key),
Err(Error(ErrorKind::EncryptionKeyNotFound(_), _)) => { Err(Error::EncryptionKeyNotFound(_)) => {
trace!(target: "privatetx", "Key for account wasnt found in sstore. Creating. Address: {:?}", contract_address); trace!(target: "privatetx", "Key for account wasnt found in sstore. Creating. Address: {:?}", contract_address);
self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address) self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address)
} }
@ -215,7 +215,7 @@ impl Encryptor for SecretStoreEncryptor {
let mut cypher = Vec::with_capacity(plain_data.len() + initialisation_vector.len()); let mut cypher = Vec::with_capacity(plain_data.len() + initialisation_vector.len());
cypher.extend(repeat(0).take(plain_data.len())); cypher.extend(repeat(0).take(plain_data.len()));
crypto::aes::encrypt_128_ctr(&key, initialisation_vector, plain_data, &mut cypher) crypto::aes::encrypt_128_ctr(&key, initialisation_vector, plain_data, &mut cypher)
.map_err(|e| ErrorKind::Encrypt(e.to_string()))?; .map_err(|e| Error::Encrypt(e.to_string()))?;
cypher.extend_from_slice(&initialisation_vector); cypher.extend_from_slice(&initialisation_vector);
Ok(cypher) Ok(cypher)
@ -230,7 +230,7 @@ impl Encryptor for SecretStoreEncryptor {
// initialization vector takes INIT_VEC_LEN bytes // initialization vector takes INIT_VEC_LEN bytes
let cypher_len = cypher.len(); let cypher_len = cypher.len();
if cypher_len < INIT_VEC_LEN { if cypher_len < INIT_VEC_LEN {
bail!(ErrorKind::Decrypt("Invalid cypher".into())); return Err(Error::Decrypt("Invalid cypher".into()));
} }
// retrieve existing key // retrieve existing key
@ -241,7 +241,7 @@ impl Encryptor for SecretStoreEncryptor {
let mut plain_data = Vec::with_capacity(cypher_len - INIT_VEC_LEN); let mut plain_data = Vec::with_capacity(cypher_len - INIT_VEC_LEN);
plain_data.extend(repeat(0).take(cypher_len - INIT_VEC_LEN)); plain_data.extend(repeat(0).take(cypher_len - INIT_VEC_LEN));
crypto::aes::decrypt_128_ctr(&key, &iv, cypher, &mut plain_data) crypto::aes::decrypt_128_ctr(&key, &iv, cypher, &mut plain_data)
.map_err(|e| ErrorKind::Decrypt(e.to_string()))?; .map_err(|e| Error::Decrypt(e.to_string()))?;
Ok(plain_data) Ok(plain_data)
} }
} }

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::error;
use derive_more::Display;
use ethereum_types::Address; use ethereum_types::Address;
use rlp::DecoderError; use rlp::DecoderError;
use ethtrie::TrieError; use ethtrie::TrieError;
@ -21,173 +23,173 @@ use ethcore::error::{Error as EthcoreError, ExecutionError};
use types::transaction::Error as TransactionError; use types::transaction::Error as TransactionError;
use ethkey::Error as KeyError; use ethkey::Error as KeyError;
use ethkey::crypto::Error as CryptoError; use ethkey::crypto::Error as CryptoError;
use txpool::Error as TxPoolError; use txpool::VerifiedTransaction;
use private_transactions::VerifiedPrivateTransaction;
error_chain! { type TxPoolError = txpool::Error<<VerifiedPrivateTransaction as VerifiedTransaction>::Hash>;
foreign_links {
Io(::std::io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."]; #[derive(Debug, Display)]
Decoder(DecoderError) #[doc = "RLP decoding error."]; pub enum Error {
Trie(TrieError) #[doc = "Error concerning TrieDBs."]; /// Error concerning the Rust standard library's IO subsystem.
Txpool(TxPoolError) #[doc = "Tx pool error."]; #[display(fmt = "Io Error: {}", _0)]
Crypto(CryptoError) #[doc = "Crypto error."]; Io(::std::io::Error),
/// RLP decoding error.
#[display(fmt = "Decoder Error: {}", _0)]
Decoder(DecoderError),
/// Error concerning TrieDBs.
#[display(fmt = "Trie Error: {}", _0)]
Trie(TrieError),
/// Transaction pool error.
#[display(fmt = "Transaction Pool Error: {}", _0)]
TxPool(TxPoolError),
/// Crypto error.
#[display(fmt = "Crypto Error {}", _0)]
Crypto(CryptoError),
/// Encryption error.
#[display(fmt = "Encryption error. ({})", _0)]
Encrypt(String),
/// Decryption error.
#[display(fmt = "Decryption error. ({})", _0)]
Decrypt(String),
/// Address not authorized.
#[display(fmt = "Private transaction execution is not authorised for {}", _0)]
NotAuthorised(Address),
/// Transaction creates more than one contract.
#[display(fmt = "Private transaction created too many contracts")]
TooManyContracts,
/// Contract call error.
#[display(fmt = "Contract call error. ({})", _0)]
Call(String),
/// State is not available.
#[display(fmt = "State is not available")]
StatePruned,
/// State is incorrect.
#[display(fmt = "State is incorrect")]
StateIncorrect,
/// Wrong private transaction type.
#[display(fmt = "Wrong private transaction type")]
BadTransactionType,
/// Contract does not exist or was not created.
#[display(fmt = "Contract does not exist or was not created")]
ContractDoesNotExist,
/// Reference to the client is corrupted.
#[display(fmt = "Reference to the client is corrupted")]
ClientIsMalformed,
/// Queue of private transactions for verification is full.
#[display(fmt = "Queue of private transactions for verification is full")]
QueueIsFull,
/// The transaction already exists in queue of private transactions.
#[display(fmt = "The transaction already exists in queue of private transactions.")]
PrivateTransactionAlreadyImported,
/// The information about private transaction is not found in the store.
#[display(fmt = "The information about private transaction is not found in the store.")]
PrivateTransactionNotFound,
/// Account for signing public transactions not set.
#[display(fmt = "Account for signing public transactions not set.")]
SignerAccountNotSet,
/// Account for validating private transactions not set.
#[display(fmt = "Account for validating private transactions not set.")]
ValidatorAccountNotSet,
/// Account for signing requests to key server not set.
#[display(fmt = "Account for signing requests to key server not set.")]
KeyServerAccountNotSet,
/// Encryption key is not found on key server.
#[display(fmt = "Encryption key is not found on key server for {}", _0)]
EncryptionKeyNotFound(Address),
/// Key server URL is not set.
#[display(fmt = "Key server URL is not set.")]
KeyServerNotSet,
/// VM execution error.
#[display(fmt = "VM execution error {}", _0)]
Execution(ExecutionError),
/// General signing error.
#[display(fmt = "General signing error {}", _0)]
Key(KeyError),
/// Error of transactions processing.
#[display(fmt = "Error of transactions processing {}", _0)]
Transaction(TransactionError),
/// General ethcore error.
#[display(fmt = "General ethcore error {}", _0)]
Ethcore(EthcoreError),
/// A convenient variant for String.
#[display(fmt = "{}", _0)]
Msg(String),
}
impl error::Error for Error {
fn source(&self) -> Option<&(error::Error + 'static)> {
match self {
Error::Io(e) => Some(e),
Error::Decoder(e) => Some(e),
Error::Trie(e) => Some(e),
Error::TxPool(e) => Some(e),
Error::Crypto(e) => Some(e),
Error::Execution(e) => Some(e),
Error::Key(e) => Some(e),
Error::Transaction(e) => Some(e),
Error::Ethcore(e) => Some(e),
_ => None,
}
} }
}
errors { impl From<String> for Error {
#[doc = "Encryption error."] fn from(s: String) -> Self {
Encrypt(err: String) { Error::Msg(s)
description("Encryption error"), }
display("Encryption error. ({})", err), }
}
#[doc = "Decryption error."] impl From<std::io::Error> for Error {
Decrypt(err: String) { fn from(err: std::io::Error) -> Self {
description("Decryption error"), Error::Io(err).into()
display("Decryption error. ({})", err),
}
#[doc = "Address not authorized."]
NotAuthorised(address: Address) {
description("Address not authorized"),
display("Private transaction execution is not authorised for {}", address),
}
#[doc = "Transaction creates more than one contract."]
TooManyContracts {
description("Transaction creates more than one contract."),
display("Private transaction created too many contracts"),
}
#[doc = "Contract call error."]
Call(err: String) {
description("Contract call error."),
display("Contract call error. ({})", err),
}
#[doc = "State is not available."]
StatePruned {
description("State is not available."),
display("State is not available"),
}
#[doc = "State is incorrect."]
StateIncorrect {
description("State is incorrect."),
display("State is incorrect"),
}
#[doc = "Wrong private transaction type."]
BadTransactionType {
description("Wrong private transaction type."),
display("Wrong private transaction type"),
}
#[doc = "Contract does not exist or was not created."]
ContractDoesNotExist {
description("Contract does not exist or was not created."),
display("Contract does not exist or was not created"),
}
#[doc = "Reference to the client is corrupted."]
ClientIsMalformed {
description("Reference to the client is corrupted."),
display("Reference to the client is corrupted"),
}
#[doc = "Queue of private transactions for verification is full."]
QueueIsFull {
description("Queue of private transactions for verification is full."),
display("Queue of private transactions for verification is full"),
}
#[doc = "The transaction already exists in queue of private transactions."]
PrivateTransactionAlreadyImported {
description("The transaction already exists in queue of private transactions."),
display("The transaction already exists in queue of private transactions."),
}
#[doc = "The information about private transaction is not found in the store."]
PrivateTransactionNotFound {
description("The information about private transaction is not found in the store."),
display("The information about private transaction is not found in the store."),
}
#[doc = "Account for signing public transactions not set."]
SignerAccountNotSet {
description("Account for signing public transactions not set."),
display("Account for signing public transactions not set."),
}
#[doc = "Account for validating private transactions not set."]
ValidatorAccountNotSet {
description("Account for validating private transactions not set."),
display("Account for validating private transactions not set."),
}
#[doc = "Account for signing requests to key server not set."]
KeyServerAccountNotSet {
description("Account for signing requests to key server not set."),
display("Account for signing requests to key server not set."),
}
#[doc = "Encryption key is not found on key server."]
EncryptionKeyNotFound(address: Address) {
description("Encryption key is not found on key server"),
display("Encryption key is not found on key server for {}", address),
}
#[doc = "Key server URL is not set."]
KeyServerNotSet {
description("Key server URL is not set."),
display("Key server URL is not set."),
}
#[doc = "VM execution error."]
Execution(err: ExecutionError) {
description("VM execution error."),
display("VM execution error {}", err),
}
#[doc = "General signing error."]
Key(err: KeyError) {
description("General signing error."),
display("General signing error {}", err),
}
#[doc = "Error of transactions processing."]
Transaction(err: TransactionError) {
description("Error of transactions processing."),
display("Error of transactions processing {}", err),
}
#[doc = "General ethcore error."]
Ethcore(err: EthcoreError) {
description("General ethcore error."),
display("General ethcore error {}", err),
}
} }
} }
impl From<KeyError> for Error { impl From<KeyError> for Error {
fn from(err: KeyError) -> Self { fn from(err: KeyError) -> Self {
ErrorKind::Key(err).into() Error::Key(err).into()
}
}
impl From<CryptoError> for Error {
fn from(err: CryptoError) -> Self {
Error::Crypto(err).into()
}
}
impl From<DecoderError> for Error {
fn from(err: DecoderError) -> Self {
Error::Decoder(err).into()
} }
} }
impl From<ExecutionError> for Error { impl From<ExecutionError> for Error {
fn from(err: ExecutionError) -> Self { fn from(err: ExecutionError) -> Self {
ErrorKind::Execution(err).into() Error::Execution(err).into()
} }
} }
impl From<TransactionError> for Error { impl From<TransactionError> for Error {
fn from(err: TransactionError) -> Self { fn from(err: TransactionError) -> Self {
ErrorKind::Transaction(err).into() Error::Transaction(err).into()
}
}
impl From<TrieError> for Error {
fn from(err: TrieError) -> Self {
Error::Trie(err).into()
}
}
impl From<TxPoolError> for Error {
fn from(err: TxPoolError) -> Self {
Error::TxPool(err).into()
} }
} }
impl From<EthcoreError> for Error { impl From<EthcoreError> for Error {
fn from(err: EthcoreError) -> Self { fn from(err: EthcoreError) -> Self {
ErrorKind::Ethcore(err).into() Error::Ethcore(err).into()
} }
} }

View File

@ -54,8 +54,7 @@ extern crate log;
extern crate ethabi_derive; extern crate ethabi_derive;
#[macro_use] #[macro_use]
extern crate ethabi_contract; extern crate ethabi_contract;
#[macro_use] extern crate derive_more;
extern crate error_chain;
#[macro_use] #[macro_use]
extern crate rlp_derive; extern crate rlp_derive;
@ -68,7 +67,7 @@ pub use encryptor::{Encryptor, SecretStoreEncryptor, EncryptorConfig, NoopEncryp
pub use key_server_keys::{KeyProvider, SecretStoreKeys, StoringKeyProvider}; pub use key_server_keys::{KeyProvider, SecretStoreKeys, StoringKeyProvider};
pub use private_transactions::{VerifiedPrivateTransaction, VerificationStore, PrivateTransactionSigningDesc, SigningStore}; pub use private_transactions::{VerifiedPrivateTransaction, VerificationStore, PrivateTransactionSigningDesc, SigningStore};
pub use messages::{PrivateTransaction, SignedPrivateTransaction}; pub use messages::{PrivateTransaction, SignedPrivateTransaction};
pub use error::{Error, ErrorKind}; pub use error::Error;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::collections::{HashMap, HashSet, BTreeMap}; use std::collections::{HashMap, HashSet, BTreeMap};
@ -238,10 +237,10 @@ impl Provider {
trace!(target: "privatetx", "Creating private transaction from regular transaction: {:?}", signed_transaction); trace!(target: "privatetx", "Creating private transaction from regular transaction: {:?}", signed_transaction);
if self.signer_account.is_none() { if self.signer_account.is_none() {
warn!(target: "privatetx", "Signing account not set"); warn!(target: "privatetx", "Signing account not set");
bail!(ErrorKind::SignerAccountNotSet); return Err(Error::SignerAccountNotSet);
} }
let tx_hash = signed_transaction.hash(); let tx_hash = signed_transaction.hash();
let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| ErrorKind::BadTransactionType)?; let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| Error::BadTransactionType)?;
let data = signed_transaction.rlp_bytes(); let data = signed_transaction.rlp_bytes();
let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?; let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?;
let private = PrivateTransaction::new(encrypted_transaction, contract); let private = PrivateTransaction::new(encrypted_transaction, contract);
@ -309,19 +308,19 @@ impl Provider {
// TODO #9825 [ToDr] Usage of BlockId::Latest // TODO #9825 [ToDr] Usage of BlockId::Latest
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest); let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest);
if let Err(e) = contract_nonce { if let Err(e) = contract_nonce {
bail!("Cannot retrieve contract nonce: {:?}", e); return Err(format!("Cannot retrieve contract nonce: {:?}", e).into());
} }
let contract_nonce = contract_nonce.expect("Error was checked before"); let contract_nonce = contract_nonce.expect("Error was checked before");
let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction); let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction);
if let Err(e) = private_state { if let Err(e) = private_state {
bail!("Cannot retrieve private state: {:?}", e); return Err(format!("Cannot retrieve private state: {:?}", e).into());
} }
let private_state = private_state.expect("Error was checked before"); let private_state = private_state.expect("Error was checked before");
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash); trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash);
let signed_state = self.accounts.sign(validator_account, private_state_hash); let signed_state = self.accounts.sign(validator_account, private_state_hash);
if let Err(e) = signed_state { if let Err(e) = signed_state {
bail!("Cannot sign the state: {:?}", e); return Err(format!("Cannot sign the state: {:?}", e).into());
} }
let signed_state = signed_state.expect("Error was checked before"); let signed_state = signed_state.expect("Error was checked before");
let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None); let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None);
@ -362,25 +361,27 @@ impl Provider {
signatures.push(signed_tx.signature()); signatures.push(signed_tx.signature());
let rsv: Vec<Signature> = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect(); let rsv: Vec<Signature> = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect();
// Create public transaction // Create public transaction
let signer_account = self.signer_account.ok_or_else(|| Error::SignerAccountNotSet)?;
let state = self.client.state_at(BlockId::Latest).ok_or(Error::StatePruned)?;
let nonce = state.nonce(&signer_account)?;
let public_tx = self.public_transaction( let public_tx = self.public_transaction(
desc.state.clone(), desc.state.clone(),
&desc.original_transaction, &desc.original_transaction,
&rsv, &rsv,
desc.original_transaction.nonce, nonce,
desc.original_transaction.gas_price desc.original_transaction.gas_price
)?; )?;
trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx); trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx);
// Sign and add it to the queue // Sign and add it to the queue
let chain_id = desc.original_transaction.chain_id(); let chain_id = desc.original_transaction.chain_id();
let hash = public_tx.hash(chain_id); let hash = public_tx.hash(chain_id);
let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?;
let signature = self.accounts.sign(signer_account, hash)?; let signature = self.accounts.sign(signer_account, hash)?;
let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?; let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?;
match self.miner.import_own_transaction(&*self.client, signed.into()) { match self.miner.import_own_transaction(&*self.client, signed.into()) {
Ok(_) => trace!(target: "privatetx", "Public transaction added to queue"), Ok(_) => trace!(target: "privatetx", "Public transaction added to queue"),
Err(err) => { Err(err) => {
warn!(target: "privatetx", "Failed to add transaction to queue, error: {:?}", err); warn!(target: "privatetx", "Failed to add transaction to queue, error: {:?}", err);
bail!(err); return Err(err.into());
} }
} }
// Notify about state changes // Notify about state changes
@ -395,7 +396,7 @@ impl Provider {
// Remove from store for signing // Remove from store for signing
if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) { if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) {
warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err); warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err);
bail!(err); return Err(err);
} }
} else { } else {
// Add signature to the store // Add signature to the store
@ -403,7 +404,7 @@ impl Provider {
Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"), Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"),
Err(err) => { Err(err) => {
warn!(target: "privatetx", "Failed to add signature to signing store, error: {:?}", err); warn!(target: "privatetx", "Failed to add signature to signing store, error: {:?}", err);
bail!(err); return Err(err);
} }
} }
} }
@ -415,7 +416,7 @@ impl Provider {
Action::Call(contract) => Ok(contract), Action::Call(contract) => Ok(contract),
_ => { _ => {
warn!(target: "privatetx", "Incorrect type of action for the transaction"); warn!(target: "privatetx", "Incorrect type of action for the transaction");
bail!(ErrorKind::BadTransactionType); return Err(Error::BadTransactionType);
} }
} }
} }
@ -434,13 +435,13 @@ impl Provider {
} }
false => { false => {
warn!(target: "privatetx", "Sender's state doesn't correspond to validator's"); warn!(target: "privatetx", "Sender's state doesn't correspond to validator's");
bail!(ErrorKind::StateIncorrect); return Err(Error::StateIncorrect);
} }
} }
} }
Err(err) => { Err(err) => {
warn!(target: "privatetx", "Sender's state doesn't correspond to validator's, error {:?}", err); warn!(target: "privatetx", "Sender's state doesn't correspond to validator's, error {:?}", err);
bail!(err); return Err(err.into());
} }
} }
} }
@ -480,21 +481,21 @@ impl Provider {
fn get_decrypted_state(&self, address: &Address, block: BlockId) -> Result<Bytes, Error> { fn get_decrypted_state(&self, address: &Address, block: BlockId) -> Result<Bytes, Error> {
let (data, decoder) = private_contract::functions::state::call(); let (data, decoder) = private_contract::functions::state::call();
let value = self.client.call_contract(block, *address, data)?; let value = self.client.call_contract(block, *address, data)?;
let state = decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?; let state = decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?;
self.decrypt(address, &state) self.decrypt(address, &state)
} }
fn get_decrypted_code(&self, address: &Address, block: BlockId) -> Result<Bytes, Error> { fn get_decrypted_code(&self, address: &Address, block: BlockId) -> Result<Bytes, Error> {
let (data, decoder) = private_contract::functions::code::call(); let (data, decoder) = private_contract::functions::code::call();
let value = self.client.call_contract(block, *address, data)?; let value = self.client.call_contract(block, *address, data)?;
let state = decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?; let state = decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?;
self.decrypt(address, &state) self.decrypt(address, &state)
} }
pub fn get_contract_nonce(&self, address: &Address, block: BlockId) -> Result<U256, Error> { pub fn get_contract_nonce(&self, address: &Address, block: BlockId) -> Result<U256, Error> {
let (data, decoder) = private_contract::functions::nonce::call(); let (data, decoder) = private_contract::functions::nonce::call();
let value = self.client.call_contract(block, *address, data)?; let value = self.client.call_contract(block, *address, data)?;
decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)).into()) decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into())
} }
fn snapshot_to_storage(raw: Bytes) -> HashMap<H256, H256> { fn snapshot_to_storage(raw: Bytes) -> HashMap<H256, H256> {
@ -531,10 +532,10 @@ impl Provider {
T: Tracer, T: Tracer,
V: VMTracer, V: VMTracer,
{ {
let mut env_info = self.client.env_info(block).ok_or(ErrorKind::StatePruned)?; let mut env_info = self.client.env_info(block).ok_or(Error::StatePruned)?;
env_info.gas_limit = transaction.gas; env_info.gas_limit = transaction.gas;
let mut state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; let mut state = self.client.state_at(block).ok_or(Error::StatePruned)?;
// TODO #9825 in case of BlockId::Latest these need to operate on the same state // TODO #9825 in case of BlockId::Latest these need to operate on the same state
let contract_address = match transaction.action { let contract_address = match transaction.action {
Action::Call(ref contract_address) => { Action::Call(ref contract_address) => {
@ -610,15 +611,15 @@ impl Provider {
/// Create encrypted public contract deployment transaction. /// Create encrypted public contract deployment transaction.
pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Address), Error> { pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Address), Error> {
if let Action::Call(_) = source.action { if let Action::Call(_) = source.action {
bail!(ErrorKind::BadTransactionType); return Err(Error::BadTransactionType);
} }
let sender = source.sender(); let sender = source.sender();
let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; let state = self.client.state_at(block).ok_or(Error::StatePruned)?;
let nonce = state.nonce(&sender)?; let nonce = state.nonce(&sender)?;
let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?;
let header = self.client.block_header(block) let header = self.client.block_header(block)
.ok_or(ErrorKind::StatePruned) .ok_or(Error::StatePruned)
.and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?; .and_then(|h| h.decode().map_err(|_| Error::StateIncorrect).into())?;
let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state); let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state);
let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone()); let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone());
let mut tx = Transaction { let mut tx = Transaction {
@ -649,7 +650,7 @@ impl Provider {
/// Create encrypted public contract deployment transaction. Returns updated encrypted state. /// Create encrypted public contract deployment transaction. Returns updated encrypted state.
pub fn execute_private_transaction(&self, block: BlockId, source: &SignedTransaction) -> Result<Bytes, Error> { pub fn execute_private_transaction(&self, block: BlockId, source: &SignedTransaction) -> Result<Bytes, Error> {
if let Action::Create = source.action { if let Action::Create = source.action {
bail!(ErrorKind::BadTransactionType); return Err(Error::BadTransactionType);
} }
let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?;
Ok(result.state) Ok(result.state)
@ -678,7 +679,7 @@ impl Provider {
pub fn get_validators(&self, block: BlockId, address: &Address) -> Result<Vec<Address>, Error> { pub fn get_validators(&self, block: BlockId, address: &Address) -> Result<Vec<Address>, Error> {
let (data, decoder) = private_contract::functions::get_validators::call(); let (data, decoder) = private_contract::functions::get_validators::call();
let value = self.client.call_contract(block, *address, data)?; let value = self.client.call_contract(block, *address, data)?;
decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)).into()) decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into())
} }
fn get_contract_version(&self, block: BlockId, address: &Address) -> usize { fn get_contract_version(&self, block: BlockId, address: &Address) -> usize {

View File

@ -28,7 +28,7 @@ use parking_lot::RwLock;
use types::transaction::{UnverifiedTransaction, SignedTransaction}; use types::transaction::{UnverifiedTransaction, SignedTransaction};
use txpool; use txpool;
use txpool::{VerifiedTransaction, Verifier}; use txpool::{VerifiedTransaction, Verifier};
use error::{Error, ErrorKind}; use error::Error;
type Pool = txpool::Pool<VerifiedPrivateTransaction, pool::scoring::NonceAndGasPrice>; type Pool = txpool::Pool<VerifiedPrivateTransaction, pool::scoring::NonceAndGasPrice>;
@ -154,7 +154,7 @@ impl Default for VerificationStore {
impl VerificationStore { impl VerificationStore {
/// Adds private transaction for verification into the store /// Adds private transaction for verification into the store
pub fn add_transaction<C: pool::client::Client>( pub fn add_transaction<C: pool::client::Client + pool::client::NonceClient + Clone>(
&self, &self,
transaction: UnverifiedTransaction, transaction: UnverifiedTransaction,
validator_account: Option<Address>, validator_account: Option<Address>,
@ -164,7 +164,7 @@ impl VerificationStore {
let options = self.verification_options.clone(); let options = self.verification_options.clone();
// Use pool's verifying pipeline for original transaction's verification // Use pool's verifying pipeline for original transaction's verification
let verifier = pool::verifier::Verifier::new(client, options, Default::default(), None); let verifier = pool::verifier::Verifier::new(client.clone(), options, Default::default(), None);
let unverified = pool::verifier::Transaction::Unverified(transaction); let unverified = pool::verifier::Transaction::Unverified(transaction);
let verified_tx = verifier.verify_transaction(unverified)?; let verified_tx = verifier.verify_transaction(unverified)?;
let signed_tx: SignedTransaction = verified_tx.signed().clone(); let signed_tx: SignedTransaction = verified_tx.signed().clone();
@ -177,8 +177,9 @@ impl VerificationStore {
transaction_hash: signed_hash, transaction_hash: signed_hash,
transaction_sender: signed_sender, transaction_sender: signed_sender,
}; };
let mut pool = self.verification_pool.write(); let replace = pool::replace::ReplaceByScoreAndReadiness::new(
pool.import(verified)?; self.verification_pool.read().scoring().clone(), client);
self.verification_pool.write().import(verified, &replace)?;
Ok(()) Ok(())
} }
@ -228,7 +229,7 @@ impl SigningStore {
contract_nonce: U256, contract_nonce: U256,
) -> Result<(), Error> { ) -> Result<(), Error> {
if self.transactions.len() > MAX_QUEUE_LEN { if self.transactions.len() > MAX_QUEUE_LEN {
bail!(ErrorKind::QueueIsFull); return Err(Error::QueueIsFull);
} }
self.transactions.insert(private_hash, PrivateTransactionSigningDesc { self.transactions.insert(private_hash, PrivateTransactionSigningDesc {
@ -254,7 +255,7 @@ impl SigningStore {
/// Adds received signature for the stored private transaction /// Adds received signature for the stored private transaction
pub fn add_signature(&mut self, private_hash: &H256, signature: Signature) -> Result<(), Error> { pub fn add_signature(&mut self, private_hash: &H256, signature: Signature) -> Result<(), Error> {
let desc = self.transactions.get_mut(private_hash).ok_or_else(|| ErrorKind::PrivateTransactionNotFound)?; let desc = self.transactions.get_mut(private_hash).ok_or_else(|| Error::PrivateTransactionNotFound)?;
if !desc.received_signatures.contains(&signature) { if !desc.received_signatures.contains(&signature) {
desc.received_signatures.push(signature); desc.received_signatures.push(signature);
} }

View File

@ -19,12 +19,9 @@ use io;
use ethcore_private_tx; use ethcore_private_tx;
error_chain! { error_chain! {
links {
PrivateTransactions(ethcore_private_tx::Error, ethcore_private_tx::ErrorKind);
}
foreign_links { foreign_links {
Ethcore(ethcore::error::Error); Ethcore(ethcore::error::Error);
IoError(io::IoError); IoError(io::IoError);
PrivateTransactions(ethcore_private_tx::Error);
} }
} }

View File

@ -32,7 +32,7 @@ parking_lot = "0.7"
price-info = { path = "./price-info", optional = true } price-info = { path = "./price-info", optional = true }
rlp = { version = "0.3.0", features = ["ethereum"] } rlp = { version = "0.3.0", features = ["ethereum"] }
trace-time = "0.1" trace-time = "0.1"
transaction-pool = "1.13" transaction-pool = "2.0"
[dev-dependencies] [dev-dependencies]
env_logger = "0.5" env_logger = "0.5"

View File

@ -92,7 +92,7 @@ impl txpool::Listener<Transaction> for Logger {
} }
} }
fn rejected(&mut self, _tx: &Arc<Transaction>, reason: &txpool::ErrorKind) { fn rejected<H: fmt::Debug + fmt::LowerHex>(&mut self, _tx: &Arc<Transaction>, reason: &txpool::Error<H>) {
trace!(target: "txqueue", "Rejected {}.", reason); trace!(target: "txqueue", "Rejected {}.", reason);
} }

View File

@ -171,7 +171,7 @@ impl txpool::Listener<Transaction> for LocalTransactionsList {
} }
} }
fn rejected(&mut self, tx: &Arc<Transaction>, reason: &txpool::ErrorKind) { fn rejected<H: fmt::Debug + fmt::LowerHex>(&mut self, tx: &Arc<Transaction>, reason: &txpool::Error<H>) {
if !tx.priority().is_local() { if !tx.priority().is_local() {
return; return;
} }

View File

@ -27,6 +27,7 @@ mod ready;
pub mod client; pub mod client;
pub mod local_transactions; pub mod local_transactions;
pub mod replace;
pub mod scoring; pub mod scoring;
pub mod verifier; pub mod verifier;
@ -121,7 +122,7 @@ pub trait ScoredTransaction {
} }
/// Verified transaction stored in the pool. /// Verified transaction stored in the pool.
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct VerifiedTransaction { pub struct VerifiedTransaction {
transaction: transaction::PendingTransaction, transaction: transaction::PendingTransaction,
// TODO [ToDr] hash and sender should go directly from the transaction // TODO [ToDr] hash and sender should go directly from the transaction

View File

@ -27,7 +27,7 @@ use txpool::{self, Verifier};
use types::transaction; use types::transaction;
use pool::{ use pool::{
self, scoring, verifier, client, ready, listener, self, replace, scoring, verifier, client, ready, listener,
PrioritizationStrategy, PendingOrdering, PendingSettings, PrioritizationStrategy, PendingOrdering, PendingSettings,
}; };
use pool::local_transactions::LocalTransactionsList; use pool::local_transactions::LocalTransactionsList;
@ -240,7 +240,7 @@ impl TransactionQueue {
/// ///
/// Given blockchain and state access (Client) /// Given blockchain and state access (Client)
/// verifies and imports transactions to the pool. /// verifies and imports transactions to the pool.
pub fn import<C: client::Client>( pub fn import<C: client::Client + client::NonceClient + Clone>(
&self, &self,
client: C, client: C,
transactions: Vec<verifier::Transaction>, transactions: Vec<verifier::Transaction>,
@ -263,12 +263,14 @@ impl TransactionQueue {
}; };
let verifier = verifier::Verifier::new( let verifier = verifier::Verifier::new(
client, client.clone(),
options, options,
self.insertion_id.clone(), self.insertion_id.clone(),
transaction_to_replace, transaction_to_replace,
); );
let mut replace = replace::ReplaceByScoreAndReadiness::new(self.pool.read().scoring().clone(), client);
let results = transactions let results = transactions
.into_iter() .into_iter()
.map(|transaction| { .map(|transaction| {
@ -286,7 +288,7 @@ impl TransactionQueue {
let imported = verifier let imported = verifier
.verify_transaction(transaction) .verify_transaction(transaction)
.and_then(|verified| { .and_then(|verified| {
self.pool.write().import(verified).map_err(convert_error) self.pool.write().import(verified, &mut replace).map_err(convert_error)
}); });
match imported { match imported {
@ -579,17 +581,13 @@ impl TransactionQueue {
} }
} }
fn convert_error(err: txpool::Error) -> transaction::Error { fn convert_error<H: fmt::Debug + fmt::LowerHex>(err: txpool::Error<H>) -> transaction::Error {
use self::txpool::ErrorKind; use self::txpool::Error;
match *err.kind() { match err {
ErrorKind::AlreadyImported(..) => transaction::Error::AlreadyImported, Error::AlreadyImported(..) => transaction::Error::AlreadyImported,
ErrorKind::TooCheapToEnter(..) => transaction::Error::LimitReached, Error::TooCheapToEnter(..) => transaction::Error::LimitReached,
ErrorKind::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace, Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace
ref e => {
warn!(target: "txqueue", "Unknown import error: {:?}", e);
transaction::Error::NotAllowed
},
} }
} }

415
miner/src/pool/replace.rs Normal file
View File

@ -0,0 +1,415 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Replacing Transactions
//!
//! When queue limits are reached, a new transaction may replace one already
//! in the pool. The decision whether to reject, replace or retain both is
//! delegated to an implementation of `ShouldReplace`.
//!
//! Here we decide based on the sender, the nonce and gas price, and finally
//! on the `Readiness` of the transactions when comparing them
use std::cmp;
use ethereum_types::{U256, H160 as Address};
use txpool::{self, scoring::{Choice, Scoring}, ReplaceTransaction};
use txpool::VerifiedTransaction;
use super::{client, ScoredTransaction};
/// Choose whether to replace based on the sender, the score and finally the
/// `Readiness` of the transactions being compared.
#[derive(Debug)]
pub struct ReplaceByScoreAndReadiness<S, C> {
scoring: S,
client: C,
}
impl<S, C> ReplaceByScoreAndReadiness<S, C> {
/// Create a new `ReplaceByScoreAndReadiness`
pub fn new(scoring: S, client: C) -> Self {
ReplaceByScoreAndReadiness { scoring, client }
}
}
impl<T, S, C> txpool::ShouldReplace<T> for ReplaceByScoreAndReadiness<S, C>
where
T: VerifiedTransaction<Sender = Address> + ScoredTransaction + PartialEq,
S: Scoring<T>,
C: client::NonceClient,
{
fn should_replace(
&self,
old: &ReplaceTransaction<T>,
new: &ReplaceTransaction<T>,
) -> Choice {
let both_local = old.priority().is_local() && new.priority().is_local();
if old.sender() == new.sender() {
// prefer earliest transaction
match new.nonce().cmp(&old.nonce()) {
cmp::Ordering::Equal => self.scoring.choose(&old, &new),
_ if both_local => Choice::InsertNew,
cmp::Ordering::Less => Choice::ReplaceOld,
cmp::Ordering::Greater => Choice::RejectNew,
}
} else if both_local {
Choice::InsertNew
} else {
let old_score = (old.priority(), old.gas_price());
let new_score = (new.priority(), new.gas_price());
if new_score > old_score {
let state = &self.client;
// calculate readiness based on state nonce + pooled txs from same sender
let is_ready = |replace: &ReplaceTransaction<T>| {
let mut nonce = state.account_nonce(replace.sender());
if let Some(txs) = replace.pooled_by_sender {
for tx in txs.iter() {
if nonce == tx.nonce() && *tx.transaction != ***replace.transaction {
nonce = nonce.saturating_add(U256::from(1))
} else {
break
}
}
}
nonce == replace.nonce()
};
if !is_ready(new) && is_ready(old) {
// prevent a ready transaction being replace by a non-ready transaction
Choice::RejectNew
} else {
Choice::ReplaceOld
}
} else {
Choice::RejectNew
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use ethkey::{Random, Generator, KeyPair};
use pool::tests::tx::{Tx, TxExt};
use pool::tests::client::TestClient;
use pool::scoring::*;
use pool::{PrioritizationStrategy, VerifiedTransaction};
use txpool::scoring::Choice::*;
use txpool::ShouldReplace;
fn local_tx_verified(tx: Tx, keypair: &KeyPair) -> VerifiedTransaction {
let mut verified_tx = tx.unsigned().sign(keypair.secret(), None).verified();
verified_tx.priority = ::pool::Priority::Local;
verified_tx
}
fn should_replace(replace: &ShouldReplace<VerifiedTransaction>, old: VerifiedTransaction, new: VerifiedTransaction) -> Choice {
let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old) };
let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(new) };
let old = ReplaceTransaction::new(&old_tx, Default::default());
let new = ReplaceTransaction::new(&new_tx, Default::default());
replace.should_replace(&old, &new)
}
#[test]
fn should_always_accept_local_transactions_unless_same_sender_and_nonce() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(1);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
// same sender txs
let keypair = Random.generate().unwrap();
let same_sender_tx1 = local_tx_verified(Tx {
nonce: 1,
gas_price: 1,
..Default::default()
}, &keypair);
let same_sender_tx2 = local_tx_verified(Tx {
nonce: 2,
gas_price: 100,
..Default::default()
}, &keypair);
let same_sender_tx3 = local_tx_verified(Tx {
nonce: 2,
gas_price: 200,
..Default::default()
}, &keypair);
// different sender txs
let sender1 = Random.generate().unwrap();
let different_sender_tx1 = local_tx_verified(Tx {
nonce: 2,
gas_price: 1,
..Default::default()
}, &sender1);
let sender2 = Random.generate().unwrap();
let different_sender_tx2 = local_tx_verified(Tx {
nonce: 1,
gas_price: 10,
..Default::default()
}, &sender2);
assert_eq!(should_replace(&replace, same_sender_tx1.clone(), same_sender_tx2.clone()), InsertNew);
assert_eq!(should_replace(&replace, same_sender_tx2.clone(), same_sender_tx1.clone()), InsertNew);
assert_eq!(should_replace(&replace, different_sender_tx1.clone(), different_sender_tx2.clone()), InsertNew);
assert_eq!(should_replace(&replace, different_sender_tx2.clone(), different_sender_tx1.clone()), InsertNew);
// txs with same sender and nonce
assert_eq!(should_replace(&replace, same_sender_tx2.clone(), same_sender_tx3.clone()), ReplaceOld);
assert_eq!(should_replace(&replace, same_sender_tx3.clone(), same_sender_tx2.clone()), RejectNew);
}
#[test]
fn should_replace_same_sender_by_nonce() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(1);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
let tx1 = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
let tx2 = Tx {
nonce: 2,
gas_price: 100,
..Default::default()
};
let tx3 = Tx {
nonce: 2,
gas_price: 110,
..Default::default()
};
let tx4 = Tx {
nonce: 2,
gas_price: 130,
..Default::default()
};
let keypair = Random.generate().unwrap();
let txs = vec![tx1, tx2, tx3, tx4].into_iter().map(|tx| {
tx.unsigned().sign(keypair.secret(), None).verified()
}).collect::<Vec<_>>();
assert_eq!(should_replace(&replace, txs[0].clone(), txs[1].clone()), RejectNew);
assert_eq!(should_replace(&replace, txs[1].clone(), txs[0].clone()), ReplaceOld);
assert_eq!(should_replace(&replace, txs[1].clone(), txs[2].clone()), RejectNew);
assert_eq!(should_replace(&replace, txs[2].clone(), txs[1].clone()), RejectNew);
assert_eq!(should_replace(&replace, txs[1].clone(), txs[3].clone()), ReplaceOld);
assert_eq!(should_replace(&replace, txs[3].clone(), txs[1].clone()), RejectNew);
}
#[test]
fn should_replace_different_sender_by_priority_and_gas_price() {
// given
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(0);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
let tx_regular_low_gas = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.signed().verified()
};
let tx_regular_high_gas = {
let tx = Tx {
nonce: 2,
gas_price: 10,
..Default::default()
};
tx.signed().verified()
};
let tx_local_low_gas = {
let tx = Tx {
nonce: 2,
gas_price: 1,
..Default::default()
};
let mut verified_tx = tx.signed().verified();
verified_tx.priority = ::pool::Priority::Local;
verified_tx
};
let tx_local_high_gas = {
let tx = Tx {
nonce: 1,
gas_price: 10,
..Default::default()
};
let mut verified_tx = tx.signed().verified();
verified_tx.priority = ::pool::Priority::Local;
verified_tx
};
assert_eq!(should_replace(&replace, tx_regular_low_gas.clone(), tx_regular_high_gas.clone()), ReplaceOld);
assert_eq!(should_replace(&replace, tx_regular_high_gas.clone(), tx_regular_low_gas.clone()), RejectNew);
assert_eq!(should_replace(&replace, tx_regular_high_gas.clone(), tx_local_low_gas.clone()), ReplaceOld);
assert_eq!(should_replace(&replace, tx_local_low_gas.clone(), tx_regular_high_gas.clone()), RejectNew);
assert_eq!(should_replace(&replace, tx_local_low_gas.clone(), tx_local_high_gas.clone()), InsertNew);
assert_eq!(should_replace(&replace, tx_local_high_gas.clone(), tx_regular_low_gas.clone()), RejectNew);
}
#[test]
fn should_not_replace_ready_transaction_with_future_transaction() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(1);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
let tx_ready_low_score = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.signed().verified()
};
let tx_future_high_score = {
let tx = Tx {
nonce: 3, // future nonce
gas_price: 10,
..Default::default()
};
tx.signed().verified()
};
assert_eq!(should_replace(&replace, tx_ready_low_score, tx_future_high_score), RejectNew);
}
#[test]
fn should_compute_readiness_with_pooled_transactions_from_the_same_sender_as_the_existing_transaction() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(1);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
let old_sender = Random.generate().unwrap();
let tx_old_ready_1 = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.unsigned().sign(&old_sender.secret(), None).verified()
};
let tx_old_ready_2 = {
let tx = Tx {
nonce: 2,
gas_price: 1,
..Default::default()
};
tx.unsigned().sign(&old_sender.secret(), None).verified()
};
let tx_old_ready_3 = {
let tx = Tx {
nonce: 3,
gas_price: 1,
..Default::default()
};
tx.unsigned().sign(&old_sender.secret(), None).verified()
};
let new_tx = {
let tx = Tx {
nonce: 3, // future nonce
gas_price: 10,
..Default::default()
};
tx.signed().verified()
};
let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_old_ready_3) };
let pooled_txs = [
txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_old_ready_1) },
txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_old_ready_2) },
];
let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(new_tx) };
let old = ReplaceTransaction::new(&old_tx, Some(&pooled_txs));
let new = ReplaceTransaction::new(&new_tx, Default::default());
assert_eq!(replace.should_replace(&old, &new), RejectNew);
}
#[test]
fn should_compute_readiness_with_pooled_transactions_from_the_same_sender_as_the_new_transaction() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(1);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
// current transaction is ready but has a lower gas price than the new one
let old_tx = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.signed().verified()
};
let new_sender = Random.generate().unwrap();
let tx_new_ready_1 = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.unsigned().sign(&new_sender.secret(), None).verified()
};
let tx_new_ready_2 = {
let tx = Tx {
nonce: 2,
gas_price: 1,
..Default::default()
};
tx.unsigned().sign(&new_sender.secret(), None).verified()
};
let tx_new_ready_3 = {
let tx = Tx {
nonce: 3,
gas_price: 10, // hi
..Default::default()
};
tx.unsigned().sign(&new_sender.secret(), None).verified()
};
let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old_tx) };
let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_3) };
let pooled_txs = [
txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_1) },
txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_2) },
];
let old = ReplaceTransaction::new(&old_tx, None);
let new = ReplaceTransaction::new(&new_tx, Some(&pooled_txs));
assert_eq!(replace.should_replace(&old, &new), ReplaceOld);
}
}

View File

@ -122,29 +122,6 @@ impl<P> txpool::Scoring<P> for NonceAndGasPrice where P: ScoredTransaction + txp
} }
} }
fn should_replace(&self, old: &P, new: &P) -> scoring::Choice {
let both_local = old.priority().is_local() && new.priority().is_local();
if old.sender() == new.sender() {
// prefer earliest transaction
match new.nonce().cmp(&old.nonce()) {
cmp::Ordering::Equal => self.choose(old, new),
_ if both_local => scoring::Choice::InsertNew,
cmp::Ordering::Less => scoring::Choice::ReplaceOld,
cmp::Ordering::Greater => scoring::Choice::RejectNew,
}
} else if both_local {
scoring::Choice::InsertNew
} else {
let old_score = (old.priority(), old.gas_price());
let new_score = (new.priority(), new.gas_price());
if new_score > old_score {
scoring::Choice::ReplaceOld
} else {
scoring::Choice::RejectNew
}
}
}
fn should_ignore_sender_limit(&self, new: &P) -> bool { fn should_ignore_sender_limit(&self, new: &P) -> bool {
new.priority().is_local() new.priority().is_local()
} }
@ -155,156 +132,8 @@ mod tests {
use super::*; use super::*;
use std::sync::Arc; use std::sync::Arc;
use ethkey::{Random, Generator, KeyPair};
use pool::tests::tx::{Tx, TxExt}; use pool::tests::tx::{Tx, TxExt};
use txpool::Scoring; use txpool::Scoring;
use txpool::scoring::Choice::*;
fn local_tx_verified(tx: Tx, keypair: &KeyPair) -> VerifiedTransaction {
let mut verified_tx = tx.unsigned().sign(keypair.secret(), None).verified();
verified_tx.priority = ::pool::Priority::Local;
verified_tx
}
#[test]
fn should_always_accept_local_transactions_unless_same_sender_and_nonce() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
// same sender txs
let keypair = Random.generate().unwrap();
let same_sender_tx1 = local_tx_verified(Tx {
nonce: 1,
gas_price: 1,
..Default::default()
}, &keypair);
let same_sender_tx2 = local_tx_verified(Tx {
nonce: 2,
gas_price: 100,
..Default::default()
}, &keypair);
let same_sender_tx3 = local_tx_verified(Tx {
nonce: 2,
gas_price: 200,
..Default::default()
}, &keypair);
// different sender txs
let different_sender_tx1 = local_tx_verified(Tx {
nonce: 2,
gas_price: 1,
..Default::default()
}, &Random.generate().unwrap());
let different_sender_tx2 = local_tx_verified(Tx {
nonce: 1,
gas_price: 10,
..Default::default()
}, &Random.generate().unwrap());
assert_eq!(scoring.should_replace(&same_sender_tx1, &same_sender_tx2), InsertNew);
assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx1), InsertNew);
assert_eq!(scoring.should_replace(&different_sender_tx1, &different_sender_tx2), InsertNew);
assert_eq!(scoring.should_replace(&different_sender_tx2, &different_sender_tx1), InsertNew);
// txs with same sender and nonce
assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx3), ReplaceOld);
assert_eq!(scoring.should_replace(&same_sender_tx3, &same_sender_tx2), RejectNew);
}
#[test]
fn should_replace_same_sender_by_nonce() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let tx1 = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
let tx2 = Tx {
nonce: 2,
gas_price: 100,
..Default::default()
};
let tx3 = Tx {
nonce: 2,
gas_price: 110,
..Default::default()
};
let tx4 = Tx {
nonce: 2,
gas_price: 130,
..Default::default()
};
let keypair = Random.generate().unwrap();
let txs = vec![tx1, tx2, tx3, tx4].into_iter().map(|tx| {
tx.unsigned().sign(keypair.secret(), None).verified()
}).collect::<Vec<_>>();
assert_eq!(scoring.should_replace(&txs[0], &txs[1]), RejectNew);
assert_eq!(scoring.should_replace(&txs[1], &txs[0]), ReplaceOld);
assert_eq!(scoring.should_replace(&txs[1], &txs[2]), RejectNew);
assert_eq!(scoring.should_replace(&txs[2], &txs[1]), RejectNew);
assert_eq!(scoring.should_replace(&txs[1], &txs[3]), ReplaceOld);
assert_eq!(scoring.should_replace(&txs[3], &txs[1]), RejectNew);
}
#[test]
fn should_replace_different_sender_by_priority_and_gas_price() {
// given
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let tx_regular_low_gas = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.signed().verified()
};
let tx_regular_high_gas = {
let tx = Tx {
nonce: 2,
gas_price: 10,
..Default::default()
};
tx.signed().verified()
};
let tx_local_low_gas = {
let tx = Tx {
nonce: 2,
gas_price: 1,
..Default::default()
};
let mut verified_tx = tx.signed().verified();
verified_tx.priority = ::pool::Priority::Local;
verified_tx
};
let tx_local_high_gas = {
let tx = Tx {
nonce: 1,
gas_price: 10,
..Default::default()
};
let mut verified_tx = tx.signed().verified();
verified_tx.priority = ::pool::Priority::Local;
verified_tx
};
assert_eq!(scoring.should_replace(&tx_regular_low_gas, &tx_regular_high_gas), ReplaceOld);
assert_eq!(scoring.should_replace(&tx_regular_high_gas, &tx_regular_low_gas), RejectNew);
assert_eq!(scoring.should_replace(&tx_regular_high_gas, &tx_local_low_gas), ReplaceOld);
assert_eq!(scoring.should_replace(&tx_local_low_gas, &tx_regular_high_gas), RejectNew);
assert_eq!(scoring.should_replace(&tx_local_low_gas, &tx_local_high_gas), InsertNew);
assert_eq!(scoring.should_replace(&tx_local_high_gas, &tx_regular_low_gas), RejectNew);
}
#[test] #[test]
fn should_calculate_score_correctly() { fn should_calculate_score_correctly() {

View File

@ -72,7 +72,7 @@ fake-fetch = { path = "../util/fake-fetch" }
kvdb-memorydb = "0.1" kvdb-memorydb = "0.1"
macros = { path = "../util/macros" } macros = { path = "../util/macros" }
pretty_assertions = "0.1" pretty_assertions = "0.1"
transaction-pool = "1.13" transaction-pool = "2.0"
[features] [features]
accounts = ["ethcore-accounts"] accounts = ["ethcore-accounts"]

View File

@ -86,7 +86,7 @@ use jsonrpc_core::{BoxFuture, Result, Error};
use jsonrpc_core::futures::{future, Future, IntoFuture}; use jsonrpc_core::futures::{future, Future, IntoFuture};
use v1::helpers::{TransactionRequest, FilledTransactionRequest, ConfirmationPayload}; use v1::helpers::{TransactionRequest, FilledTransactionRequest, ConfirmationPayload};
use v1::types::{ use v1::types::{
H520 as RpcH520, Bytes as RpcBytes, Bytes as RpcBytes,
RichRawTransaction as RpcRichRawTransaction, RichRawTransaction as RpcRichRawTransaction,
ConfirmationPayload as RpcConfirmationPayload, ConfirmationPayload as RpcConfirmationPayload,
ConfirmationResponse, ConfirmationResponse,
@ -309,7 +309,6 @@ pub fn execute<D: Dispatcher + 'static>(
let res = signer.sign_message(address, pass, SignMessage::Data(data)) let res = signer.sign_message(address, pass, SignMessage::Data(data))
.map(|result| result .map(|result| result
.map(|s| H520(s.into_electrum())) .map(|s| H520(s.into_electrum()))
.map(RpcH520::from)
.map(ConfirmationResponse::Signature) .map(ConfirmationResponse::Signature)
); );
@ -319,7 +318,6 @@ pub fn execute<D: Dispatcher + 'static>(
let res = signer.sign_message(address, pass, SignMessage::Hash(data)) let res = signer.sign_message(address, pass, SignMessage::Hash(data))
.map(|result| result .map(|result| result
.map(|rsv| H520(rsv.into_electrum())) .map(|rsv| H520(rsv.into_electrum()))
.map(RpcH520::from)
.map(ConfirmationResponse::Signature) .map(ConfirmationResponse::Signature)
); );

View File

@ -15,6 +15,7 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap; use std::collections::BTreeMap;
use ethereum_types::U256; use ethereum_types::U256;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use super::oneshot; use super::oneshot;

View File

@ -40,13 +40,14 @@ use light::on_demand::{
}; };
use light::on_demand::error::Error as OnDemandError; use light::on_demand::error::Error as OnDemandError;
use light::request::Field; use light::request::Field;
use light::TransactionQueue;
use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider}; use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider};
use ethereum_types::{U256, Address}; use ethereum_types::{Address, U256};
use hash::H256; use hash::H256;
use parking_lot::Mutex; use parking_lot::{Mutex, RwLock};
use fastmap::H256FastMap; use fastmap::H256FastMap;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use types::transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction}; use types::transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction};
@ -56,6 +57,7 @@ use v1::types::{BlockNumber, CallRequest, Log, Transaction};
const NO_INVALID_BACK_REFS_PROOF: &str = "Fails only on invalid back-references; back-references here known to be valid; qed"; const NO_INVALID_BACK_REFS_PROOF: &str = "Fails only on invalid back-references; back-references here known to be valid; qed";
const WRONG_RESPONSE_AMOUNT_TYPE_PROOF: &str = "responses correspond directly with requests in amount and type; qed"; const WRONG_RESPONSE_AMOUNT_TYPE_PROOF: &str = "responses correspond directly with requests in amount and type; qed";
const DEFAULT_GAS_PRICE: u64 = 21_000;
pub fn light_all_transactions<S>(dispatch: &Arc<dispatch::LightDispatcher<S>>) -> impl Iterator<Item=PendingTransaction> pub fn light_all_transactions<S>(dispatch: &Arc<dispatch::LightDispatcher<S>>) -> impl Iterator<Item=PendingTransaction>
where where
@ -95,7 +97,7 @@ where
on_demand: self.on_demand.clone(), on_demand: self.on_demand.clone(),
sync: self.sync.clone(), sync: self.sync.clone(),
cache: self.cache.clone(), cache: self.cache.clone(),
gas_price_percentile: self.gas_price_percentile gas_price_percentile: self.gas_price_percentile,
} }
} }
} }
@ -209,7 +211,13 @@ where
/// Helper for getting account info at a given block. /// Helper for getting account info at a given block.
/// `None` indicates the account doesn't exist at the given block. /// `None` indicates the account doesn't exist at the given block.
pub fn account(&self, address: Address, id: BlockId) -> impl Future<Item = Option<BasicAccount>, Error = Error> + Send { pub fn account(
&self,
address: Address,
id: BlockId,
tx_queue: Arc<RwLock<TransactionQueue>>
) -> impl Future<Item = Option<BasicAccount>, Error = Error> + Send {
let mut reqs = Vec::new(); let mut reqs = Vec::new();
let header_ref = match self.make_header_requests(id, &mut reqs) { let header_ref = match self.make_header_requests(id, &mut reqs) {
Ok(r) => r, Ok(r) => r,
@ -218,15 +226,26 @@ where
reqs.push(request::Account { header: header_ref, address: address }.into()); reqs.push(request::Account { header: header_ref, address: address }.into());
Either::B(self.send_requests(reqs, |mut res|match res.pop() { Either::B(self.send_requests(reqs, move |mut res| match res.pop() {
Some(OnDemandResponse::Account(acc)) => acc, Some(OnDemandResponse::Account(maybe_account)) => {
if let Some(ref acc) = maybe_account {
let mut txq = tx_queue.write();
txq.cull(address, acc.nonce);
}
maybe_account
}
_ => panic!(WRONG_RESPONSE_AMOUNT_TYPE_PROOF), _ => panic!(WRONG_RESPONSE_AMOUNT_TYPE_PROOF),
})) }))
} }
/// Helper for getting proved execution. /// Helper for getting proved execution.
pub fn proved_read_only_execution(&self, req: CallRequest, num: Option<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send { pub fn proved_read_only_execution(
const DEFAULT_GAS_PRICE: u64 = 21_000; &self,
req: CallRequest,
num: Option<BlockNumber>,
txq: Arc<RwLock<TransactionQueue>>
) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
// (21000 G_transaction + 32000 G_create + some marginal to allow a few operations) // (21000 G_transaction + 32000 G_create + some marginal to allow a few operations)
const START_GAS: u64 = 60_000; const START_GAS: u64 = 60_000;
@ -249,21 +268,12 @@ where
let from = req.from.unwrap_or_else(|| Address::zero()); let from = req.from.unwrap_or_else(|| Address::zero());
let nonce_fut = match req.nonce { let nonce_fut = match req.nonce {
Some(nonce) => Either::A(future::ok(Some(nonce))), Some(nonce) => Either::A(future::ok(Some(nonce))),
None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))), None => Either::B(self.account(from, id, txq).map(|acc| acc.map(|a| a.nonce))),
}; };
let gas_price_percentile = self.gas_price_percentile;
let gas_price_fut = match req.gas_price { let gas_price_fut = match req.gas_price {
Some(price) => Either::A(future::ok(price)), Some(price) => Either::A(future::ok(price)),
None => Either::B(dispatch::light::fetch_gas_price_corpus( None => Either::B(self.gas_price()),
self.sync.clone(),
self.client.clone(),
self.on_demand.clone(),
self.cache.clone(),
).map(move |corp| match corp.percentile(gas_price_percentile) {
Some(percentile) => *percentile,
None => DEFAULT_GAS_PRICE.into(),
}))
}; };
// if nonce resolves, this should too since it'll be in the LRU-cache. // if nonce resolves, this should too since it'll be in the LRU-cache.
@ -302,6 +312,23 @@ where
})) }))
} }
/// Helper to fetch the corpus gas price from 1) the cache 2) the network then it tries to estimate the percentile
/// using `gas_price_percentile` if the estimated percentile is zero the `DEFAULT_GAS_PRICE` is returned
pub fn gas_price(&self) -> impl Future<Item = U256, Error = Error> + Send {
let gas_price_percentile = self.gas_price_percentile;
dispatch::light::fetch_gas_price_corpus(
self.sync.clone(),
self.client.clone(),
self.on_demand.clone(),
self.cache.clone(),
)
.map(move |corp| {
corp.percentile(gas_price_percentile)
.map_or_else(|| DEFAULT_GAS_PRICE.into(), |percentile| *percentile)
})
}
/// Get a block itself. Fails on unknown block ID. /// Get a block itself. Fails on unknown block ID.
pub fn block(&self, id: BlockId) -> impl Future<Item = encoded::Block, Error = Error> + Send { pub fn block(&self, id: BlockId) -> impl Future<Item = encoded::Block, Error = Error> + Send {
let mut reqs = Vec::new(); let mut reqs = Vec::new();

View File

@ -16,12 +16,13 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use rand::{Rng, OsRng}; use rand::{Rng, OsRng};
use ethereum_types::{H256, H512};
use ethkey::{self, Public, Secret, Random, Generator, math}; use ethkey::{self, Public, Secret, Random, Generator, math};
use crypto; use crypto;
use bytes::Bytes; use bytes::Bytes;
use jsonrpc_core::Error; use jsonrpc_core::Error;
use v1::helpers::errors; use v1::helpers::errors;
use v1::types::{H256, H512, EncryptedDocumentKey}; use v1::types::EncryptedDocumentKey;
use tiny_keccak::Keccak; use tiny_keccak::Keccak;
/// Initialization vector length. /// Initialization vector length.

View File

@ -15,8 +15,9 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use ethkey::{recover, public_to_address, Signature}; use ethkey::{recover, public_to_address, Signature};
use ethereum_types::{H256, U64};
use jsonrpc_core::Result; use jsonrpc_core::Result;
use v1::types::{Bytes, RecoveredAccount, H256, U64}; use v1::types::{Bytes, RecoveredAccount};
use v1::helpers::errors; use v1::helpers::errors;
use v1::helpers::dispatch::eth_data_hash; use v1::helpers::dispatch::eth_data_hash;
use hash::keccak; use hash::keccak;
@ -35,7 +36,7 @@ pub fn verify_signature(
} else { } else {
keccak(message.0) keccak(message.0)
}; };
let v: u64 = v.into(); let v = v.as_u64();
let is_valid_for_current_chain = match (chain_id, v) { let is_valid_for_current_chain = match (chain_id, v) {
(None, v) if v == 0 || v == 1 => true, (None, v) if v == 0 || v == 1 => true,
(Some(chain_id), v) if v >= 35 => (v - 35) / 2 == chain_id, (Some(chain_id), v) if v >= 35 => (v - 35) / 2 == chain_id,
@ -54,7 +55,7 @@ pub fn verify_signature(
mod tests { mod tests {
use super::*; use super::*;
use ethkey::Generator; use ethkey::Generator;
use v1::types::H160; use ethereum_types::{H160, U64};
pub fn add_chain_replay_protection(v: u64, chain_id: Option<u64>) -> u64 { pub fn add_chain_replay_protection(v: u64, chain_id: Option<u64>) -> u64 {
v + if let Some(n) = chain_id { 35 + n * 2 } else { 0 } v + if let Some(n) = chain_id { 35 + n * 2 } else { 0 }

View File

@ -19,8 +19,8 @@
use std::{ops, str}; use std::{ops, str};
use std::collections::HashMap; use std::collections::HashMap;
use jsonrpc_pubsub::{typed::{Subscriber, Sink}, SubscriptionId}; use jsonrpc_pubsub::{typed::{Subscriber, Sink}, SubscriptionId};
use ethereum_types::H64;
use rand::{Rng, StdRng}; use rand::{Rng, StdRng};
use v1::types::H64;
#[derive(Debug, Clone, Hash, Eq, PartialEq)] #[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub struct Id(H64); pub struct Id(H64);
@ -36,8 +36,9 @@ impl str::FromStr for Id {
} }
} }
impl Id { impl Id {
// TODO: replace `format!` see [#10412](https://github.com/paritytech/parity-ethereum/issues/10412)
pub fn as_string(&self) -> String { pub fn as_string(&self) -> String {
format!("0x{:?}", self.0) format!("{:?}", self.0)
} }
} }

View File

@ -20,17 +20,13 @@ use std::sync::Arc;
use rlp; use rlp;
use ethcore::miner::{BlockChainClient, MinerService}; use ethcore::miner::{BlockChainClient, MinerService};
use ethereum_types::{H64 as EthcoreH64, H256 as EthcoreH256}; use ethereum_types::{H64, H256};
use jsonrpc_core::Error; use jsonrpc_core::Error;
use v1::types::{H64, H256};
use v1::helpers::errors; use v1::helpers::errors;
// Submit a POW work and return the block's hash // Submit a POW work and return the block's hash
pub fn submit_work_detail<C: BlockChainClient, M: MinerService>(client: &Arc<C>, miner: &Arc<M>, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result<H256, Error> { pub fn submit_work_detail<C: BlockChainClient, M: MinerService>(client: &Arc<C>, miner: &Arc<M>, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result<H256, Error> {
// TODO [ToDr] Should disallow submissions in case of PoA? // TODO [ToDr] Should disallow submissions in case of PoA?
let nonce: EthcoreH64 = nonce.into();
let pow_hash: EthcoreH256 = pow_hash.into();
let mix_hash: EthcoreH256 = mix_hash.into();
trace!(target: "miner", "submit_work_detail: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash); trace!(target: "miner", "submit_work_detail: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
let seal = vec![rlp::encode(&mix_hash), rlp::encode(&nonce)]; let seal = vec![rlp::encode(&mix_hash), rlp::encode(&nonce)];
let import = miner.submit_seal(pow_hash, seal) let import = miner.submit_seal(pow_hash, seal)

View File

@ -21,7 +21,7 @@ use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
use std::sync::Arc; use std::sync::Arc;
use rlp::Rlp; use rlp::Rlp;
use ethereum_types::{U256, H256, H160, Address}; use ethereum_types::{Address, H64, H160, H256, U64, U256};
use parking_lot::Mutex; use parking_lot::Mutex;
use ethash::{self, SeedHashCompute}; use ethash::{self, SeedHashCompute};
@ -47,8 +47,7 @@ use v1::traits::Eth;
use v1::types::{ use v1::types::{
RichBlock, Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, RichBlock, Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo,
Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount, StorageProof, Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount, StorageProof,
H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256, block_number_to_id, block_number_to_id
U64 as RpcU64,
}; };
use v1::metadata::Metadata; use v1::metadata::Metadata;
@ -530,7 +529,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
} }
} }
fn author(&self) -> Result<RpcH160> { fn author(&self) -> Result<H160> {
let miner = self.miner.authoring_params().author; let miner = self.miner.authoring_params().author;
if miner == 0.into() { if miner == 0.into() {
(self.accounts)() (self.accounts)()
@ -539,7 +538,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
.map(From::from) .map(From::from)
.ok_or_else(|| errors::account("No accounts were found", "")) .ok_or_else(|| errors::account("No accounts were found", ""))
} else { } else {
Ok(RpcH160::from(miner)) Ok(H160::from(miner))
} }
} }
@ -547,32 +546,30 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Ok(self.miner.is_currently_sealing()) Ok(self.miner.is_currently_sealing())
} }
fn chain_id(&self) -> Result<Option<RpcU64>> { fn chain_id(&self) -> Result<Option<U64>> {
Ok(self.client.signing_chain_id().map(RpcU64::from)) Ok(self.client.signing_chain_id().map(U64::from))
} }
fn hashrate(&self) -> Result<RpcU256> { fn hashrate(&self) -> Result<U256> {
Ok(RpcU256::from(self.external_miner.hashrate())) Ok(U256::from(self.external_miner.hashrate()))
} }
fn gas_price(&self) -> Result<RpcU256> { fn gas_price(&self) -> BoxFuture<U256> {
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile))) Box::new(future::ok(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)))
} }
fn accounts(&self) -> Result<Vec<RpcH160>> { fn accounts(&self) -> Result<Vec<H160>> {
self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS);
let accounts = (self.accounts)(); let accounts = (self.accounts)();
Ok(accounts.into_iter().map(Into::into).collect()) Ok(accounts.into_iter().map(Into::into).collect())
} }
fn block_number(&self) -> Result<RpcU256> { fn block_number(&self) -> Result<U256> {
Ok(RpcU256::from(self.client.chain_info().best_block_number)) Ok(U256::from(self.client.chain_info().best_block_number))
} }
fn balance(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> { fn balance(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
let address = address.into();
let num = num.unwrap_or_default(); let num = num.unwrap_or_default();
try_bf!(check_known(&*self.client, num.clone())); try_bf!(check_known(&*self.client, num.clone()));
@ -584,11 +581,10 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(res)) Box::new(future::done(res))
} }
fn proof(&self, address: RpcH160, values: Vec<RpcH256>, num: Option<BlockNumber>) -> BoxFuture<EthAccount> { fn proof(&self, address: H160, values: Vec<H256>, num: Option<BlockNumber>) -> BoxFuture<EthAccount> {
try_bf!(errors::require_experimental(self.options.allow_experimental_rpcs, "1186")); try_bf!(errors::require_experimental(self.options.allow_experimental_rpcs, "1186"));
let a: H160 = address.clone().into(); let key1 = keccak(address);
let key1 = keccak(a);
let num = num.unwrap_or_default(); let num = num.unwrap_or_default();
let id = match num { let id = match num {
@ -603,7 +599,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
try_bf!(check_known(&*self.client, num.clone())); try_bf!(check_known(&*self.client, num.clone()));
let res = match self.client.prove_account(key1, id) { let res = match self.client.prove_account(key1, id) {
Some((proof,account)) => Ok(EthAccount { Some((proof, account)) => Ok(EthAccount {
address: address, address: address,
balance: account.balance.into(), balance: account.balance.into(),
nonce: account.nonce.into(), nonce: account.nonce.into(),
@ -627,10 +623,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(res)) Box::new(future::done(res))
} }
fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Option<BlockNumber>) -> BoxFuture<RpcH256> { fn storage_at(&self, address: H160, position: U256, num: Option<BlockNumber>) -> BoxFuture<H256> {
let address: Address = RpcH160::into(address); let address: Address = address.into();
let position: U256 = RpcU256::into(pos);
let num = num.unwrap_or_default(); let num = num.unwrap_or_default();
try_bf!(check_known(&*self.client, num.clone())); try_bf!(check_known(&*self.client, num.clone()));
@ -642,8 +636,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(res)) Box::new(future::done(res))
} }
fn transaction_count(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> { fn transaction_count(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
let address: Address = RpcH160::into(address); let address: Address = address.into();
let res = match num.unwrap_or_default() { let res = match num.unwrap_or_default() {
BlockNumber::Pending if self.options.pending_nonce_from_queue => { BlockNumber::Pending if self.options.pending_nonce_from_queue => {
@ -676,7 +670,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(res)) Box::new(future::done(res))
} }
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>> { fn block_transaction_count_by_hash(&self, hash: H256) -> BoxFuture<Option<U256>> {
let trx_count = self.client.block(BlockId::Hash(hash.into())) let trx_count = self.client.block(BlockId::Hash(hash.into()))
.map(|block| block.transactions_count().into()); .map(|block| block.transactions_count().into());
let result = Ok(trx_count) let result = Ok(trx_count)
@ -684,7 +678,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(result)) Box::new(future::done(result))
} }
fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>> { fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<U256>> {
Box::new(future::done(match num { Box::new(future::done(match num {
BlockNumber::Pending => BlockNumber::Pending =>
Ok(Some(self.miner.pending_transaction_hashes(&*self.client).len().into())), Ok(Some(self.miner.pending_transaction_hashes(&*self.client).len().into())),
@ -701,7 +695,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
})) }))
} }
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>> { fn block_uncles_count_by_hash(&self, hash: H256) -> BoxFuture<Option<U256>> {
let uncle_count = self.client.block(BlockId::Hash(hash.into())) let uncle_count = self.client.block(BlockId::Hash(hash.into()))
.map(|block| block.uncles_count().into()); .map(|block| block.uncles_count().into());
let result = Ok(uncle_count) let result = Ok(uncle_count)
@ -709,7 +703,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(result)) Box::new(future::done(result))
} }
fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>> { fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<U256>> {
Box::new(future::done(match num { Box::new(future::done(match num {
BlockNumber::Pending => Ok(Some(0.into())), BlockNumber::Pending => Ok(Some(0.into())),
_ => { _ => {
@ -725,8 +719,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
})) }))
} }
fn code_at(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<Bytes> { fn code_at(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<Bytes> {
let address: Address = RpcH160::into(address); let address: Address = H160::into(address);
let num = num.unwrap_or_default(); let num = num.unwrap_or_default();
try_bf!(check_known(&*self.client, num.clone())); try_bf!(check_known(&*self.client, num.clone()));
@ -739,7 +733,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(res)) Box::new(future::done(res))
} }
fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> BoxFuture<Option<RichBlock>> { fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture<Option<RichBlock>> {
let result = self.rich_block(BlockId::Hash(hash.into()).into(), include_txs) let result = self.rich_block(BlockId::Hash(hash.into()).into(), include_txs)
.and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks));
Box::new(future::done(result)) Box::new(future::done(result))
@ -751,8 +745,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(result)) Box::new(future::done(result))
} }
fn transaction_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<Transaction>> { fn transaction_by_hash(&self, hash: H256) -> BoxFuture<Option<Transaction>> {
let hash: H256 = hash.into();
let tx = try_bf!(self.transaction(PendingTransactionId::Hash(hash))).or_else(|| { let tx = try_bf!(self.transaction(PendingTransactionId::Hash(hash))).or_else(|| {
self.miner.transaction(&hash) self.miner.transaction(&hash)
.map(|t| Transaction::from_pending(t.pending().clone())) .map(|t| Transaction::from_pending(t.pending().clone()))
@ -762,7 +755,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(result)) Box::new(future::done(result))
} }
fn transaction_by_block_hash_and_index(&self, hash: RpcH256, index: Index) -> BoxFuture<Option<Transaction>> { fn transaction_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture<Option<Transaction>> {
let id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash.into())), index.value()); let id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash.into())), index.value());
let result = self.transaction(id).and_then( let result = self.transaction(id).and_then(
errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); errors::check_block_gap(&*self.client, self.options.allow_missing_blocks));
@ -783,9 +776,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(result)) Box::new(future::done(result))
} }
fn transaction_receipt(&self, hash: RpcH256) -> BoxFuture<Option<Receipt>> { fn transaction_receipt(&self, hash: H256) -> BoxFuture<Option<Receipt>> {
let hash: H256 = hash.into();
if self.options.allow_pending_receipt_query { if self.options.allow_pending_receipt_query {
let best_block = self.client.chain_info().best_block_number; let best_block = self.client.chain_info().best_block_number;
if let Some(receipt) = self.miner.pending_receipt(best_block, &hash) { if let Some(receipt) = self.miner.pending_receipt(best_block, &hash) {
@ -799,7 +790,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(result)) Box::new(future::done(result))
} }
fn uncle_by_block_hash_and_index(&self, hash: RpcH256, index: Index) -> BoxFuture<Option<RichBlock>> { fn uncle_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture<Option<RichBlock>> {
let result = self.uncle(PendingUncleId { let result = self.uncle(PendingUncleId {
id: PendingOrBlock::Block(BlockId::Hash(hash.into())), id: PendingOrBlock::Block(BlockId::Hash(hash.into())),
position: index.value() position: index.value()
@ -889,19 +880,19 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
} }
} }
fn submit_work(&self, nonce: RpcH64, pow_hash: RpcH256, mix_hash: RpcH256) -> Result<bool> { fn submit_work(&self, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result<bool> {
match helpers::submit_work_detail(&self.client, &self.miner, nonce, pow_hash, mix_hash) { match helpers::submit_work_detail(&self.client, &self.miner, nonce, pow_hash, mix_hash) {
Ok(_) => Ok(true), Ok(_) => Ok(true),
Err(_) => Ok(false), Err(_) => Ok(false),
} }
} }
fn submit_hashrate(&self, rate: RpcU256, id: RpcH256) -> Result<bool> { fn submit_hashrate(&self, rate: U256, id: H256) -> Result<bool> {
self.external_miner.submit_hashrate(rate.into(), id.into()); self.external_miner.submit_hashrate(rate.into(), id.into());
Ok(true) Ok(true)
} }
fn send_raw_transaction(&self, raw: Bytes) -> Result<RpcH256> { fn send_raw_transaction(&self, raw: Bytes) -> Result<H256> {
Rlp::new(&raw.into_vec()).as_val() Rlp::new(&raw.into_vec()).as_val()
.map_err(errors::rlp) .map_err(errors::rlp)
.and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction)) .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))
@ -916,7 +907,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
.map(Into::into) .map(Into::into)
} }
fn submit_transaction(&self, raw: Bytes) -> Result<RpcH256> { fn submit_transaction(&self, raw: Bytes) -> Result<H256> {
self.send_raw_transaction(raw) self.send_raw_transaction(raw)
} }
@ -960,7 +951,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
)) ))
} }
fn estimate_gas(&self, request: CallRequest, num: Option<BlockNumber>) -> BoxFuture<RpcU256> { fn estimate_gas(&self, request: CallRequest, num: Option<BlockNumber>) -> BoxFuture<U256> {
let request = CallRequest::into(request); let request = CallRequest::into(request);
let signed = try_bf!(fake_sign::sign_call(request)); let signed = try_bf!(fake_sign::sign_call(request));
let num = num.unwrap_or_default(); let num = num.unwrap_or_default();

View File

@ -21,7 +21,7 @@ use std::collections::{BTreeSet, VecDeque};
use ethcore::client::{BlockChainClient, BlockId}; use ethcore::client::{BlockChainClient, BlockId};
use ethcore::miner::{self, MinerService}; use ethcore::miner::{self, MinerService};
use ethereum_types::H256; use ethereum_types::{H256, U256};
use parking_lot::Mutex; use parking_lot::Mutex;
use types::filter::Filter as EthcoreFilter; use types::filter::Filter as EthcoreFilter;
@ -29,7 +29,7 @@ use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::{future, Future};
use jsonrpc_core::futures::future::Either; use jsonrpc_core::futures::future::Either;
use v1::traits::EthFilter; use v1::traits::EthFilter;
use v1::types::{BlockNumber, Index, Filter, FilterChanges, Log, H256 as RpcH256, U256 as RpcU256}; use v1::types::{BlockNumber, Index, Filter, FilterChanges, Log};
use v1::helpers::{errors, SyncPollFilter, PollFilter, PollManager, limit_logs}; use v1::helpers::{errors, SyncPollFilter, PollFilter, PollManager, limit_logs};
use v1::impls::eth::pending_logs; use v1::impls::eth::pending_logs;
@ -137,7 +137,7 @@ impl<C, M> Filterable for EthFilterClient<C, M> where
} }
impl<T: Filterable + Send + Sync + 'static> EthFilter for T { impl<T: Filterable + Send + Sync + 'static> EthFilter for T {
fn new_filter(&self, filter: Filter) -> Result<RpcU256> { fn new_filter(&self, filter: Filter) -> Result<U256> {
let mut polls = self.polls().lock(); let mut polls = self.polls().lock();
let block_number = self.best_block_number(); let block_number = self.best_block_number();
let include_pending = filter.to_block == Some(BlockNumber::Pending); let include_pending = filter.to_block == Some(BlockNumber::Pending);
@ -150,7 +150,7 @@ impl<T: Filterable + Send + Sync + 'static> EthFilter for T {
Ok(id.into()) Ok(id.into())
} }
fn new_block_filter(&self) -> Result<RpcU256> { fn new_block_filter(&self) -> Result<U256> {
let mut polls = self.polls().lock(); let mut polls = self.polls().lock();
// +1, since we don't want to include the current block // +1, since we don't want to include the current block
let id = polls.create_poll(SyncPollFilter::new(PollFilter::Block { let id = polls.create_poll(SyncPollFilter::new(PollFilter::Block {
@ -160,7 +160,7 @@ impl<T: Filterable + Send + Sync + 'static> EthFilter for T {
Ok(id.into()) Ok(id.into())
} }
fn new_pending_transaction_filter(&self) -> Result<RpcU256> { fn new_pending_transaction_filter(&self) -> Result<U256> {
let mut polls = self.polls().lock(); let mut polls = self.polls().lock();
let pending_transactions = self.pending_transaction_hashes(); let pending_transactions = self.pending_transaction_hashes();
let id = polls.create_poll(SyncPollFilter::new(PollFilter::PendingTransaction(pending_transactions))); let id = polls.create_poll(SyncPollFilter::new(PollFilter::PendingTransaction(pending_transactions)));
@ -191,7 +191,7 @@ impl<T: Filterable + Send + Sync + 'static> EthFilter for T {
match self.block_hash(block_number) { match self.block_hash(block_number) {
Some(hash) => { Some(hash) => {
*last_block_number = n; *last_block_number = n;
hashes.push(RpcH256::from(hash)); hashes.push(H256::from(hash));
// Only keep the most recent history // Only keep the most recent history
if recent_reported_hashes.len() >= PollFilter::MAX_BLOCK_HISTORY_SIZE { if recent_reported_hashes.len() >= PollFilter::MAX_BLOCK_HISTORY_SIZE {
recent_reported_hashes.pop_back(); recent_reported_hashes.pop_back();

View File

@ -28,7 +28,7 @@ use light::client::LightChainClient;
use light::{cht, TransactionQueue}; use light::{cht, TransactionQueue};
use light::on_demand::{request, OnDemand}; use light::on_demand::{request, OnDemand};
use ethereum_types::{U256, Address}; use ethereum_types::{Address, H64, H160, H256, U64, U256};
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP};
use parking_lot::{RwLock, Mutex}; use parking_lot::{RwLock, Mutex};
use rlp::Rlp; use rlp::Rlp;
@ -38,17 +38,13 @@ use types::filter::Filter as EthcoreFilter;
use types::ids::BlockId; use types::ids::BlockId;
use v1::impls::eth_filter::Filterable; use v1::impls::eth_filter::Filterable;
use v1::helpers::{errors, limit_logs}; use v1::helpers::{errors, limit_logs, SyncPollFilter, PollManager};
use v1::helpers::{SyncPollFilter, PollManager};
use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::deprecated::{self, DeprecationNotice};
use v1::helpers::light_fetch::{self, LightFetch}; use v1::helpers::light_fetch::{self, LightFetch};
use v1::traits::Eth; use v1::traits::Eth;
use v1::types::{ use v1::types::{
RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, SyncStatus as RpcSyncStatus,
SyncStatus as RpcSyncStatus, SyncInfo as RpcSyncInfo, SyncInfo as RpcSyncInfo, Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount
Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount,
H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256,
U64 as RpcU64,
}; };
use v1::metadata::Metadata; use v1::metadata::Metadata;
@ -251,7 +247,7 @@ where
} }
} }
fn author(&self) -> Result<RpcH160> { fn author(&self) -> Result<H160> {
(self.accounts)() (self.accounts)()
.first() .first()
.cloned() .cloned()
@ -263,22 +259,19 @@ where
Ok(false) Ok(false)
} }
fn chain_id(&self) -> Result<Option<RpcU64>> { fn chain_id(&self) -> Result<Option<U64>> {
Ok(self.client.signing_chain_id().map(RpcU64::from)) Ok(self.client.signing_chain_id().map(U64::from))
} }
fn hashrate(&self) -> Result<RpcU256> { fn hashrate(&self) -> Result<U256> {
Ok(Default::default()) Ok(Default::default())
} }
fn gas_price(&self) -> Result<RpcU256> { fn gas_price(&self) -> BoxFuture<U256> {
Ok(self.cache.lock().gas_price_corpus() Box::new(self.fetcher().gas_price())
.and_then(|c| c.percentile(self.gas_price_percentile).cloned())
.map(RpcU256::from)
.unwrap_or_else(Default::default))
} }
fn accounts(&self) -> Result<Vec<RpcH160>> { fn accounts(&self) -> Result<Vec<H160>> {
self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS);
Ok((self.accounts)() Ok((self.accounts)()
@ -287,20 +280,20 @@ where
.collect()) .collect())
} }
fn block_number(&self) -> Result<RpcU256> { fn block_number(&self) -> Result<U256> {
Ok(self.client.chain_info().best_block_number.into()) Ok(self.client.chain_info().best_block_number.into())
} }
fn balance(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> { fn balance(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id(), self.transaction_queue.clone())
.map(|acc| acc.map_or(0.into(), |a| a.balance).into())) .map(|acc| acc.map_or(0.into(), |a| a.balance)))
} }
fn storage_at(&self, _address: RpcH160, _key: RpcU256, _num: Option<BlockNumber>) -> BoxFuture<RpcH256> { fn storage_at(&self, _address: H160, _key: U256, _num: Option<BlockNumber>) -> BoxFuture<H256> {
Box::new(future::err(errors::unimplemented(None))) Box::new(future::err(errors::unimplemented(None)))
} }
fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> BoxFuture<Option<RichBlock>> { fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture<Option<RichBlock>> {
Box::new(self.rich_block(BlockId::Hash(hash.into()), include_txs).map(Some)) Box::new(self.rich_block(BlockId::Hash(hash.into()), include_txs).map(Some))
} }
@ -308,12 +301,12 @@ where
Box::new(self.rich_block(num.to_block_id(), include_txs).map(Some)) Box::new(self.rich_block(num.to_block_id(), include_txs).map(Some))
} }
fn transaction_count(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> { fn transaction_count(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id(), self.transaction_queue.clone())
.map(|acc| acc.map_or(0.into(), |a| a.nonce).into())) .map(|acc| acc.map_or(0.into(), |a| a.nonce)))
} }
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>> { fn block_transaction_count_by_hash(&self, hash: H256) -> BoxFuture<Option<U256>> {
let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone());
Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| { Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| {
@ -329,7 +322,7 @@ where
})) }))
} }
fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>> { fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<U256>> {
let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone());
Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| { Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| {
@ -345,7 +338,7 @@ where
})) }))
} }
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>> { fn block_uncles_count_by_hash(&self, hash: H256) -> BoxFuture<Option<U256>> {
let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone());
Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| { Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| {
@ -361,7 +354,7 @@ where
})) }))
} }
fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>> { fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<U256>> {
let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone());
Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| { Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| {
@ -377,11 +370,11 @@ where
})) }))
} }
fn code_at(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<Bytes> { fn code_at(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<Bytes> {
Box::new(self.fetcher().code(address.into(), num.unwrap_or_default().to_block_id()).map(Into::into)) Box::new(self.fetcher().code(address.into(), num.unwrap_or_default().to_block_id()).map(Into::into))
} }
fn send_raw_transaction(&self, raw: Bytes) -> Result<RpcH256> { fn send_raw_transaction(&self, raw: Bytes) -> Result<H256> {
let best_header = self.client.best_block_header().decode().map_err(errors::decode)?; let best_header = self.client.best_block_header().decode().map_err(errors::decode)?;
Rlp::new(&raw.into_vec()).as_val() Rlp::new(&raw.into_vec()).as_val()
@ -400,12 +393,12 @@ where
.map(Into::into) .map(Into::into)
} }
fn submit_transaction(&self, raw: Bytes) -> Result<RpcH256> { fn submit_transaction(&self, raw: Bytes) -> Result<H256> {
self.send_raw_transaction(raw) self.send_raw_transaction(raw)
} }
fn call(&self, req: CallRequest, num: Option<BlockNumber>) -> BoxFuture<Bytes> { fn call(&self, req: CallRequest, num: Option<BlockNumber>) -> BoxFuture<Bytes> {
Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { Box::new(self.fetcher().proved_read_only_execution(req, num, self.transaction_queue.clone()).and_then(|res| {
match res { match res {
Ok(exec) => Ok(exec.output.into()), Ok(exec) => Ok(exec.output.into()),
Err(e) => Err(errors::execution(e)), Err(e) => Err(errors::execution(e)),
@ -413,9 +406,9 @@ where
})) }))
} }
fn estimate_gas(&self, req: CallRequest, num: Option<BlockNumber>) -> BoxFuture<RpcU256> { fn estimate_gas(&self, req: CallRequest, num: Option<BlockNumber>) -> BoxFuture<U256> {
// TODO: binary chop for more accurate estimates. // TODO: binary chop for more accurate estimates.
Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { Box::new(self.fetcher().proved_read_only_execution(req, num, self.transaction_queue.clone()).and_then(|res| {
match res { match res {
Ok(exec) => Ok((exec.refunded + exec.gas_used).into()), Ok(exec) => Ok((exec.refunded + exec.gas_used).into()),
Err(e) => Err(errors::execution(e)), Err(e) => Err(errors::execution(e)),
@ -423,7 +416,7 @@ where
})) }))
} }
fn transaction_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<Transaction>> { fn transaction_by_hash(&self, hash: H256) -> BoxFuture<Option<Transaction>> {
let hash = hash.into(); let hash = hash.into();
{ {
@ -438,7 +431,7 @@ where
Box::new(self.fetcher().transaction_by_hash(hash).map(|x| x.map(|(tx, _)| tx))) Box::new(self.fetcher().transaction_by_hash(hash).map(|x| x.map(|(tx, _)| tx)))
} }
fn transaction_by_block_hash_and_index(&self, hash: RpcH256, idx: Index) -> BoxFuture<Option<Transaction>> { fn transaction_by_block_hash_and_index(&self, hash: H256, idx: Index) -> BoxFuture<Option<Transaction>> {
Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| { Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| {
light_fetch::extract_transaction_at_index(block, idx.value()) light_fetch::extract_transaction_at_index(block, idx.value())
})) }))
@ -450,9 +443,9 @@ where
})) }))
} }
fn transaction_receipt(&self, hash: RpcH256) -> BoxFuture<Option<Receipt>> { fn transaction_receipt(&self, hash: H256) -> BoxFuture<Option<Receipt>> {
let fetcher = self.fetcher(); let fetcher = self.fetcher();
Box::new(fetcher.transaction_by_hash(hash.clone().into()).and_then(move |tx| { Box::new(fetcher.transaction_by_hash(hash.into()).and_then(move |tx| {
// the block hash included in the transaction object here has // the block hash included in the transaction object here has
// already been checked for canonicality and whether it contains // already been checked for canonicality and whether it contains
// the transaction. // the transaction.
@ -480,7 +473,7 @@ where
})) }))
} }
fn uncle_by_block_hash_and_index(&self, hash: RpcH256, idx: Index) -> BoxFuture<Option<RichBlock>> { fn uncle_by_block_hash_and_index(&self, hash: H256, idx: Index) -> BoxFuture<Option<RichBlock>> {
let client = self.client.clone(); let client = self.client.clone();
Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| { Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| {
extract_uncle_at_index(block, idx, client) extract_uncle_at_index(block, idx, client)
@ -494,7 +487,7 @@ where
})) }))
} }
fn proof(&self, _address: RpcH160, _values:Vec<RpcH256>, _num: Option<BlockNumber>) -> BoxFuture<EthAccount> { fn proof(&self, _address: H160, _values:Vec<H256>, _num: Option<BlockNumber>) -> BoxFuture<EthAccount> {
Box::new(future::err(errors::unimplemented(None))) Box::new(future::err(errors::unimplemented(None)))
} }
@ -528,11 +521,11 @@ where
Err(errors::light_unimplemented(None)) Err(errors::light_unimplemented(None))
} }
fn submit_work(&self, _nonce: RpcH64, _pow_hash: RpcH256, _mix_hash: RpcH256) -> Result<bool> { fn submit_work(&self, _nonce: H64, _pow_hash: H256, _mix_hash: H256) -> Result<bool> {
Err(errors::light_unimplemented(None)) Err(errors::light_unimplemented(None))
} }
fn submit_hashrate(&self, _rate: RpcU256, _id: RpcH256) -> Result<bool> { fn submit_hashrate(&self, _rate: U256, _id: H256) -> Result<bool> {
Err(errors::light_unimplemented(None)) Err(errors::light_unimplemented(None))
} }
} }
@ -545,11 +538,11 @@ where
{ {
fn best_block_number(&self) -> u64 { self.client.chain_info().best_block_number } fn best_block_number(&self) -> u64 { self.client.chain_info().best_block_number }
fn block_hash(&self, id: BlockId) -> Option<::ethereum_types::H256> { fn block_hash(&self, id: BlockId) -> Option<H256> {
self.client.block_hash(id) self.client.block_hash(id)
} }
fn pending_transaction_hashes(&self) -> BTreeSet<::ethereum_types::H256> { fn pending_transaction_hashes(&self) -> BTreeSet<H256> {
BTreeSet::new() BTreeSet::new()
} }

View File

@ -25,6 +25,7 @@ use ethkey::{crypto::ecies, Brain, Generator};
use ethstore::random_phrase; use ethstore::random_phrase;
use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork};
use updater::VersionInfo as UpdaterVersionInfo; use updater::VersionInfo as UpdaterVersionInfo;
use ethereum_types::{H64, H160, H256, H512, U64, U256};
use ethcore_logger::RotatingLogger; use ethcore_logger::RotatingLogger;
use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::{Result, BoxFuture};
@ -36,7 +37,7 @@ use v1::helpers::light_fetch::{LightFetch, light_all_transactions};
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::traits::Parity; use v1::traits::Parity;
use v1::types::{ use v1::types::{
Bytes, U256, U64, H64, H160, H256, H512, CallRequest, Bytes, CallRequest,
Peers, Transaction, RpcSettings, Histogram, Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus, TransactionStats, LocalTransactionStatus,
LightBlockNumber, ChainStatus, Receipt, LightBlockNumber, ChainStatus, Receipt,

View File

@ -20,16 +20,17 @@
use std::io; use std::io;
use std::sync::Arc; use std::sync::Arc;
use sync::ManageNetwork; use ethereum_types::{H160, H256, U256};
use fetch::{self, Fetch}; use fetch::{self, Fetch};
use hash::keccak_buffer; use hash::keccak_buffer;
use light::client::LightChainClient; use light::client::LightChainClient;
use sync::ManageNetwork;
use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::{Result, BoxFuture};
use jsonrpc_core::futures::Future; use jsonrpc_core::futures::Future;
use v1::helpers::errors; use v1::helpers::errors;
use v1::traits::ParitySet; use v1::traits::ParitySet;
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; use v1::types::{Bytes, ReleaseInfo, Transaction};
/// Parity-specific rpc interface for operations altering the settings. /// Parity-specific rpc interface for operations altering the settings.
pub struct ParitySetClient<F> { pub struct ParitySetClient<F> {

View File

@ -16,11 +16,13 @@
//! Traces api implementation. //! Traces api implementation.
use ethereum_types::H256;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use v1::Metadata; use v1::Metadata;
use v1::traits::Traces; use v1::traits::Traces;
use v1::helpers::errors; use v1::helpers::errors;
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceResultsWithTransactionHash, TraceOptions, H256}; use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults,
TraceResultsWithTransactionHash, TraceOptions};
/// Traces api implementation. /// Traces api implementation.
// TODO: all calling APIs should be possible w. proved remote TX execution. // TODO: all calling APIs should be possible w. proved remote TX execution.

View File

@ -20,12 +20,12 @@ use std::str::FromStr;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use crypto::DEFAULT_MAC; use crypto::DEFAULT_MAC;
use ethereum_types::{Address, H64, H160, H256, H512, U64, U256};
use ethcore::client::{BlockChainClient, StateClient, Call}; use ethcore::client::{BlockChainClient, StateClient, Call};
use ethcore::miner::{self, MinerService}; use ethcore::miner::{self, MinerService};
use ethcore::snapshot::{SnapshotService, RestorationStatus}; use ethcore::snapshot::{SnapshotService, RestorationStatus};
use ethcore::state::StateInfo; use ethcore::state::StateInfo;
use ethcore_logger::RotatingLogger; use ethcore_logger::RotatingLogger;
use ethereum_types::Address;
use ethkey::{crypto::ecies, Brain, Generator}; use ethkey::{crypto::ecies, Brain, Generator};
use ethstore::random_phrase; use ethstore::random_phrase;
use jsonrpc_core::futures::future; use jsonrpc_core::futures::future;
@ -41,7 +41,7 @@ use v1::helpers::external_signer::{SigningQueue, SignerService};
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::traits::Parity; use v1::traits::Parity;
use v1::types::{ use v1::types::{
Bytes, U256, H64, U64, H160, H256, H512, CallRequest, Bytes, CallRequest,
Peers, Transaction, RpcSettings, Histogram, Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus, TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo, BlockNumber, ConsensusCapability, VersionInfo,

View File

@ -20,8 +20,8 @@ use std::collections::{
btree_map::{BTreeMap, Entry}, btree_map::{BTreeMap, Entry},
HashSet, HashSet,
}; };
use ethereum_types::Address;
use ethereum_types::{Address, H160, H256, H520};
use ethkey::{Brain, Generator, Secret}; use ethkey::{Brain, Generator, Secret};
use ethstore::KeyFile; use ethstore::KeyFile;
use accounts::AccountProvider; use accounts::AccountProvider;
@ -29,10 +29,7 @@ use jsonrpc_core::Result;
use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::deprecated::{self, DeprecationNotice};
use v1::helpers::errors; use v1::helpers::errors;
use v1::traits::{ParityAccounts, ParityAccountsInfo}; use v1::traits::{ParityAccounts, ParityAccountsInfo};
use v1::types::{ use v1::types::{Derive, DeriveHierarchical, DeriveHash,ExtAccountInfo, AccountInfo, HwAccountInfo};
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Derive, DeriveHierarchical, DeriveHash,
ExtAccountInfo, AccountInfo, HwAccountInfo,
};
use ethkey::Password; use ethkey::Password;
/// Account management (personal) rpc implementation. /// Account management (personal) rpc implementation.
@ -58,7 +55,7 @@ impl ParityAccountsClient {
} }
impl ParityAccountsInfo for ParityAccountsClient { impl ParityAccountsInfo for ParityAccountsClient {
fn accounts_info(&self) -> Result<BTreeMap<RpcH160, AccountInfo>> { fn accounts_info(&self) -> Result<BTreeMap<H160, AccountInfo>> {
self.deprecation_notice("parity_accountsInfo"); self.deprecation_notice("parity_accountsInfo");
let dapp_accounts = self.accounts.accounts() let dapp_accounts = self.accounts.accounts()
@ -72,18 +69,18 @@ impl ParityAccountsInfo for ParityAccountsClient {
.into_iter() .into_iter()
.chain(other.into_iter()) .chain(other.into_iter())
.filter(|&(ref a, _)| dapp_accounts.contains(a)) .filter(|&(ref a, _)| dapp_accounts.contains(a))
.map(|(a, v)| (RpcH160::from(a), AccountInfo { name: v.name })) .map(|(a, v)| (H160::from(a), AccountInfo { name: v.name }))
.collect() .collect()
) )
} }
fn hardware_accounts_info(&self) -> Result<BTreeMap<RpcH160, HwAccountInfo>> { fn hardware_accounts_info(&self) -> Result<BTreeMap<H160, HwAccountInfo>> {
self.deprecation_notice("parity_hardwareAccountsInfo"); self.deprecation_notice("parity_hardwareAccountsInfo");
let info = self.accounts.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; let info = self.accounts.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
Ok(info Ok(info
.into_iter() .into_iter()
.map(|(a, v)| (RpcH160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta })) .map(|(a, v)| (H160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta }))
.collect() .collect()
) )
} }
@ -94,7 +91,7 @@ impl ParityAccountsInfo for ParityAccountsClient {
self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e)) self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))
} }
fn default_account(&self) -> Result<RpcH160> { fn default_account(&self) -> Result<H160> {
self.deprecation_notice("parity_defaultAccount"); self.deprecation_notice("parity_defaultAccount");
Ok(self.accounts.default_account() Ok(self.accounts.default_account()
@ -105,9 +102,7 @@ impl ParityAccountsInfo for ParityAccountsClient {
} }
impl ParityAccounts for ParityAccountsClient { impl ParityAccounts for ParityAccountsClient {
fn all_accounts_info(&self) -> Result<BTreeMap<RpcH160, ExtAccountInfo>> { fn all_accounts_info(&self) -> Result<BTreeMap<H160, ExtAccountInfo>> {
self.deprecation_notice("parity_allAccountsInfo");
let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
let other = self.accounts.addresses_info(); let other = self.accounts.addresses_info();
@ -120,7 +115,7 @@ impl ParityAccounts for ParityAccountsClient {
uuid: v.uuid.map(|uuid| uuid.to_string()) uuid: v.uuid.map(|uuid| uuid.to_string())
})); }));
let mut accounts: BTreeMap<RpcH160, ExtAccountInfo> = BTreeMap::new(); let mut accounts: BTreeMap<H160, ExtAccountInfo> = BTreeMap::new();
for (address, account) in account_iter { for (address, account) in account_iter {
match accounts.entry(address) { match accounts.entry(address) {
@ -138,27 +133,24 @@ impl ParityAccounts for ParityAccountsClient {
Ok(accounts) Ok(accounts)
} }
fn new_account_from_phrase(&self, phrase: String, pass: Password) -> Result<RpcH160> { fn new_account_from_phrase(&self, phrase: String, pass: Password) -> Result<H160> {
self.deprecation_notice("parity_newAccountFromPhrase"); self.deprecation_notice("parity_newAccountFromPhrase");
let brain = Brain::new(phrase).generate().unwrap(); let brain = Brain::new(phrase).generate().unwrap();
self.accounts.insert_account(brain.secret().clone(), &pass) self.accounts.insert_account(brain.secret().clone(), &pass)
.map(Into::into) .map(Into::into)
.map_err(|e| errors::account("Could not create account.", e)) .map_err(|e| errors::account("Could not create account.", e))
} }
fn new_account_from_wallet(&self, json: String, pass: Password) -> Result<RpcH160> { fn new_account_from_wallet(&self, json: String, pass: Password) -> Result<H160> {
self.deprecation_notice("parity_newAccountFromWallet"); self.deprecation_notice("parity_newAccountFromWallet");
self.accounts.import_presale(json.as_bytes(), &pass) self.accounts.import_presale(json.as_bytes(), &pass)
.or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true)) .or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true))
.map(Into::into) .map(Into::into)
.map_err(|e| errors::account("Could not create account.", e)) .map_err(|e| errors::account("Could not create account.", e))
} }
fn new_account_from_secret(&self, secret: RpcH256, pass: Password) -> Result<RpcH160> { fn new_account_from_secret(&self, secret: H256, pass: Password) -> Result<H160> {
self.deprecation_notice("parity_newAccountFromSecret"); self.deprecation_notice("parity_newAccountFromSecret");
let secret = Secret::from_unsafe_slice(&secret.0) let secret = Secret::from_unsafe_slice(&secret.0)
.map_err(|e| errors::account("Could not create account.", e))?; .map_err(|e| errors::account("Could not create account.", e))?;
self.accounts.insert_account(secret, &pass) self.accounts.insert_account(secret, &pass)
@ -166,9 +158,8 @@ impl ParityAccounts for ParityAccountsClient {
.map_err(|e| errors::account("Could not create account.", e)) .map_err(|e| errors::account("Could not create account.", e))
} }
fn test_password(&self, account: RpcH160, password: Password) -> Result<bool> { fn test_password(&self, account: H160, password: Password) -> Result<bool> {
self.deprecation_notice("parity_testPassword"); self.deprecation_notice("parity_testPassword");
let account: Address = account.into(); let account: Address = account.into();
self.accounts self.accounts
@ -176,9 +167,8 @@ impl ParityAccounts for ParityAccountsClient {
.map_err(|e| errors::account("Could not fetch account info.", e)) .map_err(|e| errors::account("Could not fetch account info.", e))
} }
fn change_password(&self, account: RpcH160, password: Password, new_password: Password) -> Result<bool> { fn change_password(&self, account: H160, password: Password, new_password: Password) -> Result<bool> {
self.deprecation_notice("parity_changePassword"); self.deprecation_notice("parity_changePassword");
let account: Address = account.into(); let account: Address = account.into();
self.accounts self.accounts
.change_password(&account, password, new_password) .change_password(&account, password, new_password)
@ -186,9 +176,8 @@ impl ParityAccounts for ParityAccountsClient {
.map_err(|e| errors::account("Could not fetch account info.", e)) .map_err(|e| errors::account("Could not fetch account info.", e))
} }
fn kill_account(&self, account: RpcH160, password: Password) -> Result<bool> { fn kill_account(&self, account: H160, password: Password) -> Result<bool> {
self.deprecation_notice("parity_killAccount"); self.deprecation_notice("parity_killAccount");
let account: Address = account.into(); let account: Address = account.into();
self.accounts self.accounts
.kill_account(&account, &password) .kill_account(&account, &password)
@ -196,18 +185,16 @@ impl ParityAccounts for ParityAccountsClient {
.map_err(|e| errors::account("Could not delete account.", e)) .map_err(|e| errors::account("Could not delete account.", e))
} }
fn remove_address(&self, addr: RpcH160) -> Result<bool> { fn remove_address(&self, addr: H160) -> Result<bool> {
self.deprecation_notice("parity_removeAddresss"); self.deprecation_notice("parity_removeAddresss");
let addr: Address = addr.into(); let addr: Address = addr.into();
self.accounts.remove_address(addr); self.accounts.remove_address(addr);
Ok(true) Ok(true)
} }
fn set_account_name(&self, addr: RpcH160, name: String) -> Result<bool> { fn set_account_name(&self, addr: H160, name: String) -> Result<bool> {
self.deprecation_notice("parity_setAccountName"); self.deprecation_notice("parity_setAccountName");
let addr: Address = addr.into(); let addr: Address = addr.into();
self.accounts.set_account_name(addr.clone(), name.clone()) self.accounts.set_account_name(addr.clone(), name.clone())
@ -215,9 +202,8 @@ impl ParityAccounts for ParityAccountsClient {
Ok(true) Ok(true)
} }
fn set_account_meta(&self, addr: RpcH160, meta: String) -> Result<bool> { fn set_account_meta(&self, addr: H160, meta: String) -> Result<bool> {
self.deprecation_notice("parity_setAccountMeta"); self.deprecation_notice("parity_setAccountMeta");
let addr: Address = addr.into(); let addr: Address = addr.into();
self.accounts.set_account_meta(addr.clone(), meta.clone()) self.accounts.set_account_meta(addr.clone(), meta.clone())
@ -225,18 +211,16 @@ impl ParityAccounts for ParityAccountsClient {
Ok(true) Ok(true)
} }
fn import_geth_accounts(&self, addresses: Vec<RpcH160>) -> Result<Vec<RpcH160>> { fn import_geth_accounts(&self, addresses: Vec<H160>) -> Result<Vec<H160>> {
self.deprecation_notice("parity_importGethAccounts"); self.deprecation_notice("parity_importGethAccounts");
self.accounts self.accounts
.import_geth_accounts(into_vec(addresses), false) .import_geth_accounts(into_vec(addresses), false)
.map(into_vec) .map(into_vec)
.map_err(|e| errors::account("Couldn't import Geth accounts", e)) .map_err(|e| errors::account("Couldn't import Geth accounts", e))
} }
fn geth_accounts(&self) -> Result<Vec<RpcH160>> { fn geth_accounts(&self) -> Result<Vec<H160>> {
self.deprecation_notice("parity_listGethAccounts"); self.deprecation_notice("parity_listGethAccounts");
Ok(into_vec(self.accounts.list_geth_accounts(false))) Ok(into_vec(self.accounts.list_geth_accounts(false)))
} }
@ -292,9 +276,8 @@ impl ParityAccounts for ParityAccountsClient {
.map(|_| true) .map(|_| true)
} }
fn change_vault(&self, address: RpcH160, new_vault: String) -> Result<bool> { fn change_vault(&self, address: H160, new_vault: String) -> Result<bool> {
self.deprecation_notice("parity_changeVault"); self.deprecation_notice("parity_changeVault");
self.accounts self.accounts
.change_vault(address.into(), &new_vault) .change_vault(address.into(), &new_vault)
.map_err(|e| errors::account("Could not change vault.", e)) .map_err(|e| errors::account("Could not change vault.", e))
@ -318,9 +301,8 @@ impl ParityAccounts for ParityAccountsClient {
.map(|_| true) .map(|_| true)
} }
fn derive_key_index(&self, addr: RpcH160, password: Password, derivation: DeriveHierarchical, save_as_account: bool) -> Result<RpcH160> { fn derive_key_index(&self, addr: H160, password: Password, derivation: DeriveHierarchical, save_as_account: bool) -> Result<H160> {
self.deprecation_notice("parity_deriveAddressIndex"); self.deprecation_notice("parity_deriveAddressIndex");
let addr: Address = addr.into(); let addr: Address = addr.into();
self.accounts self.accounts
.derive_account( .derive_account(
@ -333,9 +315,8 @@ impl ParityAccounts for ParityAccountsClient {
.map_err(|e| errors::account("Could not derive account.", e)) .map_err(|e| errors::account("Could not derive account.", e))
} }
fn derive_key_hash(&self, addr: RpcH160, password: Password, derivation: DeriveHash, save_as_account: bool) -> Result<RpcH160> { fn derive_key_hash(&self, addr: H160, password: Password, derivation: DeriveHash, save_as_account: bool) -> Result<H160> {
self.deprecation_notice("parity_deriveAddressHash"); self.deprecation_notice("parity_deriveAddressHash");
let addr: Address = addr.into(); let addr: Address = addr.into();
self.accounts self.accounts
.derive_account( .derive_account(
@ -348,9 +329,8 @@ impl ParityAccounts for ParityAccountsClient {
.map_err(|e| errors::account("Could not derive account.", e)) .map_err(|e| errors::account("Could not derive account.", e))
} }
fn export_account(&self, addr: RpcH160, password: Password) -> Result<KeyFile> { fn export_account(&self, addr: H160, password: Password) -> Result<KeyFile> {
self.deprecation_notice("parity_exportAccount"); self.deprecation_notice("parity_exportAccount");
let addr = addr.into(); let addr = addr.into();
self.accounts self.accounts
.export_account( .export_account(
@ -361,9 +341,8 @@ impl ParityAccounts for ParityAccountsClient {
.map_err(|e| errors::account("Could not export account.", e)) .map_err(|e| errors::account("Could not export account.", e))
} }
fn sign_message(&self, addr: RpcH160, password: Password, message: RpcH256) -> Result<RpcH520> { fn sign_message(&self, addr: H160, password: Password, message: H256) -> Result<H520> {
self.deprecation_notice("parity_signMessage"); self.deprecation_notice("parity_signMessage");
self.accounts self.accounts
.sign( .sign(
addr.into(), addr.into(),

View File

@ -21,7 +21,7 @@ use std::time::Duration;
use ethcore::client::{BlockChainClient, Mode}; use ethcore::client::{BlockChainClient, Mode};
use ethcore::miner::{self, MinerService}; use ethcore::miner::{self, MinerService};
use ethereum_types::H256 as EthH256; use ethereum_types::{H160, H256, U256};
use ethkey; use ethkey;
use fetch::{self, Fetch}; use fetch::{self, Fetch};
use hash::keccak_buffer; use hash::keccak_buffer;
@ -32,7 +32,7 @@ use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::Future; use jsonrpc_core::futures::Future;
use v1::helpers::errors; use v1::helpers::errors;
use v1::traits::ParitySet; use v1::traits::ParitySet;
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; use v1::types::{Bytes, ReleaseInfo, Transaction};
#[cfg(any(test, feature = "accounts"))] #[cfg(any(test, feature = "accounts"))]
pub mod accounts { pub mod accounts {
@ -160,7 +160,6 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
} }
fn set_engine_signer_secret(&self, secret: H256) -> Result<bool> { fn set_engine_signer_secret(&self, secret: H256) -> Result<bool> {
let secret: EthH256 = secret.into();
let keypair = ethkey::KeyPair::from_secret(secret.into()).map_err(|e| errors::account("Invalid secret", e))?; let keypair = ethkey::KeyPair::from_secret(secret.into()).map_err(|e| errors::account("Invalid secret", e))?;
self.miner.set_author(miner::Author::Sealer(ethcore::engines::signer::from_keypair(keypair))); self.miner.set_author(miner::Author::Sealer(ethcore::engines::signer::from_keypair(keypair)));
Ok(true) Ok(true)

View File

@ -21,7 +21,7 @@ use std::time::Duration;
use accounts::AccountProvider; use accounts::AccountProvider;
use bytes::Bytes; use bytes::Bytes;
use eip_712::{EIP712, hash_structured_data}; use eip_712::{EIP712, hash_structured_data};
use ethereum_types::{H520, U128, Address}; use ethereum_types::{H160, H256, H520, U128, Address};
use ethkey::{public_to_address, recover, Signature}; use ethkey::{public_to_address, recover, Signature};
use types::transaction::{PendingTransaction, SignedTransaction}; use types::transaction::{PendingTransaction, SignedTransaction};
@ -34,7 +34,6 @@ use v1::helpers::{errors, eip191};
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::traits::Personal; use v1::traits::Personal;
use v1::types::{ use v1::types::{
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128,
Bytes as RpcBytes, Bytes as RpcBytes,
ConfirmationPayload as RpcConfirmationPayload, ConfirmationPayload as RpcConfirmationPayload,
ConfirmationResponse as RpcConfirmationResponse, ConfirmationResponse as RpcConfirmationResponse,
@ -108,24 +107,21 @@ impl<D: Dispatcher + 'static> PersonalClient<D> {
impl<D: Dispatcher + 'static> Personal for PersonalClient<D> { impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
type Metadata = Metadata; type Metadata = Metadata;
fn accounts(&self) -> Result<Vec<RpcH160>> { fn accounts(&self) -> Result<Vec<H160>> {
self.deprecation_notice.print("personal_accounts", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("personal_accounts", deprecated::msgs::ACCOUNTS);
let accounts = self.accounts.accounts().map_err(|e| errors::account("Could not fetch accounts.", e))?; let accounts = self.accounts.accounts().map_err(|e| errors::account("Could not fetch accounts.", e))?;
Ok(accounts.into_iter().map(Into::into).collect::<Vec<RpcH160>>()) Ok(accounts.into_iter().map(Into::into).collect::<Vec<H160>>())
} }
fn new_account(&self, pass: String) -> Result<RpcH160> { fn new_account(&self, pass: String) -> Result<H160> {
self.deprecation_notice.print("personal_newAccount", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("personal_newAccount", deprecated::msgs::ACCOUNTS);
self.accounts.new_account(&pass.into()) self.accounts.new_account(&pass.into())
.map(Into::into) .map(Into::into)
.map_err(|e| errors::account("Could not create account.", e)) .map_err(|e| errors::account("Could not create account.", e))
} }
fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option<RpcU128>) -> Result<bool> { fn unlock_account(&self, account: H160, account_pass: String, duration: Option<U128>) -> Result<bool> {
self.deprecation_notice.print("personal_unlockAccount", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("personal_unlockAccount", deprecated::msgs::ACCOUNTS);
let account: Address = account.into(); let account: Address = account.into();
let store = self.accounts.clone(); let store = self.accounts.clone();
let duration = match duration { let duration = match duration {
@ -157,9 +153,8 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
} }
} }
fn sign(&self, data: RpcBytes, account: RpcH160, password: String) -> BoxFuture<RpcH520> { fn sign(&self, data: RpcBytes, account: H160, password: String) -> BoxFuture<H520> {
self.deprecation_notice.print("personal_sign", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("personal_sign", deprecated::msgs::ACCOUNTS);
let dispatcher = self.dispatcher.clone(); let dispatcher = self.dispatcher.clone();
let accounts = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _; let accounts = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _;
@ -177,9 +172,8 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
})) }))
} }
fn sign_191(&self, version: EIP191Version, data: Value, account: RpcH160, password: String) -> BoxFuture<RpcH520> { fn sign_191(&self, version: EIP191Version, data: Value, account: H160, password: String) -> BoxFuture<H520> {
self.deprecation_notice.print("personal_sign191", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("personal_sign191", deprecated::msgs::ACCOUNTS);
try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "191")); try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "191"));
let data = try_bf!(eip191::hash_message(version, data)); let data = try_bf!(eip191::hash_message(version, data));
@ -201,9 +195,8 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
) )
} }
fn sign_typed_data(&self, typed_data: EIP712, account: RpcH160, password: String) -> BoxFuture<RpcH520> { fn sign_typed_data(&self, typed_data: EIP712, account: H160, password: String) -> BoxFuture<H520> {
self.deprecation_notice.print("personal_signTypedData", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("personal_signTypedData", deprecated::msgs::ACCOUNTS);
try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "712")); try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "712"));
let data = match hash_structured_data(typed_data) { let data = match hash_structured_data(typed_data) {
@ -228,7 +221,7 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
) )
} }
fn ec_recover(&self, data: RpcBytes, signature: RpcH520) -> BoxFuture<RpcH160> { fn ec_recover(&self, data: RpcBytes, signature: H520) -> BoxFuture<H160> {
let signature: H520 = signature.into(); let signature: H520 = signature.into();
let signature = Signature::from_electrum(&signature); let signature = Signature::from_electrum(&signature);
let data: Bytes = data.into(); let data: Bytes = data.into();
@ -253,28 +246,25 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
.map(move |pending_tx| dispatcher.enrich(pending_tx.transaction))) .map(move |pending_tx| dispatcher.enrich(pending_tx.transaction)))
} }
fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<RpcH256> { fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<H256> {
self.deprecation_notice.print("personal_sendTransaction", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("personal_sendTransaction", deprecated::msgs::ACCOUNTS);
let condition = request.condition.clone().map(Into::into); let condition = request.condition.clone().map(Into::into);
let dispatcher = self.dispatcher.clone(); let dispatcher = self.dispatcher.clone();
Box::new( Box::new(
self.do_sign_transaction(meta, request, password, move |signed: WithToken<SignedTransaction>| { self.do_sign_transaction(meta, request, password, move |signed: WithToken<SignedTransaction>| {
dispatcher.dispatch_transaction( dispatcher.dispatch_transaction(
PendingTransaction::new( PendingTransaction::new(
signed.into_value(), signed.into_value(),
condition condition
) )
) )
}).and_then(|hash| {
Ok(RpcH256::from(hash))
}) })
) )
} }
fn sign_and_send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<RpcH256> { fn sign_and_send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<H256> {
self.deprecation_notice.print("personal_signAndSendTransaction", Some("use personal_sendTransaction instead.")); self.deprecation_notice.print("personal_signAndSendTransaction", Some("use personal_sendTransaction instead."));
warn!("Using deprecated personal_signAndSendTransaction, use personal_sendTransaction instead.");
self.send_transaction(meta, request, password) self.send_transaction(meta, request, password)
} }
} }

View File

@ -21,11 +21,11 @@ use std::sync::Arc;
use rlp::Rlp; use rlp::Rlp;
use ethcore_private_tx::Provider as PrivateTransactionManager; use ethcore_private_tx::Provider as PrivateTransactionManager;
use ethereum_types::Address; use ethereum_types::{Address, H160, H256, U256};
use types::transaction::SignedTransaction; use types::transaction::SignedTransaction;
use jsonrpc_core::{Error}; use jsonrpc_core::{Error};
use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, TransactionRequest, U256, use v1::types::{Bytes, PrivateTransactionReceipt, TransactionRequest,
BlockNumber, PrivateTransactionReceiptAndTransaction, CallRequest, block_number_to_id}; BlockNumber, PrivateTransactionReceiptAndTransaction, CallRequest, block_number_to_id};
use v1::traits::Private; use v1::traits::Private;
use v1::metadata::Metadata; use v1::metadata::Metadata;

View File

@ -19,16 +19,17 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::sync::Arc; use std::sync::Arc;
use crypto::DEFAULT_MAC;
use ethkey::Secret;
use accounts::AccountProvider; use accounts::AccountProvider;
use crypto::DEFAULT_MAC;
use ethereum_types::{H160, H256, H512};
use ethkey::Secret;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use v1::helpers::errors; use v1::helpers::errors;
use v1::helpers::secretstore::{generate_document_key, encrypt_document, use v1::helpers::secretstore::{generate_document_key, encrypt_document,
decrypt_document, decrypt_document_with_shadow, ordered_servers_keccak}; decrypt_document, decrypt_document_with_shadow, ordered_servers_keccak};
use v1::traits::SecretStore; use v1::traits::SecretStore;
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey}; use v1::types::{Bytes, EncryptedDocumentKey};
use ethkey::Password; use ethkey::Password;
/// Parity implementation. /// Parity implementation.

View File

@ -18,6 +18,7 @@
use std::sync::Arc; use std::sync::Arc;
use ethereum_types::U256;
use ethkey; use ethkey;
use parity_runtime::Executor; use parity_runtime::Executor;
use parking_lot::Mutex; use parking_lot::Mutex;
@ -34,7 +35,7 @@ use v1::helpers::{errors, ConfirmationPayload, FilledTransactionRequest, Subscri
use v1::helpers::external_signer::{SigningQueue, SignerService}; use v1::helpers::external_signer::{SigningQueue, SignerService};
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::traits::Signer; use v1::traits::Signer;
use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, U256, Bytes}; use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, Bytes};
/// Transactions confirmation (personal) rpc implementation. /// Transactions confirmation (personal) rpc implementation.
pub struct SignerClient<D: Dispatcher> { pub struct SignerClient<D: Dispatcher> {

View File

@ -18,9 +18,10 @@
use std::sync::Arc; use std::sync::Arc;
use transient_hashmap::TransientHashMap; use transient_hashmap::TransientHashMap;
use ethereum_types::U256;
use parking_lot::Mutex; use parking_lot::Mutex;
use ethereum_types::{H160, H256, H520, U256};
use jsonrpc_core::{BoxFuture, Result, Error}; use jsonrpc_core::{BoxFuture, Result, Error};
use jsonrpc_core::futures::{future, Future, Poll, Async}; use jsonrpc_core::futures::{future, Future, Poll, Async};
use jsonrpc_core::futures::future::Either; use jsonrpc_core::futures::future::Either;
@ -36,7 +37,7 @@ use v1::helpers::external_signer::{
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::traits::{EthSigning, ParitySigning}; use v1::traits::{EthSigning, ParitySigning};
use v1::types::{ use v1::types::{
H160 as RpcH160, H256 as RpcH256, U256 as RpcU256, Bytes as RpcBytes, H520 as RpcH520, Bytes as RpcBytes,
Either as RpcEither, Either as RpcEither,
RichRawTransaction as RpcRichRawTransaction, RichRawTransaction as RpcRichRawTransaction,
TransactionRequest as RpcTransactionRequest, TransactionRequest as RpcTransactionRequest,
@ -142,9 +143,8 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into))
} }
fn post_sign(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture<RpcEither<RpcU256, RpcConfirmationResponse>> { fn post_sign(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture<RpcEither<U256, RpcConfirmationResponse>> {
self.deprecation_notice.print("parity_postSign", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("parity_postSign", deprecated::msgs::ACCOUNTS);
let executor = self.executor.clone(); let executor = self.executor.clone();
let confirmations = self.confirmations.clone(); let confirmations = self.confirmations.clone();
@ -160,9 +160,8 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
})) }))
} }
fn post_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcEither<RpcU256, RpcConfirmationResponse>> { fn post_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcEither<U256, RpcConfirmationResponse>> {
self.deprecation_notice.print("parity_postTransaction", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("parity_postTransaction", deprecated::msgs::ACCOUNTS);
let executor = self.executor.clone(); let executor = self.executor.clone();
let confirmations = self.confirmations.clone(); let confirmations = self.confirmations.clone();
@ -176,9 +175,8 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
})) }))
} }
fn check_request(&self, id: RpcU256) -> Result<Option<RpcConfirmationResponse>> { fn check_request(&self, id: U256) -> Result<Option<RpcConfirmationResponse>> {
self.deprecation_notice.print("parity_checkRequest", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("parity_checkRequest", deprecated::msgs::ACCOUNTS);
let id: U256 = id.into(); let id: U256 = id.into();
match self.confirmations.lock().get(&id) { match self.confirmations.lock().get(&id) {
None => Err(errors::request_not_found()), // Request info has been dropped, or even never been there None => Err(errors::request_not_found()), // Request info has been dropped, or even never been there
@ -187,9 +185,8 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
} }
} }
fn decrypt_message(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture<RpcBytes> { fn decrypt_message(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture<RpcBytes> {
self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS);
let res = self.dispatch( let res = self.dispatch(
RpcConfirmationPayload::Decrypt((address.clone(), data).into()), RpcConfirmationPayload::Decrypt((address.clone(), data).into()),
meta.origin, meta.origin,
@ -208,9 +205,8 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> { impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
type Metadata = Metadata; type Metadata = Metadata;
fn sign(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture<RpcH520> { fn sign(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture<H520> {
self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS);
let res = self.dispatch( let res = self.dispatch(
RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()),
meta.origin, meta.origin,
@ -224,9 +220,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
})) }))
} }
fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> { fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<H256> {
self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS);
let res = self.dispatch( let res = self.dispatch(
RpcConfirmationPayload::SendTransaction(request), RpcConfirmationPayload::SendTransaction(request),
meta.origin, meta.origin,

View File

@ -18,8 +18,7 @@
use std::sync::Arc; use std::sync::Arc;
use ethereum_types::Address; use ethereum_types::{Address, H160, H256, H520, U256};
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::{future, Future};
use v1::helpers::{errors}; use v1::helpers::{errors};
@ -28,8 +27,7 @@ use v1::helpers::dispatch::{self, Dispatcher};
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::traits::{EthSigning, ParitySigning}; use v1::traits::{EthSigning, ParitySigning};
use v1::types::{ use v1::types::{
U256 as RpcU256, Bytes as RpcBytes,
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Bytes as RpcBytes,
Either as RpcEither, Either as RpcEither,
RichRawTransaction as RpcRichRawTransaction, RichRawTransaction as RpcRichRawTransaction,
TransactionRequest as RpcTransactionRequest, TransactionRequest as RpcTransactionRequest,
@ -70,9 +68,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
{ {
type Metadata = Metadata; type Metadata = Metadata;
fn sign(&self, _: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture<RpcH520> { fn sign(&self, _: Metadata, address: H160, data: RpcBytes) -> BoxFuture<H520> {
self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS);
Box::new(self.handle(RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), address.into()) Box::new(self.handle(RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), address.into())
.then(|res| match res { .then(|res| match res {
Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature), Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature),
@ -81,9 +78,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
})) }))
} }
fn send_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> { fn send_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<H256> {
self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS);
Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), self.accounts.default_account()) Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), self.accounts.default_account())
.then(|res| match res { .then(|res| match res {
Ok(RpcConfirmationResponse::SendTransaction(hash)) => Ok(hash), Ok(RpcConfirmationResponse::SendTransaction(hash)) => Ok(hash),
@ -113,9 +109,8 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningUnsafeClient<D> {
Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into))
} }
fn decrypt_message(&self, _: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture<RpcBytes> { fn decrypt_message(&self, _: Metadata, address: H160, data: RpcBytes) -> BoxFuture<RpcBytes> {
self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS);
Box::new(self.handle(RpcConfirmationPayload::Decrypt((address.clone(), data).into()), address.into()) Box::new(self.handle(RpcConfirmationPayload::Decrypt((address.clone(), data).into()), address.into())
.then(|res| match res { .then(|res| match res {
Ok(RpcConfirmationResponse::Decrypt(data)) => Ok(data), Ok(RpcConfirmationResponse::Decrypt(data)) => Ok(data),
@ -124,17 +119,17 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningUnsafeClient<D> {
})) }))
} }
fn post_sign(&self, _: Metadata, _: RpcH160, _: RpcBytes) -> BoxFuture<RpcEither<RpcU256, RpcConfirmationResponse>> { fn post_sign(&self, _: Metadata, _: H160, _: RpcBytes) -> BoxFuture<RpcEither<U256, RpcConfirmationResponse>> {
// We don't support this in non-signer mode. // We don't support this in non-signer mode.
Box::new(future::err(errors::signer_disabled())) Box::new(future::err(errors::signer_disabled()))
} }
fn post_transaction(&self, _: Metadata, _: RpcTransactionRequest) -> BoxFuture<RpcEither<RpcU256, RpcConfirmationResponse>> { fn post_transaction(&self, _: Metadata, _: RpcTransactionRequest) -> BoxFuture<RpcEither<U256, RpcConfirmationResponse>> {
// We don't support this in non-signer mode. // We don't support this in non-signer mode.
Box::new(future::err(errors::signer_disabled())) Box::new(future::err(errors::signer_disabled()))
} }
fn check_request(&self, _: RpcU256) -> Result<Option<RpcConfirmationResponse>> { fn check_request(&self, _: U256) -> Result<Option<RpcConfirmationResponse>> {
// We don't support this in non-signer mode. // We don't support this in non-signer mode.
Err(errors::signer_disabled()) Err(errors::signer_disabled())
} }

View File

@ -19,6 +19,7 @@
use std::sync::Arc; use std::sync::Arc;
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId}; use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId};
use ethereum_types::H256;
use rlp::Rlp; use rlp::Rlp;
use types::transaction::SignedTransaction; use types::transaction::SignedTransaction;
@ -26,7 +27,8 @@ use jsonrpc_core::Result;
use v1::Metadata; use v1::Metadata;
use v1::traits::Traces; use v1::traits::Traces;
use v1::helpers::{errors, fake_sign}; use v1::helpers::{errors, fake_sign};
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceResultsWithTransactionHash, TraceOptions, H256, block_number_to_id}; use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults,
TraceResultsWithTransactionHash, TraceOptions, block_number_to_id};
fn to_call_analytics(flags: TraceOptions) -> CallAnalytics { fn to_call_analytics(flags: TraceOptions) -> CallAnalytics {
CallAnalytics { CallAnalytics {

View File

@ -15,11 +15,12 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Web3 rpc implementation. //! Web3 rpc implementation.
use ethereum_types::H256;
use hash::keccak; use hash::keccak;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use version::version; use version::version;
use v1::traits::Web3; use v1::traits::Web3;
use v1::types::{H256, Bytes}; use v1::types::Bytes;
/// Web3 rpc implementation. /// Web3 rpc implementation.
pub struct Web3Client; pub struct Web3Client;

View File

@ -53,5 +53,5 @@ pub mod signer {
#[cfg(any(test, feature = "accounts"))] #[cfg(any(test, feature = "accounts"))]
pub use super::helpers::engine_signer::EngineSigner; pub use super::helpers::engine_signer::EngineSigner;
pub use super::helpers::external_signer::{SignerService, ConfirmationsQueue}; pub use super::helpers::external_signer::{SignerService, ConfirmationsQueue};
pub use super::types::{ConfirmationRequest, TransactionModification, U256, TransactionCondition}; pub use super::types::{ConfirmationRequest, TransactionModification, TransactionCondition};
} }

View File

@ -26,7 +26,7 @@ use ethcore::spec::{Genesis, Spec};
use ethcore::test_helpers; use ethcore::test_helpers;
use ethcore::verification::VerifierType; use ethcore::verification::VerifierType;
use ethcore::verification::queue::kind::blocks::Unverified; use ethcore::verification::queue::kind::blocks::Unverified;
use ethereum_types::{H256, Address}; use ethereum_types::{Address, H256, U256};
use ethjson::blockchain::BlockChain; use ethjson::blockchain::BlockChain;
use ethjson::spec::ForkSpec; use ethjson::spec::ForkSpec;
use io::IoChannel; use io::IoChannel;
@ -42,7 +42,6 @@ use v1::impls::{EthClient, EthClientOptions, SigningUnsafeClient};
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::tests::helpers::{TestSnapshotService, TestSyncProvider, Config}; use v1::tests::helpers::{TestSnapshotService, TestSyncProvider, Config};
use v1::traits::{Eth, EthSigning}; use v1::traits::{Eth, EthSigning};
use v1::types::U256 as NU256;
fn account_provider() -> Arc<AccountProvider> { fn account_provider() -> Arc<AccountProvider> {
Arc::new(AccountProvider::transient_provider()) Arc::new(AccountProvider::transient_provider())
@ -459,7 +458,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "eth_getBlockTransactionCountByNumber", "method": "eth_getBlockTransactionCountByNumber",
"params": [ "params": [
"#.to_owned() + &::serde_json::to_string(&NU256::from(num)).unwrap() + r#" "#.to_owned() + &::serde_json::to_string(&U256::from(num)).unwrap() + r#"
], ],
"id": "# + format!("{}", *id).as_ref() + r#" "id": "# + format!("{}", *id).as_ref() + r#"
}"#; }"#;

View File

@ -18,8 +18,8 @@ use std::sync::Arc;
use std::str::FromStr; use std::str::FromStr;
use bytes::ToPretty; use bytes::ToPretty;
use ethereum_types::{U256, Address};
use accounts::AccountProvider; use accounts::AccountProvider;
use ethereum_types::{Address, H520, U256};
use ethcore::client::TestBlockChainClient; use ethcore::client::TestBlockChainClient;
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;
use parking_lot::Mutex; use parking_lot::Mutex;
@ -31,7 +31,7 @@ use v1::{PersonalClient, Personal, Metadata};
use v1::helpers::{nonce, eip191}; use v1::helpers::{nonce, eip191};
use v1::helpers::dispatch::{eth_data_hash, FullDispatcher}; use v1::helpers::dispatch::{eth_data_hash, FullDispatcher};
use v1::tests::helpers::TestMinerService; use v1::tests::helpers::TestMinerService;
use v1::types::{EIP191Version, PresignedTransaction, H520}; use v1::types::{EIP191Version, PresignedTransaction};
use rustc_hex::ToHex; use rustc_hex::ToHex;
use serde_json::to_value; use serde_json::to_value;
use ethkey::Secret; use ethkey::Secret;
@ -156,7 +156,7 @@ fn sign() {
let hash = eth_data_hash(data); let hash = eth_data_hash(data);
let signature = H520(tester.accounts.sign(address, Some("password123".into()), hash).unwrap().into_electrum()); let signature = H520(tester.accounts.sign(address, Some("password123".into()), hash).unwrap().into_electrum());
let signature = format!("0x{:?}", signature); let signature = format!("{:?}", signature);
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + &signature + r#"","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + &signature + r#"","id":1}"#;
@ -264,7 +264,7 @@ fn ec_recover() {
let hash = eth_data_hash(data.clone()); let hash = eth_data_hash(data.clone());
let signature = H520(tester.accounts.sign(address, Some("password123".into()), hash).unwrap().into_electrum()); let signature = H520(tester.accounts.sign(address, Some("password123".into()), hash).unwrap().into_electrum());
let signature = format!("0x{:?}", signature); let signature = format!("{:?}", signature);
let request = r#"{ let request = r#"{
"jsonrpc": "2.0", "jsonrpc": "2.0",

View File

@ -18,6 +18,7 @@ use std::sync::Arc;
use crypto::DEFAULT_MAC; use crypto::DEFAULT_MAC;
use accounts::AccountProvider; use accounts::AccountProvider;
use ethereum_types::H256;
use ethkey::{KeyPair, Signature, verify_public}; use ethkey::{KeyPair, Signature, verify_public};
use serde_json; use serde_json;
@ -26,7 +27,7 @@ use v1::metadata::Metadata;
use v1::SecretStoreClient; use v1::SecretStoreClient;
use v1::traits::secretstore::SecretStore; use v1::traits::secretstore::SecretStore;
use v1::helpers::secretstore::ordered_servers_keccak; use v1::helpers::secretstore::ordered_servers_keccak;
use v1::types::{H256, EncryptedDocumentKey}; use v1::types::EncryptedDocumentKey;
struct Dependencies { struct Dependencies {
pub accounts: Arc<AccountProvider>, pub accounts: Arc<AccountProvider>,

View File

@ -16,7 +16,7 @@
use std::sync::Arc; use std::sync::Arc;
use std::str::FromStr; use std::str::FromStr;
use ethereum_types::{U256, Address}; use ethereum_types::{H520, U256, Address};
use bytes::ToPretty; use bytes::ToPretty;
use accounts::AccountProvider; use accounts::AccountProvider;
@ -31,7 +31,7 @@ use jsonrpc_core::IoHandler;
use v1::{SignerClient, Signer, Origin}; use v1::{SignerClient, Signer, Origin};
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::tests::helpers::TestMinerService; use v1::tests::helpers::TestMinerService;
use v1::types::{Bytes as RpcBytes, H520}; use v1::types::Bytes as RpcBytes;
use v1::helpers::{nonce, FilledTransactionRequest, ConfirmationPayload}; use v1::helpers::{nonce, FilledTransactionRequest, ConfirmationPayload};
use v1::helpers::external_signer::{SigningQueue, SignerService}; use v1::helpers::external_signer::{SigningQueue, SignerService};
use v1::helpers::dispatch::{self, FullDispatcher, eth_data_hash}; use v1::helpers::dispatch::{self, FullDispatcher, eth_data_hash};
@ -495,7 +495,7 @@ fn should_confirm_data_sign_with_signature() {
let data_hash = eth_data_hash(vec![1, 2, 3, 4].into()); let data_hash = eth_data_hash(vec![1, 2, 3, 4].into());
let signature = H520(tester.accounts.sign(address, Some("test".into()), data_hash).unwrap().into_electrum()); let signature = H520(tester.accounts.sign(address, Some("test".into()), data_hash).unwrap().into_electrum());
let signature = format!("0x{:?}", signature); let signature = format!("{:?}", signature);
// when // when
let request = r#"{ let request = r#"{

View File

@ -210,7 +210,7 @@ fn rpc_eth_send_transaction_with_bad_to() {
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: expected a hex-encoded hash with 0x prefix."},"id":1}"#; let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: prefix is missing."},"id":1}"#;
assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); assert_eq!(tester.io.handle_request_sync(&request), Some(response.into()));
} }

View File

@ -17,10 +17,10 @@
//! Eth rpc interface. //! Eth rpc interface.
use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::{Result, BoxFuture};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use ethereum_types::{H64, H160, H256, U64, U256};
use v1::types::{RichBlock, BlockNumber, Bytes, CallRequest, Filter, FilterChanges, Index, EthAccount}; use v1::types::{RichBlock, BlockNumber, Bytes, CallRequest, Filter, FilterChanges, Index, EthAccount};
use v1::types::{Log, Receipt, SyncStatus, Transaction, Work}; use v1::types::{Log, Receipt, SyncStatus, Transaction, Work};
use v1::types::{H64, H160, H256, U256, U64};
/// Eth rpc interface. /// Eth rpc interface.
#[rpc] #[rpc]
@ -56,7 +56,7 @@ pub trait Eth {
/// Returns current gas_price. /// Returns current gas_price.
#[rpc(name = "eth_gasPrice")] #[rpc(name = "eth_gasPrice")]
fn gas_price(&self) -> Result<U256>; fn gas_price(&self) -> BoxFuture<U256>;
/// Returns accounts list. /// Returns accounts list.
#[rpc(name = "eth_accounts")] #[rpc(name = "eth_accounts")]

View File

@ -19,7 +19,8 @@
use jsonrpc_core::BoxFuture; use jsonrpc_core::BoxFuture;
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{Bytes, H160, H256, H520, TransactionRequest, RichRawTransaction}; use ethereum_types::{H160, H256, H520};
use v1::types::{Bytes, TransactionRequest, RichRawTransaction};
/// Signing methods implementation relying on unlocked accounts. /// Signing methods implementation relying on unlocked accounts.
#[rpc] #[rpc]

View File

@ -18,10 +18,11 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use ethereum_types::{H64, H160, H256, H512, U64, U256};
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{ use v1::types::{
H160, H256, H512, U256, U64, H64, Bytes, CallRequest, Bytes, CallRequest,
Peers, Transaction, RpcSettings, Histogram, RecoveredAccount, Peers, Transaction, RpcSettings, Histogram, RecoveredAccount,
TransactionStats, LocalTransactionStatus, TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo, BlockNumber, ConsensusCapability, VersionInfo,

View File

@ -19,9 +19,10 @@ use std::collections::BTreeMap;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use ethereum_types::{H160, H256, H520};
use ethkey::Password; use ethkey::Password;
use ethstore::KeyFile; use ethstore::KeyFile;
use v1::types::{H160, H256, H520, DeriveHash, DeriveHierarchical, ExtAccountInfo}; use v1::types::{DeriveHash, DeriveHierarchical, ExtAccountInfo};
use v1::types::{AccountInfo, HwAccountInfo}; use v1::types::{AccountInfo, HwAccountInfo};
/// Parity-specific read-only accounts rpc interface. /// Parity-specific read-only accounts rpc interface.

View File

@ -16,10 +16,11 @@
//! Parity-specific rpc interface for operations altering the settings. //! Parity-specific rpc interface for operations altering the settings.
use ethereum_types::{H160, H256, U256};
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; use v1::types::{Bytes, ReleaseInfo, Transaction};
/// Parity-specific rpc interface for operations altering the account-related settings. /// Parity-specific rpc interface for operations altering the account-related settings.
#[rpc] #[rpc]

View File

@ -18,7 +18,8 @@
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{U256, H160, Bytes, ConfirmationResponse, TransactionRequest, Either}; use ethereum_types::{H160, U256};
use v1::types::{Bytes, ConfirmationResponse, TransactionRequest, Either};
/// Signing methods implementation. /// Signing methods implementation.
#[rpc] #[rpc]

View File

@ -16,10 +16,11 @@
//! Personal rpc interface. //! Personal rpc interface.
use eip_712::EIP712; use eip_712::EIP712;
use ethereum_types::{H160, H256, H520, U128};
use jsonrpc_core::types::Value; use jsonrpc_core::types::Value;
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{Bytes, U128, H160, H256, H520, TransactionRequest, RichRawTransaction as RpcRichRawTransaction, EIP191Version}; use v1::types::{Bytes, TransactionRequest, RichRawTransaction as RpcRichRawTransaction, EIP191Version};
/// Personal rpc interface. Safe (read-only) functions. /// Personal rpc interface. Safe (read-only) functions.
#[rpc] #[rpc]
@ -70,5 +71,4 @@ pub trait Personal {
/// @deprecated alias for `personal_sendTransaction`. /// @deprecated alias for `personal_sendTransaction`.
#[rpc(meta, name = "personal_signAndSendTransaction")] #[rpc(meta, name = "personal_signAndSendTransaction")]
fn sign_and_send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture<H256>; fn sign_and_send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture<H256>;
} }

View File

@ -16,10 +16,11 @@
//! SecretStore-specific rpc interface. //! SecretStore-specific rpc interface.
use ethereum_types::{H160, H256, U256};
use jsonrpc_core::Error; use jsonrpc_core::Error;
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, U256, BlockNumber, use v1::types::{Bytes, PrivateTransactionReceipt, BlockNumber,
PrivateTransactionReceiptAndTransaction, CallRequest}; PrivateTransactionReceiptAndTransaction, CallRequest};
/// Private transaction management RPC interface. /// Private transaction management RPC interface.

View File

@ -17,11 +17,12 @@
//! SecretStore-specific rpc interface. //! SecretStore-specific rpc interface.
use std::collections::BTreeSet; use std::collections::BTreeSet;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use ethereum_types::{H160, H256, H512};
use ethkey::Password; use ethkey::Password;
use v1::types::{Bytes, EncryptedDocumentKey};
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey};
/// Parity-specific rpc interface. /// Parity-specific rpc interface.
#[rpc] #[rpc]

View File

@ -15,11 +15,13 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Parity Signer-related rpc interface. //! Parity Signer-related rpc interface.
use ethereum_types::U256;
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{U256, Bytes, TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken}; use v1::types::{Bytes, TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken};
/// Signer extension for confirmations rpc interface. /// Signer extension for confirmations rpc interface.
#[rpc] #[rpc]

View File

@ -16,9 +16,11 @@
//! Traces specific rpc interface. //! Traces specific rpc interface.
use ethereum_types::H256;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceResultsWithTransactionHash, H256, TraceOptions}; use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults,
TraceResultsWithTransactionHash, TraceOptions};
/// Traces specific rpc interface. /// Traces specific rpc interface.
#[rpc] #[rpc]

View File

@ -15,10 +15,11 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Web3 rpc interface. //! Web3 rpc interface.
use ethereum_types::H256;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{H256, Bytes}; use v1::types::Bytes;
/// Web3 rpc interface. /// Web3 rpc interface.
#[rpc] #[rpc]

View File

@ -16,8 +16,8 @@
//! Return types for RPC calls //! Return types for RPC calls
use ethereum_types::{Public, Address}; use ethereum_types::{Public, Address, H160, H256, U256};
use v1::types::{H160, H256, U256, Bytes}; use v1::types::Bytes;
/// Account information. /// Account information.
#[derive(Debug, Default, Clone, PartialEq, Serialize)] #[derive(Debug, Default, Clone, PartialEq, Serialize)]

View File

@ -17,11 +17,11 @@
use std::ops::Deref; use std::ops::Deref;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use ethereum_types::{H160, H256, U256, Bloom as H2048};
use serde::ser::Error; use serde::ser::Error;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use types::encoded::Header as EthHeader; use types::encoded::Header as EthHeader;
use v1::types::{Bytes, Transaction};
use v1::types::{Bytes, Transaction, H160, H256, H2048, U256};
/// Block Transactions /// Block Transactions
#[derive(Debug)] #[derive(Debug)]
@ -205,8 +205,9 @@ impl<T: Serialize> Serialize for Rich<T> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::BTreeMap; use std::collections::BTreeMap;
use ethereum_types::{H64, H160, H256, U256, Bloom as H2048};
use serde_json; use serde_json;
use v1::types::{Transaction, H64, H160, H256, H2048, Bytes, U256}; use v1::types::{Transaction, Bytes};
use super::{Block, RichBlock, BlockTransactions, Header, RichHeader}; use super::{Block, RichBlock, BlockTransactions, Header, RichHeader};
#[test] #[test]
@ -248,8 +249,8 @@ mod tests {
let rich_block = RichBlock { let rich_block = RichBlock {
inner: block, inner: block,
extra_info: map![ extra_info: map![
"mixHash".into() => format!("0x{:?}", H256::default()), "mixHash".into() => format!("{:?}", H256::default()),
"nonce".into() => format!("0x{:?}", H64::default()) "nonce".into() => format!("{:?}", H64::default())
], ],
}; };
let serialized_rich_block = serde_json::to_string(&rich_block).unwrap(); let serialized_rich_block = serde_json::to_string(&rich_block).unwrap();
@ -286,8 +287,8 @@ mod tests {
let rich_block = RichBlock { let rich_block = RichBlock {
inner: block, inner: block,
extra_info: map![ extra_info: map![
"mixHash".into() => format!("0x{:?}", H256::default()), "mixHash".into() => format!("{:?}", H256::default()),
"nonce".into() => format!("0x{:?}", H64::default()) "nonce".into() => format!("{:?}", H64::default())
], ],
}; };
let serialized_rich_block = serde_json::to_string(&rich_block).unwrap(); let serialized_rich_block = serde_json::to_string(&rich_block).unwrap();
@ -321,8 +322,8 @@ mod tests {
let rich_header = RichHeader { let rich_header = RichHeader {
inner: header, inner: header,
extra_info: map![ extra_info: map![
"mixHash".into() => format!("0x{:?}", H256::default()), "mixHash".into() => format!("{:?}", H256::default()),
"nonce".into() => format!("0x{:?}", H64::default()) "nonce".into() => format!("{:?}", H64::default())
], ],
}; };
let serialized_rich_header = serde_json::to_string(&rich_header).unwrap(); let serialized_rich_header = serde_json::to_string(&rich_header).unwrap();

View File

@ -14,8 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::{H160, U256};
use v1::helpers::CallRequest as Request; use v1::helpers::CallRequest as Request;
use v1::types::{Bytes, H160, U256}; use v1::types::Bytes;
/// Call request /// Call request
#[derive(Debug, Default, PartialEq, Deserialize)] #[derive(Debug, Default, PartialEq, Deserialize)]
@ -57,7 +58,7 @@ mod tests {
use std::str::FromStr; use std::str::FromStr;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use serde_json; use serde_json;
use v1::types::{U256, H160}; use ethereum_types::{U256, H160};
use super::CallRequest; use super::CallRequest;
#[test] #[test]

View File

@ -21,7 +21,8 @@ use serde::{Serialize, Serializer};
use ansi_term::Colour; use ansi_term::Colour;
use bytes::ToPretty; use bytes::ToPretty;
use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes, TransactionCondition, Origin}; use ethereum_types::{H160, H256, H520, U256};
use v1::types::{TransactionRequest, RichRawTransaction, Bytes, TransactionCondition, Origin};
use v1::helpers; use v1::helpers;
use ethkey::Password; use ethkey::Password;
@ -281,8 +282,9 @@ impl<A, B> Serialize for Either<A, B> where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr; use std::str::FromStr;
use ethereum_types::{H256, U256};
use serde_json; use serde_json;
use v1::types::{U256, H256, TransactionCondition}; use v1::types::TransactionCondition;
use v1::helpers; use v1::helpers;
use super::*; use super::*;

View File

@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::{H160, H256};
use semver; use semver;
use v1::types::{H160, H256};
use updater::{self, CapState}; use updater::{self, CapState};
/// Capability info /// Capability info

View File

@ -18,10 +18,9 @@ use std::fmt;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde::de::{Error, Visitor}; use serde::de::{Error, Visitor};
use ethereum_types::H256;
use ethstore; use ethstore;
use super::hash::H256;
/// Type of derivation /// Type of derivation
pub enum DerivationType { pub enum DerivationType {
/// Soft - allow proof of parent /// Soft - allow proof of parent

View File

@ -15,9 +15,11 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! EIP-191 specific types //! EIP-191 specific types
use ethereum_types::H160;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde::de; use serde::de;
use v1::types::{H160, Bytes}; use v1::types::Bytes;
/// EIP-191 version specifier /// EIP-191 version specifier
#[derive(Debug)] #[derive(Debug)]

View File

@ -0,0 +1,84 @@
use ethereum_types::{H256, U256};
use serde_json;
type Res = Result<U256, serde_json::Error>;
#[test]
fn should_serialize_u256() {
let serialized1 = serde_json::to_string(&U256::from(0)).unwrap();
let serialized2 = serde_json::to_string(&U256::from(1)).unwrap();
let serialized3 = serde_json::to_string(&U256::from(16)).unwrap();
let serialized4 = serde_json::to_string(&U256::from(256)).unwrap();
assert_eq!(serialized1, r#""0x0""#);
assert_eq!(serialized2, r#""0x1""#);
assert_eq!(serialized3, r#""0x10""#);
assert_eq!(serialized4, r#""0x100""#);
}
#[test]
fn should_serialize_h256() {
let serialized1 = serde_json::to_string(&H256::from(0)).unwrap();
let serialized2 = serde_json::to_string(&H256::from(1)).unwrap();
let serialized3 = serde_json::to_string(&H256::from(16)).unwrap();
let serialized4 = serde_json::to_string(&H256::from(256)).unwrap();
assert_eq!(serialized1, r#""0x0000000000000000000000000000000000000000000000000000000000000000""#);
assert_eq!(serialized2, r#""0x0000000000000000000000000000000000000000000000000000000000000001""#);
assert_eq!(serialized3, r#""0x0000000000000000000000000000000000000000000000000000000000000010""#);
assert_eq!(serialized4, r#""0x0000000000000000000000000000000000000000000000000000000000000100""#);
}
#[test]
fn should_fail_to_deserialize_decimals() {
let deserialized0: Res = serde_json::from_str(r#""∀∂""#);
let deserialized1: Res = serde_json::from_str(r#""""#);
let deserialized2: Res = serde_json::from_str(r#""0""#);
let deserialized3: Res = serde_json::from_str(r#""10""#);
let deserialized4: Res = serde_json::from_str(r#""1000000""#);
let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#);
let deserialized6: Res = serde_json::from_str(r#""0x""#);
assert!(deserialized0.is_err());
assert!(deserialized1.is_err());
assert!(deserialized2.is_err());
assert!(deserialized3.is_err());
assert!(deserialized4.is_err());
assert!(deserialized5.is_err());
assert!(deserialized6.is_err(), "Quantities should represent zero as 0x0");
}
#[test]
fn should_fail_to_deserialize_bad_hex_strings() {
let deserialized1: Result<H256, serde_json::Error> = serde_json::from_str(r#""0""#);
let deserialized2: Result<H256, serde_json::Error> = serde_json::from_str(r#""0x""#);
let deserialized3: Result<H256, serde_json::Error> = serde_json::from_str(r#""0x∀∂0000000000000000000000000000000000000000000000000000000000""#);
assert!(deserialized1.is_err(), "hex string should start with 0x");
assert!(deserialized2.is_err(), "0x-prefixed hex string of length 64");
assert!(deserialized3.is_err(), "hex string should only contain hex chars");
}
#[test]
fn should_deserialize_u256() {
let deserialized1: U256 = serde_json::from_str(r#""0x0""#).unwrap();
let deserialized2: U256 = serde_json::from_str(r#""0x1""#).unwrap();
let deserialized3: U256 = serde_json::from_str(r#""0x01""#).unwrap();
let deserialized4: U256 = serde_json::from_str(r#""0x100""#).unwrap();
assert_eq!(deserialized1, 0.into());
assert_eq!(deserialized2, 1.into());
assert_eq!(deserialized3, 1.into());
assert_eq!(deserialized4, 256.into());
}
#[test]
fn should_deserialize_h256() {
let deserialized1: H256 = serde_json::from_str(r#""0x0000000000000000000000000000000000000000000000000000000000000000""#).unwrap();
let deserialized2: H256 = serde_json::from_str(r#""0x0000000000000000000000000000000000000000000000000000000000000001""#).unwrap();
let deserialized3: H256 = serde_json::from_str(r#""0x0000000000000000000000000000000000000000000000000000000000000100""#).unwrap();
assert_eq!(deserialized1, 0.into());
assert_eq!(deserialized2, 1.into());
assert_eq!(deserialized3, 256.into());
}

View File

@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::{H160, H256};
use jsonrpc_core::{Error as RpcError}; use jsonrpc_core::{Error as RpcError};
use serde::de::{Error, DeserializeOwned}; use serde::de::{Error, DeserializeOwned};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
@ -21,7 +22,7 @@ use serde_json::{Value, from_value};
use types::filter::Filter as EthFilter; use types::filter::Filter as EthFilter;
use types::ids::BlockId; use types::ids::BlockId;
use v1::types::{BlockNumber, H160, H256, Log}; use v1::types::{BlockNumber, Log};
use v1::helpers::errors::invalid_params; use v1::helpers::errors::invalid_params;
/// Variadic value /// Variadic value

View File

@ -1,165 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::fmt;
use std::str::FromStr;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use serde;
use rustc_hex::{ToHex, FromHex};
use ethereum_types::{H64 as Eth64, H160 as Eth160, H256 as Eth256, H520 as Eth520, H512 as Eth512, Bloom as Eth2048};
macro_rules! impl_hash {
($name: ident, $other: ident, $size: expr) => {
/// Hash serialization
pub struct $name(pub [u8; $size]);
impl Eq for $name { }
impl Default for $name {
fn default() -> Self {
$name([0; $size])
}
}
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0.to_hex())
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let hex = self.0.to_hex();
write!(f, "{}..{}", &hex[0..2], &hex[$size-2..$size])
}
}
impl<T> From<T> for $name where $other: From<T> {
fn from(o: T) -> Self {
$name($other::from(o).0)
}
}
impl FromStr for $name {
type Err = <$other as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
$other::from_str(s).map(|x| $name(x.0))
}
}
impl Into<$other> for $name {
fn into(self) -> $other {
$other(self.0)
}
}
impl PartialEq for $name {
fn eq(&self, other: &Self) -> bool {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref == other_ref
}
}
impl PartialOrd for $name {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref.partial_cmp(other_ref)
}
}
impl Ord for $name {
fn cmp(&self, other: &Self) -> Ordering {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref.cmp(other_ref)
}
}
impl Hash for $name {
fn hash<H>(&self, state: &mut H) where H: Hasher {
let self_ref: &[u8] = &self.0;
Hash::hash(self_ref, state)
}
}
impl Clone for $name {
fn clone(&self) -> Self {
let mut r = [0; $size];
r.copy_from_slice(&self.0);
$name(r)
}
}
impl serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer {
let mut hex = "0x".to_owned();
hex.push_str(&self.0.to_hex());
serializer.serialize_str(&hex)
}
}
impl<'a> serde::Deserialize<'a> for $name {
fn deserialize<D>(deserializer: D) -> Result<$name, D::Error> where D: serde::Deserializer<'a> {
struct HashVisitor;
impl<'b> serde::de::Visitor<'b> for HashVisitor {
type Value = $name;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a 0x-prefixed, padded, hex-encoded hash with length {}", $size * 2)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
if value.len() < 2 || !value.starts_with("0x") {
return Err(E::custom("expected a hex-encoded hash with 0x prefix"));
}
if value.len() != 2 + $size * 2 {
return Err(E::invalid_length(value.len() - 2, &self));
}
match value[2..].from_hex() {
Ok(ref v) => {
let mut result = [0u8; $size];
result.copy_from_slice(v);
Ok($name(result))
},
Err(e) => Err(E::custom(format!("invalid hex value: {:?}", e))),
}
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E> where E: serde::de::Error {
self.visit_str(value.as_ref())
}
}
deserializer.deserialize_any(HashVisitor)
}
}
}
}
impl_hash!(H64, Eth64, 8);
impl_hash!(H160, Eth160, 20);
impl_hash!(H256, Eth256, 32);
impl_hash!(H512, Eth512, 64);
impl_hash!(H520, Eth520, 65);
impl_hash!(H2048, Eth2048, 256);

View File

@ -16,7 +16,7 @@
//! Gas prices histogram. //! Gas prices histogram.
use v1::types::U256; use ethereum_types::U256;
/// Values of RPC settings. /// Values of RPC settings.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]

View File

@ -14,8 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::{H160, H256, U256};
use types::log_entry::{LocalizedLogEntry, LogEntry}; use types::log_entry::{LocalizedLogEntry, LogEntry};
use v1::types::{Bytes, H160, H256, U256}; use v1::types::Bytes;
/// Log /// Log
#[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone)] #[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone)]
@ -87,7 +88,8 @@ impl From<LogEntry> for Log {
mod tests { mod tests {
use serde_json; use serde_json;
use std::str::FromStr; use std::str::FromStr;
use v1::types::{Log, H160, H256, U256}; use v1::types::Log;
use ethereum_types::{H160, H256, U256};
#[test] #[test]
fn log_serialization() { fn log_serialization() {

View File

@ -16,6 +16,9 @@
//! RPC types //! RPC types
#[cfg(test)]
mod eth_types;
mod account_info; mod account_info;
mod block; mod block;
mod block_number; mod block_number;
@ -25,7 +28,6 @@ mod confirmations;
mod consensus_status; mod consensus_status;
mod derivation; mod derivation;
mod filter; mod filter;
mod hash;
mod histogram; mod histogram;
mod index; mod index;
mod log; mod log;
@ -40,7 +42,6 @@ mod trace_filter;
mod transaction; mod transaction;
mod transaction_request; mod transaction_request;
mod transaction_condition; mod transaction_condition;
mod uint;
mod work; mod work;
mod private_receipt; mod private_receipt;
mod eip191; mod eip191;
@ -60,7 +61,6 @@ pub use self::confirmations::{
pub use self::consensus_status::*; pub use self::consensus_status::*;
pub use self::derivation::{DeriveHash, DeriveHierarchical, Derive}; pub use self::derivation::{DeriveHash, DeriveHierarchical, Derive};
pub use self::filter::{Filter, FilterChanges}; pub use self::filter::{Filter, FilterChanges};
pub use self::hash::{H64, H160, H256, H512, H520, H2048};
pub use self::histogram::Histogram; pub use self::histogram::Histogram;
pub use self::index::Index; pub use self::index::Index;
pub use self::log::Log; pub use self::log::Log;
@ -78,7 +78,6 @@ pub use self::trace_filter::TraceFilter;
pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus}; pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus};
pub use self::transaction_request::TransactionRequest; pub use self::transaction_request::TransactionRequest;
pub use self::transaction_condition::TransactionCondition; pub use self::transaction_condition::TransactionCondition;
pub use self::uint::{U128, U256, U64};
pub use self::work::Work; pub use self::work::Work;
pub use self::private_receipt::{PrivateTransactionReceipt, PrivateTransactionReceiptAndTransaction}; pub use self::private_receipt::{PrivateTransactionReceipt, PrivateTransactionReceiptAndTransaction};

View File

@ -14,8 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use v1::types::{H160, H256, TransactionRequest};
use ethcore_private_tx::{Receipt as EthPrivateReceipt}; use ethcore_private_tx::{Receipt as EthPrivateReceipt};
use ethereum_types::{H160, H256};
use v1::types::TransactionRequest;
/// Receipt /// Receipt
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]

View File

@ -17,7 +17,7 @@
//! Request Provenance //! Request Provenance
use std::fmt; use std::fmt;
use v1::types::H256; use ethereum_types::H256;
/// RPC request origin /// RPC request origin
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]

View File

@ -16,10 +16,11 @@
//! Pub-Sub types. //! Pub-Sub types.
use ethereum_types::H256;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de::Error; use serde::de::Error;
use serde_json::{Value, from_value}; use serde_json::{Value, from_value};
use v1::types::{RichHeader, Filter, Log, H256}; use v1::types::{RichHeader, Filter, Log};
/// Subscription result. /// Subscription result.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]

View File

@ -14,7 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use v1::types::{Log, H160, H256, H2048, U256, U64}; use ethereum_types::{H160, H256, U64, U256, Bloom as H2048};
use v1::types::Log;
use types::receipt::{Receipt as EthReceipt, RichReceipt, LocalizedReceipt, TransactionOutcome}; use types::receipt::{Receipt as EthReceipt, RichReceipt, LocalizedReceipt, TransactionOutcome};
/// Receipt /// Receipt

View File

@ -14,7 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use v1::types::{Bytes, H512}; use ethereum_types::H512;
use v1::types::Bytes;
/// Encrypted document key. /// Encrypted document key.
#[derive(Default, Debug, Serialize, PartialEq)] #[derive(Default, Debug, Serialize, PartialEq)]
@ -22,7 +23,7 @@ use v1::types::{Bytes, H512};
pub struct EncryptedDocumentKey { pub struct EncryptedDocumentKey {
/// Common encryption point. Pass this to Secret Store 'Document key storing session' /// Common encryption point. Pass this to Secret Store 'Document key storing session'
pub common_point: H512, pub common_point: H512,
/// Ecnrypted point. Pass this to Secret Store 'Document key storing session'. /// Encrypted point. Pass this to Secret Store 'Document key storing session'.
pub encrypted_point: H512, pub encrypted_point: H512,
/// Document key itself, encrypted with passed account public. Pass this to 'secretstore_encrypt'. /// Document key itself, encrypted with passed account public. Pass this to 'secretstore_encrypt'.
pub encrypted_key: Bytes, pub encrypted_key: Bytes,

View File

@ -16,9 +16,10 @@
use network::client_version::ClientVersion; use network::client_version::ClientVersion;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use ethereum_types::{U256, H512};
use sync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats}; use sync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats};
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use v1::types::{U256, H512};
/// Sync info /// Sync info
#[derive(Default, Debug, Serialize, PartialEq)] #[derive(Default, Debug, Serialize, PartialEq)]

View File

@ -19,14 +19,14 @@ use std::collections::BTreeMap;
use ethcore::client::Executed; use ethcore::client::Executed;
use ethcore::trace as et; use ethcore::trace as et;
use ethcore::trace::{FlatTrace, LocalizedTrace as EthLocalizedTrace, trace, TraceError}; use ethcore::trace::{FlatTrace, LocalizedTrace as EthLocalizedTrace, trace, TraceError};
use ethereum_types::H256 as EthH256; use ethereum_types::{H160, H256, U256};
use serde::ser::SerializeStruct; use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use types::account_diff; use types::account_diff;
use types::state_diff; use types::state_diff;
use vm; use vm;
use v1::types::{Bytes, H160, H256, U256}; use v1::types::Bytes;
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
/// A diff of some chunk of memory. /// A diff of some chunk of memory.
@ -639,8 +639,8 @@ pub struct TraceResultsWithTransactionHash {
pub transaction_hash: H256, pub transaction_hash: H256,
} }
impl From<(EthH256, Executed)> for TraceResultsWithTransactionHash { impl From<(H256, Executed)> for TraceResultsWithTransactionHash {
fn from(t: (EthH256, Executed)) -> Self { fn from(t: (H256, Executed)) -> Self {
TraceResultsWithTransactionHash { TraceResultsWithTransactionHash {
output: t.1.output.into(), output: t.1.output.into(),
trace: t.1.trace.into_iter().map(Into::into).collect(), trace: t.1.trace.into_iter().map(Into::into).collect(),

View File

@ -18,7 +18,8 @@
use ethcore::client::BlockId; use ethcore::client::BlockId;
use ethcore::client; use ethcore::client;
use v1::types::{BlockNumber, H160}; use ethereum_types::H160;
use v1::types::BlockNumber;
/// Trace filter /// Trace filter
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]

View File

@ -19,9 +19,10 @@ use std::sync::Arc;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use serde::ser::SerializeStruct; use serde::ser::SerializeStruct;
use ethcore::{contract_address, CreateContractAddress}; use ethcore::{contract_address, CreateContractAddress};
use ethereum_types::{H160, H256, H512, U64, U256};
use miner; use miner;
use types::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction}; use types::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
use v1::types::{Bytes, H160, H256, U256, H512, U64, TransactionCondition}; use v1::types::{Bytes, TransactionCondition};
/// Transaction /// Transaction
#[derive(Debug, Default, Clone, PartialEq, Serialize)] #[derive(Debug, Default, Clone, PartialEq, Serialize)]

View File

@ -16,7 +16,8 @@
//! `TransactionRequest` type //! `TransactionRequest` type
use v1::types::{Bytes, H160, U256, TransactionCondition}; use ethereum_types::{H160, U256};
use v1::types::{Bytes, TransactionCondition};
use v1::helpers; use v1::helpers;
use ansi_term::Colour; use ansi_term::Colour;
@ -137,7 +138,8 @@ mod tests {
use std::str::FromStr; use std::str::FromStr;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use serde_json; use serde_json;
use v1::types::{U256, H160, TransactionCondition}; use v1::types::TransactionCondition;
use ethereum_types::{H160, U256};
use super::*; use super::*;
#[test] #[test]

View File

@ -1,172 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::str::FromStr;
use std::fmt;
use serde;
use ethereum_types::{U256 as EthU256, U128 as EthU128};
macro_rules! impl_uint {
($name: ident, $other: ident, $size: expr) => {
/// Uint serialization.
#[derive(Debug, Default, Clone, Copy, PartialEq, Hash)]
pub struct $name($other);
impl Eq for $name { }
impl<T> From<T> for $name where $other: From<T> {
fn from(o: T) -> Self {
$name($other::from(o))
}
}
impl FromStr for $name {
type Err = <$other as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
$other::from_str(s).map($name)
}
}
impl Into<$other> for $name {
fn into(self) -> $other {
self.0
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::LowerHex for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::LowerHex::fmt(&self.0, f)
}
}
impl<'a> serde::Deserialize<'a> for $name {
fn deserialize<D>(deserializer: D) -> Result<$name, D::Error>
where D: serde::Deserializer<'a> {
struct UintVisitor;
impl<'b> serde::de::Visitor<'b> for UintVisitor {
type Value = $name;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a 0x-prefixed, hex-encoded number of length {}", $size*16)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
if value.len() < 2 || !value.starts_with("0x") {
return Err(E::custom("expected a hex-encoded numbers with 0x prefix"))
}
// 0x + len
if value.len() > 2 + $size * 16 {
return Err(E::invalid_length(value.len() - 2, &self));
}
$other::from_str(&value[2..]).map($name).map_err(|e| E::custom(&format!("invalid hex value: {:?}", e)))
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E> where E: serde::de::Error {
self.visit_str(&value)
}
}
deserializer.deserialize_any(UintVisitor)
}
}
}
}
impl_uint!(U128, EthU128, 2);
impl_uint!(U256, EthU256, 4);
impl_uint!(U64, u64, 1);
impl serde::Serialize for U128 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(&format!("{:#x}", self))
}
}
impl serde::Serialize for U256 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(&format!("{:#x}", self))
}
}
impl serde::Serialize for U64 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(&format!("{:#x}", self))
}
}
#[cfg(test)]
mod tests {
use super::U256;
use serde_json;
type Res = Result<U256, serde_json::Error>;
#[test]
fn should_serialize_u256() {
let serialized1 = serde_json::to_string(&U256(0.into())).unwrap();
let serialized2 = serde_json::to_string(&U256(1.into())).unwrap();
let serialized3 = serde_json::to_string(&U256(16.into())).unwrap();
let serialized4 = serde_json::to_string(&U256(256.into())).unwrap();
assert_eq!(serialized1, r#""0x0""#);
assert_eq!(serialized2, r#""0x1""#);
assert_eq!(serialized3, r#""0x10""#);
assert_eq!(serialized4, r#""0x100""#);
}
#[test]
fn should_fail_to_deserialize_decimals() {
let deserialized0: Res = serde_json::from_str(r#""∀∂""#);
let deserialized1: Res = serde_json::from_str(r#""""#);
let deserialized2: Res = serde_json::from_str(r#""0""#);
let deserialized3: Res = serde_json::from_str(r#""10""#);
let deserialized4: Res = serde_json::from_str(r#""1000000""#);
let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#);
assert!(deserialized0.is_err());
assert!(deserialized1.is_err());
assert!(deserialized2.is_err());
assert!(deserialized3.is_err());
assert!(deserialized4.is_err());
assert!(deserialized5.is_err());
}
#[test]
fn should_deserialize_u256() {
let deserialized1: U256 = serde_json::from_str(r#""0x""#).unwrap();
let deserialized2: U256 = serde_json::from_str(r#""0x0""#).unwrap();
let deserialized3: U256 = serde_json::from_str(r#""0x1""#).unwrap();
let deserialized4: U256 = serde_json::from_str(r#""0x01""#).unwrap();
let deserialized5: U256 = serde_json::from_str(r#""0x100""#).unwrap();
assert_eq!(deserialized1, U256(0.into()));
assert_eq!(deserialized2, U256(0.into()));
assert_eq!(deserialized3, U256(1.into()));
assert_eq!(deserialized4, U256(1.into()));
assert_eq!(deserialized5, U256(256.into()));
}
}

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use super::{H256, U256}; use ethereum_types::{H256, U256};
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};