private-tx: replace error_chain (#10510)

* Update to vanilla tx pool error

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

* private-tx: replace ErrorKind and bail!

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

* private-tx: use original tx-pool error

* Don't be silly cargo
This commit is contained in:
Andrew Jones 2019-03-27 13:46:05 +00:00 committed by soc1c
parent 3b23817936
commit 7d26a82232
7 changed files with 199 additions and 196 deletions

14
Cargo.lock generated
View File

@ -513,6 +513,17 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "derive_more"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "difference" name = "difference"
version = "1.0.0" version = "1.0.0"
@ -1006,8 +1017,8 @@ name = "ethcore-private-tx"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"common-types 0.1.0", "common-types 0.1.0",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -4513,6 +4524,7 @@ dependencies = [
"checksum csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dd8e6d86f7ba48b4276ef1317edc8cc36167546d8972feb4a2b5fec0b374105" "checksum csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dd8e6d86f7ba48b4276ef1317edc8cc36167546d8972feb4a2b5fec0b374105"
"checksum ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b4660f8b07a560a88c02d76286edb9f0d5d64e495d2b0f233186155aa51be1f" "checksum ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b4660f8b07a560a88c02d76286edb9f0d5d64e495d2b0f233186155aa51be1f"
"checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "<none>" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "<none>"
"checksum derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbe9f11be34f800b3ecaaed0ec9ec2e015d1d0ba0c8644c1310f73d6e8994615"
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
"checksum docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db2906c2579b5b7207fc1e328796a9a8835dc44e22dbe8e460b1d636f9a7b225" "checksum docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db2906c2579b5b7207fc1e328796a9a8835dc44e22dbe8e460b1d636f9a7b225"

View File

@ -7,7 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
common-types = { path = "../types" } common-types = { path = "../types" }
error-chain = { version = "0.12", default-features = false } derive_more = "0.14.0"
ethabi = "6.0" ethabi = "6.0"
ethabi-contract = "6.0" ethabi-contract = "6.0"
ethabi-derive = "6.0" ethabi-derive = "6.0"

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@ use parking_lot::RwLock;
use types::transaction::{UnverifiedTransaction, SignedTransaction}; use types::transaction::{UnverifiedTransaction, SignedTransaction};
use txpool; use txpool;
use txpool::{VerifiedTransaction, Verifier}; use txpool::{VerifiedTransaction, Verifier};
use error::{Error, ErrorKind}; use error::Error;
type Pool = txpool::Pool<VerifiedPrivateTransaction, pool::scoring::NonceAndGasPrice>; type Pool = txpool::Pool<VerifiedPrivateTransaction, pool::scoring::NonceAndGasPrice>;
@ -228,7 +228,7 @@ impl SigningStore {
contract_nonce: U256, contract_nonce: U256,
) -> Result<(), Error> { ) -> Result<(), Error> {
if self.transactions.len() > MAX_QUEUE_LEN { if self.transactions.len() > MAX_QUEUE_LEN {
bail!(ErrorKind::QueueIsFull); return Err(Error::QueueIsFull);
} }
self.transactions.insert(private_hash, PrivateTransactionSigningDesc { self.transactions.insert(private_hash, PrivateTransactionSigningDesc {
@ -254,7 +254,7 @@ impl SigningStore {
/// Adds received signature for the stored private transaction /// Adds received signature for the stored private transaction
pub fn add_signature(&mut self, private_hash: &H256, signature: Signature) -> Result<(), Error> { pub fn add_signature(&mut self, private_hash: &H256, signature: Signature) -> Result<(), Error> {
let desc = self.transactions.get_mut(private_hash).ok_or_else(|| ErrorKind::PrivateTransactionNotFound)?; let desc = self.transactions.get_mut(private_hash).ok_or_else(|| Error::PrivateTransactionNotFound)?;
if !desc.received_signatures.contains(&signature) { if !desc.received_signatures.contains(&signature) {
desc.received_signatures.push(signature); desc.received_signatures.push(signature);
} }

View File

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