More meaningful errors when sending transaction
This commit is contained in:
@@ -25,7 +25,7 @@ use util::keys::store::AccountProvider;
|
||||
use v1::helpers::{SigningQueue, ConfirmationsQueue};
|
||||
use v1::traits::EthSigning;
|
||||
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.
|
||||
@@ -45,6 +45,7 @@ impl EthSigningQueueClient {
|
||||
impl EthSigning for EthSigningQueueClient {
|
||||
|
||||
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.
|
||||
rpc_unimplemented!()
|
||||
}
|
||||
@@ -55,7 +56,7 @@ impl EthSigning for EthSigningQueueClient {
|
||||
let queue = take_weak!(self.queue);
|
||||
let id = queue.add_request(request);
|
||||
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> {
|
||||
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, )| {
|
||||
let accounts = take_weak!(self.accounts);
|
||||
match accounts.account_secret(&request.from) {
|
||||
Ok(secret) => to_value(&sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret)),
|
||||
Err(_) => to_value(&H256::zero())
|
||||
Ok(secret) => sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret),
|
||||
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,16 @@ pub use self::traces::TracesClient;
|
||||
pub use self::rpc::RpcClient;
|
||||
|
||||
use v1::types::TransactionRequest;
|
||||
use ethcore::error::Error as EthcoreError;
|
||||
use ethcore::miner::{AccountDetails, MinerService};
|
||||
use ethcore::client::MiningBlockChainClient;
|
||||
use ethcore::transaction::{Action, SignedTransaction, Transaction};
|
||||
use util::numbers::*;
|
||||
use util::rlp::encode;
|
||||
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
|
||||
fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: SignedTransaction) -> Result<Value, Error>
|
||||
where C: MiningBlockChainClient, M: MinerService {
|
||||
let hash = signed_transaction.hash();
|
||||
|
||||
@@ -72,10 +74,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 {
|
||||
|
||||
let signed_transaction = {
|
||||
@@ -97,3 +101,48 @@ 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());
|
||||
dispatch_transaction(&*client, &*miner, signed_transaction)
|
||||
}
|
||||
|
||||
mod error_codes {
|
||||
// NOTE [ToDr] Codes from -32000 to -32099
|
||||
pub const UNKNOWN_ERROR: i64 = -32002;
|
||||
pub const TRANSACTION_ERROR: i64 = -32010;
|
||||
pub const ACCOUNT_LOCKED: i64 = -32020;
|
||||
}
|
||||
|
||||
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))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
Ok(secret) => {
|
||||
let hash = sign_and_dispatch(&*client, &*miner, request, secret);
|
||||
queue.request_confirmed(id, hash);
|
||||
Some(to_value(&hash))
|
||||
let res = sign_and_dispatch(&*client, &*miner, request, secret);
|
||||
queue.request_confirmed(id, res.clone());
|
||||
Some(res)
|
||||
},
|
||||
Err(_) => None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user