Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76d4064a4c | ||
|
|
a03cf2ed43 | ||
|
|
b6a764deb2 | ||
|
|
8f6911af20 | ||
|
|
d30610621f |
@@ -33,7 +33,7 @@ variables:
|
||||
|
||||
.docker-cache-status: &docker-cache-status
|
||||
variables:
|
||||
CARGO_HOME: "/cargo/${CI_JOB_NAME}"
|
||||
CARGO_HOME: "/ci-cache/parity-ethereum/cargo/${CI_JOB_NAME}"
|
||||
before_script:
|
||||
- SCCACHE_ERROR_LOG=/builds/parity/parity-ethereum/sccache_error.log RUST_LOG=sccache::server=debug sccache --start-server
|
||||
- sccache -s
|
||||
@@ -97,23 +97,24 @@ test-linux:
|
||||
|
||||
build-android:
|
||||
stage: build
|
||||
image: parity/rust-android:gitlab-ci
|
||||
image: parity/rust-parity-ethereum-android-build:stretch
|
||||
variables:
|
||||
CARGO_TARGET: armv7-linux-androideabi
|
||||
<<: *docker-cache-status
|
||||
<<: *collect_artifacts
|
||||
script:
|
||||
- scripts/gitlab/build-linux.sh
|
||||
tags:
|
||||
- linux-docker
|
||||
<<: *collect_artifacts
|
||||
|
||||
build-linux: &build-linux
|
||||
stage: build
|
||||
only: *releaseable_branches
|
||||
<<: *docker-cache-status
|
||||
<<: *collect_artifacts
|
||||
script:
|
||||
- scripts/gitlab/build-linux.sh
|
||||
- sccache -s
|
||||
<<: *collect_artifacts
|
||||
|
||||
build-linux-i386:
|
||||
<<: *build-linux
|
||||
@@ -136,6 +137,7 @@ build-linux-armhf:
|
||||
build-darwin:
|
||||
stage: build
|
||||
only: *releaseable_branches
|
||||
<<: *collect_artifacts
|
||||
variables:
|
||||
CARGO_TARGET: x86_64-apple-darwin
|
||||
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
|
||||
@@ -145,19 +147,19 @@ build-darwin:
|
||||
- scripts/gitlab/build-linux.sh
|
||||
tags:
|
||||
- rust-osx
|
||||
<<: *collect_artifacts
|
||||
|
||||
build-windows:
|
||||
stage: build
|
||||
<<: *collect_artifacts
|
||||
only: *releaseable_branches
|
||||
variables:
|
||||
CARGO_TARGET: x86_64-pc-windows-msvc
|
||||
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
|
||||
CARGO_HOME: "C:/ci-cache/parity-ethereum/cargo/$CI_JOB_NAME"
|
||||
GIT_SUBMODULE_STRATEGY: none
|
||||
script:
|
||||
- sh scripts/gitlab/build-windows.sh
|
||||
tags:
|
||||
- rust-windows
|
||||
<<: *collect_artifacts
|
||||
|
||||
publish-docker:
|
||||
stage: publish
|
||||
@@ -173,6 +175,7 @@ publish-docker:
|
||||
publish-snap: &publish-snap
|
||||
stage: publish
|
||||
only: *releaseable_branches
|
||||
<<: *collect_artifacts
|
||||
image: snapcore/snapcraft
|
||||
variables:
|
||||
BUILD_ARCH: amd64
|
||||
@@ -183,7 +186,6 @@ publish-snap: &publish-snap
|
||||
- linux-docker
|
||||
script:
|
||||
- scripts/gitlab/publish-snap.sh
|
||||
<<: *collect_artifacts
|
||||
|
||||
publish-snap-i386:
|
||||
<<: *publish-snap
|
||||
@@ -247,7 +249,7 @@ publish-awss3-release:
|
||||
|
||||
publish-docs:
|
||||
stage: publish
|
||||
# <<: *no_git
|
||||
image: parity/rust-parity-ethereum-docs:xenial
|
||||
only:
|
||||
- tags
|
||||
except:
|
||||
|
||||
647
Cargo.lock
generated
647
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity-ethereum"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "2.4.3"
|
||||
version = "2.4.5"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ name = "cli-signer"
|
||||
version = "1.4.0"
|
||||
|
||||
[dependencies]
|
||||
ethereum-types = "0.4"
|
||||
futures = "0.1"
|
||||
rpassword = "1.0"
|
||||
parity-rpc = { path = "../rpc" }
|
||||
|
||||
@@ -7,6 +7,7 @@ name = "parity-rpc-client"
|
||||
version = "1.4.0"
|
||||
|
||||
[dependencies]
|
||||
ethereum-types = "0.4"
|
||||
futures = "0.1"
|
||||
log = "0.4"
|
||||
serde = "1.0"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
pub mod client;
|
||||
pub mod signer_client;
|
||||
|
||||
extern crate ethereum_types;
|
||||
extern crate futures;
|
||||
extern crate jsonrpc_core;
|
||||
extern crate jsonrpc_ws_server as ws;
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
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_json::{Value as JsonValue, to_value};
|
||||
use std::path::PathBuf;
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
extern crate ethereum_types;
|
||||
extern crate futures;
|
||||
extern crate rpassword;
|
||||
|
||||
extern crate parity_rpc as rpc;
|
||||
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 std::io::{Write, BufRead, BufReader, stdout, stdin};
|
||||
use std::path::PathBuf;
|
||||
|
||||
@@ -7,7 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
common-types = { path = "../types" }
|
||||
error-chain = { version = "0.12", default-features = false }
|
||||
derive_more = "0.14.0"
|
||||
ethabi = "6.0"
|
||||
ethabi-contract = "6.0"
|
||||
ethabi-derive = "6.0"
|
||||
@@ -36,7 +36,7 @@ serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
tiny-keccak = "1.4"
|
||||
transaction-pool = "1.13.2"
|
||||
transaction-pool = "2.0"
|
||||
url = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -31,7 +31,7 @@ use crypto;
|
||||
use futures::Future;
|
||||
use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request};
|
||||
use bytes::{Bytes, ToPretty};
|
||||
use error::{Error, ErrorKind};
|
||||
use error::Error;
|
||||
use url::Url;
|
||||
use super::Signer;
|
||||
use super::key_server_keys::address_to_key;
|
||||
@@ -111,11 +111,11 @@ impl SecretStoreEncryptor {
|
||||
return Ok(key);
|
||||
}
|
||||
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
|
||||
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
|
||||
let url = format!("{}/{}/{}{}",
|
||||
@@ -132,16 +132,16 @@ impl SecretStoreEncryptor {
|
||||
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()
|
||||
.map_err(|e| ErrorKind::Encrypt(e.to_string()))?;
|
||||
.map_err(|e| Error::Encrypt(e.to_string()))?;
|
||||
|
||||
if response.is_not_found() {
|
||||
bail!(ErrorKind::EncryptionKeyNotFound(*contract_address));
|
||||
return Err(Error::EncryptionKeyNotFound(*contract_address));
|
||||
}
|
||||
|
||||
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
|
||||
@@ -149,7 +149,7 @@ impl SecretStoreEncryptor {
|
||||
BodyReader::new(response).read_to_string(&mut result)?;
|
||||
|
||||
// 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
|
||||
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> {
|
||||
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))?)
|
||||
}
|
||||
}
|
||||
@@ -204,7 +204,7 @@ impl Encryptor for SecretStoreEncryptor {
|
||||
// retrieve the key, try to generate it if it doesn't exist yet
|
||||
let key = match self.retrieve_key("", false, contract_address) {
|
||||
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);
|
||||
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());
|
||||
cypher.extend(repeat(0).take(plain_data.len()));
|
||||
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);
|
||||
|
||||
Ok(cypher)
|
||||
@@ -230,7 +230,7 @@ impl Encryptor for SecretStoreEncryptor {
|
||||
// initialization vector takes INIT_VEC_LEN bytes
|
||||
let cypher_len = cypher.len();
|
||||
if cypher_len < INIT_VEC_LEN {
|
||||
bail!(ErrorKind::Decrypt("Invalid cypher".into()));
|
||||
return Err(Error::Decrypt("Invalid cypher".into()));
|
||||
}
|
||||
|
||||
// retrieve existing key
|
||||
@@ -241,7 +241,7 @@ impl Encryptor for SecretStoreEncryptor {
|
||||
let mut plain_data = Vec::with_capacity(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)
|
||||
.map_err(|e| ErrorKind::Decrypt(e.to_string()))?;
|
||||
.map_err(|e| Error::Decrypt(e.to_string()))?;
|
||||
Ok(plain_data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
// 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::error;
|
||||
use derive_more::Display;
|
||||
use ethereum_types::Address;
|
||||
use rlp::DecoderError;
|
||||
use ethtrie::TrieError;
|
||||
@@ -21,173 +23,173 @@ use ethcore::error::{Error as EthcoreError, ExecutionError};
|
||||
use types::transaction::Error as TransactionError;
|
||||
use ethkey::Error as KeyError;
|
||||
use ethkey::crypto::Error as CryptoError;
|
||||
use txpool::Error as TxPoolError;
|
||||
use txpool::VerifiedTransaction;
|
||||
use private_transactions::VerifiedPrivateTransaction;
|
||||
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(::std::io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."];
|
||||
Decoder(DecoderError) #[doc = "RLP decoding error."];
|
||||
Trie(TrieError) #[doc = "Error concerning TrieDBs."];
|
||||
Txpool(TxPoolError) #[doc = "Tx pool error."];
|
||||
Crypto(CryptoError) #[doc = "Crypto error."];
|
||||
type TxPoolError = txpool::Error<<VerifiedPrivateTransaction as VerifiedTransaction>::Hash>;
|
||||
|
||||
#[derive(Debug, Display)]
|
||||
pub enum Error {
|
||||
/// Error concerning the Rust standard library's IO subsystem.
|
||||
#[display(fmt = "Io Error: {}", _0)]
|
||||
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 {
|
||||
#[doc = "Encryption error."]
|
||||
Encrypt(err: String) {
|
||||
description("Encryption error"),
|
||||
display("Encryption error. ({})", err),
|
||||
}
|
||||
impl From<String> for Error {
|
||||
fn from(s: String) -> Self {
|
||||
Error::Msg(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Decryption error."]
|
||||
Decrypt(err: String) {
|
||||
description("Decryption error"),
|
||||
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<std::io::Error> for Error {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
Error::Io(err).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeyError> for Error {
|
||||
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 {
|
||||
fn from(err: ExecutionError) -> Self {
|
||||
ErrorKind::Execution(err).into()
|
||||
Error::Execution(err).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionError> for Error {
|
||||
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 {
|
||||
fn from(err: EthcoreError) -> Self {
|
||||
ErrorKind::Ethcore(err).into()
|
||||
Error::Ethcore(err).into()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,8 +54,7 @@ extern crate log;
|
||||
extern crate ethabi_derive;
|
||||
#[macro_use]
|
||||
extern crate ethabi_contract;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate derive_more;
|
||||
#[macro_use]
|
||||
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 private_transactions::{VerifiedPrivateTransaction, VerificationStore, PrivateTransactionSigningDesc, SigningStore};
|
||||
pub use messages::{PrivateTransaction, SignedPrivateTransaction};
|
||||
pub use error::{Error, ErrorKind};
|
||||
pub use error::Error;
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::collections::{HashMap, HashSet, BTreeMap};
|
||||
@@ -238,10 +237,10 @@ impl Provider {
|
||||
trace!(target: "privatetx", "Creating private transaction from regular transaction: {:?}", signed_transaction);
|
||||
if self.signer_account.is_none() {
|
||||
warn!(target: "privatetx", "Signing account not set");
|
||||
bail!(ErrorKind::SignerAccountNotSet);
|
||||
return Err(Error::SignerAccountNotSet);
|
||||
}
|
||||
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 encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?;
|
||||
let private = PrivateTransaction::new(encrypted_transaction, contract);
|
||||
@@ -309,19 +308,19 @@ impl Provider {
|
||||
// TODO #9825 [ToDr] Usage of BlockId::Latest
|
||||
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest);
|
||||
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 private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction);
|
||||
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_hash = self.calculate_state_hash(&private_state, contract_nonce);
|
||||
trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash);
|
||||
let signed_state = self.accounts.sign(validator_account, private_state_hash);
|
||||
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_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None);
|
||||
@@ -362,25 +361,27 @@ impl Provider {
|
||||
signatures.push(signed_tx.signature());
|
||||
let rsv: Vec<Signature> = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect();
|
||||
// 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(
|
||||
desc.state.clone(),
|
||||
&desc.original_transaction,
|
||||
&rsv,
|
||||
desc.original_transaction.nonce,
|
||||
nonce,
|
||||
desc.original_transaction.gas_price
|
||||
)?;
|
||||
trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx);
|
||||
// Sign and add it to the queue
|
||||
let chain_id = desc.original_transaction.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 signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?;
|
||||
match self.miner.import_own_transaction(&*self.client, signed.into()) {
|
||||
Ok(_) => trace!(target: "privatetx", "Public transaction added to queue"),
|
||||
Err(err) => {
|
||||
warn!(target: "privatetx", "Failed to add transaction to queue, error: {:?}", err);
|
||||
bail!(err);
|
||||
return Err(err.into());
|
||||
}
|
||||
}
|
||||
// Notify about state changes
|
||||
@@ -395,7 +396,7 @@ impl Provider {
|
||||
// Remove from store for signing
|
||||
if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) {
|
||||
warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err);
|
||||
bail!(err);
|
||||
return Err(err);
|
||||
}
|
||||
} else {
|
||||
// Add signature to the store
|
||||
@@ -403,7 +404,7 @@ impl Provider {
|
||||
Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"),
|
||||
Err(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),
|
||||
_ => {
|
||||
warn!(target: "privatetx", "Incorrect type of action for the transaction");
|
||||
bail!(ErrorKind::BadTransactionType);
|
||||
return Err(Error::BadTransactionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -434,13 +435,13 @@ impl Provider {
|
||||
}
|
||||
false => {
|
||||
warn!(target: "privatetx", "Sender's state doesn't correspond to validator's");
|
||||
bail!(ErrorKind::StateIncorrect);
|
||||
return Err(Error::StateIncorrect);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(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> {
|
||||
let (data, decoder) = private_contract::functions::state::call();
|
||||
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)
|
||||
}
|
||||
|
||||
fn get_decrypted_code(&self, address: &Address, block: BlockId) -> Result<Bytes, Error> {
|
||||
let (data, decoder) = private_contract::functions::code::call();
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn get_contract_nonce(&self, address: &Address, block: BlockId) -> Result<U256, Error> {
|
||||
let (data, decoder) = private_contract::functions::nonce::call();
|
||||
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> {
|
||||
@@ -531,10 +532,10 @@ impl Provider {
|
||||
T: Tracer,
|
||||
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;
|
||||
|
||||
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
|
||||
let contract_address = match transaction.action {
|
||||
Action::Call(ref contract_address) => {
|
||||
@@ -610,15 +611,15 @@ impl Provider {
|
||||
/// 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> {
|
||||
if let Action::Call(_) = source.action {
|
||||
bail!(ErrorKind::BadTransactionType);
|
||||
return Err(Error::BadTransactionType);
|
||||
}
|
||||
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 executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?;
|
||||
let header = self.client.block_header(block)
|
||||
.ok_or(ErrorKind::StatePruned)
|
||||
.and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?;
|
||||
.ok_or(Error::StatePruned)
|
||||
.and_then(|h| h.decode().map_err(|_| Error::StateIncorrect).into())?;
|
||||
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 mut tx = Transaction {
|
||||
@@ -649,7 +650,7 @@ impl Provider {
|
||||
/// Create encrypted public contract deployment transaction. Returns updated encrypted state.
|
||||
pub fn execute_private_transaction(&self, block: BlockId, source: &SignedTransaction) -> Result<Bytes, Error> {
|
||||
if let Action::Create = source.action {
|
||||
bail!(ErrorKind::BadTransactionType);
|
||||
return Err(Error::BadTransactionType);
|
||||
}
|
||||
let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?;
|
||||
Ok(result.state)
|
||||
@@ -678,7 +679,7 @@ impl Provider {
|
||||
pub fn get_validators(&self, block: BlockId, address: &Address) -> Result<Vec<Address>, Error> {
|
||||
let (data, decoder) = private_contract::functions::get_validators::call();
|
||||
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 {
|
||||
|
||||
@@ -28,7 +28,7 @@ use parking_lot::RwLock;
|
||||
use types::transaction::{UnverifiedTransaction, SignedTransaction};
|
||||
use txpool;
|
||||
use txpool::{VerifiedTransaction, Verifier};
|
||||
use error::{Error, ErrorKind};
|
||||
use error::Error;
|
||||
|
||||
type Pool = txpool::Pool<VerifiedPrivateTransaction, pool::scoring::NonceAndGasPrice>;
|
||||
|
||||
@@ -154,7 +154,7 @@ impl Default for VerificationStore {
|
||||
|
||||
impl VerificationStore {
|
||||
/// 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,
|
||||
transaction: UnverifiedTransaction,
|
||||
validator_account: Option<Address>,
|
||||
@@ -164,7 +164,7 @@ impl VerificationStore {
|
||||
|
||||
let options = self.verification_options.clone();
|
||||
// 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 verified_tx = verifier.verify_transaction(unverified)?;
|
||||
let signed_tx: SignedTransaction = verified_tx.signed().clone();
|
||||
@@ -177,8 +177,9 @@ impl VerificationStore {
|
||||
transaction_hash: signed_hash,
|
||||
transaction_sender: signed_sender,
|
||||
};
|
||||
let mut pool = self.verification_pool.write();
|
||||
pool.import(verified)?;
|
||||
let replace = pool::replace::ReplaceByScoreAndReadiness::new(
|
||||
self.verification_pool.read().scoring().clone(), client);
|
||||
self.verification_pool.write().import(verified, &replace)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -228,7 +229,7 @@ impl SigningStore {
|
||||
contract_nonce: U256,
|
||||
) -> Result<(), Error> {
|
||||
if self.transactions.len() > MAX_QUEUE_LEN {
|
||||
bail!(ErrorKind::QueueIsFull);
|
||||
return Err(Error::QueueIsFull);
|
||||
}
|
||||
|
||||
self.transactions.insert(private_hash, PrivateTransactionSigningDesc {
|
||||
@@ -254,7 +255,7 @@ impl SigningStore {
|
||||
|
||||
/// Adds received signature for the stored private transaction
|
||||
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) {
|
||||
desc.received_signatures.push(signature);
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f90210a08eb792fdb134b57fffbdf19bd61d4c1cc351fc38a7fcf6609c82b35ea364208fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794df7d7e053933b5cc24372f878c90e62dadad5d42a0e29a2e741354b453139d244920f7d552f90a579f1dcb99ef6b470bcffc713ebaa04bb64c992b8cf56259177a192d6f0a1eddf192b8daa7dbf1ec8313428cccde20a0ee22efe3b124a0297503fd26e6f7b33c7a88aa75825259297f8e30bee3632a68b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000866a396ffc14908373480183797a1182f618845c7395609165746865726d696e652d6574632d757331a087f3616cc0ba3704e23702bf7461f8f7716f1f1ad3ac4c66391d45adc57d1dea886ecb8e800fe87049",
|
||||
"totalDifficulty": "575603227549295900024",
|
||||
"header": "f9021ba0a281d23475d3d5ff03df8636c9f528cdd91498af274a3b2f8989bbd51bfeb809a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794004730417cd2b1d19f6be2679906ded4fa8a64e2a0d5fdd62e7e29dc3da1cd3fe5ad549e000260bfdb55f523fde008f26390220d23a0370ff78457d6c7469ff333a13165f4bb8057d00cfa68365cb4d1a8c8a1da46d5a0dea37365a20f5bb5ad3766a24a9fe7b04b946e35aaba74f862467a7c5cdb7d67b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000004000000000040000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000100000000000000000000000080000000000000000020000000000000000000000000000000000000000000000000000000000000000000000020000000000001000000000000000000000000000000080010000000000000008000000000000000866fc181925a9783763801837a121d830c317c845c9d1efe9b457468657265756d436c6173736963534f4c4f2f326d696e657273a0bb6e626c7ee3d827da18e1b303d9552ba17e92cefcedfc58bdfc5bac6a8ebabe882d8c26402344c24b",
|
||||
"totalDifficulty": "598584828374329723203",
|
||||
"CHTs": [
|
||||
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
|
||||
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
|
||||
@@ -3739,7 +3739,101 @@
|
||||
"0x362ca494021482f0d9dea4abd844ca11b71fbeb0a98e7db7bfb3bb6f864eb58c",
|
||||
"0x09ec27c856f50888e4634ffaca66f8185fd13e0bb2bbf522ce6209886502c7a5",
|
||||
"0x24996d2f96618887c1c5e61d5d7ce6948853ca35811d48f72155a4778308e255",
|
||||
"0x4f199a8efc8615c623902b5c279dd995ac1df4654a07aab0423e070d14bd24d0"
|
||||
"0x4f199a8efc8615c623902b5c279dd995ac1df4654a07aab0423e070d14bd24d0",
|
||||
"0xe6875990cef0d2ce1f9d100654cdf522bbe345a462ebca769b1e288128c13201",
|
||||
"0x36c141d47991e557f7226d8b1fe791c334f046f867d7865d663f99e2a337d915",
|
||||
"0x337e59da56cde8e3f9e90fafff54d4fa240ba01aec855fd55626e4b3a45a9767",
|
||||
"0x67672d3a29c49e3545d25422b6015a1eebe86596f55d4c9b8772e89c99ac9f8b",
|
||||
"0x6d6e167641bcd2e5241ac2710951f7f0c47fb311e32e998831e6fe38f5bebb25",
|
||||
"0x6dc4fa5ae3f281a90619216491284d951151f37be648694d1952314f43ffe05d",
|
||||
"0x3c865ccee7900b39d671c43ae15df71fad294781d74815537de94d02b48dd8a0",
|
||||
"0x10ba37d2ff46db181ff8a15f38bfeecfd9c21e28bf63cb5ab975a2d7c74c0aef",
|
||||
"0xba265a598f3af5bf4c2b87bd8d28a55f963cfbd09108aaccd5b00294f662e8b9",
|
||||
"0xaab422eb98f7b0ab9a01558069a3666efa2be2510097b0054bd5c8fceb1023df",
|
||||
"0xdbff3ce1e6fb0388029f95bd091c95b88c6539fabfe6f1de8e44c47dab064ff8",
|
||||
"0xb1aa0c7254f3aaa61b58c9d973f3d89f5f4dc6bfee011ad4c4a3e3ae76aaf7df",
|
||||
"0x055e36325029db9e089808ca01b0ee3eae53703f3e91ee51e587e7b7dcaa8a3d",
|
||||
"0x00ec5a25517cf0c0a1bf892e5209fd0185ff1ffc6b2523642bf86f6a3d0c10f3",
|
||||
"0x7bc6a8d5017760f12ace9ebfcdf5a91abcfd6e4f4131df5c4dbe84d2d6a6add9",
|
||||
"0xeb5da64c8d0cc93a44da96ee9c3c0a22054a2a2e87a7491a5618ade1f59a1b96",
|
||||
"0xc0a937729678bb6aca27ae16c662ccd2dd0b53346c610d6e5d5b1655762fa4b3",
|
||||
"0x55c732917d3894ffeb9844fcb1c690d0956c4e2a8eccb6552cdde4ea90c99db2",
|
||||
"0xf1dfd2205daf748da9e8e98bc4ee94cd6b2db5560e4cead28910e14c576337aa",
|
||||
"0x60a271fb20c017f90d99c57783ebb8b1a3233398c49f89d73db14b09adf2893b",
|
||||
"0x8fbd97d55dc64f2124c79054765515f49d79a05f2962b17875f12b353c33f564",
|
||||
"0x5afd5951c5e834fbf22071047f72619496e9a9dbc6073b661c44741b67fabf03",
|
||||
"0x2d05a19223820f92e385d2c942b70cca32804546f3aa7058381ca3f6c1ecde11",
|
||||
"0x267dab323804f2e7bdcc80dde83ccbff56d1aa0fffd0edc7c02ffd4a24bbe027",
|
||||
"0xf4e9e580bbcc5a9be1f942c12d4b34eb1a4c07feffd0b95abe27ddff57a6cc8f",
|
||||
"0x3f146ceffcd100ca9fc1af743fad74acd03a289f4038413acfcfd0eb87d14a56",
|
||||
"0xef98171ed6b269c0ebd6bdbb1d98694316b639bae6a3ad01f4964c3d2eb3d2cf",
|
||||
"0x510013a35d5c71863b3385176c794ad90e17af1fd271b933f9f7ab980311b27c",
|
||||
"0x5eb181d22f30ed203c4d3fad610d31c2338dae6a88eee250af19ae0f58319ad1",
|
||||
"0x50a28d65b51ff086dcf2110feca7d990db95f078394c56bfb850a3b8cfd7f1a2",
|
||||
"0x4148b8f2136b84773b7ff71d73aa8ffb98f0f3952939849f324c28b9173efd70",
|
||||
"0xa980bc7fa736bf6d6d794ffa5e035664c45117c21e40da7ba76de7c2ff8164d0",
|
||||
"0x794a8ef17e48986df700d6e68799a50695086702d6224ae9a71663fd03f8a55e",
|
||||
"0xf354c82e1c75d7d758099dcd4d0592363eef81e85cba773aa6d6b30e1900582a",
|
||||
"0xbb4c8b990add1c4e43ddebf742eb605028ae2daa8b61db7d237386d81e4c3413",
|
||||
"0x61470a53ef9757fa7c452bdbe26d448dd8bf6590fc11420ebeddf441fe56f381",
|
||||
"0x603558b2f72405e9625ac561d62c2bbcdda84d8ef4b5510d06bdac0553025bf2",
|
||||
"0xf52d9ba6ba149d0e4266a8d05b73e4a445e9583560024e0185d4b8b12bd55640",
|
||||
"0x26ef211f77b4a67ddb0a24c4e63f7d247d6ce8635dd9862894bdc067633ff395",
|
||||
"0xed4ce5eb08b63534c5de241513a996322d168f6b8bf5c75167e79dd7ca1cc817",
|
||||
"0x9d5f39f494a36d17db609b7a7a62734ca7222426c3556132bf1e2241d6c45cd2",
|
||||
"0xe664772da4521e1140cc2c5db744010f57c15374dfb78a97701904787846a8f6",
|
||||
"0x93faea0d197923b1578ac190fe608203f637fe4991ad4954c15ea94e17ee948b",
|
||||
"0x2b028c1aaae5217cabb97c46c20541c93e55a868f78e82740f9fb9a0a033d662",
|
||||
"0x529103419484990ad11c05e0c4c696826f67fbcd491e19aaac461cc340747ec4",
|
||||
"0xc1e773415513b7bf47340d7b0a29e5d49d1a88bb3d0ee2a79726169d32012378",
|
||||
"0xf97c43bb4ae25524b180e59cb6cac75858d4a8a0772fcf4f3bd24dfad42169da",
|
||||
"0x19fa7ad12455fd022cfd15897d553e031ca1adf80c963c770250d36f1810a5f0",
|
||||
"0xe67ce6e2444b8318a01150952a537ee47b701555c79f60eb90d3c3cdf93fb6b1",
|
||||
"0x1b49d232180b0922704ebd4e9fabca5dd8ae9cfc2a39ea07226ba903a15037e3",
|
||||
"0x56540b02ffe1743468342b5664b6e51cb3ef6c48dd74d6cd74e0c0c513c13129",
|
||||
"0xd4d9d67f352c7f54d68ce994b3765b032108a5bd0b5b62d14b893949b96008d4",
|
||||
"0x44d1b765df81594fd37e7700019f19b1ebd6d9b50631455931b83ce35238cb6b",
|
||||
"0x2b67aef7cecfec055853cd63e8519bf506d7a1ae69a768e4db9415bdff532c47",
|
||||
"0xc30ac2a4acc33cec2cdc83e114fb8237c4900a2fc89dddb6af3a4dd5e4868e51",
|
||||
"0xe0e7127e086e2011f30fcd0469b35769cae163acb8ee6db8a8e2c032c2b351c5",
|
||||
"0xb46c428070d15ec926fdf1d7465a9168c56dbb959d5391e26480500a98e36047",
|
||||
"0x8dab41ce167633da3c0b5332833dfad5d2c28ef30c94973e5f4647e312781676",
|
||||
"0xc632d30657b39208c254cf4f899d00d7c3196cbdc31248798a760972bf399fec",
|
||||
"0xb4eb2c6c656406a9bc6cc6176dbdfc0e878046530d830a51e04a4e22c4572370",
|
||||
"0xadb48a02c9c87b246360edb45528ba23cceed736a2ee0cfd03177428e6243024",
|
||||
"0x443ac2e63e6d629398e607d6689725dd68fd5254916c1b76c876885456a13338",
|
||||
"0xb66c4d950a9304025654de37c7d0e9759b755d86226a816d1e3b4c7d654a1bc3",
|
||||
"0xded624610c3493bc7806844342c37909c1c1d179025c215108a12a0428ae9e36",
|
||||
"0x28c85177961714ce796f152dcd31c8b19db1c39deebfe383d6fdf2334d4261b6",
|
||||
"0x6d342534c3a4a875c5455ed3ef546e876cedb5aee7b2ecf194c6e47c6a09d3a4",
|
||||
"0x65a84879e014085b7a0de5bf604050bc6bffd8ab7748253203fff49573763558",
|
||||
"0xcb0e4339dfbfc8b420c915149a0d352fda69c31668b32452c432f067462b4325",
|
||||
"0x3466440e4c88895f2642f2986dea4be482c028592530224d73e67254b2bac69f",
|
||||
"0xb7c325fec25c7b278724ebb91c64fc2ac37e91e44b136dd6c29bf48b80990888",
|
||||
"0x7a9a2bd3ab5972c1a4ec5972f959a1e30eb678090ed76947e38d76fc3ed758a5",
|
||||
"0x74deabf896026cb20e2f5f8a88828b265d6696883dab972fe1bc9a4ca98d68b5",
|
||||
"0x195d2e25b1ec8deea095bcbaac5277f4586237e68bd9c9ad24e65a8e53d6d27a",
|
||||
"0xcc343c21f7f18c1d507cc3cf12381d7bbe55d7355363361d05d972343fb4b7fe",
|
||||
"0xd2637aaef2034203e549453225eb1d75633d2c66e8cad0419395250c1e369536",
|
||||
"0x0f8052a87aa435deee2826e6dbc944128835264d5770dbb064373de05333f8c2",
|
||||
"0x2091278a3d6a7ed1ab0458cc307903a51d75c6a1c549ebed1f0aed29ce6533b8",
|
||||
"0x3f7d25feee0dcf39372ccbad55989442d9b7ce16ac93e4b1dca63bd92d5204e4",
|
||||
"0xd0f866c38597038e360af960e3e84c79a0027576bf3fdf4358a9442f0c671b61",
|
||||
"0xc527b3694dc6b46f0562cb36e2f766e5b75793ad2794258d8be5119bff4ea8b0",
|
||||
"0x47f1d7d32904cb0945e97140c2412d12b1e0980c2f72c7878250170aae4124dd",
|
||||
"0x57aa1ef2a7ec01ee7acd0c4baed5407f30d6c34f2bc6bce7fda6366517343199",
|
||||
"0xd392127f856736dd74d16a24309a247682e2736f78fc92713c484a6f13edcdbf",
|
||||
"0x595aa7e3eddba867389d63b2eaa6b16e4e5163076f03d2c8013e40c3b0fc98c0",
|
||||
"0x50bb320d8bea03db548be3a3b619159e1993ba8eea83af6f022b9cd29ae4d0ff",
|
||||
"0x53deeb64ee923912f76a233532f474d76d8f6b8cc42eedcce81bda8ad608294c",
|
||||
"0x1af301b0eaf36d16a74b2d1f76e9e26659f047cd3466a765049260047c25bbee",
|
||||
"0x05c1d40227ece15c55f06dc922f5a9be01cc147a96e070e7a81b696f0f40b6ee",
|
||||
"0xa63ee877c70d8e51e795d153a34ce3bcc212f8fb8e77df52ff83084b9133a280",
|
||||
"0x07ab3e2107db7ff479f5be0d7a57e3b76627cf6230cdeb61d78ebaa2c391d360",
|
||||
"0xc893aee6d249c152f5db3d7763f34a3311345dff721ae9c71ab5fb3d2b3e2559",
|
||||
"0x250caa98ea3e682be9c866990f19647f443d57690052229ac0ccfa0ab30a5a71",
|
||||
"0xc32fd5318214071a41cd8e98499b2b65942c5837c686a06b536146fd0bf294bf",
|
||||
"0xac390c012eecd83fa8f4cc77a59992914b5c95af36b28747e07adea13228acbc"
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"name": "Easthub",
|
||||
"dataDir": "easthub",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x2B5E3AF16B1880000",
|
||||
"homesteadTransition": "0x0",
|
||||
"bombDefuseTransition": "0x0",
|
||||
"ecip1017EraRounds": 5000000
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"registrar": "0x0000000000000000000000000000000000000000",
|
||||
"accountStartNonce": "0x00",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID": "0x7",
|
||||
"chainID": "0x7",
|
||||
"eip150Transition": "0x0",
|
||||
"eip160Transition": "0x0",
|
||||
"eip155Transition": "0x0",
|
||||
"eip161abcTransition": "0x7fffffffffffffff",
|
||||
"eip161dTransition": "0x7fffffffffffffff"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x0400000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x323031382045617374636f696e2050726f6a656374",
|
||||
"gasLimit": "0x1388"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://ca57e40edb95a08a81b85a91e91099a0aaab777ad329ea7f3f772bc0fd511a276a5d84944725d181ff80f8c7dc1034814bff25b9723b03363d48617fed4b15f0@13.125.109.174:30303",
|
||||
"enode://57254e23a7e5fe1e081ee5d1b236e37735a120660daeb4bf1fec6943a82c915c5b6fad23eeb1a43a27c23f236e084e8051aaa28f7d4139149f844747facb62bb@18.217.39.51:30303",
|
||||
"enode://ef248f327c73c0318f4d51a62270b0612f3c4a4fd04b77d04854dc355980e137708d1e48811bc91387b0d7eb85cf447d8bbc095404f39bb7064e76751bda9cd4@52.221.160.236:30303",
|
||||
"enode://bf6f0e37dd733cf04f2b079c753d2dea7cc7c59d8637eff9a8e63e17d08e2bfc91229fbb2dff08fe6ee12e51c1b6f8ed969d7042b89d77029e7ea02b05e17be3@18.197.47.177:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"20c1252a8cb33a7a9a257b2a4cfeed8daf87c847": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"9dcd37c8e5aea3a0d37c5d0a2db683362d81febd": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"9eff080302333f44a60bfd8c33bd63015c6d921b": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"c1df2e5de98d5c41fec0642dc302971f5d3500bd": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"2e0fb67cd1d029cbaea4b74c361efcc06b3105fd": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"2b6425cc3cd90654f077889ef7262ac2f5846460": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"28562041230c6d575e233e4ed1b35c514884d964": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"16eb6896a5a83d39ac762d79d21f825f5f980d12": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"f09e3f1de27dd03a1ac0a021b2d9e45bde1b360c": {
|
||||
"balance": "100000000000000000000000000"
|
||||
},
|
||||
"2d87547819c6433f208ee3096161cdb2835a2333": {
|
||||
"balance": "100000000000000000000000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,8 +181,8 @@
|
||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f90215a0ea51746efaaede944c3397e41ae72b7908c8ce25967c1edcd02618b068486feba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794829bd824b016326a401d083b33d092293333a830a0aee38c1032f191c3d42cc581f53d31adb1f0d91f463e6a8c12fc35fd1db58d5aa0568149713d45e959d5d07624917617d0d7865124c25c28eb9b798013096ddeafa0847bb20a0b62d1d8e2b467c33b28ded6796c556cd2b2a169b640b40e58fd2340b9010048c03883204a1ef0204300012248c8841814900c04362858000450c8927a22a88d5b471c4869c00001d8641080695910c20801022c2910408829a8002620115dc8200ec2851300611284301c3243e091030706068c8160505403250d03f44437410080072a69048082b43070805d08424a021328221500101418463040904ca094a189c801e50000c41402603426c4701a6302e1023040080d8380e21d600a2083003a2604082001b183068d1470840a49008a514148800a08030a8002c821b24010f20ea31c55060582801c14483ec29d4081c7152d2244840016c123da6f42249b6002c8401618a0000a8c8df892954d8080800c160244453086480d8264b6870ae8321581e6cb836ed001837a30a08379e5a2845c72b9c0947070796520e4b883e5bda9e7a59ee4bb99e9b1bca06883c088b374f7c667ed0fda0f1ec7c18890c892b88f14b41f03e7d927bcca82880db92c004f0313a8",
|
||||
"totalDifficulty": "9242028122621986440675",
|
||||
"header": "f90212a0113ba3b1153987fc483b01ccfe9ecadbdc36a7b264be75d6486cb6b694cc38a1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a0d91db5900e312a1ba8d39505406a95dc0ea20393b723c4bf488ade4e3c4ee4c3a05e63ab076852043b1c2fe010e2f14ab13dcc8e1c546ac497a24ce88c4abf3056a0b72e4a776f895459b6bf0937040990d868b1f45889aeaa26684e07472263fc31b90100b00200000063664554889124822ce2001022840543085d5810042382888542ca3816801780384384cd6851081cdc4d4b2b205a814b049198110a6869d60f4009a79c3854c9000581044889080000611c09142200106552000044027024004038092102814ed6c48040a8715851088a20108e80165f8c0c514019037a0000121304b2343416800b029000024404248238a06818414cb8690244879491855405026bc8250220520992c2380099d10024411c6048424083d1307822442d8444700405147883c4c041300aaa2408bb61084012983825a22830040a180106b5e27182088060b111515832902903a8f1d432a48004d0250437106a503491000048a91587067a897789f4d78371d801837a309c8379ffd7845c9d879e9150505945206e616e6f706f6f6c2e6f7267a0db22736cb3f06f9c86804902731fa6841eaaa1cd6326ea2a30e9c304d48bdd04880323b06837344cb8",
|
||||
"totalDifficulty": "9633968582330911261986",
|
||||
"CHTs": [
|
||||
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
|
||||
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
|
||||
@@ -3729,7 +3729,104 @@
|
||||
"0x8ed199e2fd654bfc9dfd5e7ea7dc82bea9f4535eb480c95984a5a6bc1533bf8e",
|
||||
"0x4e5475dae57c548460d4ddd15583223bf2a4a2046c2ee56ca670892794a37d90",
|
||||
"0x80409971b3e59ec71deb1a158a92ab6fe8318cb9adebcf583586e23e42d370c4",
|
||||
"0xeb35d7c78965874110f67b77307deae4bb29dc98c01fbac3737409ede61df7c6"
|
||||
"0xeb35d7c78965874110f67b77307deae4bb29dc98c01fbac3737409ede61df7c6",
|
||||
"0xd358b672db99b007ac54ef3ea7c77c0eb0b4e9cc1437ca4eb70d71aaaf84b6f2",
|
||||
"0x0ca4c79c1709b947794ae73dd3b73b357273c4e5cfc83ec85c4c2b649e10740f",
|
||||
"0x704635b2335b5ad2be0e586e60770dc1e0548794ee2c1670cbfbc2ed0c1f64ae",
|
||||
"0x6a6f2425c865216b49e7e73026fd2e9cc02f131c0050ce849f274c37828909f0",
|
||||
"0xce31e62ac098db0fef0823941009b826d4e5b8e11f2e01208ee6abccb160c0cc",
|
||||
"0x5669c0e6ccaa8abff08e944fe8bdcf0001dce9c10ef8b90d7f821819e028dcb6",
|
||||
"0x37b59281d4eec501ed45d68c2bfac450d336ee5a18ecb7d2d812763d2cfd4321",
|
||||
"0xfb52f084a5ffd63001f47acdb2ea62e91714af63f896c151100350d83bd2c7e4",
|
||||
"0x67bfc4a94fde6e81b54ebe52914c0d73a053bbac22d6d64862e987e53c78ed61",
|
||||
"0x49c141a8ac1124f40d06c569f49363a8af092d0028b02d8f4c895af2f86d0f28",
|
||||
"0x5c81c85021692d5dd1bdbd3a4543ec86d49e674380a0e5f59d4400902d7e753b",
|
||||
"0x9b46d19b0cee63461453a487bbf855fb4a7d70933ce2b7445d1dce8dbbc11cf9",
|
||||
"0x50fe5cb0ddf34ed2ee8341848bc00df89fda05fbf0ebb1b34d12afe9e5ae4d1a",
|
||||
"0xd56b4c4880798175c2db50c5c5d6845b5c1e7b6b33172ba107f5de075ed09def",
|
||||
"0xe0928a4092e5ab5b9a34a8748c3ddf86a6a9ab50e85777c4e1e8088ac7b44ae7",
|
||||
"0xfcde6d53ff8286afecafa27d608e94c07a4d78813edeccb73a1076772d1f7e83",
|
||||
"0x1bff0dc76b0d8877a9ea133a023a5dc0f88559f16f0adffbf7b4d58b6be487a1",
|
||||
"0x5252a71f6c9784b538ecd810bded0520f349f5aa748657a9b4422474eee08388",
|
||||
"0xc4cccd5ae51babfe8e9f76af2c64227b0fd63bc2f4336b7820a32846516d9835",
|
||||
"0xd07bc360f06a492a13047247448ba37fc9a167bd81ee63607976be269d245e14",
|
||||
"0x9499022a6b509dd05eae2a7c799c332382b810843065e82ec72891b771cc3a8a",
|
||||
"0x0ba258fb2666908035e53ec37a96ee13719779de43f14a57223b704961ef667a",
|
||||
"0x4dec79cac5e3b414aa835c69bb2c580ccc03eaed675b61070f37b606ff4715bd",
|
||||
"0xac640ffa67870bd91b1ff36450256fb1e5f59e65f4ef844875185c38f7f986b5",
|
||||
"0x0af93eccdfbb75dc353ff31949329b3c96ffa93f63e9ae4a515f6e177e201d35",
|
||||
"0x5a2d5ba9defce6db1bff0bbbe4eee170fe3b9c0ecb4a1ec6e16f904b55c07beb",
|
||||
"0xd92f1c26de95255b1e0926341c35b5bfd106820dbdcb381400516d247062f3fd",
|
||||
"0x447ec0cf1a32e8201cb92d0ad13adc6e664a07612bf38ce9c598c799cd947fb1",
|
||||
"0x28460192df35aec41fe3992efc94da904d69e4b65e518fd2c530b38c1ec88819",
|
||||
"0x6b0557132b0efe568a96f77fad4f1e18cf05670c007488052f347cf3461ee98c",
|
||||
"0xb82f3f400a0edc100ddd6e82c2ea587eb5d56ea0f8faa379f8fa259f31ea0838",
|
||||
"0x370b650e0bd14d9e5d749f628fca91ff47184473b6cba948e9ad3492a68bed5e",
|
||||
"0x794e423feca451babc044923a79ceab62ff3a9a7e8947dcadd0d91f78a11cff6",
|
||||
"0x7fe410432bfc7048e6685eb6bf0b4ae9808864a2e09ed1d373dc211f40c59da7",
|
||||
"0x9f53d260f145de7b48c04829abd97989bc11d748af7d119ebf56948ca438913a",
|
||||
"0xad5ad5cd5ff452e16c07bba12f0b34bb1c3c8c33d54db45b515cf6761d6a1cc8",
|
||||
"0xcc6e322ea2c52af09d720524c85629019eac5ca01dcec5da887ad4b32157b9e4",
|
||||
"0x5d3ddb9fa275898453e8430b26270e2812709717898683f0a3291291b29d688a",
|
||||
"0xeff621bef47694a862a320a661b691b491e4a5c44e1d2026c9756f84903a6375",
|
||||
"0x110e7059d20e4531323dcf981ad6cb9d67d56815c54394ab1b0b7af4235aa218",
|
||||
"0xe44d27931b9429204cd2e9cba838f0ed707d5668ab55ecf2c906b2748fa1f16d",
|
||||
"0x9d7166683764cde8445c58697df637cd48e35b3ad00f6e6d4bbf12844ba217c5",
|
||||
"0xf5f6625754100a91cd7283d47e72cca73c39e5fa2e0405d427430bccd49cc2bb",
|
||||
"0xd6b27ee81a557ff5d8947225c19f3ba023af18415a413acdf438548b24902427",
|
||||
"0xccc665895dbabf0d8775c5fddf167b41579b0e6bff8fe99c8da00622334c8861",
|
||||
"0x1986e5fd526af0a0e74ab83cb82c18dbd5a73fe72b94c8ca10318f8f6bd2d98a",
|
||||
"0xd3f245d6f37b0c47506fc4a2b12d85ff87eb35c2f45f82c3e5bebdc7362d8cd6",
|
||||
"0x53b97494c77ef9a843ce61b2a58231bc145b492b710fc3dcf79c297187993bbf",
|
||||
"0x00d4cd1f9460a8625ed0a539257e58a9ab8051ff239172f0a9437cb9f0d1a11f",
|
||||
"0x1c3d92f1e67b04c24db2eb04184ca7ccd5533540aca4dcbe084a70648c347ee5",
|
||||
"0x200e39cb704bcda42f547c0cae54c0dd4c0b1aaf17469d69deaa67d3ef0d95c5",
|
||||
"0x5aa208366dc50c2e9f0075b0e8aad396851f54a42c9ec1114c2994da0c2fcace",
|
||||
"0xbea70811c324fb1553c4fc492521ce062756da0a469d8f98cd6c0f7a3a7b5e3a",
|
||||
"0x79aa191ef9975049a5f2b8b7e2921a3f78d045b99b7a569a93680c5ee2600a18",
|
||||
"0x233fd477509141aed423948a0c5c5b8f0ab8cc3c4836c0f44c8cd6c0811b419c",
|
||||
"0x1737e144530678804416cd7c3c8200f54f395bf7712c9ade8340988e1e123af5",
|
||||
"0xbdad2ae32cbfc13446adfe9e4101f32fb52b1e336c165a1125c917d6c1a1fceb",
|
||||
"0xc20dedeedd63be4c10d92d9d0e7b47e20d503f331cb31d47ec9e99b915305ba0",
|
||||
"0x262281f50e2892d8cfca3b8f8a6645b5931fb4601755f02fb863d719cd690381",
|
||||
"0xb0a717f11ff1e3f1a4bd775792c7e5a75af6e56967ab1615be6b4941ca9315e3",
|
||||
"0xe8f45b1aee0fb0e87148b316ee0ce662ae3bb2abd05e9666429fcf30893641b1",
|
||||
"0xe7a439e2577c4f892921f798efa19353d236146b849c20253b07f03194b36286",
|
||||
"0xf4eda704d4864d8fccefecc246fb683dbdeee5468a53dd11d71d71477d170422",
|
||||
"0x308d977f739b7a8cb4810242fb447a8f6cad45389a127f5822ca2df48fa9df86",
|
||||
"0x3115d6d0f174e00bf3e5704f57e44b62f7e279894ce62f39568ffe4367fc5a44",
|
||||
"0x6b6e6354b8d1e1ab0430fe2a5068b2b2263ff453676dbfdce5da60a6d625f20f",
|
||||
"0x9b8a7b122572f459d946e67a1c78973040bcf67a64327f689d4016c53afcc4cf",
|
||||
"0xa367c0bc2e6029afec518db94fa79288801f5ebf2cba50980fc9754a40784d19",
|
||||
"0xc1a017142eac944b5fda4cd66a9b6b6dc64551c3ce958e8811797433b96ec5d8",
|
||||
"0xc9e3999a3f162d42ae52644ce4f765b5ccc7fe2a4c91cc59048eeb8c8086718e",
|
||||
"0x67c135523c9703aa1f1b653d9279804af4cd81cd3de99e10a853b42d78143914",
|
||||
"0x9af2390bb01b245c65f76454f1c80102871131417cc8fbff4b1ada056d04dd47",
|
||||
"0xf4cec7d4f4a76c769021ab0dab848d668fd36e910259e45094d88defabd13448",
|
||||
"0xe2a224fd4510ac5f8a6782d2eed14ee164e6bb92d3f0a7e5e71497046fe9f30c",
|
||||
"0x9884ca2b5533c36e03fecf28470fd3c45292dc623fb220c5eb0a580781fbe724",
|
||||
"0x078b1365c5dc77fdea6bb010fab6c4dede06e27386d4d5f205bf7e7857b03865",
|
||||
"0x8f930fa645409fc1d7fb28637360489a5e5eaa6554857441c3fd8990243d9972",
|
||||
"0x2e21ac485ed90007e8b69cf247c28b25361729bcc7501a3296f9c06dd0742888",
|
||||
"0x46c3ea9e86ad55d87b6f5d50fd9c145bcb6ca90a4d570c1f86b5532b0762d8c0",
|
||||
"0x87edc87f5ac353d64b0f157ce3e3180ce73fdd1f0ae9db1406e49581f1780de7",
|
||||
"0xc940108991c82f871c3eea33ec93951c9bc33cd0aba1c77262cb6fc6ea16f4eb",
|
||||
"0xba2f1d37cebd9bcde635bee4c0f260af8fddb43a84508f244b562dd1f7bdbe92",
|
||||
"0x738e8d02870cf37ba27db2eb621d5f7b32a225010de41e3983ed389ebaa0e364",
|
||||
"0x84af8e6e7ceb53e068bdf16091bfe966458bb5d3e4a925360411a213aaf46a5c",
|
||||
"0x548302ac8a0af1ef5bb91d469f66f8669cdb2a07c432e7504a806e00487adb63",
|
||||
"0x35bc3a284170d090e6fe053d3bd2a8fc3aa299d113b69b90340ca4c7e019016d",
|
||||
"0xfe7b61c4388f2615642f9ffb44279f31a98c0f0d2f3f37b5f77ba09a67c12737",
|
||||
"0x864581a4e526055847c252f6169bc54b5a1615de8e1cb7e80c649315b04a9aab",
|
||||
"0xb8b4c67301cf9d3e91ae59a0394c8085737358bde297c58688b48a9d33c04205",
|
||||
"0xa1ee0d1c7d50d37f96505ed06b166722f47fdd784b71bb3d47539ae40be96262",
|
||||
"0x63b2658609397ec6a9e9d9d0a5b318b79b1e39348606ca53e0f84f6466d3aad4",
|
||||
"0x2211abc4f8bbd6784aa191805465b10520a6c505d6257063aa9b911d5781fb89",
|
||||
"0xefed35d1327328deece22922f08d3c3931c80c1ea9a8bc719b8226f38823bb6d",
|
||||
"0x64b862e2d5a6c24d569f3352b8524ebfecfd5a3205a3200ec78df72d79a66838",
|
||||
"0x6da8edf169a9c78307258a723c1ac1d96db20a7131018efad16f0606683c0f07",
|
||||
"0xbae1427beab8c3e71cea57e5f9cdd55bc278c6d6073ae2628f0d3efbf9894a42",
|
||||
"0x389bbd1b3fa390e8d3339cf5b018ec64d9cfc02bbcb801acad0857fe377ed83b"
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
"gasLimit": "0x5B8D80"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f90247a03dc1f4ed47c057717131ce81535d06194d990be6969334e9b8034e0c875f9dffa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940010f94b296a852aaac52ea6c5ac72e03afd032da0fd1833e970c207ca16e1e74d937c9d8e01a1f719643fb25963028427295fc2cca00d9d5e376ebe3558b412402702d34a93256bb03a61df9f17ae234f0a70f95b20a0129c38f28acd251820f96305d217511a725a1fae1a434d77034bd7efef1f9f5ab901000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000080000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffa839f3801837a1200834bb5f3845c7361249fde8302020a8f5061726974792d457468657265756d86312e33322e30826c6984171cd849b841d077cf579661ac8634ee865b5cc67918223aed686d6ba189624a6f6c0dfc5249418b25423e30e072a79d5377e01845d5234ff5e0b9b0207b1bf2515f805b47e300",
|
||||
"totalDifficulty": "3500253997070921577369506418666760871805116639",
|
||||
"header": "f90247a0d0c0f490e8e5045fa96fd77ce45ed983900feaab964b2b0ba3a2d3a6b5e0f842a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400d6cc1ba9cf89bd2e58009741f4f7325badc0eda0c91e59c81193c4fead4f64ecaa349e97056409dfbb787772ea3c1e55e7582b2ea08be1332f5e7eac286c7e5e5ccf3760e47f4a919548c15e748ad4351bb8405f9aa054e0533aa3433f4d07afa226230c867fc1e2844b5f49b25aba8df17630d9f8c8b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe83a26801837a12008306f78d845c9da0b09fde830203088f5061726974792d457468657265756d86312e33332e30827769841727682cb841d6db93a25c84287603ee26e48db0dd301753840cc7283d411d3febd0485e02b2520086bebfb3aec1ab69403f45f0d59249bf0d458f33aa268dc4badefc73c8d300",
|
||||
"totalDifficulty": "3571337622391237938633151520660827524104528124",
|
||||
"CHTs": [
|
||||
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
|
||||
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
|
||||
@@ -5161,7 +5161,109 @@
|
||||
"0x7ba1756f8fa6637d8cb6cc588a679f6366827bc2044865744837c63e8a5aadcc",
|
||||
"0xfc1a94a88f1e52bb78a0862eea4b996444f0264a3b301c1a31e59744d0216de8",
|
||||
"0x79472bc4de84a0c430f15bcf8569486cddd2de985409ceb8e48abec8aa3e3fe7",
|
||||
"0x02bc578dcc715304c651a43d8dcb4a761d2073a93cca2c39da3ee513f0c6d415"
|
||||
"0x02bc578dcc715304c651a43d8dcb4a761d2073a93cca2c39da3ee513f0c6d415",
|
||||
"0xcf6175cfa60c20178241c18111d64f8837ec008751c5c333bee96c616d3cb6d1",
|
||||
"0xd8281202c7b6da2a2541cd7f8d4270066f6546bec601e83647896ebdf0f2eb66",
|
||||
"0xc4975ca8b2b71f61d2ba2825833df91096bd733301d54a3c7b6eca016ac14153",
|
||||
"0xd01d6f14e93c8ba17a602378bce1c9bdb51373675109d6233c497b6c638a03a0",
|
||||
"0x805057e19b7dd857ec014b4e6333bb60f48c02d29b128fe37a69f952df8ef16b",
|
||||
"0x69c55bdbaf74bfa3d53ed32b79dd35ac2c24dd723a1c0bfd70871cefa4dbb8a8",
|
||||
"0x523efe8059e6e8e2abd85d77d22123f97cbbd9864b4a3ac1fe0c0e4b8a7131eb",
|
||||
"0xe5a4f129016bcfbd71913d1eff01cec924f9d130b8762c921d43fe5bbbbdbbd0",
|
||||
"0x07f68773d16907348ac6e7c5be293ee1163ef41b91a2a8abb17a004c4796fb42",
|
||||
"0x90742f88c71f9e689b6d2ca0236c48bba0e8ddeace5fa4d53a5af082055cfd73",
|
||||
"0xaf7af6e9f695c4ca9e9a3c0229d94cbf02fcafbc4ed978a6b662862182308a72",
|
||||
"0x0208eac99df5025cab13d9767a2ba3e42ba1eccb72cfa01d87e834d15eea3751",
|
||||
"0xee9ff9384cef76b51a9d5b8eb12fd7e00ee7f8142f81bd68393e7fcf0eaef90a",
|
||||
"0x4770986e657683d901d73df444836f11f169f94ac55ec81e4e19f2212052788c",
|
||||
"0x9f9c16d009da6e8ee20d9d5f3bd7f1a77b853dfd19beef68d980fca6bce2b707",
|
||||
"0x468efd7c8dad29cfff0e278fd950f89e2d5a57d6824c6c1a7a7659bd7e7c0ffe",
|
||||
"0xd0391bd0a2c1fb2260d89bd5e519d4ef26b4945a7ad0c1b695687fe1b24698dd",
|
||||
"0xdef9ee668e09f8769b2c706a8de426e06f0bd9c264e67bf0c0bb177b851cef23",
|
||||
"0x10c5b79048e611c6e65f92dd54754753e595cd8f8f0f1005d7a647fa59deeb78",
|
||||
"0x4ce6d5812d2565237a9b018ed6ec386cf3e9fe1f2f429605288f2ef744c5a940",
|
||||
"0xbbacf6662d816d5eb14fc1271c1a3404de94e12c175545bc8273c231c280b789",
|
||||
"0xb216fd154d3726f16907ae571728d92ae2199872f180e4cd6be3b53a8dd43ae0",
|
||||
"0x2b76e6685604c69f29399451c66ce053ae033ab011eb52c97c112df968e37232",
|
||||
"0xf93b8076ce0dc6742196d2c9af501fad39f570cd927e8fe3b8dac4127a20a6a4",
|
||||
"0x35027cc654f998af75b8379fac0a9d51703f058b518880e25e658151619f1611",
|
||||
"0x3e7f59319228d40e5e07c06b696ad6478237ed0c8a71cff418ac259c6b5579e4",
|
||||
"0x7295e21fccabab1545c1e64a57f0401e62689057ab4fef26f70c8d02b63867ab",
|
||||
"0xb06bcf07fe1345c41ba16df213d699e2e185ef2fd3b5e19b194459d0b7baffc1",
|
||||
"0x1b13d005a29e35fff33373e2d8abc81805a85e7970b48dca8fd605069c8a0d85",
|
||||
"0x90a5a61ce554bb73253d7f62c78b1764f03fb0fd8f65b6aae4f9e529acb1d991",
|
||||
"0x1b1eccf7565339748947358caf473ba0cea743da2ed4790763d3ac8c402f261c",
|
||||
"0xef9b05ae7ce93febce342336e40922e0884891da43aac06f3e9bbfc0aec688f9",
|
||||
"0x11e1075b50de92e960d0d65e9b37b3cec81095f5afc2afccc6a9a8a325264049",
|
||||
"0x128e6dba4205701f673dda9e980dc0c02f3c0c8cbc570f9a240257a261f81b39",
|
||||
"0x6fd9d3eaffaeebd52ce93ac8fcd0f69b146e2c0b05218850de1c9218db8ecd8f",
|
||||
"0xc47e3487ad63b7db773f413cd5302818061f168409c27ff2daba4579c0a4263f",
|
||||
"0x0a55695d4a132063735f7319d3a90a2e0b83fd6ec6b6f9994068f928f68afe12",
|
||||
"0x39403d84aa319edbb18e0313a61ae075ba9c5dae40b9850eccbfc3e09e6b27a7",
|
||||
"0x79ba98eede4cd0b7031472baacab20df85c704a26e4cfaa6e01e3d4a9d26ca39",
|
||||
"0x219240759d36a317f269e4301256164cb3709628e0ba07e90a6bedd664cea059",
|
||||
"0xec793562f8498937f270c6ae5490ab8f2ad21a20510699dc4d7d4d0139efeb3b",
|
||||
"0x0a3e9c209903b906013c8876cb4292e6ccc8b76dbf4af2ca25d8260f9f8e7c22",
|
||||
"0x0eb347bb16d897b4909dcaf31a0009e198cd197f722075c112fe29bc9f017f20",
|
||||
"0xac1e6a97c51f5051dc8f3a1fa33c1071e29aff3d7040972dbb5481ba215010b3",
|
||||
"0x7e1be83ac51c7e68110c6984da43885af18bc9fe988a57ada7b2379d0a122563",
|
||||
"0xdb01b1cb4084a43c9a57bf8a65a58245edee5bbbdcf0573a3626e9290b4a2e6a",
|
||||
"0x6c97523c89da4c9325fe17d2e879bbd6b4693f3e6d807564de83ccf801e66737",
|
||||
"0x7511c0b30bd4dfa6f9a4f38793ee11e2a616de5d9d2212024c0875052ef2559e",
|
||||
"0x6faa338fd78b41f2ecb623d578520b373e0c74caafce95938161dbd95edb0e24",
|
||||
"0x0622bf3e00fae0e244d138f73d16035cd05aa9e0c4c16d20b36adad77951c2d4",
|
||||
"0x72e1ed876e0bcdbdd200dbd55a9d7e8248a4c7ca75588681b61f6f76eb980060",
|
||||
"0x981a052ee33c36c52fc33598c2563ff3698e1efd130090658cb457bb814ecff8",
|
||||
"0x2b732d67211042b340c1bc49682518bb00dfcaebd0cfe861b5d38df9c127ed64",
|
||||
"0xfcba6702d24950030403f872be646d058039d735cf297fcedb5daa255d47ce72",
|
||||
"0xba3bdc1bd47ab43c2d39ee67a512f306e987b577166d7037705a1fda772bbeec",
|
||||
"0xa39705f9efc0c0b9051742b705dab9fed7a08b3a00ff15583e15de95a9933356",
|
||||
"0x551658242a3237fda7b61eae6dc40f368ffbbe3e7f292bf1b3d291d1f21a631d",
|
||||
"0x631783a116fb5af727d2617276bf310e9f018e1f072d9f3d5432773ec29a193a",
|
||||
"0x7d2bee7cbf5aa7a5247f047b1147f55380e035a5ff1ce958037d96a539fada37",
|
||||
"0xfbe38f5210d9fc7c3474be4ff932d1ca393a565426f5d1443537e962beabbbca",
|
||||
"0xfc9b71f941a0a9dafd6356c4a42c369f22144b43f32f5d50fe3d4c1cf3ee3cda",
|
||||
"0xa4eb11bb0a0e210af085dc446766f4bb0d19dfec04e9d5d0d2c0ee390597906d",
|
||||
"0x42e8e9e3d4d6de275146369fa7c010a10979793276a4406bbfd77a543809e762",
|
||||
"0xb2fef38ac3b58b498cdad7d195bdb3604ca0cfc0ca3c7282163636d3022def43",
|
||||
"0x923269e9a526ddaa446a2e7acaea5189726ff77e664c20a341f6ad2f6b810d5f",
|
||||
"0x02e876ba6df7c9ddd7a9ad9bbc15f5918b096e299260fc85a8c7ebaa71d7dde5",
|
||||
"0x660442f393884c6c4b879168ab3c80c57318c6c62a67ba8df3788edf9ad7303f",
|
||||
"0x37f7ab248fded056ae5ecde87bf51c1f4baea786fc7c9f5b6760ad13c90659ac",
|
||||
"0x36fda244e2896e45d3a8a9ed67d7c09a2974c75944a7233f571928a497b55f8c",
|
||||
"0x4914478536196c3c813fe151cdf37097c6dc9e8d5c0cf9b370fe7567905fc4be",
|
||||
"0xcedb88613a1d6fbc24909963911efbc5ff56ba09377350b5e824123b50d1a910",
|
||||
"0x236fe31e63e426111507b2f972547255bd12c6f5df9079953a8b8346179bba57",
|
||||
"0x2f08e1b0ad4024814428237b4f0e7ca5a83257d25a1cb97f42db14307113916f",
|
||||
"0x41e45a3a2239551e8cb9598fb855f3d8922386c2e004426e294d111a94856b92",
|
||||
"0xd5d385b54446abfa8c78950aacae52edede3a7a65d9c7515043431a4498e4f85",
|
||||
"0xf2d2eb5169760d81d16067b9453979783a2feea91dfa253baa3183f2419478b0",
|
||||
"0xa5aac8d064c4f4cdfdd2c7f7326c1e0260aeb44be48b391616eb01fc6d30c95e",
|
||||
"0xb2a298085b0a082fc1781aad1abd263e9cc2c5eeeaa70acd88e8bdfbc0be7d15",
|
||||
"0xe2d19c438ddb9b96e77a9bc70566f49021bb6444569eea3cd039ecab4d61f73a",
|
||||
"0xa8549fc117d3faba2ca53efb94bbb37e9cb82bed8273e408da5ed47f5df7aab4",
|
||||
"0x161c898240dd6e0a0a1f1f5948c652a796bb6586995783a35e7ed6c3c02fb82b",
|
||||
"0x57214b17853934f1a548a7e9942849a04b9220f5b783a9d2be7395108bdc12e7",
|
||||
"0x7902ef6c69f5d0a3de1e45d8b46aebcf35aa87cc5f4644186f1c34614a429175",
|
||||
"0xc290a119f495ff04f406c28461e2de50abf92743b7fdd680048e491044fc59b7",
|
||||
"0x09bf0fa4aa8b65dcc8f937e46287eb2585c85c587b425f8a0af69d02948f35d9",
|
||||
"0xff20130699483dee0caacca392c2ad58738f61ea2443869616a3bf006e0cd1ad",
|
||||
"0x937c629f7307f7411a4b1cc5b92f6a1f1f42f716463f15c449c681d16525996f",
|
||||
"0x7cd028f48f117d8da3d537f0bb0fb0c832d3111d16fc116bd06454ddd513a095",
|
||||
"0x4bf15bb783cf917375b5494e00ce003d8da01c65fcbac40d44e62a6172f2cca8",
|
||||
"0xaff5ceacf024e9146631c772e4e87f223a241e789c88ae083da716c9aa47b860",
|
||||
"0x68c1db9a727678d2018ec98d0bbc369faec2fb1283b479abd5d6f2b1b04036aa",
|
||||
"0xe70962a032b4cb81910cea9911eef50ede2eeaa6f487f1e9f8fbf88f133249b1",
|
||||
"0x1bc2bd4440a1412fbf582d167e0d08629ad2bfe0bc0dfaeb5eb7730a4baf007c",
|
||||
"0x2d4cbafea30b01e466b41f6911deae979f4f5c82dcbdd76f711f7bf9300c23f4",
|
||||
"0x252e39a51862ebaf28d9b38f9fb842c70b5bf0669ca008b4c83c542e5236a1af",
|
||||
"0xba04c89c7ec2867d778f8632e7f51e11f06e56004520444ca922eabdab623473",
|
||||
"0x74b8dc3bf589a6d9051fbed9af3021e8fb775eab0f457cfd5d38b2ec8f88a24c",
|
||||
"0x8c0a98cd1665f50b702b44e10dfbfaa70f08b65ede72e39306b1d31b75c07afb",
|
||||
"0xa38c3526f5f6bce7e64a195cf8659160bc7318b8862ba206535626c338485c64",
|
||||
"0x4ad34e3c6be8cac9be3fba22eb7e99d951baf5827df5ef921f2b01d63862e116",
|
||||
"0x596670c729beb030c8756bf2ec6c884f9b4edc433a94f5dc5d4d337dbb712d76",
|
||||
"0x39611d27f11938df810165987ee7edbe87cfb7e4068216cbb45848b4029f8419"
|
||||
]
|
||||
},
|
||||
"accounts": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -62,8 +62,8 @@
|
||||
"gasLimit": "0x1000000"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f90217a058893ba2a7f3d1625239b0ffab5b58219412b5fb51a608fc6ae7ff012496db9ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942b126e450158f14add6770739a2e6b4037526817a0a46d5b8474c625b4efd3d1d2864d7790770737587aa926fb223945d55a1d0da8a04ff0c821428157d6a4ace26e17d775eac4f42cc7d777898ded413780207fda11a0777f1c1c378807634128348e4f0eeca6a0e7f516ea411690ca04266323f671a4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000844737e14e834dd801837a1200830186a0845c76311499d883010816846765746888676f312e31312e35856c696e7578a0676e77abeb493056c28a2d8fcd1238da73a29c9d915441fd8b5e36f6e910fa5d8803afeb22c339444f",
|
||||
"totalDifficulty": "18334236703652990",
|
||||
"header": "f9021aa0a8da98b6ef1e12b6c49e85b0e965f1ed1688f5e3605f06bb3c6ce4f857aa0bc6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794635b4764d1939dfacd3a8014726159abc277becca0d03c319fe68a91e22fb3b945a8dfc73b817976e29cf57e6c8425e6a02e9bf034a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000849fe1546f8350d001837a121d80845c9d55f29fde8302020b8f5061726974792d457468657265756d86312e33322e30826c69a04bf72e97bcf64717bfd655e2bca9ed1a5253cce5373268729161b1786ca4710488db3c50627f9321c4",
|
||||
"totalDifficulty": "18787961645682286",
|
||||
"CHTs": [
|
||||
"0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a",
|
||||
"0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc",
|
||||
@@ -2555,7 +2555,102 @@
|
||||
"0x563d7efb4175fc12dab431175b5097186c2379a5aca1901e39d641d02865d426",
|
||||
"0x1a55cf9842f9008e0730ae9fc6af9f288edba323803d0ae787fc0fdda99be8c9",
|
||||
"0xccdf47cee7142cad27bbf224f0afd1a6e5178345cab510f2f8ee27115ab27ff7",
|
||||
"0xc5b3582937ad993c5c234d059e6cd3b98f2fa4e3fe4ad591ecb6ae710b51fee9"
|
||||
"0xc5b3582937ad993c5c234d059e6cd3b98f2fa4e3fe4ad591ecb6ae710b51fee9",
|
||||
"0xd651ab199355d61c49e63259e6a20d17bf72b27891271e5175a24c23fb2dc29c",
|
||||
"0x800e1e33b0cd48afc6f8f7c69b85902ad93e94bb290b35a862cbad67706a2f3d",
|
||||
"0x57c7349a6b630cb52c3c1205165df428ed51e25cc167c08739f86bfa46c69e48",
|
||||
"0xb393d362daff182dafcce65eda9038fc0c8908b3cb1ec1a1218570211c34e142",
|
||||
"0xb2f49f7a836cd0db9e4743158ff80dd97d23de7a39a0438d19c79c355339c43c",
|
||||
"0x3f46776ec25b5c67468c32c1b2ca02910a7f46b4b62b5dc5d0cc6b9d3381b958",
|
||||
"0x754c4ea722e501668aa48d6151ff423263b8a4e2f33b9e44e189ee4e78462741",
|
||||
"0x12e79ee2724763a8a7f9196bf4d0e855e0ae3f75f5a697d90a263bf562acc5a3",
|
||||
"0x407b168fea70128a8090ca86274b0b8e7965f16d54ea2b3bbabb378485b22a02",
|
||||
"0x0d1557ad0cb1466965e6ee86c5ce887eedf462dbec2e719c5f396f8ed95edf08",
|
||||
"0x29c3a0db9f83698e6ae703174dbeec06f3d2055eb933799e4ae3bf73f4570dde",
|
||||
"0x8ade20e56fcacb40f54259696bea1aa04d839b88c503d6775d7b4491e0f9e7fa",
|
||||
"0x327ef0f173632c5049988b312b1f49e9948b02125f70e117ea127088191c32d5",
|
||||
"0x2989c11c234b7fc5901e168d7adfa655ff6165098eb94d244b623ba43c6abbd6",
|
||||
"0x10b56dc8f023de6a8f97696dfe2993b56156a9b35f671438fee5830f52b633b5",
|
||||
"0x46cd37fffe94a01297f2dcef322ae72f58bbf9f58bc9f930cbf56e73f8d5ce13",
|
||||
"0x2240214683eafc37396f3078446b43ae96bc576e45db650b953ff87a895ee7d7",
|
||||
"0x0db4d500e5755cba5b962f6b83942e72fd1504cf52531916084852179669a08d",
|
||||
"0xafc686a8325a30966db0f54b64a4e7235ea54e300d280a4d2a502651a53424b5",
|
||||
"0x59d46f6fb8eadcf18e31c9fd0da6844d63a2dc19eeeaf9ad5b80113aca5bc42a",
|
||||
"0x153ae496364bf7c34c8c967e044cef69e401f0e4aff27b04808e2c299dcf15a8",
|
||||
"0xc85b8d3156729c7f8ff1989f320464144f4918140d608cf03e7dfd5b51ec2acf",
|
||||
"0x78fd0613f6f5291d4131152225fbded5464841a119d854a7550a1f178a8cdfc7",
|
||||
"0x763dc1a000b949a45f792515fed6af70047641fa3d7beeb50b141c27b4f8cd33",
|
||||
"0x42567a1e6caadaa10a13feff343ae1e2a903564affacc48aebc14f257db58ee1",
|
||||
"0x62c208337234d101cc95cb6be54c17631e26c956758493f5bb7978faf0ace984",
|
||||
"0x7977aec997a3029025ef789d3492755c80c2d028046aae8c4b926f247e1981d9",
|
||||
"0xf927505a0c29231ed187a884af15a82dbc48a1cb002f6d91496f6569c673682d",
|
||||
"0xefd2c54f6d2483a3dd7b994d8afa5441cfffa956d7da6e81bbd1691e07ac7519",
|
||||
"0x7bcf94d8927a39dd00558763cdd2edaf40d55728d720dccfa0f5e1e827079cc0",
|
||||
"0x19c7e5115ec25b14bd85e3d368e15d2bbe60451ed9a02f03770a3e845521b77c",
|
||||
"0x60e32d48de6979c70dcb3e3f068fc3632aba5844703d50851a34975338b3a837",
|
||||
"0x6722f01dc1d6dd1f0678e5b527155beb0616e33887697a56ef4cc1bac642f394",
|
||||
"0x59bf17368d69e0379f0f20ec1b1b856298b8d6b4c36354ee765c8a894e58ab9b",
|
||||
"0xe2559e7b67a15a3ddfbf1ddc597a1309d1fd780fe26da28aace16ad31754883c",
|
||||
"0xbf687ac704bf02a3877e72f738691bf5027c21f64c68a50235876a8d015ae682",
|
||||
"0xde01838df621b7368adf4fda268c827dfaa6753a39d51956c0445a2244585ec1",
|
||||
"0x4ba14d3860d1dee44904719e45a5bfe54dd1e4c9bdafd0a41279e432a021f2e6",
|
||||
"0xa2380cb32538cc80e07fda5575ecd7b35e0c12932687bd8002da652ad8c16dc2",
|
||||
"0x82d0f5c8421d6803e52e3d6a37eea0cd978686792a2f6d175d77e9c75fb4ad86",
|
||||
"0x23701b29d07c64c998ee4bf8199d5ac0f3d9724af2544cc29665a1d92a6dadce",
|
||||
"0x8bbd490220c823506e111c668f923d18addf5a23d9b5244103cc135c4335f23d",
|
||||
"0x190506f2d9decb8f9423662f406e61c99606abdcb369e25a1a89c2bdc44c6158",
|
||||
"0xb9504b090b276cbbf86349bc4dbb66b46a42ce6ae8d44d5cd7f39773fdf6112a",
|
||||
"0x38fc273344dc7230790963dfb3dedfabe142c18886d6542d77ace8ed6d117c4f",
|
||||
"0xc76929e9a3a984f6ab6395c4811f007eb6d73a86fe62f8a1c02e860769f2bcde",
|
||||
"0xc4fc2465f71d06102d232858cfd9737e6e82311a45b1cb2ac203de80c881a2f4",
|
||||
"0x34427ee5534de01e7f0510b87e6f45aac6210897472978aee3c051c39776c561",
|
||||
"0xec4f3c6349dac1e7e43b0541b1132b3d0cc8bd422436f31832184d1aa6f9c822",
|
||||
"0x024a848067a1156852c78495581392774b00f22e32021ca531afeab1aafb683e",
|
||||
"0x9bdf793e30326a181d3d8fb3f27818475b755e3d1fea200d8c514cf17024979a",
|
||||
"0x55a1d92354a31354b4b1d9366e98b27c0467b01a108d67dab7feeeda23f981d9",
|
||||
"0x74614ac3de92173d07434dd80d83aad5c1d551127896298808ad7fba96051e06",
|
||||
"0x7bdb77183ca1e7f50d292e50ef701ad3bfff3e6e28d36629c5325da03cb8d013",
|
||||
"0x3a35dc3d12de1053d204410a577b9e5c36d32fbda761f797aee248c27f7dbb02",
|
||||
"0x430aaeb1dc02bb792375d1702999cda7c384dde1c6f46ef26f1e26e5a55dfd87",
|
||||
"0xe12805d1713ba730fec6aae824bdcd0a896c6d5e12b9bfa5b6e0a2c2be251c17",
|
||||
"0x5a297bd3be2352e56136db83a76c7041ef825128152366b2d8f032abb1d6656f",
|
||||
"0x111782d82f50ea25d684af38689cea53319f1a88557d82c57e46ee5e75f99c05",
|
||||
"0xe12520cda10064d74fdefba22b5ff4c5eb95508f77fd7c8c3fe82fb89e165bf6",
|
||||
"0x6af12e8f4db19aee3865c3d681073e7433d902832bc651b8fc3f5fd038c8bca6",
|
||||
"0x82a4a2ce19ca3fd99007279d62dadba547b6818607800e963b3bc53c5541298a",
|
||||
"0xbf3a444d1b15d01a29ea22d05e71021ee3581338ecc9e770ee23ab6549a19d55",
|
||||
"0x745ff92172b5c83cdd69265b919028b350ef95a01c84810366d630162fd9b07f",
|
||||
"0x6128cd2ff1be9e56396a676362a2049f3e670c70ad2a77be724c090fd4085f0b",
|
||||
"0x8ffc6bf8165e52ecf30ec955d4be1bb093e6074c92a527382a8892ffa3d3e7f7",
|
||||
"0xd65bc11ef24c0fa476640d9effdc57030a86f547b7aa79b209954a6abf4072c4",
|
||||
"0xcd5b5e184a5c0d1c5bdd12f80736ed1a4530210b4ef5f35dacd3feba722a334a",
|
||||
"0xa80657ecf79ef03fb919bf312e02d94ab528c1b5c3858332d9bf82f807b1c232",
|
||||
"0xc67dfe4aca5001e97ba6f401f15b72be85ae45972ba98b965a6dd4954d5c2386",
|
||||
"0x59201e892aeab9e40aef69945585b81b47a7444ed61ba6c6e23e006103ed7edd",
|
||||
"0xf535c920c5316f12f0bfedc298fbad028dd84161927414b14243c4c5ddd4f4f1",
|
||||
"0x66c6e42c8137c043eb49528c718b10e5dbad9164bd3ffcc6b55b4b0501dc507b",
|
||||
"0xa60b9485cb54818e0b0bfe4faeca923915f85bbac0525d09d96f375d0b2b9f81",
|
||||
"0x8f9377dddacb6ed605c8ed8ed2bc6e2323a4e5d0c9b29bccdfbd27f57a9ec315",
|
||||
"0xc48a1940c424c2df4803ba8d5573066ce4bbf0e0fbdaa87abcb2d2f51b0a4602",
|
||||
"0xc7bce918e9f897aeb1351d2c9cbc2fbc8fd674017cb25c49846b05d609f00ed9",
|
||||
"0xcdaa86e0c026c91954c6305cb7ce6010560f691a2667baf0e95bc18cd3e067df",
|
||||
"0xf131e0910a8088fc5b0b1d2e93e31632eec67fa88f75bc4f9c3c1b0a317e1d54",
|
||||
"0xb4f8d72a85c4c2261c7b00f43b96d7d749d0e53359993f52517da36de4c9559b",
|
||||
"0x73f84bb4774a81b39b3a10d18c7a2404d21f3efd26301dbb7c8136e96304281e",
|
||||
"0x5559435a987f1444e4ec78b8530009e49c52431b37c7e9f80ce2e056d44e876a",
|
||||
"0x070664d11ee10c4e0475a7ece219eb0e606e055ee0fa1266b669e593b5ba1d87",
|
||||
"0xfdfafeba7b5551d1e2d6f179be5ddfdbd0350bd2e9dfea40e272fb608549e8c2",
|
||||
"0x50a1356bab9b56d8ed46a3e8f55b8a16af42df6b15fcc68aa548216de484c7eb",
|
||||
"0x681161a307552ff12175074601005bae0c6f7b38cfa6dcb87975a1df205e28d5",
|
||||
"0x2b39456efc2e8863197c95a4d6eef5069612cc2aa6414f0991393ffa672a1a15",
|
||||
"0x571b916a82371fafcb456524655758bd42b4f7b768e13807a1a995e642ec205c",
|
||||
"0xb2821504201eea0e6040a131a709547fc9afb44ba7bfa6a188201735753ba3b7",
|
||||
"0xb16a8af1bfdde1fae0e28f29c6db0b361840df4b55e73bddffbc1cc11bcc5584",
|
||||
"0x1df38b594f536cee38acad293a818bf83fc67830fc71bc19790d7733a2caab60",
|
||||
"0xebb3e8f76f3b6a95285154dc11d4bd94ac4c3a150383ed69f5373499b1983dc3",
|
||||
"0xb0919ed300acac5f912f01611a428861db27ffb8129a80495f735f0ac608ab35",
|
||||
"0x2ee321d9d805b78a97210df2977ab62b352705e308773b90e0f4e923adec377c",
|
||||
"0xee00cb02e9b86978ae10b119924bbe6c38f730c1d1b621d32c9d697e11105871"
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,12 +19,9 @@ use io;
|
||||
use ethcore_private_tx;
|
||||
|
||||
error_chain! {
|
||||
links {
|
||||
PrivateTransactions(ethcore_private_tx::Error, ethcore_private_tx::ErrorKind);
|
||||
}
|
||||
|
||||
foreign_links {
|
||||
Ethcore(ethcore::error::Error);
|
||||
IoError(io::IoError);
|
||||
PrivateTransactions(ethcore_private_tx::Error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,16 +79,6 @@ pub fn new_ellaism<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/ellaism.json"))
|
||||
}
|
||||
|
||||
/// Create a new Easthub mainnet chain spec.
|
||||
pub fn new_easthub<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/easthub.json"))
|
||||
}
|
||||
|
||||
/// Create a new Ethereum Social mainnet chain spec.
|
||||
pub fn new_social<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/social.json"))
|
||||
}
|
||||
|
||||
/// Create a new MIX mainnet chain spec.
|
||||
pub fn new_mix<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/mix.json"))
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
//! Block header.
|
||||
|
||||
use std::cmp;
|
||||
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP, keccak};
|
||||
use heapsize::HeapSizeOf;
|
||||
use ethereum_types::{H256, U256, Address, Bloom};
|
||||
@@ -342,7 +341,7 @@ impl Decodable for Header {
|
||||
number: r.val_at(8)?,
|
||||
gas_limit: r.val_at(9)?,
|
||||
gas_used: r.val_at(10)?,
|
||||
timestamp: cmp::min(r.val_at::<U256>(11)?, u64::max_value().into()).as_u64(),
|
||||
timestamp: r.val_at(11)?,
|
||||
extra_data: r.val_at(12)?,
|
||||
seal: vec![],
|
||||
hash: keccak(r.as_raw()).into(),
|
||||
@@ -445,4 +444,15 @@ mod tests {
|
||||
|
||||
assert_eq!(header_rlp, encoded_header);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_header_with_large_timestamp() {
|
||||
// that's rlp of block header created with ethash engine.
|
||||
// The encoding contains a large timestamp (295147905179352825856)
|
||||
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d891000000000000000000080a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
|
||||
// This should fail decoding timestamp
|
||||
let header: Result<Header, _> = rlp::decode(&header_rlp);
|
||||
assert_eq!(header.unwrap_err(), rlp::DecoderError::RlpIsTooBig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ parking_lot = "0.7"
|
||||
price-info = { path = "./price-info", optional = true }
|
||||
rlp = { version = "0.3.0", features = ["ethereum"] }
|
||||
trace-time = "0.1"
|
||||
transaction-pool = "1.13"
|
||||
transaction-pool = "2.0"
|
||||
|
||||
[dev-dependencies]
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ mod ready;
|
||||
|
||||
pub mod client;
|
||||
pub mod local_transactions;
|
||||
pub mod replace;
|
||||
pub mod scoring;
|
||||
pub mod verifier;
|
||||
|
||||
@@ -121,7 +122,7 @@ pub trait ScoredTransaction {
|
||||
}
|
||||
|
||||
/// Verified transaction stored in the pool.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VerifiedTransaction {
|
||||
transaction: transaction::PendingTransaction,
|
||||
// TODO [ToDr] hash and sender should go directly from the transaction
|
||||
|
||||
@@ -27,7 +27,7 @@ use txpool::{self, Verifier};
|
||||
use types::transaction;
|
||||
|
||||
use pool::{
|
||||
self, scoring, verifier, client, ready, listener,
|
||||
self, replace, scoring, verifier, client, ready, listener,
|
||||
PrioritizationStrategy, PendingOrdering, PendingSettings,
|
||||
};
|
||||
use pool::local_transactions::LocalTransactionsList;
|
||||
@@ -240,7 +240,7 @@ impl TransactionQueue {
|
||||
///
|
||||
/// Given blockchain and state access (Client)
|
||||
/// verifies and imports transactions to the pool.
|
||||
pub fn import<C: client::Client>(
|
||||
pub fn import<C: client::Client + client::NonceClient + Clone>(
|
||||
&self,
|
||||
client: C,
|
||||
transactions: Vec<verifier::Transaction>,
|
||||
@@ -263,12 +263,14 @@ impl TransactionQueue {
|
||||
};
|
||||
|
||||
let verifier = verifier::Verifier::new(
|
||||
client,
|
||||
client.clone(),
|
||||
options,
|
||||
self.insertion_id.clone(),
|
||||
transaction_to_replace,
|
||||
);
|
||||
|
||||
let mut replace = replace::ReplaceByScoreAndReadiness::new(self.pool.read().scoring().clone(), client);
|
||||
|
||||
let results = transactions
|
||||
.into_iter()
|
||||
.map(|transaction| {
|
||||
@@ -286,7 +288,7 @@ impl TransactionQueue {
|
||||
let imported = verifier
|
||||
.verify_transaction(transaction)
|
||||
.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 {
|
||||
@@ -579,17 +581,13 @@ impl TransactionQueue {
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_error(err: txpool::Error) -> transaction::Error {
|
||||
use self::txpool::ErrorKind;
|
||||
fn convert_error<H: fmt::Debug + fmt::LowerHex>(err: txpool::Error<H>) -> transaction::Error {
|
||||
use self::txpool::Error;
|
||||
|
||||
match *err.kind() {
|
||||
ErrorKind::AlreadyImported(..) => transaction::Error::AlreadyImported,
|
||||
ErrorKind::TooCheapToEnter(..) => transaction::Error::LimitReached,
|
||||
ErrorKind::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace,
|
||||
ref e => {
|
||||
warn!(target: "txqueue", "Unknown import error: {:?}", e);
|
||||
transaction::Error::NotAllowed
|
||||
},
|
||||
match err {
|
||||
Error::AlreadyImported(..) => transaction::Error::AlreadyImported,
|
||||
Error::TooCheapToEnter(..) => transaction::Error::LimitReached,
|
||||
Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
new.priority().is_local()
|
||||
}
|
||||
@@ -155,156 +132,8 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
use ethkey::{Random, Generator, KeyPair};
|
||||
use pool::tests::tx::{Tx, TxExt};
|
||||
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]
|
||||
fn should_calculate_score_correctly() {
|
||||
|
||||
@@ -300,7 +300,7 @@ usage! {
|
||||
|
||||
ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(),
|
||||
"--chain=[CHAIN]",
|
||||
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, mix, callisto, morden, ropsten, kovan, poasokol, testnet, or dev.",
|
||||
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, mix, callisto, morden, ropsten, kovan, poasokol, testnet, or dev.",
|
||||
|
||||
ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| c.parity.as_ref()?.keys_path.clone(),
|
||||
"--keys-path=[PATH]",
|
||||
@@ -926,7 +926,7 @@ usage! {
|
||||
"--whisper",
|
||||
"Enable the Whisper network.",
|
||||
|
||||
ARG arg_whisper_pool_size: (usize) = 10usize, or |c: &Config| c.whisper.as_ref()?.pool_size.clone(),
|
||||
ARG arg_whisper_pool_size: (usize) = 10usize, or |c: &Config| c.whisper.as_ref()?.pool_size.clone(),
|
||||
"--whisper-pool-size=[MB]",
|
||||
"Target size of the whisper message pool in megabytes.",
|
||||
|
||||
|
||||
@@ -40,8 +40,6 @@ pub enum SpecType {
|
||||
Expanse,
|
||||
Musicoin,
|
||||
Ellaism,
|
||||
Easthub,
|
||||
Social,
|
||||
Mix,
|
||||
Callisto,
|
||||
Morden,
|
||||
@@ -70,8 +68,6 @@ impl str::FromStr for SpecType {
|
||||
"expanse" => SpecType::Expanse,
|
||||
"musicoin" => SpecType::Musicoin,
|
||||
"ellaism" => SpecType::Ellaism,
|
||||
"easthub" => SpecType::Easthub,
|
||||
"social" => SpecType::Social,
|
||||
"mix" => SpecType::Mix,
|
||||
"callisto" => SpecType::Callisto,
|
||||
"morden" | "classic-testnet" => SpecType::Morden,
|
||||
@@ -95,8 +91,6 @@ impl fmt::Display for SpecType {
|
||||
SpecType::Expanse => "expanse",
|
||||
SpecType::Musicoin => "musicoin",
|
||||
SpecType::Ellaism => "ellaism",
|
||||
SpecType::Easthub => "easthub",
|
||||
SpecType::Social => "social",
|
||||
SpecType::Mix => "mix",
|
||||
SpecType::Callisto => "callisto",
|
||||
SpecType::Morden => "morden",
|
||||
@@ -120,8 +114,6 @@ impl SpecType {
|
||||
SpecType::Expanse => Ok(ethereum::new_expanse(params)),
|
||||
SpecType::Musicoin => Ok(ethereum::new_musicoin(params)),
|
||||
SpecType::Ellaism => Ok(ethereum::new_ellaism(params)),
|
||||
SpecType::Easthub => Ok(ethereum::new_easthub(params)),
|
||||
SpecType::Social => Ok(ethereum::new_social(params)),
|
||||
SpecType::Mix => Ok(ethereum::new_mix(params)),
|
||||
SpecType::Callisto => Ok(ethereum::new_callisto(params)),
|
||||
SpecType::Morden => Ok(ethereum::new_morden(params)),
|
||||
@@ -376,8 +368,6 @@ mod tests {
|
||||
assert_eq!(SpecType::Expanse, "expanse".parse().unwrap());
|
||||
assert_eq!(SpecType::Musicoin, "musicoin".parse().unwrap());
|
||||
assert_eq!(SpecType::Ellaism, "ellaism".parse().unwrap());
|
||||
assert_eq!(SpecType::Easthub, "easthub".parse().unwrap());
|
||||
assert_eq!(SpecType::Social, "social".parse().unwrap());
|
||||
assert_eq!(SpecType::Mix, "mix".parse().unwrap());
|
||||
assert_eq!(SpecType::Callisto, "callisto".parse().unwrap());
|
||||
assert_eq!(SpecType::Morden, "morden".parse().unwrap());
|
||||
@@ -403,8 +393,6 @@ mod tests {
|
||||
assert_eq!(format!("{}", SpecType::Expanse), "expanse");
|
||||
assert_eq!(format!("{}", SpecType::Musicoin), "musicoin");
|
||||
assert_eq!(format!("{}", SpecType::Ellaism), "ellaism");
|
||||
assert_eq!(format!("{}", SpecType::Easthub), "easthub");
|
||||
assert_eq!(format!("{}", SpecType::Social), "social");
|
||||
assert_eq!(format!("{}", SpecType::Mix), "mix");
|
||||
assert_eq!(format!("{}", SpecType::Callisto), "callisto");
|
||||
assert_eq!(format!("{}", SpecType::Morden), "morden");
|
||||
|
||||
@@ -72,7 +72,7 @@ fake-fetch = { path = "../util/fake-fetch" }
|
||||
kvdb-memorydb = "0.1"
|
||||
macros = { path = "../util/macros" }
|
||||
pretty_assertions = "0.1"
|
||||
transaction-pool = "1.13"
|
||||
transaction-pool = "2.0"
|
||||
|
||||
[features]
|
||||
accounts = ["ethcore-accounts"]
|
||||
|
||||
@@ -86,7 +86,7 @@ use jsonrpc_core::{BoxFuture, Result, Error};
|
||||
use jsonrpc_core::futures::{future, Future, IntoFuture};
|
||||
use v1::helpers::{TransactionRequest, FilledTransactionRequest, ConfirmationPayload};
|
||||
use v1::types::{
|
||||
H520 as RpcH520, Bytes as RpcBytes,
|
||||
Bytes as RpcBytes,
|
||||
RichRawTransaction as RpcRichRawTransaction,
|
||||
ConfirmationPayload as RpcConfirmationPayload,
|
||||
ConfirmationResponse,
|
||||
@@ -309,7 +309,6 @@ pub fn execute<D: Dispatcher + 'static>(
|
||||
let res = signer.sign_message(address, pass, SignMessage::Data(data))
|
||||
.map(|result| result
|
||||
.map(|s| H520(s.into_electrum()))
|
||||
.map(RpcH520::from)
|
||||
.map(ConfirmationResponse::Signature)
|
||||
);
|
||||
|
||||
@@ -319,7 +318,6 @@ pub fn execute<D: Dispatcher + 'static>(
|
||||
let res = signer.sign_message(address, pass, SignMessage::Hash(data))
|
||||
.map(|result| result
|
||||
.map(|rsv| H520(rsv.into_electrum()))
|
||||
.map(RpcH520::from)
|
||||
.map(ConfirmationResponse::Signature)
|
||||
);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ethereum_types::U256;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use super::oneshot;
|
||||
|
||||
@@ -15,17 +15,15 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use types::transaction::{Transaction, SignedTransaction, Action};
|
||||
use std::cmp::min;
|
||||
|
||||
use ethereum_types::U256;
|
||||
use jsonrpc_core::Error;
|
||||
use v1::helpers::CallRequest;
|
||||
|
||||
pub fn sign_call(request: CallRequest) -> Result<SignedTransaction, Error> {
|
||||
let max_gas = U256::from(50_000_000);
|
||||
let gas = match request.gas {
|
||||
Some(gas) => gas,
|
||||
None => max_gas * 10u32,
|
||||
};
|
||||
let max_gas = U256::from(500_000_000);
|
||||
let gas = min(request.gas.unwrap_or(max_gas), max_gas);
|
||||
let from = request.from.unwrap_or(0.into());
|
||||
|
||||
Ok(Transaction {
|
||||
|
||||
@@ -40,13 +40,14 @@ use light::on_demand::{
|
||||
};
|
||||
use light::on_demand::error::Error as OnDemandError;
|
||||
use light::request::Field;
|
||||
use light::TransactionQueue;
|
||||
|
||||
|
||||
use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider};
|
||||
|
||||
use ethereum_types::{U256, Address};
|
||||
use ethereum_types::{Address, U256};
|
||||
use hash::H256;
|
||||
use parking_lot::Mutex;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use fastmap::H256FastMap;
|
||||
use std::collections::BTreeMap;
|
||||
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 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>
|
||||
where
|
||||
@@ -95,7 +97,7 @@ where
|
||||
on_demand: self.on_demand.clone(),
|
||||
sync: self.sync.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.
|
||||
/// `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 header_ref = match self.make_header_requests(id, &mut reqs) {
|
||||
Ok(r) => r,
|
||||
@@ -218,15 +226,26 @@ where
|
||||
|
||||
reqs.push(request::Account { header: header_ref, address: address }.into());
|
||||
|
||||
Either::B(self.send_requests(reqs, |mut res|match res.pop() {
|
||||
Some(OnDemandResponse::Account(acc)) => acc,
|
||||
Either::B(self.send_requests(reqs, move |mut res| match res.pop() {
|
||||
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),
|
||||
}))
|
||||
}
|
||||
|
||||
/// Helper for getting proved execution.
|
||||
pub fn proved_read_only_execution(&self, req: CallRequest, num: Option<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
|
||||
const DEFAULT_GAS_PRICE: u64 = 21_000;
|
||||
pub fn proved_read_only_execution(
|
||||
&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)
|
||||
const START_GAS: u64 = 60_000;
|
||||
|
||||
@@ -249,21 +268,12 @@ where
|
||||
let from = req.from.unwrap_or_else(|| Address::zero());
|
||||
let nonce_fut = match req.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 {
|
||||
Some(price) => Either::A(future::ok(price)),
|
||||
None => Either::B(dispatch::light::fetch_gas_price_corpus(
|
||||
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(),
|
||||
}))
|
||||
None => Either::B(self.gas_price()),
|
||||
};
|
||||
|
||||
// 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.
|
||||
pub fn block(&self, id: BlockId) -> impl Future<Item = encoded::Block, Error = Error> + Send {
|
||||
let mut reqs = Vec::new();
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use rand::{Rng, OsRng};
|
||||
use ethereum_types::{H256, H512};
|
||||
use ethkey::{self, Public, Secret, Random, Generator, math};
|
||||
use crypto;
|
||||
use bytes::Bytes;
|
||||
use jsonrpc_core::Error;
|
||||
use v1::helpers::errors;
|
||||
use v1::types::{H256, H512, EncryptedDocumentKey};
|
||||
use v1::types::EncryptedDocumentKey;
|
||||
use tiny_keccak::Keccak;
|
||||
|
||||
/// Initialization vector length.
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ethkey::{recover, public_to_address, Signature};
|
||||
use ethereum_types::{H256, U64};
|
||||
use jsonrpc_core::Result;
|
||||
use v1::types::{Bytes, RecoveredAccount, H256, U64};
|
||||
use v1::types::{Bytes, RecoveredAccount};
|
||||
use v1::helpers::errors;
|
||||
use v1::helpers::dispatch::eth_data_hash;
|
||||
use hash::keccak;
|
||||
@@ -35,7 +36,7 @@ pub fn verify_signature(
|
||||
} else {
|
||||
keccak(message.0)
|
||||
};
|
||||
let v: u64 = v.into();
|
||||
let v = v.as_u64();
|
||||
let is_valid_for_current_chain = match (chain_id, v) {
|
||||
(None, v) if v == 0 || v == 1 => true,
|
||||
(Some(chain_id), v) if v >= 35 => (v - 35) / 2 == chain_id,
|
||||
@@ -54,7 +55,7 @@ pub fn verify_signature(
|
||||
mod tests {
|
||||
use super::*;
|
||||
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 {
|
||||
v + if let Some(n) = chain_id { 35 + n * 2 } else { 0 }
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
use std::{ops, str};
|
||||
use std::collections::HashMap;
|
||||
use jsonrpc_pubsub::{typed::{Subscriber, Sink}, SubscriptionId};
|
||||
use ethereum_types::H64;
|
||||
use rand::{Rng, StdRng};
|
||||
use v1::types::H64;
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct Id(H64);
|
||||
@@ -36,8 +36,9 @@ impl str::FromStr for Id {
|
||||
}
|
||||
}
|
||||
impl Id {
|
||||
// TODO: replace `format!` see [#10412](https://github.com/paritytech/parity-ethereum/issues/10412)
|
||||
pub fn as_string(&self) -> String {
|
||||
format!("0x{:?}", self.0)
|
||||
format!("{:?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,13 @@ use std::sync::Arc;
|
||||
|
||||
use rlp;
|
||||
use ethcore::miner::{BlockChainClient, MinerService};
|
||||
use ethereum_types::{H64 as EthcoreH64, H256 as EthcoreH256};
|
||||
use ethereum_types::{H64, H256};
|
||||
use jsonrpc_core::Error;
|
||||
use v1::types::{H64, H256};
|
||||
use v1::helpers::errors;
|
||||
|
||||
// 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> {
|
||||
// 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);
|
||||
let seal = vec![rlp::encode(&mix_hash), rlp::encode(&nonce)];
|
||||
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 rlp::Rlp;
|
||||
use ethereum_types::{U256, H256, H160, Address};
|
||||
use ethereum_types::{Address, H64, H160, H256, U64, U256};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use ethash::{self, SeedHashCompute};
|
||||
@@ -47,8 +47,7 @@ use v1::traits::Eth;
|
||||
use v1::types::{
|
||||
RichBlock, Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo,
|
||||
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,
|
||||
U64 as RpcU64,
|
||||
block_number_to_id
|
||||
};
|
||||
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;
|
||||
if miner == 0.into() {
|
||||
(self.accounts)()
|
||||
@@ -539,7 +538,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
.map(From::from)
|
||||
.ok_or_else(|| errors::account("No accounts were found", ""))
|
||||
} 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())
|
||||
}
|
||||
|
||||
fn chain_id(&self) -> Result<Option<RpcU64>> {
|
||||
Ok(self.client.signing_chain_id().map(RpcU64::from))
|
||||
fn chain_id(&self) -> Result<Option<U64>> {
|
||||
Ok(self.client.signing_chain_id().map(U64::from))
|
||||
}
|
||||
|
||||
fn hashrate(&self) -> Result<RpcU256> {
|
||||
Ok(RpcU256::from(self.external_miner.hashrate()))
|
||||
fn hashrate(&self) -> Result<U256> {
|
||||
Ok(U256::from(self.external_miner.hashrate()))
|
||||
}
|
||||
|
||||
fn gas_price(&self) -> Result<RpcU256> {
|
||||
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)))
|
||||
fn gas_price(&self) -> BoxFuture<U256> {
|
||||
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);
|
||||
|
||||
let accounts = (self.accounts)();
|
||||
Ok(accounts.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
fn block_number(&self) -> Result<RpcU256> {
|
||||
Ok(RpcU256::from(self.client.chain_info().best_block_number))
|
||||
fn block_number(&self) -> Result<U256> {
|
||||
Ok(U256::from(self.client.chain_info().best_block_number))
|
||||
}
|
||||
|
||||
fn balance(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
let address = address.into();
|
||||
|
||||
fn balance(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
|
||||
let num = num.unwrap_or_default();
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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"));
|
||||
|
||||
let a: H160 = address.clone().into();
|
||||
let key1 = keccak(a);
|
||||
let key1 = keccak(address);
|
||||
|
||||
let num = num.unwrap_or_default();
|
||||
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()));
|
||||
let res = match self.client.prove_account(key1, id) {
|
||||
Some((proof,account)) => Ok(EthAccount {
|
||||
Some((proof, account)) => Ok(EthAccount {
|
||||
address: address,
|
||||
balance: account.balance.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))
|
||||
}
|
||||
|
||||
fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Option<BlockNumber>) -> BoxFuture<RpcH256> {
|
||||
let address: Address = RpcH160::into(address);
|
||||
let position: U256 = RpcU256::into(pos);
|
||||
|
||||
fn storage_at(&self, address: H160, position: U256, num: Option<BlockNumber>) -> BoxFuture<H256> {
|
||||
let address: Address = address.into();
|
||||
let num = num.unwrap_or_default();
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
fn transaction_count(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
let address: Address = RpcH160::into(address);
|
||||
fn transaction_count(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
|
||||
let address: Address = address.into();
|
||||
|
||||
let res = match num.unwrap_or_default() {
|
||||
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))
|
||||
}
|
||||
|
||||
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()))
|
||||
.map(|block| block.transactions_count().into());
|
||||
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))
|
||||
}
|
||||
|
||||
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 {
|
||||
BlockNumber::Pending =>
|
||||
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()))
|
||||
.map(|block| block.uncles_count().into());
|
||||
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))
|
||||
}
|
||||
|
||||
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 {
|
||||
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> {
|
||||
let address: Address = RpcH160::into(address);
|
||||
fn code_at(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<Bytes> {
|
||||
let address: Address = H160::into(address);
|
||||
|
||||
let num = num.unwrap_or_default();
|
||||
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))
|
||||
}
|
||||
|
||||
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)
|
||||
.and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks));
|
||||
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))
|
||||
}
|
||||
|
||||
fn transaction_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<Transaction>> {
|
||||
let hash: H256 = hash.into();
|
||||
fn transaction_by_hash(&self, hash: H256) -> BoxFuture<Option<Transaction>> {
|
||||
let tx = try_bf!(self.transaction(PendingTransactionId::Hash(hash))).or_else(|| {
|
||||
self.miner.transaction(&hash)
|
||||
.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))
|
||||
}
|
||||
|
||||
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 result = self.transaction(id).and_then(
|
||||
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))
|
||||
}
|
||||
|
||||
fn transaction_receipt(&self, hash: RpcH256) -> BoxFuture<Option<Receipt>> {
|
||||
let hash: H256 = hash.into();
|
||||
|
||||
fn transaction_receipt(&self, hash: H256) -> BoxFuture<Option<Receipt>> {
|
||||
if self.options.allow_pending_receipt_query {
|
||||
let best_block = self.client.chain_info().best_block_number;
|
||||
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))
|
||||
}
|
||||
|
||||
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 {
|
||||
id: PendingOrBlock::Block(BlockId::Hash(hash.into())),
|
||||
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) {
|
||||
Ok(_) => Ok(true),
|
||||
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());
|
||||
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()
|
||||
.map_err(errors::rlp)
|
||||
.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)
|
||||
}
|
||||
|
||||
fn submit_transaction(&self, raw: Bytes) -> Result<RpcH256> {
|
||||
fn submit_transaction(&self, raw: Bytes) -> Result<H256> {
|
||||
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 signed = try_bf!(fake_sign::sign_call(request));
|
||||
let num = num.unwrap_or_default();
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::collections::{BTreeSet, VecDeque};
|
||||
|
||||
use ethcore::client::{BlockChainClient, BlockId};
|
||||
use ethcore::miner::{self, MinerService};
|
||||
use ethereum_types::H256;
|
||||
use ethereum_types::{H256, U256};
|
||||
use parking_lot::Mutex;
|
||||
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::Either;
|
||||
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::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 {
|
||||
fn new_filter(&self, filter: Filter) -> Result<RpcU256> {
|
||||
fn new_filter(&self, filter: Filter) -> Result<U256> {
|
||||
let mut polls = self.polls().lock();
|
||||
let block_number = self.best_block_number();
|
||||
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())
|
||||
}
|
||||
|
||||
fn new_block_filter(&self) -> Result<RpcU256> {
|
||||
fn new_block_filter(&self) -> Result<U256> {
|
||||
let mut polls = self.polls().lock();
|
||||
// +1, since we don't want to include the current 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())
|
||||
}
|
||||
|
||||
fn new_pending_transaction_filter(&self) -> Result<RpcU256> {
|
||||
fn new_pending_transaction_filter(&self) -> Result<U256> {
|
||||
let mut polls = self.polls().lock();
|
||||
let pending_transactions = self.pending_transaction_hashes();
|
||||
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) {
|
||||
Some(hash) => {
|
||||
*last_block_number = n;
|
||||
hashes.push(RpcH256::from(hash));
|
||||
hashes.push(H256::from(hash));
|
||||
// Only keep the most recent history
|
||||
if recent_reported_hashes.len() >= PollFilter::MAX_BLOCK_HISTORY_SIZE {
|
||||
recent_reported_hashes.pop_back();
|
||||
|
||||
@@ -28,7 +28,7 @@ use light::client::LightChainClient;
|
||||
use light::{cht, TransactionQueue};
|
||||
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 parking_lot::{RwLock, Mutex};
|
||||
use rlp::Rlp;
|
||||
@@ -38,17 +38,13 @@ use types::filter::Filter as EthcoreFilter;
|
||||
use types::ids::BlockId;
|
||||
|
||||
use v1::impls::eth_filter::Filterable;
|
||||
use v1::helpers::{errors, limit_logs};
|
||||
use v1::helpers::{SyncPollFilter, PollManager};
|
||||
use v1::helpers::{errors, limit_logs, SyncPollFilter, PollManager};
|
||||
use v1::helpers::deprecated::{self, DeprecationNotice};
|
||||
use v1::helpers::light_fetch::{self, LightFetch};
|
||||
use v1::traits::Eth;
|
||||
use v1::types::{
|
||||
RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes,
|
||||
SyncStatus as RpcSyncStatus, SyncInfo as RpcSyncInfo,
|
||||
Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount,
|
||||
H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256,
|
||||
U64 as RpcU64,
|
||||
RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, SyncStatus as RpcSyncStatus,
|
||||
SyncInfo as RpcSyncInfo, Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount
|
||||
};
|
||||
use v1::metadata::Metadata;
|
||||
|
||||
@@ -251,7 +247,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn author(&self) -> Result<RpcH160> {
|
||||
fn author(&self) -> Result<H160> {
|
||||
(self.accounts)()
|
||||
.first()
|
||||
.cloned()
|
||||
@@ -263,22 +259,19 @@ where
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn chain_id(&self) -> Result<Option<RpcU64>> {
|
||||
Ok(self.client.signing_chain_id().map(RpcU64::from))
|
||||
fn chain_id(&self) -> Result<Option<U64>> {
|
||||
Ok(self.client.signing_chain_id().map(U64::from))
|
||||
}
|
||||
|
||||
fn hashrate(&self) -> Result<RpcU256> {
|
||||
fn hashrate(&self) -> Result<U256> {
|
||||
Ok(Default::default())
|
||||
}
|
||||
|
||||
fn gas_price(&self) -> Result<RpcU256> {
|
||||
Ok(self.cache.lock().gas_price_corpus()
|
||||
.and_then(|c| c.percentile(self.gas_price_percentile).cloned())
|
||||
.map(RpcU256::from)
|
||||
.unwrap_or_else(Default::default))
|
||||
fn gas_price(&self) -> BoxFuture<U256> {
|
||||
Box::new(self.fetcher().gas_price())
|
||||
}
|
||||
|
||||
fn accounts(&self) -> Result<Vec<RpcH160>> {
|
||||
fn accounts(&self) -> Result<Vec<H160>> {
|
||||
self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS);
|
||||
|
||||
Ok((self.accounts)()
|
||||
@@ -287,20 +280,20 @@ where
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn block_number(&self) -> Result<RpcU256> {
|
||||
fn block_number(&self) -> Result<U256> {
|
||||
Ok(self.client.chain_info().best_block_number.into())
|
||||
}
|
||||
|
||||
fn balance(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id())
|
||||
.map(|acc| acc.map_or(0.into(), |a| a.balance).into()))
|
||||
fn balance(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
|
||||
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)))
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -308,12 +301,12 @@ where
|
||||
Box::new(self.rich_block(num.to_block_id(), include_txs).map(Some))
|
||||
}
|
||||
|
||||
fn transaction_count(&self, address: RpcH160, num: Option<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id())
|
||||
.map(|acc| acc.map_or(0.into(), |a| a.nonce).into()))
|
||||
fn transaction_count(&self, address: H160, num: Option<BlockNumber>) -> BoxFuture<U256> {
|
||||
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)))
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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());
|
||||
|
||||
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());
|
||||
|
||||
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());
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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)?;
|
||||
|
||||
Rlp::new(&raw.into_vec()).as_val()
|
||||
@@ -400,12 +393,12 @@ where
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn submit_transaction(&self, raw: Bytes) -> Result<RpcH256> {
|
||||
fn submit_transaction(&self, raw: Bytes) -> Result<H256> {
|
||||
self.send_raw_transaction(raw)
|
||||
}
|
||||
|
||||
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 {
|
||||
Ok(exec) => Ok(exec.output.into()),
|
||||
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.
|
||||
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 {
|
||||
Ok(exec) => Ok((exec.refunded + exec.gas_used).into()),
|
||||
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();
|
||||
|
||||
{
|
||||
@@ -438,7 +431,7 @@ where
|
||||
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| {
|
||||
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();
|
||||
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
|
||||
// already been checked for canonicality and whether it contains
|
||||
// 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();
|
||||
Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| {
|
||||
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)))
|
||||
}
|
||||
|
||||
@@ -528,11 +521,11 @@ where
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
@@ -545,11 +538,11 @@ where
|
||||
{
|
||||
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)
|
||||
}
|
||||
|
||||
fn pending_transaction_hashes(&self) -> BTreeSet<::ethereum_types::H256> {
|
||||
fn pending_transaction_hashes(&self) -> BTreeSet<H256> {
|
||||
BTreeSet::new()
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ use ethkey::{crypto::ecies, Brain, Generator};
|
||||
use ethstore::random_phrase;
|
||||
use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork};
|
||||
use updater::VersionInfo as UpdaterVersionInfo;
|
||||
use ethereum_types::{H64, H160, H256, H512, U64, U256};
|
||||
use ethcore_logger::RotatingLogger;
|
||||
|
||||
use jsonrpc_core::{Result, BoxFuture};
|
||||
@@ -36,7 +37,7 @@ use v1::helpers::light_fetch::{LightFetch, light_all_transactions};
|
||||
use v1::metadata::Metadata;
|
||||
use v1::traits::Parity;
|
||||
use v1::types::{
|
||||
Bytes, U256, U64, H64, H160, H256, H512, CallRequest,
|
||||
Bytes, CallRequest,
|
||||
Peers, Transaction, RpcSettings, Histogram,
|
||||
TransactionStats, LocalTransactionStatus,
|
||||
LightBlockNumber, ChainStatus, Receipt,
|
||||
|
||||
@@ -20,16 +20,17 @@
|
||||
use std::io;
|
||||
use std::sync::Arc;
|
||||
|
||||
use sync::ManageNetwork;
|
||||
use ethereum_types::{H160, H256, U256};
|
||||
use fetch::{self, Fetch};
|
||||
use hash::keccak_buffer;
|
||||
use light::client::LightChainClient;
|
||||
use sync::ManageNetwork;
|
||||
|
||||
use jsonrpc_core::{Result, BoxFuture};
|
||||
use jsonrpc_core::futures::Future;
|
||||
use v1::helpers::errors;
|
||||
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.
|
||||
pub struct ParitySetClient<F> {
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
|
||||
//! Traces api implementation.
|
||||
|
||||
use ethereum_types::H256;
|
||||
use jsonrpc_core::Result;
|
||||
use v1::Metadata;
|
||||
use v1::traits::Traces;
|
||||
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.
|
||||
// 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 crypto::DEFAULT_MAC;
|
||||
use ethereum_types::{Address, H64, H160, H256, H512, U64, U256};
|
||||
use ethcore::client::{BlockChainClient, StateClient, Call};
|
||||
use ethcore::miner::{self, MinerService};
|
||||
use ethcore::snapshot::{SnapshotService, RestorationStatus};
|
||||
use ethcore::state::StateInfo;
|
||||
use ethcore_logger::RotatingLogger;
|
||||
use ethereum_types::Address;
|
||||
use ethkey::{crypto::ecies, Brain, Generator};
|
||||
use ethstore::random_phrase;
|
||||
use jsonrpc_core::futures::future;
|
||||
@@ -41,7 +41,7 @@ use v1::helpers::external_signer::{SigningQueue, SignerService};
|
||||
use v1::metadata::Metadata;
|
||||
use v1::traits::Parity;
|
||||
use v1::types::{
|
||||
Bytes, U256, H64, U64, H160, H256, H512, CallRequest,
|
||||
Bytes, CallRequest,
|
||||
Peers, Transaction, RpcSettings, Histogram,
|
||||
TransactionStats, LocalTransactionStatus,
|
||||
BlockNumber, ConsensusCapability, VersionInfo,
|
||||
|
||||
@@ -20,8 +20,8 @@ use std::collections::{
|
||||
btree_map::{BTreeMap, Entry},
|
||||
HashSet,
|
||||
};
|
||||
use ethereum_types::Address;
|
||||
|
||||
use ethereum_types::{Address, H160, H256, H520};
|
||||
use ethkey::{Brain, Generator, Secret};
|
||||
use ethstore::KeyFile;
|
||||
use accounts::AccountProvider;
|
||||
@@ -29,10 +29,7 @@ use jsonrpc_core::Result;
|
||||
use v1::helpers::deprecated::{self, DeprecationNotice};
|
||||
use v1::helpers::errors;
|
||||
use v1::traits::{ParityAccounts, ParityAccountsInfo};
|
||||
use v1::types::{
|
||||
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Derive, DeriveHierarchical, DeriveHash,
|
||||
ExtAccountInfo, AccountInfo, HwAccountInfo,
|
||||
};
|
||||
use v1::types::{Derive, DeriveHierarchical, DeriveHash,ExtAccountInfo, AccountInfo, HwAccountInfo};
|
||||
use ethkey::Password;
|
||||
|
||||
/// Account management (personal) rpc implementation.
|
||||
@@ -58,7 +55,7 @@ impl 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");
|
||||
|
||||
let dapp_accounts = self.accounts.accounts()
|
||||
@@ -72,18 +69,18 @@ impl ParityAccountsInfo for ParityAccountsClient {
|
||||
.into_iter()
|
||||
.chain(other.into_iter())
|
||||
.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()
|
||||
)
|
||||
}
|
||||
|
||||
fn hardware_accounts_info(&self) -> Result<BTreeMap<RpcH160, HwAccountInfo>> {
|
||||
fn hardware_accounts_info(&self) -> Result<BTreeMap<H160, HwAccountInfo>> {
|
||||
self.deprecation_notice("parity_hardwareAccountsInfo");
|
||||
|
||||
let info = self.accounts.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
|
||||
Ok(info
|
||||
.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()
|
||||
)
|
||||
}
|
||||
@@ -94,7 +91,7 @@ impl ParityAccountsInfo for ParityAccountsClient {
|
||||
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");
|
||||
|
||||
Ok(self.accounts.default_account()
|
||||
@@ -105,9 +102,7 @@ impl ParityAccountsInfo for ParityAccountsClient {
|
||||
}
|
||||
|
||||
impl ParityAccounts for ParityAccountsClient {
|
||||
fn all_accounts_info(&self) -> Result<BTreeMap<RpcH160, ExtAccountInfo>> {
|
||||
self.deprecation_notice("parity_allAccountsInfo");
|
||||
|
||||
fn all_accounts_info(&self) -> Result<BTreeMap<H160, ExtAccountInfo>> {
|
||||
let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
|
||||
let other = self.accounts.addresses_info();
|
||||
|
||||
@@ -120,7 +115,7 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
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 {
|
||||
match accounts.entry(address) {
|
||||
@@ -138,27 +133,24 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
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");
|
||||
|
||||
let brain = Brain::new(phrase).generate().unwrap();
|
||||
self.accounts.insert_account(brain.secret().clone(), &pass)
|
||||
.map(Into::into)
|
||||
.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.accounts.import_presale(json.as_bytes(), &pass)
|
||||
.or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true))
|
||||
.map(Into::into)
|
||||
.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");
|
||||
|
||||
let secret = Secret::from_unsafe_slice(&secret.0)
|
||||
.map_err(|e| errors::account("Could not create account.", e))?;
|
||||
self.accounts.insert_account(secret, &pass)
|
||||
@@ -166,9 +158,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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");
|
||||
|
||||
let account: Address = account.into();
|
||||
|
||||
self.accounts
|
||||
@@ -176,9 +167,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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");
|
||||
|
||||
let account: Address = account.into();
|
||||
self.accounts
|
||||
.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))
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
let account: Address = account.into();
|
||||
self.accounts
|
||||
.kill_account(&account, &password)
|
||||
@@ -196,18 +185,16 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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");
|
||||
|
||||
let addr: Address = addr.into();
|
||||
|
||||
self.accounts.remove_address(addr);
|
||||
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");
|
||||
|
||||
let addr: Address = addr.into();
|
||||
|
||||
self.accounts.set_account_name(addr.clone(), name.clone())
|
||||
@@ -215,9 +202,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
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");
|
||||
|
||||
let addr: Address = addr.into();
|
||||
|
||||
self.accounts.set_account_meta(addr.clone(), meta.clone())
|
||||
@@ -225,18 +211,16 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
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.accounts
|
||||
.import_geth_accounts(into_vec(addresses), false)
|
||||
.map(into_vec)
|
||||
.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");
|
||||
|
||||
Ok(into_vec(self.accounts.list_geth_accounts(false)))
|
||||
}
|
||||
|
||||
@@ -292,9 +276,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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.accounts
|
||||
.change_vault(address.into(), &new_vault)
|
||||
.map_err(|e| errors::account("Could not change vault.", e))
|
||||
@@ -318,9 +301,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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");
|
||||
|
||||
let addr: Address = addr.into();
|
||||
self.accounts
|
||||
.derive_account(
|
||||
@@ -333,9 +315,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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");
|
||||
|
||||
let addr: Address = addr.into();
|
||||
self.accounts
|
||||
.derive_account(
|
||||
@@ -348,9 +329,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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");
|
||||
|
||||
let addr = addr.into();
|
||||
self.accounts
|
||||
.export_account(
|
||||
@@ -361,9 +341,8 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
.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.accounts
|
||||
.sign(
|
||||
addr.into(),
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::time::Duration;
|
||||
|
||||
use ethcore::client::{BlockChainClient, Mode};
|
||||
use ethcore::miner::{self, MinerService};
|
||||
use ethereum_types::H256 as EthH256;
|
||||
use ethereum_types::{H160, H256, U256};
|
||||
use ethkey;
|
||||
use fetch::{self, Fetch};
|
||||
use hash::keccak_buffer;
|
||||
@@ -32,7 +32,7 @@ use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_core::futures::Future;
|
||||
use v1::helpers::errors;
|
||||
use v1::traits::ParitySet;
|
||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
|
||||
use v1::types::{Bytes, ReleaseInfo, Transaction};
|
||||
|
||||
#[cfg(any(test, feature = "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> {
|
||||
let secret: EthH256 = secret.into();
|
||||
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)));
|
||||
Ok(true)
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::time::Duration;
|
||||
use accounts::AccountProvider;
|
||||
use bytes::Bytes;
|
||||
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 types::transaction::{PendingTransaction, SignedTransaction};
|
||||
|
||||
@@ -34,7 +34,6 @@ use v1::helpers::{errors, eip191};
|
||||
use v1::metadata::Metadata;
|
||||
use v1::traits::Personal;
|
||||
use v1::types::{
|
||||
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128,
|
||||
Bytes as RpcBytes,
|
||||
ConfirmationPayload as RpcConfirmationPayload,
|
||||
ConfirmationResponse as RpcConfirmationResponse,
|
||||
@@ -108,24 +107,21 @@ impl<D: Dispatcher + 'static> PersonalClient<D> {
|
||||
impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn accounts(&self) -> Result<Vec<RpcH160>> {
|
||||
fn accounts(&self) -> Result<Vec<H160>> {
|
||||
self.deprecation_notice.print("personal_accounts", deprecated::msgs::ACCOUNTS);
|
||||
|
||||
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.accounts.new_account(&pass.into())
|
||||
.map(Into::into)
|
||||
.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);
|
||||
|
||||
let account: Address = account.into();
|
||||
let store = self.accounts.clone();
|
||||
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);
|
||||
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
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);
|
||||
|
||||
try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "191"));
|
||||
|
||||
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);
|
||||
|
||||
try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "712"));
|
||||
|
||||
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 = Signature::from_electrum(&signature);
|
||||
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)))
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
let condition = request.condition.clone().map(Into::into);
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
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(
|
||||
PendingTransaction::new(
|
||||
signed.into_value(),
|
||||
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."));
|
||||
|
||||
warn!("Using deprecated personal_signAndSendTransaction, use personal_sendTransaction instead.");
|
||||
self.send_transaction(meta, request, password)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ use std::sync::Arc;
|
||||
use rlp::Rlp;
|
||||
|
||||
use ethcore_private_tx::Provider as PrivateTransactionManager;
|
||||
use ethereum_types::Address;
|
||||
use ethereum_types::{Address, H160, H256, U256};
|
||||
use types::transaction::SignedTransaction;
|
||||
|
||||
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};
|
||||
use v1::traits::Private;
|
||||
use v1::metadata::Metadata;
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crypto::DEFAULT_MAC;
|
||||
use ethkey::Secret;
|
||||
use accounts::AccountProvider;
|
||||
use crypto::DEFAULT_MAC;
|
||||
use ethereum_types::{H160, H256, H512};
|
||||
use ethkey::Secret;
|
||||
|
||||
use jsonrpc_core::Result;
|
||||
use v1::helpers::errors;
|
||||
use v1::helpers::secretstore::{generate_document_key, encrypt_document,
|
||||
decrypt_document, decrypt_document_with_shadow, ordered_servers_keccak};
|
||||
use v1::traits::SecretStore;
|
||||
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey};
|
||||
use v1::types::{Bytes, EncryptedDocumentKey};
|
||||
use ethkey::Password;
|
||||
|
||||
/// Parity implementation.
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethereum_types::U256;
|
||||
use ethkey;
|
||||
use parity_runtime::Executor;
|
||||
use parking_lot::Mutex;
|
||||
@@ -34,7 +35,7 @@ use v1::helpers::{errors, ConfirmationPayload, FilledTransactionRequest, Subscri
|
||||
use v1::helpers::external_signer::{SigningQueue, SignerService};
|
||||
use v1::metadata::Metadata;
|
||||
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.
|
||||
pub struct SignerClient<D: Dispatcher> {
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
use transient_hashmap::TransientHashMap;
|
||||
use ethereum_types::U256;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use ethereum_types::{H160, H256, H520, U256};
|
||||
|
||||
use jsonrpc_core::{BoxFuture, Result, Error};
|
||||
use jsonrpc_core::futures::{future, Future, Poll, Async};
|
||||
use jsonrpc_core::futures::future::Either;
|
||||
@@ -36,7 +37,7 @@ use v1::helpers::external_signer::{
|
||||
use v1::metadata::Metadata;
|
||||
use v1::traits::{EthSigning, ParitySigning};
|
||||
use v1::types::{
|
||||
H160 as RpcH160, H256 as RpcH256, U256 as RpcU256, Bytes as RpcBytes, H520 as RpcH520,
|
||||
Bytes as RpcBytes,
|
||||
Either as RpcEither,
|
||||
RichRawTransaction as RpcRichRawTransaction,
|
||||
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))
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
let executor = self.executor.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);
|
||||
|
||||
let executor = self.executor.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);
|
||||
|
||||
let id: U256 = id.into();
|
||||
match self.confirmations.lock().get(&id) {
|
||||
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);
|
||||
|
||||
let res = self.dispatch(
|
||||
RpcConfirmationPayload::Decrypt((address.clone(), data).into()),
|
||||
meta.origin,
|
||||
@@ -208,9 +205,8 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
|
||||
impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
|
||||
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);
|
||||
|
||||
let res = self.dispatch(
|
||||
RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()),
|
||||
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);
|
||||
|
||||
let res = self.dispatch(
|
||||
RpcConfirmationPayload::SendTransaction(request),
|
||||
meta.origin,
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethereum_types::Address;
|
||||
|
||||
use ethereum_types::{Address, H160, H256, H520, U256};
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_core::futures::{future, Future};
|
||||
use v1::helpers::{errors};
|
||||
@@ -28,8 +27,7 @@ use v1::helpers::dispatch::{self, Dispatcher};
|
||||
use v1::metadata::Metadata;
|
||||
use v1::traits::{EthSigning, ParitySigning};
|
||||
use v1::types::{
|
||||
U256 as RpcU256,
|
||||
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Bytes as RpcBytes,
|
||||
Bytes as RpcBytes,
|
||||
Either as RpcEither,
|
||||
RichRawTransaction as RpcRichRawTransaction,
|
||||
TransactionRequest as RpcTransactionRequest,
|
||||
@@ -70,9 +68,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
|
||||
{
|
||||
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);
|
||||
|
||||
Box::new(self.handle(RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), address.into())
|
||||
.then(|res| match res {
|
||||
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);
|
||||
|
||||
Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), self.accounts.default_account())
|
||||
.then(|res| match res {
|
||||
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))
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Box::new(self.handle(RpcConfirmationPayload::Decrypt((address.clone(), data).into()), address.into())
|
||||
.then(|res| match res {
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
Err(errors::signer_disabled())
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId};
|
||||
use ethereum_types::H256;
|
||||
use rlp::Rlp;
|
||||
use types::transaction::SignedTransaction;
|
||||
|
||||
@@ -26,7 +27,8 @@ use jsonrpc_core::Result;
|
||||
use v1::Metadata;
|
||||
use v1::traits::Traces;
|
||||
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 {
|
||||
CallAnalytics {
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Web3 rpc implementation.
|
||||
use ethereum_types::H256;
|
||||
use hash::keccak;
|
||||
use jsonrpc_core::Result;
|
||||
use version::version;
|
||||
use v1::traits::Web3;
|
||||
use v1::types::{H256, Bytes};
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// Web3 rpc implementation.
|
||||
pub struct Web3Client;
|
||||
|
||||
@@ -53,5 +53,5 @@ pub mod signer {
|
||||
#[cfg(any(test, feature = "accounts"))]
|
||||
pub use super::helpers::engine_signer::EngineSigner;
|
||||
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::verification::VerifierType;
|
||||
use ethcore::verification::queue::kind::blocks::Unverified;
|
||||
use ethereum_types::{H256, Address};
|
||||
use ethereum_types::{Address, H256, U256};
|
||||
use ethjson::blockchain::BlockChain;
|
||||
use ethjson::spec::ForkSpec;
|
||||
use io::IoChannel;
|
||||
@@ -42,7 +42,6 @@ use v1::impls::{EthClient, EthClientOptions, SigningUnsafeClient};
|
||||
use v1::metadata::Metadata;
|
||||
use v1::tests::helpers::{TestSnapshotService, TestSyncProvider, Config};
|
||||
use v1::traits::{Eth, EthSigning};
|
||||
use v1::types::U256 as NU256;
|
||||
|
||||
fn account_provider() -> Arc<AccountProvider> {
|
||||
Arc::new(AccountProvider::transient_provider())
|
||||
@@ -459,7 +458,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "eth_getBlockTransactionCountByNumber",
|
||||
"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#"
|
||||
}"#;
|
||||
|
||||
@@ -18,8 +18,8 @@ use std::sync::Arc;
|
||||
use std::str::FromStr;
|
||||
|
||||
use bytes::ToPretty;
|
||||
use ethereum_types::{U256, Address};
|
||||
use accounts::AccountProvider;
|
||||
use ethereum_types::{Address, H520, U256};
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
use jsonrpc_core::IoHandler;
|
||||
use parking_lot::Mutex;
|
||||
@@ -31,7 +31,7 @@ use v1::{PersonalClient, Personal, Metadata};
|
||||
use v1::helpers::{nonce, eip191};
|
||||
use v1::helpers::dispatch::{eth_data_hash, FullDispatcher};
|
||||
use v1::tests::helpers::TestMinerService;
|
||||
use v1::types::{EIP191Version, PresignedTransaction, H520};
|
||||
use v1::types::{EIP191Version, PresignedTransaction};
|
||||
use rustc_hex::ToHex;
|
||||
use serde_json::to_value;
|
||||
use ethkey::Secret;
|
||||
@@ -156,7 +156,7 @@ fn sign() {
|
||||
|
||||
let hash = eth_data_hash(data);
|
||||
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}"#;
|
||||
|
||||
@@ -264,7 +264,7 @@ fn ec_recover() {
|
||||
|
||||
let hash = eth_data_hash(data.clone());
|
||||
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#"{
|
||||
"jsonrpc": "2.0",
|
||||
|
||||
@@ -18,6 +18,7 @@ use std::sync::Arc;
|
||||
|
||||
use crypto::DEFAULT_MAC;
|
||||
use accounts::AccountProvider;
|
||||
use ethereum_types::H256;
|
||||
use ethkey::{KeyPair, Signature, verify_public};
|
||||
|
||||
use serde_json;
|
||||
@@ -26,7 +27,7 @@ use v1::metadata::Metadata;
|
||||
use v1::SecretStoreClient;
|
||||
use v1::traits::secretstore::SecretStore;
|
||||
use v1::helpers::secretstore::ordered_servers_keccak;
|
||||
use v1::types::{H256, EncryptedDocumentKey};
|
||||
use v1::types::EncryptedDocumentKey;
|
||||
|
||||
struct Dependencies {
|
||||
pub accounts: Arc<AccountProvider>,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::str::FromStr;
|
||||
use ethereum_types::{U256, Address};
|
||||
use ethereum_types::{H520, U256, Address};
|
||||
use bytes::ToPretty;
|
||||
|
||||
use accounts::AccountProvider;
|
||||
@@ -31,7 +31,7 @@ use jsonrpc_core::IoHandler;
|
||||
use v1::{SignerClient, Signer, Origin};
|
||||
use v1::metadata::Metadata;
|
||||
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::external_signer::{SigningQueue, SignerService};
|
||||
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 signature = H520(tester.accounts.sign(address, Some("test".into()), data_hash).unwrap().into_electrum());
|
||||
let signature = format!("0x{:?}", signature);
|
||||
let signature = format!("{:?}", signature);
|
||||
|
||||
// when
|
||||
let request = r#"{
|
||||
|
||||
@@ -210,7 +210,7 @@ fn rpc_eth_send_transaction_with_bad_to() {
|
||||
"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()));
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
//! Eth rpc interface.
|
||||
use jsonrpc_core::{Result, BoxFuture};
|
||||
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::{Log, Receipt, SyncStatus, Transaction, Work};
|
||||
use v1::types::{H64, H160, H256, U256, U64};
|
||||
|
||||
/// Eth rpc interface.
|
||||
#[rpc]
|
||||
@@ -56,7 +56,7 @@ pub trait Eth {
|
||||
|
||||
/// Returns current gas_price.
|
||||
#[rpc(name = "eth_gasPrice")]
|
||||
fn gas_price(&self) -> Result<U256>;
|
||||
fn gas_price(&self) -> BoxFuture<U256>;
|
||||
|
||||
/// Returns accounts list.
|
||||
#[rpc(name = "eth_accounts")]
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
use jsonrpc_core::BoxFuture;
|
||||
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.
|
||||
#[rpc]
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ethereum_types::{H64, H160, H256, H512, U64, U256};
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_derive::rpc;
|
||||
use v1::types::{
|
||||
H160, H256, H512, U256, U64, H64, Bytes, CallRequest,
|
||||
Bytes, CallRequest,
|
||||
Peers, Transaction, RpcSettings, Histogram, RecoveredAccount,
|
||||
TransactionStats, LocalTransactionStatus,
|
||||
BlockNumber, ConsensusCapability, VersionInfo,
|
||||
|
||||
@@ -19,9 +19,10 @@ use std::collections::BTreeMap;
|
||||
|
||||
use jsonrpc_core::Result;
|
||||
use jsonrpc_derive::rpc;
|
||||
use ethereum_types::{H160, H256, H520};
|
||||
use ethkey::Password;
|
||||
use ethstore::KeyFile;
|
||||
use v1::types::{H160, H256, H520, DeriveHash, DeriveHierarchical, ExtAccountInfo};
|
||||
use v1::types::{DeriveHash, DeriveHierarchical, ExtAccountInfo};
|
||||
use v1::types::{AccountInfo, HwAccountInfo};
|
||||
|
||||
/// Parity-specific read-only accounts rpc interface.
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
//! Parity-specific rpc interface for operations altering the settings.
|
||||
|
||||
use ethereum_types::{H160, H256, U256};
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
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.
|
||||
#[rpc]
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
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.
|
||||
#[rpc]
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
//! Personal rpc interface.
|
||||
use eip_712::EIP712;
|
||||
use ethereum_types::{H160, H256, H520, U128};
|
||||
use jsonrpc_core::types::Value;
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
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.
|
||||
#[rpc]
|
||||
@@ -70,5 +71,4 @@ pub trait Personal {
|
||||
/// @deprecated alias for `personal_sendTransaction`.
|
||||
#[rpc(meta, name = "personal_signAndSendTransaction")]
|
||||
fn sign_and_send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture<H256>;
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
//! SecretStore-specific rpc interface.
|
||||
|
||||
use ethereum_types::{H160, H256, U256};
|
||||
use jsonrpc_core::Error;
|
||||
use jsonrpc_derive::rpc;
|
||||
|
||||
use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, U256, BlockNumber,
|
||||
use v1::types::{Bytes, PrivateTransactionReceipt, BlockNumber,
|
||||
PrivateTransactionReceiptAndTransaction, CallRequest};
|
||||
|
||||
/// Private transaction management RPC interface.
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
//! SecretStore-specific rpc interface.
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use jsonrpc_core::Result;
|
||||
use jsonrpc_derive::rpc;
|
||||
use ethereum_types::{H160, H256, H512};
|
||||
use ethkey::Password;
|
||||
|
||||
use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey};
|
||||
use v1::types::{Bytes, EncryptedDocumentKey};
|
||||
|
||||
/// Parity-specific rpc interface.
|
||||
#[rpc]
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Parity Signer-related rpc interface.
|
||||
|
||||
use ethereum_types::U256;
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId};
|
||||
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.
|
||||
#[rpc]
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
//! Traces specific rpc interface.
|
||||
|
||||
use ethereum_types::H256;
|
||||
use jsonrpc_core::Result;
|
||||
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.
|
||||
#[rpc]
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Web3 rpc interface.
|
||||
use ethereum_types::H256;
|
||||
use jsonrpc_core::Result;
|
||||
use jsonrpc_derive::rpc;
|
||||
|
||||
use v1::types::{H256, Bytes};
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// Web3 rpc interface.
|
||||
#[rpc]
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
//! Return types for RPC calls
|
||||
|
||||
use ethereum_types::{Public, Address};
|
||||
use v1::types::{H160, H256, U256, Bytes};
|
||||
use ethereum_types::{Public, Address, H160, H256, U256};
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// Account information.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
use std::ops::Deref;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ethereum_types::{H160, H256, U256, Bloom as H2048};
|
||||
use serde::ser::Error;
|
||||
use serde::{Serialize, Serializer};
|
||||
use types::encoded::Header as EthHeader;
|
||||
|
||||
use v1::types::{Bytes, Transaction, H160, H256, H2048, U256};
|
||||
use v1::types::{Bytes, Transaction};
|
||||
|
||||
/// Block Transactions
|
||||
#[derive(Debug)]
|
||||
@@ -205,8 +205,9 @@ impl<T: Serialize> Serialize for Rich<T> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
use ethereum_types::{H64, H160, H256, U256, Bloom as H2048};
|
||||
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};
|
||||
|
||||
#[test]
|
||||
@@ -248,8 +249,8 @@ mod tests {
|
||||
let rich_block = RichBlock {
|
||||
inner: block,
|
||||
extra_info: map![
|
||||
"mixHash".into() => format!("0x{:?}", H256::default()),
|
||||
"nonce".into() => format!("0x{:?}", H64::default())
|
||||
"mixHash".into() => format!("{:?}", H256::default()),
|
||||
"nonce".into() => format!("{:?}", H64::default())
|
||||
],
|
||||
};
|
||||
let serialized_rich_block = serde_json::to_string(&rich_block).unwrap();
|
||||
@@ -286,8 +287,8 @@ mod tests {
|
||||
let rich_block = RichBlock {
|
||||
inner: block,
|
||||
extra_info: map![
|
||||
"mixHash".into() => format!("0x{:?}", H256::default()),
|
||||
"nonce".into() => format!("0x{:?}", H64::default())
|
||||
"mixHash".into() => format!("{:?}", H256::default()),
|
||||
"nonce".into() => format!("{:?}", H64::default())
|
||||
],
|
||||
};
|
||||
let serialized_rich_block = serde_json::to_string(&rich_block).unwrap();
|
||||
@@ -321,8 +322,8 @@ mod tests {
|
||||
let rich_header = RichHeader {
|
||||
inner: header,
|
||||
extra_info: map![
|
||||
"mixHash".into() => format!("0x{:?}", H256::default()),
|
||||
"nonce".into() => format!("0x{:?}", H64::default())
|
||||
"mixHash".into() => format!("{:?}", H256::default()),
|
||||
"nonce".into() => format!("{:?}", H64::default())
|
||||
],
|
||||
};
|
||||
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
|
||||
// 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::types::{Bytes, H160, U256};
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// Call request
|
||||
#[derive(Debug, Default, PartialEq, Deserialize)]
|
||||
@@ -57,7 +58,7 @@ mod tests {
|
||||
use std::str::FromStr;
|
||||
use rustc_hex::FromHex;
|
||||
use serde_json;
|
||||
use v1::types::{U256, H160};
|
||||
use ethereum_types::{U256, H160};
|
||||
use super::CallRequest;
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -21,7 +21,8 @@ use serde::{Serialize, Serializer};
|
||||
use ansi_term::Colour;
|
||||
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 ethkey::Password;
|
||||
|
||||
@@ -281,8 +282,9 @@ impl<A, B> Serialize for Either<A, B> where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
use ethereum_types::{H256, U256};
|
||||
use serde_json;
|
||||
use v1::types::{U256, H256, TransactionCondition};
|
||||
use v1::types::TransactionCondition;
|
||||
use v1::helpers;
|
||||
use super::*;
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// 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 ethereum_types::{H160, H256};
|
||||
use semver;
|
||||
use v1::types::{H160, H256};
|
||||
use updater::{self, CapState};
|
||||
|
||||
/// Capability info
|
||||
|
||||
@@ -18,10 +18,9 @@ use std::fmt;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde::de::{Error, Visitor};
|
||||
|
||||
use ethereum_types::H256;
|
||||
use ethstore;
|
||||
|
||||
use super::hash::H256;
|
||||
|
||||
/// Type of derivation
|
||||
pub enum DerivationType {
|
||||
/// Soft - allow proof of parent
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! EIP-191 specific types
|
||||
|
||||
use ethereum_types::H160;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde::de;
|
||||
use v1::types::{H160, Bytes};
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// EIP-191 version specifier
|
||||
#[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
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ethereum_types::{H160, H256};
|
||||
use jsonrpc_core::{Error as RpcError};
|
||||
use serde::de::{Error, DeserializeOwned};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
@@ -21,7 +22,7 @@ use serde_json::{Value, from_value};
|
||||
use types::filter::Filter as EthFilter;
|
||||
use types::ids::BlockId;
|
||||
|
||||
use v1::types::{BlockNumber, H160, H256, Log};
|
||||
use v1::types::{BlockNumber, Log};
|
||||
use v1::helpers::errors::invalid_params;
|
||||
|
||||
/// 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.
|
||||
|
||||
use v1::types::U256;
|
||||
use ethereum_types::U256;
|
||||
|
||||
/// Values of RPC settings.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
// 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 ethereum_types::{H160, H256, U256};
|
||||
use types::log_entry::{LocalizedLogEntry, LogEntry};
|
||||
use v1::types::{Bytes, H160, H256, U256};
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// Log
|
||||
#[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone)]
|
||||
@@ -87,7 +88,8 @@ impl From<LogEntry> for Log {
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use std::str::FromStr;
|
||||
use v1::types::{Log, H160, H256, U256};
|
||||
use v1::types::Log;
|
||||
use ethereum_types::{H160, H256, U256};
|
||||
|
||||
#[test]
|
||||
fn log_serialization() {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
//! RPC types
|
||||
|
||||
#[cfg(test)]
|
||||
mod eth_types;
|
||||
|
||||
mod account_info;
|
||||
mod block;
|
||||
mod block_number;
|
||||
@@ -25,7 +28,6 @@ mod confirmations;
|
||||
mod consensus_status;
|
||||
mod derivation;
|
||||
mod filter;
|
||||
mod hash;
|
||||
mod histogram;
|
||||
mod index;
|
||||
mod log;
|
||||
@@ -40,7 +42,6 @@ mod trace_filter;
|
||||
mod transaction;
|
||||
mod transaction_request;
|
||||
mod transaction_condition;
|
||||
mod uint;
|
||||
mod work;
|
||||
mod private_receipt;
|
||||
mod eip191;
|
||||
@@ -60,7 +61,6 @@ pub use self::confirmations::{
|
||||
pub use self::consensus_status::*;
|
||||
pub use self::derivation::{DeriveHash, DeriveHierarchical, Derive};
|
||||
pub use self::filter::{Filter, FilterChanges};
|
||||
pub use self::hash::{H64, H160, H256, H512, H520, H2048};
|
||||
pub use self::histogram::Histogram;
|
||||
pub use self::index::Index;
|
||||
pub use self::log::Log;
|
||||
@@ -78,7 +78,6 @@ pub use self::trace_filter::TraceFilter;
|
||||
pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus};
|
||||
pub use self::transaction_request::TransactionRequest;
|
||||
pub use self::transaction_condition::TransactionCondition;
|
||||
pub use self::uint::{U128, U256, U64};
|
||||
pub use self::work::Work;
|
||||
pub use self::private_receipt::{PrivateTransactionReceipt, PrivateTransactionReceiptAndTransaction};
|
||||
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
// 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 v1::types::{H160, H256, TransactionRequest};
|
||||
use ethcore_private_tx::{Receipt as EthPrivateReceipt};
|
||||
use ethereum_types::{H160, H256};
|
||||
use v1::types::TransactionRequest;
|
||||
|
||||
/// Receipt
|
||||
#[derive(Debug, Serialize)]
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Request Provenance
|
||||
|
||||
use std::fmt;
|
||||
use v1::types::H256;
|
||||
use ethereum_types::H256;
|
||||
|
||||
/// RPC request origin
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
//! Pub-Sub types.
|
||||
|
||||
use ethereum_types::H256;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::Error;
|
||||
use serde_json::{Value, from_value};
|
||||
use v1::types::{RichHeader, Filter, Log, H256};
|
||||
use v1::types::{RichHeader, Filter, Log};
|
||||
|
||||
/// Subscription result.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
// 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 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};
|
||||
|
||||
/// Receipt
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
// 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 v1::types::{Bytes, H512};
|
||||
use ethereum_types::H512;
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// Encrypted document key.
|
||||
#[derive(Default, Debug, Serialize, PartialEq)]
|
||||
@@ -22,7 +23,7 @@ use v1::types::{Bytes, H512};
|
||||
pub struct EncryptedDocumentKey {
|
||||
/// Common encryption point. Pass this to Secret Store 'Document key storing session'
|
||||
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,
|
||||
/// Document key itself, encrypted with passed account public. Pass this to 'secretstore_encrypt'.
|
||||
pub encrypted_key: Bytes,
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
use network::client_version::ClientVersion;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ethereum_types::{U256, H512};
|
||||
use sync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats};
|
||||
use serde::{Serialize, Serializer};
|
||||
use v1::types::{U256, H512};
|
||||
|
||||
/// Sync info
|
||||
#[derive(Default, Debug, Serialize, PartialEq)]
|
||||
|
||||
@@ -19,14 +19,14 @@ use std::collections::BTreeMap;
|
||||
use ethcore::client::Executed;
|
||||
use ethcore::trace as et;
|
||||
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::{Serialize, Serializer};
|
||||
use types::account_diff;
|
||||
use types::state_diff;
|
||||
use vm;
|
||||
|
||||
use v1::types::{Bytes, H160, H256, U256};
|
||||
use v1::types::Bytes;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
/// A diff of some chunk of memory.
|
||||
@@ -639,8 +639,8 @@ pub struct TraceResultsWithTransactionHash {
|
||||
pub transaction_hash: H256,
|
||||
}
|
||||
|
||||
impl From<(EthH256, Executed)> for TraceResultsWithTransactionHash {
|
||||
fn from(t: (EthH256, Executed)) -> Self {
|
||||
impl From<(H256, Executed)> for TraceResultsWithTransactionHash {
|
||||
fn from(t: (H256, Executed)) -> Self {
|
||||
TraceResultsWithTransactionHash {
|
||||
output: t.1.output.into(),
|
||||
trace: t.1.trace.into_iter().map(Into::into).collect(),
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
use ethcore::client::BlockId;
|
||||
use ethcore::client;
|
||||
use v1::types::{BlockNumber, H160};
|
||||
use ethereum_types::H160;
|
||||
use v1::types::BlockNumber;
|
||||
|
||||
/// Trace filter
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
|
||||
@@ -19,9 +19,10 @@ use std::sync::Arc;
|
||||
use serde::{Serialize, Serializer};
|
||||
use serde::ser::SerializeStruct;
|
||||
use ethcore::{contract_address, CreateContractAddress};
|
||||
use ethereum_types::{H160, H256, H512, U64, U256};
|
||||
use miner;
|
||||
use types::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
|
||||
use v1::types::{Bytes, H160, H256, U256, H512, U64, TransactionCondition};
|
||||
use v1::types::{Bytes, TransactionCondition};
|
||||
|
||||
/// Transaction
|
||||
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
//! `TransactionRequest` type
|
||||
|
||||
use v1::types::{Bytes, H160, U256, TransactionCondition};
|
||||
use ethereum_types::{H160, U256};
|
||||
use v1::types::{Bytes, TransactionCondition};
|
||||
use v1::helpers;
|
||||
use ansi_term::Colour;
|
||||
|
||||
@@ -137,7 +138,8 @@ mod tests {
|
||||
use std::str::FromStr;
|
||||
use rustc_hex::FromHex;
|
||||
use serde_json;
|
||||
use v1::types::{U256, H160, TransactionCondition};
|
||||
use v1::types::TransactionCondition;
|
||||
use ethereum_types::{H160, U256};
|
||||
use super::*;
|
||||
|
||||
#[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()));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user