Merge pull request #1290 from ethcore/send-tx-errors
More meaningful errors when sending transaction
This commit is contained in:
commit
10bbe8c8a2
42
Cargo.lock
generated
42
Cargo.lock
generated
@ -72,7 +72,7 @@ dependencies = [
|
|||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -234,7 +234,7 @@ dependencies = [
|
|||||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ dependencies = [
|
|||||||
"ethcore-rpc 1.2.0",
|
"ethcore-rpc 1.2.0",
|
||||||
"ethcore-util 1.2.0",
|
"ethcore-util 1.2.0",
|
||||||
"hyper 0.9.3 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.9.3 (git+https://github.com/ethcore/hyper)",
|
||||||
"jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
|
"jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -291,8 +291,8 @@ dependencies = [
|
|||||||
"parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)",
|
"parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)",
|
||||||
"parity-dapps-wallet 0.6.1 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)",
|
"parity-dapps-wallet 0.6.1 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -331,7 +331,7 @@ name = "ethcore-ipc-nano"
|
|||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-ipc 1.2.0",
|
"ethcore-ipc 1.2.0",
|
||||||
"jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||||
]
|
]
|
||||||
@ -348,12 +348,12 @@ dependencies = [
|
|||||||
"ethjson 0.1.0",
|
"ethjson 0.1.0",
|
||||||
"ethsync 1.2.0",
|
"ethsync 1.2.0",
|
||||||
"json-ipc-server 0.2.3 (git+https://github.com/ethcore/json-ipc-server.git)",
|
"json-ipc-server 0.2.3 (git+https://github.com/ethcore/json-ipc-server.git)",
|
||||||
"jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
|
"jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -367,7 +367,7 @@ dependencies = [
|
|||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-rpc 1.2.0",
|
"ethcore-rpc 1.2.0",
|
||||||
"ethcore-util 1.2.0",
|
"ethcore-util 1.2.0",
|
||||||
"jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-minimal-sysui 0.1.0 (git+https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git)",
|
"parity-minimal-sysui 0.1.0 (git+https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -402,7 +402,7 @@ dependencies = [
|
|||||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sha3 0.1.0",
|
"sha3 0.1.0",
|
||||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -417,8 +417,8 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-util 1.2.0",
|
"ethcore-util 1.2.0",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -576,7 +576,7 @@ source = "git+https://github.com/ethcore/json-ipc-server.git#b224bdbcb53cab349c2
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -594,11 +594,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-core"
|
name = "jsonrpc-core"
|
||||||
version = "2.0.5"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -609,7 +609,7 @@ version = "5.1.0"
|
|||||||
source = "git+https://github.com/ethcore/jsonrpc-http-server.git#6117b1d77b5a60d6fa2dc884f12aa7f5fd4585ca"
|
source = "git+https://github.com/ethcore/jsonrpc-http-server.git#6117b1d77b5a60d6fa2dc884f12aa7f5fd4585ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hyper 0.9.3 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.9.3 (git+https://github.com/ethcore/hyper)",
|
||||||
"jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1181,12 +1181,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.7.7"
|
version = "0.7.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_codegen"
|
name = "serde_codegen"
|
||||||
version = "0.7.7"
|
version = "0.7.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1202,7 +1202,7 @@ version = "0.7.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -19,8 +19,11 @@ use std::time::{Instant, Duration};
|
|||||||
use std::sync::{mpsc, Mutex, RwLock, Arc};
|
use std::sync::{mpsc, Mutex, RwLock, Arc};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use v1::types::{TransactionRequest, TransactionConfirmation};
|
use v1::types::{TransactionRequest, TransactionConfirmation};
|
||||||
use util::{U256, H256};
|
use util::U256;
|
||||||
|
use jsonrpc_core;
|
||||||
|
|
||||||
|
/// Result that can be returned from JSON RPC.
|
||||||
|
pub type RpcResult = Result<jsonrpc_core::Value, jsonrpc_core::Error>;
|
||||||
|
|
||||||
/// Possible events happening in the queue that can be listened to.
|
/// Possible events happening in the queue that can be listened to.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -59,7 +62,7 @@ pub trait SigningQueue: Send + Sync {
|
|||||||
|
|
||||||
/// Removes a request from the queue.
|
/// Removes a request from the queue.
|
||||||
/// Notifies possible token holders that transaction was confirmed and given hash was assigned.
|
/// Notifies possible token holders that transaction was confirmed and given hash was assigned.
|
||||||
fn request_confirmed(&self, id: U256, hash: H256) -> Option<TransactionConfirmation>;
|
fn request_confirmed(&self, id: U256, result: RpcResult) -> Option<TransactionConfirmation>;
|
||||||
|
|
||||||
/// Returns a request if it is contained in the queue.
|
/// Returns a request if it is contained in the queue.
|
||||||
fn peek(&self, id: &U256) -> Option<TransactionConfirmation>;
|
fn peek(&self, id: &U256) -> Option<TransactionConfirmation>;
|
||||||
@ -75,7 +78,7 @@ enum ConfirmationResult {
|
|||||||
/// The transaction has been rejected.
|
/// The transaction has been rejected.
|
||||||
Rejected,
|
Rejected,
|
||||||
/// The transaction has been confirmed.
|
/// The transaction has been confirmed.
|
||||||
Confirmed(H256),
|
Confirmed(RpcResult),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Time you need to confirm the transaction in UI.
|
/// Time you need to confirm the transaction in UI.
|
||||||
@ -100,7 +103,7 @@ pub struct ConfirmationPromise {
|
|||||||
|
|
||||||
impl ConfirmationToken {
|
impl ConfirmationToken {
|
||||||
/// Submit solution to all listeners
|
/// Submit solution to all listeners
|
||||||
fn resolve(&self, result: Option<H256>) {
|
fn resolve(&self, result: Option<RpcResult>) {
|
||||||
let mut res = self.result.lock().unwrap();
|
let mut res = self.result.lock().unwrap();
|
||||||
*res = result.map_or(ConfirmationResult::Rejected, |h| ConfirmationResult::Confirmed(h));
|
*res = result.map_or(ConfirmationResult::Rejected, |h| ConfirmationResult::Confirmed(h));
|
||||||
// Notify listener
|
// Notify listener
|
||||||
@ -119,8 +122,8 @@ impl ConfirmationPromise {
|
|||||||
/// Blocks current thread and awaits for
|
/// Blocks current thread and awaits for
|
||||||
/// resolution of the transaction (rejected / confirmed)
|
/// resolution of the transaction (rejected / confirmed)
|
||||||
/// Returns `None` if transaction was rejected or timeout reached.
|
/// Returns `None` if transaction was rejected or timeout reached.
|
||||||
/// Returns `Some(hash)` if transaction was confirmed.
|
/// Returns `Some(result)` if transaction was confirmed.
|
||||||
pub fn wait_with_timeout(&self) -> Option<H256> {
|
pub fn wait_with_timeout(&self) -> Option<RpcResult> {
|
||||||
let timeout = Duration::from_secs(QUEUE_TIMEOUT_DURATION_SEC);
|
let timeout = Duration::from_secs(QUEUE_TIMEOUT_DURATION_SEC);
|
||||||
let deadline = Instant::now() + timeout;
|
let deadline = Instant::now() + timeout;
|
||||||
|
|
||||||
@ -137,7 +140,7 @@ impl ConfirmationPromise {
|
|||||||
// Check the result
|
// Check the result
|
||||||
match *res {
|
match *res {
|
||||||
ConfirmationResult::Rejected => return None,
|
ConfirmationResult::Rejected => return None,
|
||||||
ConfirmationResult::Confirmed(h) => return Some(h),
|
ConfirmationResult::Confirmed(ref h) => return Some(h.clone()),
|
||||||
ConfirmationResult::Waiting => continue,
|
ConfirmationResult::Waiting => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,12 +207,12 @@ impl ConfirmationsQueue {
|
|||||||
|
|
||||||
/// Removes transaction from this queue and notifies `ConfirmationPromise` holders about the result.
|
/// Removes transaction from this queue and notifies `ConfirmationPromise` holders about the result.
|
||||||
/// Notifies also a receiver about that event.
|
/// Notifies also a receiver about that event.
|
||||||
fn remove(&self, id: U256, result: Option<H256>) -> Option<TransactionConfirmation> {
|
fn remove(&self, id: U256, result: Option<RpcResult>) -> Option<TransactionConfirmation> {
|
||||||
let token = self.queue.write().unwrap().remove(&id);
|
let token = self.queue.write().unwrap().remove(&id);
|
||||||
|
|
||||||
if let Some(token) = token {
|
if let Some(token) = token {
|
||||||
// notify receiver about the event
|
// notify receiver about the event
|
||||||
self.notify(result.map_or_else(
|
self.notify(result.clone().map_or_else(
|
||||||
|| QueueEvent::RequestRejected(id),
|
|| QueueEvent::RequestRejected(id),
|
||||||
|_| QueueEvent::RequestConfirmed(id)
|
|_| QueueEvent::RequestConfirmed(id)
|
||||||
));
|
));
|
||||||
@ -265,9 +268,9 @@ impl SigningQueue for ConfirmationsQueue {
|
|||||||
self.remove(id, None)
|
self.remove(id, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_confirmed(&self, id: U256, hash: H256) -> Option<TransactionConfirmation> {
|
fn request_confirmed(&self, id: U256, result: RpcResult) -> Option<TransactionConfirmation> {
|
||||||
debug!(target: "own_tx", "Signer: Transaction confirmed ({:?}).", id);
|
debug!(target: "own_tx", "Signer: Transaction confirmed ({:?}).", id);
|
||||||
self.remove(id, Some(hash))
|
self.remove(id, Some(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn requests(&self) -> Vec<TransactionConfirmation> {
|
fn requests(&self) -> Vec<TransactionConfirmation> {
|
||||||
@ -286,6 +289,7 @@ mod test {
|
|||||||
use util::numbers::{U256, H256};
|
use util::numbers::{U256, H256};
|
||||||
use v1::types::TransactionRequest;
|
use v1::types::TransactionRequest;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use jsonrpc_core::to_value;
|
||||||
|
|
||||||
fn request() -> TransactionRequest {
|
fn request() -> TransactionRequest {
|
||||||
TransactionRequest {
|
TransactionRequest {
|
||||||
@ -317,10 +321,10 @@ mod test {
|
|||||||
// Just wait for the other thread to start
|
// Just wait for the other thread to start
|
||||||
thread::sleep(Duration::from_millis(100));
|
thread::sleep(Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
queue.request_confirmed(id, H256::from(1));
|
queue.request_confirmed(id, to_value(&H256::from(1)));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(handle.join().expect("Thread should finish nicely"), H256::from(1));
|
assert_eq!(handle.join().expect("Thread should finish nicely"), to_value(&H256::from(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -37,7 +37,7 @@ use ethcore::filter::Filter as EthcoreFilter;
|
|||||||
use self::ethash::SeedHashCompute;
|
use self::ethash::SeedHashCompute;
|
||||||
use v1::traits::Eth;
|
use v1::traits::Eth;
|
||||||
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt};
|
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt};
|
||||||
use v1::impls::dispatch_transaction;
|
use v1::impls::{dispatch_transaction, error_codes};
|
||||||
use serde;
|
use serde;
|
||||||
|
|
||||||
/// Eth rpc implementation.
|
/// Eth rpc implementation.
|
||||||
@ -218,13 +218,9 @@ fn from_params_default_third<F1, F2>(params: Params) -> Result<(F1, F2, BlockNum
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// must be in range [-32099, -32000]
|
|
||||||
const UNSUPPORTED_REQUEST_CODE: i64 = -32000;
|
|
||||||
const NO_WORK_CODE: i64 = -32001;
|
|
||||||
|
|
||||||
fn make_unsupported_err() -> Error {
|
fn make_unsupported_err() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(UNSUPPORTED_REQUEST_CODE),
|
code: ErrorCode::ServerError(error_codes::UNSUPPORTED_REQUEST_CODE),
|
||||||
message: "Unsupported request.".into(),
|
message: "Unsupported request.".into(),
|
||||||
data: None
|
data: None
|
||||||
}
|
}
|
||||||
@ -232,7 +228,7 @@ fn make_unsupported_err() -> Error {
|
|||||||
|
|
||||||
fn no_work_err() -> Error {
|
fn no_work_err() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(NO_WORK_CODE),
|
code: ErrorCode::ServerError(error_codes::NO_WORK_CODE),
|
||||||
message: "Still syncing.".into(),
|
message: "Still syncing.".into(),
|
||||||
data: None
|
data: None
|
||||||
}
|
}
|
||||||
@ -516,7 +512,7 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
|
|||||||
.and_then(|(raw_transaction, )| {
|
.and_then(|(raw_transaction, )| {
|
||||||
let raw_transaction = raw_transaction.to_vec();
|
let raw_transaction = raw_transaction.to_vec();
|
||||||
match UntrustedRlp::new(&raw_transaction).as_val() {
|
match UntrustedRlp::new(&raw_transaction).as_val() {
|
||||||
Ok(signed_transaction) => to_value(&dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction)),
|
Ok(signed_transaction) => dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction),
|
||||||
Err(_) => to_value(&H256::zero()),
|
Err(_) => to_value(&H256::zero()),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -25,7 +25,7 @@ use util::keys::store::AccountProvider;
|
|||||||
use v1::helpers::{SigningQueue, ConfirmationsQueue};
|
use v1::helpers::{SigningQueue, ConfirmationsQueue};
|
||||||
use v1::traits::EthSigning;
|
use v1::traits::EthSigning;
|
||||||
use v1::types::TransactionRequest;
|
use v1::types::TransactionRequest;
|
||||||
use v1::impls::sign_and_dispatch;
|
use v1::impls::{sign_and_dispatch, error_codes};
|
||||||
|
|
||||||
|
|
||||||
/// Implementation of functions that require signing when no trusted signer is used.
|
/// Implementation of functions that require signing when no trusted signer is used.
|
||||||
@ -45,6 +45,7 @@ impl EthSigningQueueClient {
|
|||||||
impl EthSigning for EthSigningQueueClient {
|
impl EthSigning for EthSigningQueueClient {
|
||||||
|
|
||||||
fn sign(&self, _params: Params) -> Result<Value, Error> {
|
fn sign(&self, _params: Params) -> Result<Value, Error> {
|
||||||
|
warn!("Invoking eth_sign is not yet supported with signer enabled.");
|
||||||
// TODO [ToDr] Implement sign when rest of the signing queue is ready.
|
// TODO [ToDr] Implement sign when rest of the signing queue is ready.
|
||||||
rpc_unimplemented!()
|
rpc_unimplemented!()
|
||||||
}
|
}
|
||||||
@ -55,7 +56,7 @@ impl EthSigning for EthSigningQueueClient {
|
|||||||
let queue = take_weak!(self.queue);
|
let queue = take_weak!(self.queue);
|
||||||
let id = queue.add_request(request);
|
let id = queue.add_request(request);
|
||||||
let result = id.wait_with_timeout();
|
let result = id.wait_with_timeout();
|
||||||
to_value(&result.unwrap_or_else(H256::new))
|
result.unwrap_or_else(|| to_value(&H256::new()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +94,9 @@ impl<C, A, M> EthSigning for EthSigningUnsafeClient<C, A, M> where
|
|||||||
|
|
||||||
fn sign(&self, params: Params) -> Result<Value, Error> {
|
fn sign(&self, params: Params) -> Result<Value, Error> {
|
||||||
from_params::<(Address, H256)>(params).and_then(|(addr, msg)| {
|
from_params::<(Address, H256)>(params).and_then(|(addr, msg)| {
|
||||||
to_value(&take_weak!(self.accounts).sign(&addr, &msg).unwrap_or(H520::zero()))
|
take_weak!(self.accounts).sign(&addr, &msg)
|
||||||
|
.map(|v| to_value(&v))
|
||||||
|
.unwrap_or_else(|e| Err(account_locked(format!("Error: {:?}", e))))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,10 +105,17 @@ impl<C, A, M> EthSigning for EthSigningUnsafeClient<C, A, M> where
|
|||||||
.and_then(|(request, )| {
|
.and_then(|(request, )| {
|
||||||
let accounts = take_weak!(self.accounts);
|
let accounts = take_weak!(self.accounts);
|
||||||
match accounts.account_secret(&request.from) {
|
match accounts.account_secret(&request.from) {
|
||||||
Ok(secret) => to_value(&sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret)),
|
Ok(secret) => sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret),
|
||||||
Err(_) => to_value(&H256::zero())
|
Err(e) => Err(account_locked(format!("Error: {:?}", e))),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn account_locked(data: String) -> Error {
|
||||||
|
Error {
|
||||||
|
code: ErrorCode::ServerError(error_codes::ACCOUNT_LOCKED),
|
||||||
|
message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(),
|
||||||
|
data: Some(Value::String(data)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,14 +54,25 @@ pub use self::traces::TracesClient;
|
|||||||
pub use self::rpc::RpcClient;
|
pub use self::rpc::RpcClient;
|
||||||
|
|
||||||
use v1::types::TransactionRequest;
|
use v1::types::TransactionRequest;
|
||||||
|
use ethcore::error::Error as EthcoreError;
|
||||||
use ethcore::miner::{AccountDetails, MinerService};
|
use ethcore::miner::{AccountDetails, MinerService};
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
use ethcore::transaction::{Action, SignedTransaction, Transaction};
|
use ethcore::transaction::{Action, SignedTransaction, Transaction};
|
||||||
use util::numbers::*;
|
use util::numbers::*;
|
||||||
use util::rlp::encode;
|
use util::rlp::encode;
|
||||||
use util::bytes::ToPretty;
|
use util::bytes::ToPretty;
|
||||||
|
use jsonrpc_core::{Error, ErrorCode, Value, to_value};
|
||||||
|
|
||||||
fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: SignedTransaction) -> H256
|
mod error_codes {
|
||||||
|
// NOTE [ToDr] Codes from [-32099, -32000]
|
||||||
|
pub const UNSUPPORTED_REQUEST_CODE: i64 = -32000;
|
||||||
|
pub const NO_WORK_CODE: i64 = -32001;
|
||||||
|
pub const UNKNOWN_ERROR: i64 = -32002;
|
||||||
|
pub const TRANSACTION_ERROR: i64 = -32010;
|
||||||
|
pub const ACCOUNT_LOCKED: i64 = -32020;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: SignedTransaction) -> Result<Value, Error>
|
||||||
where C: MiningBlockChainClient, M: MinerService {
|
where C: MiningBlockChainClient, M: MinerService {
|
||||||
let hash = signed_transaction.hash();
|
let hash = signed_transaction.hash();
|
||||||
|
|
||||||
@ -72,10 +83,12 @@ fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: SignedT
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
import.map(|_| hash).unwrap_or(H256::zero())
|
import
|
||||||
|
.map_err(transaction_error)
|
||||||
|
.and_then(|_| to_value(&hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionRequest, secret: H256) -> H256
|
fn sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionRequest, secret: H256) -> Result<Value, Error>
|
||||||
where C: MiningBlockChainClient, M: MinerService {
|
where C: MiningBlockChainClient, M: MinerService {
|
||||||
|
|
||||||
let signed_transaction = {
|
let signed_transaction = {
|
||||||
@ -97,3 +110,41 @@ fn sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionRequest, s
|
|||||||
trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty());
|
trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty());
|
||||||
dispatch_transaction(&*client, &*miner, signed_transaction)
|
dispatch_transaction(&*client, &*miner, signed_transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transaction_error(error: EthcoreError) -> Error {
|
||||||
|
use ethcore::error::TransactionError::*;
|
||||||
|
|
||||||
|
if let EthcoreError::Transaction(e) = error {
|
||||||
|
let msg = match e {
|
||||||
|
AlreadyImported => "Transaction with the same hash was already imported.".into(),
|
||||||
|
Old => "Transaction nonce is too low. Try incrementing the nonce.".into(),
|
||||||
|
TooCheapToReplace => {
|
||||||
|
"Transaction fee is too low. There is another transaction with same nonce in the queue. Try increasing the fee or incrementing the nonce.".into()
|
||||||
|
},
|
||||||
|
LimitReached => {
|
||||||
|
"There is too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into()
|
||||||
|
},
|
||||||
|
InsufficientGasPrice { minimal, got } => {
|
||||||
|
format!("Transaction fee is to low. It does not satisfy your node's minimal fee (minimal: {}, got: {}). Try increasing the fee.", minimal, got)
|
||||||
|
},
|
||||||
|
InsufficientBalance { balance, cost } => {
|
||||||
|
format!("Insufficient funds. Account you try to send transaction from does not have enough funds. Required {} and got: {}.", cost, balance)
|
||||||
|
},
|
||||||
|
GasLimitExceeded { limit, got } => {
|
||||||
|
format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got)
|
||||||
|
},
|
||||||
|
InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(),
|
||||||
|
};
|
||||||
|
Error {
|
||||||
|
code: ErrorCode::ServerError(error_codes::TRANSACTION_ERROR),
|
||||||
|
message: msg,
|
||||||
|
data: None,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Error {
|
||||||
|
code: ErrorCode::ServerError(error_codes::UNKNOWN_ERROR),
|
||||||
|
message: "Unknown error when sending transaction.".into(),
|
||||||
|
data: Some(Value::String(format!("{:?}", error))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -92,7 +92,7 @@ impl<A: 'static, C: 'static, M: 'static> Personal for PersonalClient<A, C, M>
|
|||||||
.and_then(|(request, password)| {
|
.and_then(|(request, password)| {
|
||||||
let accounts = take_weak!(self.accounts);
|
let accounts = take_weak!(self.accounts);
|
||||||
match accounts.locked_account_secret(&request.from, &password) {
|
match accounts.locked_account_secret(&request.from, &password) {
|
||||||
Ok(secret) => to_value(&sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret)),
|
Ok(secret) => sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret),
|
||||||
Err(_) => to_value(&H256::zero()),
|
Err(_) => to_value(&H256::zero()),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -73,9 +73,9 @@ impl<A: 'static, C: 'static, M: 'static> PersonalSigner for SignerClient<A, C, M
|
|||||||
}
|
}
|
||||||
match accounts.locked_account_secret(&request.from, &pass) {
|
match accounts.locked_account_secret(&request.from, &pass) {
|
||||||
Ok(secret) => {
|
Ok(secret) => {
|
||||||
let hash = sign_and_dispatch(&*client, &*miner, request, secret);
|
let res = sign_and_dispatch(&*client, &*miner, request, secret);
|
||||||
queue.request_confirmed(id, hash);
|
queue.request_confirmed(id, res.clone());
|
||||||
Some(to_value(&hash))
|
Some(res)
|
||||||
},
|
},
|
||||||
Err(_) => None
|
Err(_) => None
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user