diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 8cbf26b7c..50c22b187 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -21,6 +21,7 @@ macro_rules! rpc_unimplemented { } use std::fmt; +use rlp::DecoderError; use ethcore::error::{Error as EthcoreError, CallError}; use ethcore::account_provider::{Error as AccountError}; use fetch::FetchError; @@ -271,6 +272,14 @@ pub fn from_transaction_error(error: EthcoreError) -> Error { } } +pub fn from_rlp_error(error: DecoderError) -> Error { + Error { + code: ErrorCode::InvalidParams, + message: "Invalid RLP.".into(), + data: Some(Value::String(format!("{:?}", error))), + } +} + pub fn from_call_error(error: CallError) -> Error { match error { CallError::StatePruned => state_pruned(), diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index a6dc86bc2..4e54078fb 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -611,7 +611,7 @@ impl Eth for EthClient where let raw_transaction = raw.to_vec(); match UntrustedRlp::new(&raw_transaction).as_val() { Ok(signed_transaction) => dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction), - Err(_) => Ok(RpcH256::from(H256::from(0))), + Err(e) => Err(errors::from_rlp_error(e)), } } @@ -621,15 +621,15 @@ impl Eth for EthClient where let request = CallRequest::into(request); let signed = try!(self.sign_call(request)); - let r = match num.0 { + let result = match num.0 { BlockNumber::Pending => take_weak!(self.miner).call(&*take_weak!(self.client), &signed, Default::default()), num => take_weak!(self.client).call(&signed, num.into(), Default::default()), }; - match r { - Ok(b) => Ok(Bytes(b.output)), - Err(e) => Err(errors::from_call_error(e)), - } + + result + .map(|b| b.output.into()) + .map_err(errors::from_call_error) } fn estimate_gas(&self, request: CallRequest, num: Trailing) -> Result { @@ -637,12 +637,14 @@ impl Eth for EthClient where let request = CallRequest::into(request); let signed = try!(self.sign_call(request)); - let r = match num.0 { + let result = match num.0 { BlockNumber::Pending => take_weak!(self.miner).call(&*take_weak!(self.client), &signed, Default::default()), num => take_weak!(self.client).call(&signed, num.into(), Default::default()), }; - Ok(RpcU256::from(r.map(|res| res.gas_used + res.refunded).unwrap_or(From::from(0)))) + result + .map(|res| (res.gas_used + res.refunded).into()) + .map_err(errors::from_call_error) } fn compile_lll(&self, _: String) -> Result { diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index f69e73b62..d324715d6 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -805,6 +805,23 @@ fn rpc_eth_send_transaction_error() { assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); } +#[test] +fn rpc_eth_send_raw_transaction_error() { + let tester = EthTester::default(); + + let req = r#"{ + "jsonrpc": "2.0", + "method": "eth_sendRawTransaction", + "params": [ + "0x0123" + ], + "id": 1 + }"#; + let res = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid RLP.","data":"RlpIncorrectListLen"},"id":1}"#.into(); + + assert_eq!(tester.io.handle_request_sync(&req), Some(res)); +} + #[test] fn rpc_eth_send_raw_transaction() { let tester = EthTester::default();