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:
parent
d30610621f
commit
8f6911af20
637
Cargo.lock
generated
637
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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" }
|
||||||
|
@ -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"
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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]
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
415
miner/src/pool/replace.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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() {
|
||||||
|
@ -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"]
|
||||||
|
@ -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)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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.
|
||||||
|
@ -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 }
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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> {
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
|
@ -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(),
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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> {
|
||||||
|
@ -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,
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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};
|
||||||
}
|
}
|
||||||
|
@ -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#"
|
||||||
}"#;
|
}"#;
|
||||||
|
@ -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",
|
||||||
|
@ -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>,
|
||||||
|
@ -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#"{
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
@ -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")]
|
||||||
|
@ -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]
|
||||||
|
@ -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,
|
||||||
|
@ -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.
|
||||||
|
@ -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]
|
||||||
|
@ -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]
|
||||||
|
@ -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>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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]
|
||||||
|
@ -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]
|
||||||
|
@ -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]
|
||||||
|
@ -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]
|
||||||
|
@ -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)]
|
||||||
|
@ -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();
|
||||||
|
@ -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]
|
||||||
|
@ -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::*;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)]
|
||||||
|
84
rpc/src/v1/types/eth_types.rs
Normal file
84
rpc/src/v1/types/eth_types.rs
Normal 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());
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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);
|
|
@ -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)]
|
||||||
|
@ -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() {
|
||||||
|
@ -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};
|
||||||
|
|
||||||
|
@ -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)]
|
||||||
|
@ -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)]
|
||||||
|
@ -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)]
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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)]
|
||||||
|
@ -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(),
|
||||||
|
@ -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)]
|
||||||
|
@ -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)]
|
||||||
|
@ -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]
|
||||||
|
@ -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()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -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};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user